4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
28 #include "disas/disas.h"
31 #include "qemu/bitops.h"
37 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) (s->user)
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
62 static TCGv_i32 cpu_R[16];
63 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
64 static TCGv_i32 cpu_exclusive_addr;
65 static TCGv_i32 cpu_exclusive_val;
66 static TCGv_i32 cpu_exclusive_high;
67 #ifdef CONFIG_USER_ONLY
68 static TCGv_i32 cpu_exclusive_test;
69 static TCGv_i32 cpu_exclusive_info;
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s, cpu_F1s;
74 static TCGv_i64 cpu_F0d, cpu_F1d;
76 #include "exec/gen-icount.h"
78 static const char *regnames[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
87 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
89 for (i = 0; i < 16; i++) {
90 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
91 offsetof(CPUARMState, regs[i]),
94 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
95 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
96 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
97 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
99 cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
100 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
101 cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
102 offsetof(CPUARMState, exclusive_val), "exclusive_val");
103 cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
104 offsetof(CPUARMState, exclusive_high), "exclusive_high");
105 #ifdef CONFIG_USER_ONLY
106 cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
107 offsetof(CPUARMState, exclusive_test), "exclusive_test");
108 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
109 offsetof(CPUARMState, exclusive_info), "exclusive_info");
112 a64_translate_init();
115 static inline TCGv_i32 load_cpu_offset(int offset)
117 TCGv_i32 tmp = tcg_temp_new_i32();
118 tcg_gen_ld_i32(tmp, cpu_env, offset);
122 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
124 static inline void store_cpu_offset(TCGv_i32 var, int offset)
126 tcg_gen_st_i32(var, cpu_env, offset);
127 tcg_temp_free_i32(var);
130 #define store_cpu_field(var, name) \
131 store_cpu_offset(var, offsetof(CPUARMState, name))
133 /* Set a variable to the value of a CPU register. */
134 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
138 /* normally, since we updated PC, we need only to add one insn */
140 addr = (long)s->pc + 2;
142 addr = (long)s->pc + 4;
143 tcg_gen_movi_i32(var, addr);
145 tcg_gen_mov_i32(var, cpu_R[reg]);
149 /* Create a new temporary and set it to the value of a CPU register. */
150 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
152 TCGv_i32 tmp = tcg_temp_new_i32();
153 load_reg_var(s, tmp, reg);
157 /* Set a CPU register. The source must be a temporary and will be
159 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
162 tcg_gen_andi_i32(var, var, ~1);
163 s->is_jmp = DISAS_JUMP;
165 tcg_gen_mov_i32(cpu_R[reg], var);
166 tcg_temp_free_i32(var);
169 /* Value extensions. */
170 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
171 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
172 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
173 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
175 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
176 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
179 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
181 TCGv_i32 tmp_mask = tcg_const_i32(mask);
182 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
183 tcg_temp_free_i32(tmp_mask);
185 /* Set NZCV flags from the high 4 bits of var. */
186 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
188 static void gen_exception(int excp)
190 TCGv_i32 tmp = tcg_temp_new_i32();
191 tcg_gen_movi_i32(tmp, excp);
192 gen_helper_exception(cpu_env, tmp);
193 tcg_temp_free_i32(tmp);
196 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
198 TCGv_i32 tmp1 = tcg_temp_new_i32();
199 TCGv_i32 tmp2 = tcg_temp_new_i32();
200 tcg_gen_ext16s_i32(tmp1, a);
201 tcg_gen_ext16s_i32(tmp2, b);
202 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
203 tcg_temp_free_i32(tmp2);
204 tcg_gen_sari_i32(a, a, 16);
205 tcg_gen_sari_i32(b, b, 16);
206 tcg_gen_mul_i32(b, b, a);
207 tcg_gen_mov_i32(a, tmp1);
208 tcg_temp_free_i32(tmp1);
211 /* Byteswap each halfword. */
212 static void gen_rev16(TCGv_i32 var)
214 TCGv_i32 tmp = tcg_temp_new_i32();
215 tcg_gen_shri_i32(tmp, var, 8);
216 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
217 tcg_gen_shli_i32(var, var, 8);
218 tcg_gen_andi_i32(var, var, 0xff00ff00);
219 tcg_gen_or_i32(var, var, tmp);
220 tcg_temp_free_i32(tmp);
223 /* Byteswap low halfword and sign extend. */
224 static void gen_revsh(TCGv_i32 var)
226 tcg_gen_ext16u_i32(var, var);
227 tcg_gen_bswap16_i32(var, var);
228 tcg_gen_ext16s_i32(var, var);
231 /* Unsigned bitfield extract. */
232 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
235 tcg_gen_shri_i32(var, var, shift);
236 tcg_gen_andi_i32(var, var, mask);
239 /* Signed bitfield extract. */
240 static void gen_sbfx(TCGv_i32 var, int shift, int width)
245 tcg_gen_sari_i32(var, var, shift);
246 if (shift + width < 32) {
247 signbit = 1u << (width - 1);
248 tcg_gen_andi_i32(var, var, (1u << width) - 1);
249 tcg_gen_xori_i32(var, var, signbit);
250 tcg_gen_subi_i32(var, var, signbit);
254 /* Return (b << 32) + a. Mark inputs as dead */
255 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
257 TCGv_i64 tmp64 = tcg_temp_new_i64();
259 tcg_gen_extu_i32_i64(tmp64, b);
260 tcg_temp_free_i32(b);
261 tcg_gen_shli_i64(tmp64, tmp64, 32);
262 tcg_gen_add_i64(a, tmp64, a);
264 tcg_temp_free_i64(tmp64);
268 /* Return (b << 32) - a. Mark inputs as dead. */
269 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
271 TCGv_i64 tmp64 = tcg_temp_new_i64();
273 tcg_gen_extu_i32_i64(tmp64, b);
274 tcg_temp_free_i32(b);
275 tcg_gen_shli_i64(tmp64, tmp64, 32);
276 tcg_gen_sub_i64(a, tmp64, a);
278 tcg_temp_free_i64(tmp64);
282 /* 32x32->64 multiply. Marks inputs as dead. */
283 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
285 TCGv_i32 lo = tcg_temp_new_i32();
286 TCGv_i32 hi = tcg_temp_new_i32();
289 tcg_gen_mulu2_i32(lo, hi, a, b);
290 tcg_temp_free_i32(a);
291 tcg_temp_free_i32(b);
293 ret = tcg_temp_new_i64();
294 tcg_gen_concat_i32_i64(ret, lo, hi);
295 tcg_temp_free_i32(lo);
296 tcg_temp_free_i32(hi);
301 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
303 TCGv_i32 lo = tcg_temp_new_i32();
304 TCGv_i32 hi = tcg_temp_new_i32();
307 tcg_gen_muls2_i32(lo, hi, a, b);
308 tcg_temp_free_i32(a);
309 tcg_temp_free_i32(b);
311 ret = tcg_temp_new_i64();
312 tcg_gen_concat_i32_i64(ret, lo, hi);
313 tcg_temp_free_i32(lo);
314 tcg_temp_free_i32(hi);
319 /* Swap low and high halfwords. */
320 static void gen_swap_half(TCGv_i32 var)
322 TCGv_i32 tmp = tcg_temp_new_i32();
323 tcg_gen_shri_i32(tmp, var, 16);
324 tcg_gen_shli_i32(var, var, 16);
325 tcg_gen_or_i32(var, var, tmp);
326 tcg_temp_free_i32(tmp);
329 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
330 tmp = (t0 ^ t1) & 0x8000;
333 t0 = (t0 + t1) ^ tmp;
336 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
338 TCGv_i32 tmp = tcg_temp_new_i32();
339 tcg_gen_xor_i32(tmp, t0, t1);
340 tcg_gen_andi_i32(tmp, tmp, 0x8000);
341 tcg_gen_andi_i32(t0, t0, ~0x8000);
342 tcg_gen_andi_i32(t1, t1, ~0x8000);
343 tcg_gen_add_i32(t0, t0, t1);
344 tcg_gen_xor_i32(t0, t0, tmp);
345 tcg_temp_free_i32(tmp);
346 tcg_temp_free_i32(t1);
349 /* Set CF to the top bit of var. */
350 static void gen_set_CF_bit31(TCGv_i32 var)
352 tcg_gen_shri_i32(cpu_CF, var, 31);
355 /* Set N and Z flags from var. */
356 static inline void gen_logic_CC(TCGv_i32 var)
358 tcg_gen_mov_i32(cpu_NF, var);
359 tcg_gen_mov_i32(cpu_ZF, var);
363 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
365 tcg_gen_add_i32(t0, t0, t1);
366 tcg_gen_add_i32(t0, t0, cpu_CF);
369 /* dest = T0 + T1 + CF. */
370 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
372 tcg_gen_add_i32(dest, t0, t1);
373 tcg_gen_add_i32(dest, dest, cpu_CF);
376 /* dest = T0 - T1 + CF - 1. */
377 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
379 tcg_gen_sub_i32(dest, t0, t1);
380 tcg_gen_add_i32(dest, dest, cpu_CF);
381 tcg_gen_subi_i32(dest, dest, 1);
384 /* dest = T0 + T1. Compute C, N, V and Z flags */
385 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
387 TCGv_i32 tmp = tcg_temp_new_i32();
388 tcg_gen_movi_i32(tmp, 0);
389 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
390 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
391 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
392 tcg_gen_xor_i32(tmp, t0, t1);
393 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
394 tcg_temp_free_i32(tmp);
395 tcg_gen_mov_i32(dest, cpu_NF);
398 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
399 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
401 TCGv_i32 tmp = tcg_temp_new_i32();
402 if (TCG_TARGET_HAS_add2_i32) {
403 tcg_gen_movi_i32(tmp, 0);
404 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
405 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
407 TCGv_i64 q0 = tcg_temp_new_i64();
408 TCGv_i64 q1 = tcg_temp_new_i64();
409 tcg_gen_extu_i32_i64(q0, t0);
410 tcg_gen_extu_i32_i64(q1, t1);
411 tcg_gen_add_i64(q0, q0, q1);
412 tcg_gen_extu_i32_i64(q1, cpu_CF);
413 tcg_gen_add_i64(q0, q0, q1);
414 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
415 tcg_temp_free_i64(q0);
416 tcg_temp_free_i64(q1);
418 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
419 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
420 tcg_gen_xor_i32(tmp, t0, t1);
421 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
422 tcg_temp_free_i32(tmp);
423 tcg_gen_mov_i32(dest, cpu_NF);
426 /* dest = T0 - T1. Compute C, N, V and Z flags */
427 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
430 tcg_gen_sub_i32(cpu_NF, t0, t1);
431 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
432 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
433 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
434 tmp = tcg_temp_new_i32();
435 tcg_gen_xor_i32(tmp, t0, t1);
436 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
437 tcg_temp_free_i32(tmp);
438 tcg_gen_mov_i32(dest, cpu_NF);
441 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
442 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
444 TCGv_i32 tmp = tcg_temp_new_i32();
445 tcg_gen_not_i32(tmp, t1);
446 gen_adc_CC(dest, t0, tmp);
447 tcg_temp_free_i32(tmp);
450 #define GEN_SHIFT(name) \
451 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
453 TCGv_i32 tmp1, tmp2, tmp3; \
454 tmp1 = tcg_temp_new_i32(); \
455 tcg_gen_andi_i32(tmp1, t1, 0xff); \
456 tmp2 = tcg_const_i32(0); \
457 tmp3 = tcg_const_i32(0x1f); \
458 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
459 tcg_temp_free_i32(tmp3); \
460 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
461 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
462 tcg_temp_free_i32(tmp2); \
463 tcg_temp_free_i32(tmp1); \
469 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
472 tmp1 = tcg_temp_new_i32();
473 tcg_gen_andi_i32(tmp1, t1, 0xff);
474 tmp2 = tcg_const_i32(0x1f);
475 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
476 tcg_temp_free_i32(tmp2);
477 tcg_gen_sar_i32(dest, t0, tmp1);
478 tcg_temp_free_i32(tmp1);
481 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
483 TCGv_i32 c0 = tcg_const_i32(0);
484 TCGv_i32 tmp = tcg_temp_new_i32();
485 tcg_gen_neg_i32(tmp, src);
486 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
487 tcg_temp_free_i32(c0);
488 tcg_temp_free_i32(tmp);
491 static void shifter_out_im(TCGv_i32 var, int shift)
494 tcg_gen_andi_i32(cpu_CF, var, 1);
496 tcg_gen_shri_i32(cpu_CF, var, shift);
498 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
503 /* Shift by immediate. Includes special handling for shift == 0. */
504 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
505 int shift, int flags)
511 shifter_out_im(var, 32 - shift);
512 tcg_gen_shli_i32(var, var, shift);
518 tcg_gen_shri_i32(cpu_CF, var, 31);
520 tcg_gen_movi_i32(var, 0);
523 shifter_out_im(var, shift - 1);
524 tcg_gen_shri_i32(var, var, shift);
531 shifter_out_im(var, shift - 1);
534 tcg_gen_sari_i32(var, var, shift);
536 case 3: /* ROR/RRX */
539 shifter_out_im(var, shift - 1);
540 tcg_gen_rotri_i32(var, var, shift); break;
542 TCGv_i32 tmp = tcg_temp_new_i32();
543 tcg_gen_shli_i32(tmp, cpu_CF, 31);
545 shifter_out_im(var, 0);
546 tcg_gen_shri_i32(var, var, 1);
547 tcg_gen_or_i32(var, var, tmp);
548 tcg_temp_free_i32(tmp);
553 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
554 TCGv_i32 shift, int flags)
558 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
559 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
560 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
561 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
566 gen_shl(var, var, shift);
569 gen_shr(var, var, shift);
572 gen_sar(var, var, shift);
574 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
575 tcg_gen_rotr_i32(var, var, shift); break;
578 tcg_temp_free_i32(shift);
581 #define PAS_OP(pfx) \
583 case 0: gen_pas_helper(glue(pfx,add16)); break; \
584 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
585 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
586 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
587 case 4: gen_pas_helper(glue(pfx,add8)); break; \
588 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
590 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
595 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
597 tmp = tcg_temp_new_ptr();
598 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
600 tcg_temp_free_ptr(tmp);
603 tmp = tcg_temp_new_ptr();
604 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
606 tcg_temp_free_ptr(tmp);
608 #undef gen_pas_helper
609 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
622 #undef gen_pas_helper
627 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
628 #define PAS_OP(pfx) \
630 case 0: gen_pas_helper(glue(pfx,add8)); break; \
631 case 1: gen_pas_helper(glue(pfx,add16)); break; \
632 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
633 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
634 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
635 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
637 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
642 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
644 tmp = tcg_temp_new_ptr();
645 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
647 tcg_temp_free_ptr(tmp);
650 tmp = tcg_temp_new_ptr();
651 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
653 tcg_temp_free_ptr(tmp);
655 #undef gen_pas_helper
656 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
669 #undef gen_pas_helper
675 * generate a conditional branch based on ARM condition code cc.
676 * This is common between ARM and Aarch64 targets.
678 void arm_gen_test_cc(int cc, int label)
685 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
688 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
691 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
694 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
697 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
700 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
703 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
706 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
708 case 8: /* hi: C && !Z */
709 inv = gen_new_label();
710 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
711 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
714 case 9: /* ls: !C || Z */
715 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
716 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
718 case 10: /* ge: N == V -> N ^ V == 0 */
719 tmp = tcg_temp_new_i32();
720 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
721 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
722 tcg_temp_free_i32(tmp);
724 case 11: /* lt: N != V -> N ^ V != 0 */
725 tmp = tcg_temp_new_i32();
726 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
727 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
728 tcg_temp_free_i32(tmp);
730 case 12: /* gt: !Z && N == V */
731 inv = gen_new_label();
732 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
733 tmp = tcg_temp_new_i32();
734 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
735 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
736 tcg_temp_free_i32(tmp);
739 case 13: /* le: Z || N != V */
740 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
741 tmp = tcg_temp_new_i32();
742 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
743 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
744 tcg_temp_free_i32(tmp);
747 fprintf(stderr, "Bad condition code 0x%x\n", cc);
752 static const uint8_t table_logic_cc[16] = {
771 /* Set PC and Thumb state from an immediate address. */
772 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
776 s->is_jmp = DISAS_UPDATE;
777 if (s->thumb != (addr & 1)) {
778 tmp = tcg_temp_new_i32();
779 tcg_gen_movi_i32(tmp, addr & 1);
780 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
781 tcg_temp_free_i32(tmp);
783 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
786 /* Set PC and Thumb state from var. var is marked as dead. */
787 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
789 s->is_jmp = DISAS_UPDATE;
790 tcg_gen_andi_i32(cpu_R[15], var, ~1);
791 tcg_gen_andi_i32(var, var, 1);
792 store_cpu_field(var, thumb);
795 /* Variant of store_reg which uses branch&exchange logic when storing
796 to r15 in ARM architecture v7 and above. The source must be a temporary
797 and will be marked as dead. */
798 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
799 int reg, TCGv_i32 var)
801 if (reg == 15 && ENABLE_ARCH_7) {
804 store_reg(s, reg, var);
808 /* Variant of store_reg which uses branch&exchange logic when storing
809 * to r15 in ARM architecture v5T and above. This is used for storing
810 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
811 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
812 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
813 int reg, TCGv_i32 var)
815 if (reg == 15 && ENABLE_ARCH_5) {
818 store_reg(s, reg, var);
822 /* Abstractions of "generate code to do a guest load/store for
823 * AArch32", where a vaddr is always 32 bits (and is zero
824 * extended if we're a 64 bit core) and data is also
825 * 32 bits unless specifically doing a 64 bit access.
826 * These functions work like tcg_gen_qemu_{ld,st}* except
827 * that the address argument is TCGv_i32 rather than TCGv.
829 #if TARGET_LONG_BITS == 32
831 #define DO_GEN_LD(SUFF, OPC) \
832 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
834 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
837 #define DO_GEN_ST(SUFF, OPC) \
838 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
840 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
843 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
845 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
848 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
850 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
855 #define DO_GEN_LD(SUFF, OPC) \
856 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
858 TCGv addr64 = tcg_temp_new(); \
859 tcg_gen_extu_i32_i64(addr64, addr); \
860 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
861 tcg_temp_free(addr64); \
864 #define DO_GEN_ST(SUFF, OPC) \
865 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
867 TCGv addr64 = tcg_temp_new(); \
868 tcg_gen_extu_i32_i64(addr64, addr); \
869 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
870 tcg_temp_free(addr64); \
873 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
875 TCGv addr64 = tcg_temp_new();
876 tcg_gen_extu_i32_i64(addr64, addr);
877 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
878 tcg_temp_free(addr64);
881 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
883 TCGv addr64 = tcg_temp_new();
884 tcg_gen_extu_i32_i64(addr64, addr);
885 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
886 tcg_temp_free(addr64);
893 DO_GEN_LD(16s, MO_TESW)
894 DO_GEN_LD(16u, MO_TEUW)
895 DO_GEN_LD(32u, MO_TEUL)
897 DO_GEN_ST(16, MO_TEUW)
898 DO_GEN_ST(32, MO_TEUL)
900 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
902 tcg_gen_movi_i32(cpu_R[15], val);
905 /* Force a TB lookup after an instruction that changes the CPU state. */
906 static inline void gen_lookup_tb(DisasContext *s)
908 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
909 s->is_jmp = DISAS_UPDATE;
912 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
915 int val, rm, shift, shiftop;
918 if (!(insn & (1 << 25))) {
921 if (!(insn & (1 << 23)))
924 tcg_gen_addi_i32(var, var, val);
928 shift = (insn >> 7) & 0x1f;
929 shiftop = (insn >> 5) & 3;
930 offset = load_reg(s, rm);
931 gen_arm_shift_im(offset, shiftop, shift, 0);
932 if (!(insn & (1 << 23)))
933 tcg_gen_sub_i32(var, var, offset);
935 tcg_gen_add_i32(var, var, offset);
936 tcg_temp_free_i32(offset);
940 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
941 int extra, TCGv_i32 var)
946 if (insn & (1 << 22)) {
948 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
949 if (!(insn & (1 << 23)))
953 tcg_gen_addi_i32(var, var, val);
957 tcg_gen_addi_i32(var, var, extra);
959 offset = load_reg(s, rm);
960 if (!(insn & (1 << 23)))
961 tcg_gen_sub_i32(var, var, offset);
963 tcg_gen_add_i32(var, var, offset);
964 tcg_temp_free_i32(offset);
968 static TCGv_ptr get_fpstatus_ptr(int neon)
970 TCGv_ptr statusptr = tcg_temp_new_ptr();
973 offset = offsetof(CPUARMState, vfp.standard_fp_status);
975 offset = offsetof(CPUARMState, vfp.fp_status);
977 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
981 #define VFP_OP2(name) \
982 static inline void gen_vfp_##name(int dp) \
984 TCGv_ptr fpst = get_fpstatus_ptr(0); \
986 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
988 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
990 tcg_temp_free_ptr(fpst); \
1000 static inline void gen_vfp_F1_mul(int dp)
1002 /* Like gen_vfp_mul() but put result in F1 */
1003 TCGv_ptr fpst = get_fpstatus_ptr(0);
1005 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1007 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1009 tcg_temp_free_ptr(fpst);
1012 static inline void gen_vfp_F1_neg(int dp)
1014 /* Like gen_vfp_neg() but put result in F1 */
1016 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1018 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1022 static inline void gen_vfp_abs(int dp)
1025 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1027 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1030 static inline void gen_vfp_neg(int dp)
1033 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1035 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1038 static inline void gen_vfp_sqrt(int dp)
1041 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1043 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1046 static inline void gen_vfp_cmp(int dp)
1049 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1051 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1054 static inline void gen_vfp_cmpe(int dp)
1057 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1059 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1062 static inline void gen_vfp_F1_ld0(int dp)
1065 tcg_gen_movi_i64(cpu_F1d, 0);
1067 tcg_gen_movi_i32(cpu_F1s, 0);
1070 #define VFP_GEN_ITOF(name) \
1071 static inline void gen_vfp_##name(int dp, int neon) \
1073 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1075 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1077 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1079 tcg_temp_free_ptr(statusptr); \
1086 #define VFP_GEN_FTOI(name) \
1087 static inline void gen_vfp_##name(int dp, int neon) \
1089 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1091 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1093 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1095 tcg_temp_free_ptr(statusptr); \
1104 #define VFP_GEN_FIX(name) \
1105 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1107 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1108 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1110 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1112 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1114 tcg_temp_free_i32(tmp_shift); \
1115 tcg_temp_free_ptr(statusptr); \
1127 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1130 gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1132 gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1136 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1139 gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1141 gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1146 vfp_reg_offset (int dp, int reg)
1149 return offsetof(CPUARMState, vfp.regs[reg]);
1151 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1152 + offsetof(CPU_DoubleU, l.upper);
1154 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1155 + offsetof(CPU_DoubleU, l.lower);
1159 /* Return the offset of a 32-bit piece of a NEON register.
1160 zero is the least significant end of the register. */
1162 neon_reg_offset (int reg, int n)
1166 return vfp_reg_offset(0, sreg);
1169 static TCGv_i32 neon_load_reg(int reg, int pass)
1171 TCGv_i32 tmp = tcg_temp_new_i32();
1172 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1176 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1178 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1179 tcg_temp_free_i32(var);
1182 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1184 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1187 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1189 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1193 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1194 #define tcg_gen_st_f32 tcg_gen_st_i32
1195 #define tcg_gen_st_f64 tcg_gen_st_i64
1197 static inline void gen_mov_F0_vreg(int dp, int reg)
1200 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1202 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1205 static inline void gen_mov_F1_vreg(int dp, int reg)
1208 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1210 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1213 static inline void gen_mov_vreg_F0(int dp, int reg)
1216 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1218 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1221 #define ARM_CP_RW_BIT (1 << 20)
1223 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1225 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1228 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1230 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1233 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1235 TCGv_i32 var = tcg_temp_new_i32();
1236 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1240 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1242 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1243 tcg_temp_free_i32(var);
1246 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1248 iwmmxt_store_reg(cpu_M0, rn);
1251 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1253 iwmmxt_load_reg(cpu_M0, rn);
1256 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1258 iwmmxt_load_reg(cpu_V1, rn);
1259 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1262 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1264 iwmmxt_load_reg(cpu_V1, rn);
1265 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1268 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1270 iwmmxt_load_reg(cpu_V1, rn);
1271 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1274 #define IWMMXT_OP(name) \
1275 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1277 iwmmxt_load_reg(cpu_V1, rn); \
1278 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1281 #define IWMMXT_OP_ENV(name) \
1282 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1284 iwmmxt_load_reg(cpu_V1, rn); \
1285 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1288 #define IWMMXT_OP_ENV_SIZE(name) \
1289 IWMMXT_OP_ENV(name##b) \
1290 IWMMXT_OP_ENV(name##w) \
1291 IWMMXT_OP_ENV(name##l)
1293 #define IWMMXT_OP_ENV1(name) \
1294 static inline void gen_op_iwmmxt_##name##_M0(void) \
1296 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1310 IWMMXT_OP_ENV_SIZE(unpackl)
1311 IWMMXT_OP_ENV_SIZE(unpackh)
1313 IWMMXT_OP_ENV1(unpacklub)
1314 IWMMXT_OP_ENV1(unpackluw)
1315 IWMMXT_OP_ENV1(unpacklul)
1316 IWMMXT_OP_ENV1(unpackhub)
1317 IWMMXT_OP_ENV1(unpackhuw)
1318 IWMMXT_OP_ENV1(unpackhul)
1319 IWMMXT_OP_ENV1(unpacklsb)
1320 IWMMXT_OP_ENV1(unpacklsw)
1321 IWMMXT_OP_ENV1(unpacklsl)
1322 IWMMXT_OP_ENV1(unpackhsb)
1323 IWMMXT_OP_ENV1(unpackhsw)
1324 IWMMXT_OP_ENV1(unpackhsl)
1326 IWMMXT_OP_ENV_SIZE(cmpeq)
1327 IWMMXT_OP_ENV_SIZE(cmpgtu)
1328 IWMMXT_OP_ENV_SIZE(cmpgts)
1330 IWMMXT_OP_ENV_SIZE(mins)
1331 IWMMXT_OP_ENV_SIZE(minu)
1332 IWMMXT_OP_ENV_SIZE(maxs)
1333 IWMMXT_OP_ENV_SIZE(maxu)
1335 IWMMXT_OP_ENV_SIZE(subn)
1336 IWMMXT_OP_ENV_SIZE(addn)
1337 IWMMXT_OP_ENV_SIZE(subu)
1338 IWMMXT_OP_ENV_SIZE(addu)
1339 IWMMXT_OP_ENV_SIZE(subs)
1340 IWMMXT_OP_ENV_SIZE(adds)
1342 IWMMXT_OP_ENV(avgb0)
1343 IWMMXT_OP_ENV(avgb1)
1344 IWMMXT_OP_ENV(avgw0)
1345 IWMMXT_OP_ENV(avgw1)
1349 IWMMXT_OP_ENV(packuw)
1350 IWMMXT_OP_ENV(packul)
1351 IWMMXT_OP_ENV(packuq)
1352 IWMMXT_OP_ENV(packsw)
1353 IWMMXT_OP_ENV(packsl)
1354 IWMMXT_OP_ENV(packsq)
1356 static void gen_op_iwmmxt_set_mup(void)
1359 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1360 tcg_gen_ori_i32(tmp, tmp, 2);
1361 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1364 static void gen_op_iwmmxt_set_cup(void)
1367 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1368 tcg_gen_ori_i32(tmp, tmp, 1);
1369 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1372 static void gen_op_iwmmxt_setpsr_nz(void)
1374 TCGv_i32 tmp = tcg_temp_new_i32();
1375 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1376 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1379 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1381 iwmmxt_load_reg(cpu_V1, rn);
1382 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1383 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1386 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1393 rd = (insn >> 16) & 0xf;
1394 tmp = load_reg(s, rd);
1396 offset = (insn & 0xff) << ((insn >> 7) & 2);
1397 if (insn & (1 << 24)) {
1399 if (insn & (1 << 23))
1400 tcg_gen_addi_i32(tmp, tmp, offset);
1402 tcg_gen_addi_i32(tmp, tmp, -offset);
1403 tcg_gen_mov_i32(dest, tmp);
1404 if (insn & (1 << 21))
1405 store_reg(s, rd, tmp);
1407 tcg_temp_free_i32(tmp);
1408 } else if (insn & (1 << 21)) {
1410 tcg_gen_mov_i32(dest, tmp);
1411 if (insn & (1 << 23))
1412 tcg_gen_addi_i32(tmp, tmp, offset);
1414 tcg_gen_addi_i32(tmp, tmp, -offset);
1415 store_reg(s, rd, tmp);
1416 } else if (!(insn & (1 << 23)))
1421 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1423 int rd = (insn >> 0) & 0xf;
1426 if (insn & (1 << 8)) {
1427 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1430 tmp = iwmmxt_load_creg(rd);
1433 tmp = tcg_temp_new_i32();
1434 iwmmxt_load_reg(cpu_V0, rd);
1435 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1437 tcg_gen_andi_i32(tmp, tmp, mask);
1438 tcg_gen_mov_i32(dest, tmp);
1439 tcg_temp_free_i32(tmp);
1443 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1444 (ie. an undefined instruction). */
1445 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1448 int rdhi, rdlo, rd0, rd1, i;
1450 TCGv_i32 tmp, tmp2, tmp3;
1452 if ((insn & 0x0e000e00) == 0x0c000000) {
1453 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1455 rdlo = (insn >> 12) & 0xf;
1456 rdhi = (insn >> 16) & 0xf;
1457 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1458 iwmmxt_load_reg(cpu_V0, wrd);
1459 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1460 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1461 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1462 } else { /* TMCRR */
1463 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1464 iwmmxt_store_reg(cpu_V0, wrd);
1465 gen_op_iwmmxt_set_mup();
1470 wrd = (insn >> 12) & 0xf;
1471 addr = tcg_temp_new_i32();
1472 if (gen_iwmmxt_address(s, insn, addr)) {
1473 tcg_temp_free_i32(addr);
1476 if (insn & ARM_CP_RW_BIT) {
1477 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1478 tmp = tcg_temp_new_i32();
1479 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1480 iwmmxt_store_creg(wrd, tmp);
1483 if (insn & (1 << 8)) {
1484 if (insn & (1 << 22)) { /* WLDRD */
1485 gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1487 } else { /* WLDRW wRd */
1488 tmp = tcg_temp_new_i32();
1489 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1492 tmp = tcg_temp_new_i32();
1493 if (insn & (1 << 22)) { /* WLDRH */
1494 gen_aa32_ld16u(tmp, addr, IS_USER(s));
1495 } else { /* WLDRB */
1496 gen_aa32_ld8u(tmp, addr, IS_USER(s));
1500 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1501 tcg_temp_free_i32(tmp);
1503 gen_op_iwmmxt_movq_wRn_M0(wrd);
1506 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1507 tmp = iwmmxt_load_creg(wrd);
1508 gen_aa32_st32(tmp, addr, IS_USER(s));
1510 gen_op_iwmmxt_movq_M0_wRn(wrd);
1511 tmp = tcg_temp_new_i32();
1512 if (insn & (1 << 8)) {
1513 if (insn & (1 << 22)) { /* WSTRD */
1514 gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1515 } else { /* WSTRW wRd */
1516 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1517 gen_aa32_st32(tmp, addr, IS_USER(s));
1520 if (insn & (1 << 22)) { /* WSTRH */
1521 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1522 gen_aa32_st16(tmp, addr, IS_USER(s));
1523 } else { /* WSTRB */
1524 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1525 gen_aa32_st8(tmp, addr, IS_USER(s));
1529 tcg_temp_free_i32(tmp);
1531 tcg_temp_free_i32(addr);
1535 if ((insn & 0x0f000000) != 0x0e000000)
1538 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1539 case 0x000: /* WOR */
1540 wrd = (insn >> 12) & 0xf;
1541 rd0 = (insn >> 0) & 0xf;
1542 rd1 = (insn >> 16) & 0xf;
1543 gen_op_iwmmxt_movq_M0_wRn(rd0);
1544 gen_op_iwmmxt_orq_M0_wRn(rd1);
1545 gen_op_iwmmxt_setpsr_nz();
1546 gen_op_iwmmxt_movq_wRn_M0(wrd);
1547 gen_op_iwmmxt_set_mup();
1548 gen_op_iwmmxt_set_cup();
1550 case 0x011: /* TMCR */
1553 rd = (insn >> 12) & 0xf;
1554 wrd = (insn >> 16) & 0xf;
1556 case ARM_IWMMXT_wCID:
1557 case ARM_IWMMXT_wCASF:
1559 case ARM_IWMMXT_wCon:
1560 gen_op_iwmmxt_set_cup();
1562 case ARM_IWMMXT_wCSSF:
1563 tmp = iwmmxt_load_creg(wrd);
1564 tmp2 = load_reg(s, rd);
1565 tcg_gen_andc_i32(tmp, tmp, tmp2);
1566 tcg_temp_free_i32(tmp2);
1567 iwmmxt_store_creg(wrd, tmp);
1569 case ARM_IWMMXT_wCGR0:
1570 case ARM_IWMMXT_wCGR1:
1571 case ARM_IWMMXT_wCGR2:
1572 case ARM_IWMMXT_wCGR3:
1573 gen_op_iwmmxt_set_cup();
1574 tmp = load_reg(s, rd);
1575 iwmmxt_store_creg(wrd, tmp);
1581 case 0x100: /* WXOR */
1582 wrd = (insn >> 12) & 0xf;
1583 rd0 = (insn >> 0) & 0xf;
1584 rd1 = (insn >> 16) & 0xf;
1585 gen_op_iwmmxt_movq_M0_wRn(rd0);
1586 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1587 gen_op_iwmmxt_setpsr_nz();
1588 gen_op_iwmmxt_movq_wRn_M0(wrd);
1589 gen_op_iwmmxt_set_mup();
1590 gen_op_iwmmxt_set_cup();
1592 case 0x111: /* TMRC */
1595 rd = (insn >> 12) & 0xf;
1596 wrd = (insn >> 16) & 0xf;
1597 tmp = iwmmxt_load_creg(wrd);
1598 store_reg(s, rd, tmp);
1600 case 0x300: /* WANDN */
1601 wrd = (insn >> 12) & 0xf;
1602 rd0 = (insn >> 0) & 0xf;
1603 rd1 = (insn >> 16) & 0xf;
1604 gen_op_iwmmxt_movq_M0_wRn(rd0);
1605 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1606 gen_op_iwmmxt_andq_M0_wRn(rd1);
1607 gen_op_iwmmxt_setpsr_nz();
1608 gen_op_iwmmxt_movq_wRn_M0(wrd);
1609 gen_op_iwmmxt_set_mup();
1610 gen_op_iwmmxt_set_cup();
1612 case 0x200: /* WAND */
1613 wrd = (insn >> 12) & 0xf;
1614 rd0 = (insn >> 0) & 0xf;
1615 rd1 = (insn >> 16) & 0xf;
1616 gen_op_iwmmxt_movq_M0_wRn(rd0);
1617 gen_op_iwmmxt_andq_M0_wRn(rd1);
1618 gen_op_iwmmxt_setpsr_nz();
1619 gen_op_iwmmxt_movq_wRn_M0(wrd);
1620 gen_op_iwmmxt_set_mup();
1621 gen_op_iwmmxt_set_cup();
1623 case 0x810: case 0xa10: /* WMADD */
1624 wrd = (insn >> 12) & 0xf;
1625 rd0 = (insn >> 0) & 0xf;
1626 rd1 = (insn >> 16) & 0xf;
1627 gen_op_iwmmxt_movq_M0_wRn(rd0);
1628 if (insn & (1 << 21))
1629 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1631 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1632 gen_op_iwmmxt_movq_wRn_M0(wrd);
1633 gen_op_iwmmxt_set_mup();
1635 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1636 wrd = (insn >> 12) & 0xf;
1637 rd0 = (insn >> 16) & 0xf;
1638 rd1 = (insn >> 0) & 0xf;
1639 gen_op_iwmmxt_movq_M0_wRn(rd0);
1640 switch ((insn >> 22) & 3) {
1642 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1645 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1648 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1653 gen_op_iwmmxt_movq_wRn_M0(wrd);
1654 gen_op_iwmmxt_set_mup();
1655 gen_op_iwmmxt_set_cup();
1657 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1658 wrd = (insn >> 12) & 0xf;
1659 rd0 = (insn >> 16) & 0xf;
1660 rd1 = (insn >> 0) & 0xf;
1661 gen_op_iwmmxt_movq_M0_wRn(rd0);
1662 switch ((insn >> 22) & 3) {
1664 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1667 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1670 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1675 gen_op_iwmmxt_movq_wRn_M0(wrd);
1676 gen_op_iwmmxt_set_mup();
1677 gen_op_iwmmxt_set_cup();
1679 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1680 wrd = (insn >> 12) & 0xf;
1681 rd0 = (insn >> 16) & 0xf;
1682 rd1 = (insn >> 0) & 0xf;
1683 gen_op_iwmmxt_movq_M0_wRn(rd0);
1684 if (insn & (1 << 22))
1685 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1687 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1688 if (!(insn & (1 << 20)))
1689 gen_op_iwmmxt_addl_M0_wRn(wrd);
1690 gen_op_iwmmxt_movq_wRn_M0(wrd);
1691 gen_op_iwmmxt_set_mup();
1693 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1694 wrd = (insn >> 12) & 0xf;
1695 rd0 = (insn >> 16) & 0xf;
1696 rd1 = (insn >> 0) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0);
1698 if (insn & (1 << 21)) {
1699 if (insn & (1 << 20))
1700 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1702 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1704 if (insn & (1 << 20))
1705 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1707 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1709 gen_op_iwmmxt_movq_wRn_M0(wrd);
1710 gen_op_iwmmxt_set_mup();
1712 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1713 wrd = (insn >> 12) & 0xf;
1714 rd0 = (insn >> 16) & 0xf;
1715 rd1 = (insn >> 0) & 0xf;
1716 gen_op_iwmmxt_movq_M0_wRn(rd0);
1717 if (insn & (1 << 21))
1718 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1720 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1721 if (!(insn & (1 << 20))) {
1722 iwmmxt_load_reg(cpu_V1, wrd);
1723 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1725 gen_op_iwmmxt_movq_wRn_M0(wrd);
1726 gen_op_iwmmxt_set_mup();
1728 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1729 wrd = (insn >> 12) & 0xf;
1730 rd0 = (insn >> 16) & 0xf;
1731 rd1 = (insn >> 0) & 0xf;
1732 gen_op_iwmmxt_movq_M0_wRn(rd0);
1733 switch ((insn >> 22) & 3) {
1735 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1738 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1741 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1746 gen_op_iwmmxt_movq_wRn_M0(wrd);
1747 gen_op_iwmmxt_set_mup();
1748 gen_op_iwmmxt_set_cup();
1750 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1751 wrd = (insn >> 12) & 0xf;
1752 rd0 = (insn >> 16) & 0xf;
1753 rd1 = (insn >> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0);
1755 if (insn & (1 << 22)) {
1756 if (insn & (1 << 20))
1757 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1759 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1761 if (insn & (1 << 20))
1762 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1764 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1766 gen_op_iwmmxt_movq_wRn_M0(wrd);
1767 gen_op_iwmmxt_set_mup();
1768 gen_op_iwmmxt_set_cup();
1770 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1771 wrd = (insn >> 12) & 0xf;
1772 rd0 = (insn >> 16) & 0xf;
1773 rd1 = (insn >> 0) & 0xf;
1774 gen_op_iwmmxt_movq_M0_wRn(rd0);
1775 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1776 tcg_gen_andi_i32(tmp, tmp, 7);
1777 iwmmxt_load_reg(cpu_V1, rd1);
1778 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1779 tcg_temp_free_i32(tmp);
1780 gen_op_iwmmxt_movq_wRn_M0(wrd);
1781 gen_op_iwmmxt_set_mup();
1783 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1784 if (((insn >> 6) & 3) == 3)
1786 rd = (insn >> 12) & 0xf;
1787 wrd = (insn >> 16) & 0xf;
1788 tmp = load_reg(s, rd);
1789 gen_op_iwmmxt_movq_M0_wRn(wrd);
1790 switch ((insn >> 6) & 3) {
1792 tmp2 = tcg_const_i32(0xff);
1793 tmp3 = tcg_const_i32((insn & 7) << 3);
1796 tmp2 = tcg_const_i32(0xffff);
1797 tmp3 = tcg_const_i32((insn & 3) << 4);
1800 tmp2 = tcg_const_i32(0xffffffff);
1801 tmp3 = tcg_const_i32((insn & 1) << 5);
1804 TCGV_UNUSED_I32(tmp2);
1805 TCGV_UNUSED_I32(tmp3);
1807 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1808 tcg_temp_free_i32(tmp3);
1809 tcg_temp_free_i32(tmp2);
1810 tcg_temp_free_i32(tmp);
1811 gen_op_iwmmxt_movq_wRn_M0(wrd);
1812 gen_op_iwmmxt_set_mup();
1814 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1815 rd = (insn >> 12) & 0xf;
1816 wrd = (insn >> 16) & 0xf;
1817 if (rd == 15 || ((insn >> 22) & 3) == 3)
1819 gen_op_iwmmxt_movq_M0_wRn(wrd);
1820 tmp = tcg_temp_new_i32();
1821 switch ((insn >> 22) & 3) {
1823 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1824 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1826 tcg_gen_ext8s_i32(tmp, tmp);
1828 tcg_gen_andi_i32(tmp, tmp, 0xff);
1832 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1833 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1835 tcg_gen_ext16s_i32(tmp, tmp);
1837 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1841 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1842 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1845 store_reg(s, rd, tmp);
1847 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1848 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1850 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1851 switch ((insn >> 22) & 3) {
1853 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1856 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1859 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1862 tcg_gen_shli_i32(tmp, tmp, 28);
1864 tcg_temp_free_i32(tmp);
1866 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1867 if (((insn >> 6) & 3) == 3)
1869 rd = (insn >> 12) & 0xf;
1870 wrd = (insn >> 16) & 0xf;
1871 tmp = load_reg(s, rd);
1872 switch ((insn >> 6) & 3) {
1874 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1877 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1880 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1883 tcg_temp_free_i32(tmp);
1884 gen_op_iwmmxt_movq_wRn_M0(wrd);
1885 gen_op_iwmmxt_set_mup();
1887 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1888 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1890 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1891 tmp2 = tcg_temp_new_i32();
1892 tcg_gen_mov_i32(tmp2, tmp);
1893 switch ((insn >> 22) & 3) {
1895 for (i = 0; i < 7; i ++) {
1896 tcg_gen_shli_i32(tmp2, tmp2, 4);
1897 tcg_gen_and_i32(tmp, tmp, tmp2);
1901 for (i = 0; i < 3; i ++) {
1902 tcg_gen_shli_i32(tmp2, tmp2, 8);
1903 tcg_gen_and_i32(tmp, tmp, tmp2);
1907 tcg_gen_shli_i32(tmp2, tmp2, 16);
1908 tcg_gen_and_i32(tmp, tmp, tmp2);
1912 tcg_temp_free_i32(tmp2);
1913 tcg_temp_free_i32(tmp);
1915 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1916 wrd = (insn >> 12) & 0xf;
1917 rd0 = (insn >> 16) & 0xf;
1918 gen_op_iwmmxt_movq_M0_wRn(rd0);
1919 switch ((insn >> 22) & 3) {
1921 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1924 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1927 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1932 gen_op_iwmmxt_movq_wRn_M0(wrd);
1933 gen_op_iwmmxt_set_mup();
1935 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1936 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1938 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1939 tmp2 = tcg_temp_new_i32();
1940 tcg_gen_mov_i32(tmp2, tmp);
1941 switch ((insn >> 22) & 3) {
1943 for (i = 0; i < 7; i ++) {
1944 tcg_gen_shli_i32(tmp2, tmp2, 4);
1945 tcg_gen_or_i32(tmp, tmp, tmp2);
1949 for (i = 0; i < 3; i ++) {
1950 tcg_gen_shli_i32(tmp2, tmp2, 8);
1951 tcg_gen_or_i32(tmp, tmp, tmp2);
1955 tcg_gen_shli_i32(tmp2, tmp2, 16);
1956 tcg_gen_or_i32(tmp, tmp, tmp2);
1960 tcg_temp_free_i32(tmp2);
1961 tcg_temp_free_i32(tmp);
1963 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1964 rd = (insn >> 12) & 0xf;
1965 rd0 = (insn >> 16) & 0xf;
1966 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1968 gen_op_iwmmxt_movq_M0_wRn(rd0);
1969 tmp = tcg_temp_new_i32();
1970 switch ((insn >> 22) & 3) {
1972 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1975 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1978 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1981 store_reg(s, rd, tmp);
1983 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1984 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1985 wrd = (insn >> 12) & 0xf;
1986 rd0 = (insn >> 16) & 0xf;
1987 rd1 = (insn >> 0) & 0xf;
1988 gen_op_iwmmxt_movq_M0_wRn(rd0);
1989 switch ((insn >> 22) & 3) {
1991 if (insn & (1 << 21))
1992 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1994 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1997 if (insn & (1 << 21))
1998 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2000 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2003 if (insn & (1 << 21))
2004 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2006 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2011 gen_op_iwmmxt_movq_wRn_M0(wrd);
2012 gen_op_iwmmxt_set_mup();
2013 gen_op_iwmmxt_set_cup();
2015 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2016 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2017 wrd = (insn >> 12) & 0xf;
2018 rd0 = (insn >> 16) & 0xf;
2019 gen_op_iwmmxt_movq_M0_wRn(rd0);
2020 switch ((insn >> 22) & 3) {
2022 if (insn & (1 << 21))
2023 gen_op_iwmmxt_unpacklsb_M0();
2025 gen_op_iwmmxt_unpacklub_M0();
2028 if (insn & (1 << 21))
2029 gen_op_iwmmxt_unpacklsw_M0();
2031 gen_op_iwmmxt_unpackluw_M0();
2034 if (insn & (1 << 21))
2035 gen_op_iwmmxt_unpacklsl_M0();
2037 gen_op_iwmmxt_unpacklul_M0();
2042 gen_op_iwmmxt_movq_wRn_M0(wrd);
2043 gen_op_iwmmxt_set_mup();
2044 gen_op_iwmmxt_set_cup();
2046 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2047 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2048 wrd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 16) & 0xf;
2050 gen_op_iwmmxt_movq_M0_wRn(rd0);
2051 switch ((insn >> 22) & 3) {
2053 if (insn & (1 << 21))
2054 gen_op_iwmmxt_unpackhsb_M0();
2056 gen_op_iwmmxt_unpackhub_M0();
2059 if (insn & (1 << 21))
2060 gen_op_iwmmxt_unpackhsw_M0();
2062 gen_op_iwmmxt_unpackhuw_M0();
2065 if (insn & (1 << 21))
2066 gen_op_iwmmxt_unpackhsl_M0();
2068 gen_op_iwmmxt_unpackhul_M0();
2073 gen_op_iwmmxt_movq_wRn_M0(wrd);
2074 gen_op_iwmmxt_set_mup();
2075 gen_op_iwmmxt_set_cup();
2077 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2078 case 0x214: case 0x614: case 0xa14: case 0xe14:
2079 if (((insn >> 22) & 3) == 0)
2081 wrd = (insn >> 12) & 0xf;
2082 rd0 = (insn >> 16) & 0xf;
2083 gen_op_iwmmxt_movq_M0_wRn(rd0);
2084 tmp = tcg_temp_new_i32();
2085 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2086 tcg_temp_free_i32(tmp);
2089 switch ((insn >> 22) & 3) {
2091 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2094 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2097 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2100 tcg_temp_free_i32(tmp);
2101 gen_op_iwmmxt_movq_wRn_M0(wrd);
2102 gen_op_iwmmxt_set_mup();
2103 gen_op_iwmmxt_set_cup();
2105 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2106 case 0x014: case 0x414: case 0x814: case 0xc14:
2107 if (((insn >> 22) & 3) == 0)
2109 wrd = (insn >> 12) & 0xf;
2110 rd0 = (insn >> 16) & 0xf;
2111 gen_op_iwmmxt_movq_M0_wRn(rd0);
2112 tmp = tcg_temp_new_i32();
2113 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2114 tcg_temp_free_i32(tmp);
2117 switch ((insn >> 22) & 3) {
2119 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2122 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2125 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2128 tcg_temp_free_i32(tmp);
2129 gen_op_iwmmxt_movq_wRn_M0(wrd);
2130 gen_op_iwmmxt_set_mup();
2131 gen_op_iwmmxt_set_cup();
2133 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2134 case 0x114: case 0x514: case 0x914: case 0xd14:
2135 if (((insn >> 22) & 3) == 0)
2137 wrd = (insn >> 12) & 0xf;
2138 rd0 = (insn >> 16) & 0xf;
2139 gen_op_iwmmxt_movq_M0_wRn(rd0);
2140 tmp = tcg_temp_new_i32();
2141 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2142 tcg_temp_free_i32(tmp);
2145 switch ((insn >> 22) & 3) {
2147 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2150 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2153 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2156 tcg_temp_free_i32(tmp);
2157 gen_op_iwmmxt_movq_wRn_M0(wrd);
2158 gen_op_iwmmxt_set_mup();
2159 gen_op_iwmmxt_set_cup();
2161 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2162 case 0x314: case 0x714: case 0xb14: case 0xf14:
2163 if (((insn >> 22) & 3) == 0)
2165 wrd = (insn >> 12) & 0xf;
2166 rd0 = (insn >> 16) & 0xf;
2167 gen_op_iwmmxt_movq_M0_wRn(rd0);
2168 tmp = tcg_temp_new_i32();
2169 switch ((insn >> 22) & 3) {
2171 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2172 tcg_temp_free_i32(tmp);
2175 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2178 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2179 tcg_temp_free_i32(tmp);
2182 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2185 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2186 tcg_temp_free_i32(tmp);
2189 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2192 tcg_temp_free_i32(tmp);
2193 gen_op_iwmmxt_movq_wRn_M0(wrd);
2194 gen_op_iwmmxt_set_mup();
2195 gen_op_iwmmxt_set_cup();
2197 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2198 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2199 wrd = (insn >> 12) & 0xf;
2200 rd0 = (insn >> 16) & 0xf;
2201 rd1 = (insn >> 0) & 0xf;
2202 gen_op_iwmmxt_movq_M0_wRn(rd0);
2203 switch ((insn >> 22) & 3) {
2205 if (insn & (1 << 21))
2206 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2208 gen_op_iwmmxt_minub_M0_wRn(rd1);
2211 if (insn & (1 << 21))
2212 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2214 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2217 if (insn & (1 << 21))
2218 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2220 gen_op_iwmmxt_minul_M0_wRn(rd1);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd);
2226 gen_op_iwmmxt_set_mup();
2228 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2229 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2230 wrd = (insn >> 12) & 0xf;
2231 rd0 = (insn >> 16) & 0xf;
2232 rd1 = (insn >> 0) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0);
2234 switch ((insn >> 22) & 3) {
2236 if (insn & (1 << 21))
2237 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2239 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2242 if (insn & (1 << 21))
2243 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2245 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2248 if (insn & (1 << 21))
2249 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2251 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2256 gen_op_iwmmxt_movq_wRn_M0(wrd);
2257 gen_op_iwmmxt_set_mup();
2259 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2260 case 0x402: case 0x502: case 0x602: case 0x702:
2261 wrd = (insn >> 12) & 0xf;
2262 rd0 = (insn >> 16) & 0xf;
2263 rd1 = (insn >> 0) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0);
2265 tmp = tcg_const_i32((insn >> 20) & 3);
2266 iwmmxt_load_reg(cpu_V1, rd1);
2267 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2268 tcg_temp_free_i32(tmp);
2269 gen_op_iwmmxt_movq_wRn_M0(wrd);
2270 gen_op_iwmmxt_set_mup();
2272 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2273 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2274 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2275 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2276 wrd = (insn >> 12) & 0xf;
2277 rd0 = (insn >> 16) & 0xf;
2278 rd1 = (insn >> 0) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0);
2280 switch ((insn >> 20) & 0xf) {
2282 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2285 gen_op_iwmmxt_subub_M0_wRn(rd1);
2288 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2291 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2294 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2297 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2300 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2303 gen_op_iwmmxt_subul_M0_wRn(rd1);
2306 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2311 gen_op_iwmmxt_movq_wRn_M0(wrd);
2312 gen_op_iwmmxt_set_mup();
2313 gen_op_iwmmxt_set_cup();
2315 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2316 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2317 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2318 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2319 wrd = (insn >> 12) & 0xf;
2320 rd0 = (insn >> 16) & 0xf;
2321 gen_op_iwmmxt_movq_M0_wRn(rd0);
2322 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2323 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2324 tcg_temp_free_i32(tmp);
2325 gen_op_iwmmxt_movq_wRn_M0(wrd);
2326 gen_op_iwmmxt_set_mup();
2327 gen_op_iwmmxt_set_cup();
2329 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2330 case 0x418: case 0x518: case 0x618: case 0x718:
2331 case 0x818: case 0x918: case 0xa18: case 0xb18:
2332 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2333 wrd = (insn >> 12) & 0xf;
2334 rd0 = (insn >> 16) & 0xf;
2335 rd1 = (insn >> 0) & 0xf;
2336 gen_op_iwmmxt_movq_M0_wRn(rd0);
2337 switch ((insn >> 20) & 0xf) {
2339 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2342 gen_op_iwmmxt_addub_M0_wRn(rd1);
2345 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2348 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2351 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2354 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2357 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2360 gen_op_iwmmxt_addul_M0_wRn(rd1);
2363 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2368 gen_op_iwmmxt_movq_wRn_M0(wrd);
2369 gen_op_iwmmxt_set_mup();
2370 gen_op_iwmmxt_set_cup();
2372 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2373 case 0x408: case 0x508: case 0x608: case 0x708:
2374 case 0x808: case 0x908: case 0xa08: case 0xb08:
2375 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2376 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2378 wrd = (insn >> 12) & 0xf;
2379 rd0 = (insn >> 16) & 0xf;
2380 rd1 = (insn >> 0) & 0xf;
2381 gen_op_iwmmxt_movq_M0_wRn(rd0);
2382 switch ((insn >> 22) & 3) {
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2387 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2390 if (insn & (1 << 21))
2391 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2393 gen_op_iwmmxt_packul_M0_wRn(rd1);
2396 if (insn & (1 << 21))
2397 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2399 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2402 gen_op_iwmmxt_movq_wRn_M0(wrd);
2403 gen_op_iwmmxt_set_mup();
2404 gen_op_iwmmxt_set_cup();
2406 case 0x201: case 0x203: case 0x205: case 0x207:
2407 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2408 case 0x211: case 0x213: case 0x215: case 0x217:
2409 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2410 wrd = (insn >> 5) & 0xf;
2411 rd0 = (insn >> 12) & 0xf;
2412 rd1 = (insn >> 0) & 0xf;
2413 if (rd0 == 0xf || rd1 == 0xf)
2415 gen_op_iwmmxt_movq_M0_wRn(wrd);
2416 tmp = load_reg(s, rd0);
2417 tmp2 = load_reg(s, rd1);
2418 switch ((insn >> 16) & 0xf) {
2419 case 0x0: /* TMIA */
2420 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2422 case 0x8: /* TMIAPH */
2423 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2425 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2426 if (insn & (1 << 16))
2427 tcg_gen_shri_i32(tmp, tmp, 16);
2428 if (insn & (1 << 17))
2429 tcg_gen_shri_i32(tmp2, tmp2, 16);
2430 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2433 tcg_temp_free_i32(tmp2);
2434 tcg_temp_free_i32(tmp);
2437 tcg_temp_free_i32(tmp2);
2438 tcg_temp_free_i32(tmp);
2439 gen_op_iwmmxt_movq_wRn_M0(wrd);
2440 gen_op_iwmmxt_set_mup();
2449 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2450 (ie. an undefined instruction). */
2451 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2453 int acc, rd0, rd1, rdhi, rdlo;
2456 if ((insn & 0x0ff00f10) == 0x0e200010) {
2457 /* Multiply with Internal Accumulate Format */
2458 rd0 = (insn >> 12) & 0xf;
2460 acc = (insn >> 5) & 7;
2465 tmp = load_reg(s, rd0);
2466 tmp2 = load_reg(s, rd1);
2467 switch ((insn >> 16) & 0xf) {
2469 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2471 case 0x8: /* MIAPH */
2472 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2474 case 0xc: /* MIABB */
2475 case 0xd: /* MIABT */
2476 case 0xe: /* MIATB */
2477 case 0xf: /* MIATT */
2478 if (insn & (1 << 16))
2479 tcg_gen_shri_i32(tmp, tmp, 16);
2480 if (insn & (1 << 17))
2481 tcg_gen_shri_i32(tmp2, tmp2, 16);
2482 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2487 tcg_temp_free_i32(tmp2);
2488 tcg_temp_free_i32(tmp);
2490 gen_op_iwmmxt_movq_wRn_M0(acc);
2494 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2495 /* Internal Accumulator Access Format */
2496 rdhi = (insn >> 16) & 0xf;
2497 rdlo = (insn >> 12) & 0xf;
2503 if (insn & ARM_CP_RW_BIT) { /* MRA */
2504 iwmmxt_load_reg(cpu_V0, acc);
2505 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2506 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2507 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2508 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2510 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2511 iwmmxt_store_reg(cpu_V0, acc);
2519 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2520 #define VFP_SREG(insn, bigbit, smallbit) \
2521 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2522 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2523 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2524 reg = (((insn) >> (bigbit)) & 0x0f) \
2525 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2527 if (insn & (1 << (smallbit))) \
2529 reg = ((insn) >> (bigbit)) & 0x0f; \
2532 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2533 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2534 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2535 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2536 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2537 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2539 /* Move between integer and VFP cores. */
2540 static TCGv_i32 gen_vfp_mrs(void)
2542 TCGv_i32 tmp = tcg_temp_new_i32();
2543 tcg_gen_mov_i32(tmp, cpu_F0s);
2547 static void gen_vfp_msr(TCGv_i32 tmp)
2549 tcg_gen_mov_i32(cpu_F0s, tmp);
2550 tcg_temp_free_i32(tmp);
2553 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2555 TCGv_i32 tmp = tcg_temp_new_i32();
2557 tcg_gen_shri_i32(var, var, shift);
2558 tcg_gen_ext8u_i32(var, var);
2559 tcg_gen_shli_i32(tmp, var, 8);
2560 tcg_gen_or_i32(var, var, tmp);
2561 tcg_gen_shli_i32(tmp, var, 16);
2562 tcg_gen_or_i32(var, var, tmp);
2563 tcg_temp_free_i32(tmp);
2566 static void gen_neon_dup_low16(TCGv_i32 var)
2568 TCGv_i32 tmp = tcg_temp_new_i32();
2569 tcg_gen_ext16u_i32(var, var);
2570 tcg_gen_shli_i32(tmp, var, 16);
2571 tcg_gen_or_i32(var, var, tmp);
2572 tcg_temp_free_i32(tmp);
2575 static void gen_neon_dup_high16(TCGv_i32 var)
2577 TCGv_i32 tmp = tcg_temp_new_i32();
2578 tcg_gen_andi_i32(var, var, 0xffff0000);
2579 tcg_gen_shri_i32(tmp, var, 16);
2580 tcg_gen_or_i32(var, var, tmp);
2581 tcg_temp_free_i32(tmp);
2584 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2586 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2587 TCGv_i32 tmp = tcg_temp_new_i32();
2590 gen_aa32_ld8u(tmp, addr, IS_USER(s));
2591 gen_neon_dup_u8(tmp, 0);
2594 gen_aa32_ld16u(tmp, addr, IS_USER(s));
2595 gen_neon_dup_low16(tmp);
2598 gen_aa32_ld32u(tmp, addr, IS_USER(s));
2600 default: /* Avoid compiler warnings. */
2606 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2609 uint32_t cc = extract32(insn, 20, 2);
2612 TCGv_i64 frn, frm, dest;
2613 TCGv_i64 tmp, zero, zf, nf, vf;
2615 zero = tcg_const_i64(0);
2617 frn = tcg_temp_new_i64();
2618 frm = tcg_temp_new_i64();
2619 dest = tcg_temp_new_i64();
2621 zf = tcg_temp_new_i64();
2622 nf = tcg_temp_new_i64();
2623 vf = tcg_temp_new_i64();
2625 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2626 tcg_gen_ext_i32_i64(nf, cpu_NF);
2627 tcg_gen_ext_i32_i64(vf, cpu_VF);
2629 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2630 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2633 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2637 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2640 case 2: /* ge: N == V -> N ^ V == 0 */
2641 tmp = tcg_temp_new_i64();
2642 tcg_gen_xor_i64(tmp, vf, nf);
2643 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2645 tcg_temp_free_i64(tmp);
2647 case 3: /* gt: !Z && N == V */
2648 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2650 tmp = tcg_temp_new_i64();
2651 tcg_gen_xor_i64(tmp, vf, nf);
2652 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2654 tcg_temp_free_i64(tmp);
2657 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2658 tcg_temp_free_i64(frn);
2659 tcg_temp_free_i64(frm);
2660 tcg_temp_free_i64(dest);
2662 tcg_temp_free_i64(zf);
2663 tcg_temp_free_i64(nf);
2664 tcg_temp_free_i64(vf);
2666 tcg_temp_free_i64(zero);
2668 TCGv_i32 frn, frm, dest;
2671 zero = tcg_const_i32(0);
2673 frn = tcg_temp_new_i32();
2674 frm = tcg_temp_new_i32();
2675 dest = tcg_temp_new_i32();
2676 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2677 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2680 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2684 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2687 case 2: /* ge: N == V -> N ^ V == 0 */
2688 tmp = tcg_temp_new_i32();
2689 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2690 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2692 tcg_temp_free_i32(tmp);
2694 case 3: /* gt: !Z && N == V */
2695 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2697 tmp = tcg_temp_new_i32();
2698 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2699 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2701 tcg_temp_free_i32(tmp);
2704 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2705 tcg_temp_free_i32(frn);
2706 tcg_temp_free_i32(frm);
2707 tcg_temp_free_i32(dest);
2709 tcg_temp_free_i32(zero);
2715 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2716 uint32_t rm, uint32_t dp)
2718 uint32_t vmin = extract32(insn, 6, 1);
2719 TCGv_ptr fpst = get_fpstatus_ptr(0);
2722 TCGv_i64 frn, frm, dest;
2724 frn = tcg_temp_new_i64();
2725 frm = tcg_temp_new_i64();
2726 dest = tcg_temp_new_i64();
2728 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2729 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2731 gen_helper_vfp_minnmd(dest, frn, frm, fpst);
2733 gen_helper_vfp_maxnmd(dest, frn, frm, fpst);
2735 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2736 tcg_temp_free_i64(frn);
2737 tcg_temp_free_i64(frm);
2738 tcg_temp_free_i64(dest);
2740 TCGv_i32 frn, frm, dest;
2742 frn = tcg_temp_new_i32();
2743 frm = tcg_temp_new_i32();
2744 dest = tcg_temp_new_i32();
2746 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2747 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2749 gen_helper_vfp_minnms(dest, frn, frm, fpst);
2751 gen_helper_vfp_maxnms(dest, frn, frm, fpst);
2753 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2754 tcg_temp_free_i32(frn);
2755 tcg_temp_free_i32(frm);
2756 tcg_temp_free_i32(dest);
2759 tcg_temp_free_ptr(fpst);
2763 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2765 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2767 if (!arm_feature(env, ARM_FEATURE_V8)) {
2772 VFP_DREG_D(rd, insn);
2773 VFP_DREG_N(rn, insn);
2774 VFP_DREG_M(rm, insn);
2776 rd = VFP_SREG_D(insn);
2777 rn = VFP_SREG_N(insn);
2778 rm = VFP_SREG_M(insn);
2781 if ((insn & 0x0f800e50) == 0x0e000a00) {
2782 return handle_vsel(insn, rd, rn, rm, dp);
2783 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2784 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2789 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2790 (ie. an undefined instruction). */
2791 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2793 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2799 if (!arm_feature(env, ARM_FEATURE_VFP))
2802 if (!s->vfp_enabled) {
2803 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2804 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2806 rn = (insn >> 16) & 0xf;
2807 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2808 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2812 if (extract32(insn, 28, 4) == 0xf) {
2813 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2814 * only used in v8 and above.
2816 return disas_vfp_v8_insn(env, s, insn);
2819 dp = ((insn & 0xf00) == 0xb00);
2820 switch ((insn >> 24) & 0xf) {
2822 if (insn & (1 << 4)) {
2823 /* single register transfer */
2824 rd = (insn >> 12) & 0xf;
2829 VFP_DREG_N(rn, insn);
2832 if (insn & 0x00c00060
2833 && !arm_feature(env, ARM_FEATURE_NEON))
2836 pass = (insn >> 21) & 1;
2837 if (insn & (1 << 22)) {
2839 offset = ((insn >> 5) & 3) * 8;
2840 } else if (insn & (1 << 5)) {
2842 offset = (insn & (1 << 6)) ? 16 : 0;
2847 if (insn & ARM_CP_RW_BIT) {
2849 tmp = neon_load_reg(rn, pass);
2853 tcg_gen_shri_i32(tmp, tmp, offset);
2854 if (insn & (1 << 23))
2860 if (insn & (1 << 23)) {
2862 tcg_gen_shri_i32(tmp, tmp, 16);
2868 tcg_gen_sari_i32(tmp, tmp, 16);
2877 store_reg(s, rd, tmp);
2880 tmp = load_reg(s, rd);
2881 if (insn & (1 << 23)) {
2884 gen_neon_dup_u8(tmp, 0);
2885 } else if (size == 1) {
2886 gen_neon_dup_low16(tmp);
2888 for (n = 0; n <= pass * 2; n++) {
2889 tmp2 = tcg_temp_new_i32();
2890 tcg_gen_mov_i32(tmp2, tmp);
2891 neon_store_reg(rn, n, tmp2);
2893 neon_store_reg(rn, n, tmp);
2898 tmp2 = neon_load_reg(rn, pass);
2899 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2900 tcg_temp_free_i32(tmp2);
2903 tmp2 = neon_load_reg(rn, pass);
2904 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2905 tcg_temp_free_i32(tmp2);
2910 neon_store_reg(rn, pass, tmp);
2914 if ((insn & 0x6f) != 0x00)
2916 rn = VFP_SREG_N(insn);
2917 if (insn & ARM_CP_RW_BIT) {
2919 if (insn & (1 << 21)) {
2920 /* system register */
2925 /* VFP2 allows access to FSID from userspace.
2926 VFP3 restricts all id registers to privileged
2929 && arm_feature(env, ARM_FEATURE_VFP3))
2931 tmp = load_cpu_field(vfp.xregs[rn]);
2936 tmp = load_cpu_field(vfp.xregs[rn]);
2938 case ARM_VFP_FPINST:
2939 case ARM_VFP_FPINST2:
2940 /* Not present in VFP3. */
2942 || arm_feature(env, ARM_FEATURE_VFP3))
2944 tmp = load_cpu_field(vfp.xregs[rn]);
2948 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2949 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2951 tmp = tcg_temp_new_i32();
2952 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2958 || !arm_feature(env, ARM_FEATURE_MVFR))
2960 tmp = load_cpu_field(vfp.xregs[rn]);
2966 gen_mov_F0_vreg(0, rn);
2967 tmp = gen_vfp_mrs();
2970 /* Set the 4 flag bits in the CPSR. */
2972 tcg_temp_free_i32(tmp);
2974 store_reg(s, rd, tmp);
2978 if (insn & (1 << 21)) {
2980 /* system register */
2985 /* Writes are ignored. */
2988 tmp = load_reg(s, rd);
2989 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2990 tcg_temp_free_i32(tmp);
2996 /* TODO: VFP subarchitecture support.
2997 * For now, keep the EN bit only */
2998 tmp = load_reg(s, rd);
2999 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3000 store_cpu_field(tmp, vfp.xregs[rn]);
3003 case ARM_VFP_FPINST:
3004 case ARM_VFP_FPINST2:
3005 tmp = load_reg(s, rd);
3006 store_cpu_field(tmp, vfp.xregs[rn]);
3012 tmp = load_reg(s, rd);
3014 gen_mov_vreg_F0(0, rn);
3019 /* data processing */
3020 /* The opcode is in bits 23, 21, 20 and 6. */
3021 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3025 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3027 /* rn is register number */
3028 VFP_DREG_N(rn, insn);
3031 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3032 /* Integer or single precision destination. */
3033 rd = VFP_SREG_D(insn);
3035 VFP_DREG_D(rd, insn);
3038 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3039 /* VCVT from int is always from S reg regardless of dp bit.
3040 * VCVT with immediate frac_bits has same format as SREG_M
3042 rm = VFP_SREG_M(insn);
3044 VFP_DREG_M(rm, insn);
3047 rn = VFP_SREG_N(insn);
3048 if (op == 15 && rn == 15) {
3049 /* Double precision destination. */
3050 VFP_DREG_D(rd, insn);
3052 rd = VFP_SREG_D(insn);
3054 /* NB that we implicitly rely on the encoding for the frac_bits
3055 * in VCVT of fixed to float being the same as that of an SREG_M
3057 rm = VFP_SREG_M(insn);
3060 veclen = s->vec_len;
3061 if (op == 15 && rn > 3)
3064 /* Shut up compiler warnings. */
3075 /* Figure out what type of vector operation this is. */
3076 if ((rd & bank_mask) == 0) {
3081 delta_d = (s->vec_stride >> 1) + 1;
3083 delta_d = s->vec_stride + 1;
3085 if ((rm & bank_mask) == 0) {
3086 /* mixed scalar/vector */
3095 /* Load the initial operands. */
3100 /* Integer source */
3101 gen_mov_F0_vreg(0, rm);
3106 gen_mov_F0_vreg(dp, rd);
3107 gen_mov_F1_vreg(dp, rm);
3111 /* Compare with zero */
3112 gen_mov_F0_vreg(dp, rd);
3123 /* Source and destination the same. */
3124 gen_mov_F0_vreg(dp, rd);
3130 /* VCVTB, VCVTT: only present with the halfprec extension,
3131 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3133 if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3136 /* Otherwise fall through */
3138 /* One source operand. */
3139 gen_mov_F0_vreg(dp, rm);
3143 /* Two source operands. */
3144 gen_mov_F0_vreg(dp, rn);
3145 gen_mov_F1_vreg(dp, rm);
3149 /* Perform the calculation. */
3151 case 0: /* VMLA: fd + (fn * fm) */
3152 /* Note that order of inputs to the add matters for NaNs */
3154 gen_mov_F0_vreg(dp, rd);
3157 case 1: /* VMLS: fd + -(fn * fm) */
3160 gen_mov_F0_vreg(dp, rd);
3163 case 2: /* VNMLS: -fd + (fn * fm) */
3164 /* Note that it isn't valid to replace (-A + B) with (B - A)
3165 * or similar plausible looking simplifications
3166 * because this will give wrong results for NaNs.
3169 gen_mov_F0_vreg(dp, rd);
3173 case 3: /* VNMLA: -fd + -(fn * fm) */
3176 gen_mov_F0_vreg(dp, rd);
3180 case 4: /* mul: fn * fm */
3183 case 5: /* nmul: -(fn * fm) */
3187 case 6: /* add: fn + fm */
3190 case 7: /* sub: fn - fm */
3193 case 8: /* div: fn / fm */
3196 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3197 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3198 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3199 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3200 /* These are fused multiply-add, and must be done as one
3201 * floating point operation with no rounding between the
3202 * multiplication and addition steps.
3203 * NB that doing the negations here as separate steps is
3204 * correct : an input NaN should come out with its sign bit
3205 * flipped if it is a negated-input.
3207 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3215 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3217 frd = tcg_temp_new_i64();
3218 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3221 gen_helper_vfp_negd(frd, frd);
3223 fpst = get_fpstatus_ptr(0);
3224 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3225 cpu_F1d, frd, fpst);
3226 tcg_temp_free_ptr(fpst);
3227 tcg_temp_free_i64(frd);
3233 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3235 frd = tcg_temp_new_i32();
3236 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3238 gen_helper_vfp_negs(frd, frd);
3240 fpst = get_fpstatus_ptr(0);
3241 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3242 cpu_F1s, frd, fpst);
3243 tcg_temp_free_ptr(fpst);
3244 tcg_temp_free_i32(frd);
3247 case 14: /* fconst */
3248 if (!arm_feature(env, ARM_FEATURE_VFP3))
3251 n = (insn << 12) & 0x80000000;
3252 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3259 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3266 tcg_gen_movi_i32(cpu_F0s, n);
3269 case 15: /* extension space */
3283 case 4: /* vcvtb.f32.f16 */
3284 tmp = gen_vfp_mrs();
3285 tcg_gen_ext16u_i32(tmp, tmp);
3286 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3287 tcg_temp_free_i32(tmp);
3289 case 5: /* vcvtt.f32.f16 */
3290 tmp = gen_vfp_mrs();
3291 tcg_gen_shri_i32(tmp, tmp, 16);
3292 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3293 tcg_temp_free_i32(tmp);
3295 case 6: /* vcvtb.f16.f32 */
3296 tmp = tcg_temp_new_i32();
3297 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3298 gen_mov_F0_vreg(0, rd);
3299 tmp2 = gen_vfp_mrs();
3300 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3301 tcg_gen_or_i32(tmp, tmp, tmp2);
3302 tcg_temp_free_i32(tmp2);
3305 case 7: /* vcvtt.f16.f32 */
3306 tmp = tcg_temp_new_i32();
3307 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3308 tcg_gen_shli_i32(tmp, tmp, 16);
3309 gen_mov_F0_vreg(0, rd);
3310 tmp2 = gen_vfp_mrs();
3311 tcg_gen_ext16u_i32(tmp2, tmp2);
3312 tcg_gen_or_i32(tmp, tmp, tmp2);
3313 tcg_temp_free_i32(tmp2);
3325 case 11: /* cmpez */
3329 case 15: /* single<->double conversion */
3331 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3333 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3335 case 16: /* fuito */
3336 gen_vfp_uito(dp, 0);
3338 case 17: /* fsito */
3339 gen_vfp_sito(dp, 0);
3341 case 20: /* fshto */
3342 if (!arm_feature(env, ARM_FEATURE_VFP3))
3344 gen_vfp_shto(dp, 16 - rm, 0);
3346 case 21: /* fslto */
3347 if (!arm_feature(env, ARM_FEATURE_VFP3))
3349 gen_vfp_slto(dp, 32 - rm, 0);
3351 case 22: /* fuhto */
3352 if (!arm_feature(env, ARM_FEATURE_VFP3))
3354 gen_vfp_uhto(dp, 16 - rm, 0);
3356 case 23: /* fulto */
3357 if (!arm_feature(env, ARM_FEATURE_VFP3))
3359 gen_vfp_ulto(dp, 32 - rm, 0);
3361 case 24: /* ftoui */
3362 gen_vfp_toui(dp, 0);
3364 case 25: /* ftouiz */
3365 gen_vfp_touiz(dp, 0);
3367 case 26: /* ftosi */
3368 gen_vfp_tosi(dp, 0);
3370 case 27: /* ftosiz */
3371 gen_vfp_tosiz(dp, 0);
3373 case 28: /* ftosh */
3374 if (!arm_feature(env, ARM_FEATURE_VFP3))
3376 gen_vfp_tosh(dp, 16 - rm, 0);
3378 case 29: /* ftosl */
3379 if (!arm_feature(env, ARM_FEATURE_VFP3))
3381 gen_vfp_tosl(dp, 32 - rm, 0);
3383 case 30: /* ftouh */
3384 if (!arm_feature(env, ARM_FEATURE_VFP3))
3386 gen_vfp_touh(dp, 16 - rm, 0);
3388 case 31: /* ftoul */
3389 if (!arm_feature(env, ARM_FEATURE_VFP3))
3391 gen_vfp_toul(dp, 32 - rm, 0);
3393 default: /* undefined */
3397 default: /* undefined */
3401 /* Write back the result. */
3402 if (op == 15 && (rn >= 8 && rn <= 11))
3403 ; /* Comparison, do nothing. */
3404 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3405 /* VCVT double to int: always integer result. */
3406 gen_mov_vreg_F0(0, rd);
3407 else if (op == 15 && rn == 15)
3409 gen_mov_vreg_F0(!dp, rd);
3411 gen_mov_vreg_F0(dp, rd);
3413 /* break out of the loop if we have finished */
3417 if (op == 15 && delta_m == 0) {
3418 /* single source one-many */
3420 rd = ((rd + delta_d) & (bank_mask - 1))
3422 gen_mov_vreg_F0(dp, rd);
3426 /* Setup the next operands. */
3428 rd = ((rd + delta_d) & (bank_mask - 1))
3432 /* One source operand. */
3433 rm = ((rm + delta_m) & (bank_mask - 1))
3435 gen_mov_F0_vreg(dp, rm);
3437 /* Two source operands. */
3438 rn = ((rn + delta_d) & (bank_mask - 1))
3440 gen_mov_F0_vreg(dp, rn);
3442 rm = ((rm + delta_m) & (bank_mask - 1))
3444 gen_mov_F1_vreg(dp, rm);
3452 if ((insn & 0x03e00000) == 0x00400000) {
3453 /* two-register transfer */
3454 rn = (insn >> 16) & 0xf;
3455 rd = (insn >> 12) & 0xf;
3457 VFP_DREG_M(rm, insn);
3459 rm = VFP_SREG_M(insn);
3462 if (insn & ARM_CP_RW_BIT) {
3465 gen_mov_F0_vreg(0, rm * 2);
3466 tmp = gen_vfp_mrs();
3467 store_reg(s, rd, tmp);
3468 gen_mov_F0_vreg(0, rm * 2 + 1);
3469 tmp = gen_vfp_mrs();
3470 store_reg(s, rn, tmp);
3472 gen_mov_F0_vreg(0, rm);
3473 tmp = gen_vfp_mrs();
3474 store_reg(s, rd, tmp);
3475 gen_mov_F0_vreg(0, rm + 1);
3476 tmp = gen_vfp_mrs();
3477 store_reg(s, rn, tmp);
3482 tmp = load_reg(s, rd);
3484 gen_mov_vreg_F0(0, rm * 2);
3485 tmp = load_reg(s, rn);
3487 gen_mov_vreg_F0(0, rm * 2 + 1);
3489 tmp = load_reg(s, rd);
3491 gen_mov_vreg_F0(0, rm);
3492 tmp = load_reg(s, rn);
3494 gen_mov_vreg_F0(0, rm + 1);
3499 rn = (insn >> 16) & 0xf;
3501 VFP_DREG_D(rd, insn);
3503 rd = VFP_SREG_D(insn);
3504 if ((insn & 0x01200000) == 0x01000000) {
3505 /* Single load/store */
3506 offset = (insn & 0xff) << 2;
3507 if ((insn & (1 << 23)) == 0)
3509 if (s->thumb && rn == 15) {
3510 /* This is actually UNPREDICTABLE */
3511 addr = tcg_temp_new_i32();
3512 tcg_gen_movi_i32(addr, s->pc & ~2);
3514 addr = load_reg(s, rn);
3516 tcg_gen_addi_i32(addr, addr, offset);
3517 if (insn & (1 << 20)) {
3518 gen_vfp_ld(s, dp, addr);
3519 gen_mov_vreg_F0(dp, rd);
3521 gen_mov_F0_vreg(dp, rd);
3522 gen_vfp_st(s, dp, addr);
3524 tcg_temp_free_i32(addr);
3526 /* load/store multiple */
3527 int w = insn & (1 << 21);
3529 n = (insn >> 1) & 0x7f;
3533 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3534 /* P == U , W == 1 => UNDEF */
3537 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3538 /* UNPREDICTABLE cases for bad immediates: we choose to
3539 * UNDEF to avoid generating huge numbers of TCG ops
3543 if (rn == 15 && w) {
3544 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3548 if (s->thumb && rn == 15) {
3549 /* This is actually UNPREDICTABLE */
3550 addr = tcg_temp_new_i32();
3551 tcg_gen_movi_i32(addr, s->pc & ~2);
3553 addr = load_reg(s, rn);
3555 if (insn & (1 << 24)) /* pre-decrement */
3556 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3562 for (i = 0; i < n; i++) {
3563 if (insn & ARM_CP_RW_BIT) {
3565 gen_vfp_ld(s, dp, addr);
3566 gen_mov_vreg_F0(dp, rd + i);
3569 gen_mov_F0_vreg(dp, rd + i);
3570 gen_vfp_st(s, dp, addr);
3572 tcg_gen_addi_i32(addr, addr, offset);
3576 if (insn & (1 << 24))
3577 offset = -offset * n;
3578 else if (dp && (insn & 1))
3584 tcg_gen_addi_i32(addr, addr, offset);
3585 store_reg(s, rn, addr);
3587 tcg_temp_free_i32(addr);
3593 /* Should never happen. */
3599 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3601 TranslationBlock *tb;
3604 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3606 gen_set_pc_im(s, dest);
3607 tcg_gen_exit_tb((uintptr_t)tb + n);
3609 gen_set_pc_im(s, dest);
3614 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3616 if (unlikely(s->singlestep_enabled)) {
3617 /* An indirect jump so that we still trigger the debug exception. */
3622 gen_goto_tb(s, 0, dest);
3623 s->is_jmp = DISAS_TB_JUMP;
3627 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3630 tcg_gen_sari_i32(t0, t0, 16);
3634 tcg_gen_sari_i32(t1, t1, 16);
3637 tcg_gen_mul_i32(t0, t0, t1);
3640 /* Return the mask of PSR bits set by a MSR instruction. */
3641 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3645 if (flags & (1 << 0))
3647 if (flags & (1 << 1))
3649 if (flags & (1 << 2))
3651 if (flags & (1 << 3))
3654 /* Mask out undefined bits. */
3655 mask &= ~CPSR_RESERVED;
3656 if (!arm_feature(env, ARM_FEATURE_V4T))
3658 if (!arm_feature(env, ARM_FEATURE_V5))
3659 mask &= ~CPSR_Q; /* V5TE in reality*/
3660 if (!arm_feature(env, ARM_FEATURE_V6))
3661 mask &= ~(CPSR_E | CPSR_GE);
3662 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3664 /* Mask out execution state bits. */
3667 /* Mask out privileged bits. */
3673 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3674 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3678 /* ??? This is also undefined in system mode. */
3682 tmp = load_cpu_field(spsr);
3683 tcg_gen_andi_i32(tmp, tmp, ~mask);
3684 tcg_gen_andi_i32(t0, t0, mask);
3685 tcg_gen_or_i32(tmp, tmp, t0);
3686 store_cpu_field(tmp, spsr);
3688 gen_set_cpsr(t0, mask);
3690 tcg_temp_free_i32(t0);
3695 /* Returns nonzero if access to the PSR is not permitted. */
3696 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3699 tmp = tcg_temp_new_i32();
3700 tcg_gen_movi_i32(tmp, val);
3701 return gen_set_psr(s, mask, spsr, tmp);
3704 /* Generate an old-style exception return. Marks pc as dead. */
3705 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3708 store_reg(s, 15, pc);
3709 tmp = load_cpu_field(spsr);
3710 gen_set_cpsr(tmp, 0xffffffff);
3711 tcg_temp_free_i32(tmp);
3712 s->is_jmp = DISAS_UPDATE;
3715 /* Generate a v6 exception return. Marks both values as dead. */
3716 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3718 gen_set_cpsr(cpsr, 0xffffffff);
3719 tcg_temp_free_i32(cpsr);
3720 store_reg(s, 15, pc);
3721 s->is_jmp = DISAS_UPDATE;
3725 gen_set_condexec (DisasContext *s)
3727 if (s->condexec_mask) {
3728 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3729 TCGv_i32 tmp = tcg_temp_new_i32();
3730 tcg_gen_movi_i32(tmp, val);
3731 store_cpu_field(tmp, condexec_bits);
3735 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3737 gen_set_condexec(s);
3738 gen_set_pc_im(s, s->pc - offset);
3739 gen_exception(excp);
3740 s->is_jmp = DISAS_JUMP;
3743 static void gen_nop_hint(DisasContext *s, int val)
3747 gen_set_pc_im(s, s->pc);
3748 s->is_jmp = DISAS_WFI;
3753 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3759 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3761 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3764 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3765 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3766 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3771 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3774 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3775 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3776 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3781 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3782 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3783 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3784 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3785 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3787 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3788 switch ((size << 1) | u) { \
3790 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3793 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3796 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3799 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3802 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3805 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3807 default: return 1; \
3810 #define GEN_NEON_INTEGER_OP(name) do { \
3811 switch ((size << 1) | u) { \
3813 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3816 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3819 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3822 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3825 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3828 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3830 default: return 1; \
3833 static TCGv_i32 neon_load_scratch(int scratch)
3835 TCGv_i32 tmp = tcg_temp_new_i32();
3836 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3840 static void neon_store_scratch(int scratch, TCGv_i32 var)
3842 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3843 tcg_temp_free_i32(var);
3846 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3850 tmp = neon_load_reg(reg & 7, reg >> 4);
3852 gen_neon_dup_high16(tmp);
3854 gen_neon_dup_low16(tmp);
3857 tmp = neon_load_reg(reg & 15, reg >> 4);
3862 static int gen_neon_unzip(int rd, int rm, int size, int q)
3865 if (!q && size == 2) {
3868 tmp = tcg_const_i32(rd);
3869 tmp2 = tcg_const_i32(rm);
3873 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3876 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3879 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3887 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3890 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3896 tcg_temp_free_i32(tmp);
3897 tcg_temp_free_i32(tmp2);
3901 static int gen_neon_zip(int rd, int rm, int size, int q)
3904 if (!q && size == 2) {
3907 tmp = tcg_const_i32(rd);
3908 tmp2 = tcg_const_i32(rm);
3912 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3915 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3918 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3926 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3929 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3935 tcg_temp_free_i32(tmp);
3936 tcg_temp_free_i32(tmp2);
3940 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3944 rd = tcg_temp_new_i32();
3945 tmp = tcg_temp_new_i32();
3947 tcg_gen_shli_i32(rd, t0, 8);
3948 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3949 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3950 tcg_gen_or_i32(rd, rd, tmp);
3952 tcg_gen_shri_i32(t1, t1, 8);
3953 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3954 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3955 tcg_gen_or_i32(t1, t1, tmp);
3956 tcg_gen_mov_i32(t0, rd);
3958 tcg_temp_free_i32(tmp);
3959 tcg_temp_free_i32(rd);
3962 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3966 rd = tcg_temp_new_i32();
3967 tmp = tcg_temp_new_i32();
3969 tcg_gen_shli_i32(rd, t0, 16);
3970 tcg_gen_andi_i32(tmp, t1, 0xffff);
3971 tcg_gen_or_i32(rd, rd, tmp);
3972 tcg_gen_shri_i32(t1, t1, 16);
3973 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3974 tcg_gen_or_i32(t1, t1, tmp);
3975 tcg_gen_mov_i32(t0, rd);
3977 tcg_temp_free_i32(tmp);
3978 tcg_temp_free_i32(rd);
3986 } neon_ls_element_type[11] = {
4000 /* Translate a NEON load/store element instruction. Return nonzero if the
4001 instruction is invalid. */
4002 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4021 if (!s->vfp_enabled)
4023 VFP_DREG_D(rd, insn);
4024 rn = (insn >> 16) & 0xf;
4026 load = (insn & (1 << 21)) != 0;
4027 if ((insn & (1 << 23)) == 0) {
4028 /* Load store all elements. */
4029 op = (insn >> 8) & 0xf;
4030 size = (insn >> 6) & 3;
4033 /* Catch UNDEF cases for bad values of align field */
4036 if (((insn >> 5) & 1) == 1) {
4041 if (((insn >> 4) & 3) == 3) {
4048 nregs = neon_ls_element_type[op].nregs;
4049 interleave = neon_ls_element_type[op].interleave;
4050 spacing = neon_ls_element_type[op].spacing;
4051 if (size == 3 && (interleave | spacing) != 1)
4053 addr = tcg_temp_new_i32();
4054 load_reg_var(s, addr, rn);
4055 stride = (1 << size) * interleave;
4056 for (reg = 0; reg < nregs; reg++) {
4057 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4058 load_reg_var(s, addr, rn);
4059 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4060 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4061 load_reg_var(s, addr, rn);
4062 tcg_gen_addi_i32(addr, addr, 1 << size);
4065 tmp64 = tcg_temp_new_i64();
4067 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4068 neon_store_reg64(tmp64, rd);
4070 neon_load_reg64(tmp64, rd);
4071 gen_aa32_st64(tmp64, addr, IS_USER(s));
4073 tcg_temp_free_i64(tmp64);
4074 tcg_gen_addi_i32(addr, addr, stride);
4076 for (pass = 0; pass < 2; pass++) {
4079 tmp = tcg_temp_new_i32();
4080 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4081 neon_store_reg(rd, pass, tmp);
4083 tmp = neon_load_reg(rd, pass);
4084 gen_aa32_st32(tmp, addr, IS_USER(s));
4085 tcg_temp_free_i32(tmp);
4087 tcg_gen_addi_i32(addr, addr, stride);
4088 } else if (size == 1) {
4090 tmp = tcg_temp_new_i32();
4091 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4092 tcg_gen_addi_i32(addr, addr, stride);
4093 tmp2 = tcg_temp_new_i32();
4094 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4095 tcg_gen_addi_i32(addr, addr, stride);
4096 tcg_gen_shli_i32(tmp2, tmp2, 16);
4097 tcg_gen_or_i32(tmp, tmp, tmp2);
4098 tcg_temp_free_i32(tmp2);
4099 neon_store_reg(rd, pass, tmp);
4101 tmp = neon_load_reg(rd, pass);
4102 tmp2 = tcg_temp_new_i32();
4103 tcg_gen_shri_i32(tmp2, tmp, 16);
4104 gen_aa32_st16(tmp, addr, IS_USER(s));
4105 tcg_temp_free_i32(tmp);
4106 tcg_gen_addi_i32(addr, addr, stride);
4107 gen_aa32_st16(tmp2, addr, IS_USER(s));
4108 tcg_temp_free_i32(tmp2);
4109 tcg_gen_addi_i32(addr, addr, stride);
4111 } else /* size == 0 */ {
4113 TCGV_UNUSED_I32(tmp2);
4114 for (n = 0; n < 4; n++) {
4115 tmp = tcg_temp_new_i32();
4116 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4117 tcg_gen_addi_i32(addr, addr, stride);
4121 tcg_gen_shli_i32(tmp, tmp, n * 8);
4122 tcg_gen_or_i32(tmp2, tmp2, tmp);
4123 tcg_temp_free_i32(tmp);
4126 neon_store_reg(rd, pass, tmp2);
4128 tmp2 = neon_load_reg(rd, pass);
4129 for (n = 0; n < 4; n++) {
4130 tmp = tcg_temp_new_i32();
4132 tcg_gen_mov_i32(tmp, tmp2);
4134 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4136 gen_aa32_st8(tmp, addr, IS_USER(s));
4137 tcg_temp_free_i32(tmp);
4138 tcg_gen_addi_i32(addr, addr, stride);
4140 tcg_temp_free_i32(tmp2);
4147 tcg_temp_free_i32(addr);
4150 size = (insn >> 10) & 3;
4152 /* Load single element to all lanes. */
4153 int a = (insn >> 4) & 1;
4157 size = (insn >> 6) & 3;
4158 nregs = ((insn >> 8) & 3) + 1;
4161 if (nregs != 4 || a == 0) {
4164 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4167 if (nregs == 1 && a == 1 && size == 0) {
4170 if (nregs == 3 && a == 1) {
4173 addr = tcg_temp_new_i32();
4174 load_reg_var(s, addr, rn);
4176 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4177 tmp = gen_load_and_replicate(s, addr, size);
4178 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4179 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4180 if (insn & (1 << 5)) {
4181 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4182 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4184 tcg_temp_free_i32(tmp);
4186 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4187 stride = (insn & (1 << 5)) ? 2 : 1;
4188 for (reg = 0; reg < nregs; reg++) {
4189 tmp = gen_load_and_replicate(s, addr, size);
4190 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4191 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4192 tcg_temp_free_i32(tmp);
4193 tcg_gen_addi_i32(addr, addr, 1 << size);
4197 tcg_temp_free_i32(addr);
4198 stride = (1 << size) * nregs;
4200 /* Single element. */
4201 int idx = (insn >> 4) & 0xf;
4202 pass = (insn >> 7) & 1;
4205 shift = ((insn >> 5) & 3) * 8;
4209 shift = ((insn >> 6) & 1) * 16;
4210 stride = (insn & (1 << 5)) ? 2 : 1;
4214 stride = (insn & (1 << 6)) ? 2 : 1;
4219 nregs = ((insn >> 8) & 3) + 1;
4220 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4223 if (((idx & (1 << size)) != 0) ||
4224 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4229 if ((idx & 1) != 0) {
4234 if (size == 2 && (idx & 2) != 0) {
4239 if ((size == 2) && ((idx & 3) == 3)) {
4246 if ((rd + stride * (nregs - 1)) > 31) {
4247 /* Attempts to write off the end of the register file
4248 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4249 * the neon_load_reg() would write off the end of the array.
4253 addr = tcg_temp_new_i32();
4254 load_reg_var(s, addr, rn);
4255 for (reg = 0; reg < nregs; reg++) {
4257 tmp = tcg_temp_new_i32();
4260 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4263 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4266 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4268 default: /* Avoid compiler warnings. */
4272 tmp2 = neon_load_reg(rd, pass);
4273 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4274 shift, size ? 16 : 8);
4275 tcg_temp_free_i32(tmp2);
4277 neon_store_reg(rd, pass, tmp);
4278 } else { /* Store */
4279 tmp = neon_load_reg(rd, pass);
4281 tcg_gen_shri_i32(tmp, tmp, shift);
4284 gen_aa32_st8(tmp, addr, IS_USER(s));
4287 gen_aa32_st16(tmp, addr, IS_USER(s));
4290 gen_aa32_st32(tmp, addr, IS_USER(s));
4293 tcg_temp_free_i32(tmp);
4296 tcg_gen_addi_i32(addr, addr, 1 << size);
4298 tcg_temp_free_i32(addr);
4299 stride = nregs * (1 << size);
4305 base = load_reg(s, rn);
4307 tcg_gen_addi_i32(base, base, stride);
4310 index = load_reg(s, rm);
4311 tcg_gen_add_i32(base, base, index);
4312 tcg_temp_free_i32(index);
4314 store_reg(s, rn, base);
4319 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4320 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4322 tcg_gen_and_i32(t, t, c);
4323 tcg_gen_andc_i32(f, f, c);
4324 tcg_gen_or_i32(dest, t, f);
4327 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4330 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4331 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4332 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4337 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4340 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4341 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4342 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4347 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4350 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4351 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4352 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4357 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4360 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4361 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4362 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4367 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4373 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4374 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4379 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4380 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4387 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4388 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4393 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4394 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4401 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4405 case 0: gen_helper_neon_widen_u8(dest, src); break;
4406 case 1: gen_helper_neon_widen_u16(dest, src); break;
4407 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4412 case 0: gen_helper_neon_widen_s8(dest, src); break;
4413 case 1: gen_helper_neon_widen_s16(dest, src); break;
4414 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4418 tcg_temp_free_i32(src);
4421 static inline void gen_neon_addl(int size)
4424 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4425 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4426 case 2: tcg_gen_add_i64(CPU_V001); break;
4431 static inline void gen_neon_subl(int size)
4434 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4435 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4436 case 2: tcg_gen_sub_i64(CPU_V001); break;
4441 static inline void gen_neon_negl(TCGv_i64 var, int size)
4444 case 0: gen_helper_neon_negl_u16(var, var); break;
4445 case 1: gen_helper_neon_negl_u32(var, var); break;
4447 tcg_gen_neg_i64(var, var);
4453 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4456 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4457 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4462 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4467 switch ((size << 1) | u) {
4468 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4469 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4470 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4471 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4473 tmp = gen_muls_i64_i32(a, b);
4474 tcg_gen_mov_i64(dest, tmp);
4475 tcg_temp_free_i64(tmp);
4478 tmp = gen_mulu_i64_i32(a, b);
4479 tcg_gen_mov_i64(dest, tmp);
4480 tcg_temp_free_i64(tmp);
4485 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4486 Don't forget to clean them now. */
4488 tcg_temp_free_i32(a);
4489 tcg_temp_free_i32(b);
4493 static void gen_neon_narrow_op(int op, int u, int size,
4494 TCGv_i32 dest, TCGv_i64 src)
4498 gen_neon_unarrow_sats(size, dest, src);
4500 gen_neon_narrow(size, dest, src);
4504 gen_neon_narrow_satu(size, dest, src);
4506 gen_neon_narrow_sats(size, dest, src);
4511 /* Symbolic constants for op fields for Neon 3-register same-length.
4512 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4515 #define NEON_3R_VHADD 0
4516 #define NEON_3R_VQADD 1
4517 #define NEON_3R_VRHADD 2
4518 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4519 #define NEON_3R_VHSUB 4
4520 #define NEON_3R_VQSUB 5
4521 #define NEON_3R_VCGT 6
4522 #define NEON_3R_VCGE 7
4523 #define NEON_3R_VSHL 8
4524 #define NEON_3R_VQSHL 9
4525 #define NEON_3R_VRSHL 10
4526 #define NEON_3R_VQRSHL 11
4527 #define NEON_3R_VMAX 12
4528 #define NEON_3R_VMIN 13
4529 #define NEON_3R_VABD 14
4530 #define NEON_3R_VABA 15
4531 #define NEON_3R_VADD_VSUB 16
4532 #define NEON_3R_VTST_VCEQ 17
4533 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4534 #define NEON_3R_VMUL 19
4535 #define NEON_3R_VPMAX 20
4536 #define NEON_3R_VPMIN 21
4537 #define NEON_3R_VQDMULH_VQRDMULH 22
4538 #define NEON_3R_VPADD 23
4539 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4540 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4541 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4542 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4543 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4544 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4545 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4547 static const uint8_t neon_3r_sizes[] = {
4548 [NEON_3R_VHADD] = 0x7,
4549 [NEON_3R_VQADD] = 0xf,
4550 [NEON_3R_VRHADD] = 0x7,
4551 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4552 [NEON_3R_VHSUB] = 0x7,
4553 [NEON_3R_VQSUB] = 0xf,
4554 [NEON_3R_VCGT] = 0x7,
4555 [NEON_3R_VCGE] = 0x7,
4556 [NEON_3R_VSHL] = 0xf,
4557 [NEON_3R_VQSHL] = 0xf,
4558 [NEON_3R_VRSHL] = 0xf,
4559 [NEON_3R_VQRSHL] = 0xf,
4560 [NEON_3R_VMAX] = 0x7,
4561 [NEON_3R_VMIN] = 0x7,
4562 [NEON_3R_VABD] = 0x7,
4563 [NEON_3R_VABA] = 0x7,
4564 [NEON_3R_VADD_VSUB] = 0xf,
4565 [NEON_3R_VTST_VCEQ] = 0x7,
4566 [NEON_3R_VML] = 0x7,
4567 [NEON_3R_VMUL] = 0x7,
4568 [NEON_3R_VPMAX] = 0x7,
4569 [NEON_3R_VPMIN] = 0x7,
4570 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4571 [NEON_3R_VPADD] = 0x7,
4572 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4573 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4574 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4575 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4576 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4577 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4578 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4581 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4582 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4585 #define NEON_2RM_VREV64 0
4586 #define NEON_2RM_VREV32 1
4587 #define NEON_2RM_VREV16 2
4588 #define NEON_2RM_VPADDL 4
4589 #define NEON_2RM_VPADDL_U 5
4590 #define NEON_2RM_AESE 6 /* Includes AESD */
4591 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4592 #define NEON_2RM_VCLS 8
4593 #define NEON_2RM_VCLZ 9
4594 #define NEON_2RM_VCNT 10
4595 #define NEON_2RM_VMVN 11
4596 #define NEON_2RM_VPADAL 12
4597 #define NEON_2RM_VPADAL_U 13
4598 #define NEON_2RM_VQABS 14
4599 #define NEON_2RM_VQNEG 15
4600 #define NEON_2RM_VCGT0 16
4601 #define NEON_2RM_VCGE0 17
4602 #define NEON_2RM_VCEQ0 18
4603 #define NEON_2RM_VCLE0 19
4604 #define NEON_2RM_VCLT0 20
4605 #define NEON_2RM_VABS 22
4606 #define NEON_2RM_VNEG 23
4607 #define NEON_2RM_VCGT0_F 24
4608 #define NEON_2RM_VCGE0_F 25
4609 #define NEON_2RM_VCEQ0_F 26
4610 #define NEON_2RM_VCLE0_F 27
4611 #define NEON_2RM_VCLT0_F 28
4612 #define NEON_2RM_VABS_F 30
4613 #define NEON_2RM_VNEG_F 31
4614 #define NEON_2RM_VSWP 32
4615 #define NEON_2RM_VTRN 33
4616 #define NEON_2RM_VUZP 34
4617 #define NEON_2RM_VZIP 35
4618 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4619 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4620 #define NEON_2RM_VSHLL 38
4621 #define NEON_2RM_VCVT_F16_F32 44
4622 #define NEON_2RM_VCVT_F32_F16 46
4623 #define NEON_2RM_VRECPE 56
4624 #define NEON_2RM_VRSQRTE 57
4625 #define NEON_2RM_VRECPE_F 58
4626 #define NEON_2RM_VRSQRTE_F 59
4627 #define NEON_2RM_VCVT_FS 60
4628 #define NEON_2RM_VCVT_FU 61
4629 #define NEON_2RM_VCVT_SF 62
4630 #define NEON_2RM_VCVT_UF 63
4632 static int neon_2rm_is_float_op(int op)
4634 /* Return true if this neon 2reg-misc op is float-to-float */
4635 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4636 op >= NEON_2RM_VRECPE_F);
4639 /* Each entry in this array has bit n set if the insn allows
4640 * size value n (otherwise it will UNDEF). Since unallocated
4641 * op values will have no bits set they always UNDEF.
4643 static const uint8_t neon_2rm_sizes[] = {
4644 [NEON_2RM_VREV64] = 0x7,
4645 [NEON_2RM_VREV32] = 0x3,
4646 [NEON_2RM_VREV16] = 0x1,
4647 [NEON_2RM_VPADDL] = 0x7,
4648 [NEON_2RM_VPADDL_U] = 0x7,
4649 [NEON_2RM_AESE] = 0x1,
4650 [NEON_2RM_AESMC] = 0x1,
4651 [NEON_2RM_VCLS] = 0x7,
4652 [NEON_2RM_VCLZ] = 0x7,
4653 [NEON_2RM_VCNT] = 0x1,
4654 [NEON_2RM_VMVN] = 0x1,
4655 [NEON_2RM_VPADAL] = 0x7,
4656 [NEON_2RM_VPADAL_U] = 0x7,
4657 [NEON_2RM_VQABS] = 0x7,
4658 [NEON_2RM_VQNEG] = 0x7,
4659 [NEON_2RM_VCGT0] = 0x7,
4660 [NEON_2RM_VCGE0] = 0x7,
4661 [NEON_2RM_VCEQ0] = 0x7,
4662 [NEON_2RM_VCLE0] = 0x7,
4663 [NEON_2RM_VCLT0] = 0x7,
4664 [NEON_2RM_VABS] = 0x7,
4665 [NEON_2RM_VNEG] = 0x7,
4666 [NEON_2RM_VCGT0_F] = 0x4,
4667 [NEON_2RM_VCGE0_F] = 0x4,
4668 [NEON_2RM_VCEQ0_F] = 0x4,
4669 [NEON_2RM_VCLE0_F] = 0x4,
4670 [NEON_2RM_VCLT0_F] = 0x4,
4671 [NEON_2RM_VABS_F] = 0x4,
4672 [NEON_2RM_VNEG_F] = 0x4,
4673 [NEON_2RM_VSWP] = 0x1,
4674 [NEON_2RM_VTRN] = 0x7,
4675 [NEON_2RM_VUZP] = 0x7,
4676 [NEON_2RM_VZIP] = 0x7,
4677 [NEON_2RM_VMOVN] = 0x7,
4678 [NEON_2RM_VQMOVN] = 0x7,
4679 [NEON_2RM_VSHLL] = 0x7,
4680 [NEON_2RM_VCVT_F16_F32] = 0x2,
4681 [NEON_2RM_VCVT_F32_F16] = 0x2,
4682 [NEON_2RM_VRECPE] = 0x4,
4683 [NEON_2RM_VRSQRTE] = 0x4,
4684 [NEON_2RM_VRECPE_F] = 0x4,
4685 [NEON_2RM_VRSQRTE_F] = 0x4,
4686 [NEON_2RM_VCVT_FS] = 0x4,
4687 [NEON_2RM_VCVT_FU] = 0x4,
4688 [NEON_2RM_VCVT_SF] = 0x4,
4689 [NEON_2RM_VCVT_UF] = 0x4,
4692 /* Translate a NEON data processing instruction. Return nonzero if the
4693 instruction is invalid.
4694 We process data in a mixture of 32-bit and 64-bit chunks.
4695 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4697 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4709 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4712 if (!s->vfp_enabled)
4714 q = (insn & (1 << 6)) != 0;
4715 u = (insn >> 24) & 1;
4716 VFP_DREG_D(rd, insn);
4717 VFP_DREG_N(rn, insn);
4718 VFP_DREG_M(rm, insn);
4719 size = (insn >> 20) & 3;
4720 if ((insn & (1 << 23)) == 0) {
4721 /* Three register same length. */
4722 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4723 /* Catch invalid op and bad size combinations: UNDEF */
4724 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4727 /* All insns of this form UNDEF for either this condition or the
4728 * superset of cases "Q==1"; we catch the latter later.
4730 if (q && ((rd | rn | rm) & 1)) {
4733 if (size == 3 && op != NEON_3R_LOGIC) {
4734 /* 64-bit element instructions. */
4735 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4736 neon_load_reg64(cpu_V0, rn + pass);
4737 neon_load_reg64(cpu_V1, rm + pass);
4741 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4744 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4750 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4753 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4759 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4761 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4766 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4769 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4775 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4777 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4780 case NEON_3R_VQRSHL:
4782 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4785 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4789 case NEON_3R_VADD_VSUB:
4791 tcg_gen_sub_i64(CPU_V001);
4793 tcg_gen_add_i64(CPU_V001);
4799 neon_store_reg64(cpu_V0, rd + pass);
4808 case NEON_3R_VQRSHL:
4811 /* Shift instruction operands are reversed. */
4826 case NEON_3R_FLOAT_ARITH:
4827 pairwise = (u && size < 2); /* if VPADD (float) */
4829 case NEON_3R_FLOAT_MINMAX:
4830 pairwise = u; /* if VPMIN/VPMAX (float) */
4832 case NEON_3R_FLOAT_CMP:
4834 /* no encoding for U=0 C=1x */
4838 case NEON_3R_FLOAT_ACMP:
4843 case NEON_3R_FLOAT_MISC:
4844 /* VMAXNM/VMINNM in ARMv8 */
4845 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4850 if (u && (size != 0)) {
4851 /* UNDEF on invalid size for polynomial subcase */
4856 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4864 if (pairwise && q) {
4865 /* All the pairwise insns UNDEF if Q is set */
4869 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4874 tmp = neon_load_reg(rn, 0);
4875 tmp2 = neon_load_reg(rn, 1);
4877 tmp = neon_load_reg(rm, 0);
4878 tmp2 = neon_load_reg(rm, 1);
4882 tmp = neon_load_reg(rn, pass);
4883 tmp2 = neon_load_reg(rm, pass);
4887 GEN_NEON_INTEGER_OP(hadd);
4890 GEN_NEON_INTEGER_OP_ENV(qadd);
4892 case NEON_3R_VRHADD:
4893 GEN_NEON_INTEGER_OP(rhadd);
4895 case NEON_3R_LOGIC: /* Logic ops. */
4896 switch ((u << 2) | size) {
4898 tcg_gen_and_i32(tmp, tmp, tmp2);
4901 tcg_gen_andc_i32(tmp, tmp, tmp2);
4904 tcg_gen_or_i32(tmp, tmp, tmp2);
4907 tcg_gen_orc_i32(tmp, tmp, tmp2);
4910 tcg_gen_xor_i32(tmp, tmp, tmp2);
4913 tmp3 = neon_load_reg(rd, pass);
4914 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4915 tcg_temp_free_i32(tmp3);
4918 tmp3 = neon_load_reg(rd, pass);
4919 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4920 tcg_temp_free_i32(tmp3);
4923 tmp3 = neon_load_reg(rd, pass);
4924 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4925 tcg_temp_free_i32(tmp3);
4930 GEN_NEON_INTEGER_OP(hsub);
4933 GEN_NEON_INTEGER_OP_ENV(qsub);
4936 GEN_NEON_INTEGER_OP(cgt);
4939 GEN_NEON_INTEGER_OP(cge);
4942 GEN_NEON_INTEGER_OP(shl);
4945 GEN_NEON_INTEGER_OP_ENV(qshl);
4948 GEN_NEON_INTEGER_OP(rshl);
4950 case NEON_3R_VQRSHL:
4951 GEN_NEON_INTEGER_OP_ENV(qrshl);
4954 GEN_NEON_INTEGER_OP(max);
4957 GEN_NEON_INTEGER_OP(min);
4960 GEN_NEON_INTEGER_OP(abd);
4963 GEN_NEON_INTEGER_OP(abd);
4964 tcg_temp_free_i32(tmp2);
4965 tmp2 = neon_load_reg(rd, pass);
4966 gen_neon_add(size, tmp, tmp2);
4968 case NEON_3R_VADD_VSUB:
4969 if (!u) { /* VADD */
4970 gen_neon_add(size, tmp, tmp2);
4973 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4974 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4975 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4980 case NEON_3R_VTST_VCEQ:
4981 if (!u) { /* VTST */
4983 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4984 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4985 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4990 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4991 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4992 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4997 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4999 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5000 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5001 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5004 tcg_temp_free_i32(tmp2);
5005 tmp2 = neon_load_reg(rd, pass);
5007 gen_neon_rsb(size, tmp, tmp2);
5009 gen_neon_add(size, tmp, tmp2);
5013 if (u) { /* polynomial */
5014 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5015 } else { /* Integer */
5017 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5018 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5019 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5025 GEN_NEON_INTEGER_OP(pmax);
5028 GEN_NEON_INTEGER_OP(pmin);
5030 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5031 if (!u) { /* VQDMULH */
5034 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5037 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5041 } else { /* VQRDMULH */
5044 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5047 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5055 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5056 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5057 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5061 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5063 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5064 switch ((u << 2) | size) {
5067 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5070 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5073 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5078 tcg_temp_free_ptr(fpstatus);
5081 case NEON_3R_FLOAT_MULTIPLY:
5083 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5084 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5086 tcg_temp_free_i32(tmp2);
5087 tmp2 = neon_load_reg(rd, pass);
5089 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5091 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5094 tcg_temp_free_ptr(fpstatus);
5097 case NEON_3R_FLOAT_CMP:
5099 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5101 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5104 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5106 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5109 tcg_temp_free_ptr(fpstatus);
5112 case NEON_3R_FLOAT_ACMP:
5114 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5116 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5118 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5120 tcg_temp_free_ptr(fpstatus);
5123 case NEON_3R_FLOAT_MINMAX:
5125 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5127 gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
5129 gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
5131 tcg_temp_free_ptr(fpstatus);
5134 case NEON_3R_FLOAT_MISC:
5137 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5139 gen_helper_vfp_maxnms(tmp, tmp, tmp2, fpstatus);
5141 gen_helper_vfp_minnms(tmp, tmp, tmp2, fpstatus);
5143 tcg_temp_free_ptr(fpstatus);
5146 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5148 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5154 /* VFMA, VFMS: fused multiply-add */
5155 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5156 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5159 gen_helper_vfp_negs(tmp, tmp);
5161 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5162 tcg_temp_free_i32(tmp3);
5163 tcg_temp_free_ptr(fpstatus);
5169 tcg_temp_free_i32(tmp2);
5171 /* Save the result. For elementwise operations we can put it
5172 straight into the destination register. For pairwise operations
5173 we have to be careful to avoid clobbering the source operands. */
5174 if (pairwise && rd == rm) {
5175 neon_store_scratch(pass, tmp);
5177 neon_store_reg(rd, pass, tmp);
5181 if (pairwise && rd == rm) {
5182 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5183 tmp = neon_load_scratch(pass);
5184 neon_store_reg(rd, pass, tmp);
5187 /* End of 3 register same size operations. */
5188 } else if (insn & (1 << 4)) {
5189 if ((insn & 0x00380080) != 0) {
5190 /* Two registers and shift. */
5191 op = (insn >> 8) & 0xf;
5192 if (insn & (1 << 7)) {
5200 while ((insn & (1 << (size + 19))) == 0)
5203 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5204 /* To avoid excessive duplication of ops we implement shift
5205 by immediate using the variable shift operations. */
5207 /* Shift by immediate:
5208 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5209 if (q && ((rd | rm) & 1)) {
5212 if (!u && (op == 4 || op == 6)) {
5215 /* Right shifts are encoded as N - shift, where N is the
5216 element size in bits. */
5218 shift = shift - (1 << (size + 3));
5226 imm = (uint8_t) shift;
5231 imm = (uint16_t) shift;
5242 for (pass = 0; pass < count; pass++) {
5244 neon_load_reg64(cpu_V0, rm + pass);
5245 tcg_gen_movi_i64(cpu_V1, imm);
5250 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5252 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5257 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5259 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5262 case 5: /* VSHL, VSLI */
5263 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5265 case 6: /* VQSHLU */
5266 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5271 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5274 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5279 if (op == 1 || op == 3) {
5281 neon_load_reg64(cpu_V1, rd + pass);
5282 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5283 } else if (op == 4 || (op == 5 && u)) {
5285 neon_load_reg64(cpu_V1, rd + pass);
5287 if (shift < -63 || shift > 63) {
5291 mask = 0xffffffffffffffffull >> -shift;
5293 mask = 0xffffffffffffffffull << shift;
5296 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5297 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5299 neon_store_reg64(cpu_V0, rd + pass);
5300 } else { /* size < 3 */
5301 /* Operands in T0 and T1. */
5302 tmp = neon_load_reg(rm, pass);
5303 tmp2 = tcg_temp_new_i32();
5304 tcg_gen_movi_i32(tmp2, imm);
5308 GEN_NEON_INTEGER_OP(shl);
5312 GEN_NEON_INTEGER_OP(rshl);
5315 case 5: /* VSHL, VSLI */
5317 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5318 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5319 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5323 case 6: /* VQSHLU */
5326 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5330 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5334 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5342 GEN_NEON_INTEGER_OP_ENV(qshl);
5345 tcg_temp_free_i32(tmp2);
5347 if (op == 1 || op == 3) {
5349 tmp2 = neon_load_reg(rd, pass);
5350 gen_neon_add(size, tmp, tmp2);
5351 tcg_temp_free_i32(tmp2);
5352 } else if (op == 4 || (op == 5 && u)) {
5357 mask = 0xff >> -shift;
5359 mask = (uint8_t)(0xff << shift);
5365 mask = 0xffff >> -shift;
5367 mask = (uint16_t)(0xffff << shift);
5371 if (shift < -31 || shift > 31) {
5375 mask = 0xffffffffu >> -shift;
5377 mask = 0xffffffffu << shift;
5383 tmp2 = neon_load_reg(rd, pass);
5384 tcg_gen_andi_i32(tmp, tmp, mask);
5385 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5386 tcg_gen_or_i32(tmp, tmp, tmp2);
5387 tcg_temp_free_i32(tmp2);
5389 neon_store_reg(rd, pass, tmp);
5392 } else if (op < 10) {
5393 /* Shift by immediate and narrow:
5394 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5395 int input_unsigned = (op == 8) ? !u : u;
5399 shift = shift - (1 << (size + 3));
5402 tmp64 = tcg_const_i64(shift);
5403 neon_load_reg64(cpu_V0, rm);
5404 neon_load_reg64(cpu_V1, rm + 1);
5405 for (pass = 0; pass < 2; pass++) {
5413 if (input_unsigned) {
5414 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5416 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5419 if (input_unsigned) {
5420 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5422 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5425 tmp = tcg_temp_new_i32();
5426 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5427 neon_store_reg(rd, pass, tmp);
5429 tcg_temp_free_i64(tmp64);
5432 imm = (uint16_t)shift;
5436 imm = (uint32_t)shift;
5438 tmp2 = tcg_const_i32(imm);
5439 tmp4 = neon_load_reg(rm + 1, 0);
5440 tmp5 = neon_load_reg(rm + 1, 1);
5441 for (pass = 0; pass < 2; pass++) {
5443 tmp = neon_load_reg(rm, 0);
5447 gen_neon_shift_narrow(size, tmp, tmp2, q,
5450 tmp3 = neon_load_reg(rm, 1);
5454 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5456 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5457 tcg_temp_free_i32(tmp);
5458 tcg_temp_free_i32(tmp3);
5459 tmp = tcg_temp_new_i32();
5460 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5461 neon_store_reg(rd, pass, tmp);
5463 tcg_temp_free_i32(tmp2);
5465 } else if (op == 10) {
5467 if (q || (rd & 1)) {
5470 tmp = neon_load_reg(rm, 0);
5471 tmp2 = neon_load_reg(rm, 1);
5472 for (pass = 0; pass < 2; pass++) {
5476 gen_neon_widen(cpu_V0, tmp, size, u);
5479 /* The shift is less than the width of the source
5480 type, so we can just shift the whole register. */
5481 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5482 /* Widen the result of shift: we need to clear
5483 * the potential overflow bits resulting from
5484 * left bits of the narrow input appearing as
5485 * right bits of left the neighbour narrow
5487 if (size < 2 || !u) {
5490 imm = (0xffu >> (8 - shift));
5492 } else if (size == 1) {
5493 imm = 0xffff >> (16 - shift);
5496 imm = 0xffffffff >> (32 - shift);
5499 imm64 = imm | (((uint64_t)imm) << 32);
5503 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5506 neon_store_reg64(cpu_V0, rd + pass);
5508 } else if (op >= 14) {
5509 /* VCVT fixed-point. */
5510 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5513 /* We have already masked out the must-be-1 top bit of imm6,
5514 * hence this 32-shift where the ARM ARM has 64-imm6.
5517 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5518 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5521 gen_vfp_ulto(0, shift, 1);
5523 gen_vfp_slto(0, shift, 1);
5526 gen_vfp_toul(0, shift, 1);
5528 gen_vfp_tosl(0, shift, 1);
5530 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5535 } else { /* (insn & 0x00380080) == 0 */
5537 if (q && (rd & 1)) {
5541 op = (insn >> 8) & 0xf;
5542 /* One register and immediate. */
5543 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5544 invert = (insn & (1 << 5)) != 0;
5545 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5546 * We choose to not special-case this and will behave as if a
5547 * valid constant encoding of 0 had been given.
5566 imm = (imm << 8) | (imm << 24);
5569 imm = (imm << 8) | 0xff;
5572 imm = (imm << 16) | 0xffff;
5575 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5583 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5584 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5590 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5591 if (op & 1 && op < 12) {
5592 tmp = neon_load_reg(rd, pass);
5594 /* The immediate value has already been inverted, so
5596 tcg_gen_andi_i32(tmp, tmp, imm);
5598 tcg_gen_ori_i32(tmp, tmp, imm);
5602 tmp = tcg_temp_new_i32();
5603 if (op == 14 && invert) {
5607 for (n = 0; n < 4; n++) {
5608 if (imm & (1 << (n + (pass & 1) * 4)))
5609 val |= 0xff << (n * 8);
5611 tcg_gen_movi_i32(tmp, val);
5613 tcg_gen_movi_i32(tmp, imm);
5616 neon_store_reg(rd, pass, tmp);
5619 } else { /* (insn & 0x00800010 == 0x00800000) */
5621 op = (insn >> 8) & 0xf;
5622 if ((insn & (1 << 6)) == 0) {
5623 /* Three registers of different lengths. */
5627 /* undefreq: bit 0 : UNDEF if size != 0
5628 * bit 1 : UNDEF if size == 0
5629 * bit 2 : UNDEF if U == 1
5630 * Note that [1:0] set implies 'always UNDEF'
5633 /* prewiden, src1_wide, src2_wide, undefreq */
5634 static const int neon_3reg_wide[16][4] = {
5635 {1, 0, 0, 0}, /* VADDL */
5636 {1, 1, 0, 0}, /* VADDW */
5637 {1, 0, 0, 0}, /* VSUBL */
5638 {1, 1, 0, 0}, /* VSUBW */
5639 {0, 1, 1, 0}, /* VADDHN */
5640 {0, 0, 0, 0}, /* VABAL */
5641 {0, 1, 1, 0}, /* VSUBHN */
5642 {0, 0, 0, 0}, /* VABDL */
5643 {0, 0, 0, 0}, /* VMLAL */
5644 {0, 0, 0, 6}, /* VQDMLAL */
5645 {0, 0, 0, 0}, /* VMLSL */
5646 {0, 0, 0, 6}, /* VQDMLSL */
5647 {0, 0, 0, 0}, /* Integer VMULL */
5648 {0, 0, 0, 2}, /* VQDMULL */
5649 {0, 0, 0, 5}, /* Polynomial VMULL */
5650 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5653 prewiden = neon_3reg_wide[op][0];
5654 src1_wide = neon_3reg_wide[op][1];
5655 src2_wide = neon_3reg_wide[op][2];
5656 undefreq = neon_3reg_wide[op][3];
5658 if (((undefreq & 1) && (size != 0)) ||
5659 ((undefreq & 2) && (size == 0)) ||
5660 ((undefreq & 4) && u)) {
5663 if ((src1_wide && (rn & 1)) ||
5664 (src2_wide && (rm & 1)) ||
5665 (!src2_wide && (rd & 1))) {
5669 /* Avoid overlapping operands. Wide source operands are
5670 always aligned so will never overlap with wide
5671 destinations in problematic ways. */
5672 if (rd == rm && !src2_wide) {
5673 tmp = neon_load_reg(rm, 1);
5674 neon_store_scratch(2, tmp);
5675 } else if (rd == rn && !src1_wide) {
5676 tmp = neon_load_reg(rn, 1);
5677 neon_store_scratch(2, tmp);
5679 TCGV_UNUSED_I32(tmp3);
5680 for (pass = 0; pass < 2; pass++) {
5682 neon_load_reg64(cpu_V0, rn + pass);
5683 TCGV_UNUSED_I32(tmp);
5685 if (pass == 1 && rd == rn) {
5686 tmp = neon_load_scratch(2);
5688 tmp = neon_load_reg(rn, pass);
5691 gen_neon_widen(cpu_V0, tmp, size, u);
5695 neon_load_reg64(cpu_V1, rm + pass);
5696 TCGV_UNUSED_I32(tmp2);
5698 if (pass == 1 && rd == rm) {
5699 tmp2 = neon_load_scratch(2);
5701 tmp2 = neon_load_reg(rm, pass);
5704 gen_neon_widen(cpu_V1, tmp2, size, u);
5708 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5709 gen_neon_addl(size);
5711 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5712 gen_neon_subl(size);
5714 case 5: case 7: /* VABAL, VABDL */
5715 switch ((size << 1) | u) {
5717 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5720 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5723 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5726 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5729 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5732 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5736 tcg_temp_free_i32(tmp2);
5737 tcg_temp_free_i32(tmp);
5739 case 8: case 9: case 10: case 11: case 12: case 13:
5740 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5741 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5743 case 14: /* Polynomial VMULL */
5744 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5745 tcg_temp_free_i32(tmp2);
5746 tcg_temp_free_i32(tmp);
5748 default: /* 15 is RESERVED: caught earlier */
5753 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5754 neon_store_reg64(cpu_V0, rd + pass);
5755 } else if (op == 5 || (op >= 8 && op <= 11)) {
5757 neon_load_reg64(cpu_V1, rd + pass);
5759 case 10: /* VMLSL */
5760 gen_neon_negl(cpu_V0, size);
5762 case 5: case 8: /* VABAL, VMLAL */
5763 gen_neon_addl(size);
5765 case 9: case 11: /* VQDMLAL, VQDMLSL */
5766 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5768 gen_neon_negl(cpu_V0, size);
5770 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5775 neon_store_reg64(cpu_V0, rd + pass);
5776 } else if (op == 4 || op == 6) {
5777 /* Narrowing operation. */
5778 tmp = tcg_temp_new_i32();
5782 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5785 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5788 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5789 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5796 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5799 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5802 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5803 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5804 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5812 neon_store_reg(rd, 0, tmp3);
5813 neon_store_reg(rd, 1, tmp);
5816 /* Write back the result. */
5817 neon_store_reg64(cpu_V0, rd + pass);
5821 /* Two registers and a scalar. NB that for ops of this form
5822 * the ARM ARM labels bit 24 as Q, but it is in our variable
5829 case 1: /* Float VMLA scalar */
5830 case 5: /* Floating point VMLS scalar */
5831 case 9: /* Floating point VMUL scalar */
5836 case 0: /* Integer VMLA scalar */
5837 case 4: /* Integer VMLS scalar */
5838 case 8: /* Integer VMUL scalar */
5839 case 12: /* VQDMULH scalar */
5840 case 13: /* VQRDMULH scalar */
5841 if (u && ((rd | rn) & 1)) {
5844 tmp = neon_get_scalar(size, rm);
5845 neon_store_scratch(0, tmp);
5846 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5847 tmp = neon_load_scratch(0);
5848 tmp2 = neon_load_reg(rn, pass);
5851 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5853 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5855 } else if (op == 13) {
5857 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5859 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5861 } else if (op & 1) {
5862 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5863 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5864 tcg_temp_free_ptr(fpstatus);
5867 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5868 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5869 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5873 tcg_temp_free_i32(tmp2);
5876 tmp2 = neon_load_reg(rd, pass);
5879 gen_neon_add(size, tmp, tmp2);
5883 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5884 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5885 tcg_temp_free_ptr(fpstatus);
5889 gen_neon_rsb(size, tmp, tmp2);
5893 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5894 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5895 tcg_temp_free_ptr(fpstatus);
5901 tcg_temp_free_i32(tmp2);
5903 neon_store_reg(rd, pass, tmp);
5906 case 3: /* VQDMLAL scalar */
5907 case 7: /* VQDMLSL scalar */
5908 case 11: /* VQDMULL scalar */
5913 case 2: /* VMLAL sclar */
5914 case 6: /* VMLSL scalar */
5915 case 10: /* VMULL scalar */
5919 tmp2 = neon_get_scalar(size, rm);
5920 /* We need a copy of tmp2 because gen_neon_mull
5921 * deletes it during pass 0. */
5922 tmp4 = tcg_temp_new_i32();
5923 tcg_gen_mov_i32(tmp4, tmp2);
5924 tmp3 = neon_load_reg(rn, 1);
5926 for (pass = 0; pass < 2; pass++) {
5928 tmp = neon_load_reg(rn, 0);
5933 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5935 neon_load_reg64(cpu_V1, rd + pass);
5939 gen_neon_negl(cpu_V0, size);
5942 gen_neon_addl(size);
5945 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5947 gen_neon_negl(cpu_V0, size);
5949 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5955 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5960 neon_store_reg64(cpu_V0, rd + pass);
5965 default: /* 14 and 15 are RESERVED */
5969 } else { /* size == 3 */
5972 imm = (insn >> 8) & 0xf;
5977 if (q && ((rd | rn | rm) & 1)) {
5982 neon_load_reg64(cpu_V0, rn);
5984 neon_load_reg64(cpu_V1, rn + 1);
5986 } else if (imm == 8) {
5987 neon_load_reg64(cpu_V0, rn + 1);
5989 neon_load_reg64(cpu_V1, rm);
5992 tmp64 = tcg_temp_new_i64();
5994 neon_load_reg64(cpu_V0, rn);
5995 neon_load_reg64(tmp64, rn + 1);
5997 neon_load_reg64(cpu_V0, rn + 1);
5998 neon_load_reg64(tmp64, rm);
6000 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6001 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6002 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6004 neon_load_reg64(cpu_V1, rm);
6006 neon_load_reg64(cpu_V1, rm + 1);
6009 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6010 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6011 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6012 tcg_temp_free_i64(tmp64);
6015 neon_load_reg64(cpu_V0, rn);
6016 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6017 neon_load_reg64(cpu_V1, rm);
6018 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6019 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6021 neon_store_reg64(cpu_V0, rd);
6023 neon_store_reg64(cpu_V1, rd + 1);
6025 } else if ((insn & (1 << 11)) == 0) {
6026 /* Two register misc. */
6027 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6028 size = (insn >> 18) & 3;
6029 /* UNDEF for unknown op values and bad op-size combinations */
6030 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6033 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6034 q && ((rm | rd) & 1)) {
6038 case NEON_2RM_VREV64:
6039 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6040 tmp = neon_load_reg(rm, pass * 2);
6041 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6043 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6044 case 1: gen_swap_half(tmp); break;
6045 case 2: /* no-op */ break;
6048 neon_store_reg(rd, pass * 2 + 1, tmp);
6050 neon_store_reg(rd, pass * 2, tmp2);
6053 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6054 case 1: gen_swap_half(tmp2); break;
6057 neon_store_reg(rd, pass * 2, tmp2);
6061 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6062 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6063 for (pass = 0; pass < q + 1; pass++) {
6064 tmp = neon_load_reg(rm, pass * 2);
6065 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6066 tmp = neon_load_reg(rm, pass * 2 + 1);
6067 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6069 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6070 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6071 case 2: tcg_gen_add_i64(CPU_V001); break;
6074 if (op >= NEON_2RM_VPADAL) {
6076 neon_load_reg64(cpu_V1, rd + pass);
6077 gen_neon_addl(size);
6079 neon_store_reg64(cpu_V0, rd + pass);
6085 for (n = 0; n < (q ? 4 : 2); n += 2) {
6086 tmp = neon_load_reg(rm, n);
6087 tmp2 = neon_load_reg(rd, n + 1);
6088 neon_store_reg(rm, n, tmp2);
6089 neon_store_reg(rd, n + 1, tmp);
6096 if (gen_neon_unzip(rd, rm, size, q)) {
6101 if (gen_neon_zip(rd, rm, size, q)) {
6105 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6106 /* also VQMOVUN; op field and mnemonics don't line up */
6110 TCGV_UNUSED_I32(tmp2);
6111 for (pass = 0; pass < 2; pass++) {
6112 neon_load_reg64(cpu_V0, rm + pass);
6113 tmp = tcg_temp_new_i32();
6114 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6119 neon_store_reg(rd, 0, tmp2);
6120 neon_store_reg(rd, 1, tmp);
6124 case NEON_2RM_VSHLL:
6125 if (q || (rd & 1)) {
6128 tmp = neon_load_reg(rm, 0);
6129 tmp2 = neon_load_reg(rm, 1);
6130 for (pass = 0; pass < 2; pass++) {
6133 gen_neon_widen(cpu_V0, tmp, size, 1);
6134 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6135 neon_store_reg64(cpu_V0, rd + pass);
6138 case NEON_2RM_VCVT_F16_F32:
6139 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6143 tmp = tcg_temp_new_i32();
6144 tmp2 = tcg_temp_new_i32();
6145 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6146 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6147 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6148 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6149 tcg_gen_shli_i32(tmp2, tmp2, 16);
6150 tcg_gen_or_i32(tmp2, tmp2, tmp);
6151 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6152 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6153 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6154 neon_store_reg(rd, 0, tmp2);
6155 tmp2 = tcg_temp_new_i32();
6156 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6157 tcg_gen_shli_i32(tmp2, tmp2, 16);
6158 tcg_gen_or_i32(tmp2, tmp2, tmp);
6159 neon_store_reg(rd, 1, tmp2);
6160 tcg_temp_free_i32(tmp);
6162 case NEON_2RM_VCVT_F32_F16:
6163 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6167 tmp3 = tcg_temp_new_i32();
6168 tmp = neon_load_reg(rm, 0);
6169 tmp2 = neon_load_reg(rm, 1);
6170 tcg_gen_ext16u_i32(tmp3, tmp);
6171 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6172 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6173 tcg_gen_shri_i32(tmp3, tmp, 16);
6174 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6175 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6176 tcg_temp_free_i32(tmp);
6177 tcg_gen_ext16u_i32(tmp3, tmp2);
6178 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6179 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6180 tcg_gen_shri_i32(tmp3, tmp2, 16);
6181 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6182 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6183 tcg_temp_free_i32(tmp2);
6184 tcg_temp_free_i32(tmp3);
6186 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6187 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6188 || ((rm | rd) & 1)) {
6191 tmp = tcg_const_i32(rd);
6192 tmp2 = tcg_const_i32(rm);
6194 /* Bit 6 is the lowest opcode bit; it distinguishes between
6195 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6197 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6199 if (op == NEON_2RM_AESE) {
6200 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6202 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6204 tcg_temp_free_i32(tmp);
6205 tcg_temp_free_i32(tmp2);
6206 tcg_temp_free_i32(tmp3);
6210 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6211 if (neon_2rm_is_float_op(op)) {
6212 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6213 neon_reg_offset(rm, pass));
6214 TCGV_UNUSED_I32(tmp);
6216 tmp = neon_load_reg(rm, pass);
6219 case NEON_2RM_VREV32:
6221 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6222 case 1: gen_swap_half(tmp); break;
6226 case NEON_2RM_VREV16:
6231 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6232 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6233 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6239 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6240 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6241 case 2: gen_helper_clz(tmp, tmp); break;
6246 gen_helper_neon_cnt_u8(tmp, tmp);
6249 tcg_gen_not_i32(tmp, tmp);
6251 case NEON_2RM_VQABS:
6254 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6257 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6260 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6265 case NEON_2RM_VQNEG:
6268 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6271 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6274 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6279 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6280 tmp2 = tcg_const_i32(0);
6282 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6283 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6284 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6287 tcg_temp_free_i32(tmp2);
6288 if (op == NEON_2RM_VCLE0) {
6289 tcg_gen_not_i32(tmp, tmp);
6292 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6293 tmp2 = tcg_const_i32(0);
6295 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6296 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6297 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6300 tcg_temp_free_i32(tmp2);
6301 if (op == NEON_2RM_VCLT0) {
6302 tcg_gen_not_i32(tmp, tmp);
6305 case NEON_2RM_VCEQ0:
6306 tmp2 = tcg_const_i32(0);
6308 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6309 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6310 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6313 tcg_temp_free_i32(tmp2);
6317 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6318 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6319 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6324 tmp2 = tcg_const_i32(0);
6325 gen_neon_rsb(size, tmp, tmp2);
6326 tcg_temp_free_i32(tmp2);
6328 case NEON_2RM_VCGT0_F:
6330 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6331 tmp2 = tcg_const_i32(0);
6332 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6333 tcg_temp_free_i32(tmp2);
6334 tcg_temp_free_ptr(fpstatus);
6337 case NEON_2RM_VCGE0_F:
6339 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6340 tmp2 = tcg_const_i32(0);
6341 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6342 tcg_temp_free_i32(tmp2);
6343 tcg_temp_free_ptr(fpstatus);
6346 case NEON_2RM_VCEQ0_F:
6348 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6349 tmp2 = tcg_const_i32(0);
6350 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6351 tcg_temp_free_i32(tmp2);
6352 tcg_temp_free_ptr(fpstatus);
6355 case NEON_2RM_VCLE0_F:
6357 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6358 tmp2 = tcg_const_i32(0);
6359 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6360 tcg_temp_free_i32(tmp2);
6361 tcg_temp_free_ptr(fpstatus);
6364 case NEON_2RM_VCLT0_F:
6366 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6367 tmp2 = tcg_const_i32(0);
6368 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6369 tcg_temp_free_i32(tmp2);
6370 tcg_temp_free_ptr(fpstatus);
6373 case NEON_2RM_VABS_F:
6376 case NEON_2RM_VNEG_F:
6380 tmp2 = neon_load_reg(rd, pass);
6381 neon_store_reg(rm, pass, tmp2);
6384 tmp2 = neon_load_reg(rd, pass);
6386 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6387 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6390 neon_store_reg(rm, pass, tmp2);
6392 case NEON_2RM_VRECPE:
6393 gen_helper_recpe_u32(tmp, tmp, cpu_env);
6395 case NEON_2RM_VRSQRTE:
6396 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6398 case NEON_2RM_VRECPE_F:
6399 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6401 case NEON_2RM_VRSQRTE_F:
6402 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6404 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6407 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6410 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6411 gen_vfp_tosiz(0, 1);
6413 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6414 gen_vfp_touiz(0, 1);
6417 /* Reserved op values were caught by the
6418 * neon_2rm_sizes[] check earlier.
6422 if (neon_2rm_is_float_op(op)) {
6423 tcg_gen_st_f32(cpu_F0s, cpu_env,
6424 neon_reg_offset(rd, pass));
6426 neon_store_reg(rd, pass, tmp);
6431 } else if ((insn & (1 << 10)) == 0) {
6433 int n = ((insn >> 8) & 3) + 1;
6434 if ((rn + n) > 32) {
6435 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6436 * helper function running off the end of the register file.
6441 if (insn & (1 << 6)) {
6442 tmp = neon_load_reg(rd, 0);
6444 tmp = tcg_temp_new_i32();
6445 tcg_gen_movi_i32(tmp, 0);
6447 tmp2 = neon_load_reg(rm, 0);
6448 tmp4 = tcg_const_i32(rn);
6449 tmp5 = tcg_const_i32(n);
6450 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6451 tcg_temp_free_i32(tmp);
6452 if (insn & (1 << 6)) {
6453 tmp = neon_load_reg(rd, 1);
6455 tmp = tcg_temp_new_i32();
6456 tcg_gen_movi_i32(tmp, 0);
6458 tmp3 = neon_load_reg(rm, 1);
6459 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6460 tcg_temp_free_i32(tmp5);
6461 tcg_temp_free_i32(tmp4);
6462 neon_store_reg(rd, 0, tmp2);
6463 neon_store_reg(rd, 1, tmp3);
6464 tcg_temp_free_i32(tmp);
6465 } else if ((insn & 0x380) == 0) {
6467 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6470 if (insn & (1 << 19)) {
6471 tmp = neon_load_reg(rm, 1);
6473 tmp = neon_load_reg(rm, 0);
6475 if (insn & (1 << 16)) {
6476 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6477 } else if (insn & (1 << 17)) {
6478 if ((insn >> 18) & 1)
6479 gen_neon_dup_high16(tmp);
6481 gen_neon_dup_low16(tmp);
6483 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6484 tmp2 = tcg_temp_new_i32();
6485 tcg_gen_mov_i32(tmp2, tmp);
6486 neon_store_reg(rd, pass, tmp2);
6488 tcg_temp_free_i32(tmp);
6497 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6499 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6500 const ARMCPRegInfo *ri;
6502 cpnum = (insn >> 8) & 0xf;
6503 if (arm_feature(env, ARM_FEATURE_XSCALE)
6504 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6507 /* First check for coprocessor space used for actual instructions */
6511 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6512 return disas_iwmmxt_insn(env, s, insn);
6513 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6514 return disas_dsp_insn(env, s, insn);
6521 /* Otherwise treat as a generic register access */
6522 is64 = (insn & (1 << 25)) == 0;
6523 if (!is64 && ((insn & (1 << 4)) == 0)) {
6531 opc1 = (insn >> 4) & 0xf;
6533 rt2 = (insn >> 16) & 0xf;
6535 crn = (insn >> 16) & 0xf;
6536 opc1 = (insn >> 21) & 7;
6537 opc2 = (insn >> 5) & 7;
6540 isread = (insn >> 20) & 1;
6541 rt = (insn >> 12) & 0xf;
6543 ri = get_arm_cp_reginfo(s->cp_regs,
6544 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6546 /* Check access permissions */
6547 if (!cp_access_ok(s->current_pl, ri, isread)) {
6551 /* Handle special cases first */
6552 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6559 gen_set_pc_im(s, s->pc);
6560 s->is_jmp = DISAS_WFI;
6566 if (use_icount && (ri->type & ARM_CP_IO)) {
6575 if (ri->type & ARM_CP_CONST) {
6576 tmp64 = tcg_const_i64(ri->resetvalue);
6577 } else if (ri->readfn) {
6579 gen_set_pc_im(s, s->pc);
6580 tmp64 = tcg_temp_new_i64();
6581 tmpptr = tcg_const_ptr(ri);
6582 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6583 tcg_temp_free_ptr(tmpptr);
6585 tmp64 = tcg_temp_new_i64();
6586 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6588 tmp = tcg_temp_new_i32();
6589 tcg_gen_trunc_i64_i32(tmp, tmp64);
6590 store_reg(s, rt, tmp);
6591 tcg_gen_shri_i64(tmp64, tmp64, 32);
6592 tmp = tcg_temp_new_i32();
6593 tcg_gen_trunc_i64_i32(tmp, tmp64);
6594 tcg_temp_free_i64(tmp64);
6595 store_reg(s, rt2, tmp);
6598 if (ri->type & ARM_CP_CONST) {
6599 tmp = tcg_const_i32(ri->resetvalue);
6600 } else if (ri->readfn) {
6602 gen_set_pc_im(s, s->pc);
6603 tmp = tcg_temp_new_i32();
6604 tmpptr = tcg_const_ptr(ri);
6605 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6606 tcg_temp_free_ptr(tmpptr);
6608 tmp = load_cpu_offset(ri->fieldoffset);
6611 /* Destination register of r15 for 32 bit loads sets
6612 * the condition codes from the high 4 bits of the value
6615 tcg_temp_free_i32(tmp);
6617 store_reg(s, rt, tmp);
6622 if (ri->type & ARM_CP_CONST) {
6623 /* If not forbidden by access permissions, treat as WI */
6628 TCGv_i32 tmplo, tmphi;
6629 TCGv_i64 tmp64 = tcg_temp_new_i64();
6630 tmplo = load_reg(s, rt);
6631 tmphi = load_reg(s, rt2);
6632 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6633 tcg_temp_free_i32(tmplo);
6634 tcg_temp_free_i32(tmphi);
6636 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6637 gen_set_pc_im(s, s->pc);
6638 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6639 tcg_temp_free_ptr(tmpptr);
6641 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6643 tcg_temp_free_i64(tmp64);
6648 gen_set_pc_im(s, s->pc);
6649 tmp = load_reg(s, rt);
6650 tmpptr = tcg_const_ptr(ri);
6651 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6652 tcg_temp_free_ptr(tmpptr);
6653 tcg_temp_free_i32(tmp);
6655 TCGv_i32 tmp = load_reg(s, rt);
6656 store_cpu_offset(tmp, ri->fieldoffset);
6661 if (use_icount && (ri->type & ARM_CP_IO)) {
6662 /* I/O operations must end the TB here (whether read or write) */
6665 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6666 /* We default to ending the TB on a coprocessor register write,
6667 * but allow this to be suppressed by the register definition
6668 * (usually only necessary to work around guest bugs).
6680 /* Store a 64-bit value to a register pair. Clobbers val. */
6681 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6684 tmp = tcg_temp_new_i32();
6685 tcg_gen_trunc_i64_i32(tmp, val);
6686 store_reg(s, rlow, tmp);
6687 tmp = tcg_temp_new_i32();
6688 tcg_gen_shri_i64(val, val, 32);
6689 tcg_gen_trunc_i64_i32(tmp, val);
6690 store_reg(s, rhigh, tmp);
6693 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6694 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6699 /* Load value and extend to 64 bits. */
6700 tmp = tcg_temp_new_i64();
6701 tmp2 = load_reg(s, rlow);
6702 tcg_gen_extu_i32_i64(tmp, tmp2);
6703 tcg_temp_free_i32(tmp2);
6704 tcg_gen_add_i64(val, val, tmp);
6705 tcg_temp_free_i64(tmp);
6708 /* load and add a 64-bit value from a register pair. */
6709 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6715 /* Load 64-bit value rd:rn. */
6716 tmpl = load_reg(s, rlow);
6717 tmph = load_reg(s, rhigh);
6718 tmp = tcg_temp_new_i64();
6719 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6720 tcg_temp_free_i32(tmpl);
6721 tcg_temp_free_i32(tmph);
6722 tcg_gen_add_i64(val, val, tmp);
6723 tcg_temp_free_i64(tmp);
6726 /* Set N and Z flags from hi|lo. */
6727 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6729 tcg_gen_mov_i32(cpu_NF, hi);
6730 tcg_gen_or_i32(cpu_ZF, lo, hi);
6733 /* Load/Store exclusive instructions are implemented by remembering
6734 the value/address loaded, and seeing if these are the same
6735 when the store is performed. This should be sufficient to implement
6736 the architecturally mandated semantics, and avoids having to monitor
6739 In system emulation mode only one CPU will be running at once, so
6740 this sequence is effectively atomic. In user emulation mode we
6741 throw an exception and handle the atomic operation elsewhere. */
6742 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6743 TCGv_i32 addr, int size)
6745 TCGv_i32 tmp = tcg_temp_new_i32();
6749 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6752 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6756 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6761 tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6762 store_reg(s, rt, tmp);
6764 TCGv_i32 tmp2 = tcg_temp_new_i32();
6765 tcg_gen_addi_i32(tmp2, addr, 4);
6766 tmp = tcg_temp_new_i32();
6767 gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6768 tcg_temp_free_i32(tmp2);
6769 tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6770 store_reg(s, rt2, tmp);
6772 tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6775 static void gen_clrex(DisasContext *s)
6777 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6780 #ifdef CONFIG_USER_ONLY
6781 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6782 TCGv_i32 addr, int size)
6784 tcg_gen_mov_i32(cpu_exclusive_test, addr);
6785 tcg_gen_movi_i32(cpu_exclusive_info,
6786 size | (rd << 4) | (rt << 8) | (rt2 << 12));
6787 gen_exception_insn(s, 4, EXCP_STREX);
6790 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6791 TCGv_i32 addr, int size)
6797 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6803 fail_label = gen_new_label();
6804 done_label = gen_new_label();
6805 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6806 tmp = tcg_temp_new_i32();
6809 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6812 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6816 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6821 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6822 tcg_temp_free_i32(tmp);
6824 TCGv_i32 tmp2 = tcg_temp_new_i32();
6825 tcg_gen_addi_i32(tmp2, addr, 4);
6826 tmp = tcg_temp_new_i32();
6827 gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6828 tcg_temp_free_i32(tmp2);
6829 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6830 tcg_temp_free_i32(tmp);
6832 tmp = load_reg(s, rt);
6835 gen_aa32_st8(tmp, addr, IS_USER(s));
6838 gen_aa32_st16(tmp, addr, IS_USER(s));
6842 gen_aa32_st32(tmp, addr, IS_USER(s));
6847 tcg_temp_free_i32(tmp);
6849 tcg_gen_addi_i32(addr, addr, 4);
6850 tmp = load_reg(s, rt2);
6851 gen_aa32_st32(tmp, addr, IS_USER(s));
6852 tcg_temp_free_i32(tmp);
6854 tcg_gen_movi_i32(cpu_R[rd], 0);
6855 tcg_gen_br(done_label);
6856 gen_set_label(fail_label);
6857 tcg_gen_movi_i32(cpu_R[rd], 1);
6858 gen_set_label(done_label);
6859 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6866 * @mode: mode field from insn (which stack to store to)
6867 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6868 * @writeback: true if writeback bit set
6870 * Generate code for the SRS (Store Return State) insn.
6872 static void gen_srs(DisasContext *s,
6873 uint32_t mode, uint32_t amode, bool writeback)
6876 TCGv_i32 addr = tcg_temp_new_i32();
6877 TCGv_i32 tmp = tcg_const_i32(mode);
6878 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6879 tcg_temp_free_i32(tmp);
6896 tcg_gen_addi_i32(addr, addr, offset);
6897 tmp = load_reg(s, 14);
6898 gen_aa32_st32(tmp, addr, 0);
6899 tcg_temp_free_i32(tmp);
6900 tmp = load_cpu_field(spsr);
6901 tcg_gen_addi_i32(addr, addr, 4);
6902 gen_aa32_st32(tmp, addr, 0);
6903 tcg_temp_free_i32(tmp);
6921 tcg_gen_addi_i32(addr, addr, offset);
6922 tmp = tcg_const_i32(mode);
6923 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6924 tcg_temp_free_i32(tmp);
6926 tcg_temp_free_i32(addr);
6929 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6931 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6938 insn = arm_ldl_code(env, s->pc, s->bswap_code);
6941 /* M variants do not implement ARM mode. */
6946 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6947 * choose to UNDEF. In ARMv5 and above the space is used
6948 * for miscellaneous unconditional instructions.
6952 /* Unconditional instructions. */
6953 if (((insn >> 25) & 7) == 1) {
6954 /* NEON Data processing. */
6955 if (!arm_feature(env, ARM_FEATURE_NEON))
6958 if (disas_neon_data_insn(env, s, insn))
6962 if ((insn & 0x0f100000) == 0x04000000) {
6963 /* NEON load/store. */
6964 if (!arm_feature(env, ARM_FEATURE_NEON))
6967 if (disas_neon_ls_insn(env, s, insn))
6971 if ((insn & 0x0f000e10) == 0x0e000a00) {
6973 if (disas_vfp_insn(env, s, insn)) {
6978 if (((insn & 0x0f30f000) == 0x0510f000) ||
6979 ((insn & 0x0f30f010) == 0x0710f000)) {
6980 if ((insn & (1 << 22)) == 0) {
6982 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6986 /* Otherwise PLD; v5TE+ */
6990 if (((insn & 0x0f70f000) == 0x0450f000) ||
6991 ((insn & 0x0f70f010) == 0x0650f000)) {
6993 return; /* PLI; V7 */
6995 if (((insn & 0x0f700000) == 0x04100000) ||
6996 ((insn & 0x0f700010) == 0x06100000)) {
6997 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7000 return; /* v7MP: Unallocated memory hint: must NOP */
7003 if ((insn & 0x0ffffdff) == 0x01010000) {
7006 if (((insn >> 9) & 1) != s->bswap_code) {
7007 /* Dynamic endianness switching not implemented. */
7008 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7012 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7013 switch ((insn >> 4) & 0xf) {
7022 /* We don't emulate caches so these are a no-op. */
7027 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7033 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7035 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7041 rn = (insn >> 16) & 0xf;
7042 addr = load_reg(s, rn);
7043 i = (insn >> 23) & 3;
7045 case 0: offset = -4; break; /* DA */
7046 case 1: offset = 0; break; /* IA */
7047 case 2: offset = -8; break; /* DB */
7048 case 3: offset = 4; break; /* IB */
7052 tcg_gen_addi_i32(addr, addr, offset);
7053 /* Load PC into tmp and CPSR into tmp2. */
7054 tmp = tcg_temp_new_i32();
7055 gen_aa32_ld32u(tmp, addr, 0);
7056 tcg_gen_addi_i32(addr, addr, 4);
7057 tmp2 = tcg_temp_new_i32();
7058 gen_aa32_ld32u(tmp2, addr, 0);
7059 if (insn & (1 << 21)) {
7060 /* Base writeback. */
7062 case 0: offset = -8; break;
7063 case 1: offset = 4; break;
7064 case 2: offset = -4; break;
7065 case 3: offset = 0; break;
7069 tcg_gen_addi_i32(addr, addr, offset);
7070 store_reg(s, rn, addr);
7072 tcg_temp_free_i32(addr);
7074 gen_rfe(s, tmp, tmp2);
7076 } else if ((insn & 0x0e000000) == 0x0a000000) {
7077 /* branch link and change to thumb (blx <offset>) */
7080 val = (uint32_t)s->pc;
7081 tmp = tcg_temp_new_i32();
7082 tcg_gen_movi_i32(tmp, val);
7083 store_reg(s, 14, tmp);
7084 /* Sign-extend the 24-bit offset */
7085 offset = (((int32_t)insn) << 8) >> 8;
7086 /* offset * 4 + bit24 * 2 + (thumb bit) */
7087 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7088 /* pipeline offset */
7090 /* protected by ARCH(5); above, near the start of uncond block */
7093 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7094 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7095 /* iWMMXt register transfer. */
7096 if (env->cp15.c15_cpar & (1 << 1))
7097 if (!disas_iwmmxt_insn(env, s, insn))
7100 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7101 /* Coprocessor double register transfer. */
7103 } else if ((insn & 0x0f000010) == 0x0e000010) {
7104 /* Additional coprocessor register transfer. */
7105 } else if ((insn & 0x0ff10020) == 0x01000000) {
7108 /* cps (privileged) */
7112 if (insn & (1 << 19)) {
7113 if (insn & (1 << 8))
7115 if (insn & (1 << 7))
7117 if (insn & (1 << 6))
7119 if (insn & (1 << 18))
7122 if (insn & (1 << 17)) {
7124 val |= (insn & 0x1f);
7127 gen_set_psr_im(s, mask, 0, val);
7134 /* if not always execute, we generate a conditional jump to
7136 s->condlabel = gen_new_label();
7137 arm_gen_test_cc(cond ^ 1, s->condlabel);
7140 if ((insn & 0x0f900000) == 0x03000000) {
7141 if ((insn & (1 << 21)) == 0) {
7143 rd = (insn >> 12) & 0xf;
7144 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7145 if ((insn & (1 << 22)) == 0) {
7147 tmp = tcg_temp_new_i32();
7148 tcg_gen_movi_i32(tmp, val);
7151 tmp = load_reg(s, rd);
7152 tcg_gen_ext16u_i32(tmp, tmp);
7153 tcg_gen_ori_i32(tmp, tmp, val << 16);
7155 store_reg(s, rd, tmp);
7157 if (((insn >> 12) & 0xf) != 0xf)
7159 if (((insn >> 16) & 0xf) == 0) {
7160 gen_nop_hint(s, insn & 0xff);
7162 /* CPSR = immediate */
7164 shift = ((insn >> 8) & 0xf) * 2;
7166 val = (val >> shift) | (val << (32 - shift));
7167 i = ((insn & (1 << 22)) != 0);
7168 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7172 } else if ((insn & 0x0f900000) == 0x01000000
7173 && (insn & 0x00000090) != 0x00000090) {
7174 /* miscellaneous instructions */
7175 op1 = (insn >> 21) & 3;
7176 sh = (insn >> 4) & 0xf;
7179 case 0x0: /* move program status register */
7182 tmp = load_reg(s, rm);
7183 i = ((op1 & 2) != 0);
7184 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7188 rd = (insn >> 12) & 0xf;
7192 tmp = load_cpu_field(spsr);
7194 tmp = tcg_temp_new_i32();
7195 gen_helper_cpsr_read(tmp, cpu_env);
7197 store_reg(s, rd, tmp);
7202 /* branch/exchange thumb (bx). */
7204 tmp = load_reg(s, rm);
7206 } else if (op1 == 3) {
7209 rd = (insn >> 12) & 0xf;
7210 tmp = load_reg(s, rm);
7211 gen_helper_clz(tmp, tmp);
7212 store_reg(s, rd, tmp);
7220 /* Trivial implementation equivalent to bx. */
7221 tmp = load_reg(s, rm);
7232 /* branch link/exchange thumb (blx) */
7233 tmp = load_reg(s, rm);
7234 tmp2 = tcg_temp_new_i32();
7235 tcg_gen_movi_i32(tmp2, s->pc);
7236 store_reg(s, 14, tmp2);
7239 case 0x5: /* saturating add/subtract */
7241 rd = (insn >> 12) & 0xf;
7242 rn = (insn >> 16) & 0xf;
7243 tmp = load_reg(s, rm);
7244 tmp2 = load_reg(s, rn);
7246 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7248 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7250 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7251 tcg_temp_free_i32(tmp2);
7252 store_reg(s, rd, tmp);
7255 /* SMC instruction (op1 == 3)
7256 and undefined instructions (op1 == 0 || op1 == 2)
7263 gen_exception_insn(s, 4, EXCP_BKPT);
7265 case 0x8: /* signed multiply */
7270 rs = (insn >> 8) & 0xf;
7271 rn = (insn >> 12) & 0xf;
7272 rd = (insn >> 16) & 0xf;
7274 /* (32 * 16) >> 16 */
7275 tmp = load_reg(s, rm);
7276 tmp2 = load_reg(s, rs);
7278 tcg_gen_sari_i32(tmp2, tmp2, 16);
7281 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7282 tcg_gen_shri_i64(tmp64, tmp64, 16);
7283 tmp = tcg_temp_new_i32();
7284 tcg_gen_trunc_i64_i32(tmp, tmp64);
7285 tcg_temp_free_i64(tmp64);
7286 if ((sh & 2) == 0) {
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);
7294 tmp = load_reg(s, rm);
7295 tmp2 = load_reg(s, rs);
7296 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7297 tcg_temp_free_i32(tmp2);
7299 tmp64 = tcg_temp_new_i64();
7300 tcg_gen_ext_i32_i64(tmp64, tmp);
7301 tcg_temp_free_i32(tmp);
7302 gen_addq(s, tmp64, rn, rd);
7303 gen_storeq_reg(s, rn, rd, tmp64);
7304 tcg_temp_free_i64(tmp64);
7307 tmp2 = load_reg(s, rn);
7308 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7309 tcg_temp_free_i32(tmp2);
7311 store_reg(s, rd, tmp);
7318 } else if (((insn & 0x0e000000) == 0 &&
7319 (insn & 0x00000090) != 0x90) ||
7320 ((insn & 0x0e000000) == (1 << 25))) {
7321 int set_cc, logic_cc, shiftop;
7323 op1 = (insn >> 21) & 0xf;
7324 set_cc = (insn >> 20) & 1;
7325 logic_cc = table_logic_cc[op1] & set_cc;
7327 /* data processing instruction */
7328 if (insn & (1 << 25)) {
7329 /* immediate operand */
7331 shift = ((insn >> 8) & 0xf) * 2;
7333 val = (val >> shift) | (val << (32 - shift));
7335 tmp2 = tcg_temp_new_i32();
7336 tcg_gen_movi_i32(tmp2, val);
7337 if (logic_cc && shift) {
7338 gen_set_CF_bit31(tmp2);
7343 tmp2 = load_reg(s, rm);
7344 shiftop = (insn >> 5) & 3;
7345 if (!(insn & (1 << 4))) {
7346 shift = (insn >> 7) & 0x1f;
7347 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7349 rs = (insn >> 8) & 0xf;
7350 tmp = load_reg(s, rs);
7351 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7354 if (op1 != 0x0f && op1 != 0x0d) {
7355 rn = (insn >> 16) & 0xf;
7356 tmp = load_reg(s, rn);
7358 TCGV_UNUSED_I32(tmp);
7360 rd = (insn >> 12) & 0xf;
7363 tcg_gen_and_i32(tmp, tmp, tmp2);
7367 store_reg_bx(env, s, rd, tmp);
7370 tcg_gen_xor_i32(tmp, tmp, tmp2);
7374 store_reg_bx(env, s, rd, tmp);
7377 if (set_cc && rd == 15) {
7378 /* SUBS r15, ... is used for exception return. */
7382 gen_sub_CC(tmp, tmp, tmp2);
7383 gen_exception_return(s, tmp);
7386 gen_sub_CC(tmp, tmp, tmp2);
7388 tcg_gen_sub_i32(tmp, tmp, tmp2);
7390 store_reg_bx(env, s, rd, tmp);
7395 gen_sub_CC(tmp, tmp2, tmp);
7397 tcg_gen_sub_i32(tmp, tmp2, tmp);
7399 store_reg_bx(env, s, rd, tmp);
7403 gen_add_CC(tmp, tmp, tmp2);
7405 tcg_gen_add_i32(tmp, tmp, tmp2);
7407 store_reg_bx(env, s, rd, tmp);
7411 gen_adc_CC(tmp, tmp, tmp2);
7413 gen_add_carry(tmp, tmp, tmp2);
7415 store_reg_bx(env, s, rd, tmp);
7419 gen_sbc_CC(tmp, tmp, tmp2);
7421 gen_sub_carry(tmp, tmp, tmp2);
7423 store_reg_bx(env, s, rd, tmp);
7427 gen_sbc_CC(tmp, tmp2, tmp);
7429 gen_sub_carry(tmp, tmp2, tmp);
7431 store_reg_bx(env, s, rd, tmp);
7435 tcg_gen_and_i32(tmp, tmp, tmp2);
7438 tcg_temp_free_i32(tmp);
7442 tcg_gen_xor_i32(tmp, tmp, tmp2);
7445 tcg_temp_free_i32(tmp);
7449 gen_sub_CC(tmp, tmp, tmp2);
7451 tcg_temp_free_i32(tmp);
7455 gen_add_CC(tmp, tmp, tmp2);
7457 tcg_temp_free_i32(tmp);
7460 tcg_gen_or_i32(tmp, tmp, tmp2);
7464 store_reg_bx(env, s, rd, tmp);
7467 if (logic_cc && rd == 15) {
7468 /* MOVS r15, ... is used for exception return. */
7472 gen_exception_return(s, tmp2);
7477 store_reg_bx(env, s, rd, tmp2);
7481 tcg_gen_andc_i32(tmp, tmp, tmp2);
7485 store_reg_bx(env, s, rd, tmp);
7489 tcg_gen_not_i32(tmp2, tmp2);
7493 store_reg_bx(env, s, rd, tmp2);
7496 if (op1 != 0x0f && op1 != 0x0d) {
7497 tcg_temp_free_i32(tmp2);
7500 /* other instructions */
7501 op1 = (insn >> 24) & 0xf;
7505 /* multiplies, extra load/stores */
7506 sh = (insn >> 5) & 3;
7509 rd = (insn >> 16) & 0xf;
7510 rn = (insn >> 12) & 0xf;
7511 rs = (insn >> 8) & 0xf;
7513 op1 = (insn >> 20) & 0xf;
7515 case 0: case 1: case 2: case 3: case 6:
7517 tmp = load_reg(s, rs);
7518 tmp2 = load_reg(s, rm);
7519 tcg_gen_mul_i32(tmp, tmp, tmp2);
7520 tcg_temp_free_i32(tmp2);
7521 if (insn & (1 << 22)) {
7522 /* Subtract (mls) */
7524 tmp2 = load_reg(s, rn);
7525 tcg_gen_sub_i32(tmp, tmp2, tmp);
7526 tcg_temp_free_i32(tmp2);
7527 } else if (insn & (1 << 21)) {
7529 tmp2 = load_reg(s, rn);
7530 tcg_gen_add_i32(tmp, tmp, tmp2);
7531 tcg_temp_free_i32(tmp2);
7533 if (insn & (1 << 20))
7535 store_reg(s, rd, tmp);
7538 /* 64 bit mul double accumulate (UMAAL) */
7540 tmp = load_reg(s, rs);
7541 tmp2 = load_reg(s, rm);
7542 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7543 gen_addq_lo(s, tmp64, rn);
7544 gen_addq_lo(s, tmp64, rd);
7545 gen_storeq_reg(s, rn, rd, tmp64);
7546 tcg_temp_free_i64(tmp64);
7548 case 8: case 9: case 10: case 11:
7549 case 12: case 13: case 14: case 15:
7550 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7551 tmp = load_reg(s, rs);
7552 tmp2 = load_reg(s, rm);
7553 if (insn & (1 << 22)) {
7554 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7556 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7558 if (insn & (1 << 21)) { /* mult accumulate */
7559 TCGv_i32 al = load_reg(s, rn);
7560 TCGv_i32 ah = load_reg(s, rd);
7561 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7562 tcg_temp_free_i32(al);
7563 tcg_temp_free_i32(ah);
7565 if (insn & (1 << 20)) {
7566 gen_logicq_cc(tmp, tmp2);
7568 store_reg(s, rn, tmp);
7569 store_reg(s, rd, tmp2);
7575 rn = (insn >> 16) & 0xf;
7576 rd = (insn >> 12) & 0xf;
7577 if (insn & (1 << 23)) {
7578 /* load/store exclusive */
7579 int op2 = (insn >> 8) & 3;
7580 op1 = (insn >> 21) & 0x3;
7583 case 0: /* lda/stl */
7589 case 1: /* reserved */
7591 case 2: /* ldaex/stlex */
7594 case 3: /* ldrex/strex */
7603 addr = tcg_temp_local_new_i32();
7604 load_reg_var(s, addr, rn);
7606 /* Since the emulation does not have barriers,
7607 the acquire/release semantics need no special
7610 if (insn & (1 << 20)) {
7611 tmp = tcg_temp_new_i32();
7614 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7617 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7620 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7625 store_reg(s, rd, tmp);
7628 tmp = load_reg(s, rm);
7631 gen_aa32_st32(tmp, addr, IS_USER(s));
7634 gen_aa32_st8(tmp, addr, IS_USER(s));
7637 gen_aa32_st16(tmp, addr, IS_USER(s));
7642 tcg_temp_free_i32(tmp);
7644 } else if (insn & (1 << 20)) {
7647 gen_load_exclusive(s, rd, 15, addr, 2);
7649 case 1: /* ldrexd */
7650 gen_load_exclusive(s, rd, rd + 1, addr, 3);
7652 case 2: /* ldrexb */
7653 gen_load_exclusive(s, rd, 15, addr, 0);
7655 case 3: /* ldrexh */
7656 gen_load_exclusive(s, rd, 15, addr, 1);
7665 gen_store_exclusive(s, rd, rm, 15, addr, 2);
7667 case 1: /* strexd */
7668 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7670 case 2: /* strexb */
7671 gen_store_exclusive(s, rd, rm, 15, addr, 0);
7673 case 3: /* strexh */
7674 gen_store_exclusive(s, rd, rm, 15, addr, 1);
7680 tcg_temp_free_i32(addr);
7682 /* SWP instruction */
7685 /* ??? This is not really atomic. However we know
7686 we never have multiple CPUs running in parallel,
7687 so it is good enough. */
7688 addr = load_reg(s, rn);
7689 tmp = load_reg(s, rm);
7690 tmp2 = tcg_temp_new_i32();
7691 if (insn & (1 << 22)) {
7692 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7693 gen_aa32_st8(tmp, addr, IS_USER(s));
7695 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7696 gen_aa32_st32(tmp, addr, IS_USER(s));
7698 tcg_temp_free_i32(tmp);
7699 tcg_temp_free_i32(addr);
7700 store_reg(s, rd, tmp2);
7706 /* Misc load/store */
7707 rn = (insn >> 16) & 0xf;
7708 rd = (insn >> 12) & 0xf;
7709 addr = load_reg(s, rn);
7710 if (insn & (1 << 24))
7711 gen_add_datah_offset(s, insn, 0, addr);
7713 if (insn & (1 << 20)) {
7715 tmp = tcg_temp_new_i32();
7718 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7721 gen_aa32_ld8s(tmp, addr, IS_USER(s));
7725 gen_aa32_ld16s(tmp, addr, IS_USER(s));
7729 } else if (sh & 2) {
7734 tmp = load_reg(s, rd);
7735 gen_aa32_st32(tmp, addr, IS_USER(s));
7736 tcg_temp_free_i32(tmp);
7737 tcg_gen_addi_i32(addr, addr, 4);
7738 tmp = load_reg(s, rd + 1);
7739 gen_aa32_st32(tmp, addr, IS_USER(s));
7740 tcg_temp_free_i32(tmp);
7744 tmp = tcg_temp_new_i32();
7745 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7746 store_reg(s, rd, tmp);
7747 tcg_gen_addi_i32(addr, addr, 4);
7748 tmp = tcg_temp_new_i32();
7749 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7753 address_offset = -4;
7756 tmp = load_reg(s, rd);
7757 gen_aa32_st16(tmp, addr, IS_USER(s));
7758 tcg_temp_free_i32(tmp);
7761 /* Perform base writeback before the loaded value to
7762 ensure correct behavior with overlapping index registers.
7763 ldrd with base writeback is is undefined if the
7764 destination and index registers overlap. */
7765 if (!(insn & (1 << 24))) {
7766 gen_add_datah_offset(s, insn, address_offset, addr);
7767 store_reg(s, rn, addr);
7768 } else if (insn & (1 << 21)) {
7770 tcg_gen_addi_i32(addr, addr, address_offset);
7771 store_reg(s, rn, addr);
7773 tcg_temp_free_i32(addr);
7776 /* Complete the load. */
7777 store_reg(s, rd, tmp);
7786 if (insn & (1 << 4)) {
7788 /* Armv6 Media instructions. */
7790 rn = (insn >> 16) & 0xf;
7791 rd = (insn >> 12) & 0xf;
7792 rs = (insn >> 8) & 0xf;
7793 switch ((insn >> 23) & 3) {
7794 case 0: /* Parallel add/subtract. */
7795 op1 = (insn >> 20) & 7;
7796 tmp = load_reg(s, rn);
7797 tmp2 = load_reg(s, rm);
7798 sh = (insn >> 5) & 7;
7799 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7801 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7802 tcg_temp_free_i32(tmp2);
7803 store_reg(s, rd, tmp);
7806 if ((insn & 0x00700020) == 0) {
7807 /* Halfword pack. */
7808 tmp = load_reg(s, rn);
7809 tmp2 = load_reg(s, rm);
7810 shift = (insn >> 7) & 0x1f;
7811 if (insn & (1 << 6)) {
7815 tcg_gen_sari_i32(tmp2, tmp2, shift);
7816 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7817 tcg_gen_ext16u_i32(tmp2, tmp2);
7821 tcg_gen_shli_i32(tmp2, tmp2, shift);
7822 tcg_gen_ext16u_i32(tmp, tmp);
7823 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7825 tcg_gen_or_i32(tmp, tmp, tmp2);
7826 tcg_temp_free_i32(tmp2);
7827 store_reg(s, rd, tmp);
7828 } else if ((insn & 0x00200020) == 0x00200000) {
7830 tmp = load_reg(s, rm);
7831 shift = (insn >> 7) & 0x1f;
7832 if (insn & (1 << 6)) {
7835 tcg_gen_sari_i32(tmp, tmp, shift);
7837 tcg_gen_shli_i32(tmp, tmp, shift);
7839 sh = (insn >> 16) & 0x1f;
7840 tmp2 = tcg_const_i32(sh);
7841 if (insn & (1 << 22))
7842 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7844 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7845 tcg_temp_free_i32(tmp2);
7846 store_reg(s, rd, tmp);
7847 } else if ((insn & 0x00300fe0) == 0x00200f20) {
7849 tmp = load_reg(s, rm);
7850 sh = (insn >> 16) & 0x1f;
7851 tmp2 = tcg_const_i32(sh);
7852 if (insn & (1 << 22))
7853 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7855 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7856 tcg_temp_free_i32(tmp2);
7857 store_reg(s, rd, tmp);
7858 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7860 tmp = load_reg(s, rn);
7861 tmp2 = load_reg(s, rm);
7862 tmp3 = tcg_temp_new_i32();
7863 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7864 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7865 tcg_temp_free_i32(tmp3);
7866 tcg_temp_free_i32(tmp2);
7867 store_reg(s, rd, tmp);
7868 } else if ((insn & 0x000003e0) == 0x00000060) {
7869 tmp = load_reg(s, rm);
7870 shift = (insn >> 10) & 3;
7871 /* ??? In many cases it's not necessary to do a
7872 rotate, a shift is sufficient. */
7874 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7875 op1 = (insn >> 20) & 7;
7877 case 0: gen_sxtb16(tmp); break;
7878 case 2: gen_sxtb(tmp); break;
7879 case 3: gen_sxth(tmp); break;
7880 case 4: gen_uxtb16(tmp); break;
7881 case 6: gen_uxtb(tmp); break;
7882 case 7: gen_uxth(tmp); break;
7883 default: goto illegal_op;
7886 tmp2 = load_reg(s, rn);
7887 if ((op1 & 3) == 0) {
7888 gen_add16(tmp, tmp2);
7890 tcg_gen_add_i32(tmp, tmp, tmp2);
7891 tcg_temp_free_i32(tmp2);
7894 store_reg(s, rd, tmp);
7895 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7897 tmp = load_reg(s, rm);
7898 if (insn & (1 << 22)) {
7899 if (insn & (1 << 7)) {
7903 gen_helper_rbit(tmp, tmp);
7906 if (insn & (1 << 7))
7909 tcg_gen_bswap32_i32(tmp, tmp);
7911 store_reg(s, rd, tmp);
7916 case 2: /* Multiplies (Type 3). */
7917 switch ((insn >> 20) & 0x7) {
7919 if (((insn >> 6) ^ (insn >> 7)) & 1) {
7920 /* op2 not 00x or 11x : UNDEF */
7923 /* Signed multiply most significant [accumulate].
7924 (SMMUL, SMMLA, SMMLS) */
7925 tmp = load_reg(s, rm);
7926 tmp2 = load_reg(s, rs);
7927 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7930 tmp = load_reg(s, rd);
7931 if (insn & (1 << 6)) {
7932 tmp64 = gen_subq_msw(tmp64, tmp);
7934 tmp64 = gen_addq_msw(tmp64, tmp);
7937 if (insn & (1 << 5)) {
7938 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7940 tcg_gen_shri_i64(tmp64, tmp64, 32);
7941 tmp = tcg_temp_new_i32();
7942 tcg_gen_trunc_i64_i32(tmp, tmp64);
7943 tcg_temp_free_i64(tmp64);
7944 store_reg(s, rn, tmp);
7948 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7949 if (insn & (1 << 7)) {
7952 tmp = load_reg(s, rm);
7953 tmp2 = load_reg(s, rs);
7954 if (insn & (1 << 5))
7955 gen_swap_half(tmp2);
7956 gen_smul_dual(tmp, tmp2);
7957 if (insn & (1 << 6)) {
7958 /* This subtraction cannot overflow. */
7959 tcg_gen_sub_i32(tmp, tmp, tmp2);
7961 /* This addition cannot overflow 32 bits;
7962 * however it may overflow considered as a signed
7963 * operation, in which case we must set the Q flag.
7965 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7967 tcg_temp_free_i32(tmp2);
7968 if (insn & (1 << 22)) {
7969 /* smlald, smlsld */
7970 tmp64 = tcg_temp_new_i64();
7971 tcg_gen_ext_i32_i64(tmp64, tmp);
7972 tcg_temp_free_i32(tmp);
7973 gen_addq(s, tmp64, rd, rn);
7974 gen_storeq_reg(s, rd, rn, tmp64);
7975 tcg_temp_free_i64(tmp64);
7977 /* smuad, smusd, smlad, smlsd */
7980 tmp2 = load_reg(s, rd);
7981 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7982 tcg_temp_free_i32(tmp2);
7984 store_reg(s, rn, tmp);
7990 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7993 if (((insn >> 5) & 7) || (rd != 15)) {
7996 tmp = load_reg(s, rm);
7997 tmp2 = load_reg(s, rs);
7998 if (insn & (1 << 21)) {
7999 gen_helper_udiv(tmp, tmp, tmp2);
8001 gen_helper_sdiv(tmp, tmp, tmp2);
8003 tcg_temp_free_i32(tmp2);
8004 store_reg(s, rn, tmp);
8011 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8013 case 0: /* Unsigned sum of absolute differences. */
8015 tmp = load_reg(s, rm);
8016 tmp2 = load_reg(s, rs);
8017 gen_helper_usad8(tmp, tmp, tmp2);
8018 tcg_temp_free_i32(tmp2);
8020 tmp2 = load_reg(s, rd);
8021 tcg_gen_add_i32(tmp, tmp, tmp2);
8022 tcg_temp_free_i32(tmp2);
8024 store_reg(s, rn, tmp);
8026 case 0x20: case 0x24: case 0x28: case 0x2c:
8027 /* Bitfield insert/clear. */
8029 shift = (insn >> 7) & 0x1f;
8030 i = (insn >> 16) & 0x1f;
8033 tmp = tcg_temp_new_i32();
8034 tcg_gen_movi_i32(tmp, 0);
8036 tmp = load_reg(s, rm);
8039 tmp2 = load_reg(s, rd);
8040 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8041 tcg_temp_free_i32(tmp2);
8043 store_reg(s, rd, tmp);
8045 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8046 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8048 tmp = load_reg(s, rm);
8049 shift = (insn >> 7) & 0x1f;
8050 i = ((insn >> 16) & 0x1f) + 1;
8055 gen_ubfx(tmp, shift, (1u << i) - 1);
8057 gen_sbfx(tmp, shift, i);
8060 store_reg(s, rd, tmp);
8070 /* Check for undefined extension instructions
8071 * per the ARM Bible IE:
8072 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8074 sh = (0xf << 20) | (0xf << 4);
8075 if (op1 == 0x7 && ((insn & sh) == sh))
8079 /* load/store byte/word */
8080 rn = (insn >> 16) & 0xf;
8081 rd = (insn >> 12) & 0xf;
8082 tmp2 = load_reg(s, rn);
8083 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8084 if (insn & (1 << 24))
8085 gen_add_data_offset(s, insn, tmp2);
8086 if (insn & (1 << 20)) {
8088 tmp = tcg_temp_new_i32();
8089 if (insn & (1 << 22)) {
8090 gen_aa32_ld8u(tmp, tmp2, i);
8092 gen_aa32_ld32u(tmp, tmp2, i);
8096 tmp = load_reg(s, rd);
8097 if (insn & (1 << 22)) {
8098 gen_aa32_st8(tmp, tmp2, i);
8100 gen_aa32_st32(tmp, tmp2, i);
8102 tcg_temp_free_i32(tmp);
8104 if (!(insn & (1 << 24))) {
8105 gen_add_data_offset(s, insn, tmp2);
8106 store_reg(s, rn, tmp2);
8107 } else if (insn & (1 << 21)) {
8108 store_reg(s, rn, tmp2);
8110 tcg_temp_free_i32(tmp2);
8112 if (insn & (1 << 20)) {
8113 /* Complete the load. */
8114 store_reg_from_load(env, s, rd, tmp);
8120 int j, n, user, loaded_base;
8121 TCGv_i32 loaded_var;
8122 /* load/store multiple words */
8123 /* XXX: store correct base if write back */
8125 if (insn & (1 << 22)) {
8127 goto illegal_op; /* only usable in supervisor mode */
8129 if ((insn & (1 << 15)) == 0)
8132 rn = (insn >> 16) & 0xf;
8133 addr = load_reg(s, rn);
8135 /* compute total size */
8137 TCGV_UNUSED_I32(loaded_var);
8140 if (insn & (1 << i))
8143 /* XXX: test invalid n == 0 case ? */
8144 if (insn & (1 << 23)) {
8145 if (insn & (1 << 24)) {
8147 tcg_gen_addi_i32(addr, addr, 4);
8149 /* post increment */
8152 if (insn & (1 << 24)) {
8154 tcg_gen_addi_i32(addr, addr, -(n * 4));
8156 /* post decrement */
8158 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8163 if (insn & (1 << i)) {
8164 if (insn & (1 << 20)) {
8166 tmp = tcg_temp_new_i32();
8167 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8169 tmp2 = tcg_const_i32(i);
8170 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8171 tcg_temp_free_i32(tmp2);
8172 tcg_temp_free_i32(tmp);
8173 } else if (i == rn) {
8177 store_reg_from_load(env, s, i, tmp);
8182 /* special case: r15 = PC + 8 */
8183 val = (long)s->pc + 4;
8184 tmp = tcg_temp_new_i32();
8185 tcg_gen_movi_i32(tmp, val);
8187 tmp = tcg_temp_new_i32();
8188 tmp2 = tcg_const_i32(i);
8189 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8190 tcg_temp_free_i32(tmp2);
8192 tmp = load_reg(s, i);
8194 gen_aa32_st32(tmp, addr, IS_USER(s));
8195 tcg_temp_free_i32(tmp);
8198 /* no need to add after the last transfer */
8200 tcg_gen_addi_i32(addr, addr, 4);
8203 if (insn & (1 << 21)) {
8205 if (insn & (1 << 23)) {
8206 if (insn & (1 << 24)) {
8209 /* post increment */
8210 tcg_gen_addi_i32(addr, addr, 4);
8213 if (insn & (1 << 24)) {
8216 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8218 /* post decrement */
8219 tcg_gen_addi_i32(addr, addr, -(n * 4));
8222 store_reg(s, rn, addr);
8224 tcg_temp_free_i32(addr);
8227 store_reg(s, rn, loaded_var);
8229 if ((insn & (1 << 22)) && !user) {
8230 /* Restore CPSR from SPSR. */
8231 tmp = load_cpu_field(spsr);
8232 gen_set_cpsr(tmp, 0xffffffff);
8233 tcg_temp_free_i32(tmp);
8234 s->is_jmp = DISAS_UPDATE;
8243 /* branch (and link) */
8244 val = (int32_t)s->pc;
8245 if (insn & (1 << 24)) {
8246 tmp = tcg_temp_new_i32();
8247 tcg_gen_movi_i32(tmp, val);
8248 store_reg(s, 14, tmp);
8250 offset = sextract32(insn << 2, 0, 26);
8258 if (((insn >> 8) & 0xe) == 10) {
8260 if (disas_vfp_insn(env, s, insn)) {
8263 } else if (disas_coproc_insn(env, s, insn)) {
8270 gen_set_pc_im(s, s->pc);
8271 s->is_jmp = DISAS_SWI;
8275 gen_exception_insn(s, 4, EXCP_UDEF);
8281 /* Return true if this is a Thumb-2 logical op. */
8283 thumb2_logic_op(int op)
8288 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8289 then set condition code flags based on the result of the operation.
8290 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8291 to the high bit of T1.
8292 Returns zero if the opcode is valid. */
8295 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8296 TCGv_i32 t0, TCGv_i32 t1)
8303 tcg_gen_and_i32(t0, t0, t1);
8307 tcg_gen_andc_i32(t0, t0, t1);
8311 tcg_gen_or_i32(t0, t0, t1);
8315 tcg_gen_orc_i32(t0, t0, t1);
8319 tcg_gen_xor_i32(t0, t0, t1);
8324 gen_add_CC(t0, t0, t1);
8326 tcg_gen_add_i32(t0, t0, t1);
8330 gen_adc_CC(t0, t0, t1);
8336 gen_sbc_CC(t0, t0, t1);
8338 gen_sub_carry(t0, t0, t1);
8343 gen_sub_CC(t0, t0, t1);
8345 tcg_gen_sub_i32(t0, t0, t1);
8349 gen_sub_CC(t0, t1, t0);
8351 tcg_gen_sub_i32(t0, t1, t0);
8353 default: /* 5, 6, 7, 9, 12, 15. */
8359 gen_set_CF_bit31(t1);
8364 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8366 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8368 uint32_t insn, imm, shift, offset;
8369 uint32_t rd, rn, rm, rs;
8380 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8381 || arm_feature (env, ARM_FEATURE_M))) {
8382 /* Thumb-1 cores may need to treat bl and blx as a pair of
8383 16-bit instructions to get correct prefetch abort behavior. */
8385 if ((insn & (1 << 12)) == 0) {
8387 /* Second half of blx. */
8388 offset = ((insn & 0x7ff) << 1);
8389 tmp = load_reg(s, 14);
8390 tcg_gen_addi_i32(tmp, tmp, offset);
8391 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8393 tmp2 = tcg_temp_new_i32();
8394 tcg_gen_movi_i32(tmp2, s->pc | 1);
8395 store_reg(s, 14, tmp2);
8399 if (insn & (1 << 11)) {
8400 /* Second half of bl. */
8401 offset = ((insn & 0x7ff) << 1) | 1;
8402 tmp = load_reg(s, 14);
8403 tcg_gen_addi_i32(tmp, tmp, offset);
8405 tmp2 = tcg_temp_new_i32();
8406 tcg_gen_movi_i32(tmp2, s->pc | 1);
8407 store_reg(s, 14, tmp2);
8411 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8412 /* Instruction spans a page boundary. Implement it as two
8413 16-bit instructions in case the second half causes an
8415 offset = ((int32_t)insn << 21) >> 9;
8416 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8419 /* Fall through to 32-bit decode. */
8422 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8424 insn |= (uint32_t)insn_hw1 << 16;
8426 if ((insn & 0xf800e800) != 0xf000e800) {
8430 rn = (insn >> 16) & 0xf;
8431 rs = (insn >> 12) & 0xf;
8432 rd = (insn >> 8) & 0xf;
8434 switch ((insn >> 25) & 0xf) {
8435 case 0: case 1: case 2: case 3:
8436 /* 16-bit instructions. Should never happen. */
8439 if (insn & (1 << 22)) {
8440 /* Other load/store, table branch. */
8441 if (insn & 0x01200000) {
8442 /* Load/store doubleword. */
8444 addr = tcg_temp_new_i32();
8445 tcg_gen_movi_i32(addr, s->pc & ~3);
8447 addr = load_reg(s, rn);
8449 offset = (insn & 0xff) * 4;
8450 if ((insn & (1 << 23)) == 0)
8452 if (insn & (1 << 24)) {
8453 tcg_gen_addi_i32(addr, addr, offset);
8456 if (insn & (1 << 20)) {
8458 tmp = tcg_temp_new_i32();
8459 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8460 store_reg(s, rs, tmp);
8461 tcg_gen_addi_i32(addr, addr, 4);
8462 tmp = tcg_temp_new_i32();
8463 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8464 store_reg(s, rd, tmp);
8467 tmp = load_reg(s, rs);
8468 gen_aa32_st32(tmp, addr, IS_USER(s));
8469 tcg_temp_free_i32(tmp);
8470 tcg_gen_addi_i32(addr, addr, 4);
8471 tmp = load_reg(s, rd);
8472 gen_aa32_st32(tmp, addr, IS_USER(s));
8473 tcg_temp_free_i32(tmp);
8475 if (insn & (1 << 21)) {
8476 /* Base writeback. */
8479 tcg_gen_addi_i32(addr, addr, offset - 4);
8480 store_reg(s, rn, addr);
8482 tcg_temp_free_i32(addr);
8484 } else if ((insn & (1 << 23)) == 0) {
8485 /* Load/store exclusive word. */
8486 addr = tcg_temp_local_new_i32();
8487 load_reg_var(s, addr, rn);
8488 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8489 if (insn & (1 << 20)) {
8490 gen_load_exclusive(s, rs, 15, addr, 2);
8492 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8494 tcg_temp_free_i32(addr);
8495 } else if ((insn & (7 << 5)) == 0) {
8498 addr = tcg_temp_new_i32();
8499 tcg_gen_movi_i32(addr, s->pc);
8501 addr = load_reg(s, rn);
8503 tmp = load_reg(s, rm);
8504 tcg_gen_add_i32(addr, addr, tmp);
8505 if (insn & (1 << 4)) {
8507 tcg_gen_add_i32(addr, addr, tmp);
8508 tcg_temp_free_i32(tmp);
8509 tmp = tcg_temp_new_i32();
8510 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8512 tcg_temp_free_i32(tmp);
8513 tmp = tcg_temp_new_i32();
8514 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8516 tcg_temp_free_i32(addr);
8517 tcg_gen_shli_i32(tmp, tmp, 1);
8518 tcg_gen_addi_i32(tmp, tmp, s->pc);
8519 store_reg(s, 15, tmp);
8521 int op2 = (insn >> 6) & 0x3;
8522 op = (insn >> 4) & 0x3;
8527 /* Load/store exclusive byte/halfword/doubleword */
8534 /* Load-acquire/store-release */
8540 /* Load-acquire/store-release exclusive */
8544 addr = tcg_temp_local_new_i32();
8545 load_reg_var(s, addr, rn);
8547 if (insn & (1 << 20)) {
8548 tmp = tcg_temp_new_i32();
8551 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8554 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8557 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8562 store_reg(s, rs, tmp);
8564 tmp = load_reg(s, rs);
8567 gen_aa32_st8(tmp, addr, IS_USER(s));
8570 gen_aa32_st16(tmp, addr, IS_USER(s));
8573 gen_aa32_st32(tmp, addr, IS_USER(s));
8578 tcg_temp_free_i32(tmp);
8580 } else if (insn & (1 << 20)) {
8581 gen_load_exclusive(s, rs, rd, addr, op);
8583 gen_store_exclusive(s, rm, rs, rd, addr, op);
8585 tcg_temp_free_i32(addr);
8588 /* Load/store multiple, RFE, SRS. */
8589 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8590 /* RFE, SRS: not available in user mode or on M profile */
8591 if (IS_USER(s) || IS_M(env)) {
8594 if (insn & (1 << 20)) {
8596 addr = load_reg(s, rn);
8597 if ((insn & (1 << 24)) == 0)
8598 tcg_gen_addi_i32(addr, addr, -8);
8599 /* Load PC into tmp and CPSR into tmp2. */
8600 tmp = tcg_temp_new_i32();
8601 gen_aa32_ld32u(tmp, addr, 0);
8602 tcg_gen_addi_i32(addr, addr, 4);
8603 tmp2 = tcg_temp_new_i32();
8604 gen_aa32_ld32u(tmp2, addr, 0);
8605 if (insn & (1 << 21)) {
8606 /* Base writeback. */
8607 if (insn & (1 << 24)) {
8608 tcg_gen_addi_i32(addr, addr, 4);
8610 tcg_gen_addi_i32(addr, addr, -4);
8612 store_reg(s, rn, addr);
8614 tcg_temp_free_i32(addr);
8616 gen_rfe(s, tmp, tmp2);
8619 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8623 int i, loaded_base = 0;
8624 TCGv_i32 loaded_var;
8625 /* Load/store multiple. */
8626 addr = load_reg(s, rn);
8628 for (i = 0; i < 16; i++) {
8629 if (insn & (1 << i))
8632 if (insn & (1 << 24)) {
8633 tcg_gen_addi_i32(addr, addr, -offset);
8636 TCGV_UNUSED_I32(loaded_var);
8637 for (i = 0; i < 16; i++) {
8638 if ((insn & (1 << i)) == 0)
8640 if (insn & (1 << 20)) {
8642 tmp = tcg_temp_new_i32();
8643 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8646 } else if (i == rn) {
8650 store_reg(s, i, tmp);
8654 tmp = load_reg(s, i);
8655 gen_aa32_st32(tmp, addr, IS_USER(s));
8656 tcg_temp_free_i32(tmp);
8658 tcg_gen_addi_i32(addr, addr, 4);
8661 store_reg(s, rn, loaded_var);
8663 if (insn & (1 << 21)) {
8664 /* Base register writeback. */
8665 if (insn & (1 << 24)) {
8666 tcg_gen_addi_i32(addr, addr, -offset);
8668 /* Fault if writeback register is in register list. */
8669 if (insn & (1 << rn))
8671 store_reg(s, rn, addr);
8673 tcg_temp_free_i32(addr);
8680 op = (insn >> 21) & 0xf;
8682 /* Halfword pack. */
8683 tmp = load_reg(s, rn);
8684 tmp2 = load_reg(s, rm);
8685 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8686 if (insn & (1 << 5)) {
8690 tcg_gen_sari_i32(tmp2, tmp2, shift);
8691 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8692 tcg_gen_ext16u_i32(tmp2, tmp2);
8696 tcg_gen_shli_i32(tmp2, tmp2, shift);
8697 tcg_gen_ext16u_i32(tmp, tmp);
8698 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8700 tcg_gen_or_i32(tmp, tmp, tmp2);
8701 tcg_temp_free_i32(tmp2);
8702 store_reg(s, rd, tmp);
8704 /* Data processing register constant shift. */
8706 tmp = tcg_temp_new_i32();
8707 tcg_gen_movi_i32(tmp, 0);
8709 tmp = load_reg(s, rn);
8711 tmp2 = load_reg(s, rm);
8713 shiftop = (insn >> 4) & 3;
8714 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8715 conds = (insn & (1 << 20)) != 0;
8716 logic_cc = (conds && thumb2_logic_op(op));
8717 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8718 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8720 tcg_temp_free_i32(tmp2);
8722 store_reg(s, rd, tmp);
8724 tcg_temp_free_i32(tmp);
8728 case 13: /* Misc data processing. */
8729 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8730 if (op < 4 && (insn & 0xf000) != 0xf000)
8733 case 0: /* Register controlled shift. */
8734 tmp = load_reg(s, rn);
8735 tmp2 = load_reg(s, rm);
8736 if ((insn & 0x70) != 0)
8738 op = (insn >> 21) & 3;
8739 logic_cc = (insn & (1 << 20)) != 0;
8740 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8743 store_reg_bx(env, s, rd, tmp);
8745 case 1: /* Sign/zero extend. */
8746 tmp = load_reg(s, rm);
8747 shift = (insn >> 4) & 3;
8748 /* ??? In many cases it's not necessary to do a
8749 rotate, a shift is sufficient. */
8751 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8752 op = (insn >> 20) & 7;
8754 case 0: gen_sxth(tmp); break;
8755 case 1: gen_uxth(tmp); break;
8756 case 2: gen_sxtb16(tmp); break;
8757 case 3: gen_uxtb16(tmp); break;
8758 case 4: gen_sxtb(tmp); break;
8759 case 5: gen_uxtb(tmp); break;
8760 default: goto illegal_op;
8763 tmp2 = load_reg(s, rn);
8764 if ((op >> 1) == 1) {
8765 gen_add16(tmp, tmp2);
8767 tcg_gen_add_i32(tmp, tmp, tmp2);
8768 tcg_temp_free_i32(tmp2);
8771 store_reg(s, rd, tmp);
8773 case 2: /* SIMD add/subtract. */
8774 op = (insn >> 20) & 7;
8775 shift = (insn >> 4) & 7;
8776 if ((op & 3) == 3 || (shift & 3) == 3)
8778 tmp = load_reg(s, rn);
8779 tmp2 = load_reg(s, rm);
8780 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8781 tcg_temp_free_i32(tmp2);
8782 store_reg(s, rd, tmp);
8784 case 3: /* Other data processing. */
8785 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8787 /* Saturating add/subtract. */
8788 tmp = load_reg(s, rn);
8789 tmp2 = load_reg(s, rm);
8791 gen_helper_double_saturate(tmp, cpu_env, tmp);
8793 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8795 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8796 tcg_temp_free_i32(tmp2);
8798 tmp = load_reg(s, rn);
8800 case 0x0a: /* rbit */
8801 gen_helper_rbit(tmp, tmp);
8803 case 0x08: /* rev */
8804 tcg_gen_bswap32_i32(tmp, tmp);
8806 case 0x09: /* rev16 */
8809 case 0x0b: /* revsh */
8812 case 0x10: /* sel */
8813 tmp2 = load_reg(s, rm);
8814 tmp3 = tcg_temp_new_i32();
8815 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8816 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8817 tcg_temp_free_i32(tmp3);
8818 tcg_temp_free_i32(tmp2);
8820 case 0x18: /* clz */
8821 gen_helper_clz(tmp, tmp);
8827 store_reg(s, rd, tmp);
8829 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8830 op = (insn >> 4) & 0xf;
8831 tmp = load_reg(s, rn);
8832 tmp2 = load_reg(s, rm);
8833 switch ((insn >> 20) & 7) {
8834 case 0: /* 32 x 32 -> 32 */
8835 tcg_gen_mul_i32(tmp, tmp, tmp2);
8836 tcg_temp_free_i32(tmp2);
8838 tmp2 = load_reg(s, rs);
8840 tcg_gen_sub_i32(tmp, tmp2, tmp);
8842 tcg_gen_add_i32(tmp, tmp, tmp2);
8843 tcg_temp_free_i32(tmp2);
8846 case 1: /* 16 x 16 -> 32 */
8847 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8848 tcg_temp_free_i32(tmp2);
8850 tmp2 = load_reg(s, rs);
8851 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8852 tcg_temp_free_i32(tmp2);
8855 case 2: /* Dual multiply add. */
8856 case 4: /* Dual multiply subtract. */
8858 gen_swap_half(tmp2);
8859 gen_smul_dual(tmp, tmp2);
8860 if (insn & (1 << 22)) {
8861 /* This subtraction cannot overflow. */
8862 tcg_gen_sub_i32(tmp, tmp, tmp2);
8864 /* This addition cannot overflow 32 bits;
8865 * however it may overflow considered as a signed
8866 * operation, in which case we must set the Q flag.
8868 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8870 tcg_temp_free_i32(tmp2);
8873 tmp2 = load_reg(s, rs);
8874 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8875 tcg_temp_free_i32(tmp2);
8878 case 3: /* 32 * 16 -> 32msb */
8880 tcg_gen_sari_i32(tmp2, tmp2, 16);
8883 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8884 tcg_gen_shri_i64(tmp64, tmp64, 16);
8885 tmp = tcg_temp_new_i32();
8886 tcg_gen_trunc_i64_i32(tmp, tmp64);
8887 tcg_temp_free_i64(tmp64);
8890 tmp2 = load_reg(s, rs);
8891 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8892 tcg_temp_free_i32(tmp2);
8895 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8896 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8898 tmp = load_reg(s, rs);
8899 if (insn & (1 << 20)) {
8900 tmp64 = gen_addq_msw(tmp64, tmp);
8902 tmp64 = gen_subq_msw(tmp64, tmp);
8905 if (insn & (1 << 4)) {
8906 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8908 tcg_gen_shri_i64(tmp64, tmp64, 32);
8909 tmp = tcg_temp_new_i32();
8910 tcg_gen_trunc_i64_i32(tmp, tmp64);
8911 tcg_temp_free_i64(tmp64);
8913 case 7: /* Unsigned sum of absolute differences. */
8914 gen_helper_usad8(tmp, tmp, tmp2);
8915 tcg_temp_free_i32(tmp2);
8917 tmp2 = load_reg(s, rs);
8918 tcg_gen_add_i32(tmp, tmp, tmp2);
8919 tcg_temp_free_i32(tmp2);
8923 store_reg(s, rd, tmp);
8925 case 6: case 7: /* 64-bit multiply, Divide. */
8926 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8927 tmp = load_reg(s, rn);
8928 tmp2 = load_reg(s, rm);
8929 if ((op & 0x50) == 0x10) {
8931 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8935 gen_helper_udiv(tmp, tmp, tmp2);
8937 gen_helper_sdiv(tmp, tmp, tmp2);
8938 tcg_temp_free_i32(tmp2);
8939 store_reg(s, rd, tmp);
8940 } else if ((op & 0xe) == 0xc) {
8941 /* Dual multiply accumulate long. */
8943 gen_swap_half(tmp2);
8944 gen_smul_dual(tmp, tmp2);
8946 tcg_gen_sub_i32(tmp, tmp, tmp2);
8948 tcg_gen_add_i32(tmp, tmp, tmp2);
8950 tcg_temp_free_i32(tmp2);
8952 tmp64 = tcg_temp_new_i64();
8953 tcg_gen_ext_i32_i64(tmp64, tmp);
8954 tcg_temp_free_i32(tmp);
8955 gen_addq(s, tmp64, rs, rd);
8956 gen_storeq_reg(s, rs, rd, tmp64);
8957 tcg_temp_free_i64(tmp64);
8960 /* Unsigned 64-bit multiply */
8961 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8965 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8966 tcg_temp_free_i32(tmp2);
8967 tmp64 = tcg_temp_new_i64();
8968 tcg_gen_ext_i32_i64(tmp64, tmp);
8969 tcg_temp_free_i32(tmp);
8971 /* Signed 64-bit multiply */
8972 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8977 gen_addq_lo(s, tmp64, rs);
8978 gen_addq_lo(s, tmp64, rd);
8979 } else if (op & 0x40) {
8980 /* 64-bit accumulate. */
8981 gen_addq(s, tmp64, rs, rd);
8983 gen_storeq_reg(s, rs, rd, tmp64);
8984 tcg_temp_free_i64(tmp64);
8989 case 6: case 7: case 14: case 15:
8991 if (((insn >> 24) & 3) == 3) {
8992 /* Translate into the equivalent ARM encoding. */
8993 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8994 if (disas_neon_data_insn(env, s, insn))
8996 } else if (((insn >> 8) & 0xe) == 10) {
8997 if (disas_vfp_insn(env, s, insn)) {
9001 if (insn & (1 << 28))
9003 if (disas_coproc_insn (env, s, insn))
9007 case 8: case 9: case 10: case 11:
9008 if (insn & (1 << 15)) {
9009 /* Branches, misc control. */
9010 if (insn & 0x5000) {
9011 /* Unconditional branch. */
9012 /* signextend(hw1[10:0]) -> offset[:12]. */
9013 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9014 /* hw1[10:0] -> offset[11:1]. */
9015 offset |= (insn & 0x7ff) << 1;
9016 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9017 offset[24:22] already have the same value because of the
9018 sign extension above. */
9019 offset ^= ((~insn) & (1 << 13)) << 10;
9020 offset ^= ((~insn) & (1 << 11)) << 11;
9022 if (insn & (1 << 14)) {
9023 /* Branch and link. */
9024 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9028 if (insn & (1 << 12)) {
9033 offset &= ~(uint32_t)2;
9034 /* thumb2 bx, no need to check */
9035 gen_bx_im(s, offset);
9037 } else if (((insn >> 23) & 7) == 7) {
9039 if (insn & (1 << 13))
9042 if (insn & (1 << 26)) {
9043 /* Secure monitor call (v6Z) */
9044 qemu_log_mask(LOG_UNIMP,
9045 "arm: unimplemented secure monitor call\n");
9046 goto illegal_op; /* not implemented. */
9048 op = (insn >> 20) & 7;
9050 case 0: /* msr cpsr. */
9052 tmp = load_reg(s, rn);
9053 addr = tcg_const_i32(insn & 0xff);
9054 gen_helper_v7m_msr(cpu_env, addr, tmp);
9055 tcg_temp_free_i32(addr);
9056 tcg_temp_free_i32(tmp);
9061 case 1: /* msr spsr. */
9064 tmp = load_reg(s, rn);
9066 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9070 case 2: /* cps, nop-hint. */
9071 if (((insn >> 8) & 7) == 0) {
9072 gen_nop_hint(s, insn & 0xff);
9074 /* Implemented as NOP in user mode. */
9079 if (insn & (1 << 10)) {
9080 if (insn & (1 << 7))
9082 if (insn & (1 << 6))
9084 if (insn & (1 << 5))
9086 if (insn & (1 << 9))
9087 imm = CPSR_A | CPSR_I | CPSR_F;
9089 if (insn & (1 << 8)) {
9091 imm |= (insn & 0x1f);
9094 gen_set_psr_im(s, offset, 0, imm);
9097 case 3: /* Special control operations. */
9099 op = (insn >> 4) & 0xf;
9107 /* These execute as NOPs. */
9114 /* Trivial implementation equivalent to bx. */
9115 tmp = load_reg(s, rn);
9118 case 5: /* Exception return. */
9122 if (rn != 14 || rd != 15) {
9125 tmp = load_reg(s, rn);
9126 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9127 gen_exception_return(s, tmp);
9129 case 6: /* mrs cpsr. */
9130 tmp = tcg_temp_new_i32();
9132 addr = tcg_const_i32(insn & 0xff);
9133 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9134 tcg_temp_free_i32(addr);
9136 gen_helper_cpsr_read(tmp, cpu_env);
9138 store_reg(s, rd, tmp);
9140 case 7: /* mrs spsr. */
9141 /* Not accessible in user mode. */
9142 if (IS_USER(s) || IS_M(env))
9144 tmp = load_cpu_field(spsr);
9145 store_reg(s, rd, tmp);
9150 /* Conditional branch. */
9151 op = (insn >> 22) & 0xf;
9152 /* Generate a conditional jump to next instruction. */
9153 s->condlabel = gen_new_label();
9154 arm_gen_test_cc(op ^ 1, s->condlabel);
9157 /* offset[11:1] = insn[10:0] */
9158 offset = (insn & 0x7ff) << 1;
9159 /* offset[17:12] = insn[21:16]. */
9160 offset |= (insn & 0x003f0000) >> 4;
9161 /* offset[31:20] = insn[26]. */
9162 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9163 /* offset[18] = insn[13]. */
9164 offset |= (insn & (1 << 13)) << 5;
9165 /* offset[19] = insn[11]. */
9166 offset |= (insn & (1 << 11)) << 8;
9168 /* jump to the offset */
9169 gen_jmp(s, s->pc + offset);
9172 /* Data processing immediate. */
9173 if (insn & (1 << 25)) {
9174 if (insn & (1 << 24)) {
9175 if (insn & (1 << 20))
9177 /* Bitfield/Saturate. */
9178 op = (insn >> 21) & 7;
9180 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9182 tmp = tcg_temp_new_i32();
9183 tcg_gen_movi_i32(tmp, 0);
9185 tmp = load_reg(s, rn);
9188 case 2: /* Signed bitfield extract. */
9190 if (shift + imm > 32)
9193 gen_sbfx(tmp, shift, imm);
9195 case 6: /* Unsigned bitfield extract. */
9197 if (shift + imm > 32)
9200 gen_ubfx(tmp, shift, (1u << imm) - 1);
9202 case 3: /* Bitfield insert/clear. */
9205 imm = imm + 1 - shift;
9207 tmp2 = load_reg(s, rd);
9208 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9209 tcg_temp_free_i32(tmp2);
9214 default: /* Saturate. */
9217 tcg_gen_sari_i32(tmp, tmp, shift);
9219 tcg_gen_shli_i32(tmp, tmp, shift);
9221 tmp2 = tcg_const_i32(imm);
9224 if ((op & 1) && shift == 0)
9225 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9227 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9230 if ((op & 1) && shift == 0)
9231 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9233 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9235 tcg_temp_free_i32(tmp2);
9238 store_reg(s, rd, tmp);
9240 imm = ((insn & 0x04000000) >> 15)
9241 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9242 if (insn & (1 << 22)) {
9243 /* 16-bit immediate. */
9244 imm |= (insn >> 4) & 0xf000;
9245 if (insn & (1 << 23)) {
9247 tmp = load_reg(s, rd);
9248 tcg_gen_ext16u_i32(tmp, tmp);
9249 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9252 tmp = tcg_temp_new_i32();
9253 tcg_gen_movi_i32(tmp, imm);
9256 /* Add/sub 12-bit immediate. */
9258 offset = s->pc & ~(uint32_t)3;
9259 if (insn & (1 << 23))
9263 tmp = tcg_temp_new_i32();
9264 tcg_gen_movi_i32(tmp, offset);
9266 tmp = load_reg(s, rn);
9267 if (insn & (1 << 23))
9268 tcg_gen_subi_i32(tmp, tmp, imm);
9270 tcg_gen_addi_i32(tmp, tmp, imm);
9273 store_reg(s, rd, tmp);
9276 int shifter_out = 0;
9277 /* modified 12-bit immediate. */
9278 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9279 imm = (insn & 0xff);
9282 /* Nothing to do. */
9284 case 1: /* 00XY00XY */
9287 case 2: /* XY00XY00 */
9291 case 3: /* XYXYXYXY */
9295 default: /* Rotated constant. */
9296 shift = (shift << 1) | (imm >> 7);
9298 imm = imm << (32 - shift);
9302 tmp2 = tcg_temp_new_i32();
9303 tcg_gen_movi_i32(tmp2, imm);
9304 rn = (insn >> 16) & 0xf;
9306 tmp = tcg_temp_new_i32();
9307 tcg_gen_movi_i32(tmp, 0);
9309 tmp = load_reg(s, rn);
9311 op = (insn >> 21) & 0xf;
9312 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9313 shifter_out, tmp, tmp2))
9315 tcg_temp_free_i32(tmp2);
9316 rd = (insn >> 8) & 0xf;
9318 store_reg(s, rd, tmp);
9320 tcg_temp_free_i32(tmp);
9325 case 12: /* Load/store single data item. */
9330 if ((insn & 0x01100000) == 0x01000000) {
9331 if (disas_neon_ls_insn(env, s, insn))
9335 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9337 if (!(insn & (1 << 20))) {
9341 /* Byte or halfword load space with dest == r15 : memory hints.
9342 * Catch them early so we don't emit pointless addressing code.
9343 * This space is a mix of:
9344 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9345 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9347 * unallocated hints, which must be treated as NOPs
9348 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9349 * which is easiest for the decoding logic
9350 * Some space which must UNDEF
9352 int op1 = (insn >> 23) & 3;
9353 int op2 = (insn >> 6) & 0x3f;
9358 /* UNPREDICTABLE, unallocated hint or
9359 * PLD/PLDW/PLI (literal)
9364 return 0; /* PLD/PLDW/PLI or unallocated hint */
9366 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9367 return 0; /* PLD/PLDW/PLI or unallocated hint */
9369 /* UNDEF space, or an UNPREDICTABLE */
9375 addr = tcg_temp_new_i32();
9377 /* s->pc has already been incremented by 4. */
9378 imm = s->pc & 0xfffffffc;
9379 if (insn & (1 << 23))
9380 imm += insn & 0xfff;
9382 imm -= insn & 0xfff;
9383 tcg_gen_movi_i32(addr, imm);
9385 addr = load_reg(s, rn);
9386 if (insn & (1 << 23)) {
9387 /* Positive offset. */
9389 tcg_gen_addi_i32(addr, addr, imm);
9392 switch ((insn >> 8) & 0xf) {
9393 case 0x0: /* Shifted Register. */
9394 shift = (insn >> 4) & 0xf;
9396 tcg_temp_free_i32(addr);
9399 tmp = load_reg(s, rm);
9401 tcg_gen_shli_i32(tmp, tmp, shift);
9402 tcg_gen_add_i32(addr, addr, tmp);
9403 tcg_temp_free_i32(tmp);
9405 case 0xc: /* Negative offset. */
9406 tcg_gen_addi_i32(addr, addr, -imm);
9408 case 0xe: /* User privilege. */
9409 tcg_gen_addi_i32(addr, addr, imm);
9412 case 0x9: /* Post-decrement. */
9415 case 0xb: /* Post-increment. */
9419 case 0xd: /* Pre-decrement. */
9422 case 0xf: /* Pre-increment. */
9423 tcg_gen_addi_i32(addr, addr, imm);
9427 tcg_temp_free_i32(addr);
9432 if (insn & (1 << 20)) {
9434 tmp = tcg_temp_new_i32();
9437 gen_aa32_ld8u(tmp, addr, user);
9440 gen_aa32_ld8s(tmp, addr, user);
9443 gen_aa32_ld16u(tmp, addr, user);
9446 gen_aa32_ld16s(tmp, addr, user);
9449 gen_aa32_ld32u(tmp, addr, user);
9452 tcg_temp_free_i32(tmp);
9453 tcg_temp_free_i32(addr);
9459 store_reg(s, rs, tmp);
9463 tmp = load_reg(s, rs);
9466 gen_aa32_st8(tmp, addr, user);
9469 gen_aa32_st16(tmp, addr, user);
9472 gen_aa32_st32(tmp, addr, user);
9475 tcg_temp_free_i32(tmp);
9476 tcg_temp_free_i32(addr);
9479 tcg_temp_free_i32(tmp);
9482 tcg_gen_addi_i32(addr, addr, imm);
9484 store_reg(s, rn, addr);
9486 tcg_temp_free_i32(addr);
9498 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9500 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9507 if (s->condexec_mask) {
9508 cond = s->condexec_cond;
9509 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9510 s->condlabel = gen_new_label();
9511 arm_gen_test_cc(cond ^ 1, s->condlabel);
9516 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9519 switch (insn >> 12) {
9523 op = (insn >> 11) & 3;
9526 rn = (insn >> 3) & 7;
9527 tmp = load_reg(s, rn);
9528 if (insn & (1 << 10)) {
9530 tmp2 = tcg_temp_new_i32();
9531 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9534 rm = (insn >> 6) & 7;
9535 tmp2 = load_reg(s, rm);
9537 if (insn & (1 << 9)) {
9538 if (s->condexec_mask)
9539 tcg_gen_sub_i32(tmp, tmp, tmp2);
9541 gen_sub_CC(tmp, tmp, tmp2);
9543 if (s->condexec_mask)
9544 tcg_gen_add_i32(tmp, tmp, tmp2);
9546 gen_add_CC(tmp, tmp, tmp2);
9548 tcg_temp_free_i32(tmp2);
9549 store_reg(s, rd, tmp);
9551 /* shift immediate */
9552 rm = (insn >> 3) & 7;
9553 shift = (insn >> 6) & 0x1f;
9554 tmp = load_reg(s, rm);
9555 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9556 if (!s->condexec_mask)
9558 store_reg(s, rd, tmp);
9562 /* arithmetic large immediate */
9563 op = (insn >> 11) & 3;
9564 rd = (insn >> 8) & 0x7;
9565 if (op == 0) { /* mov */
9566 tmp = tcg_temp_new_i32();
9567 tcg_gen_movi_i32(tmp, insn & 0xff);
9568 if (!s->condexec_mask)
9570 store_reg(s, rd, tmp);
9572 tmp = load_reg(s, rd);
9573 tmp2 = tcg_temp_new_i32();
9574 tcg_gen_movi_i32(tmp2, insn & 0xff);
9577 gen_sub_CC(tmp, tmp, tmp2);
9578 tcg_temp_free_i32(tmp);
9579 tcg_temp_free_i32(tmp2);
9582 if (s->condexec_mask)
9583 tcg_gen_add_i32(tmp, tmp, tmp2);
9585 gen_add_CC(tmp, tmp, tmp2);
9586 tcg_temp_free_i32(tmp2);
9587 store_reg(s, rd, tmp);
9590 if (s->condexec_mask)
9591 tcg_gen_sub_i32(tmp, tmp, tmp2);
9593 gen_sub_CC(tmp, tmp, tmp2);
9594 tcg_temp_free_i32(tmp2);
9595 store_reg(s, rd, tmp);
9601 if (insn & (1 << 11)) {
9602 rd = (insn >> 8) & 7;
9603 /* load pc-relative. Bit 1 of PC is ignored. */
9604 val = s->pc + 2 + ((insn & 0xff) * 4);
9605 val &= ~(uint32_t)2;
9606 addr = tcg_temp_new_i32();
9607 tcg_gen_movi_i32(addr, val);
9608 tmp = tcg_temp_new_i32();
9609 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9610 tcg_temp_free_i32(addr);
9611 store_reg(s, rd, tmp);
9614 if (insn & (1 << 10)) {
9615 /* data processing extended or blx */
9616 rd = (insn & 7) | ((insn >> 4) & 8);
9617 rm = (insn >> 3) & 0xf;
9618 op = (insn >> 8) & 3;
9621 tmp = load_reg(s, rd);
9622 tmp2 = load_reg(s, rm);
9623 tcg_gen_add_i32(tmp, tmp, tmp2);
9624 tcg_temp_free_i32(tmp2);
9625 store_reg(s, rd, tmp);
9628 tmp = load_reg(s, rd);
9629 tmp2 = load_reg(s, rm);
9630 gen_sub_CC(tmp, tmp, tmp2);
9631 tcg_temp_free_i32(tmp2);
9632 tcg_temp_free_i32(tmp);
9634 case 2: /* mov/cpy */
9635 tmp = load_reg(s, rm);
9636 store_reg(s, rd, tmp);
9638 case 3:/* branch [and link] exchange thumb register */
9639 tmp = load_reg(s, rm);
9640 if (insn & (1 << 7)) {
9642 val = (uint32_t)s->pc | 1;
9643 tmp2 = tcg_temp_new_i32();
9644 tcg_gen_movi_i32(tmp2, val);
9645 store_reg(s, 14, tmp2);
9647 /* already thumb, no need to check */
9654 /* data processing register */
9656 rm = (insn >> 3) & 7;
9657 op = (insn >> 6) & 0xf;
9658 if (op == 2 || op == 3 || op == 4 || op == 7) {
9659 /* the shift/rotate ops want the operands backwards */
9668 if (op == 9) { /* neg */
9669 tmp = tcg_temp_new_i32();
9670 tcg_gen_movi_i32(tmp, 0);
9671 } else if (op != 0xf) { /* mvn doesn't read its first operand */
9672 tmp = load_reg(s, rd);
9674 TCGV_UNUSED_I32(tmp);
9677 tmp2 = load_reg(s, rm);
9680 tcg_gen_and_i32(tmp, tmp, tmp2);
9681 if (!s->condexec_mask)
9685 tcg_gen_xor_i32(tmp, tmp, tmp2);
9686 if (!s->condexec_mask)
9690 if (s->condexec_mask) {
9691 gen_shl(tmp2, tmp2, tmp);
9693 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9698 if (s->condexec_mask) {
9699 gen_shr(tmp2, tmp2, tmp);
9701 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9706 if (s->condexec_mask) {
9707 gen_sar(tmp2, tmp2, tmp);
9709 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9714 if (s->condexec_mask) {
9717 gen_adc_CC(tmp, tmp, tmp2);
9721 if (s->condexec_mask) {
9722 gen_sub_carry(tmp, tmp, tmp2);
9724 gen_sbc_CC(tmp, tmp, tmp2);
9728 if (s->condexec_mask) {
9729 tcg_gen_andi_i32(tmp, tmp, 0x1f);
9730 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9732 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9737 tcg_gen_and_i32(tmp, tmp, tmp2);
9742 if (s->condexec_mask)
9743 tcg_gen_neg_i32(tmp, tmp2);
9745 gen_sub_CC(tmp, tmp, tmp2);
9748 gen_sub_CC(tmp, tmp, tmp2);
9752 gen_add_CC(tmp, tmp, tmp2);
9756 tcg_gen_or_i32(tmp, tmp, tmp2);
9757 if (!s->condexec_mask)
9761 tcg_gen_mul_i32(tmp, tmp, tmp2);
9762 if (!s->condexec_mask)
9766 tcg_gen_andc_i32(tmp, tmp, tmp2);
9767 if (!s->condexec_mask)
9771 tcg_gen_not_i32(tmp2, tmp2);
9772 if (!s->condexec_mask)
9780 store_reg(s, rm, tmp2);
9782 tcg_temp_free_i32(tmp);
9784 store_reg(s, rd, tmp);
9785 tcg_temp_free_i32(tmp2);
9788 tcg_temp_free_i32(tmp);
9789 tcg_temp_free_i32(tmp2);
9794 /* load/store register offset. */
9796 rn = (insn >> 3) & 7;
9797 rm = (insn >> 6) & 7;
9798 op = (insn >> 9) & 7;
9799 addr = load_reg(s, rn);
9800 tmp = load_reg(s, rm);
9801 tcg_gen_add_i32(addr, addr, tmp);
9802 tcg_temp_free_i32(tmp);
9804 if (op < 3) { /* store */
9805 tmp = load_reg(s, rd);
9807 tmp = tcg_temp_new_i32();
9812 gen_aa32_st32(tmp, addr, IS_USER(s));
9815 gen_aa32_st16(tmp, addr, IS_USER(s));
9818 gen_aa32_st8(tmp, addr, IS_USER(s));
9821 gen_aa32_ld8s(tmp, addr, IS_USER(s));
9824 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9827 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9830 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9833 gen_aa32_ld16s(tmp, addr, IS_USER(s));
9836 if (op >= 3) { /* load */
9837 store_reg(s, rd, tmp);
9839 tcg_temp_free_i32(tmp);
9841 tcg_temp_free_i32(addr);
9845 /* load/store word immediate offset */
9847 rn = (insn >> 3) & 7;
9848 addr = load_reg(s, rn);
9849 val = (insn >> 4) & 0x7c;
9850 tcg_gen_addi_i32(addr, addr, val);
9852 if (insn & (1 << 11)) {
9854 tmp = tcg_temp_new_i32();
9855 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9856 store_reg(s, rd, tmp);
9859 tmp = load_reg(s, rd);
9860 gen_aa32_st32(tmp, addr, IS_USER(s));
9861 tcg_temp_free_i32(tmp);
9863 tcg_temp_free_i32(addr);
9867 /* load/store byte immediate offset */
9869 rn = (insn >> 3) & 7;
9870 addr = load_reg(s, rn);
9871 val = (insn >> 6) & 0x1f;
9872 tcg_gen_addi_i32(addr, addr, val);
9874 if (insn & (1 << 11)) {
9876 tmp = tcg_temp_new_i32();
9877 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9878 store_reg(s, rd, tmp);
9881 tmp = load_reg(s, rd);
9882 gen_aa32_st8(tmp, addr, IS_USER(s));
9883 tcg_temp_free_i32(tmp);
9885 tcg_temp_free_i32(addr);
9889 /* load/store halfword immediate offset */
9891 rn = (insn >> 3) & 7;
9892 addr = load_reg(s, rn);
9893 val = (insn >> 5) & 0x3e;
9894 tcg_gen_addi_i32(addr, addr, val);
9896 if (insn & (1 << 11)) {
9898 tmp = tcg_temp_new_i32();
9899 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9900 store_reg(s, rd, tmp);
9903 tmp = load_reg(s, rd);
9904 gen_aa32_st16(tmp, addr, IS_USER(s));
9905 tcg_temp_free_i32(tmp);
9907 tcg_temp_free_i32(addr);
9911 /* load/store from stack */
9912 rd = (insn >> 8) & 7;
9913 addr = load_reg(s, 13);
9914 val = (insn & 0xff) * 4;
9915 tcg_gen_addi_i32(addr, addr, val);
9917 if (insn & (1 << 11)) {
9919 tmp = tcg_temp_new_i32();
9920 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9921 store_reg(s, rd, tmp);
9924 tmp = load_reg(s, rd);
9925 gen_aa32_st32(tmp, addr, IS_USER(s));
9926 tcg_temp_free_i32(tmp);
9928 tcg_temp_free_i32(addr);
9932 /* add to high reg */
9933 rd = (insn >> 8) & 7;
9934 if (insn & (1 << 11)) {
9936 tmp = load_reg(s, 13);
9938 /* PC. bit 1 is ignored. */
9939 tmp = tcg_temp_new_i32();
9940 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9942 val = (insn & 0xff) * 4;
9943 tcg_gen_addi_i32(tmp, tmp, val);
9944 store_reg(s, rd, tmp);
9949 op = (insn >> 8) & 0xf;
9952 /* adjust stack pointer */
9953 tmp = load_reg(s, 13);
9954 val = (insn & 0x7f) * 4;
9955 if (insn & (1 << 7))
9956 val = -(int32_t)val;
9957 tcg_gen_addi_i32(tmp, tmp, val);
9958 store_reg(s, 13, tmp);
9961 case 2: /* sign/zero extend. */
9964 rm = (insn >> 3) & 7;
9965 tmp = load_reg(s, rm);
9966 switch ((insn >> 6) & 3) {
9967 case 0: gen_sxth(tmp); break;
9968 case 1: gen_sxtb(tmp); break;
9969 case 2: gen_uxth(tmp); break;
9970 case 3: gen_uxtb(tmp); break;
9972 store_reg(s, rd, tmp);
9974 case 4: case 5: case 0xc: case 0xd:
9976 addr = load_reg(s, 13);
9977 if (insn & (1 << 8))
9981 for (i = 0; i < 8; i++) {
9982 if (insn & (1 << i))
9985 if ((insn & (1 << 11)) == 0) {
9986 tcg_gen_addi_i32(addr, addr, -offset);
9988 for (i = 0; i < 8; i++) {
9989 if (insn & (1 << i)) {
9990 if (insn & (1 << 11)) {
9992 tmp = tcg_temp_new_i32();
9993 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9994 store_reg(s, i, tmp);
9997 tmp = load_reg(s, i);
9998 gen_aa32_st32(tmp, addr, IS_USER(s));
9999 tcg_temp_free_i32(tmp);
10001 /* advance to the next address. */
10002 tcg_gen_addi_i32(addr, addr, 4);
10005 TCGV_UNUSED_I32(tmp);
10006 if (insn & (1 << 8)) {
10007 if (insn & (1 << 11)) {
10009 tmp = tcg_temp_new_i32();
10010 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10011 /* don't set the pc until the rest of the instruction
10015 tmp = load_reg(s, 14);
10016 gen_aa32_st32(tmp, addr, IS_USER(s));
10017 tcg_temp_free_i32(tmp);
10019 tcg_gen_addi_i32(addr, addr, 4);
10021 if ((insn & (1 << 11)) == 0) {
10022 tcg_gen_addi_i32(addr, addr, -offset);
10024 /* write back the new stack pointer */
10025 store_reg(s, 13, addr);
10026 /* set the new PC value */
10027 if ((insn & 0x0900) == 0x0900) {
10028 store_reg_from_load(env, s, 15, tmp);
10032 case 1: case 3: case 9: case 11: /* czb */
10034 tmp = load_reg(s, rm);
10035 s->condlabel = gen_new_label();
10037 if (insn & (1 << 11))
10038 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10040 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10041 tcg_temp_free_i32(tmp);
10042 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10043 val = (uint32_t)s->pc + 2;
10048 case 15: /* IT, nop-hint. */
10049 if ((insn & 0xf) == 0) {
10050 gen_nop_hint(s, (insn >> 4) & 0xf);
10054 s->condexec_cond = (insn >> 4) & 0xe;
10055 s->condexec_mask = insn & 0x1f;
10056 /* No actual code generated for this insn, just setup state. */
10059 case 0xe: /* bkpt */
10061 gen_exception_insn(s, 2, EXCP_BKPT);
10064 case 0xa: /* rev */
10066 rn = (insn >> 3) & 0x7;
10068 tmp = load_reg(s, rn);
10069 switch ((insn >> 6) & 3) {
10070 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10071 case 1: gen_rev16(tmp); break;
10072 case 3: gen_revsh(tmp); break;
10073 default: goto illegal_op;
10075 store_reg(s, rd, tmp);
10079 switch ((insn >> 5) & 7) {
10083 if (((insn >> 3) & 1) != s->bswap_code) {
10084 /* Dynamic endianness switching not implemented. */
10085 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10096 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10099 addr = tcg_const_i32(19);
10100 gen_helper_v7m_msr(cpu_env, addr, tmp);
10101 tcg_temp_free_i32(addr);
10105 addr = tcg_const_i32(16);
10106 gen_helper_v7m_msr(cpu_env, addr, tmp);
10107 tcg_temp_free_i32(addr);
10109 tcg_temp_free_i32(tmp);
10112 if (insn & (1 << 4)) {
10113 shift = CPSR_A | CPSR_I | CPSR_F;
10117 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10132 /* load/store multiple */
10133 TCGv_i32 loaded_var;
10134 TCGV_UNUSED_I32(loaded_var);
10135 rn = (insn >> 8) & 0x7;
10136 addr = load_reg(s, rn);
10137 for (i = 0; i < 8; i++) {
10138 if (insn & (1 << i)) {
10139 if (insn & (1 << 11)) {
10141 tmp = tcg_temp_new_i32();
10142 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10146 store_reg(s, i, tmp);
10150 tmp = load_reg(s, i);
10151 gen_aa32_st32(tmp, addr, IS_USER(s));
10152 tcg_temp_free_i32(tmp);
10154 /* advance to the next address */
10155 tcg_gen_addi_i32(addr, addr, 4);
10158 if ((insn & (1 << rn)) == 0) {
10159 /* base reg not in list: base register writeback */
10160 store_reg(s, rn, addr);
10162 /* base reg in list: if load, complete it now */
10163 if (insn & (1 << 11)) {
10164 store_reg(s, rn, loaded_var);
10166 tcg_temp_free_i32(addr);
10171 /* conditional branch or swi */
10172 cond = (insn >> 8) & 0xf;
10178 gen_set_pc_im(s, s->pc);
10179 s->is_jmp = DISAS_SWI;
10182 /* generate a conditional jump to next instruction */
10183 s->condlabel = gen_new_label();
10184 arm_gen_test_cc(cond ^ 1, s->condlabel);
10187 /* jump to the offset */
10188 val = (uint32_t)s->pc + 2;
10189 offset = ((int32_t)insn << 24) >> 24;
10190 val += offset << 1;
10195 if (insn & (1 << 11)) {
10196 if (disas_thumb2_insn(env, s, insn))
10200 /* unconditional branch */
10201 val = (uint32_t)s->pc;
10202 offset = ((int32_t)insn << 21) >> 21;
10203 val += (offset << 1) + 2;
10208 if (disas_thumb2_insn(env, s, insn))
10214 gen_exception_insn(s, 4, EXCP_UDEF);
10218 gen_exception_insn(s, 2, EXCP_UDEF);
10221 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10222 basic block 'tb'. If search_pc is TRUE, also generate PC
10223 information for each intermediate instruction. */
10224 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10225 TranslationBlock *tb,
10228 CPUState *cs = CPU(cpu);
10229 CPUARMState *env = &cpu->env;
10230 DisasContext dc1, *dc = &dc1;
10232 uint16_t *gen_opc_end;
10234 target_ulong pc_start;
10235 target_ulong next_page_start;
10239 /* generate intermediate code */
10241 /* The A64 decoder has its own top level loop, because it doesn't need
10242 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10244 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10245 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10253 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10255 dc->is_jmp = DISAS_NEXT;
10257 dc->singlestep_enabled = cs->singlestep_enabled;
10261 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10262 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10263 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10264 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10265 #if !defined(CONFIG_USER_ONLY)
10266 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10268 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10269 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10270 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10271 dc->cp_regs = cpu->cp_regs;
10272 dc->current_pl = arm_current_pl(env);
10274 cpu_F0s = tcg_temp_new_i32();
10275 cpu_F1s = tcg_temp_new_i32();
10276 cpu_F0d = tcg_temp_new_i64();
10277 cpu_F1d = tcg_temp_new_i64();
10280 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10281 cpu_M0 = tcg_temp_new_i64();
10282 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10285 max_insns = tb->cflags & CF_COUNT_MASK;
10286 if (max_insns == 0)
10287 max_insns = CF_COUNT_MASK;
10291 tcg_clear_temp_count();
10293 /* A note on handling of the condexec (IT) bits:
10295 * We want to avoid the overhead of having to write the updated condexec
10296 * bits back to the CPUARMState for every instruction in an IT block. So:
10297 * (1) if the condexec bits are not already zero then we write
10298 * zero back into the CPUARMState now. This avoids complications trying
10299 * to do it at the end of the block. (For example if we don't do this
10300 * it's hard to identify whether we can safely skip writing condexec
10301 * at the end of the TB, which we definitely want to do for the case
10302 * where a TB doesn't do anything with the IT state at all.)
10303 * (2) if we are going to leave the TB then we call gen_set_condexec()
10304 * which will write the correct value into CPUARMState if zero is wrong.
10305 * This is done both for leaving the TB at the end, and for leaving
10306 * it because of an exception we know will happen, which is done in
10307 * gen_exception_insn(). The latter is necessary because we need to
10308 * leave the TB with the PC/IT state just prior to execution of the
10309 * instruction which caused the exception.
10310 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10311 * then the CPUARMState will be wrong and we need to reset it.
10312 * This is handled in the same way as restoration of the
10313 * PC in these situations: we will be called again with search_pc=1
10314 * and generate a mapping of the condexec bits for each PC in
10315 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10316 * this to restore the condexec bits.
10318 * Note that there are no instructions which can read the condexec
10319 * bits, and none which can write non-static values to them, so
10320 * we don't need to care about whether CPUARMState is correct in the
10324 /* Reset the conditional execution bits immediately. This avoids
10325 complications trying to do it at the end of the block. */
10326 if (dc->condexec_mask || dc->condexec_cond)
10328 TCGv_i32 tmp = tcg_temp_new_i32();
10329 tcg_gen_movi_i32(tmp, 0);
10330 store_cpu_field(tmp, condexec_bits);
10333 #ifdef CONFIG_USER_ONLY
10334 /* Intercept jump to the magic kernel page. */
10335 if (dc->pc >= 0xffff0000) {
10336 /* We always get here via a jump, so know we are not in a
10337 conditional execution block. */
10338 gen_exception(EXCP_KERNEL_TRAP);
10339 dc->is_jmp = DISAS_UPDATE;
10343 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10344 /* We always get here via a jump, so know we are not in a
10345 conditional execution block. */
10346 gen_exception(EXCP_EXCEPTION_EXIT);
10347 dc->is_jmp = DISAS_UPDATE;
10352 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10353 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10354 if (bp->pc == dc->pc) {
10355 gen_exception_insn(dc, 0, EXCP_DEBUG);
10356 /* Advance PC so that clearing the breakpoint will
10357 invalidate this TB. */
10359 goto done_generating;
10364 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10368 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10370 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10371 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10372 tcg_ctx.gen_opc_instr_start[lj] = 1;
10373 tcg_ctx.gen_opc_icount[lj] = num_insns;
10376 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10379 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10380 tcg_gen_debug_insn_start(dc->pc);
10384 disas_thumb_insn(env, dc);
10385 if (dc->condexec_mask) {
10386 dc->condexec_cond = (dc->condexec_cond & 0xe)
10387 | ((dc->condexec_mask >> 4) & 1);
10388 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10389 if (dc->condexec_mask == 0) {
10390 dc->condexec_cond = 0;
10394 disas_arm_insn(env, dc);
10397 if (dc->condjmp && !dc->is_jmp) {
10398 gen_set_label(dc->condlabel);
10402 if (tcg_check_temp_count()) {
10403 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10407 /* Translation stops when a conditional branch is encountered.
10408 * Otherwise the subsequent code could get translated several times.
10409 * Also stop translation when a page boundary is reached. This
10410 * ensures prefetch aborts occur at the right place. */
10412 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10413 !cs->singlestep_enabled &&
10415 dc->pc < next_page_start &&
10416 num_insns < max_insns);
10418 if (tb->cflags & CF_LAST_IO) {
10420 /* FIXME: This can theoretically happen with self-modifying
10422 cpu_abort(env, "IO on conditional branch instruction");
10427 /* At this stage dc->condjmp will only be set when the skipped
10428 instruction was a conditional branch or trap, and the PC has
10429 already been written. */
10430 if (unlikely(cs->singlestep_enabled)) {
10431 /* Make sure the pc is updated, and raise a debug exception. */
10433 gen_set_condexec(dc);
10434 if (dc->is_jmp == DISAS_SWI) {
10435 gen_exception(EXCP_SWI);
10437 gen_exception(EXCP_DEBUG);
10439 gen_set_label(dc->condlabel);
10441 if (dc->condjmp || !dc->is_jmp) {
10442 gen_set_pc_im(dc, dc->pc);
10445 gen_set_condexec(dc);
10446 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10447 gen_exception(EXCP_SWI);
10449 /* FIXME: Single stepping a WFI insn will not halt
10451 gen_exception(EXCP_DEBUG);
10454 /* While branches must always occur at the end of an IT block,
10455 there are a few other things that can cause us to terminate
10456 the TB in the middle of an IT block:
10457 - Exception generating instructions (bkpt, swi, undefined).
10459 - Hardware watchpoints.
10460 Hardware breakpoints have already been handled and skip this code.
10462 gen_set_condexec(dc);
10463 switch(dc->is_jmp) {
10465 gen_goto_tb(dc, 1, dc->pc);
10470 /* indicate that the hash table must be used to find the next TB */
10471 tcg_gen_exit_tb(0);
10473 case DISAS_TB_JUMP:
10474 /* nothing more to generate */
10477 gen_helper_wfi(cpu_env);
10480 gen_exception(EXCP_SWI);
10484 gen_set_label(dc->condlabel);
10485 gen_set_condexec(dc);
10486 gen_goto_tb(dc, 1, dc->pc);
10492 gen_tb_end(tb, num_insns);
10493 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10496 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10497 qemu_log("----------------\n");
10498 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10499 log_target_disas(env, pc_start, dc->pc - pc_start,
10500 dc->thumb | (dc->bswap_code << 1));
10505 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10508 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10510 tb->size = dc->pc - pc_start;
10511 tb->icount = num_insns;
10515 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10517 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10520 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10522 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10525 static const char *cpu_mode_names[16] = {
10526 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10527 "???", "???", "???", "und", "???", "???", "???", "sys"
10530 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10533 ARMCPU *cpu = ARM_CPU(cs);
10534 CPUARMState *env = &cpu->env;
10538 for(i=0;i<16;i++) {
10539 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10541 cpu_fprintf(f, "\n");
10543 cpu_fprintf(f, " ");
10545 psr = cpsr_read(env);
10546 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10548 psr & (1 << 31) ? 'N' : '-',
10549 psr & (1 << 30) ? 'Z' : '-',
10550 psr & (1 << 29) ? 'C' : '-',
10551 psr & (1 << 28) ? 'V' : '-',
10552 psr & CPSR_T ? 'T' : 'A',
10553 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10555 if (flags & CPU_DUMP_FPU) {
10556 int numvfpregs = 0;
10557 if (arm_feature(env, ARM_FEATURE_VFP)) {
10560 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10563 for (i = 0; i < numvfpregs; i++) {
10564 uint64_t v = float64_val(env->vfp.regs[i]);
10565 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10566 i * 2, (uint32_t)v,
10567 i * 2 + 1, (uint32_t)(v >> 32),
10570 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10574 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10577 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10578 env->condexec_bits = 0;
10580 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10581 env->condexec_bits = gen_opc_condexec_bits[pc_pos];