4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "disas/disas.h"
31 #include "qemu/bitops.h"
37 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
59 /* These instructions trap after executing, so defer them until after the
60 conditional execution state has been updated. */
65 /* We reuse the same 64-bit temporaries for efficiency. */
66 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
67 static TCGv_i32 cpu_R[16];
68 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
69 static TCGv_i32 cpu_exclusive_addr;
70 static TCGv_i32 cpu_exclusive_val;
71 static TCGv_i32 cpu_exclusive_high;
72 #ifdef CONFIG_USER_ONLY
73 static TCGv_i32 cpu_exclusive_test;
74 static TCGv_i32 cpu_exclusive_info;
77 /* FIXME: These should be removed. */
78 static TCGv_i32 cpu_F0s, cpu_F1s;
79 static TCGv_i64 cpu_F0d, cpu_F1d;
81 #include "exec/gen-icount.h"
83 static const char *regnames[] =
84 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
85 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
87 /* initialize TCG globals. */
88 void arm_translate_init(void)
92 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
94 for (i = 0; i < 16; i++) {
95 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
96 offsetof(CPUARMState, regs[i]),
99 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
100 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
101 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
102 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
104 cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
105 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
106 cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
107 offsetof(CPUARMState, exclusive_val), "exclusive_val");
108 cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
109 offsetof(CPUARMState, exclusive_high), "exclusive_high");
110 #ifdef CONFIG_USER_ONLY
111 cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
112 offsetof(CPUARMState, exclusive_test), "exclusive_test");
113 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
114 offsetof(CPUARMState, exclusive_info), "exclusive_info");
117 a64_translate_init();
120 static inline TCGv_i32 load_cpu_offset(int offset)
122 TCGv_i32 tmp = tcg_temp_new_i32();
123 tcg_gen_ld_i32(tmp, cpu_env, offset);
127 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
129 static inline void store_cpu_offset(TCGv_i32 var, int offset)
131 tcg_gen_st_i32(var, cpu_env, offset);
132 tcg_temp_free_i32(var);
135 #define store_cpu_field(var, name) \
136 store_cpu_offset(var, offsetof(CPUARMState, name))
138 /* Set a variable to the value of a CPU register. */
139 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
143 /* normally, since we updated PC, we need only to add one insn */
145 addr = (long)s->pc + 2;
147 addr = (long)s->pc + 4;
148 tcg_gen_movi_i32(var, addr);
150 tcg_gen_mov_i32(var, cpu_R[reg]);
154 /* Create a new temporary and set it to the value of a CPU register. */
155 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
157 TCGv_i32 tmp = tcg_temp_new_i32();
158 load_reg_var(s, tmp, reg);
162 /* Set a CPU register. The source must be a temporary and will be
164 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
167 tcg_gen_andi_i32(var, var, ~1);
168 s->is_jmp = DISAS_JUMP;
170 tcg_gen_mov_i32(cpu_R[reg], var);
171 tcg_temp_free_i32(var);
174 /* Value extensions. */
175 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
176 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
177 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
178 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
180 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
181 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
184 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
186 TCGv_i32 tmp_mask = tcg_const_i32(mask);
187 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
188 tcg_temp_free_i32(tmp_mask);
190 /* Set NZCV flags from the high 4 bits of var. */
191 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
193 static void gen_exception(int excp)
195 TCGv_i32 tmp = tcg_temp_new_i32();
196 tcg_gen_movi_i32(tmp, excp);
197 gen_helper_exception(cpu_env, tmp);
198 tcg_temp_free_i32(tmp);
201 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
203 TCGv_i32 tmp1 = tcg_temp_new_i32();
204 TCGv_i32 tmp2 = tcg_temp_new_i32();
205 tcg_gen_ext16s_i32(tmp1, a);
206 tcg_gen_ext16s_i32(tmp2, b);
207 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
208 tcg_temp_free_i32(tmp2);
209 tcg_gen_sari_i32(a, a, 16);
210 tcg_gen_sari_i32(b, b, 16);
211 tcg_gen_mul_i32(b, b, a);
212 tcg_gen_mov_i32(a, tmp1);
213 tcg_temp_free_i32(tmp1);
216 /* Byteswap each halfword. */
217 static void gen_rev16(TCGv_i32 var)
219 TCGv_i32 tmp = tcg_temp_new_i32();
220 tcg_gen_shri_i32(tmp, var, 8);
221 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
222 tcg_gen_shli_i32(var, var, 8);
223 tcg_gen_andi_i32(var, var, 0xff00ff00);
224 tcg_gen_or_i32(var, var, tmp);
225 tcg_temp_free_i32(tmp);
228 /* Byteswap low halfword and sign extend. */
229 static void gen_revsh(TCGv_i32 var)
231 tcg_gen_ext16u_i32(var, var);
232 tcg_gen_bswap16_i32(var, var);
233 tcg_gen_ext16s_i32(var, var);
236 /* Unsigned bitfield extract. */
237 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
240 tcg_gen_shri_i32(var, var, shift);
241 tcg_gen_andi_i32(var, var, mask);
244 /* Signed bitfield extract. */
245 static void gen_sbfx(TCGv_i32 var, int shift, int width)
250 tcg_gen_sari_i32(var, var, shift);
251 if (shift + width < 32) {
252 signbit = 1u << (width - 1);
253 tcg_gen_andi_i32(var, var, (1u << width) - 1);
254 tcg_gen_xori_i32(var, var, signbit);
255 tcg_gen_subi_i32(var, var, signbit);
259 /* Return (b << 32) + a. Mark inputs as dead */
260 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
262 TCGv_i64 tmp64 = tcg_temp_new_i64();
264 tcg_gen_extu_i32_i64(tmp64, b);
265 tcg_temp_free_i32(b);
266 tcg_gen_shli_i64(tmp64, tmp64, 32);
267 tcg_gen_add_i64(a, tmp64, a);
269 tcg_temp_free_i64(tmp64);
273 /* Return (b << 32) - a. Mark inputs as dead. */
274 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
276 TCGv_i64 tmp64 = tcg_temp_new_i64();
278 tcg_gen_extu_i32_i64(tmp64, b);
279 tcg_temp_free_i32(b);
280 tcg_gen_shli_i64(tmp64, tmp64, 32);
281 tcg_gen_sub_i64(a, tmp64, a);
283 tcg_temp_free_i64(tmp64);
287 /* 32x32->64 multiply. Marks inputs as dead. */
288 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
290 TCGv_i32 lo = tcg_temp_new_i32();
291 TCGv_i32 hi = tcg_temp_new_i32();
294 tcg_gen_mulu2_i32(lo, hi, a, b);
295 tcg_temp_free_i32(a);
296 tcg_temp_free_i32(b);
298 ret = tcg_temp_new_i64();
299 tcg_gen_concat_i32_i64(ret, lo, hi);
300 tcg_temp_free_i32(lo);
301 tcg_temp_free_i32(hi);
306 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
308 TCGv_i32 lo = tcg_temp_new_i32();
309 TCGv_i32 hi = tcg_temp_new_i32();
312 tcg_gen_muls2_i32(lo, hi, a, b);
313 tcg_temp_free_i32(a);
314 tcg_temp_free_i32(b);
316 ret = tcg_temp_new_i64();
317 tcg_gen_concat_i32_i64(ret, lo, hi);
318 tcg_temp_free_i32(lo);
319 tcg_temp_free_i32(hi);
324 /* Swap low and high halfwords. */
325 static void gen_swap_half(TCGv_i32 var)
327 TCGv_i32 tmp = tcg_temp_new_i32();
328 tcg_gen_shri_i32(tmp, var, 16);
329 tcg_gen_shli_i32(var, var, 16);
330 tcg_gen_or_i32(var, var, tmp);
331 tcg_temp_free_i32(tmp);
334 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
335 tmp = (t0 ^ t1) & 0x8000;
338 t0 = (t0 + t1) ^ tmp;
341 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
343 TCGv_i32 tmp = tcg_temp_new_i32();
344 tcg_gen_xor_i32(tmp, t0, t1);
345 tcg_gen_andi_i32(tmp, tmp, 0x8000);
346 tcg_gen_andi_i32(t0, t0, ~0x8000);
347 tcg_gen_andi_i32(t1, t1, ~0x8000);
348 tcg_gen_add_i32(t0, t0, t1);
349 tcg_gen_xor_i32(t0, t0, tmp);
350 tcg_temp_free_i32(tmp);
351 tcg_temp_free_i32(t1);
354 /* Set CF to the top bit of var. */
355 static void gen_set_CF_bit31(TCGv_i32 var)
357 tcg_gen_shri_i32(cpu_CF, var, 31);
360 /* Set N and Z flags from var. */
361 static inline void gen_logic_CC(TCGv_i32 var)
363 tcg_gen_mov_i32(cpu_NF, var);
364 tcg_gen_mov_i32(cpu_ZF, var);
368 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
370 tcg_gen_add_i32(t0, t0, t1);
371 tcg_gen_add_i32(t0, t0, cpu_CF);
374 /* dest = T0 + T1 + CF. */
375 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
377 tcg_gen_add_i32(dest, t0, t1);
378 tcg_gen_add_i32(dest, dest, cpu_CF);
381 /* dest = T0 - T1 + CF - 1. */
382 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
384 tcg_gen_sub_i32(dest, t0, t1);
385 tcg_gen_add_i32(dest, dest, cpu_CF);
386 tcg_gen_subi_i32(dest, dest, 1);
389 /* dest = T0 + T1. Compute C, N, V and Z flags */
390 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
392 TCGv_i32 tmp = tcg_temp_new_i32();
393 tcg_gen_movi_i32(tmp, 0);
394 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
395 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
396 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
397 tcg_gen_xor_i32(tmp, t0, t1);
398 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
399 tcg_temp_free_i32(tmp);
400 tcg_gen_mov_i32(dest, cpu_NF);
403 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
404 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
406 TCGv_i32 tmp = tcg_temp_new_i32();
407 if (TCG_TARGET_HAS_add2_i32) {
408 tcg_gen_movi_i32(tmp, 0);
409 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
410 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
412 TCGv_i64 q0 = tcg_temp_new_i64();
413 TCGv_i64 q1 = tcg_temp_new_i64();
414 tcg_gen_extu_i32_i64(q0, t0);
415 tcg_gen_extu_i32_i64(q1, t1);
416 tcg_gen_add_i64(q0, q0, q1);
417 tcg_gen_extu_i32_i64(q1, cpu_CF);
418 tcg_gen_add_i64(q0, q0, q1);
419 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
420 tcg_temp_free_i64(q0);
421 tcg_temp_free_i64(q1);
423 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
424 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
425 tcg_gen_xor_i32(tmp, t0, t1);
426 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
427 tcg_temp_free_i32(tmp);
428 tcg_gen_mov_i32(dest, cpu_NF);
431 /* dest = T0 - T1. Compute C, N, V and Z flags */
432 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
435 tcg_gen_sub_i32(cpu_NF, t0, t1);
436 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
437 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
438 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
439 tmp = tcg_temp_new_i32();
440 tcg_gen_xor_i32(tmp, t0, t1);
441 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
442 tcg_temp_free_i32(tmp);
443 tcg_gen_mov_i32(dest, cpu_NF);
446 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
447 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
449 TCGv_i32 tmp = tcg_temp_new_i32();
450 tcg_gen_not_i32(tmp, t1);
451 gen_adc_CC(dest, t0, tmp);
452 tcg_temp_free_i32(tmp);
455 #define GEN_SHIFT(name) \
456 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
458 TCGv_i32 tmp1, tmp2, tmp3; \
459 tmp1 = tcg_temp_new_i32(); \
460 tcg_gen_andi_i32(tmp1, t1, 0xff); \
461 tmp2 = tcg_const_i32(0); \
462 tmp3 = tcg_const_i32(0x1f); \
463 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
464 tcg_temp_free_i32(tmp3); \
465 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
466 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
467 tcg_temp_free_i32(tmp2); \
468 tcg_temp_free_i32(tmp1); \
474 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
477 tmp1 = tcg_temp_new_i32();
478 tcg_gen_andi_i32(tmp1, t1, 0xff);
479 tmp2 = tcg_const_i32(0x1f);
480 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
481 tcg_temp_free_i32(tmp2);
482 tcg_gen_sar_i32(dest, t0, tmp1);
483 tcg_temp_free_i32(tmp1);
486 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
488 TCGv_i32 c0 = tcg_const_i32(0);
489 TCGv_i32 tmp = tcg_temp_new_i32();
490 tcg_gen_neg_i32(tmp, src);
491 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
492 tcg_temp_free_i32(c0);
493 tcg_temp_free_i32(tmp);
496 static void shifter_out_im(TCGv_i32 var, int shift)
499 tcg_gen_andi_i32(cpu_CF, var, 1);
501 tcg_gen_shri_i32(cpu_CF, var, shift);
503 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
508 /* Shift by immediate. Includes special handling for shift == 0. */
509 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
510 int shift, int flags)
516 shifter_out_im(var, 32 - shift);
517 tcg_gen_shli_i32(var, var, shift);
523 tcg_gen_shri_i32(cpu_CF, var, 31);
525 tcg_gen_movi_i32(var, 0);
528 shifter_out_im(var, shift - 1);
529 tcg_gen_shri_i32(var, var, shift);
536 shifter_out_im(var, shift - 1);
539 tcg_gen_sari_i32(var, var, shift);
541 case 3: /* ROR/RRX */
544 shifter_out_im(var, shift - 1);
545 tcg_gen_rotri_i32(var, var, shift); break;
547 TCGv_i32 tmp = tcg_temp_new_i32();
548 tcg_gen_shli_i32(tmp, cpu_CF, 31);
550 shifter_out_im(var, 0);
551 tcg_gen_shri_i32(var, var, 1);
552 tcg_gen_or_i32(var, var, tmp);
553 tcg_temp_free_i32(tmp);
558 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
559 TCGv_i32 shift, int flags)
563 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
564 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
565 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
566 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
571 gen_shl(var, var, shift);
574 gen_shr(var, var, shift);
577 gen_sar(var, var, shift);
579 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
580 tcg_gen_rotr_i32(var, var, shift); break;
583 tcg_temp_free_i32(shift);
586 #define PAS_OP(pfx) \
588 case 0: gen_pas_helper(glue(pfx,add16)); break; \
589 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
590 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
591 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
592 case 4: gen_pas_helper(glue(pfx,add8)); break; \
593 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
595 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
600 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
602 tmp = tcg_temp_new_ptr();
603 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
605 tcg_temp_free_ptr(tmp);
608 tmp = tcg_temp_new_ptr();
609 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
611 tcg_temp_free_ptr(tmp);
613 #undef gen_pas_helper
614 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
627 #undef gen_pas_helper
632 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
633 #define PAS_OP(pfx) \
635 case 0: gen_pas_helper(glue(pfx,add8)); break; \
636 case 1: gen_pas_helper(glue(pfx,add16)); break; \
637 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
638 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
639 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
640 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
642 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
647 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
649 tmp = tcg_temp_new_ptr();
650 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
652 tcg_temp_free_ptr(tmp);
655 tmp = tcg_temp_new_ptr();
656 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
658 tcg_temp_free_ptr(tmp);
660 #undef gen_pas_helper
661 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
674 #undef gen_pas_helper
679 static void gen_test_cc(int cc, int label)
686 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
689 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
692 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
695 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
698 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
701 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
704 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
707 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
709 case 8: /* hi: C && !Z */
710 inv = gen_new_label();
711 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
712 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
715 case 9: /* ls: !C || Z */
716 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
717 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
719 case 10: /* ge: N == V -> N ^ V == 0 */
720 tmp = tcg_temp_new_i32();
721 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
722 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
723 tcg_temp_free_i32(tmp);
725 case 11: /* lt: N != V -> N ^ V != 0 */
726 tmp = tcg_temp_new_i32();
727 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
728 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
729 tcg_temp_free_i32(tmp);
731 case 12: /* gt: !Z && N == V */
732 inv = gen_new_label();
733 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
734 tmp = tcg_temp_new_i32();
735 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
736 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
737 tcg_temp_free_i32(tmp);
740 case 13: /* le: Z || N != V */
741 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
742 tmp = tcg_temp_new_i32();
743 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
744 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
745 tcg_temp_free_i32(tmp);
748 fprintf(stderr, "Bad condition code 0x%x\n", cc);
753 static const uint8_t table_logic_cc[16] = {
772 /* Set PC and Thumb state from an immediate address. */
773 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
777 s->is_jmp = DISAS_UPDATE;
778 if (s->thumb != (addr & 1)) {
779 tmp = tcg_temp_new_i32();
780 tcg_gen_movi_i32(tmp, addr & 1);
781 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
782 tcg_temp_free_i32(tmp);
784 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
787 /* Set PC and Thumb state from var. var is marked as dead. */
788 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
790 s->is_jmp = DISAS_UPDATE;
791 tcg_gen_andi_i32(cpu_R[15], var, ~1);
792 tcg_gen_andi_i32(var, var, 1);
793 store_cpu_field(var, thumb);
796 /* Variant of store_reg which uses branch&exchange logic when storing
797 to r15 in ARM architecture v7 and above. The source must be a temporary
798 and will be marked as dead. */
799 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
800 int reg, TCGv_i32 var)
802 if (reg == 15 && ENABLE_ARCH_7) {
805 store_reg(s, reg, var);
809 /* Variant of store_reg which uses branch&exchange logic when storing
810 * to r15 in ARM architecture v5T and above. This is used for storing
811 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
812 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
813 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
814 int reg, TCGv_i32 var)
816 if (reg == 15 && ENABLE_ARCH_5) {
819 store_reg(s, reg, var);
823 /* Abstractions of "generate code to do a guest load/store for
824 * AArch32", where a vaddr is always 32 bits (and is zero
825 * extended if we're a 64 bit core) and data is also
826 * 32 bits unless specifically doing a 64 bit access.
827 * These functions work like tcg_gen_qemu_{ld,st}* except
828 * that the address argument is TCGv_i32 rather than TCGv.
830 #if TARGET_LONG_BITS == 32
832 #define DO_GEN_LD(SUFF, OPC) \
833 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
835 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
838 #define DO_GEN_ST(SUFF, OPC) \
839 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
841 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
844 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
846 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
849 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
851 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
856 #define DO_GEN_LD(SUFF, OPC) \
857 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
859 TCGv addr64 = tcg_temp_new(); \
860 tcg_gen_extu_i32_i64(addr64, addr); \
861 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
862 tcg_temp_free(addr64); \
865 #define DO_GEN_ST(SUFF, OPC) \
866 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
868 TCGv addr64 = tcg_temp_new(); \
869 tcg_gen_extu_i32_i64(addr64, addr); \
870 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
871 tcg_temp_free(addr64); \
874 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
876 TCGv addr64 = tcg_temp_new();
877 tcg_gen_extu_i32_i64(addr64, addr);
878 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
879 tcg_temp_free(addr64);
882 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
884 TCGv addr64 = tcg_temp_new();
885 tcg_gen_extu_i32_i64(addr64, addr);
886 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
887 tcg_temp_free(addr64);
894 DO_GEN_LD(16s, MO_TESW)
895 DO_GEN_LD(16u, MO_TEUW)
896 DO_GEN_LD(32u, MO_TEUL)
898 DO_GEN_ST(16, MO_TEUW)
899 DO_GEN_ST(32, MO_TEUL)
901 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
904 gen_a64_set_pc_im(val);
906 tcg_gen_movi_i32(cpu_R[15], val);
910 /* Force a TB lookup after an instruction that changes the CPU state. */
911 static inline void gen_lookup_tb(DisasContext *s)
913 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
914 s->is_jmp = DISAS_UPDATE;
917 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
920 int val, rm, shift, shiftop;
923 if (!(insn & (1 << 25))) {
926 if (!(insn & (1 << 23)))
929 tcg_gen_addi_i32(var, var, val);
933 shift = (insn >> 7) & 0x1f;
934 shiftop = (insn >> 5) & 3;
935 offset = load_reg(s, rm);
936 gen_arm_shift_im(offset, shiftop, shift, 0);
937 if (!(insn & (1 << 23)))
938 tcg_gen_sub_i32(var, var, offset);
940 tcg_gen_add_i32(var, var, offset);
941 tcg_temp_free_i32(offset);
945 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
946 int extra, TCGv_i32 var)
951 if (insn & (1 << 22)) {
953 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
954 if (!(insn & (1 << 23)))
958 tcg_gen_addi_i32(var, var, val);
962 tcg_gen_addi_i32(var, var, extra);
964 offset = load_reg(s, rm);
965 if (!(insn & (1 << 23)))
966 tcg_gen_sub_i32(var, var, offset);
968 tcg_gen_add_i32(var, var, offset);
969 tcg_temp_free_i32(offset);
973 static TCGv_ptr get_fpstatus_ptr(int neon)
975 TCGv_ptr statusptr = tcg_temp_new_ptr();
978 offset = offsetof(CPUARMState, vfp.standard_fp_status);
980 offset = offsetof(CPUARMState, vfp.fp_status);
982 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
986 #define VFP_OP2(name) \
987 static inline void gen_vfp_##name(int dp) \
989 TCGv_ptr fpst = get_fpstatus_ptr(0); \
991 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
993 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
995 tcg_temp_free_ptr(fpst); \
1005 static inline void gen_vfp_F1_mul(int dp)
1007 /* Like gen_vfp_mul() but put result in F1 */
1008 TCGv_ptr fpst = get_fpstatus_ptr(0);
1010 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1012 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1014 tcg_temp_free_ptr(fpst);
1017 static inline void gen_vfp_F1_neg(int dp)
1019 /* Like gen_vfp_neg() but put result in F1 */
1021 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1023 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1027 static inline void gen_vfp_abs(int dp)
1030 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1032 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1035 static inline void gen_vfp_neg(int dp)
1038 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1040 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1043 static inline void gen_vfp_sqrt(int dp)
1046 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1048 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1051 static inline void gen_vfp_cmp(int dp)
1054 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1056 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1059 static inline void gen_vfp_cmpe(int dp)
1062 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1064 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1067 static inline void gen_vfp_F1_ld0(int dp)
1070 tcg_gen_movi_i64(cpu_F1d, 0);
1072 tcg_gen_movi_i32(cpu_F1s, 0);
1075 #define VFP_GEN_ITOF(name) \
1076 static inline void gen_vfp_##name(int dp, int neon) \
1078 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1080 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1082 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1084 tcg_temp_free_ptr(statusptr); \
1091 #define VFP_GEN_FTOI(name) \
1092 static inline void gen_vfp_##name(int dp, int neon) \
1094 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1096 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1098 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1100 tcg_temp_free_ptr(statusptr); \
1109 #define VFP_GEN_FIX(name) \
1110 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1112 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1113 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1115 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1117 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1119 tcg_temp_free_i32(tmp_shift); \
1120 tcg_temp_free_ptr(statusptr); \
1132 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1135 gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1137 gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1141 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1144 gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1146 gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1151 vfp_reg_offset (int dp, int reg)
1154 return offsetof(CPUARMState, vfp.regs[reg]);
1156 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1157 + offsetof(CPU_DoubleU, l.upper);
1159 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1160 + offsetof(CPU_DoubleU, l.lower);
1164 /* Return the offset of a 32-bit piece of a NEON register.
1165 zero is the least significant end of the register. */
1167 neon_reg_offset (int reg, int n)
1171 return vfp_reg_offset(0, sreg);
1174 static TCGv_i32 neon_load_reg(int reg, int pass)
1176 TCGv_i32 tmp = tcg_temp_new_i32();
1177 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1181 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1183 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1184 tcg_temp_free_i32(var);
1187 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1189 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1194 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1197 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1198 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1199 #define tcg_gen_st_f32 tcg_gen_st_i32
1200 #define tcg_gen_st_f64 tcg_gen_st_i64
1202 static inline void gen_mov_F0_vreg(int dp, int reg)
1205 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1207 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1210 static inline void gen_mov_F1_vreg(int dp, int reg)
1213 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1215 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1218 static inline void gen_mov_vreg_F0(int dp, int reg)
1221 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1223 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1226 #define ARM_CP_RW_BIT (1 << 20)
1228 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1230 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1233 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1235 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1238 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1240 TCGv_i32 var = tcg_temp_new_i32();
1241 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1245 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1247 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1248 tcg_temp_free_i32(var);
1251 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1253 iwmmxt_store_reg(cpu_M0, rn);
1256 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1258 iwmmxt_load_reg(cpu_M0, rn);
1261 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1263 iwmmxt_load_reg(cpu_V1, rn);
1264 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1267 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1269 iwmmxt_load_reg(cpu_V1, rn);
1270 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1273 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1275 iwmmxt_load_reg(cpu_V1, rn);
1276 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1279 #define IWMMXT_OP(name) \
1280 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1282 iwmmxt_load_reg(cpu_V1, rn); \
1283 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1286 #define IWMMXT_OP_ENV(name) \
1287 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1289 iwmmxt_load_reg(cpu_V1, rn); \
1290 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1293 #define IWMMXT_OP_ENV_SIZE(name) \
1294 IWMMXT_OP_ENV(name##b) \
1295 IWMMXT_OP_ENV(name##w) \
1296 IWMMXT_OP_ENV(name##l)
1298 #define IWMMXT_OP_ENV1(name) \
1299 static inline void gen_op_iwmmxt_##name##_M0(void) \
1301 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1315 IWMMXT_OP_ENV_SIZE(unpackl)
1316 IWMMXT_OP_ENV_SIZE(unpackh)
1318 IWMMXT_OP_ENV1(unpacklub)
1319 IWMMXT_OP_ENV1(unpackluw)
1320 IWMMXT_OP_ENV1(unpacklul)
1321 IWMMXT_OP_ENV1(unpackhub)
1322 IWMMXT_OP_ENV1(unpackhuw)
1323 IWMMXT_OP_ENV1(unpackhul)
1324 IWMMXT_OP_ENV1(unpacklsb)
1325 IWMMXT_OP_ENV1(unpacklsw)
1326 IWMMXT_OP_ENV1(unpacklsl)
1327 IWMMXT_OP_ENV1(unpackhsb)
1328 IWMMXT_OP_ENV1(unpackhsw)
1329 IWMMXT_OP_ENV1(unpackhsl)
1331 IWMMXT_OP_ENV_SIZE(cmpeq)
1332 IWMMXT_OP_ENV_SIZE(cmpgtu)
1333 IWMMXT_OP_ENV_SIZE(cmpgts)
1335 IWMMXT_OP_ENV_SIZE(mins)
1336 IWMMXT_OP_ENV_SIZE(minu)
1337 IWMMXT_OP_ENV_SIZE(maxs)
1338 IWMMXT_OP_ENV_SIZE(maxu)
1340 IWMMXT_OP_ENV_SIZE(subn)
1341 IWMMXT_OP_ENV_SIZE(addn)
1342 IWMMXT_OP_ENV_SIZE(subu)
1343 IWMMXT_OP_ENV_SIZE(addu)
1344 IWMMXT_OP_ENV_SIZE(subs)
1345 IWMMXT_OP_ENV_SIZE(adds)
1347 IWMMXT_OP_ENV(avgb0)
1348 IWMMXT_OP_ENV(avgb1)
1349 IWMMXT_OP_ENV(avgw0)
1350 IWMMXT_OP_ENV(avgw1)
1354 IWMMXT_OP_ENV(packuw)
1355 IWMMXT_OP_ENV(packul)
1356 IWMMXT_OP_ENV(packuq)
1357 IWMMXT_OP_ENV(packsw)
1358 IWMMXT_OP_ENV(packsl)
1359 IWMMXT_OP_ENV(packsq)
1361 static void gen_op_iwmmxt_set_mup(void)
1364 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1365 tcg_gen_ori_i32(tmp, tmp, 2);
1366 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1369 static void gen_op_iwmmxt_set_cup(void)
1372 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1373 tcg_gen_ori_i32(tmp, tmp, 1);
1374 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1377 static void gen_op_iwmmxt_setpsr_nz(void)
1379 TCGv_i32 tmp = tcg_temp_new_i32();
1380 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1381 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1384 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1386 iwmmxt_load_reg(cpu_V1, rn);
1387 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1388 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1391 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1398 rd = (insn >> 16) & 0xf;
1399 tmp = load_reg(s, rd);
1401 offset = (insn & 0xff) << ((insn >> 7) & 2);
1402 if (insn & (1 << 24)) {
1404 if (insn & (1 << 23))
1405 tcg_gen_addi_i32(tmp, tmp, offset);
1407 tcg_gen_addi_i32(tmp, tmp, -offset);
1408 tcg_gen_mov_i32(dest, tmp);
1409 if (insn & (1 << 21))
1410 store_reg(s, rd, tmp);
1412 tcg_temp_free_i32(tmp);
1413 } else if (insn & (1 << 21)) {
1415 tcg_gen_mov_i32(dest, tmp);
1416 if (insn & (1 << 23))
1417 tcg_gen_addi_i32(tmp, tmp, offset);
1419 tcg_gen_addi_i32(tmp, tmp, -offset);
1420 store_reg(s, rd, tmp);
1421 } else if (!(insn & (1 << 23)))
1426 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1428 int rd = (insn >> 0) & 0xf;
1431 if (insn & (1 << 8)) {
1432 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1435 tmp = iwmmxt_load_creg(rd);
1438 tmp = tcg_temp_new_i32();
1439 iwmmxt_load_reg(cpu_V0, rd);
1440 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1442 tcg_gen_andi_i32(tmp, tmp, mask);
1443 tcg_gen_mov_i32(dest, tmp);
1444 tcg_temp_free_i32(tmp);
1448 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1449 (ie. an undefined instruction). */
1450 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1453 int rdhi, rdlo, rd0, rd1, i;
1455 TCGv_i32 tmp, tmp2, tmp3;
1457 if ((insn & 0x0e000e00) == 0x0c000000) {
1458 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1460 rdlo = (insn >> 12) & 0xf;
1461 rdhi = (insn >> 16) & 0xf;
1462 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1463 iwmmxt_load_reg(cpu_V0, wrd);
1464 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1465 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1466 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1467 } else { /* TMCRR */
1468 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1469 iwmmxt_store_reg(cpu_V0, wrd);
1470 gen_op_iwmmxt_set_mup();
1475 wrd = (insn >> 12) & 0xf;
1476 addr = tcg_temp_new_i32();
1477 if (gen_iwmmxt_address(s, insn, addr)) {
1478 tcg_temp_free_i32(addr);
1481 if (insn & ARM_CP_RW_BIT) {
1482 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1483 tmp = tcg_temp_new_i32();
1484 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1485 iwmmxt_store_creg(wrd, tmp);
1488 if (insn & (1 << 8)) {
1489 if (insn & (1 << 22)) { /* WLDRD */
1490 gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1492 } else { /* WLDRW wRd */
1493 tmp = tcg_temp_new_i32();
1494 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1497 tmp = tcg_temp_new_i32();
1498 if (insn & (1 << 22)) { /* WLDRH */
1499 gen_aa32_ld16u(tmp, addr, IS_USER(s));
1500 } else { /* WLDRB */
1501 gen_aa32_ld8u(tmp, addr, IS_USER(s));
1505 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1506 tcg_temp_free_i32(tmp);
1508 gen_op_iwmmxt_movq_wRn_M0(wrd);
1511 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1512 tmp = iwmmxt_load_creg(wrd);
1513 gen_aa32_st32(tmp, addr, IS_USER(s));
1515 gen_op_iwmmxt_movq_M0_wRn(wrd);
1516 tmp = tcg_temp_new_i32();
1517 if (insn & (1 << 8)) {
1518 if (insn & (1 << 22)) { /* WSTRD */
1519 gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1520 } else { /* WSTRW wRd */
1521 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1522 gen_aa32_st32(tmp, addr, IS_USER(s));
1525 if (insn & (1 << 22)) { /* WSTRH */
1526 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1527 gen_aa32_st16(tmp, addr, IS_USER(s));
1528 } else { /* WSTRB */
1529 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1530 gen_aa32_st8(tmp, addr, IS_USER(s));
1534 tcg_temp_free_i32(tmp);
1536 tcg_temp_free_i32(addr);
1540 if ((insn & 0x0f000000) != 0x0e000000)
1543 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1544 case 0x000: /* WOR */
1545 wrd = (insn >> 12) & 0xf;
1546 rd0 = (insn >> 0) & 0xf;
1547 rd1 = (insn >> 16) & 0xf;
1548 gen_op_iwmmxt_movq_M0_wRn(rd0);
1549 gen_op_iwmmxt_orq_M0_wRn(rd1);
1550 gen_op_iwmmxt_setpsr_nz();
1551 gen_op_iwmmxt_movq_wRn_M0(wrd);
1552 gen_op_iwmmxt_set_mup();
1553 gen_op_iwmmxt_set_cup();
1555 case 0x011: /* TMCR */
1558 rd = (insn >> 12) & 0xf;
1559 wrd = (insn >> 16) & 0xf;
1561 case ARM_IWMMXT_wCID:
1562 case ARM_IWMMXT_wCASF:
1564 case ARM_IWMMXT_wCon:
1565 gen_op_iwmmxt_set_cup();
1567 case ARM_IWMMXT_wCSSF:
1568 tmp = iwmmxt_load_creg(wrd);
1569 tmp2 = load_reg(s, rd);
1570 tcg_gen_andc_i32(tmp, tmp, tmp2);
1571 tcg_temp_free_i32(tmp2);
1572 iwmmxt_store_creg(wrd, tmp);
1574 case ARM_IWMMXT_wCGR0:
1575 case ARM_IWMMXT_wCGR1:
1576 case ARM_IWMMXT_wCGR2:
1577 case ARM_IWMMXT_wCGR3:
1578 gen_op_iwmmxt_set_cup();
1579 tmp = load_reg(s, rd);
1580 iwmmxt_store_creg(wrd, tmp);
1586 case 0x100: /* WXOR */
1587 wrd = (insn >> 12) & 0xf;
1588 rd0 = (insn >> 0) & 0xf;
1589 rd1 = (insn >> 16) & 0xf;
1590 gen_op_iwmmxt_movq_M0_wRn(rd0);
1591 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1592 gen_op_iwmmxt_setpsr_nz();
1593 gen_op_iwmmxt_movq_wRn_M0(wrd);
1594 gen_op_iwmmxt_set_mup();
1595 gen_op_iwmmxt_set_cup();
1597 case 0x111: /* TMRC */
1600 rd = (insn >> 12) & 0xf;
1601 wrd = (insn >> 16) & 0xf;
1602 tmp = iwmmxt_load_creg(wrd);
1603 store_reg(s, rd, tmp);
1605 case 0x300: /* WANDN */
1606 wrd = (insn >> 12) & 0xf;
1607 rd0 = (insn >> 0) & 0xf;
1608 rd1 = (insn >> 16) & 0xf;
1609 gen_op_iwmmxt_movq_M0_wRn(rd0);
1610 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1611 gen_op_iwmmxt_andq_M0_wRn(rd1);
1612 gen_op_iwmmxt_setpsr_nz();
1613 gen_op_iwmmxt_movq_wRn_M0(wrd);
1614 gen_op_iwmmxt_set_mup();
1615 gen_op_iwmmxt_set_cup();
1617 case 0x200: /* WAND */
1618 wrd = (insn >> 12) & 0xf;
1619 rd0 = (insn >> 0) & 0xf;
1620 rd1 = (insn >> 16) & 0xf;
1621 gen_op_iwmmxt_movq_M0_wRn(rd0);
1622 gen_op_iwmmxt_andq_M0_wRn(rd1);
1623 gen_op_iwmmxt_setpsr_nz();
1624 gen_op_iwmmxt_movq_wRn_M0(wrd);
1625 gen_op_iwmmxt_set_mup();
1626 gen_op_iwmmxt_set_cup();
1628 case 0x810: case 0xa10: /* WMADD */
1629 wrd = (insn >> 12) & 0xf;
1630 rd0 = (insn >> 0) & 0xf;
1631 rd1 = (insn >> 16) & 0xf;
1632 gen_op_iwmmxt_movq_M0_wRn(rd0);
1633 if (insn & (1 << 21))
1634 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1636 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1637 gen_op_iwmmxt_movq_wRn_M0(wrd);
1638 gen_op_iwmmxt_set_mup();
1640 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1641 wrd = (insn >> 12) & 0xf;
1642 rd0 = (insn >> 16) & 0xf;
1643 rd1 = (insn >> 0) & 0xf;
1644 gen_op_iwmmxt_movq_M0_wRn(rd0);
1645 switch ((insn >> 22) & 3) {
1647 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1650 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1653 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1658 gen_op_iwmmxt_movq_wRn_M0(wrd);
1659 gen_op_iwmmxt_set_mup();
1660 gen_op_iwmmxt_set_cup();
1662 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1663 wrd = (insn >> 12) & 0xf;
1664 rd0 = (insn >> 16) & 0xf;
1665 rd1 = (insn >> 0) & 0xf;
1666 gen_op_iwmmxt_movq_M0_wRn(rd0);
1667 switch ((insn >> 22) & 3) {
1669 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1672 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1675 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1680 gen_op_iwmmxt_movq_wRn_M0(wrd);
1681 gen_op_iwmmxt_set_mup();
1682 gen_op_iwmmxt_set_cup();
1684 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1685 wrd = (insn >> 12) & 0xf;
1686 rd0 = (insn >> 16) & 0xf;
1687 rd1 = (insn >> 0) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0);
1689 if (insn & (1 << 22))
1690 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1692 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1693 if (!(insn & (1 << 20)))
1694 gen_op_iwmmxt_addl_M0_wRn(wrd);
1695 gen_op_iwmmxt_movq_wRn_M0(wrd);
1696 gen_op_iwmmxt_set_mup();
1698 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1699 wrd = (insn >> 12) & 0xf;
1700 rd0 = (insn >> 16) & 0xf;
1701 rd1 = (insn >> 0) & 0xf;
1702 gen_op_iwmmxt_movq_M0_wRn(rd0);
1703 if (insn & (1 << 21)) {
1704 if (insn & (1 << 20))
1705 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1707 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1709 if (insn & (1 << 20))
1710 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1712 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1714 gen_op_iwmmxt_movq_wRn_M0(wrd);
1715 gen_op_iwmmxt_set_mup();
1717 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1718 wrd = (insn >> 12) & 0xf;
1719 rd0 = (insn >> 16) & 0xf;
1720 rd1 = (insn >> 0) & 0xf;
1721 gen_op_iwmmxt_movq_M0_wRn(rd0);
1722 if (insn & (1 << 21))
1723 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1725 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1726 if (!(insn & (1 << 20))) {
1727 iwmmxt_load_reg(cpu_V1, wrd);
1728 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1730 gen_op_iwmmxt_movq_wRn_M0(wrd);
1731 gen_op_iwmmxt_set_mup();
1733 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1734 wrd = (insn >> 12) & 0xf;
1735 rd0 = (insn >> 16) & 0xf;
1736 rd1 = (insn >> 0) & 0xf;
1737 gen_op_iwmmxt_movq_M0_wRn(rd0);
1738 switch ((insn >> 22) & 3) {
1740 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1743 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1746 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1751 gen_op_iwmmxt_movq_wRn_M0(wrd);
1752 gen_op_iwmmxt_set_mup();
1753 gen_op_iwmmxt_set_cup();
1755 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1756 wrd = (insn >> 12) & 0xf;
1757 rd0 = (insn >> 16) & 0xf;
1758 rd1 = (insn >> 0) & 0xf;
1759 gen_op_iwmmxt_movq_M0_wRn(rd0);
1760 if (insn & (1 << 22)) {
1761 if (insn & (1 << 20))
1762 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1764 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1766 if (insn & (1 << 20))
1767 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1769 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1771 gen_op_iwmmxt_movq_wRn_M0(wrd);
1772 gen_op_iwmmxt_set_mup();
1773 gen_op_iwmmxt_set_cup();
1775 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1776 wrd = (insn >> 12) & 0xf;
1777 rd0 = (insn >> 16) & 0xf;
1778 rd1 = (insn >> 0) & 0xf;
1779 gen_op_iwmmxt_movq_M0_wRn(rd0);
1780 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1781 tcg_gen_andi_i32(tmp, tmp, 7);
1782 iwmmxt_load_reg(cpu_V1, rd1);
1783 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1784 tcg_temp_free_i32(tmp);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd);
1786 gen_op_iwmmxt_set_mup();
1788 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1789 if (((insn >> 6) & 3) == 3)
1791 rd = (insn >> 12) & 0xf;
1792 wrd = (insn >> 16) & 0xf;
1793 tmp = load_reg(s, rd);
1794 gen_op_iwmmxt_movq_M0_wRn(wrd);
1795 switch ((insn >> 6) & 3) {
1797 tmp2 = tcg_const_i32(0xff);
1798 tmp3 = tcg_const_i32((insn & 7) << 3);
1801 tmp2 = tcg_const_i32(0xffff);
1802 tmp3 = tcg_const_i32((insn & 3) << 4);
1805 tmp2 = tcg_const_i32(0xffffffff);
1806 tmp3 = tcg_const_i32((insn & 1) << 5);
1809 TCGV_UNUSED_I32(tmp2);
1810 TCGV_UNUSED_I32(tmp3);
1812 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1813 tcg_temp_free_i32(tmp3);
1814 tcg_temp_free_i32(tmp2);
1815 tcg_temp_free_i32(tmp);
1816 gen_op_iwmmxt_movq_wRn_M0(wrd);
1817 gen_op_iwmmxt_set_mup();
1819 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1820 rd = (insn >> 12) & 0xf;
1821 wrd = (insn >> 16) & 0xf;
1822 if (rd == 15 || ((insn >> 22) & 3) == 3)
1824 gen_op_iwmmxt_movq_M0_wRn(wrd);
1825 tmp = tcg_temp_new_i32();
1826 switch ((insn >> 22) & 3) {
1828 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1829 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1831 tcg_gen_ext8s_i32(tmp, tmp);
1833 tcg_gen_andi_i32(tmp, tmp, 0xff);
1837 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1838 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1840 tcg_gen_ext16s_i32(tmp, tmp);
1842 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1846 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1847 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1850 store_reg(s, rd, tmp);
1852 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1853 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1855 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1856 switch ((insn >> 22) & 3) {
1858 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1861 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1864 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1867 tcg_gen_shli_i32(tmp, tmp, 28);
1869 tcg_temp_free_i32(tmp);
1871 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1872 if (((insn >> 6) & 3) == 3)
1874 rd = (insn >> 12) & 0xf;
1875 wrd = (insn >> 16) & 0xf;
1876 tmp = load_reg(s, rd);
1877 switch ((insn >> 6) & 3) {
1879 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1882 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1885 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1888 tcg_temp_free_i32(tmp);
1889 gen_op_iwmmxt_movq_wRn_M0(wrd);
1890 gen_op_iwmmxt_set_mup();
1892 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1893 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1895 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1896 tmp2 = tcg_temp_new_i32();
1897 tcg_gen_mov_i32(tmp2, tmp);
1898 switch ((insn >> 22) & 3) {
1900 for (i = 0; i < 7; i ++) {
1901 tcg_gen_shli_i32(tmp2, tmp2, 4);
1902 tcg_gen_and_i32(tmp, tmp, tmp2);
1906 for (i = 0; i < 3; i ++) {
1907 tcg_gen_shli_i32(tmp2, tmp2, 8);
1908 tcg_gen_and_i32(tmp, tmp, tmp2);
1912 tcg_gen_shli_i32(tmp2, tmp2, 16);
1913 tcg_gen_and_i32(tmp, tmp, tmp2);
1917 tcg_temp_free_i32(tmp2);
1918 tcg_temp_free_i32(tmp);
1920 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1921 wrd = (insn >> 12) & 0xf;
1922 rd0 = (insn >> 16) & 0xf;
1923 gen_op_iwmmxt_movq_M0_wRn(rd0);
1924 switch ((insn >> 22) & 3) {
1926 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1929 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1932 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd);
1938 gen_op_iwmmxt_set_mup();
1940 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1941 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1943 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1944 tmp2 = tcg_temp_new_i32();
1945 tcg_gen_mov_i32(tmp2, tmp);
1946 switch ((insn >> 22) & 3) {
1948 for (i = 0; i < 7; i ++) {
1949 tcg_gen_shli_i32(tmp2, tmp2, 4);
1950 tcg_gen_or_i32(tmp, tmp, tmp2);
1954 for (i = 0; i < 3; i ++) {
1955 tcg_gen_shli_i32(tmp2, tmp2, 8);
1956 tcg_gen_or_i32(tmp, tmp, tmp2);
1960 tcg_gen_shli_i32(tmp2, tmp2, 16);
1961 tcg_gen_or_i32(tmp, tmp, tmp2);
1965 tcg_temp_free_i32(tmp2);
1966 tcg_temp_free_i32(tmp);
1968 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1969 rd = (insn >> 12) & 0xf;
1970 rd0 = (insn >> 16) & 0xf;
1971 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1973 gen_op_iwmmxt_movq_M0_wRn(rd0);
1974 tmp = tcg_temp_new_i32();
1975 switch ((insn >> 22) & 3) {
1977 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1980 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1983 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1986 store_reg(s, rd, tmp);
1988 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1989 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1990 wrd = (insn >> 12) & 0xf;
1991 rd0 = (insn >> 16) & 0xf;
1992 rd1 = (insn >> 0) & 0xf;
1993 gen_op_iwmmxt_movq_M0_wRn(rd0);
1994 switch ((insn >> 22) & 3) {
1996 if (insn & (1 << 21))
1997 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1999 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2002 if (insn & (1 << 21))
2003 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2005 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2008 if (insn & (1 << 21))
2009 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2011 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2016 gen_op_iwmmxt_movq_wRn_M0(wrd);
2017 gen_op_iwmmxt_set_mup();
2018 gen_op_iwmmxt_set_cup();
2020 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2021 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2022 wrd = (insn >> 12) & 0xf;
2023 rd0 = (insn >> 16) & 0xf;
2024 gen_op_iwmmxt_movq_M0_wRn(rd0);
2025 switch ((insn >> 22) & 3) {
2027 if (insn & (1 << 21))
2028 gen_op_iwmmxt_unpacklsb_M0();
2030 gen_op_iwmmxt_unpacklub_M0();
2033 if (insn & (1 << 21))
2034 gen_op_iwmmxt_unpacklsw_M0();
2036 gen_op_iwmmxt_unpackluw_M0();
2039 if (insn & (1 << 21))
2040 gen_op_iwmmxt_unpacklsl_M0();
2042 gen_op_iwmmxt_unpacklul_M0();
2047 gen_op_iwmmxt_movq_wRn_M0(wrd);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2051 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2052 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2053 wrd = (insn >> 12) & 0xf;
2054 rd0 = (insn >> 16) & 0xf;
2055 gen_op_iwmmxt_movq_M0_wRn(rd0);
2056 switch ((insn >> 22) & 3) {
2058 if (insn & (1 << 21))
2059 gen_op_iwmmxt_unpackhsb_M0();
2061 gen_op_iwmmxt_unpackhub_M0();
2064 if (insn & (1 << 21))
2065 gen_op_iwmmxt_unpackhsw_M0();
2067 gen_op_iwmmxt_unpackhuw_M0();
2070 if (insn & (1 << 21))
2071 gen_op_iwmmxt_unpackhsl_M0();
2073 gen_op_iwmmxt_unpackhul_M0();
2078 gen_op_iwmmxt_movq_wRn_M0(wrd);
2079 gen_op_iwmmxt_set_mup();
2080 gen_op_iwmmxt_set_cup();
2082 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2083 case 0x214: case 0x614: case 0xa14: case 0xe14:
2084 if (((insn >> 22) & 3) == 0)
2086 wrd = (insn >> 12) & 0xf;
2087 rd0 = (insn >> 16) & 0xf;
2088 gen_op_iwmmxt_movq_M0_wRn(rd0);
2089 tmp = tcg_temp_new_i32();
2090 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2091 tcg_temp_free_i32(tmp);
2094 switch ((insn >> 22) & 3) {
2096 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2099 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2102 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2105 tcg_temp_free_i32(tmp);
2106 gen_op_iwmmxt_movq_wRn_M0(wrd);
2107 gen_op_iwmmxt_set_mup();
2108 gen_op_iwmmxt_set_cup();
2110 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2111 case 0x014: case 0x414: case 0x814: case 0xc14:
2112 if (((insn >> 22) & 3) == 0)
2114 wrd = (insn >> 12) & 0xf;
2115 rd0 = (insn >> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0);
2117 tmp = tcg_temp_new_i32();
2118 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2119 tcg_temp_free_i32(tmp);
2122 switch ((insn >> 22) & 3) {
2124 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2127 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2130 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2133 tcg_temp_free_i32(tmp);
2134 gen_op_iwmmxt_movq_wRn_M0(wrd);
2135 gen_op_iwmmxt_set_mup();
2136 gen_op_iwmmxt_set_cup();
2138 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2139 case 0x114: case 0x514: case 0x914: case 0xd14:
2140 if (((insn >> 22) & 3) == 0)
2142 wrd = (insn >> 12) & 0xf;
2143 rd0 = (insn >> 16) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0);
2145 tmp = tcg_temp_new_i32();
2146 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2147 tcg_temp_free_i32(tmp);
2150 switch ((insn >> 22) & 3) {
2152 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2155 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2158 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2161 tcg_temp_free_i32(tmp);
2162 gen_op_iwmmxt_movq_wRn_M0(wrd);
2163 gen_op_iwmmxt_set_mup();
2164 gen_op_iwmmxt_set_cup();
2166 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2167 case 0x314: case 0x714: case 0xb14: case 0xf14:
2168 if (((insn >> 22) & 3) == 0)
2170 wrd = (insn >> 12) & 0xf;
2171 rd0 = (insn >> 16) & 0xf;
2172 gen_op_iwmmxt_movq_M0_wRn(rd0);
2173 tmp = tcg_temp_new_i32();
2174 switch ((insn >> 22) & 3) {
2176 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2177 tcg_temp_free_i32(tmp);
2180 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2183 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2184 tcg_temp_free_i32(tmp);
2187 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2190 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2191 tcg_temp_free_i32(tmp);
2194 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2197 tcg_temp_free_i32(tmp);
2198 gen_op_iwmmxt_movq_wRn_M0(wrd);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2202 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2203 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2204 wrd = (insn >> 12) & 0xf;
2205 rd0 = (insn >> 16) & 0xf;
2206 rd1 = (insn >> 0) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0);
2208 switch ((insn >> 22) & 3) {
2210 if (insn & (1 << 21))
2211 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2213 gen_op_iwmmxt_minub_M0_wRn(rd1);
2216 if (insn & (1 << 21))
2217 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2219 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2222 if (insn & (1 << 21))
2223 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2225 gen_op_iwmmxt_minul_M0_wRn(rd1);
2230 gen_op_iwmmxt_movq_wRn_M0(wrd);
2231 gen_op_iwmmxt_set_mup();
2233 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2234 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2235 wrd = (insn >> 12) & 0xf;
2236 rd0 = (insn >> 16) & 0xf;
2237 rd1 = (insn >> 0) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0);
2239 switch ((insn >> 22) & 3) {
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2244 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2247 if (insn & (1 << 21))
2248 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2250 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2253 if (insn & (1 << 21))
2254 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2256 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2261 gen_op_iwmmxt_movq_wRn_M0(wrd);
2262 gen_op_iwmmxt_set_mup();
2264 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2265 case 0x402: case 0x502: case 0x602: case 0x702:
2266 wrd = (insn >> 12) & 0xf;
2267 rd0 = (insn >> 16) & 0xf;
2268 rd1 = (insn >> 0) & 0xf;
2269 gen_op_iwmmxt_movq_M0_wRn(rd0);
2270 tmp = tcg_const_i32((insn >> 20) & 3);
2271 iwmmxt_load_reg(cpu_V1, rd1);
2272 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2273 tcg_temp_free_i32(tmp);
2274 gen_op_iwmmxt_movq_wRn_M0(wrd);
2275 gen_op_iwmmxt_set_mup();
2277 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2278 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2279 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2280 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2281 wrd = (insn >> 12) & 0xf;
2282 rd0 = (insn >> 16) & 0xf;
2283 rd1 = (insn >> 0) & 0xf;
2284 gen_op_iwmmxt_movq_M0_wRn(rd0);
2285 switch ((insn >> 20) & 0xf) {
2287 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2290 gen_op_iwmmxt_subub_M0_wRn(rd1);
2293 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2296 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2299 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2302 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2305 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2308 gen_op_iwmmxt_subul_M0_wRn(rd1);
2311 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2316 gen_op_iwmmxt_movq_wRn_M0(wrd);
2317 gen_op_iwmmxt_set_mup();
2318 gen_op_iwmmxt_set_cup();
2320 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2321 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2322 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2323 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2324 wrd = (insn >> 12) & 0xf;
2325 rd0 = (insn >> 16) & 0xf;
2326 gen_op_iwmmxt_movq_M0_wRn(rd0);
2327 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2328 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2329 tcg_temp_free_i32(tmp);
2330 gen_op_iwmmxt_movq_wRn_M0(wrd);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2334 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2335 case 0x418: case 0x518: case 0x618: case 0x718:
2336 case 0x818: case 0x918: case 0xa18: case 0xb18:
2337 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2338 wrd = (insn >> 12) & 0xf;
2339 rd0 = (insn >> 16) & 0xf;
2340 rd1 = (insn >> 0) & 0xf;
2341 gen_op_iwmmxt_movq_M0_wRn(rd0);
2342 switch ((insn >> 20) & 0xf) {
2344 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2347 gen_op_iwmmxt_addub_M0_wRn(rd1);
2350 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2353 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2356 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2359 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2362 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2365 gen_op_iwmmxt_addul_M0_wRn(rd1);
2368 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2373 gen_op_iwmmxt_movq_wRn_M0(wrd);
2374 gen_op_iwmmxt_set_mup();
2375 gen_op_iwmmxt_set_cup();
2377 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2378 case 0x408: case 0x508: case 0x608: case 0x708:
2379 case 0x808: case 0x908: case 0xa08: case 0xb08:
2380 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2381 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2383 wrd = (insn >> 12) & 0xf;
2384 rd0 = (insn >> 16) & 0xf;
2385 rd1 = (insn >> 0) & 0xf;
2386 gen_op_iwmmxt_movq_M0_wRn(rd0);
2387 switch ((insn >> 22) & 3) {
2389 if (insn & (1 << 21))
2390 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2392 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2395 if (insn & (1 << 21))
2396 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2398 gen_op_iwmmxt_packul_M0_wRn(rd1);
2401 if (insn & (1 << 21))
2402 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2404 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2407 gen_op_iwmmxt_movq_wRn_M0(wrd);
2408 gen_op_iwmmxt_set_mup();
2409 gen_op_iwmmxt_set_cup();
2411 case 0x201: case 0x203: case 0x205: case 0x207:
2412 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2413 case 0x211: case 0x213: case 0x215: case 0x217:
2414 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2415 wrd = (insn >> 5) & 0xf;
2416 rd0 = (insn >> 12) & 0xf;
2417 rd1 = (insn >> 0) & 0xf;
2418 if (rd0 == 0xf || rd1 == 0xf)
2420 gen_op_iwmmxt_movq_M0_wRn(wrd);
2421 tmp = load_reg(s, rd0);
2422 tmp2 = load_reg(s, rd1);
2423 switch ((insn >> 16) & 0xf) {
2424 case 0x0: /* TMIA */
2425 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2427 case 0x8: /* TMIAPH */
2428 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2430 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2431 if (insn & (1 << 16))
2432 tcg_gen_shri_i32(tmp, tmp, 16);
2433 if (insn & (1 << 17))
2434 tcg_gen_shri_i32(tmp2, tmp2, 16);
2435 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2438 tcg_temp_free_i32(tmp2);
2439 tcg_temp_free_i32(tmp);
2442 tcg_temp_free_i32(tmp2);
2443 tcg_temp_free_i32(tmp);
2444 gen_op_iwmmxt_movq_wRn_M0(wrd);
2445 gen_op_iwmmxt_set_mup();
2454 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2455 (ie. an undefined instruction). */
2456 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2458 int acc, rd0, rd1, rdhi, rdlo;
2461 if ((insn & 0x0ff00f10) == 0x0e200010) {
2462 /* Multiply with Internal Accumulate Format */
2463 rd0 = (insn >> 12) & 0xf;
2465 acc = (insn >> 5) & 7;
2470 tmp = load_reg(s, rd0);
2471 tmp2 = load_reg(s, rd1);
2472 switch ((insn >> 16) & 0xf) {
2474 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2476 case 0x8: /* MIAPH */
2477 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2479 case 0xc: /* MIABB */
2480 case 0xd: /* MIABT */
2481 case 0xe: /* MIATB */
2482 case 0xf: /* MIATT */
2483 if (insn & (1 << 16))
2484 tcg_gen_shri_i32(tmp, tmp, 16);
2485 if (insn & (1 << 17))
2486 tcg_gen_shri_i32(tmp2, tmp2, 16);
2487 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2492 tcg_temp_free_i32(tmp2);
2493 tcg_temp_free_i32(tmp);
2495 gen_op_iwmmxt_movq_wRn_M0(acc);
2499 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2500 /* Internal Accumulator Access Format */
2501 rdhi = (insn >> 16) & 0xf;
2502 rdlo = (insn >> 12) & 0xf;
2508 if (insn & ARM_CP_RW_BIT) { /* MRA */
2509 iwmmxt_load_reg(cpu_V0, acc);
2510 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2511 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2512 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2513 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2515 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2516 iwmmxt_store_reg(cpu_V0, acc);
2524 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2525 #define VFP_SREG(insn, bigbit, smallbit) \
2526 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2527 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2528 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2529 reg = (((insn) >> (bigbit)) & 0x0f) \
2530 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2532 if (insn & (1 << (smallbit))) \
2534 reg = ((insn) >> (bigbit)) & 0x0f; \
2537 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2538 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2539 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2540 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2541 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2542 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2544 /* Move between integer and VFP cores. */
2545 static TCGv_i32 gen_vfp_mrs(void)
2547 TCGv_i32 tmp = tcg_temp_new_i32();
2548 tcg_gen_mov_i32(tmp, cpu_F0s);
2552 static void gen_vfp_msr(TCGv_i32 tmp)
2554 tcg_gen_mov_i32(cpu_F0s, tmp);
2555 tcg_temp_free_i32(tmp);
2558 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2560 TCGv_i32 tmp = tcg_temp_new_i32();
2562 tcg_gen_shri_i32(var, var, shift);
2563 tcg_gen_ext8u_i32(var, var);
2564 tcg_gen_shli_i32(tmp, var, 8);
2565 tcg_gen_or_i32(var, var, tmp);
2566 tcg_gen_shli_i32(tmp, var, 16);
2567 tcg_gen_or_i32(var, var, tmp);
2568 tcg_temp_free_i32(tmp);
2571 static void gen_neon_dup_low16(TCGv_i32 var)
2573 TCGv_i32 tmp = tcg_temp_new_i32();
2574 tcg_gen_ext16u_i32(var, var);
2575 tcg_gen_shli_i32(tmp, var, 16);
2576 tcg_gen_or_i32(var, var, tmp);
2577 tcg_temp_free_i32(tmp);
2580 static void gen_neon_dup_high16(TCGv_i32 var)
2582 TCGv_i32 tmp = tcg_temp_new_i32();
2583 tcg_gen_andi_i32(var, var, 0xffff0000);
2584 tcg_gen_shri_i32(tmp, var, 16);
2585 tcg_gen_or_i32(var, var, tmp);
2586 tcg_temp_free_i32(tmp);
2589 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2591 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2592 TCGv_i32 tmp = tcg_temp_new_i32();
2595 gen_aa32_ld8u(tmp, addr, IS_USER(s));
2596 gen_neon_dup_u8(tmp, 0);
2599 gen_aa32_ld16u(tmp, addr, IS_USER(s));
2600 gen_neon_dup_low16(tmp);
2603 gen_aa32_ld32u(tmp, addr, IS_USER(s));
2605 default: /* Avoid compiler warnings. */
2611 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2614 uint32_t cc = extract32(insn, 20, 2);
2617 TCGv_i64 frn, frm, dest;
2618 TCGv_i64 tmp, zero, zf, nf, vf;
2620 zero = tcg_const_i64(0);
2622 frn = tcg_temp_new_i64();
2623 frm = tcg_temp_new_i64();
2624 dest = tcg_temp_new_i64();
2626 zf = tcg_temp_new_i64();
2627 nf = tcg_temp_new_i64();
2628 vf = tcg_temp_new_i64();
2630 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2631 tcg_gen_ext_i32_i64(nf, cpu_NF);
2632 tcg_gen_ext_i32_i64(vf, cpu_VF);
2634 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2635 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2638 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2642 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2645 case 2: /* ge: N == V -> N ^ V == 0 */
2646 tmp = tcg_temp_new_i64();
2647 tcg_gen_xor_i64(tmp, vf, nf);
2648 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2650 tcg_temp_free_i64(tmp);
2652 case 3: /* gt: !Z && N == V */
2653 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2655 tmp = tcg_temp_new_i64();
2656 tcg_gen_xor_i64(tmp, vf, nf);
2657 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2659 tcg_temp_free_i64(tmp);
2662 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2663 tcg_temp_free_i64(frn);
2664 tcg_temp_free_i64(frm);
2665 tcg_temp_free_i64(dest);
2667 tcg_temp_free_i64(zf);
2668 tcg_temp_free_i64(nf);
2669 tcg_temp_free_i64(vf);
2671 tcg_temp_free_i64(zero);
2673 TCGv_i32 frn, frm, dest;
2676 zero = tcg_const_i32(0);
2678 frn = tcg_temp_new_i32();
2679 frm = tcg_temp_new_i32();
2680 dest = tcg_temp_new_i32();
2681 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2682 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2685 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2689 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2692 case 2: /* ge: N == V -> N ^ V == 0 */
2693 tmp = tcg_temp_new_i32();
2694 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2695 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2697 tcg_temp_free_i32(tmp);
2699 case 3: /* gt: !Z && N == V */
2700 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2702 tmp = tcg_temp_new_i32();
2703 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2704 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2706 tcg_temp_free_i32(tmp);
2709 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2710 tcg_temp_free_i32(frn);
2711 tcg_temp_free_i32(frm);
2712 tcg_temp_free_i32(dest);
2714 tcg_temp_free_i32(zero);
2720 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2721 uint32_t rm, uint32_t dp)
2723 uint32_t vmin = extract32(insn, 6, 1);
2724 TCGv_ptr fpst = get_fpstatus_ptr(0);
2727 TCGv_i64 frn, frm, dest;
2729 frn = tcg_temp_new_i64();
2730 frm = tcg_temp_new_i64();
2731 dest = tcg_temp_new_i64();
2733 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2734 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2736 gen_helper_vfp_minnmd(dest, frn, frm, fpst);
2738 gen_helper_vfp_maxnmd(dest, frn, frm, fpst);
2740 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2741 tcg_temp_free_i64(frn);
2742 tcg_temp_free_i64(frm);
2743 tcg_temp_free_i64(dest);
2745 TCGv_i32 frn, frm, dest;
2747 frn = tcg_temp_new_i32();
2748 frm = tcg_temp_new_i32();
2749 dest = tcg_temp_new_i32();
2751 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2752 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2754 gen_helper_vfp_minnms(dest, frn, frm, fpst);
2756 gen_helper_vfp_maxnms(dest, frn, frm, fpst);
2758 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2759 tcg_temp_free_i32(frn);
2760 tcg_temp_free_i32(frm);
2761 tcg_temp_free_i32(dest);
2764 tcg_temp_free_ptr(fpst);
2768 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2770 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2772 if (!arm_feature(env, ARM_FEATURE_V8)) {
2777 VFP_DREG_D(rd, insn);
2778 VFP_DREG_N(rn, insn);
2779 VFP_DREG_M(rm, insn);
2781 rd = VFP_SREG_D(insn);
2782 rn = VFP_SREG_N(insn);
2783 rm = VFP_SREG_M(insn);
2786 if ((insn & 0x0f800e50) == 0x0e000a00) {
2787 return handle_vsel(insn, rd, rn, rm, dp);
2788 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2789 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2794 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2795 (ie. an undefined instruction). */
2796 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2798 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2804 if (!arm_feature(env, ARM_FEATURE_VFP))
2807 if (!s->vfp_enabled) {
2808 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2809 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2811 rn = (insn >> 16) & 0xf;
2812 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2813 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2817 if (extract32(insn, 28, 4) == 0xf) {
2818 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2819 * only used in v8 and above.
2821 return disas_vfp_v8_insn(env, s, insn);
2824 dp = ((insn & 0xf00) == 0xb00);
2825 switch ((insn >> 24) & 0xf) {
2827 if (insn & (1 << 4)) {
2828 /* single register transfer */
2829 rd = (insn >> 12) & 0xf;
2834 VFP_DREG_N(rn, insn);
2837 if (insn & 0x00c00060
2838 && !arm_feature(env, ARM_FEATURE_NEON))
2841 pass = (insn >> 21) & 1;
2842 if (insn & (1 << 22)) {
2844 offset = ((insn >> 5) & 3) * 8;
2845 } else if (insn & (1 << 5)) {
2847 offset = (insn & (1 << 6)) ? 16 : 0;
2852 if (insn & ARM_CP_RW_BIT) {
2854 tmp = neon_load_reg(rn, pass);
2858 tcg_gen_shri_i32(tmp, tmp, offset);
2859 if (insn & (1 << 23))
2865 if (insn & (1 << 23)) {
2867 tcg_gen_shri_i32(tmp, tmp, 16);
2873 tcg_gen_sari_i32(tmp, tmp, 16);
2882 store_reg(s, rd, tmp);
2885 tmp = load_reg(s, rd);
2886 if (insn & (1 << 23)) {
2889 gen_neon_dup_u8(tmp, 0);
2890 } else if (size == 1) {
2891 gen_neon_dup_low16(tmp);
2893 for (n = 0; n <= pass * 2; n++) {
2894 tmp2 = tcg_temp_new_i32();
2895 tcg_gen_mov_i32(tmp2, tmp);
2896 neon_store_reg(rn, n, tmp2);
2898 neon_store_reg(rn, n, tmp);
2903 tmp2 = neon_load_reg(rn, pass);
2904 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2905 tcg_temp_free_i32(tmp2);
2908 tmp2 = neon_load_reg(rn, pass);
2909 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2910 tcg_temp_free_i32(tmp2);
2915 neon_store_reg(rn, pass, tmp);
2919 if ((insn & 0x6f) != 0x00)
2921 rn = VFP_SREG_N(insn);
2922 if (insn & ARM_CP_RW_BIT) {
2924 if (insn & (1 << 21)) {
2925 /* system register */
2930 /* VFP2 allows access to FSID from userspace.
2931 VFP3 restricts all id registers to privileged
2934 && arm_feature(env, ARM_FEATURE_VFP3))
2936 tmp = load_cpu_field(vfp.xregs[rn]);
2941 tmp = load_cpu_field(vfp.xregs[rn]);
2943 case ARM_VFP_FPINST:
2944 case ARM_VFP_FPINST2:
2945 /* Not present in VFP3. */
2947 || arm_feature(env, ARM_FEATURE_VFP3))
2949 tmp = load_cpu_field(vfp.xregs[rn]);
2953 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2954 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2956 tmp = tcg_temp_new_i32();
2957 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2963 || !arm_feature(env, ARM_FEATURE_MVFR))
2965 tmp = load_cpu_field(vfp.xregs[rn]);
2971 gen_mov_F0_vreg(0, rn);
2972 tmp = gen_vfp_mrs();
2975 /* Set the 4 flag bits in the CPSR. */
2977 tcg_temp_free_i32(tmp);
2979 store_reg(s, rd, tmp);
2983 if (insn & (1 << 21)) {
2985 /* system register */
2990 /* Writes are ignored. */
2993 tmp = load_reg(s, rd);
2994 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2995 tcg_temp_free_i32(tmp);
3001 /* TODO: VFP subarchitecture support.
3002 * For now, keep the EN bit only */
3003 tmp = load_reg(s, rd);
3004 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3005 store_cpu_field(tmp, vfp.xregs[rn]);
3008 case ARM_VFP_FPINST:
3009 case ARM_VFP_FPINST2:
3010 tmp = load_reg(s, rd);
3011 store_cpu_field(tmp, vfp.xregs[rn]);
3017 tmp = load_reg(s, rd);
3019 gen_mov_vreg_F0(0, rn);
3024 /* data processing */
3025 /* The opcode is in bits 23, 21, 20 and 6. */
3026 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3030 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3032 /* rn is register number */
3033 VFP_DREG_N(rn, insn);
3036 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3037 /* Integer or single precision destination. */
3038 rd = VFP_SREG_D(insn);
3040 VFP_DREG_D(rd, insn);
3043 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3044 /* VCVT from int is always from S reg regardless of dp bit.
3045 * VCVT with immediate frac_bits has same format as SREG_M
3047 rm = VFP_SREG_M(insn);
3049 VFP_DREG_M(rm, insn);
3052 rn = VFP_SREG_N(insn);
3053 if (op == 15 && rn == 15) {
3054 /* Double precision destination. */
3055 VFP_DREG_D(rd, insn);
3057 rd = VFP_SREG_D(insn);
3059 /* NB that we implicitly rely on the encoding for the frac_bits
3060 * in VCVT of fixed to float being the same as that of an SREG_M
3062 rm = VFP_SREG_M(insn);
3065 veclen = s->vec_len;
3066 if (op == 15 && rn > 3)
3069 /* Shut up compiler warnings. */
3080 /* Figure out what type of vector operation this is. */
3081 if ((rd & bank_mask) == 0) {
3086 delta_d = (s->vec_stride >> 1) + 1;
3088 delta_d = s->vec_stride + 1;
3090 if ((rm & bank_mask) == 0) {
3091 /* mixed scalar/vector */
3100 /* Load the initial operands. */
3105 /* Integer source */
3106 gen_mov_F0_vreg(0, rm);
3111 gen_mov_F0_vreg(dp, rd);
3112 gen_mov_F1_vreg(dp, rm);
3116 /* Compare with zero */
3117 gen_mov_F0_vreg(dp, rd);
3128 /* Source and destination the same. */
3129 gen_mov_F0_vreg(dp, rd);
3135 /* VCVTB, VCVTT: only present with the halfprec extension,
3136 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3138 if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3141 /* Otherwise fall through */
3143 /* One source operand. */
3144 gen_mov_F0_vreg(dp, rm);
3148 /* Two source operands. */
3149 gen_mov_F0_vreg(dp, rn);
3150 gen_mov_F1_vreg(dp, rm);
3154 /* Perform the calculation. */
3156 case 0: /* VMLA: fd + (fn * fm) */
3157 /* Note that order of inputs to the add matters for NaNs */
3159 gen_mov_F0_vreg(dp, rd);
3162 case 1: /* VMLS: fd + -(fn * fm) */
3165 gen_mov_F0_vreg(dp, rd);
3168 case 2: /* VNMLS: -fd + (fn * fm) */
3169 /* Note that it isn't valid to replace (-A + B) with (B - A)
3170 * or similar plausible looking simplifications
3171 * because this will give wrong results for NaNs.
3174 gen_mov_F0_vreg(dp, rd);
3178 case 3: /* VNMLA: -fd + -(fn * fm) */
3181 gen_mov_F0_vreg(dp, rd);
3185 case 4: /* mul: fn * fm */
3188 case 5: /* nmul: -(fn * fm) */
3192 case 6: /* add: fn + fm */
3195 case 7: /* sub: fn - fm */
3198 case 8: /* div: fn / fm */
3201 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3202 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3203 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3204 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3205 /* These are fused multiply-add, and must be done as one
3206 * floating point operation with no rounding between the
3207 * multiplication and addition steps.
3208 * NB that doing the negations here as separate steps is
3209 * correct : an input NaN should come out with its sign bit
3210 * flipped if it is a negated-input.
3212 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3220 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3222 frd = tcg_temp_new_i64();
3223 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3226 gen_helper_vfp_negd(frd, frd);
3228 fpst = get_fpstatus_ptr(0);
3229 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3230 cpu_F1d, frd, fpst);
3231 tcg_temp_free_ptr(fpst);
3232 tcg_temp_free_i64(frd);
3238 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3240 frd = tcg_temp_new_i32();
3241 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3243 gen_helper_vfp_negs(frd, frd);
3245 fpst = get_fpstatus_ptr(0);
3246 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3247 cpu_F1s, frd, fpst);
3248 tcg_temp_free_ptr(fpst);
3249 tcg_temp_free_i32(frd);
3252 case 14: /* fconst */
3253 if (!arm_feature(env, ARM_FEATURE_VFP3))
3256 n = (insn << 12) & 0x80000000;
3257 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3264 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3271 tcg_gen_movi_i32(cpu_F0s, n);
3274 case 15: /* extension space */
3288 case 4: /* vcvtb.f32.f16 */
3289 tmp = gen_vfp_mrs();
3290 tcg_gen_ext16u_i32(tmp, tmp);
3291 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3292 tcg_temp_free_i32(tmp);
3294 case 5: /* vcvtt.f32.f16 */
3295 tmp = gen_vfp_mrs();
3296 tcg_gen_shri_i32(tmp, tmp, 16);
3297 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3298 tcg_temp_free_i32(tmp);
3300 case 6: /* vcvtb.f16.f32 */
3301 tmp = tcg_temp_new_i32();
3302 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3303 gen_mov_F0_vreg(0, rd);
3304 tmp2 = gen_vfp_mrs();
3305 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3306 tcg_gen_or_i32(tmp, tmp, tmp2);
3307 tcg_temp_free_i32(tmp2);
3310 case 7: /* vcvtt.f16.f32 */
3311 tmp = tcg_temp_new_i32();
3312 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3313 tcg_gen_shli_i32(tmp, tmp, 16);
3314 gen_mov_F0_vreg(0, rd);
3315 tmp2 = gen_vfp_mrs();
3316 tcg_gen_ext16u_i32(tmp2, tmp2);
3317 tcg_gen_or_i32(tmp, tmp, tmp2);
3318 tcg_temp_free_i32(tmp2);
3330 case 11: /* cmpez */
3334 case 15: /* single<->double conversion */
3336 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3338 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3340 case 16: /* fuito */
3341 gen_vfp_uito(dp, 0);
3343 case 17: /* fsito */
3344 gen_vfp_sito(dp, 0);
3346 case 20: /* fshto */
3347 if (!arm_feature(env, ARM_FEATURE_VFP3))
3349 gen_vfp_shto(dp, 16 - rm, 0);
3351 case 21: /* fslto */
3352 if (!arm_feature(env, ARM_FEATURE_VFP3))
3354 gen_vfp_slto(dp, 32 - rm, 0);
3356 case 22: /* fuhto */
3357 if (!arm_feature(env, ARM_FEATURE_VFP3))
3359 gen_vfp_uhto(dp, 16 - rm, 0);
3361 case 23: /* fulto */
3362 if (!arm_feature(env, ARM_FEATURE_VFP3))
3364 gen_vfp_ulto(dp, 32 - rm, 0);
3366 case 24: /* ftoui */
3367 gen_vfp_toui(dp, 0);
3369 case 25: /* ftouiz */
3370 gen_vfp_touiz(dp, 0);
3372 case 26: /* ftosi */
3373 gen_vfp_tosi(dp, 0);
3375 case 27: /* ftosiz */
3376 gen_vfp_tosiz(dp, 0);
3378 case 28: /* ftosh */
3379 if (!arm_feature(env, ARM_FEATURE_VFP3))
3381 gen_vfp_tosh(dp, 16 - rm, 0);
3383 case 29: /* ftosl */
3384 if (!arm_feature(env, ARM_FEATURE_VFP3))
3386 gen_vfp_tosl(dp, 32 - rm, 0);
3388 case 30: /* ftouh */
3389 if (!arm_feature(env, ARM_FEATURE_VFP3))
3391 gen_vfp_touh(dp, 16 - rm, 0);
3393 case 31: /* ftoul */
3394 if (!arm_feature(env, ARM_FEATURE_VFP3))
3396 gen_vfp_toul(dp, 32 - rm, 0);
3398 default: /* undefined */
3402 default: /* undefined */
3406 /* Write back the result. */
3407 if (op == 15 && (rn >= 8 && rn <= 11))
3408 ; /* Comparison, do nothing. */
3409 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3410 /* VCVT double to int: always integer result. */
3411 gen_mov_vreg_F0(0, rd);
3412 else if (op == 15 && rn == 15)
3414 gen_mov_vreg_F0(!dp, rd);
3416 gen_mov_vreg_F0(dp, rd);
3418 /* break out of the loop if we have finished */
3422 if (op == 15 && delta_m == 0) {
3423 /* single source one-many */
3425 rd = ((rd + delta_d) & (bank_mask - 1))
3427 gen_mov_vreg_F0(dp, rd);
3431 /* Setup the next operands. */
3433 rd = ((rd + delta_d) & (bank_mask - 1))
3437 /* One source operand. */
3438 rm = ((rm + delta_m) & (bank_mask - 1))
3440 gen_mov_F0_vreg(dp, rm);
3442 /* Two source operands. */
3443 rn = ((rn + delta_d) & (bank_mask - 1))
3445 gen_mov_F0_vreg(dp, rn);
3447 rm = ((rm + delta_m) & (bank_mask - 1))
3449 gen_mov_F1_vreg(dp, rm);
3457 if ((insn & 0x03e00000) == 0x00400000) {
3458 /* two-register transfer */
3459 rn = (insn >> 16) & 0xf;
3460 rd = (insn >> 12) & 0xf;
3462 VFP_DREG_M(rm, insn);
3464 rm = VFP_SREG_M(insn);
3467 if (insn & ARM_CP_RW_BIT) {
3470 gen_mov_F0_vreg(0, rm * 2);
3471 tmp = gen_vfp_mrs();
3472 store_reg(s, rd, tmp);
3473 gen_mov_F0_vreg(0, rm * 2 + 1);
3474 tmp = gen_vfp_mrs();
3475 store_reg(s, rn, tmp);
3477 gen_mov_F0_vreg(0, rm);
3478 tmp = gen_vfp_mrs();
3479 store_reg(s, rd, tmp);
3480 gen_mov_F0_vreg(0, rm + 1);
3481 tmp = gen_vfp_mrs();
3482 store_reg(s, rn, tmp);
3487 tmp = load_reg(s, rd);
3489 gen_mov_vreg_F0(0, rm * 2);
3490 tmp = load_reg(s, rn);
3492 gen_mov_vreg_F0(0, rm * 2 + 1);
3494 tmp = load_reg(s, rd);
3496 gen_mov_vreg_F0(0, rm);
3497 tmp = load_reg(s, rn);
3499 gen_mov_vreg_F0(0, rm + 1);
3504 rn = (insn >> 16) & 0xf;
3506 VFP_DREG_D(rd, insn);
3508 rd = VFP_SREG_D(insn);
3509 if ((insn & 0x01200000) == 0x01000000) {
3510 /* Single load/store */
3511 offset = (insn & 0xff) << 2;
3512 if ((insn & (1 << 23)) == 0)
3514 if (s->thumb && rn == 15) {
3515 /* This is actually UNPREDICTABLE */
3516 addr = tcg_temp_new_i32();
3517 tcg_gen_movi_i32(addr, s->pc & ~2);
3519 addr = load_reg(s, rn);
3521 tcg_gen_addi_i32(addr, addr, offset);
3522 if (insn & (1 << 20)) {
3523 gen_vfp_ld(s, dp, addr);
3524 gen_mov_vreg_F0(dp, rd);
3526 gen_mov_F0_vreg(dp, rd);
3527 gen_vfp_st(s, dp, addr);
3529 tcg_temp_free_i32(addr);
3531 /* load/store multiple */
3532 int w = insn & (1 << 21);
3534 n = (insn >> 1) & 0x7f;
3538 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3539 /* P == U , W == 1 => UNDEF */
3542 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3543 /* UNPREDICTABLE cases for bad immediates: we choose to
3544 * UNDEF to avoid generating huge numbers of TCG ops
3548 if (rn == 15 && w) {
3549 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3553 if (s->thumb && rn == 15) {
3554 /* This is actually UNPREDICTABLE */
3555 addr = tcg_temp_new_i32();
3556 tcg_gen_movi_i32(addr, s->pc & ~2);
3558 addr = load_reg(s, rn);
3560 if (insn & (1 << 24)) /* pre-decrement */
3561 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3567 for (i = 0; i < n; i++) {
3568 if (insn & ARM_CP_RW_BIT) {
3570 gen_vfp_ld(s, dp, addr);
3571 gen_mov_vreg_F0(dp, rd + i);
3574 gen_mov_F0_vreg(dp, rd + i);
3575 gen_vfp_st(s, dp, addr);
3577 tcg_gen_addi_i32(addr, addr, offset);
3581 if (insn & (1 << 24))
3582 offset = -offset * n;
3583 else if (dp && (insn & 1))
3589 tcg_gen_addi_i32(addr, addr, offset);
3590 store_reg(s, rn, addr);
3592 tcg_temp_free_i32(addr);
3598 /* Should never happen. */
3604 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3606 TranslationBlock *tb;
3609 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3611 gen_set_pc_im(s, dest);
3612 tcg_gen_exit_tb((uintptr_t)tb + n);
3614 gen_set_pc_im(s, dest);
3619 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3621 if (unlikely(s->singlestep_enabled)) {
3622 /* An indirect jump so that we still trigger the debug exception. */
3627 gen_goto_tb(s, 0, dest);
3628 s->is_jmp = DISAS_TB_JUMP;
3632 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3635 tcg_gen_sari_i32(t0, t0, 16);
3639 tcg_gen_sari_i32(t1, t1, 16);
3642 tcg_gen_mul_i32(t0, t0, t1);
3645 /* Return the mask of PSR bits set by a MSR instruction. */
3646 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3650 if (flags & (1 << 0))
3652 if (flags & (1 << 1))
3654 if (flags & (1 << 2))
3656 if (flags & (1 << 3))
3659 /* Mask out undefined bits. */
3660 mask &= ~CPSR_RESERVED;
3661 if (!arm_feature(env, ARM_FEATURE_V4T))
3663 if (!arm_feature(env, ARM_FEATURE_V5))
3664 mask &= ~CPSR_Q; /* V5TE in reality*/
3665 if (!arm_feature(env, ARM_FEATURE_V6))
3666 mask &= ~(CPSR_E | CPSR_GE);
3667 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3669 /* Mask out execution state bits. */
3672 /* Mask out privileged bits. */
3678 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3679 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3683 /* ??? This is also undefined in system mode. */
3687 tmp = load_cpu_field(spsr);
3688 tcg_gen_andi_i32(tmp, tmp, ~mask);
3689 tcg_gen_andi_i32(t0, t0, mask);
3690 tcg_gen_or_i32(tmp, tmp, t0);
3691 store_cpu_field(tmp, spsr);
3693 gen_set_cpsr(t0, mask);
3695 tcg_temp_free_i32(t0);
3700 /* Returns nonzero if access to the PSR is not permitted. */
3701 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3704 tmp = tcg_temp_new_i32();
3705 tcg_gen_movi_i32(tmp, val);
3706 return gen_set_psr(s, mask, spsr, tmp);
3709 /* Generate an old-style exception return. Marks pc as dead. */
3710 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3713 store_reg(s, 15, pc);
3714 tmp = load_cpu_field(spsr);
3715 gen_set_cpsr(tmp, 0xffffffff);
3716 tcg_temp_free_i32(tmp);
3717 s->is_jmp = DISAS_UPDATE;
3720 /* Generate a v6 exception return. Marks both values as dead. */
3721 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3723 gen_set_cpsr(cpsr, 0xffffffff);
3724 tcg_temp_free_i32(cpsr);
3725 store_reg(s, 15, pc);
3726 s->is_jmp = DISAS_UPDATE;
3730 gen_set_condexec (DisasContext *s)
3732 if (s->condexec_mask) {
3733 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3734 TCGv_i32 tmp = tcg_temp_new_i32();
3735 tcg_gen_movi_i32(tmp, val);
3736 store_cpu_field(tmp, condexec_bits);
3740 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3742 gen_set_condexec(s);
3743 gen_set_pc_im(s, s->pc - offset);
3744 gen_exception(excp);
3745 s->is_jmp = DISAS_JUMP;
3748 static void gen_nop_hint(DisasContext *s, int val)
3752 gen_set_pc_im(s, s->pc);
3753 s->is_jmp = DISAS_WFI;
3758 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3764 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3766 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3769 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3770 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3771 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3776 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3779 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3780 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3781 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3786 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3787 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3788 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3789 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3790 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3792 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3793 switch ((size << 1) | u) { \
3795 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3798 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3801 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3804 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3807 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3810 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3812 default: return 1; \
3815 #define GEN_NEON_INTEGER_OP(name) do { \
3816 switch ((size << 1) | u) { \
3818 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3821 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3824 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3827 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3830 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3833 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3835 default: return 1; \
3838 static TCGv_i32 neon_load_scratch(int scratch)
3840 TCGv_i32 tmp = tcg_temp_new_i32();
3841 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3845 static void neon_store_scratch(int scratch, TCGv_i32 var)
3847 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3848 tcg_temp_free_i32(var);
3851 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3855 tmp = neon_load_reg(reg & 7, reg >> 4);
3857 gen_neon_dup_high16(tmp);
3859 gen_neon_dup_low16(tmp);
3862 tmp = neon_load_reg(reg & 15, reg >> 4);
3867 static int gen_neon_unzip(int rd, int rm, int size, int q)
3870 if (!q && size == 2) {
3873 tmp = tcg_const_i32(rd);
3874 tmp2 = tcg_const_i32(rm);
3878 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3881 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3884 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3892 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3895 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3901 tcg_temp_free_i32(tmp);
3902 tcg_temp_free_i32(tmp2);
3906 static int gen_neon_zip(int rd, int rm, int size, int q)
3909 if (!q && size == 2) {
3912 tmp = tcg_const_i32(rd);
3913 tmp2 = tcg_const_i32(rm);
3917 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3920 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3923 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3931 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3934 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3940 tcg_temp_free_i32(tmp);
3941 tcg_temp_free_i32(tmp2);
3945 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3949 rd = tcg_temp_new_i32();
3950 tmp = tcg_temp_new_i32();
3952 tcg_gen_shli_i32(rd, t0, 8);
3953 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3954 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3955 tcg_gen_or_i32(rd, rd, tmp);
3957 tcg_gen_shri_i32(t1, t1, 8);
3958 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3959 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3960 tcg_gen_or_i32(t1, t1, tmp);
3961 tcg_gen_mov_i32(t0, rd);
3963 tcg_temp_free_i32(tmp);
3964 tcg_temp_free_i32(rd);
3967 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3971 rd = tcg_temp_new_i32();
3972 tmp = tcg_temp_new_i32();
3974 tcg_gen_shli_i32(rd, t0, 16);
3975 tcg_gen_andi_i32(tmp, t1, 0xffff);
3976 tcg_gen_or_i32(rd, rd, tmp);
3977 tcg_gen_shri_i32(t1, t1, 16);
3978 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3979 tcg_gen_or_i32(t1, t1, tmp);
3980 tcg_gen_mov_i32(t0, rd);
3982 tcg_temp_free_i32(tmp);
3983 tcg_temp_free_i32(rd);
3991 } neon_ls_element_type[11] = {
4005 /* Translate a NEON load/store element instruction. Return nonzero if the
4006 instruction is invalid. */
4007 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4026 if (!s->vfp_enabled)
4028 VFP_DREG_D(rd, insn);
4029 rn = (insn >> 16) & 0xf;
4031 load = (insn & (1 << 21)) != 0;
4032 if ((insn & (1 << 23)) == 0) {
4033 /* Load store all elements. */
4034 op = (insn >> 8) & 0xf;
4035 size = (insn >> 6) & 3;
4038 /* Catch UNDEF cases for bad values of align field */
4041 if (((insn >> 5) & 1) == 1) {
4046 if (((insn >> 4) & 3) == 3) {
4053 nregs = neon_ls_element_type[op].nregs;
4054 interleave = neon_ls_element_type[op].interleave;
4055 spacing = neon_ls_element_type[op].spacing;
4056 if (size == 3 && (interleave | spacing) != 1)
4058 addr = tcg_temp_new_i32();
4059 load_reg_var(s, addr, rn);
4060 stride = (1 << size) * interleave;
4061 for (reg = 0; reg < nregs; reg++) {
4062 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4063 load_reg_var(s, addr, rn);
4064 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4065 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4066 load_reg_var(s, addr, rn);
4067 tcg_gen_addi_i32(addr, addr, 1 << size);
4070 tmp64 = tcg_temp_new_i64();
4072 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4073 neon_store_reg64(tmp64, rd);
4075 neon_load_reg64(tmp64, rd);
4076 gen_aa32_st64(tmp64, addr, IS_USER(s));
4078 tcg_temp_free_i64(tmp64);
4079 tcg_gen_addi_i32(addr, addr, stride);
4081 for (pass = 0; pass < 2; pass++) {
4084 tmp = tcg_temp_new_i32();
4085 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4086 neon_store_reg(rd, pass, tmp);
4088 tmp = neon_load_reg(rd, pass);
4089 gen_aa32_st32(tmp, addr, IS_USER(s));
4090 tcg_temp_free_i32(tmp);
4092 tcg_gen_addi_i32(addr, addr, stride);
4093 } else if (size == 1) {
4095 tmp = tcg_temp_new_i32();
4096 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4097 tcg_gen_addi_i32(addr, addr, stride);
4098 tmp2 = tcg_temp_new_i32();
4099 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4100 tcg_gen_addi_i32(addr, addr, stride);
4101 tcg_gen_shli_i32(tmp2, tmp2, 16);
4102 tcg_gen_or_i32(tmp, tmp, tmp2);
4103 tcg_temp_free_i32(tmp2);
4104 neon_store_reg(rd, pass, tmp);
4106 tmp = neon_load_reg(rd, pass);
4107 tmp2 = tcg_temp_new_i32();
4108 tcg_gen_shri_i32(tmp2, tmp, 16);
4109 gen_aa32_st16(tmp, addr, IS_USER(s));
4110 tcg_temp_free_i32(tmp);
4111 tcg_gen_addi_i32(addr, addr, stride);
4112 gen_aa32_st16(tmp2, addr, IS_USER(s));
4113 tcg_temp_free_i32(tmp2);
4114 tcg_gen_addi_i32(addr, addr, stride);
4116 } else /* size == 0 */ {
4118 TCGV_UNUSED_I32(tmp2);
4119 for (n = 0; n < 4; n++) {
4120 tmp = tcg_temp_new_i32();
4121 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4122 tcg_gen_addi_i32(addr, addr, stride);
4126 tcg_gen_shli_i32(tmp, tmp, n * 8);
4127 tcg_gen_or_i32(tmp2, tmp2, tmp);
4128 tcg_temp_free_i32(tmp);
4131 neon_store_reg(rd, pass, tmp2);
4133 tmp2 = neon_load_reg(rd, pass);
4134 for (n = 0; n < 4; n++) {
4135 tmp = tcg_temp_new_i32();
4137 tcg_gen_mov_i32(tmp, tmp2);
4139 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4141 gen_aa32_st8(tmp, addr, IS_USER(s));
4142 tcg_temp_free_i32(tmp);
4143 tcg_gen_addi_i32(addr, addr, stride);
4145 tcg_temp_free_i32(tmp2);
4152 tcg_temp_free_i32(addr);
4155 size = (insn >> 10) & 3;
4157 /* Load single element to all lanes. */
4158 int a = (insn >> 4) & 1;
4162 size = (insn >> 6) & 3;
4163 nregs = ((insn >> 8) & 3) + 1;
4166 if (nregs != 4 || a == 0) {
4169 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4172 if (nregs == 1 && a == 1 && size == 0) {
4175 if (nregs == 3 && a == 1) {
4178 addr = tcg_temp_new_i32();
4179 load_reg_var(s, addr, rn);
4181 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4182 tmp = gen_load_and_replicate(s, addr, size);
4183 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4184 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4185 if (insn & (1 << 5)) {
4186 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4187 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4189 tcg_temp_free_i32(tmp);
4191 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4192 stride = (insn & (1 << 5)) ? 2 : 1;
4193 for (reg = 0; reg < nregs; reg++) {
4194 tmp = gen_load_and_replicate(s, addr, size);
4195 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4196 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4197 tcg_temp_free_i32(tmp);
4198 tcg_gen_addi_i32(addr, addr, 1 << size);
4202 tcg_temp_free_i32(addr);
4203 stride = (1 << size) * nregs;
4205 /* Single element. */
4206 int idx = (insn >> 4) & 0xf;
4207 pass = (insn >> 7) & 1;
4210 shift = ((insn >> 5) & 3) * 8;
4214 shift = ((insn >> 6) & 1) * 16;
4215 stride = (insn & (1 << 5)) ? 2 : 1;
4219 stride = (insn & (1 << 6)) ? 2 : 1;
4224 nregs = ((insn >> 8) & 3) + 1;
4225 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4228 if (((idx & (1 << size)) != 0) ||
4229 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4234 if ((idx & 1) != 0) {
4239 if (size == 2 && (idx & 2) != 0) {
4244 if ((size == 2) && ((idx & 3) == 3)) {
4251 if ((rd + stride * (nregs - 1)) > 31) {
4252 /* Attempts to write off the end of the register file
4253 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4254 * the neon_load_reg() would write off the end of the array.
4258 addr = tcg_temp_new_i32();
4259 load_reg_var(s, addr, rn);
4260 for (reg = 0; reg < nregs; reg++) {
4262 tmp = tcg_temp_new_i32();
4265 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4268 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4271 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4273 default: /* Avoid compiler warnings. */
4277 tmp2 = neon_load_reg(rd, pass);
4278 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4279 shift, size ? 16 : 8);
4280 tcg_temp_free_i32(tmp2);
4282 neon_store_reg(rd, pass, tmp);
4283 } else { /* Store */
4284 tmp = neon_load_reg(rd, pass);
4286 tcg_gen_shri_i32(tmp, tmp, shift);
4289 gen_aa32_st8(tmp, addr, IS_USER(s));
4292 gen_aa32_st16(tmp, addr, IS_USER(s));
4295 gen_aa32_st32(tmp, addr, IS_USER(s));
4298 tcg_temp_free_i32(tmp);
4301 tcg_gen_addi_i32(addr, addr, 1 << size);
4303 tcg_temp_free_i32(addr);
4304 stride = nregs * (1 << size);
4310 base = load_reg(s, rn);
4312 tcg_gen_addi_i32(base, base, stride);
4315 index = load_reg(s, rm);
4316 tcg_gen_add_i32(base, base, index);
4317 tcg_temp_free_i32(index);
4319 store_reg(s, rn, base);
4324 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4325 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4327 tcg_gen_and_i32(t, t, c);
4328 tcg_gen_andc_i32(f, f, c);
4329 tcg_gen_or_i32(dest, t, f);
4332 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4335 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4336 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4337 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4342 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4345 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4346 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4347 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4352 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4355 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4356 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4357 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4362 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4365 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4366 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4367 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4372 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4378 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4379 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4384 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4385 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4392 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4393 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4398 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4399 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4406 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4410 case 0: gen_helper_neon_widen_u8(dest, src); break;
4411 case 1: gen_helper_neon_widen_u16(dest, src); break;
4412 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4417 case 0: gen_helper_neon_widen_s8(dest, src); break;
4418 case 1: gen_helper_neon_widen_s16(dest, src); break;
4419 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4423 tcg_temp_free_i32(src);
4426 static inline void gen_neon_addl(int size)
4429 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4430 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4431 case 2: tcg_gen_add_i64(CPU_V001); break;
4436 static inline void gen_neon_subl(int size)
4439 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4440 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4441 case 2: tcg_gen_sub_i64(CPU_V001); break;
4446 static inline void gen_neon_negl(TCGv_i64 var, int size)
4449 case 0: gen_helper_neon_negl_u16(var, var); break;
4450 case 1: gen_helper_neon_negl_u32(var, var); break;
4452 tcg_gen_neg_i64(var, var);
4458 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4461 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4462 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4467 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4472 switch ((size << 1) | u) {
4473 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4474 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4475 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4476 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4478 tmp = gen_muls_i64_i32(a, b);
4479 tcg_gen_mov_i64(dest, tmp);
4480 tcg_temp_free_i64(tmp);
4483 tmp = gen_mulu_i64_i32(a, b);
4484 tcg_gen_mov_i64(dest, tmp);
4485 tcg_temp_free_i64(tmp);
4490 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4491 Don't forget to clean them now. */
4493 tcg_temp_free_i32(a);
4494 tcg_temp_free_i32(b);
4498 static void gen_neon_narrow_op(int op, int u, int size,
4499 TCGv_i32 dest, TCGv_i64 src)
4503 gen_neon_unarrow_sats(size, dest, src);
4505 gen_neon_narrow(size, dest, src);
4509 gen_neon_narrow_satu(size, dest, src);
4511 gen_neon_narrow_sats(size, dest, src);
4516 /* Symbolic constants for op fields for Neon 3-register same-length.
4517 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4520 #define NEON_3R_VHADD 0
4521 #define NEON_3R_VQADD 1
4522 #define NEON_3R_VRHADD 2
4523 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4524 #define NEON_3R_VHSUB 4
4525 #define NEON_3R_VQSUB 5
4526 #define NEON_3R_VCGT 6
4527 #define NEON_3R_VCGE 7
4528 #define NEON_3R_VSHL 8
4529 #define NEON_3R_VQSHL 9
4530 #define NEON_3R_VRSHL 10
4531 #define NEON_3R_VQRSHL 11
4532 #define NEON_3R_VMAX 12
4533 #define NEON_3R_VMIN 13
4534 #define NEON_3R_VABD 14
4535 #define NEON_3R_VABA 15
4536 #define NEON_3R_VADD_VSUB 16
4537 #define NEON_3R_VTST_VCEQ 17
4538 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4539 #define NEON_3R_VMUL 19
4540 #define NEON_3R_VPMAX 20
4541 #define NEON_3R_VPMIN 21
4542 #define NEON_3R_VQDMULH_VQRDMULH 22
4543 #define NEON_3R_VPADD 23
4544 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4545 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4546 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4547 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4548 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4549 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4550 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4552 static const uint8_t neon_3r_sizes[] = {
4553 [NEON_3R_VHADD] = 0x7,
4554 [NEON_3R_VQADD] = 0xf,
4555 [NEON_3R_VRHADD] = 0x7,
4556 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4557 [NEON_3R_VHSUB] = 0x7,
4558 [NEON_3R_VQSUB] = 0xf,
4559 [NEON_3R_VCGT] = 0x7,
4560 [NEON_3R_VCGE] = 0x7,
4561 [NEON_3R_VSHL] = 0xf,
4562 [NEON_3R_VQSHL] = 0xf,
4563 [NEON_3R_VRSHL] = 0xf,
4564 [NEON_3R_VQRSHL] = 0xf,
4565 [NEON_3R_VMAX] = 0x7,
4566 [NEON_3R_VMIN] = 0x7,
4567 [NEON_3R_VABD] = 0x7,
4568 [NEON_3R_VABA] = 0x7,
4569 [NEON_3R_VADD_VSUB] = 0xf,
4570 [NEON_3R_VTST_VCEQ] = 0x7,
4571 [NEON_3R_VML] = 0x7,
4572 [NEON_3R_VMUL] = 0x7,
4573 [NEON_3R_VPMAX] = 0x7,
4574 [NEON_3R_VPMIN] = 0x7,
4575 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4576 [NEON_3R_VPADD] = 0x7,
4577 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4578 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4579 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4580 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4581 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4582 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4583 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4586 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4587 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4590 #define NEON_2RM_VREV64 0
4591 #define NEON_2RM_VREV32 1
4592 #define NEON_2RM_VREV16 2
4593 #define NEON_2RM_VPADDL 4
4594 #define NEON_2RM_VPADDL_U 5
4595 #define NEON_2RM_VCLS 8
4596 #define NEON_2RM_VCLZ 9
4597 #define NEON_2RM_VCNT 10
4598 #define NEON_2RM_VMVN 11
4599 #define NEON_2RM_VPADAL 12
4600 #define NEON_2RM_VPADAL_U 13
4601 #define NEON_2RM_VQABS 14
4602 #define NEON_2RM_VQNEG 15
4603 #define NEON_2RM_VCGT0 16
4604 #define NEON_2RM_VCGE0 17
4605 #define NEON_2RM_VCEQ0 18
4606 #define NEON_2RM_VCLE0 19
4607 #define NEON_2RM_VCLT0 20
4608 #define NEON_2RM_VABS 22
4609 #define NEON_2RM_VNEG 23
4610 #define NEON_2RM_VCGT0_F 24
4611 #define NEON_2RM_VCGE0_F 25
4612 #define NEON_2RM_VCEQ0_F 26
4613 #define NEON_2RM_VCLE0_F 27
4614 #define NEON_2RM_VCLT0_F 28
4615 #define NEON_2RM_VABS_F 30
4616 #define NEON_2RM_VNEG_F 31
4617 #define NEON_2RM_VSWP 32
4618 #define NEON_2RM_VTRN 33
4619 #define NEON_2RM_VUZP 34
4620 #define NEON_2RM_VZIP 35
4621 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4622 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4623 #define NEON_2RM_VSHLL 38
4624 #define NEON_2RM_VCVT_F16_F32 44
4625 #define NEON_2RM_VCVT_F32_F16 46
4626 #define NEON_2RM_VRECPE 56
4627 #define NEON_2RM_VRSQRTE 57
4628 #define NEON_2RM_VRECPE_F 58
4629 #define NEON_2RM_VRSQRTE_F 59
4630 #define NEON_2RM_VCVT_FS 60
4631 #define NEON_2RM_VCVT_FU 61
4632 #define NEON_2RM_VCVT_SF 62
4633 #define NEON_2RM_VCVT_UF 63
4635 static int neon_2rm_is_float_op(int op)
4637 /* Return true if this neon 2reg-misc op is float-to-float */
4638 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4639 op >= NEON_2RM_VRECPE_F);
4642 /* Each entry in this array has bit n set if the insn allows
4643 * size value n (otherwise it will UNDEF). Since unallocated
4644 * op values will have no bits set they always UNDEF.
4646 static const uint8_t neon_2rm_sizes[] = {
4647 [NEON_2RM_VREV64] = 0x7,
4648 [NEON_2RM_VREV32] = 0x3,
4649 [NEON_2RM_VREV16] = 0x1,
4650 [NEON_2RM_VPADDL] = 0x7,
4651 [NEON_2RM_VPADDL_U] = 0x7,
4652 [NEON_2RM_VCLS] = 0x7,
4653 [NEON_2RM_VCLZ] = 0x7,
4654 [NEON_2RM_VCNT] = 0x1,
4655 [NEON_2RM_VMVN] = 0x1,
4656 [NEON_2RM_VPADAL] = 0x7,
4657 [NEON_2RM_VPADAL_U] = 0x7,
4658 [NEON_2RM_VQABS] = 0x7,
4659 [NEON_2RM_VQNEG] = 0x7,
4660 [NEON_2RM_VCGT0] = 0x7,
4661 [NEON_2RM_VCGE0] = 0x7,
4662 [NEON_2RM_VCEQ0] = 0x7,
4663 [NEON_2RM_VCLE0] = 0x7,
4664 [NEON_2RM_VCLT0] = 0x7,
4665 [NEON_2RM_VABS] = 0x7,
4666 [NEON_2RM_VNEG] = 0x7,
4667 [NEON_2RM_VCGT0_F] = 0x4,
4668 [NEON_2RM_VCGE0_F] = 0x4,
4669 [NEON_2RM_VCEQ0_F] = 0x4,
4670 [NEON_2RM_VCLE0_F] = 0x4,
4671 [NEON_2RM_VCLT0_F] = 0x4,
4672 [NEON_2RM_VABS_F] = 0x4,
4673 [NEON_2RM_VNEG_F] = 0x4,
4674 [NEON_2RM_VSWP] = 0x1,
4675 [NEON_2RM_VTRN] = 0x7,
4676 [NEON_2RM_VUZP] = 0x7,
4677 [NEON_2RM_VZIP] = 0x7,
4678 [NEON_2RM_VMOVN] = 0x7,
4679 [NEON_2RM_VQMOVN] = 0x7,
4680 [NEON_2RM_VSHLL] = 0x7,
4681 [NEON_2RM_VCVT_F16_F32] = 0x2,
4682 [NEON_2RM_VCVT_F32_F16] = 0x2,
4683 [NEON_2RM_VRECPE] = 0x4,
4684 [NEON_2RM_VRSQRTE] = 0x4,
4685 [NEON_2RM_VRECPE_F] = 0x4,
4686 [NEON_2RM_VRSQRTE_F] = 0x4,
4687 [NEON_2RM_VCVT_FS] = 0x4,
4688 [NEON_2RM_VCVT_FU] = 0x4,
4689 [NEON_2RM_VCVT_SF] = 0x4,
4690 [NEON_2RM_VCVT_UF] = 0x4,
4693 /* Translate a NEON data processing instruction. Return nonzero if the
4694 instruction is invalid.
4695 We process data in a mixture of 32-bit and 64-bit chunks.
4696 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4698 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4710 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4713 if (!s->vfp_enabled)
4715 q = (insn & (1 << 6)) != 0;
4716 u = (insn >> 24) & 1;
4717 VFP_DREG_D(rd, insn);
4718 VFP_DREG_N(rn, insn);
4719 VFP_DREG_M(rm, insn);
4720 size = (insn >> 20) & 3;
4721 if ((insn & (1 << 23)) == 0) {
4722 /* Three register same length. */
4723 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4724 /* Catch invalid op and bad size combinations: UNDEF */
4725 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4728 /* All insns of this form UNDEF for either this condition or the
4729 * superset of cases "Q==1"; we catch the latter later.
4731 if (q && ((rd | rn | rm) & 1)) {
4734 if (size == 3 && op != NEON_3R_LOGIC) {
4735 /* 64-bit element instructions. */
4736 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4737 neon_load_reg64(cpu_V0, rn + pass);
4738 neon_load_reg64(cpu_V1, rm + pass);
4742 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4745 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4751 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4754 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4760 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4762 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4767 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4770 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4776 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4778 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4781 case NEON_3R_VQRSHL:
4783 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4786 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4790 case NEON_3R_VADD_VSUB:
4792 tcg_gen_sub_i64(CPU_V001);
4794 tcg_gen_add_i64(CPU_V001);
4800 neon_store_reg64(cpu_V0, rd + pass);
4809 case NEON_3R_VQRSHL:
4812 /* Shift instruction operands are reversed. */
4827 case NEON_3R_FLOAT_ARITH:
4828 pairwise = (u && size < 2); /* if VPADD (float) */
4830 case NEON_3R_FLOAT_MINMAX:
4831 pairwise = u; /* if VPMIN/VPMAX (float) */
4833 case NEON_3R_FLOAT_CMP:
4835 /* no encoding for U=0 C=1x */
4839 case NEON_3R_FLOAT_ACMP:
4844 case NEON_3R_FLOAT_MISC:
4845 /* VMAXNM/VMINNM in ARMv8 */
4846 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4851 if (u && (size != 0)) {
4852 /* UNDEF on invalid size for polynomial subcase */
4857 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4865 if (pairwise && q) {
4866 /* All the pairwise insns UNDEF if Q is set */
4870 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4875 tmp = neon_load_reg(rn, 0);
4876 tmp2 = neon_load_reg(rn, 1);
4878 tmp = neon_load_reg(rm, 0);
4879 tmp2 = neon_load_reg(rm, 1);
4883 tmp = neon_load_reg(rn, pass);
4884 tmp2 = neon_load_reg(rm, pass);
4888 GEN_NEON_INTEGER_OP(hadd);
4891 GEN_NEON_INTEGER_OP_ENV(qadd);
4893 case NEON_3R_VRHADD:
4894 GEN_NEON_INTEGER_OP(rhadd);
4896 case NEON_3R_LOGIC: /* Logic ops. */
4897 switch ((u << 2) | size) {
4899 tcg_gen_and_i32(tmp, tmp, tmp2);
4902 tcg_gen_andc_i32(tmp, tmp, tmp2);
4905 tcg_gen_or_i32(tmp, tmp, tmp2);
4908 tcg_gen_orc_i32(tmp, tmp, tmp2);
4911 tcg_gen_xor_i32(tmp, tmp, tmp2);
4914 tmp3 = neon_load_reg(rd, pass);
4915 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4916 tcg_temp_free_i32(tmp3);
4919 tmp3 = neon_load_reg(rd, pass);
4920 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4921 tcg_temp_free_i32(tmp3);
4924 tmp3 = neon_load_reg(rd, pass);
4925 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4926 tcg_temp_free_i32(tmp3);
4931 GEN_NEON_INTEGER_OP(hsub);
4934 GEN_NEON_INTEGER_OP_ENV(qsub);
4937 GEN_NEON_INTEGER_OP(cgt);
4940 GEN_NEON_INTEGER_OP(cge);
4943 GEN_NEON_INTEGER_OP(shl);
4946 GEN_NEON_INTEGER_OP_ENV(qshl);
4949 GEN_NEON_INTEGER_OP(rshl);
4951 case NEON_3R_VQRSHL:
4952 GEN_NEON_INTEGER_OP_ENV(qrshl);
4955 GEN_NEON_INTEGER_OP(max);
4958 GEN_NEON_INTEGER_OP(min);
4961 GEN_NEON_INTEGER_OP(abd);
4964 GEN_NEON_INTEGER_OP(abd);
4965 tcg_temp_free_i32(tmp2);
4966 tmp2 = neon_load_reg(rd, pass);
4967 gen_neon_add(size, tmp, tmp2);
4969 case NEON_3R_VADD_VSUB:
4970 if (!u) { /* VADD */
4971 gen_neon_add(size, tmp, tmp2);
4974 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4975 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4976 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4981 case NEON_3R_VTST_VCEQ:
4982 if (!u) { /* VTST */
4984 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4985 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4986 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4991 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4992 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4993 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4998 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5000 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5001 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5002 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5005 tcg_temp_free_i32(tmp2);
5006 tmp2 = neon_load_reg(rd, pass);
5008 gen_neon_rsb(size, tmp, tmp2);
5010 gen_neon_add(size, tmp, tmp2);
5014 if (u) { /* polynomial */
5015 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5016 } else { /* Integer */
5018 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5019 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5020 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5026 GEN_NEON_INTEGER_OP(pmax);
5029 GEN_NEON_INTEGER_OP(pmin);
5031 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5032 if (!u) { /* VQDMULH */
5035 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5038 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5042 } else { /* VQRDMULH */
5045 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5048 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5056 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5057 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5058 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5062 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5064 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5065 switch ((u << 2) | size) {
5068 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5071 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5074 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5079 tcg_temp_free_ptr(fpstatus);
5082 case NEON_3R_FLOAT_MULTIPLY:
5084 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5085 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5087 tcg_temp_free_i32(tmp2);
5088 tmp2 = neon_load_reg(rd, pass);
5090 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5092 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5095 tcg_temp_free_ptr(fpstatus);
5098 case NEON_3R_FLOAT_CMP:
5100 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5102 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5105 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5107 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5110 tcg_temp_free_ptr(fpstatus);
5113 case NEON_3R_FLOAT_ACMP:
5115 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5117 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5119 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5121 tcg_temp_free_ptr(fpstatus);
5124 case NEON_3R_FLOAT_MINMAX:
5126 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5128 gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
5130 gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
5132 tcg_temp_free_ptr(fpstatus);
5135 case NEON_3R_FLOAT_MISC:
5138 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5140 gen_helper_vfp_maxnms(tmp, tmp, tmp2, fpstatus);
5142 gen_helper_vfp_minnms(tmp, tmp, tmp2, fpstatus);
5144 tcg_temp_free_ptr(fpstatus);
5147 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5149 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5155 /* VFMA, VFMS: fused multiply-add */
5156 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5157 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5160 gen_helper_vfp_negs(tmp, tmp);
5162 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5163 tcg_temp_free_i32(tmp3);
5164 tcg_temp_free_ptr(fpstatus);
5170 tcg_temp_free_i32(tmp2);
5172 /* Save the result. For elementwise operations we can put it
5173 straight into the destination register. For pairwise operations
5174 we have to be careful to avoid clobbering the source operands. */
5175 if (pairwise && rd == rm) {
5176 neon_store_scratch(pass, tmp);
5178 neon_store_reg(rd, pass, tmp);
5182 if (pairwise && rd == rm) {
5183 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5184 tmp = neon_load_scratch(pass);
5185 neon_store_reg(rd, pass, tmp);
5188 /* End of 3 register same size operations. */
5189 } else if (insn & (1 << 4)) {
5190 if ((insn & 0x00380080) != 0) {
5191 /* Two registers and shift. */
5192 op = (insn >> 8) & 0xf;
5193 if (insn & (1 << 7)) {
5201 while ((insn & (1 << (size + 19))) == 0)
5204 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5205 /* To avoid excessive duplication of ops we implement shift
5206 by immediate using the variable shift operations. */
5208 /* Shift by immediate:
5209 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5210 if (q && ((rd | rm) & 1)) {
5213 if (!u && (op == 4 || op == 6)) {
5216 /* Right shifts are encoded as N - shift, where N is the
5217 element size in bits. */
5219 shift = shift - (1 << (size + 3));
5227 imm = (uint8_t) shift;
5232 imm = (uint16_t) shift;
5243 for (pass = 0; pass < count; pass++) {
5245 neon_load_reg64(cpu_V0, rm + pass);
5246 tcg_gen_movi_i64(cpu_V1, imm);
5251 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5253 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5258 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5260 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5263 case 5: /* VSHL, VSLI */
5264 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5266 case 6: /* VQSHLU */
5267 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5272 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5275 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5280 if (op == 1 || op == 3) {
5282 neon_load_reg64(cpu_V1, rd + pass);
5283 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5284 } else if (op == 4 || (op == 5 && u)) {
5286 neon_load_reg64(cpu_V1, rd + pass);
5288 if (shift < -63 || shift > 63) {
5292 mask = 0xffffffffffffffffull >> -shift;
5294 mask = 0xffffffffffffffffull << shift;
5297 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5298 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5300 neon_store_reg64(cpu_V0, rd + pass);
5301 } else { /* size < 3 */
5302 /* Operands in T0 and T1. */
5303 tmp = neon_load_reg(rm, pass);
5304 tmp2 = tcg_temp_new_i32();
5305 tcg_gen_movi_i32(tmp2, imm);
5309 GEN_NEON_INTEGER_OP(shl);
5313 GEN_NEON_INTEGER_OP(rshl);
5316 case 5: /* VSHL, VSLI */
5318 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5319 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5320 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5324 case 6: /* VQSHLU */
5327 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5331 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5335 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5343 GEN_NEON_INTEGER_OP_ENV(qshl);
5346 tcg_temp_free_i32(tmp2);
5348 if (op == 1 || op == 3) {
5350 tmp2 = neon_load_reg(rd, pass);
5351 gen_neon_add(size, tmp, tmp2);
5352 tcg_temp_free_i32(tmp2);
5353 } else if (op == 4 || (op == 5 && u)) {
5358 mask = 0xff >> -shift;
5360 mask = (uint8_t)(0xff << shift);
5366 mask = 0xffff >> -shift;
5368 mask = (uint16_t)(0xffff << shift);
5372 if (shift < -31 || shift > 31) {
5376 mask = 0xffffffffu >> -shift;
5378 mask = 0xffffffffu << shift;
5384 tmp2 = neon_load_reg(rd, pass);
5385 tcg_gen_andi_i32(tmp, tmp, mask);
5386 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5387 tcg_gen_or_i32(tmp, tmp, tmp2);
5388 tcg_temp_free_i32(tmp2);
5390 neon_store_reg(rd, pass, tmp);
5393 } else if (op < 10) {
5394 /* Shift by immediate and narrow:
5395 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5396 int input_unsigned = (op == 8) ? !u : u;
5400 shift = shift - (1 << (size + 3));
5403 tmp64 = tcg_const_i64(shift);
5404 neon_load_reg64(cpu_V0, rm);
5405 neon_load_reg64(cpu_V1, rm + 1);
5406 for (pass = 0; pass < 2; pass++) {
5414 if (input_unsigned) {
5415 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5417 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5420 if (input_unsigned) {
5421 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5423 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5426 tmp = tcg_temp_new_i32();
5427 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5428 neon_store_reg(rd, pass, tmp);
5430 tcg_temp_free_i64(tmp64);
5433 imm = (uint16_t)shift;
5437 imm = (uint32_t)shift;
5439 tmp2 = tcg_const_i32(imm);
5440 tmp4 = neon_load_reg(rm + 1, 0);
5441 tmp5 = neon_load_reg(rm + 1, 1);
5442 for (pass = 0; pass < 2; pass++) {
5444 tmp = neon_load_reg(rm, 0);
5448 gen_neon_shift_narrow(size, tmp, tmp2, q,
5451 tmp3 = neon_load_reg(rm, 1);
5455 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5457 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5458 tcg_temp_free_i32(tmp);
5459 tcg_temp_free_i32(tmp3);
5460 tmp = tcg_temp_new_i32();
5461 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5462 neon_store_reg(rd, pass, tmp);
5464 tcg_temp_free_i32(tmp2);
5466 } else if (op == 10) {
5468 if (q || (rd & 1)) {
5471 tmp = neon_load_reg(rm, 0);
5472 tmp2 = neon_load_reg(rm, 1);
5473 for (pass = 0; pass < 2; pass++) {
5477 gen_neon_widen(cpu_V0, tmp, size, u);
5480 /* The shift is less than the width of the source
5481 type, so we can just shift the whole register. */
5482 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5483 /* Widen the result of shift: we need to clear
5484 * the potential overflow bits resulting from
5485 * left bits of the narrow input appearing as
5486 * right bits of left the neighbour narrow
5488 if (size < 2 || !u) {
5491 imm = (0xffu >> (8 - shift));
5493 } else if (size == 1) {
5494 imm = 0xffff >> (16 - shift);
5497 imm = 0xffffffff >> (32 - shift);
5500 imm64 = imm | (((uint64_t)imm) << 32);
5504 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5507 neon_store_reg64(cpu_V0, rd + pass);
5509 } else if (op >= 14) {
5510 /* VCVT fixed-point. */
5511 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5514 /* We have already masked out the must-be-1 top bit of imm6,
5515 * hence this 32-shift where the ARM ARM has 64-imm6.
5518 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5519 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5522 gen_vfp_ulto(0, shift, 1);
5524 gen_vfp_slto(0, shift, 1);
5527 gen_vfp_toul(0, shift, 1);
5529 gen_vfp_tosl(0, shift, 1);
5531 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5536 } else { /* (insn & 0x00380080) == 0 */
5538 if (q && (rd & 1)) {
5542 op = (insn >> 8) & 0xf;
5543 /* One register and immediate. */
5544 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5545 invert = (insn & (1 << 5)) != 0;
5546 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5547 * We choose to not special-case this and will behave as if a
5548 * valid constant encoding of 0 had been given.
5567 imm = (imm << 8) | (imm << 24);
5570 imm = (imm << 8) | 0xff;
5573 imm = (imm << 16) | 0xffff;
5576 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5584 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5585 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5591 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5592 if (op & 1 && op < 12) {
5593 tmp = neon_load_reg(rd, pass);
5595 /* The immediate value has already been inverted, so
5597 tcg_gen_andi_i32(tmp, tmp, imm);
5599 tcg_gen_ori_i32(tmp, tmp, imm);
5603 tmp = tcg_temp_new_i32();
5604 if (op == 14 && invert) {
5608 for (n = 0; n < 4; n++) {
5609 if (imm & (1 << (n + (pass & 1) * 4)))
5610 val |= 0xff << (n * 8);
5612 tcg_gen_movi_i32(tmp, val);
5614 tcg_gen_movi_i32(tmp, imm);
5617 neon_store_reg(rd, pass, tmp);
5620 } else { /* (insn & 0x00800010 == 0x00800000) */
5622 op = (insn >> 8) & 0xf;
5623 if ((insn & (1 << 6)) == 0) {
5624 /* Three registers of different lengths. */
5628 /* undefreq: bit 0 : UNDEF if size != 0
5629 * bit 1 : UNDEF if size == 0
5630 * bit 2 : UNDEF if U == 1
5631 * Note that [1:0] set implies 'always UNDEF'
5634 /* prewiden, src1_wide, src2_wide, undefreq */
5635 static const int neon_3reg_wide[16][4] = {
5636 {1, 0, 0, 0}, /* VADDL */
5637 {1, 1, 0, 0}, /* VADDW */
5638 {1, 0, 0, 0}, /* VSUBL */
5639 {1, 1, 0, 0}, /* VSUBW */
5640 {0, 1, 1, 0}, /* VADDHN */
5641 {0, 0, 0, 0}, /* VABAL */
5642 {0, 1, 1, 0}, /* VSUBHN */
5643 {0, 0, 0, 0}, /* VABDL */
5644 {0, 0, 0, 0}, /* VMLAL */
5645 {0, 0, 0, 6}, /* VQDMLAL */
5646 {0, 0, 0, 0}, /* VMLSL */
5647 {0, 0, 0, 6}, /* VQDMLSL */
5648 {0, 0, 0, 0}, /* Integer VMULL */
5649 {0, 0, 0, 2}, /* VQDMULL */
5650 {0, 0, 0, 5}, /* Polynomial VMULL */
5651 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5654 prewiden = neon_3reg_wide[op][0];
5655 src1_wide = neon_3reg_wide[op][1];
5656 src2_wide = neon_3reg_wide[op][2];
5657 undefreq = neon_3reg_wide[op][3];
5659 if (((undefreq & 1) && (size != 0)) ||
5660 ((undefreq & 2) && (size == 0)) ||
5661 ((undefreq & 4) && u)) {
5664 if ((src1_wide && (rn & 1)) ||
5665 (src2_wide && (rm & 1)) ||
5666 (!src2_wide && (rd & 1))) {
5670 /* Avoid overlapping operands. Wide source operands are
5671 always aligned so will never overlap with wide
5672 destinations in problematic ways. */
5673 if (rd == rm && !src2_wide) {
5674 tmp = neon_load_reg(rm, 1);
5675 neon_store_scratch(2, tmp);
5676 } else if (rd == rn && !src1_wide) {
5677 tmp = neon_load_reg(rn, 1);
5678 neon_store_scratch(2, tmp);
5680 TCGV_UNUSED_I32(tmp3);
5681 for (pass = 0; pass < 2; pass++) {
5683 neon_load_reg64(cpu_V0, rn + pass);
5684 TCGV_UNUSED_I32(tmp);
5686 if (pass == 1 && rd == rn) {
5687 tmp = neon_load_scratch(2);
5689 tmp = neon_load_reg(rn, pass);
5692 gen_neon_widen(cpu_V0, tmp, size, u);
5696 neon_load_reg64(cpu_V1, rm + pass);
5697 TCGV_UNUSED_I32(tmp2);
5699 if (pass == 1 && rd == rm) {
5700 tmp2 = neon_load_scratch(2);
5702 tmp2 = neon_load_reg(rm, pass);
5705 gen_neon_widen(cpu_V1, tmp2, size, u);
5709 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5710 gen_neon_addl(size);
5712 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5713 gen_neon_subl(size);
5715 case 5: case 7: /* VABAL, VABDL */
5716 switch ((size << 1) | u) {
5718 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5721 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5724 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5727 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5730 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5733 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5737 tcg_temp_free_i32(tmp2);
5738 tcg_temp_free_i32(tmp);
5740 case 8: case 9: case 10: case 11: case 12: case 13:
5741 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5742 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5744 case 14: /* Polynomial VMULL */
5745 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5746 tcg_temp_free_i32(tmp2);
5747 tcg_temp_free_i32(tmp);
5749 default: /* 15 is RESERVED: caught earlier */
5754 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5755 neon_store_reg64(cpu_V0, rd + pass);
5756 } else if (op == 5 || (op >= 8 && op <= 11)) {
5758 neon_load_reg64(cpu_V1, rd + pass);
5760 case 10: /* VMLSL */
5761 gen_neon_negl(cpu_V0, size);
5763 case 5: case 8: /* VABAL, VMLAL */
5764 gen_neon_addl(size);
5766 case 9: case 11: /* VQDMLAL, VQDMLSL */
5767 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5769 gen_neon_negl(cpu_V0, size);
5771 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5776 neon_store_reg64(cpu_V0, rd + pass);
5777 } else if (op == 4 || op == 6) {
5778 /* Narrowing operation. */
5779 tmp = tcg_temp_new_i32();
5783 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5786 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5789 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5790 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5797 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5800 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5803 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5804 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5805 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5813 neon_store_reg(rd, 0, tmp3);
5814 neon_store_reg(rd, 1, tmp);
5817 /* Write back the result. */
5818 neon_store_reg64(cpu_V0, rd + pass);
5822 /* Two registers and a scalar. NB that for ops of this form
5823 * the ARM ARM labels bit 24 as Q, but it is in our variable
5830 case 1: /* Float VMLA scalar */
5831 case 5: /* Floating point VMLS scalar */
5832 case 9: /* Floating point VMUL scalar */
5837 case 0: /* Integer VMLA scalar */
5838 case 4: /* Integer VMLS scalar */
5839 case 8: /* Integer VMUL scalar */
5840 case 12: /* VQDMULH scalar */
5841 case 13: /* VQRDMULH scalar */
5842 if (u && ((rd | rn) & 1)) {
5845 tmp = neon_get_scalar(size, rm);
5846 neon_store_scratch(0, tmp);
5847 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5848 tmp = neon_load_scratch(0);
5849 tmp2 = neon_load_reg(rn, pass);
5852 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5854 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5856 } else if (op == 13) {
5858 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5860 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5862 } else if (op & 1) {
5863 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5864 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5865 tcg_temp_free_ptr(fpstatus);
5868 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5869 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5870 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5874 tcg_temp_free_i32(tmp2);
5877 tmp2 = neon_load_reg(rd, pass);
5880 gen_neon_add(size, tmp, tmp2);
5884 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5885 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5886 tcg_temp_free_ptr(fpstatus);
5890 gen_neon_rsb(size, tmp, tmp2);
5894 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5895 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5896 tcg_temp_free_ptr(fpstatus);
5902 tcg_temp_free_i32(tmp2);
5904 neon_store_reg(rd, pass, tmp);
5907 case 3: /* VQDMLAL scalar */
5908 case 7: /* VQDMLSL scalar */
5909 case 11: /* VQDMULL scalar */
5914 case 2: /* VMLAL sclar */
5915 case 6: /* VMLSL scalar */
5916 case 10: /* VMULL scalar */
5920 tmp2 = neon_get_scalar(size, rm);
5921 /* We need a copy of tmp2 because gen_neon_mull
5922 * deletes it during pass 0. */
5923 tmp4 = tcg_temp_new_i32();
5924 tcg_gen_mov_i32(tmp4, tmp2);
5925 tmp3 = neon_load_reg(rn, 1);
5927 for (pass = 0; pass < 2; pass++) {
5929 tmp = neon_load_reg(rn, 0);
5934 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5936 neon_load_reg64(cpu_V1, rd + pass);
5940 gen_neon_negl(cpu_V0, size);
5943 gen_neon_addl(size);
5946 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5948 gen_neon_negl(cpu_V0, size);
5950 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5956 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5961 neon_store_reg64(cpu_V0, rd + pass);
5966 default: /* 14 and 15 are RESERVED */
5970 } else { /* size == 3 */
5973 imm = (insn >> 8) & 0xf;
5978 if (q && ((rd | rn | rm) & 1)) {
5983 neon_load_reg64(cpu_V0, rn);
5985 neon_load_reg64(cpu_V1, rn + 1);
5987 } else if (imm == 8) {
5988 neon_load_reg64(cpu_V0, rn + 1);
5990 neon_load_reg64(cpu_V1, rm);
5993 tmp64 = tcg_temp_new_i64();
5995 neon_load_reg64(cpu_V0, rn);
5996 neon_load_reg64(tmp64, rn + 1);
5998 neon_load_reg64(cpu_V0, rn + 1);
5999 neon_load_reg64(tmp64, rm);
6001 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6002 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6003 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6005 neon_load_reg64(cpu_V1, rm);
6007 neon_load_reg64(cpu_V1, rm + 1);
6010 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6011 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6012 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6013 tcg_temp_free_i64(tmp64);
6016 neon_load_reg64(cpu_V0, rn);
6017 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6018 neon_load_reg64(cpu_V1, rm);
6019 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6020 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6022 neon_store_reg64(cpu_V0, rd);
6024 neon_store_reg64(cpu_V1, rd + 1);
6026 } else if ((insn & (1 << 11)) == 0) {
6027 /* Two register misc. */
6028 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6029 size = (insn >> 18) & 3;
6030 /* UNDEF for unknown op values and bad op-size combinations */
6031 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6034 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6035 q && ((rm | rd) & 1)) {
6039 case NEON_2RM_VREV64:
6040 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6041 tmp = neon_load_reg(rm, pass * 2);
6042 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6044 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6045 case 1: gen_swap_half(tmp); break;
6046 case 2: /* no-op */ break;
6049 neon_store_reg(rd, pass * 2 + 1, tmp);
6051 neon_store_reg(rd, pass * 2, tmp2);
6054 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6055 case 1: gen_swap_half(tmp2); break;
6058 neon_store_reg(rd, pass * 2, tmp2);
6062 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6063 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6064 for (pass = 0; pass < q + 1; pass++) {
6065 tmp = neon_load_reg(rm, pass * 2);
6066 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6067 tmp = neon_load_reg(rm, pass * 2 + 1);
6068 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6070 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6071 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6072 case 2: tcg_gen_add_i64(CPU_V001); break;
6075 if (op >= NEON_2RM_VPADAL) {
6077 neon_load_reg64(cpu_V1, rd + pass);
6078 gen_neon_addl(size);
6080 neon_store_reg64(cpu_V0, rd + pass);
6086 for (n = 0; n < (q ? 4 : 2); n += 2) {
6087 tmp = neon_load_reg(rm, n);
6088 tmp2 = neon_load_reg(rd, n + 1);
6089 neon_store_reg(rm, n, tmp2);
6090 neon_store_reg(rd, n + 1, tmp);
6097 if (gen_neon_unzip(rd, rm, size, q)) {
6102 if (gen_neon_zip(rd, rm, size, q)) {
6106 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6107 /* also VQMOVUN; op field and mnemonics don't line up */
6111 TCGV_UNUSED_I32(tmp2);
6112 for (pass = 0; pass < 2; pass++) {
6113 neon_load_reg64(cpu_V0, rm + pass);
6114 tmp = tcg_temp_new_i32();
6115 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6120 neon_store_reg(rd, 0, tmp2);
6121 neon_store_reg(rd, 1, tmp);
6125 case NEON_2RM_VSHLL:
6126 if (q || (rd & 1)) {
6129 tmp = neon_load_reg(rm, 0);
6130 tmp2 = neon_load_reg(rm, 1);
6131 for (pass = 0; pass < 2; pass++) {
6134 gen_neon_widen(cpu_V0, tmp, size, 1);
6135 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6136 neon_store_reg64(cpu_V0, rd + pass);
6139 case NEON_2RM_VCVT_F16_F32:
6140 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6144 tmp = tcg_temp_new_i32();
6145 tmp2 = tcg_temp_new_i32();
6146 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6147 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6148 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6149 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6150 tcg_gen_shli_i32(tmp2, tmp2, 16);
6151 tcg_gen_or_i32(tmp2, tmp2, tmp);
6152 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6153 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6154 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6155 neon_store_reg(rd, 0, tmp2);
6156 tmp2 = tcg_temp_new_i32();
6157 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6158 tcg_gen_shli_i32(tmp2, tmp2, 16);
6159 tcg_gen_or_i32(tmp2, tmp2, tmp);
6160 neon_store_reg(rd, 1, tmp2);
6161 tcg_temp_free_i32(tmp);
6163 case NEON_2RM_VCVT_F32_F16:
6164 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6168 tmp3 = tcg_temp_new_i32();
6169 tmp = neon_load_reg(rm, 0);
6170 tmp2 = neon_load_reg(rm, 1);
6171 tcg_gen_ext16u_i32(tmp3, tmp);
6172 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6173 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6174 tcg_gen_shri_i32(tmp3, tmp, 16);
6175 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6176 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6177 tcg_temp_free_i32(tmp);
6178 tcg_gen_ext16u_i32(tmp3, tmp2);
6179 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6180 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6181 tcg_gen_shri_i32(tmp3, tmp2, 16);
6182 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6183 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6184 tcg_temp_free_i32(tmp2);
6185 tcg_temp_free_i32(tmp3);
6189 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6190 if (neon_2rm_is_float_op(op)) {
6191 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6192 neon_reg_offset(rm, pass));
6193 TCGV_UNUSED_I32(tmp);
6195 tmp = neon_load_reg(rm, pass);
6198 case NEON_2RM_VREV32:
6200 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6201 case 1: gen_swap_half(tmp); break;
6205 case NEON_2RM_VREV16:
6210 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6211 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6212 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6218 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6219 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6220 case 2: gen_helper_clz(tmp, tmp); break;
6225 gen_helper_neon_cnt_u8(tmp, tmp);
6228 tcg_gen_not_i32(tmp, tmp);
6230 case NEON_2RM_VQABS:
6233 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6236 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6239 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6244 case NEON_2RM_VQNEG:
6247 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6250 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6253 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6258 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6259 tmp2 = tcg_const_i32(0);
6261 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6262 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6263 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6266 tcg_temp_free_i32(tmp2);
6267 if (op == NEON_2RM_VCLE0) {
6268 tcg_gen_not_i32(tmp, tmp);
6271 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6272 tmp2 = tcg_const_i32(0);
6274 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6275 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6276 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6279 tcg_temp_free_i32(tmp2);
6280 if (op == NEON_2RM_VCLT0) {
6281 tcg_gen_not_i32(tmp, tmp);
6284 case NEON_2RM_VCEQ0:
6285 tmp2 = tcg_const_i32(0);
6287 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6288 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6289 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6292 tcg_temp_free_i32(tmp2);
6296 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6297 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6298 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6303 tmp2 = tcg_const_i32(0);
6304 gen_neon_rsb(size, tmp, tmp2);
6305 tcg_temp_free_i32(tmp2);
6307 case NEON_2RM_VCGT0_F:
6309 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6310 tmp2 = tcg_const_i32(0);
6311 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6312 tcg_temp_free_i32(tmp2);
6313 tcg_temp_free_ptr(fpstatus);
6316 case NEON_2RM_VCGE0_F:
6318 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6319 tmp2 = tcg_const_i32(0);
6320 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6321 tcg_temp_free_i32(tmp2);
6322 tcg_temp_free_ptr(fpstatus);
6325 case NEON_2RM_VCEQ0_F:
6327 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6328 tmp2 = tcg_const_i32(0);
6329 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6330 tcg_temp_free_i32(tmp2);
6331 tcg_temp_free_ptr(fpstatus);
6334 case NEON_2RM_VCLE0_F:
6336 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6337 tmp2 = tcg_const_i32(0);
6338 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6339 tcg_temp_free_i32(tmp2);
6340 tcg_temp_free_ptr(fpstatus);
6343 case NEON_2RM_VCLT0_F:
6345 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6346 tmp2 = tcg_const_i32(0);
6347 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6348 tcg_temp_free_i32(tmp2);
6349 tcg_temp_free_ptr(fpstatus);
6352 case NEON_2RM_VABS_F:
6355 case NEON_2RM_VNEG_F:
6359 tmp2 = neon_load_reg(rd, pass);
6360 neon_store_reg(rm, pass, tmp2);
6363 tmp2 = neon_load_reg(rd, pass);
6365 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6366 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6369 neon_store_reg(rm, pass, tmp2);
6371 case NEON_2RM_VRECPE:
6372 gen_helper_recpe_u32(tmp, tmp, cpu_env);
6374 case NEON_2RM_VRSQRTE:
6375 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6377 case NEON_2RM_VRECPE_F:
6378 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6380 case NEON_2RM_VRSQRTE_F:
6381 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6383 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6386 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6389 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6390 gen_vfp_tosiz(0, 1);
6392 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6393 gen_vfp_touiz(0, 1);
6396 /* Reserved op values were caught by the
6397 * neon_2rm_sizes[] check earlier.
6401 if (neon_2rm_is_float_op(op)) {
6402 tcg_gen_st_f32(cpu_F0s, cpu_env,
6403 neon_reg_offset(rd, pass));
6405 neon_store_reg(rd, pass, tmp);
6410 } else if ((insn & (1 << 10)) == 0) {
6412 int n = ((insn >> 8) & 3) + 1;
6413 if ((rn + n) > 32) {
6414 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6415 * helper function running off the end of the register file.
6420 if (insn & (1 << 6)) {
6421 tmp = neon_load_reg(rd, 0);
6423 tmp = tcg_temp_new_i32();
6424 tcg_gen_movi_i32(tmp, 0);
6426 tmp2 = neon_load_reg(rm, 0);
6427 tmp4 = tcg_const_i32(rn);
6428 tmp5 = tcg_const_i32(n);
6429 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6430 tcg_temp_free_i32(tmp);
6431 if (insn & (1 << 6)) {
6432 tmp = neon_load_reg(rd, 1);
6434 tmp = tcg_temp_new_i32();
6435 tcg_gen_movi_i32(tmp, 0);
6437 tmp3 = neon_load_reg(rm, 1);
6438 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6439 tcg_temp_free_i32(tmp5);
6440 tcg_temp_free_i32(tmp4);
6441 neon_store_reg(rd, 0, tmp2);
6442 neon_store_reg(rd, 1, tmp3);
6443 tcg_temp_free_i32(tmp);
6444 } else if ((insn & 0x380) == 0) {
6446 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6449 if (insn & (1 << 19)) {
6450 tmp = neon_load_reg(rm, 1);
6452 tmp = neon_load_reg(rm, 0);
6454 if (insn & (1 << 16)) {
6455 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6456 } else if (insn & (1 << 17)) {
6457 if ((insn >> 18) & 1)
6458 gen_neon_dup_high16(tmp);
6460 gen_neon_dup_low16(tmp);
6462 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6463 tmp2 = tcg_temp_new_i32();
6464 tcg_gen_mov_i32(tmp2, tmp);
6465 neon_store_reg(rd, pass, tmp2);
6467 tcg_temp_free_i32(tmp);
6476 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6478 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6479 const ARMCPRegInfo *ri;
6480 ARMCPU *cpu = arm_env_get_cpu(env);
6482 cpnum = (insn >> 8) & 0xf;
6483 if (arm_feature(env, ARM_FEATURE_XSCALE)
6484 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6487 /* First check for coprocessor space used for actual instructions */
6491 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6492 return disas_iwmmxt_insn(env, s, insn);
6493 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6494 return disas_dsp_insn(env, s, insn);
6501 /* Otherwise treat as a generic register access */
6502 is64 = (insn & (1 << 25)) == 0;
6503 if (!is64 && ((insn & (1 << 4)) == 0)) {
6511 opc1 = (insn >> 4) & 0xf;
6513 rt2 = (insn >> 16) & 0xf;
6515 crn = (insn >> 16) & 0xf;
6516 opc1 = (insn >> 21) & 7;
6517 opc2 = (insn >> 5) & 7;
6520 isread = (insn >> 20) & 1;
6521 rt = (insn >> 12) & 0xf;
6523 ri = get_arm_cp_reginfo(cpu,
6524 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6526 /* Check access permissions */
6527 if (!cp_access_ok(env, ri, isread)) {
6531 /* Handle special cases first */
6532 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6539 gen_set_pc_im(s, s->pc);
6540 s->is_jmp = DISAS_WFI;
6546 if (use_icount && (ri->type & ARM_CP_IO)) {
6555 if (ri->type & ARM_CP_CONST) {
6556 tmp64 = tcg_const_i64(ri->resetvalue);
6557 } else if (ri->readfn) {
6559 gen_set_pc_im(s, s->pc);
6560 tmp64 = tcg_temp_new_i64();
6561 tmpptr = tcg_const_ptr(ri);
6562 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6563 tcg_temp_free_ptr(tmpptr);
6565 tmp64 = tcg_temp_new_i64();
6566 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6568 tmp = tcg_temp_new_i32();
6569 tcg_gen_trunc_i64_i32(tmp, tmp64);
6570 store_reg(s, rt, tmp);
6571 tcg_gen_shri_i64(tmp64, tmp64, 32);
6572 tmp = tcg_temp_new_i32();
6573 tcg_gen_trunc_i64_i32(tmp, tmp64);
6574 tcg_temp_free_i64(tmp64);
6575 store_reg(s, rt2, tmp);
6578 if (ri->type & ARM_CP_CONST) {
6579 tmp = tcg_const_i32(ri->resetvalue);
6580 } else if (ri->readfn) {
6582 gen_set_pc_im(s, s->pc);
6583 tmp = tcg_temp_new_i32();
6584 tmpptr = tcg_const_ptr(ri);
6585 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6586 tcg_temp_free_ptr(tmpptr);
6588 tmp = load_cpu_offset(ri->fieldoffset);
6591 /* Destination register of r15 for 32 bit loads sets
6592 * the condition codes from the high 4 bits of the value
6595 tcg_temp_free_i32(tmp);
6597 store_reg(s, rt, tmp);
6602 if (ri->type & ARM_CP_CONST) {
6603 /* If not forbidden by access permissions, treat as WI */
6608 TCGv_i32 tmplo, tmphi;
6609 TCGv_i64 tmp64 = tcg_temp_new_i64();
6610 tmplo = load_reg(s, rt);
6611 tmphi = load_reg(s, rt2);
6612 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6613 tcg_temp_free_i32(tmplo);
6614 tcg_temp_free_i32(tmphi);
6616 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6617 gen_set_pc_im(s, s->pc);
6618 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6619 tcg_temp_free_ptr(tmpptr);
6621 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6623 tcg_temp_free_i64(tmp64);
6628 gen_set_pc_im(s, s->pc);
6629 tmp = load_reg(s, rt);
6630 tmpptr = tcg_const_ptr(ri);
6631 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6632 tcg_temp_free_ptr(tmpptr);
6633 tcg_temp_free_i32(tmp);
6635 TCGv_i32 tmp = load_reg(s, rt);
6636 store_cpu_offset(tmp, ri->fieldoffset);
6641 if (use_icount && (ri->type & ARM_CP_IO)) {
6642 /* I/O operations must end the TB here (whether read or write) */
6645 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6646 /* We default to ending the TB on a coprocessor register write,
6647 * but allow this to be suppressed by the register definition
6648 * (usually only necessary to work around guest bugs).
6660 /* Store a 64-bit value to a register pair. Clobbers val. */
6661 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6664 tmp = tcg_temp_new_i32();
6665 tcg_gen_trunc_i64_i32(tmp, val);
6666 store_reg(s, rlow, tmp);
6667 tmp = tcg_temp_new_i32();
6668 tcg_gen_shri_i64(val, val, 32);
6669 tcg_gen_trunc_i64_i32(tmp, val);
6670 store_reg(s, rhigh, tmp);
6673 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6674 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6679 /* Load value and extend to 64 bits. */
6680 tmp = tcg_temp_new_i64();
6681 tmp2 = load_reg(s, rlow);
6682 tcg_gen_extu_i32_i64(tmp, tmp2);
6683 tcg_temp_free_i32(tmp2);
6684 tcg_gen_add_i64(val, val, tmp);
6685 tcg_temp_free_i64(tmp);
6688 /* load and add a 64-bit value from a register pair. */
6689 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6695 /* Load 64-bit value rd:rn. */
6696 tmpl = load_reg(s, rlow);
6697 tmph = load_reg(s, rhigh);
6698 tmp = tcg_temp_new_i64();
6699 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6700 tcg_temp_free_i32(tmpl);
6701 tcg_temp_free_i32(tmph);
6702 tcg_gen_add_i64(val, val, tmp);
6703 tcg_temp_free_i64(tmp);
6706 /* Set N and Z flags from hi|lo. */
6707 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6709 tcg_gen_mov_i32(cpu_NF, hi);
6710 tcg_gen_or_i32(cpu_ZF, lo, hi);
6713 /* Load/Store exclusive instructions are implemented by remembering
6714 the value/address loaded, and seeing if these are the same
6715 when the store is performed. This should be sufficient to implement
6716 the architecturally mandated semantics, and avoids having to monitor
6719 In system emulation mode only one CPU will be running at once, so
6720 this sequence is effectively atomic. In user emulation mode we
6721 throw an exception and handle the atomic operation elsewhere. */
6722 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6723 TCGv_i32 addr, int size)
6725 TCGv_i32 tmp = tcg_temp_new_i32();
6729 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6732 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6736 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6741 tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6742 store_reg(s, rt, tmp);
6744 TCGv_i32 tmp2 = tcg_temp_new_i32();
6745 tcg_gen_addi_i32(tmp2, addr, 4);
6746 tmp = tcg_temp_new_i32();
6747 gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6748 tcg_temp_free_i32(tmp2);
6749 tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6750 store_reg(s, rt2, tmp);
6752 tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6755 static void gen_clrex(DisasContext *s)
6757 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6760 #ifdef CONFIG_USER_ONLY
6761 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6762 TCGv_i32 addr, int size)
6764 tcg_gen_mov_i32(cpu_exclusive_test, addr);
6765 tcg_gen_movi_i32(cpu_exclusive_info,
6766 size | (rd << 4) | (rt << 8) | (rt2 << 12));
6767 gen_exception_insn(s, 4, EXCP_STREX);
6770 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6771 TCGv_i32 addr, int size)
6777 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6783 fail_label = gen_new_label();
6784 done_label = gen_new_label();
6785 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6786 tmp = tcg_temp_new_i32();
6789 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6792 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6796 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6801 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6802 tcg_temp_free_i32(tmp);
6804 TCGv_i32 tmp2 = tcg_temp_new_i32();
6805 tcg_gen_addi_i32(tmp2, addr, 4);
6806 tmp = tcg_temp_new_i32();
6807 gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6808 tcg_temp_free_i32(tmp2);
6809 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6810 tcg_temp_free_i32(tmp);
6812 tmp = load_reg(s, rt);
6815 gen_aa32_st8(tmp, addr, IS_USER(s));
6818 gen_aa32_st16(tmp, addr, IS_USER(s));
6822 gen_aa32_st32(tmp, addr, IS_USER(s));
6827 tcg_temp_free_i32(tmp);
6829 tcg_gen_addi_i32(addr, addr, 4);
6830 tmp = load_reg(s, rt2);
6831 gen_aa32_st32(tmp, addr, IS_USER(s));
6832 tcg_temp_free_i32(tmp);
6834 tcg_gen_movi_i32(cpu_R[rd], 0);
6835 tcg_gen_br(done_label);
6836 gen_set_label(fail_label);
6837 tcg_gen_movi_i32(cpu_R[rd], 1);
6838 gen_set_label(done_label);
6839 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6846 * @mode: mode field from insn (which stack to store to)
6847 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6848 * @writeback: true if writeback bit set
6850 * Generate code for the SRS (Store Return State) insn.
6852 static void gen_srs(DisasContext *s,
6853 uint32_t mode, uint32_t amode, bool writeback)
6856 TCGv_i32 addr = tcg_temp_new_i32();
6857 TCGv_i32 tmp = tcg_const_i32(mode);
6858 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6859 tcg_temp_free_i32(tmp);
6876 tcg_gen_addi_i32(addr, addr, offset);
6877 tmp = load_reg(s, 14);
6878 gen_aa32_st32(tmp, addr, 0);
6879 tcg_temp_free_i32(tmp);
6880 tmp = load_cpu_field(spsr);
6881 tcg_gen_addi_i32(addr, addr, 4);
6882 gen_aa32_st32(tmp, addr, 0);
6883 tcg_temp_free_i32(tmp);
6901 tcg_gen_addi_i32(addr, addr, offset);
6902 tmp = tcg_const_i32(mode);
6903 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6904 tcg_temp_free_i32(tmp);
6906 tcg_temp_free_i32(addr);
6909 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6911 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6918 insn = arm_ldl_code(env, s->pc, s->bswap_code);
6921 /* M variants do not implement ARM mode. */
6926 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6927 * choose to UNDEF. In ARMv5 and above the space is used
6928 * for miscellaneous unconditional instructions.
6932 /* Unconditional instructions. */
6933 if (((insn >> 25) & 7) == 1) {
6934 /* NEON Data processing. */
6935 if (!arm_feature(env, ARM_FEATURE_NEON))
6938 if (disas_neon_data_insn(env, s, insn))
6942 if ((insn & 0x0f100000) == 0x04000000) {
6943 /* NEON load/store. */
6944 if (!arm_feature(env, ARM_FEATURE_NEON))
6947 if (disas_neon_ls_insn(env, s, insn))
6951 if ((insn & 0x0f000e10) == 0x0e000a00) {
6953 if (disas_vfp_insn(env, s, insn)) {
6958 if (((insn & 0x0f30f000) == 0x0510f000) ||
6959 ((insn & 0x0f30f010) == 0x0710f000)) {
6960 if ((insn & (1 << 22)) == 0) {
6962 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6966 /* Otherwise PLD; v5TE+ */
6970 if (((insn & 0x0f70f000) == 0x0450f000) ||
6971 ((insn & 0x0f70f010) == 0x0650f000)) {
6973 return; /* PLI; V7 */
6975 if (((insn & 0x0f700000) == 0x04100000) ||
6976 ((insn & 0x0f700010) == 0x06100000)) {
6977 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6980 return; /* v7MP: Unallocated memory hint: must NOP */
6983 if ((insn & 0x0ffffdff) == 0x01010000) {
6986 if (((insn >> 9) & 1) != s->bswap_code) {
6987 /* Dynamic endianness switching not implemented. */
6988 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
6992 } else if ((insn & 0x0fffff00) == 0x057ff000) {
6993 switch ((insn >> 4) & 0xf) {
7002 /* We don't emulate caches so these are a no-op. */
7007 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7013 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7015 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7021 rn = (insn >> 16) & 0xf;
7022 addr = load_reg(s, rn);
7023 i = (insn >> 23) & 3;
7025 case 0: offset = -4; break; /* DA */
7026 case 1: offset = 0; break; /* IA */
7027 case 2: offset = -8; break; /* DB */
7028 case 3: offset = 4; break; /* IB */
7032 tcg_gen_addi_i32(addr, addr, offset);
7033 /* Load PC into tmp and CPSR into tmp2. */
7034 tmp = tcg_temp_new_i32();
7035 gen_aa32_ld32u(tmp, addr, 0);
7036 tcg_gen_addi_i32(addr, addr, 4);
7037 tmp2 = tcg_temp_new_i32();
7038 gen_aa32_ld32u(tmp2, addr, 0);
7039 if (insn & (1 << 21)) {
7040 /* Base writeback. */
7042 case 0: offset = -8; break;
7043 case 1: offset = 4; break;
7044 case 2: offset = -4; break;
7045 case 3: offset = 0; break;
7049 tcg_gen_addi_i32(addr, addr, offset);
7050 store_reg(s, rn, addr);
7052 tcg_temp_free_i32(addr);
7054 gen_rfe(s, tmp, tmp2);
7056 } else if ((insn & 0x0e000000) == 0x0a000000) {
7057 /* branch link and change to thumb (blx <offset>) */
7060 val = (uint32_t)s->pc;
7061 tmp = tcg_temp_new_i32();
7062 tcg_gen_movi_i32(tmp, val);
7063 store_reg(s, 14, tmp);
7064 /* Sign-extend the 24-bit offset */
7065 offset = (((int32_t)insn) << 8) >> 8;
7066 /* offset * 4 + bit24 * 2 + (thumb bit) */
7067 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7068 /* pipeline offset */
7070 /* protected by ARCH(5); above, near the start of uncond block */
7073 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7074 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7075 /* iWMMXt register transfer. */
7076 if (env->cp15.c15_cpar & (1 << 1))
7077 if (!disas_iwmmxt_insn(env, s, insn))
7080 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7081 /* Coprocessor double register transfer. */
7083 } else if ((insn & 0x0f000010) == 0x0e000010) {
7084 /* Additional coprocessor register transfer. */
7085 } else if ((insn & 0x0ff10020) == 0x01000000) {
7088 /* cps (privileged) */
7092 if (insn & (1 << 19)) {
7093 if (insn & (1 << 8))
7095 if (insn & (1 << 7))
7097 if (insn & (1 << 6))
7099 if (insn & (1 << 18))
7102 if (insn & (1 << 17)) {
7104 val |= (insn & 0x1f);
7107 gen_set_psr_im(s, mask, 0, val);
7114 /* if not always execute, we generate a conditional jump to
7116 s->condlabel = gen_new_label();
7117 gen_test_cc(cond ^ 1, s->condlabel);
7120 if ((insn & 0x0f900000) == 0x03000000) {
7121 if ((insn & (1 << 21)) == 0) {
7123 rd = (insn >> 12) & 0xf;
7124 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7125 if ((insn & (1 << 22)) == 0) {
7127 tmp = tcg_temp_new_i32();
7128 tcg_gen_movi_i32(tmp, val);
7131 tmp = load_reg(s, rd);
7132 tcg_gen_ext16u_i32(tmp, tmp);
7133 tcg_gen_ori_i32(tmp, tmp, val << 16);
7135 store_reg(s, rd, tmp);
7137 if (((insn >> 12) & 0xf) != 0xf)
7139 if (((insn >> 16) & 0xf) == 0) {
7140 gen_nop_hint(s, insn & 0xff);
7142 /* CPSR = immediate */
7144 shift = ((insn >> 8) & 0xf) * 2;
7146 val = (val >> shift) | (val << (32 - shift));
7147 i = ((insn & (1 << 22)) != 0);
7148 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7152 } else if ((insn & 0x0f900000) == 0x01000000
7153 && (insn & 0x00000090) != 0x00000090) {
7154 /* miscellaneous instructions */
7155 op1 = (insn >> 21) & 3;
7156 sh = (insn >> 4) & 0xf;
7159 case 0x0: /* move program status register */
7162 tmp = load_reg(s, rm);
7163 i = ((op1 & 2) != 0);
7164 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7168 rd = (insn >> 12) & 0xf;
7172 tmp = load_cpu_field(spsr);
7174 tmp = tcg_temp_new_i32();
7175 gen_helper_cpsr_read(tmp, cpu_env);
7177 store_reg(s, rd, tmp);
7182 /* branch/exchange thumb (bx). */
7184 tmp = load_reg(s, rm);
7186 } else if (op1 == 3) {
7189 rd = (insn >> 12) & 0xf;
7190 tmp = load_reg(s, rm);
7191 gen_helper_clz(tmp, tmp);
7192 store_reg(s, rd, tmp);
7200 /* Trivial implementation equivalent to bx. */
7201 tmp = load_reg(s, rm);
7212 /* branch link/exchange thumb (blx) */
7213 tmp = load_reg(s, rm);
7214 tmp2 = tcg_temp_new_i32();
7215 tcg_gen_movi_i32(tmp2, s->pc);
7216 store_reg(s, 14, tmp2);
7219 case 0x5: /* saturating add/subtract */
7221 rd = (insn >> 12) & 0xf;
7222 rn = (insn >> 16) & 0xf;
7223 tmp = load_reg(s, rm);
7224 tmp2 = load_reg(s, rn);
7226 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7228 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7230 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7231 tcg_temp_free_i32(tmp2);
7232 store_reg(s, rd, tmp);
7235 /* SMC instruction (op1 == 3)
7236 and undefined instructions (op1 == 0 || op1 == 2)
7243 gen_exception_insn(s, 4, EXCP_BKPT);
7245 case 0x8: /* signed multiply */
7250 rs = (insn >> 8) & 0xf;
7251 rn = (insn >> 12) & 0xf;
7252 rd = (insn >> 16) & 0xf;
7254 /* (32 * 16) >> 16 */
7255 tmp = load_reg(s, rm);
7256 tmp2 = load_reg(s, rs);
7258 tcg_gen_sari_i32(tmp2, tmp2, 16);
7261 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7262 tcg_gen_shri_i64(tmp64, tmp64, 16);
7263 tmp = tcg_temp_new_i32();
7264 tcg_gen_trunc_i64_i32(tmp, tmp64);
7265 tcg_temp_free_i64(tmp64);
7266 if ((sh & 2) == 0) {
7267 tmp2 = load_reg(s, rn);
7268 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7269 tcg_temp_free_i32(tmp2);
7271 store_reg(s, rd, tmp);
7274 tmp = load_reg(s, rm);
7275 tmp2 = load_reg(s, rs);
7276 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7277 tcg_temp_free_i32(tmp2);
7279 tmp64 = tcg_temp_new_i64();
7280 tcg_gen_ext_i32_i64(tmp64, tmp);
7281 tcg_temp_free_i32(tmp);
7282 gen_addq(s, tmp64, rn, rd);
7283 gen_storeq_reg(s, rn, rd, tmp64);
7284 tcg_temp_free_i64(tmp64);
7287 tmp2 = load_reg(s, rn);
7288 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7289 tcg_temp_free_i32(tmp2);
7291 store_reg(s, rd, tmp);
7298 } else if (((insn & 0x0e000000) == 0 &&
7299 (insn & 0x00000090) != 0x90) ||
7300 ((insn & 0x0e000000) == (1 << 25))) {
7301 int set_cc, logic_cc, shiftop;
7303 op1 = (insn >> 21) & 0xf;
7304 set_cc = (insn >> 20) & 1;
7305 logic_cc = table_logic_cc[op1] & set_cc;
7307 /* data processing instruction */
7308 if (insn & (1 << 25)) {
7309 /* immediate operand */
7311 shift = ((insn >> 8) & 0xf) * 2;
7313 val = (val >> shift) | (val << (32 - shift));
7315 tmp2 = tcg_temp_new_i32();
7316 tcg_gen_movi_i32(tmp2, val);
7317 if (logic_cc && shift) {
7318 gen_set_CF_bit31(tmp2);
7323 tmp2 = load_reg(s, rm);
7324 shiftop = (insn >> 5) & 3;
7325 if (!(insn & (1 << 4))) {
7326 shift = (insn >> 7) & 0x1f;
7327 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7329 rs = (insn >> 8) & 0xf;
7330 tmp = load_reg(s, rs);
7331 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7334 if (op1 != 0x0f && op1 != 0x0d) {
7335 rn = (insn >> 16) & 0xf;
7336 tmp = load_reg(s, rn);
7338 TCGV_UNUSED_I32(tmp);
7340 rd = (insn >> 12) & 0xf;
7343 tcg_gen_and_i32(tmp, tmp, tmp2);
7347 store_reg_bx(env, s, rd, tmp);
7350 tcg_gen_xor_i32(tmp, tmp, tmp2);
7354 store_reg_bx(env, s, rd, tmp);
7357 if (set_cc && rd == 15) {
7358 /* SUBS r15, ... is used for exception return. */
7362 gen_sub_CC(tmp, tmp, tmp2);
7363 gen_exception_return(s, tmp);
7366 gen_sub_CC(tmp, tmp, tmp2);
7368 tcg_gen_sub_i32(tmp, tmp, tmp2);
7370 store_reg_bx(env, s, rd, tmp);
7375 gen_sub_CC(tmp, tmp2, tmp);
7377 tcg_gen_sub_i32(tmp, tmp2, tmp);
7379 store_reg_bx(env, s, rd, tmp);
7383 gen_add_CC(tmp, tmp, tmp2);
7385 tcg_gen_add_i32(tmp, tmp, tmp2);
7387 store_reg_bx(env, s, rd, tmp);
7391 gen_adc_CC(tmp, tmp, tmp2);
7393 gen_add_carry(tmp, tmp, tmp2);
7395 store_reg_bx(env, s, rd, tmp);
7399 gen_sbc_CC(tmp, tmp, tmp2);
7401 gen_sub_carry(tmp, tmp, tmp2);
7403 store_reg_bx(env, s, rd, tmp);
7407 gen_sbc_CC(tmp, tmp2, tmp);
7409 gen_sub_carry(tmp, tmp2, tmp);
7411 store_reg_bx(env, s, rd, tmp);
7415 tcg_gen_and_i32(tmp, tmp, tmp2);
7418 tcg_temp_free_i32(tmp);
7422 tcg_gen_xor_i32(tmp, tmp, tmp2);
7425 tcg_temp_free_i32(tmp);
7429 gen_sub_CC(tmp, tmp, tmp2);
7431 tcg_temp_free_i32(tmp);
7435 gen_add_CC(tmp, tmp, tmp2);
7437 tcg_temp_free_i32(tmp);
7440 tcg_gen_or_i32(tmp, tmp, tmp2);
7444 store_reg_bx(env, s, rd, tmp);
7447 if (logic_cc && rd == 15) {
7448 /* MOVS r15, ... is used for exception return. */
7452 gen_exception_return(s, tmp2);
7457 store_reg_bx(env, s, rd, tmp2);
7461 tcg_gen_andc_i32(tmp, tmp, tmp2);
7465 store_reg_bx(env, s, rd, tmp);
7469 tcg_gen_not_i32(tmp2, tmp2);
7473 store_reg_bx(env, s, rd, tmp2);
7476 if (op1 != 0x0f && op1 != 0x0d) {
7477 tcg_temp_free_i32(tmp2);
7480 /* other instructions */
7481 op1 = (insn >> 24) & 0xf;
7485 /* multiplies, extra load/stores */
7486 sh = (insn >> 5) & 3;
7489 rd = (insn >> 16) & 0xf;
7490 rn = (insn >> 12) & 0xf;
7491 rs = (insn >> 8) & 0xf;
7493 op1 = (insn >> 20) & 0xf;
7495 case 0: case 1: case 2: case 3: case 6:
7497 tmp = load_reg(s, rs);
7498 tmp2 = load_reg(s, rm);
7499 tcg_gen_mul_i32(tmp, tmp, tmp2);
7500 tcg_temp_free_i32(tmp2);
7501 if (insn & (1 << 22)) {
7502 /* Subtract (mls) */
7504 tmp2 = load_reg(s, rn);
7505 tcg_gen_sub_i32(tmp, tmp2, tmp);
7506 tcg_temp_free_i32(tmp2);
7507 } else if (insn & (1 << 21)) {
7509 tmp2 = load_reg(s, rn);
7510 tcg_gen_add_i32(tmp, tmp, tmp2);
7511 tcg_temp_free_i32(tmp2);
7513 if (insn & (1 << 20))
7515 store_reg(s, rd, tmp);
7518 /* 64 bit mul double accumulate (UMAAL) */
7520 tmp = load_reg(s, rs);
7521 tmp2 = load_reg(s, rm);
7522 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7523 gen_addq_lo(s, tmp64, rn);
7524 gen_addq_lo(s, tmp64, rd);
7525 gen_storeq_reg(s, rn, rd, tmp64);
7526 tcg_temp_free_i64(tmp64);
7528 case 8: case 9: case 10: case 11:
7529 case 12: case 13: case 14: case 15:
7530 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7531 tmp = load_reg(s, rs);
7532 tmp2 = load_reg(s, rm);
7533 if (insn & (1 << 22)) {
7534 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7536 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7538 if (insn & (1 << 21)) { /* mult accumulate */
7539 TCGv_i32 al = load_reg(s, rn);
7540 TCGv_i32 ah = load_reg(s, rd);
7541 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7542 tcg_temp_free_i32(al);
7543 tcg_temp_free_i32(ah);
7545 if (insn & (1 << 20)) {
7546 gen_logicq_cc(tmp, tmp2);
7548 store_reg(s, rn, tmp);
7549 store_reg(s, rd, tmp2);
7555 rn = (insn >> 16) & 0xf;
7556 rd = (insn >> 12) & 0xf;
7557 if (insn & (1 << 23)) {
7558 /* load/store exclusive */
7559 int op2 = (insn >> 8) & 3;
7560 op1 = (insn >> 21) & 0x3;
7563 case 0: /* lda/stl */
7569 case 1: /* reserved */
7571 case 2: /* ldaex/stlex */
7574 case 3: /* ldrex/strex */
7583 addr = tcg_temp_local_new_i32();
7584 load_reg_var(s, addr, rn);
7586 /* Since the emulation does not have barriers,
7587 the acquire/release semantics need no special
7590 if (insn & (1 << 20)) {
7591 tmp = tcg_temp_new_i32();
7594 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7597 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7600 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7605 store_reg(s, rd, tmp);
7608 tmp = load_reg(s, rm);
7611 gen_aa32_st32(tmp, addr, IS_USER(s));
7614 gen_aa32_st8(tmp, addr, IS_USER(s));
7617 gen_aa32_st16(tmp, addr, IS_USER(s));
7622 tcg_temp_free_i32(tmp);
7624 } else if (insn & (1 << 20)) {
7627 gen_load_exclusive(s, rd, 15, addr, 2);
7629 case 1: /* ldrexd */
7630 gen_load_exclusive(s, rd, rd + 1, addr, 3);
7632 case 2: /* ldrexb */
7633 gen_load_exclusive(s, rd, 15, addr, 0);
7635 case 3: /* ldrexh */
7636 gen_load_exclusive(s, rd, 15, addr, 1);
7645 gen_store_exclusive(s, rd, rm, 15, addr, 2);
7647 case 1: /* strexd */
7648 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7650 case 2: /* strexb */
7651 gen_store_exclusive(s, rd, rm, 15, addr, 0);
7653 case 3: /* strexh */
7654 gen_store_exclusive(s, rd, rm, 15, addr, 1);
7660 tcg_temp_free_i32(addr);
7662 /* SWP instruction */
7665 /* ??? This is not really atomic. However we know
7666 we never have multiple CPUs running in parallel,
7667 so it is good enough. */
7668 addr = load_reg(s, rn);
7669 tmp = load_reg(s, rm);
7670 tmp2 = tcg_temp_new_i32();
7671 if (insn & (1 << 22)) {
7672 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7673 gen_aa32_st8(tmp, addr, IS_USER(s));
7675 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7676 gen_aa32_st32(tmp, addr, IS_USER(s));
7678 tcg_temp_free_i32(tmp);
7679 tcg_temp_free_i32(addr);
7680 store_reg(s, rd, tmp2);
7686 /* Misc load/store */
7687 rn = (insn >> 16) & 0xf;
7688 rd = (insn >> 12) & 0xf;
7689 addr = load_reg(s, rn);
7690 if (insn & (1 << 24))
7691 gen_add_datah_offset(s, insn, 0, addr);
7693 if (insn & (1 << 20)) {
7695 tmp = tcg_temp_new_i32();
7698 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7701 gen_aa32_ld8s(tmp, addr, IS_USER(s));
7705 gen_aa32_ld16s(tmp, addr, IS_USER(s));
7709 } else if (sh & 2) {
7714 tmp = load_reg(s, rd);
7715 gen_aa32_st32(tmp, addr, IS_USER(s));
7716 tcg_temp_free_i32(tmp);
7717 tcg_gen_addi_i32(addr, addr, 4);
7718 tmp = load_reg(s, rd + 1);
7719 gen_aa32_st32(tmp, addr, IS_USER(s));
7720 tcg_temp_free_i32(tmp);
7724 tmp = tcg_temp_new_i32();
7725 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7726 store_reg(s, rd, tmp);
7727 tcg_gen_addi_i32(addr, addr, 4);
7728 tmp = tcg_temp_new_i32();
7729 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7733 address_offset = -4;
7736 tmp = load_reg(s, rd);
7737 gen_aa32_st16(tmp, addr, IS_USER(s));
7738 tcg_temp_free_i32(tmp);
7741 /* Perform base writeback before the loaded value to
7742 ensure correct behavior with overlapping index registers.
7743 ldrd with base writeback is is undefined if the
7744 destination and index registers overlap. */
7745 if (!(insn & (1 << 24))) {
7746 gen_add_datah_offset(s, insn, address_offset, addr);
7747 store_reg(s, rn, addr);
7748 } else if (insn & (1 << 21)) {
7750 tcg_gen_addi_i32(addr, addr, address_offset);
7751 store_reg(s, rn, addr);
7753 tcg_temp_free_i32(addr);
7756 /* Complete the load. */
7757 store_reg(s, rd, tmp);
7766 if (insn & (1 << 4)) {
7768 /* Armv6 Media instructions. */
7770 rn = (insn >> 16) & 0xf;
7771 rd = (insn >> 12) & 0xf;
7772 rs = (insn >> 8) & 0xf;
7773 switch ((insn >> 23) & 3) {
7774 case 0: /* Parallel add/subtract. */
7775 op1 = (insn >> 20) & 7;
7776 tmp = load_reg(s, rn);
7777 tmp2 = load_reg(s, rm);
7778 sh = (insn >> 5) & 7;
7779 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7781 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7782 tcg_temp_free_i32(tmp2);
7783 store_reg(s, rd, tmp);
7786 if ((insn & 0x00700020) == 0) {
7787 /* Halfword pack. */
7788 tmp = load_reg(s, rn);
7789 tmp2 = load_reg(s, rm);
7790 shift = (insn >> 7) & 0x1f;
7791 if (insn & (1 << 6)) {
7795 tcg_gen_sari_i32(tmp2, tmp2, shift);
7796 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7797 tcg_gen_ext16u_i32(tmp2, tmp2);
7801 tcg_gen_shli_i32(tmp2, tmp2, shift);
7802 tcg_gen_ext16u_i32(tmp, tmp);
7803 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7805 tcg_gen_or_i32(tmp, tmp, tmp2);
7806 tcg_temp_free_i32(tmp2);
7807 store_reg(s, rd, tmp);
7808 } else if ((insn & 0x00200020) == 0x00200000) {
7810 tmp = load_reg(s, rm);
7811 shift = (insn >> 7) & 0x1f;
7812 if (insn & (1 << 6)) {
7815 tcg_gen_sari_i32(tmp, tmp, shift);
7817 tcg_gen_shli_i32(tmp, tmp, shift);
7819 sh = (insn >> 16) & 0x1f;
7820 tmp2 = tcg_const_i32(sh);
7821 if (insn & (1 << 22))
7822 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7824 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7825 tcg_temp_free_i32(tmp2);
7826 store_reg(s, rd, tmp);
7827 } else if ((insn & 0x00300fe0) == 0x00200f20) {
7829 tmp = load_reg(s, rm);
7830 sh = (insn >> 16) & 0x1f;
7831 tmp2 = tcg_const_i32(sh);
7832 if (insn & (1 << 22))
7833 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7835 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7836 tcg_temp_free_i32(tmp2);
7837 store_reg(s, rd, tmp);
7838 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7840 tmp = load_reg(s, rn);
7841 tmp2 = load_reg(s, rm);
7842 tmp3 = tcg_temp_new_i32();
7843 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7844 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7845 tcg_temp_free_i32(tmp3);
7846 tcg_temp_free_i32(tmp2);
7847 store_reg(s, rd, tmp);
7848 } else if ((insn & 0x000003e0) == 0x00000060) {
7849 tmp = load_reg(s, rm);
7850 shift = (insn >> 10) & 3;
7851 /* ??? In many cases it's not necessary to do a
7852 rotate, a shift is sufficient. */
7854 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7855 op1 = (insn >> 20) & 7;
7857 case 0: gen_sxtb16(tmp); break;
7858 case 2: gen_sxtb(tmp); break;
7859 case 3: gen_sxth(tmp); break;
7860 case 4: gen_uxtb16(tmp); break;
7861 case 6: gen_uxtb(tmp); break;
7862 case 7: gen_uxth(tmp); break;
7863 default: goto illegal_op;
7866 tmp2 = load_reg(s, rn);
7867 if ((op1 & 3) == 0) {
7868 gen_add16(tmp, tmp2);
7870 tcg_gen_add_i32(tmp, tmp, tmp2);
7871 tcg_temp_free_i32(tmp2);
7874 store_reg(s, rd, tmp);
7875 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7877 tmp = load_reg(s, rm);
7878 if (insn & (1 << 22)) {
7879 if (insn & (1 << 7)) {
7883 gen_helper_rbit(tmp, tmp);
7886 if (insn & (1 << 7))
7889 tcg_gen_bswap32_i32(tmp, tmp);
7891 store_reg(s, rd, tmp);
7896 case 2: /* Multiplies (Type 3). */
7897 switch ((insn >> 20) & 0x7) {
7899 if (((insn >> 6) ^ (insn >> 7)) & 1) {
7900 /* op2 not 00x or 11x : UNDEF */
7903 /* Signed multiply most significant [accumulate].
7904 (SMMUL, SMMLA, SMMLS) */
7905 tmp = load_reg(s, rm);
7906 tmp2 = load_reg(s, rs);
7907 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7910 tmp = load_reg(s, rd);
7911 if (insn & (1 << 6)) {
7912 tmp64 = gen_subq_msw(tmp64, tmp);
7914 tmp64 = gen_addq_msw(tmp64, tmp);
7917 if (insn & (1 << 5)) {
7918 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7920 tcg_gen_shri_i64(tmp64, tmp64, 32);
7921 tmp = tcg_temp_new_i32();
7922 tcg_gen_trunc_i64_i32(tmp, tmp64);
7923 tcg_temp_free_i64(tmp64);
7924 store_reg(s, rn, tmp);
7928 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7929 if (insn & (1 << 7)) {
7932 tmp = load_reg(s, rm);
7933 tmp2 = load_reg(s, rs);
7934 if (insn & (1 << 5))
7935 gen_swap_half(tmp2);
7936 gen_smul_dual(tmp, tmp2);
7937 if (insn & (1 << 6)) {
7938 /* This subtraction cannot overflow. */
7939 tcg_gen_sub_i32(tmp, tmp, tmp2);
7941 /* This addition cannot overflow 32 bits;
7942 * however it may overflow considered as a signed
7943 * operation, in which case we must set the Q flag.
7945 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7947 tcg_temp_free_i32(tmp2);
7948 if (insn & (1 << 22)) {
7949 /* smlald, smlsld */
7950 tmp64 = tcg_temp_new_i64();
7951 tcg_gen_ext_i32_i64(tmp64, tmp);
7952 tcg_temp_free_i32(tmp);
7953 gen_addq(s, tmp64, rd, rn);
7954 gen_storeq_reg(s, rd, rn, tmp64);
7955 tcg_temp_free_i64(tmp64);
7957 /* smuad, smusd, smlad, smlsd */
7960 tmp2 = load_reg(s, rd);
7961 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7962 tcg_temp_free_i32(tmp2);
7964 store_reg(s, rn, tmp);
7970 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7973 if (((insn >> 5) & 7) || (rd != 15)) {
7976 tmp = load_reg(s, rm);
7977 tmp2 = load_reg(s, rs);
7978 if (insn & (1 << 21)) {
7979 gen_helper_udiv(tmp, tmp, tmp2);
7981 gen_helper_sdiv(tmp, tmp, tmp2);
7983 tcg_temp_free_i32(tmp2);
7984 store_reg(s, rn, tmp);
7991 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7993 case 0: /* Unsigned sum of absolute differences. */
7995 tmp = load_reg(s, rm);
7996 tmp2 = load_reg(s, rs);
7997 gen_helper_usad8(tmp, tmp, tmp2);
7998 tcg_temp_free_i32(tmp2);
8000 tmp2 = load_reg(s, rd);
8001 tcg_gen_add_i32(tmp, tmp, tmp2);
8002 tcg_temp_free_i32(tmp2);
8004 store_reg(s, rn, tmp);
8006 case 0x20: case 0x24: case 0x28: case 0x2c:
8007 /* Bitfield insert/clear. */
8009 shift = (insn >> 7) & 0x1f;
8010 i = (insn >> 16) & 0x1f;
8013 tmp = tcg_temp_new_i32();
8014 tcg_gen_movi_i32(tmp, 0);
8016 tmp = load_reg(s, rm);
8019 tmp2 = load_reg(s, rd);
8020 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8021 tcg_temp_free_i32(tmp2);
8023 store_reg(s, rd, tmp);
8025 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8026 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8028 tmp = load_reg(s, rm);
8029 shift = (insn >> 7) & 0x1f;
8030 i = ((insn >> 16) & 0x1f) + 1;
8035 gen_ubfx(tmp, shift, (1u << i) - 1);
8037 gen_sbfx(tmp, shift, i);
8040 store_reg(s, rd, tmp);
8050 /* Check for undefined extension instructions
8051 * per the ARM Bible IE:
8052 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8054 sh = (0xf << 20) | (0xf << 4);
8055 if (op1 == 0x7 && ((insn & sh) == sh))
8059 /* load/store byte/word */
8060 rn = (insn >> 16) & 0xf;
8061 rd = (insn >> 12) & 0xf;
8062 tmp2 = load_reg(s, rn);
8063 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8064 if (insn & (1 << 24))
8065 gen_add_data_offset(s, insn, tmp2);
8066 if (insn & (1 << 20)) {
8068 tmp = tcg_temp_new_i32();
8069 if (insn & (1 << 22)) {
8070 gen_aa32_ld8u(tmp, tmp2, i);
8072 gen_aa32_ld32u(tmp, tmp2, i);
8076 tmp = load_reg(s, rd);
8077 if (insn & (1 << 22)) {
8078 gen_aa32_st8(tmp, tmp2, i);
8080 gen_aa32_st32(tmp, tmp2, i);
8082 tcg_temp_free_i32(tmp);
8084 if (!(insn & (1 << 24))) {
8085 gen_add_data_offset(s, insn, tmp2);
8086 store_reg(s, rn, tmp2);
8087 } else if (insn & (1 << 21)) {
8088 store_reg(s, rn, tmp2);
8090 tcg_temp_free_i32(tmp2);
8092 if (insn & (1 << 20)) {
8093 /* Complete the load. */
8094 store_reg_from_load(env, s, rd, tmp);
8100 int j, n, user, loaded_base;
8101 TCGv_i32 loaded_var;
8102 /* load/store multiple words */
8103 /* XXX: store correct base if write back */
8105 if (insn & (1 << 22)) {
8107 goto illegal_op; /* only usable in supervisor mode */
8109 if ((insn & (1 << 15)) == 0)
8112 rn = (insn >> 16) & 0xf;
8113 addr = load_reg(s, rn);
8115 /* compute total size */
8117 TCGV_UNUSED_I32(loaded_var);
8120 if (insn & (1 << i))
8123 /* XXX: test invalid n == 0 case ? */
8124 if (insn & (1 << 23)) {
8125 if (insn & (1 << 24)) {
8127 tcg_gen_addi_i32(addr, addr, 4);
8129 /* post increment */
8132 if (insn & (1 << 24)) {
8134 tcg_gen_addi_i32(addr, addr, -(n * 4));
8136 /* post decrement */
8138 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8143 if (insn & (1 << i)) {
8144 if (insn & (1 << 20)) {
8146 tmp = tcg_temp_new_i32();
8147 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8149 tmp2 = tcg_const_i32(i);
8150 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8151 tcg_temp_free_i32(tmp2);
8152 tcg_temp_free_i32(tmp);
8153 } else if (i == rn) {
8157 store_reg_from_load(env, s, i, tmp);
8162 /* special case: r15 = PC + 8 */
8163 val = (long)s->pc + 4;
8164 tmp = tcg_temp_new_i32();
8165 tcg_gen_movi_i32(tmp, val);
8167 tmp = tcg_temp_new_i32();
8168 tmp2 = tcg_const_i32(i);
8169 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8170 tcg_temp_free_i32(tmp2);
8172 tmp = load_reg(s, i);
8174 gen_aa32_st32(tmp, addr, IS_USER(s));
8175 tcg_temp_free_i32(tmp);
8178 /* no need to add after the last transfer */
8180 tcg_gen_addi_i32(addr, addr, 4);
8183 if (insn & (1 << 21)) {
8185 if (insn & (1 << 23)) {
8186 if (insn & (1 << 24)) {
8189 /* post increment */
8190 tcg_gen_addi_i32(addr, addr, 4);
8193 if (insn & (1 << 24)) {
8196 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8198 /* post decrement */
8199 tcg_gen_addi_i32(addr, addr, -(n * 4));
8202 store_reg(s, rn, addr);
8204 tcg_temp_free_i32(addr);
8207 store_reg(s, rn, loaded_var);
8209 if ((insn & (1 << 22)) && !user) {
8210 /* Restore CPSR from SPSR. */
8211 tmp = load_cpu_field(spsr);
8212 gen_set_cpsr(tmp, 0xffffffff);
8213 tcg_temp_free_i32(tmp);
8214 s->is_jmp = DISAS_UPDATE;
8223 /* branch (and link) */
8224 val = (int32_t)s->pc;
8225 if (insn & (1 << 24)) {
8226 tmp = tcg_temp_new_i32();
8227 tcg_gen_movi_i32(tmp, val);
8228 store_reg(s, 14, tmp);
8230 offset = sextract32(insn << 2, 0, 26);
8238 if (((insn >> 8) & 0xe) == 10) {
8240 if (disas_vfp_insn(env, s, insn)) {
8243 } else if (disas_coproc_insn(env, s, insn)) {
8250 gen_set_pc_im(s, s->pc);
8251 s->is_jmp = DISAS_SWI;
8255 gen_exception_insn(s, 4, EXCP_UDEF);
8261 /* Return true if this is a Thumb-2 logical op. */
8263 thumb2_logic_op(int op)
8268 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8269 then set condition code flags based on the result of the operation.
8270 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8271 to the high bit of T1.
8272 Returns zero if the opcode is valid. */
8275 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8276 TCGv_i32 t0, TCGv_i32 t1)
8283 tcg_gen_and_i32(t0, t0, t1);
8287 tcg_gen_andc_i32(t0, t0, t1);
8291 tcg_gen_or_i32(t0, t0, t1);
8295 tcg_gen_orc_i32(t0, t0, t1);
8299 tcg_gen_xor_i32(t0, t0, t1);
8304 gen_add_CC(t0, t0, t1);
8306 tcg_gen_add_i32(t0, t0, t1);
8310 gen_adc_CC(t0, t0, t1);
8316 gen_sbc_CC(t0, t0, t1);
8318 gen_sub_carry(t0, t0, t1);
8323 gen_sub_CC(t0, t0, t1);
8325 tcg_gen_sub_i32(t0, t0, t1);
8329 gen_sub_CC(t0, t1, t0);
8331 tcg_gen_sub_i32(t0, t1, t0);
8333 default: /* 5, 6, 7, 9, 12, 15. */
8339 gen_set_CF_bit31(t1);
8344 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8346 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8348 uint32_t insn, imm, shift, offset;
8349 uint32_t rd, rn, rm, rs;
8360 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8361 || arm_feature (env, ARM_FEATURE_M))) {
8362 /* Thumb-1 cores may need to treat bl and blx as a pair of
8363 16-bit instructions to get correct prefetch abort behavior. */
8365 if ((insn & (1 << 12)) == 0) {
8367 /* Second half of blx. */
8368 offset = ((insn & 0x7ff) << 1);
8369 tmp = load_reg(s, 14);
8370 tcg_gen_addi_i32(tmp, tmp, offset);
8371 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8373 tmp2 = tcg_temp_new_i32();
8374 tcg_gen_movi_i32(tmp2, s->pc | 1);
8375 store_reg(s, 14, tmp2);
8379 if (insn & (1 << 11)) {
8380 /* Second half of bl. */
8381 offset = ((insn & 0x7ff) << 1) | 1;
8382 tmp = load_reg(s, 14);
8383 tcg_gen_addi_i32(tmp, tmp, offset);
8385 tmp2 = tcg_temp_new_i32();
8386 tcg_gen_movi_i32(tmp2, s->pc | 1);
8387 store_reg(s, 14, tmp2);
8391 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8392 /* Instruction spans a page boundary. Implement it as two
8393 16-bit instructions in case the second half causes an
8395 offset = ((int32_t)insn << 21) >> 9;
8396 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8399 /* Fall through to 32-bit decode. */
8402 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8404 insn |= (uint32_t)insn_hw1 << 16;
8406 if ((insn & 0xf800e800) != 0xf000e800) {
8410 rn = (insn >> 16) & 0xf;
8411 rs = (insn >> 12) & 0xf;
8412 rd = (insn >> 8) & 0xf;
8414 switch ((insn >> 25) & 0xf) {
8415 case 0: case 1: case 2: case 3:
8416 /* 16-bit instructions. Should never happen. */
8419 if (insn & (1 << 22)) {
8420 /* Other load/store, table branch. */
8421 if (insn & 0x01200000) {
8422 /* Load/store doubleword. */
8424 addr = tcg_temp_new_i32();
8425 tcg_gen_movi_i32(addr, s->pc & ~3);
8427 addr = load_reg(s, rn);
8429 offset = (insn & 0xff) * 4;
8430 if ((insn & (1 << 23)) == 0)
8432 if (insn & (1 << 24)) {
8433 tcg_gen_addi_i32(addr, addr, offset);
8436 if (insn & (1 << 20)) {
8438 tmp = tcg_temp_new_i32();
8439 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8440 store_reg(s, rs, tmp);
8441 tcg_gen_addi_i32(addr, addr, 4);
8442 tmp = tcg_temp_new_i32();
8443 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8444 store_reg(s, rd, tmp);
8447 tmp = load_reg(s, rs);
8448 gen_aa32_st32(tmp, addr, IS_USER(s));
8449 tcg_temp_free_i32(tmp);
8450 tcg_gen_addi_i32(addr, addr, 4);
8451 tmp = load_reg(s, rd);
8452 gen_aa32_st32(tmp, addr, IS_USER(s));
8453 tcg_temp_free_i32(tmp);
8455 if (insn & (1 << 21)) {
8456 /* Base writeback. */
8459 tcg_gen_addi_i32(addr, addr, offset - 4);
8460 store_reg(s, rn, addr);
8462 tcg_temp_free_i32(addr);
8464 } else if ((insn & (1 << 23)) == 0) {
8465 /* Load/store exclusive word. */
8466 addr = tcg_temp_local_new_i32();
8467 load_reg_var(s, addr, rn);
8468 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8469 if (insn & (1 << 20)) {
8470 gen_load_exclusive(s, rs, 15, addr, 2);
8472 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8474 tcg_temp_free_i32(addr);
8475 } else if ((insn & (7 << 5)) == 0) {
8478 addr = tcg_temp_new_i32();
8479 tcg_gen_movi_i32(addr, s->pc);
8481 addr = load_reg(s, rn);
8483 tmp = load_reg(s, rm);
8484 tcg_gen_add_i32(addr, addr, tmp);
8485 if (insn & (1 << 4)) {
8487 tcg_gen_add_i32(addr, addr, tmp);
8488 tcg_temp_free_i32(tmp);
8489 tmp = tcg_temp_new_i32();
8490 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8492 tcg_temp_free_i32(tmp);
8493 tmp = tcg_temp_new_i32();
8494 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8496 tcg_temp_free_i32(addr);
8497 tcg_gen_shli_i32(tmp, tmp, 1);
8498 tcg_gen_addi_i32(tmp, tmp, s->pc);
8499 store_reg(s, 15, tmp);
8501 int op2 = (insn >> 6) & 0x3;
8502 op = (insn >> 4) & 0x3;
8507 /* Load/store exclusive byte/halfword/doubleword */
8514 /* Load-acquire/store-release */
8520 /* Load-acquire/store-release exclusive */
8524 addr = tcg_temp_local_new_i32();
8525 load_reg_var(s, addr, rn);
8527 if (insn & (1 << 20)) {
8528 tmp = tcg_temp_new_i32();
8531 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8534 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8537 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8542 store_reg(s, rs, tmp);
8544 tmp = load_reg(s, rs);
8547 gen_aa32_st8(tmp, addr, IS_USER(s));
8550 gen_aa32_st16(tmp, addr, IS_USER(s));
8553 gen_aa32_st32(tmp, addr, IS_USER(s));
8558 tcg_temp_free_i32(tmp);
8560 } else if (insn & (1 << 20)) {
8561 gen_load_exclusive(s, rs, rd, addr, op);
8563 gen_store_exclusive(s, rm, rs, rd, addr, op);
8565 tcg_temp_free_i32(addr);
8568 /* Load/store multiple, RFE, SRS. */
8569 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8570 /* RFE, SRS: not available in user mode or on M profile */
8571 if (IS_USER(s) || IS_M(env)) {
8574 if (insn & (1 << 20)) {
8576 addr = load_reg(s, rn);
8577 if ((insn & (1 << 24)) == 0)
8578 tcg_gen_addi_i32(addr, addr, -8);
8579 /* Load PC into tmp and CPSR into tmp2. */
8580 tmp = tcg_temp_new_i32();
8581 gen_aa32_ld32u(tmp, addr, 0);
8582 tcg_gen_addi_i32(addr, addr, 4);
8583 tmp2 = tcg_temp_new_i32();
8584 gen_aa32_ld32u(tmp2, addr, 0);
8585 if (insn & (1 << 21)) {
8586 /* Base writeback. */
8587 if (insn & (1 << 24)) {
8588 tcg_gen_addi_i32(addr, addr, 4);
8590 tcg_gen_addi_i32(addr, addr, -4);
8592 store_reg(s, rn, addr);
8594 tcg_temp_free_i32(addr);
8596 gen_rfe(s, tmp, tmp2);
8599 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8603 int i, loaded_base = 0;
8604 TCGv_i32 loaded_var;
8605 /* Load/store multiple. */
8606 addr = load_reg(s, rn);
8608 for (i = 0; i < 16; i++) {
8609 if (insn & (1 << i))
8612 if (insn & (1 << 24)) {
8613 tcg_gen_addi_i32(addr, addr, -offset);
8616 TCGV_UNUSED_I32(loaded_var);
8617 for (i = 0; i < 16; i++) {
8618 if ((insn & (1 << i)) == 0)
8620 if (insn & (1 << 20)) {
8622 tmp = tcg_temp_new_i32();
8623 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8626 } else if (i == rn) {
8630 store_reg(s, i, tmp);
8634 tmp = load_reg(s, i);
8635 gen_aa32_st32(tmp, addr, IS_USER(s));
8636 tcg_temp_free_i32(tmp);
8638 tcg_gen_addi_i32(addr, addr, 4);
8641 store_reg(s, rn, loaded_var);
8643 if (insn & (1 << 21)) {
8644 /* Base register writeback. */
8645 if (insn & (1 << 24)) {
8646 tcg_gen_addi_i32(addr, addr, -offset);
8648 /* Fault if writeback register is in register list. */
8649 if (insn & (1 << rn))
8651 store_reg(s, rn, addr);
8653 tcg_temp_free_i32(addr);
8660 op = (insn >> 21) & 0xf;
8662 /* Halfword pack. */
8663 tmp = load_reg(s, rn);
8664 tmp2 = load_reg(s, rm);
8665 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8666 if (insn & (1 << 5)) {
8670 tcg_gen_sari_i32(tmp2, tmp2, shift);
8671 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8672 tcg_gen_ext16u_i32(tmp2, tmp2);
8676 tcg_gen_shli_i32(tmp2, tmp2, shift);
8677 tcg_gen_ext16u_i32(tmp, tmp);
8678 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8680 tcg_gen_or_i32(tmp, tmp, tmp2);
8681 tcg_temp_free_i32(tmp2);
8682 store_reg(s, rd, tmp);
8684 /* Data processing register constant shift. */
8686 tmp = tcg_temp_new_i32();
8687 tcg_gen_movi_i32(tmp, 0);
8689 tmp = load_reg(s, rn);
8691 tmp2 = load_reg(s, rm);
8693 shiftop = (insn >> 4) & 3;
8694 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8695 conds = (insn & (1 << 20)) != 0;
8696 logic_cc = (conds && thumb2_logic_op(op));
8697 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8698 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8700 tcg_temp_free_i32(tmp2);
8702 store_reg(s, rd, tmp);
8704 tcg_temp_free_i32(tmp);
8708 case 13: /* Misc data processing. */
8709 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8710 if (op < 4 && (insn & 0xf000) != 0xf000)
8713 case 0: /* Register controlled shift. */
8714 tmp = load_reg(s, rn);
8715 tmp2 = load_reg(s, rm);
8716 if ((insn & 0x70) != 0)
8718 op = (insn >> 21) & 3;
8719 logic_cc = (insn & (1 << 20)) != 0;
8720 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8723 store_reg_bx(env, s, rd, tmp);
8725 case 1: /* Sign/zero extend. */
8726 tmp = load_reg(s, rm);
8727 shift = (insn >> 4) & 3;
8728 /* ??? In many cases it's not necessary to do a
8729 rotate, a shift is sufficient. */
8731 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8732 op = (insn >> 20) & 7;
8734 case 0: gen_sxth(tmp); break;
8735 case 1: gen_uxth(tmp); break;
8736 case 2: gen_sxtb16(tmp); break;
8737 case 3: gen_uxtb16(tmp); break;
8738 case 4: gen_sxtb(tmp); break;
8739 case 5: gen_uxtb(tmp); break;
8740 default: goto illegal_op;
8743 tmp2 = load_reg(s, rn);
8744 if ((op >> 1) == 1) {
8745 gen_add16(tmp, tmp2);
8747 tcg_gen_add_i32(tmp, tmp, tmp2);
8748 tcg_temp_free_i32(tmp2);
8751 store_reg(s, rd, tmp);
8753 case 2: /* SIMD add/subtract. */
8754 op = (insn >> 20) & 7;
8755 shift = (insn >> 4) & 7;
8756 if ((op & 3) == 3 || (shift & 3) == 3)
8758 tmp = load_reg(s, rn);
8759 tmp2 = load_reg(s, rm);
8760 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8761 tcg_temp_free_i32(tmp2);
8762 store_reg(s, rd, tmp);
8764 case 3: /* Other data processing. */
8765 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8767 /* Saturating add/subtract. */
8768 tmp = load_reg(s, rn);
8769 tmp2 = load_reg(s, rm);
8771 gen_helper_double_saturate(tmp, cpu_env, tmp);
8773 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8775 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8776 tcg_temp_free_i32(tmp2);
8778 tmp = load_reg(s, rn);
8780 case 0x0a: /* rbit */
8781 gen_helper_rbit(tmp, tmp);
8783 case 0x08: /* rev */
8784 tcg_gen_bswap32_i32(tmp, tmp);
8786 case 0x09: /* rev16 */
8789 case 0x0b: /* revsh */
8792 case 0x10: /* sel */
8793 tmp2 = load_reg(s, rm);
8794 tmp3 = tcg_temp_new_i32();
8795 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8796 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8797 tcg_temp_free_i32(tmp3);
8798 tcg_temp_free_i32(tmp2);
8800 case 0x18: /* clz */
8801 gen_helper_clz(tmp, tmp);
8807 store_reg(s, rd, tmp);
8809 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8810 op = (insn >> 4) & 0xf;
8811 tmp = load_reg(s, rn);
8812 tmp2 = load_reg(s, rm);
8813 switch ((insn >> 20) & 7) {
8814 case 0: /* 32 x 32 -> 32 */
8815 tcg_gen_mul_i32(tmp, tmp, tmp2);
8816 tcg_temp_free_i32(tmp2);
8818 tmp2 = load_reg(s, rs);
8820 tcg_gen_sub_i32(tmp, tmp2, tmp);
8822 tcg_gen_add_i32(tmp, tmp, tmp2);
8823 tcg_temp_free_i32(tmp2);
8826 case 1: /* 16 x 16 -> 32 */
8827 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8828 tcg_temp_free_i32(tmp2);
8830 tmp2 = load_reg(s, rs);
8831 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8832 tcg_temp_free_i32(tmp2);
8835 case 2: /* Dual multiply add. */
8836 case 4: /* Dual multiply subtract. */
8838 gen_swap_half(tmp2);
8839 gen_smul_dual(tmp, tmp2);
8840 if (insn & (1 << 22)) {
8841 /* This subtraction cannot overflow. */
8842 tcg_gen_sub_i32(tmp, tmp, tmp2);
8844 /* This addition cannot overflow 32 bits;
8845 * however it may overflow considered as a signed
8846 * operation, in which case we must set the Q flag.
8848 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8850 tcg_temp_free_i32(tmp2);
8853 tmp2 = load_reg(s, rs);
8854 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8855 tcg_temp_free_i32(tmp2);
8858 case 3: /* 32 * 16 -> 32msb */
8860 tcg_gen_sari_i32(tmp2, tmp2, 16);
8863 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8864 tcg_gen_shri_i64(tmp64, tmp64, 16);
8865 tmp = tcg_temp_new_i32();
8866 tcg_gen_trunc_i64_i32(tmp, tmp64);
8867 tcg_temp_free_i64(tmp64);
8870 tmp2 = load_reg(s, rs);
8871 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8872 tcg_temp_free_i32(tmp2);
8875 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8876 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8878 tmp = load_reg(s, rs);
8879 if (insn & (1 << 20)) {
8880 tmp64 = gen_addq_msw(tmp64, tmp);
8882 tmp64 = gen_subq_msw(tmp64, tmp);
8885 if (insn & (1 << 4)) {
8886 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8888 tcg_gen_shri_i64(tmp64, tmp64, 32);
8889 tmp = tcg_temp_new_i32();
8890 tcg_gen_trunc_i64_i32(tmp, tmp64);
8891 tcg_temp_free_i64(tmp64);
8893 case 7: /* Unsigned sum of absolute differences. */
8894 gen_helper_usad8(tmp, tmp, tmp2);
8895 tcg_temp_free_i32(tmp2);
8897 tmp2 = load_reg(s, rs);
8898 tcg_gen_add_i32(tmp, tmp, tmp2);
8899 tcg_temp_free_i32(tmp2);
8903 store_reg(s, rd, tmp);
8905 case 6: case 7: /* 64-bit multiply, Divide. */
8906 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8907 tmp = load_reg(s, rn);
8908 tmp2 = load_reg(s, rm);
8909 if ((op & 0x50) == 0x10) {
8911 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8915 gen_helper_udiv(tmp, tmp, tmp2);
8917 gen_helper_sdiv(tmp, tmp, tmp2);
8918 tcg_temp_free_i32(tmp2);
8919 store_reg(s, rd, tmp);
8920 } else if ((op & 0xe) == 0xc) {
8921 /* Dual multiply accumulate long. */
8923 gen_swap_half(tmp2);
8924 gen_smul_dual(tmp, tmp2);
8926 tcg_gen_sub_i32(tmp, tmp, tmp2);
8928 tcg_gen_add_i32(tmp, tmp, tmp2);
8930 tcg_temp_free_i32(tmp2);
8932 tmp64 = tcg_temp_new_i64();
8933 tcg_gen_ext_i32_i64(tmp64, tmp);
8934 tcg_temp_free_i32(tmp);
8935 gen_addq(s, tmp64, rs, rd);
8936 gen_storeq_reg(s, rs, rd, tmp64);
8937 tcg_temp_free_i64(tmp64);
8940 /* Unsigned 64-bit multiply */
8941 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8945 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8946 tcg_temp_free_i32(tmp2);
8947 tmp64 = tcg_temp_new_i64();
8948 tcg_gen_ext_i32_i64(tmp64, tmp);
8949 tcg_temp_free_i32(tmp);
8951 /* Signed 64-bit multiply */
8952 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8957 gen_addq_lo(s, tmp64, rs);
8958 gen_addq_lo(s, tmp64, rd);
8959 } else if (op & 0x40) {
8960 /* 64-bit accumulate. */
8961 gen_addq(s, tmp64, rs, rd);
8963 gen_storeq_reg(s, rs, rd, tmp64);
8964 tcg_temp_free_i64(tmp64);
8969 case 6: case 7: case 14: case 15:
8971 if (((insn >> 24) & 3) == 3) {
8972 /* Translate into the equivalent ARM encoding. */
8973 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8974 if (disas_neon_data_insn(env, s, insn))
8976 } else if (((insn >> 8) & 0xe) == 10) {
8977 if (disas_vfp_insn(env, s, insn)) {
8981 if (insn & (1 << 28))
8983 if (disas_coproc_insn (env, s, insn))
8987 case 8: case 9: case 10: case 11:
8988 if (insn & (1 << 15)) {
8989 /* Branches, misc control. */
8990 if (insn & 0x5000) {
8991 /* Unconditional branch. */
8992 /* signextend(hw1[10:0]) -> offset[:12]. */
8993 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8994 /* hw1[10:0] -> offset[11:1]. */
8995 offset |= (insn & 0x7ff) << 1;
8996 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8997 offset[24:22] already have the same value because of the
8998 sign extension above. */
8999 offset ^= ((~insn) & (1 << 13)) << 10;
9000 offset ^= ((~insn) & (1 << 11)) << 11;
9002 if (insn & (1 << 14)) {
9003 /* Branch and link. */
9004 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9008 if (insn & (1 << 12)) {
9013 offset &= ~(uint32_t)2;
9014 /* thumb2 bx, no need to check */
9015 gen_bx_im(s, offset);
9017 } else if (((insn >> 23) & 7) == 7) {
9019 if (insn & (1 << 13))
9022 if (insn & (1 << 26)) {
9023 /* Secure monitor call (v6Z) */
9024 qemu_log_mask(LOG_UNIMP,
9025 "arm: unimplemented secure monitor call\n");
9026 goto illegal_op; /* not implemented. */
9028 op = (insn >> 20) & 7;
9030 case 0: /* msr cpsr. */
9032 tmp = load_reg(s, rn);
9033 addr = tcg_const_i32(insn & 0xff);
9034 gen_helper_v7m_msr(cpu_env, addr, tmp);
9035 tcg_temp_free_i32(addr);
9036 tcg_temp_free_i32(tmp);
9041 case 1: /* msr spsr. */
9044 tmp = load_reg(s, rn);
9046 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9050 case 2: /* cps, nop-hint. */
9051 if (((insn >> 8) & 7) == 0) {
9052 gen_nop_hint(s, insn & 0xff);
9054 /* Implemented as NOP in user mode. */
9059 if (insn & (1 << 10)) {
9060 if (insn & (1 << 7))
9062 if (insn & (1 << 6))
9064 if (insn & (1 << 5))
9066 if (insn & (1 << 9))
9067 imm = CPSR_A | CPSR_I | CPSR_F;
9069 if (insn & (1 << 8)) {
9071 imm |= (insn & 0x1f);
9074 gen_set_psr_im(s, offset, 0, imm);
9077 case 3: /* Special control operations. */
9079 op = (insn >> 4) & 0xf;
9087 /* These execute as NOPs. */
9094 /* Trivial implementation equivalent to bx. */
9095 tmp = load_reg(s, rn);
9098 case 5: /* Exception return. */
9102 if (rn != 14 || rd != 15) {
9105 tmp = load_reg(s, rn);
9106 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9107 gen_exception_return(s, tmp);
9109 case 6: /* mrs cpsr. */
9110 tmp = tcg_temp_new_i32();
9112 addr = tcg_const_i32(insn & 0xff);
9113 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9114 tcg_temp_free_i32(addr);
9116 gen_helper_cpsr_read(tmp, cpu_env);
9118 store_reg(s, rd, tmp);
9120 case 7: /* mrs spsr. */
9121 /* Not accessible in user mode. */
9122 if (IS_USER(s) || IS_M(env))
9124 tmp = load_cpu_field(spsr);
9125 store_reg(s, rd, tmp);
9130 /* Conditional branch. */
9131 op = (insn >> 22) & 0xf;
9132 /* Generate a conditional jump to next instruction. */
9133 s->condlabel = gen_new_label();
9134 gen_test_cc(op ^ 1, s->condlabel);
9137 /* offset[11:1] = insn[10:0] */
9138 offset = (insn & 0x7ff) << 1;
9139 /* offset[17:12] = insn[21:16]. */
9140 offset |= (insn & 0x003f0000) >> 4;
9141 /* offset[31:20] = insn[26]. */
9142 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9143 /* offset[18] = insn[13]. */
9144 offset |= (insn & (1 << 13)) << 5;
9145 /* offset[19] = insn[11]. */
9146 offset |= (insn & (1 << 11)) << 8;
9148 /* jump to the offset */
9149 gen_jmp(s, s->pc + offset);
9152 /* Data processing immediate. */
9153 if (insn & (1 << 25)) {
9154 if (insn & (1 << 24)) {
9155 if (insn & (1 << 20))
9157 /* Bitfield/Saturate. */
9158 op = (insn >> 21) & 7;
9160 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9162 tmp = tcg_temp_new_i32();
9163 tcg_gen_movi_i32(tmp, 0);
9165 tmp = load_reg(s, rn);
9168 case 2: /* Signed bitfield extract. */
9170 if (shift + imm > 32)
9173 gen_sbfx(tmp, shift, imm);
9175 case 6: /* Unsigned bitfield extract. */
9177 if (shift + imm > 32)
9180 gen_ubfx(tmp, shift, (1u << imm) - 1);
9182 case 3: /* Bitfield insert/clear. */
9185 imm = imm + 1 - shift;
9187 tmp2 = load_reg(s, rd);
9188 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9189 tcg_temp_free_i32(tmp2);
9194 default: /* Saturate. */
9197 tcg_gen_sari_i32(tmp, tmp, shift);
9199 tcg_gen_shli_i32(tmp, tmp, shift);
9201 tmp2 = tcg_const_i32(imm);
9204 if ((op & 1) && shift == 0)
9205 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9207 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9210 if ((op & 1) && shift == 0)
9211 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9213 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9215 tcg_temp_free_i32(tmp2);
9218 store_reg(s, rd, tmp);
9220 imm = ((insn & 0x04000000) >> 15)
9221 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9222 if (insn & (1 << 22)) {
9223 /* 16-bit immediate. */
9224 imm |= (insn >> 4) & 0xf000;
9225 if (insn & (1 << 23)) {
9227 tmp = load_reg(s, rd);
9228 tcg_gen_ext16u_i32(tmp, tmp);
9229 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9232 tmp = tcg_temp_new_i32();
9233 tcg_gen_movi_i32(tmp, imm);
9236 /* Add/sub 12-bit immediate. */
9238 offset = s->pc & ~(uint32_t)3;
9239 if (insn & (1 << 23))
9243 tmp = tcg_temp_new_i32();
9244 tcg_gen_movi_i32(tmp, offset);
9246 tmp = load_reg(s, rn);
9247 if (insn & (1 << 23))
9248 tcg_gen_subi_i32(tmp, tmp, imm);
9250 tcg_gen_addi_i32(tmp, tmp, imm);
9253 store_reg(s, rd, tmp);
9256 int shifter_out = 0;
9257 /* modified 12-bit immediate. */
9258 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9259 imm = (insn & 0xff);
9262 /* Nothing to do. */
9264 case 1: /* 00XY00XY */
9267 case 2: /* XY00XY00 */
9271 case 3: /* XYXYXYXY */
9275 default: /* Rotated constant. */
9276 shift = (shift << 1) | (imm >> 7);
9278 imm = imm << (32 - shift);
9282 tmp2 = tcg_temp_new_i32();
9283 tcg_gen_movi_i32(tmp2, imm);
9284 rn = (insn >> 16) & 0xf;
9286 tmp = tcg_temp_new_i32();
9287 tcg_gen_movi_i32(tmp, 0);
9289 tmp = load_reg(s, rn);
9291 op = (insn >> 21) & 0xf;
9292 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9293 shifter_out, tmp, tmp2))
9295 tcg_temp_free_i32(tmp2);
9296 rd = (insn >> 8) & 0xf;
9298 store_reg(s, rd, tmp);
9300 tcg_temp_free_i32(tmp);
9305 case 12: /* Load/store single data item. */
9310 if ((insn & 0x01100000) == 0x01000000) {
9311 if (disas_neon_ls_insn(env, s, insn))
9315 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9317 if (!(insn & (1 << 20))) {
9321 /* Byte or halfword load space with dest == r15 : memory hints.
9322 * Catch them early so we don't emit pointless addressing code.
9323 * This space is a mix of:
9324 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9325 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9327 * unallocated hints, which must be treated as NOPs
9328 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9329 * which is easiest for the decoding logic
9330 * Some space which must UNDEF
9332 int op1 = (insn >> 23) & 3;
9333 int op2 = (insn >> 6) & 0x3f;
9338 /* UNPREDICTABLE, unallocated hint or
9339 * PLD/PLDW/PLI (literal)
9344 return 0; /* PLD/PLDW/PLI or unallocated hint */
9346 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9347 return 0; /* PLD/PLDW/PLI or unallocated hint */
9349 /* UNDEF space, or an UNPREDICTABLE */
9355 addr = tcg_temp_new_i32();
9357 /* s->pc has already been incremented by 4. */
9358 imm = s->pc & 0xfffffffc;
9359 if (insn & (1 << 23))
9360 imm += insn & 0xfff;
9362 imm -= insn & 0xfff;
9363 tcg_gen_movi_i32(addr, imm);
9365 addr = load_reg(s, rn);
9366 if (insn & (1 << 23)) {
9367 /* Positive offset. */
9369 tcg_gen_addi_i32(addr, addr, imm);
9372 switch ((insn >> 8) & 0xf) {
9373 case 0x0: /* Shifted Register. */
9374 shift = (insn >> 4) & 0xf;
9376 tcg_temp_free_i32(addr);
9379 tmp = load_reg(s, rm);
9381 tcg_gen_shli_i32(tmp, tmp, shift);
9382 tcg_gen_add_i32(addr, addr, tmp);
9383 tcg_temp_free_i32(tmp);
9385 case 0xc: /* Negative offset. */
9386 tcg_gen_addi_i32(addr, addr, -imm);
9388 case 0xe: /* User privilege. */
9389 tcg_gen_addi_i32(addr, addr, imm);
9392 case 0x9: /* Post-decrement. */
9395 case 0xb: /* Post-increment. */
9399 case 0xd: /* Pre-decrement. */
9402 case 0xf: /* Pre-increment. */
9403 tcg_gen_addi_i32(addr, addr, imm);
9407 tcg_temp_free_i32(addr);
9412 if (insn & (1 << 20)) {
9414 tmp = tcg_temp_new_i32();
9417 gen_aa32_ld8u(tmp, addr, user);
9420 gen_aa32_ld8s(tmp, addr, user);
9423 gen_aa32_ld16u(tmp, addr, user);
9426 gen_aa32_ld16s(tmp, addr, user);
9429 gen_aa32_ld32u(tmp, addr, user);
9432 tcg_temp_free_i32(tmp);
9433 tcg_temp_free_i32(addr);
9439 store_reg(s, rs, tmp);
9443 tmp = load_reg(s, rs);
9446 gen_aa32_st8(tmp, addr, user);
9449 gen_aa32_st16(tmp, addr, user);
9452 gen_aa32_st32(tmp, addr, user);
9455 tcg_temp_free_i32(tmp);
9456 tcg_temp_free_i32(addr);
9459 tcg_temp_free_i32(tmp);
9462 tcg_gen_addi_i32(addr, addr, imm);
9464 store_reg(s, rn, addr);
9466 tcg_temp_free_i32(addr);
9478 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9480 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9487 if (s->condexec_mask) {
9488 cond = s->condexec_cond;
9489 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9490 s->condlabel = gen_new_label();
9491 gen_test_cc(cond ^ 1, s->condlabel);
9496 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9499 switch (insn >> 12) {
9503 op = (insn >> 11) & 3;
9506 rn = (insn >> 3) & 7;
9507 tmp = load_reg(s, rn);
9508 if (insn & (1 << 10)) {
9510 tmp2 = tcg_temp_new_i32();
9511 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9514 rm = (insn >> 6) & 7;
9515 tmp2 = load_reg(s, rm);
9517 if (insn & (1 << 9)) {
9518 if (s->condexec_mask)
9519 tcg_gen_sub_i32(tmp, tmp, tmp2);
9521 gen_sub_CC(tmp, tmp, tmp2);
9523 if (s->condexec_mask)
9524 tcg_gen_add_i32(tmp, tmp, tmp2);
9526 gen_add_CC(tmp, tmp, tmp2);
9528 tcg_temp_free_i32(tmp2);
9529 store_reg(s, rd, tmp);
9531 /* shift immediate */
9532 rm = (insn >> 3) & 7;
9533 shift = (insn >> 6) & 0x1f;
9534 tmp = load_reg(s, rm);
9535 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9536 if (!s->condexec_mask)
9538 store_reg(s, rd, tmp);
9542 /* arithmetic large immediate */
9543 op = (insn >> 11) & 3;
9544 rd = (insn >> 8) & 0x7;
9545 if (op == 0) { /* mov */
9546 tmp = tcg_temp_new_i32();
9547 tcg_gen_movi_i32(tmp, insn & 0xff);
9548 if (!s->condexec_mask)
9550 store_reg(s, rd, tmp);
9552 tmp = load_reg(s, rd);
9553 tmp2 = tcg_temp_new_i32();
9554 tcg_gen_movi_i32(tmp2, insn & 0xff);
9557 gen_sub_CC(tmp, tmp, tmp2);
9558 tcg_temp_free_i32(tmp);
9559 tcg_temp_free_i32(tmp2);
9562 if (s->condexec_mask)
9563 tcg_gen_add_i32(tmp, tmp, tmp2);
9565 gen_add_CC(tmp, tmp, tmp2);
9566 tcg_temp_free_i32(tmp2);
9567 store_reg(s, rd, tmp);
9570 if (s->condexec_mask)
9571 tcg_gen_sub_i32(tmp, tmp, tmp2);
9573 gen_sub_CC(tmp, tmp, tmp2);
9574 tcg_temp_free_i32(tmp2);
9575 store_reg(s, rd, tmp);
9581 if (insn & (1 << 11)) {
9582 rd = (insn >> 8) & 7;
9583 /* load pc-relative. Bit 1 of PC is ignored. */
9584 val = s->pc + 2 + ((insn & 0xff) * 4);
9585 val &= ~(uint32_t)2;
9586 addr = tcg_temp_new_i32();
9587 tcg_gen_movi_i32(addr, val);
9588 tmp = tcg_temp_new_i32();
9589 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9590 tcg_temp_free_i32(addr);
9591 store_reg(s, rd, tmp);
9594 if (insn & (1 << 10)) {
9595 /* data processing extended or blx */
9596 rd = (insn & 7) | ((insn >> 4) & 8);
9597 rm = (insn >> 3) & 0xf;
9598 op = (insn >> 8) & 3;
9601 tmp = load_reg(s, rd);
9602 tmp2 = load_reg(s, rm);
9603 tcg_gen_add_i32(tmp, tmp, tmp2);
9604 tcg_temp_free_i32(tmp2);
9605 store_reg(s, rd, tmp);
9608 tmp = load_reg(s, rd);
9609 tmp2 = load_reg(s, rm);
9610 gen_sub_CC(tmp, tmp, tmp2);
9611 tcg_temp_free_i32(tmp2);
9612 tcg_temp_free_i32(tmp);
9614 case 2: /* mov/cpy */
9615 tmp = load_reg(s, rm);
9616 store_reg(s, rd, tmp);
9618 case 3:/* branch [and link] exchange thumb register */
9619 tmp = load_reg(s, rm);
9620 if (insn & (1 << 7)) {
9622 val = (uint32_t)s->pc | 1;
9623 tmp2 = tcg_temp_new_i32();
9624 tcg_gen_movi_i32(tmp2, val);
9625 store_reg(s, 14, tmp2);
9627 /* already thumb, no need to check */
9634 /* data processing register */
9636 rm = (insn >> 3) & 7;
9637 op = (insn >> 6) & 0xf;
9638 if (op == 2 || op == 3 || op == 4 || op == 7) {
9639 /* the shift/rotate ops want the operands backwards */
9648 if (op == 9) { /* neg */
9649 tmp = tcg_temp_new_i32();
9650 tcg_gen_movi_i32(tmp, 0);
9651 } else if (op != 0xf) { /* mvn doesn't read its first operand */
9652 tmp = load_reg(s, rd);
9654 TCGV_UNUSED_I32(tmp);
9657 tmp2 = load_reg(s, rm);
9660 tcg_gen_and_i32(tmp, tmp, tmp2);
9661 if (!s->condexec_mask)
9665 tcg_gen_xor_i32(tmp, tmp, tmp2);
9666 if (!s->condexec_mask)
9670 if (s->condexec_mask) {
9671 gen_shl(tmp2, tmp2, tmp);
9673 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9678 if (s->condexec_mask) {
9679 gen_shr(tmp2, tmp2, tmp);
9681 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9686 if (s->condexec_mask) {
9687 gen_sar(tmp2, tmp2, tmp);
9689 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9694 if (s->condexec_mask) {
9697 gen_adc_CC(tmp, tmp, tmp2);
9701 if (s->condexec_mask) {
9702 gen_sub_carry(tmp, tmp, tmp2);
9704 gen_sbc_CC(tmp, tmp, tmp2);
9708 if (s->condexec_mask) {
9709 tcg_gen_andi_i32(tmp, tmp, 0x1f);
9710 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9712 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9717 tcg_gen_and_i32(tmp, tmp, tmp2);
9722 if (s->condexec_mask)
9723 tcg_gen_neg_i32(tmp, tmp2);
9725 gen_sub_CC(tmp, tmp, tmp2);
9728 gen_sub_CC(tmp, tmp, tmp2);
9732 gen_add_CC(tmp, tmp, tmp2);
9736 tcg_gen_or_i32(tmp, tmp, tmp2);
9737 if (!s->condexec_mask)
9741 tcg_gen_mul_i32(tmp, tmp, tmp2);
9742 if (!s->condexec_mask)
9746 tcg_gen_andc_i32(tmp, tmp, tmp2);
9747 if (!s->condexec_mask)
9751 tcg_gen_not_i32(tmp2, tmp2);
9752 if (!s->condexec_mask)
9760 store_reg(s, rm, tmp2);
9762 tcg_temp_free_i32(tmp);
9764 store_reg(s, rd, tmp);
9765 tcg_temp_free_i32(tmp2);
9768 tcg_temp_free_i32(tmp);
9769 tcg_temp_free_i32(tmp2);
9774 /* load/store register offset. */
9776 rn = (insn >> 3) & 7;
9777 rm = (insn >> 6) & 7;
9778 op = (insn >> 9) & 7;
9779 addr = load_reg(s, rn);
9780 tmp = load_reg(s, rm);
9781 tcg_gen_add_i32(addr, addr, tmp);
9782 tcg_temp_free_i32(tmp);
9784 if (op < 3) { /* store */
9785 tmp = load_reg(s, rd);
9787 tmp = tcg_temp_new_i32();
9792 gen_aa32_st32(tmp, addr, IS_USER(s));
9795 gen_aa32_st16(tmp, addr, IS_USER(s));
9798 gen_aa32_st8(tmp, addr, IS_USER(s));
9801 gen_aa32_ld8s(tmp, addr, IS_USER(s));
9804 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9807 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9810 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9813 gen_aa32_ld16s(tmp, addr, IS_USER(s));
9816 if (op >= 3) { /* load */
9817 store_reg(s, rd, tmp);
9819 tcg_temp_free_i32(tmp);
9821 tcg_temp_free_i32(addr);
9825 /* load/store word immediate offset */
9827 rn = (insn >> 3) & 7;
9828 addr = load_reg(s, rn);
9829 val = (insn >> 4) & 0x7c;
9830 tcg_gen_addi_i32(addr, addr, val);
9832 if (insn & (1 << 11)) {
9834 tmp = tcg_temp_new_i32();
9835 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9836 store_reg(s, rd, tmp);
9839 tmp = load_reg(s, rd);
9840 gen_aa32_st32(tmp, addr, IS_USER(s));
9841 tcg_temp_free_i32(tmp);
9843 tcg_temp_free_i32(addr);
9847 /* load/store byte immediate offset */
9849 rn = (insn >> 3) & 7;
9850 addr = load_reg(s, rn);
9851 val = (insn >> 6) & 0x1f;
9852 tcg_gen_addi_i32(addr, addr, val);
9854 if (insn & (1 << 11)) {
9856 tmp = tcg_temp_new_i32();
9857 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9858 store_reg(s, rd, tmp);
9861 tmp = load_reg(s, rd);
9862 gen_aa32_st8(tmp, addr, IS_USER(s));
9863 tcg_temp_free_i32(tmp);
9865 tcg_temp_free_i32(addr);
9869 /* load/store halfword immediate offset */
9871 rn = (insn >> 3) & 7;
9872 addr = load_reg(s, rn);
9873 val = (insn >> 5) & 0x3e;
9874 tcg_gen_addi_i32(addr, addr, val);
9876 if (insn & (1 << 11)) {
9878 tmp = tcg_temp_new_i32();
9879 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9880 store_reg(s, rd, tmp);
9883 tmp = load_reg(s, rd);
9884 gen_aa32_st16(tmp, addr, IS_USER(s));
9885 tcg_temp_free_i32(tmp);
9887 tcg_temp_free_i32(addr);
9891 /* load/store from stack */
9892 rd = (insn >> 8) & 7;
9893 addr = load_reg(s, 13);
9894 val = (insn & 0xff) * 4;
9895 tcg_gen_addi_i32(addr, addr, val);
9897 if (insn & (1 << 11)) {
9899 tmp = tcg_temp_new_i32();
9900 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9901 store_reg(s, rd, tmp);
9904 tmp = load_reg(s, rd);
9905 gen_aa32_st32(tmp, addr, IS_USER(s));
9906 tcg_temp_free_i32(tmp);
9908 tcg_temp_free_i32(addr);
9912 /* add to high reg */
9913 rd = (insn >> 8) & 7;
9914 if (insn & (1 << 11)) {
9916 tmp = load_reg(s, 13);
9918 /* PC. bit 1 is ignored. */
9919 tmp = tcg_temp_new_i32();
9920 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9922 val = (insn & 0xff) * 4;
9923 tcg_gen_addi_i32(tmp, tmp, val);
9924 store_reg(s, rd, tmp);
9929 op = (insn >> 8) & 0xf;
9932 /* adjust stack pointer */
9933 tmp = load_reg(s, 13);
9934 val = (insn & 0x7f) * 4;
9935 if (insn & (1 << 7))
9936 val = -(int32_t)val;
9937 tcg_gen_addi_i32(tmp, tmp, val);
9938 store_reg(s, 13, tmp);
9941 case 2: /* sign/zero extend. */
9944 rm = (insn >> 3) & 7;
9945 tmp = load_reg(s, rm);
9946 switch ((insn >> 6) & 3) {
9947 case 0: gen_sxth(tmp); break;
9948 case 1: gen_sxtb(tmp); break;
9949 case 2: gen_uxth(tmp); break;
9950 case 3: gen_uxtb(tmp); break;
9952 store_reg(s, rd, tmp);
9954 case 4: case 5: case 0xc: case 0xd:
9956 addr = load_reg(s, 13);
9957 if (insn & (1 << 8))
9961 for (i = 0; i < 8; i++) {
9962 if (insn & (1 << i))
9965 if ((insn & (1 << 11)) == 0) {
9966 tcg_gen_addi_i32(addr, addr, -offset);
9968 for (i = 0; i < 8; i++) {
9969 if (insn & (1 << i)) {
9970 if (insn & (1 << 11)) {
9972 tmp = tcg_temp_new_i32();
9973 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9974 store_reg(s, i, tmp);
9977 tmp = load_reg(s, i);
9978 gen_aa32_st32(tmp, addr, IS_USER(s));
9979 tcg_temp_free_i32(tmp);
9981 /* advance to the next address. */
9982 tcg_gen_addi_i32(addr, addr, 4);
9985 TCGV_UNUSED_I32(tmp);
9986 if (insn & (1 << 8)) {
9987 if (insn & (1 << 11)) {
9989 tmp = tcg_temp_new_i32();
9990 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9991 /* don't set the pc until the rest of the instruction
9995 tmp = load_reg(s, 14);
9996 gen_aa32_st32(tmp, addr, IS_USER(s));
9997 tcg_temp_free_i32(tmp);
9999 tcg_gen_addi_i32(addr, addr, 4);
10001 if ((insn & (1 << 11)) == 0) {
10002 tcg_gen_addi_i32(addr, addr, -offset);
10004 /* write back the new stack pointer */
10005 store_reg(s, 13, addr);
10006 /* set the new PC value */
10007 if ((insn & 0x0900) == 0x0900) {
10008 store_reg_from_load(env, s, 15, tmp);
10012 case 1: case 3: case 9: case 11: /* czb */
10014 tmp = load_reg(s, rm);
10015 s->condlabel = gen_new_label();
10017 if (insn & (1 << 11))
10018 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10020 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10021 tcg_temp_free_i32(tmp);
10022 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10023 val = (uint32_t)s->pc + 2;
10028 case 15: /* IT, nop-hint. */
10029 if ((insn & 0xf) == 0) {
10030 gen_nop_hint(s, (insn >> 4) & 0xf);
10034 s->condexec_cond = (insn >> 4) & 0xe;
10035 s->condexec_mask = insn & 0x1f;
10036 /* No actual code generated for this insn, just setup state. */
10039 case 0xe: /* bkpt */
10041 gen_exception_insn(s, 2, EXCP_BKPT);
10044 case 0xa: /* rev */
10046 rn = (insn >> 3) & 0x7;
10048 tmp = load_reg(s, rn);
10049 switch ((insn >> 6) & 3) {
10050 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10051 case 1: gen_rev16(tmp); break;
10052 case 3: gen_revsh(tmp); break;
10053 default: goto illegal_op;
10055 store_reg(s, rd, tmp);
10059 switch ((insn >> 5) & 7) {
10063 if (((insn >> 3) & 1) != s->bswap_code) {
10064 /* Dynamic endianness switching not implemented. */
10065 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10076 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10079 addr = tcg_const_i32(19);
10080 gen_helper_v7m_msr(cpu_env, addr, tmp);
10081 tcg_temp_free_i32(addr);
10085 addr = tcg_const_i32(16);
10086 gen_helper_v7m_msr(cpu_env, addr, tmp);
10087 tcg_temp_free_i32(addr);
10089 tcg_temp_free_i32(tmp);
10092 if (insn & (1 << 4)) {
10093 shift = CPSR_A | CPSR_I | CPSR_F;
10097 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10112 /* load/store multiple */
10113 TCGv_i32 loaded_var;
10114 TCGV_UNUSED_I32(loaded_var);
10115 rn = (insn >> 8) & 0x7;
10116 addr = load_reg(s, rn);
10117 for (i = 0; i < 8; i++) {
10118 if (insn & (1 << i)) {
10119 if (insn & (1 << 11)) {
10121 tmp = tcg_temp_new_i32();
10122 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10126 store_reg(s, i, tmp);
10130 tmp = load_reg(s, i);
10131 gen_aa32_st32(tmp, addr, IS_USER(s));
10132 tcg_temp_free_i32(tmp);
10134 /* advance to the next address */
10135 tcg_gen_addi_i32(addr, addr, 4);
10138 if ((insn & (1 << rn)) == 0) {
10139 /* base reg not in list: base register writeback */
10140 store_reg(s, rn, addr);
10142 /* base reg in list: if load, complete it now */
10143 if (insn & (1 << 11)) {
10144 store_reg(s, rn, loaded_var);
10146 tcg_temp_free_i32(addr);
10151 /* conditional branch or swi */
10152 cond = (insn >> 8) & 0xf;
10158 gen_set_pc_im(s, s->pc);
10159 s->is_jmp = DISAS_SWI;
10162 /* generate a conditional jump to next instruction */
10163 s->condlabel = gen_new_label();
10164 gen_test_cc(cond ^ 1, s->condlabel);
10167 /* jump to the offset */
10168 val = (uint32_t)s->pc + 2;
10169 offset = ((int32_t)insn << 24) >> 24;
10170 val += offset << 1;
10175 if (insn & (1 << 11)) {
10176 if (disas_thumb2_insn(env, s, insn))
10180 /* unconditional branch */
10181 val = (uint32_t)s->pc;
10182 offset = ((int32_t)insn << 21) >> 21;
10183 val += (offset << 1) + 2;
10188 if (disas_thumb2_insn(env, s, insn))
10194 gen_exception_insn(s, 4, EXCP_UDEF);
10198 gen_exception_insn(s, 2, EXCP_UDEF);
10201 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10202 basic block 'tb'. If search_pc is TRUE, also generate PC
10203 information for each intermediate instruction. */
10204 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10205 TranslationBlock *tb,
10208 CPUState *cs = CPU(cpu);
10209 CPUARMState *env = &cpu->env;
10210 DisasContext dc1, *dc = &dc1;
10212 uint16_t *gen_opc_end;
10214 target_ulong pc_start;
10215 target_ulong next_page_start;
10219 /* generate intermediate code */
10224 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10226 dc->is_jmp = DISAS_NEXT;
10228 dc->singlestep_enabled = cs->singlestep_enabled;
10231 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10234 dc->bswap_code = 0;
10235 dc->condexec_mask = 0;
10236 dc->condexec_cond = 0;
10237 #if !defined(CONFIG_USER_ONLY)
10240 dc->vfp_enabled = 0;
10242 dc->vec_stride = 0;
10245 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10246 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10247 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10248 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10249 #if !defined(CONFIG_USER_ONLY)
10250 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10252 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10253 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10254 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10256 cpu_F0s = tcg_temp_new_i32();
10257 cpu_F1s = tcg_temp_new_i32();
10258 cpu_F0d = tcg_temp_new_i64();
10259 cpu_F1d = tcg_temp_new_i64();
10262 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10263 cpu_M0 = tcg_temp_new_i64();
10264 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10267 max_insns = tb->cflags & CF_COUNT_MASK;
10268 if (max_insns == 0)
10269 max_insns = CF_COUNT_MASK;
10273 tcg_clear_temp_count();
10275 /* A note on handling of the condexec (IT) bits:
10277 * We want to avoid the overhead of having to write the updated condexec
10278 * bits back to the CPUARMState for every instruction in an IT block. So:
10279 * (1) if the condexec bits are not already zero then we write
10280 * zero back into the CPUARMState now. This avoids complications trying
10281 * to do it at the end of the block. (For example if we don't do this
10282 * it's hard to identify whether we can safely skip writing condexec
10283 * at the end of the TB, which we definitely want to do for the case
10284 * where a TB doesn't do anything with the IT state at all.)
10285 * (2) if we are going to leave the TB then we call gen_set_condexec()
10286 * which will write the correct value into CPUARMState if zero is wrong.
10287 * This is done both for leaving the TB at the end, and for leaving
10288 * it because of an exception we know will happen, which is done in
10289 * gen_exception_insn(). The latter is necessary because we need to
10290 * leave the TB with the PC/IT state just prior to execution of the
10291 * instruction which caused the exception.
10292 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10293 * then the CPUARMState will be wrong and we need to reset it.
10294 * This is handled in the same way as restoration of the
10295 * PC in these situations: we will be called again with search_pc=1
10296 * and generate a mapping of the condexec bits for each PC in
10297 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10298 * this to restore the condexec bits.
10300 * Note that there are no instructions which can read the condexec
10301 * bits, and none which can write non-static values to them, so
10302 * we don't need to care about whether CPUARMState is correct in the
10306 /* Reset the conditional execution bits immediately. This avoids
10307 complications trying to do it at the end of the block. */
10308 if (dc->condexec_mask || dc->condexec_cond)
10310 TCGv_i32 tmp = tcg_temp_new_i32();
10311 tcg_gen_movi_i32(tmp, 0);
10312 store_cpu_field(tmp, condexec_bits);
10315 #ifdef CONFIG_USER_ONLY
10316 /* Intercept jump to the magic kernel page. */
10317 if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10318 /* We always get here via a jump, so know we are not in a
10319 conditional execution block. */
10320 gen_exception(EXCP_KERNEL_TRAP);
10321 dc->is_jmp = DISAS_UPDATE;
10325 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10326 /* We always get here via a jump, so know we are not in a
10327 conditional execution block. */
10328 gen_exception(EXCP_EXCEPTION_EXIT);
10329 dc->is_jmp = DISAS_UPDATE;
10334 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10335 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10336 if (bp->pc == dc->pc) {
10337 gen_exception_insn(dc, 0, EXCP_DEBUG);
10338 /* Advance PC so that clearing the breakpoint will
10339 invalidate this TB. */
10341 goto done_generating;
10346 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10350 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10352 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10353 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10354 tcg_ctx.gen_opc_instr_start[lj] = 1;
10355 tcg_ctx.gen_opc_icount[lj] = num_insns;
10358 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10361 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10362 tcg_gen_debug_insn_start(dc->pc);
10366 disas_a64_insn(env, dc);
10367 } else if (dc->thumb) {
10368 disas_thumb_insn(env, dc);
10369 if (dc->condexec_mask) {
10370 dc->condexec_cond = (dc->condexec_cond & 0xe)
10371 | ((dc->condexec_mask >> 4) & 1);
10372 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10373 if (dc->condexec_mask == 0) {
10374 dc->condexec_cond = 0;
10378 disas_arm_insn(env, dc);
10381 if (dc->condjmp && !dc->is_jmp) {
10382 gen_set_label(dc->condlabel);
10386 if (tcg_check_temp_count()) {
10387 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10391 /* Translation stops when a conditional branch is encountered.
10392 * Otherwise the subsequent code could get translated several times.
10393 * Also stop translation when a page boundary is reached. This
10394 * ensures prefetch aborts occur at the right place. */
10396 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10397 !cs->singlestep_enabled &&
10399 dc->pc < next_page_start &&
10400 num_insns < max_insns);
10402 if (tb->cflags & CF_LAST_IO) {
10404 /* FIXME: This can theoretically happen with self-modifying
10406 cpu_abort(env, "IO on conditional branch instruction");
10411 /* At this stage dc->condjmp will only be set when the skipped
10412 instruction was a conditional branch or trap, and the PC has
10413 already been written. */
10414 if (unlikely(cs->singlestep_enabled)) {
10415 /* Make sure the pc is updated, and raise a debug exception. */
10417 gen_set_condexec(dc);
10418 if (dc->is_jmp == DISAS_SWI) {
10419 gen_exception(EXCP_SWI);
10421 gen_exception(EXCP_DEBUG);
10423 gen_set_label(dc->condlabel);
10425 if (dc->condjmp || !dc->is_jmp) {
10426 gen_set_pc_im(dc, dc->pc);
10429 gen_set_condexec(dc);
10430 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10431 gen_exception(EXCP_SWI);
10433 /* FIXME: Single stepping a WFI insn will not halt
10435 gen_exception(EXCP_DEBUG);
10438 /* While branches must always occur at the end of an IT block,
10439 there are a few other things that can cause us to terminate
10440 the TB in the middle of an IT block:
10441 - Exception generating instructions (bkpt, swi, undefined).
10443 - Hardware watchpoints.
10444 Hardware breakpoints have already been handled and skip this code.
10446 gen_set_condexec(dc);
10447 switch(dc->is_jmp) {
10449 gen_goto_tb(dc, 1, dc->pc);
10454 /* indicate that the hash table must be used to find the next TB */
10455 tcg_gen_exit_tb(0);
10457 case DISAS_TB_JUMP:
10458 /* nothing more to generate */
10461 gen_helper_wfi(cpu_env);
10464 gen_exception(EXCP_SWI);
10468 gen_set_label(dc->condlabel);
10469 gen_set_condexec(dc);
10470 gen_goto_tb(dc, 1, dc->pc);
10476 gen_tb_end(tb, num_insns);
10477 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10480 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10481 qemu_log("----------------\n");
10482 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10483 log_target_disas(env, pc_start, dc->pc - pc_start,
10484 dc->thumb | (dc->bswap_code << 1));
10489 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10492 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10494 tb->size = dc->pc - pc_start;
10495 tb->icount = num_insns;
10499 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10501 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10504 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10506 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10509 static const char *cpu_mode_names[16] = {
10510 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10511 "???", "???", "???", "und", "???", "???", "???", "sys"
10514 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10517 ARMCPU *cpu = ARM_CPU(cs);
10518 CPUARMState *env = &cpu->env;
10522 for(i=0;i<16;i++) {
10523 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10525 cpu_fprintf(f, "\n");
10527 cpu_fprintf(f, " ");
10529 psr = cpsr_read(env);
10530 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10532 psr & (1 << 31) ? 'N' : '-',
10533 psr & (1 << 30) ? 'Z' : '-',
10534 psr & (1 << 29) ? 'C' : '-',
10535 psr & (1 << 28) ? 'V' : '-',
10536 psr & CPSR_T ? 'T' : 'A',
10537 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10539 if (flags & CPU_DUMP_FPU) {
10540 int numvfpregs = 0;
10541 if (arm_feature(env, ARM_FEATURE_VFP)) {
10544 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10547 for (i = 0; i < numvfpregs; i++) {
10548 uint64_t v = float64_val(env->vfp.regs[i]);
10549 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10550 i * 2, (uint32_t)v,
10551 i * 2 + 1, (uint32_t)(v >> 32),
10554 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10558 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10561 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10563 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10565 env->condexec_bits = gen_opc_condexec_bits[pc_pos];