Merge remote-tracking branch 'qemu/master'
[qemu/ar7.git] / target-arm / translate.c
blob8a999e8be2752d948dcba9f36041fd1857f8f3d8
1 /*
2 * ARM translation
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/>.
22 #include "qemu-common.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "tcg-op.h"
27 #include "qemu/log.h"
28 #include "qemu/bitops.h"
29 #include "arm_ldst.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.h"
37 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_dc_feature(s, 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)
54 #define IS_USER(s) 1
55 #else
56 #define IS_USER(s) (s->user)
57 #endif
59 TCGv_ptr cpu_env;
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 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
64 TCGv_i64 cpu_exclusive_addr;
65 TCGv_i64 cpu_exclusive_val;
66 #ifdef CONFIG_USER_ONLY
67 TCGv_i64 cpu_exclusive_test;
68 TCGv_i32 cpu_exclusive_info;
69 #endif
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s, cpu_F1s;
73 static TCGv_i64 cpu_F0d, cpu_F1d;
75 #include "exec/gen-icount.h"
77 static const char *regnames[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
84 int i;
86 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
90 offsetof(CPUARMState, regs[i]),
91 regnames[i]);
93 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
104 offsetof(CPUARMState, exclusive_test), "exclusive_test");
105 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
106 offsetof(CPUARMState, exclusive_info), "exclusive_info");
107 #endif
109 a64_translate_init();
112 static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
114 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
115 * insns:
116 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
117 * otherwise, access as if at PL0.
119 switch (s->mmu_idx) {
120 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
121 case ARMMMUIdx_S12NSE0:
122 case ARMMMUIdx_S12NSE1:
123 return ARMMMUIdx_S12NSE0;
124 case ARMMMUIdx_S1E3:
125 case ARMMMUIdx_S1SE0:
126 case ARMMMUIdx_S1SE1:
127 return ARMMMUIdx_S1SE0;
128 case ARMMMUIdx_S2NS:
129 default:
130 g_assert_not_reached();
134 static inline TCGv_i32 load_cpu_offset(int offset)
136 TCGv_i32 tmp = tcg_temp_new_i32();
137 tcg_gen_ld_i32(tmp, cpu_env, offset);
138 return tmp;
141 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
143 static inline void store_cpu_offset(TCGv_i32 var, int offset)
145 tcg_gen_st_i32(var, cpu_env, offset);
146 tcg_temp_free_i32(var);
149 #define store_cpu_field(var, name) \
150 store_cpu_offset(var, offsetof(CPUARMState, name))
152 /* Set a variable to the value of a CPU register. */
153 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
155 if (reg == 15) {
156 uint32_t addr;
157 /* normally, since we updated PC, we need only to add one insn */
158 if (s->thumb)
159 addr = (long)s->pc + 2;
160 else
161 addr = (long)s->pc + 4;
162 tcg_gen_movi_i32(var, addr);
163 } else {
164 tcg_gen_mov_i32(var, cpu_R[reg]);
168 /* Create a new temporary and set it to the value of a CPU register. */
169 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
171 TCGv_i32 tmp = tcg_temp_new_i32();
172 load_reg_var(s, tmp, reg);
173 return tmp;
176 /* Set a CPU register. The source must be a temporary and will be
177 marked as dead. */
178 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
180 if (reg == 15) {
181 tcg_gen_andi_i32(var, var, ~1);
182 s->is_jmp = DISAS_JUMP;
184 tcg_gen_mov_i32(cpu_R[reg], var);
185 tcg_temp_free_i32(var);
188 /* Value extensions. */
189 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
190 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
191 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
192 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
194 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
195 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
198 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
200 TCGv_i32 tmp_mask = tcg_const_i32(mask);
201 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
202 tcg_temp_free_i32(tmp_mask);
204 /* Set NZCV flags from the high 4 bits of var. */
205 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
207 static void gen_exception_internal(int excp)
209 TCGv_i32 tcg_excp = tcg_const_i32(excp);
211 assert(excp_is_internal(excp));
212 gen_helper_exception_internal(cpu_env, tcg_excp);
213 tcg_temp_free_i32(tcg_excp);
216 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
218 TCGv_i32 tcg_excp = tcg_const_i32(excp);
219 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
220 TCGv_i32 tcg_el = tcg_const_i32(target_el);
222 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
223 tcg_syn, tcg_el);
225 tcg_temp_free_i32(tcg_el);
226 tcg_temp_free_i32(tcg_syn);
227 tcg_temp_free_i32(tcg_excp);
230 static void gen_ss_advance(DisasContext *s)
232 /* If the singlestep state is Active-not-pending, advance to
233 * Active-pending.
235 if (s->ss_active) {
236 s->pstate_ss = 0;
237 gen_helper_clear_pstate_ss(cpu_env);
241 static void gen_step_complete_exception(DisasContext *s)
243 /* We just completed step of an insn. Move from Active-not-pending
244 * to Active-pending, and then also take the swstep exception.
245 * This corresponds to making the (IMPDEF) choice to prioritize
246 * swstep exceptions over asynchronous exceptions taken to an exception
247 * level where debug is disabled. This choice has the advantage that
248 * we do not need to maintain internal state corresponding to the
249 * ISV/EX syndrome bits between completion of the step and generation
250 * of the exception, and our syndrome information is always correct.
252 gen_ss_advance(s);
253 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
254 default_exception_el(s));
255 s->is_jmp = DISAS_EXC;
258 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
260 TCGv_i32 tmp1 = tcg_temp_new_i32();
261 TCGv_i32 tmp2 = tcg_temp_new_i32();
262 tcg_gen_ext16s_i32(tmp1, a);
263 tcg_gen_ext16s_i32(tmp2, b);
264 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
265 tcg_temp_free_i32(tmp2);
266 tcg_gen_sari_i32(a, a, 16);
267 tcg_gen_sari_i32(b, b, 16);
268 tcg_gen_mul_i32(b, b, a);
269 tcg_gen_mov_i32(a, tmp1);
270 tcg_temp_free_i32(tmp1);
273 /* Byteswap each halfword. */
274 static void gen_rev16(TCGv_i32 var)
276 TCGv_i32 tmp = tcg_temp_new_i32();
277 tcg_gen_shri_i32(tmp, var, 8);
278 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
279 tcg_gen_shli_i32(var, var, 8);
280 tcg_gen_andi_i32(var, var, 0xff00ff00);
281 tcg_gen_or_i32(var, var, tmp);
282 tcg_temp_free_i32(tmp);
285 /* Byteswap low halfword and sign extend. */
286 static void gen_revsh(TCGv_i32 var)
288 tcg_gen_ext16u_i32(var, var);
289 tcg_gen_bswap16_i32(var, var);
290 tcg_gen_ext16s_i32(var, var);
293 /* Unsigned bitfield extract. */
294 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
296 if (shift)
297 tcg_gen_shri_i32(var, var, shift);
298 tcg_gen_andi_i32(var, var, mask);
301 /* Signed bitfield extract. */
302 static void gen_sbfx(TCGv_i32 var, int shift, int width)
304 uint32_t signbit;
306 if (shift)
307 tcg_gen_sari_i32(var, var, shift);
308 if (shift + width < 32) {
309 signbit = 1u << (width - 1);
310 tcg_gen_andi_i32(var, var, (1u << width) - 1);
311 tcg_gen_xori_i32(var, var, signbit);
312 tcg_gen_subi_i32(var, var, signbit);
316 /* Return (b << 32) + a. Mark inputs as dead */
317 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
319 TCGv_i64 tmp64 = tcg_temp_new_i64();
321 tcg_gen_extu_i32_i64(tmp64, b);
322 tcg_temp_free_i32(b);
323 tcg_gen_shli_i64(tmp64, tmp64, 32);
324 tcg_gen_add_i64(a, tmp64, a);
326 tcg_temp_free_i64(tmp64);
327 return a;
330 /* Return (b << 32) - a. Mark inputs as dead. */
331 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
333 TCGv_i64 tmp64 = tcg_temp_new_i64();
335 tcg_gen_extu_i32_i64(tmp64, b);
336 tcg_temp_free_i32(b);
337 tcg_gen_shli_i64(tmp64, tmp64, 32);
338 tcg_gen_sub_i64(a, tmp64, a);
340 tcg_temp_free_i64(tmp64);
341 return a;
344 /* 32x32->64 multiply. Marks inputs as dead. */
345 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
347 TCGv_i32 lo = tcg_temp_new_i32();
348 TCGv_i32 hi = tcg_temp_new_i32();
349 TCGv_i64 ret;
351 tcg_gen_mulu2_i32(lo, hi, a, b);
352 tcg_temp_free_i32(a);
353 tcg_temp_free_i32(b);
355 ret = tcg_temp_new_i64();
356 tcg_gen_concat_i32_i64(ret, lo, hi);
357 tcg_temp_free_i32(lo);
358 tcg_temp_free_i32(hi);
360 return ret;
363 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
365 TCGv_i32 lo = tcg_temp_new_i32();
366 TCGv_i32 hi = tcg_temp_new_i32();
367 TCGv_i64 ret;
369 tcg_gen_muls2_i32(lo, hi, a, b);
370 tcg_temp_free_i32(a);
371 tcg_temp_free_i32(b);
373 ret = tcg_temp_new_i64();
374 tcg_gen_concat_i32_i64(ret, lo, hi);
375 tcg_temp_free_i32(lo);
376 tcg_temp_free_i32(hi);
378 return ret;
381 /* Swap low and high halfwords. */
382 static void gen_swap_half(TCGv_i32 var)
384 TCGv_i32 tmp = tcg_temp_new_i32();
385 tcg_gen_shri_i32(tmp, var, 16);
386 tcg_gen_shli_i32(var, var, 16);
387 tcg_gen_or_i32(var, var, tmp);
388 tcg_temp_free_i32(tmp);
391 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
392 tmp = (t0 ^ t1) & 0x8000;
393 t0 &= ~0x8000;
394 t1 &= ~0x8000;
395 t0 = (t0 + t1) ^ tmp;
398 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
400 TCGv_i32 tmp = tcg_temp_new_i32();
401 tcg_gen_xor_i32(tmp, t0, t1);
402 tcg_gen_andi_i32(tmp, tmp, 0x8000);
403 tcg_gen_andi_i32(t0, t0, ~0x8000);
404 tcg_gen_andi_i32(t1, t1, ~0x8000);
405 tcg_gen_add_i32(t0, t0, t1);
406 tcg_gen_xor_i32(t0, t0, tmp);
407 tcg_temp_free_i32(tmp);
408 tcg_temp_free_i32(t1);
411 /* Set CF to the top bit of var. */
412 static void gen_set_CF_bit31(TCGv_i32 var)
414 tcg_gen_shri_i32(cpu_CF, var, 31);
417 /* Set N and Z flags from var. */
418 static inline void gen_logic_CC(TCGv_i32 var)
420 tcg_gen_mov_i32(cpu_NF, var);
421 tcg_gen_mov_i32(cpu_ZF, var);
424 /* T0 += T1 + CF. */
425 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
427 tcg_gen_add_i32(t0, t0, t1);
428 tcg_gen_add_i32(t0, t0, cpu_CF);
431 /* dest = T0 + T1 + CF. */
432 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
434 tcg_gen_add_i32(dest, t0, t1);
435 tcg_gen_add_i32(dest, dest, cpu_CF);
438 /* dest = T0 - T1 + CF - 1. */
439 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
441 tcg_gen_sub_i32(dest, t0, t1);
442 tcg_gen_add_i32(dest, dest, cpu_CF);
443 tcg_gen_subi_i32(dest, dest, 1);
446 /* dest = T0 + T1. Compute C, N, V and Z flags */
447 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
449 TCGv_i32 tmp = tcg_temp_new_i32();
450 tcg_gen_movi_i32(tmp, 0);
451 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
452 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
453 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
454 tcg_gen_xor_i32(tmp, t0, t1);
455 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
456 tcg_temp_free_i32(tmp);
457 tcg_gen_mov_i32(dest, cpu_NF);
460 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
461 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
463 TCGv_i32 tmp = tcg_temp_new_i32();
464 if (TCG_TARGET_HAS_add2_i32) {
465 tcg_gen_movi_i32(tmp, 0);
466 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
467 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
468 } else {
469 TCGv_i64 q0 = tcg_temp_new_i64();
470 TCGv_i64 q1 = tcg_temp_new_i64();
471 tcg_gen_extu_i32_i64(q0, t0);
472 tcg_gen_extu_i32_i64(q1, t1);
473 tcg_gen_add_i64(q0, q0, q1);
474 tcg_gen_extu_i32_i64(q1, cpu_CF);
475 tcg_gen_add_i64(q0, q0, q1);
476 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
477 tcg_temp_free_i64(q0);
478 tcg_temp_free_i64(q1);
480 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
481 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
482 tcg_gen_xor_i32(tmp, t0, t1);
483 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
484 tcg_temp_free_i32(tmp);
485 tcg_gen_mov_i32(dest, cpu_NF);
488 /* dest = T0 - T1. Compute C, N, V and Z flags */
489 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
491 TCGv_i32 tmp;
492 tcg_gen_sub_i32(cpu_NF, t0, t1);
493 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
494 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
495 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
496 tmp = tcg_temp_new_i32();
497 tcg_gen_xor_i32(tmp, t0, t1);
498 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
499 tcg_temp_free_i32(tmp);
500 tcg_gen_mov_i32(dest, cpu_NF);
503 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
504 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
506 TCGv_i32 tmp = tcg_temp_new_i32();
507 tcg_gen_not_i32(tmp, t1);
508 gen_adc_CC(dest, t0, tmp);
509 tcg_temp_free_i32(tmp);
512 #define GEN_SHIFT(name) \
513 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
515 TCGv_i32 tmp1, tmp2, tmp3; \
516 tmp1 = tcg_temp_new_i32(); \
517 tcg_gen_andi_i32(tmp1, t1, 0xff); \
518 tmp2 = tcg_const_i32(0); \
519 tmp3 = tcg_const_i32(0x1f); \
520 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
521 tcg_temp_free_i32(tmp3); \
522 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
523 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
524 tcg_temp_free_i32(tmp2); \
525 tcg_temp_free_i32(tmp1); \
527 GEN_SHIFT(shl)
528 GEN_SHIFT(shr)
529 #undef GEN_SHIFT
531 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
533 TCGv_i32 tmp1, tmp2;
534 tmp1 = tcg_temp_new_i32();
535 tcg_gen_andi_i32(tmp1, t1, 0xff);
536 tmp2 = tcg_const_i32(0x1f);
537 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
538 tcg_temp_free_i32(tmp2);
539 tcg_gen_sar_i32(dest, t0, tmp1);
540 tcg_temp_free_i32(tmp1);
543 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
545 TCGv_i32 c0 = tcg_const_i32(0);
546 TCGv_i32 tmp = tcg_temp_new_i32();
547 tcg_gen_neg_i32(tmp, src);
548 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
549 tcg_temp_free_i32(c0);
550 tcg_temp_free_i32(tmp);
553 static void shifter_out_im(TCGv_i32 var, int shift)
555 if (shift == 0) {
556 tcg_gen_andi_i32(cpu_CF, var, 1);
557 } else {
558 tcg_gen_shri_i32(cpu_CF, var, shift);
559 if (shift != 31) {
560 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
565 /* Shift by immediate. Includes special handling for shift == 0. */
566 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
567 int shift, int flags)
569 switch (shiftop) {
570 case 0: /* LSL */
571 if (shift != 0) {
572 if (flags)
573 shifter_out_im(var, 32 - shift);
574 tcg_gen_shli_i32(var, var, shift);
576 break;
577 case 1: /* LSR */
578 if (shift == 0) {
579 if (flags) {
580 tcg_gen_shri_i32(cpu_CF, var, 31);
582 tcg_gen_movi_i32(var, 0);
583 } else {
584 if (flags)
585 shifter_out_im(var, shift - 1);
586 tcg_gen_shri_i32(var, var, shift);
588 break;
589 case 2: /* ASR */
590 if (shift == 0)
591 shift = 32;
592 if (flags)
593 shifter_out_im(var, shift - 1);
594 if (shift == 32)
595 shift = 31;
596 tcg_gen_sari_i32(var, var, shift);
597 break;
598 case 3: /* ROR/RRX */
599 if (shift != 0) {
600 if (flags)
601 shifter_out_im(var, shift - 1);
602 tcg_gen_rotri_i32(var, var, shift); break;
603 } else {
604 TCGv_i32 tmp = tcg_temp_new_i32();
605 tcg_gen_shli_i32(tmp, cpu_CF, 31);
606 if (flags)
607 shifter_out_im(var, 0);
608 tcg_gen_shri_i32(var, var, 1);
609 tcg_gen_or_i32(var, var, tmp);
610 tcg_temp_free_i32(tmp);
615 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
616 TCGv_i32 shift, int flags)
618 if (flags) {
619 switch (shiftop) {
620 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
621 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
622 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
623 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
625 } else {
626 switch (shiftop) {
627 case 0:
628 gen_shl(var, var, shift);
629 break;
630 case 1:
631 gen_shr(var, var, shift);
632 break;
633 case 2:
634 gen_sar(var, var, shift);
635 break;
636 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
637 tcg_gen_rotr_i32(var, var, shift); break;
640 tcg_temp_free_i32(shift);
643 #define PAS_OP(pfx) \
644 switch (op2) { \
645 case 0: gen_pas_helper(glue(pfx,add16)); break; \
646 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
647 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
648 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
649 case 4: gen_pas_helper(glue(pfx,add8)); break; \
650 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
652 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
654 TCGv_ptr tmp;
656 switch (op1) {
657 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
658 case 1:
659 tmp = tcg_temp_new_ptr();
660 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
661 PAS_OP(s)
662 tcg_temp_free_ptr(tmp);
663 break;
664 case 5:
665 tmp = tcg_temp_new_ptr();
666 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
667 PAS_OP(u)
668 tcg_temp_free_ptr(tmp);
669 break;
670 #undef gen_pas_helper
671 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
672 case 2:
673 PAS_OP(q);
674 break;
675 case 3:
676 PAS_OP(sh);
677 break;
678 case 6:
679 PAS_OP(uq);
680 break;
681 case 7:
682 PAS_OP(uh);
683 break;
684 #undef gen_pas_helper
687 #undef PAS_OP
689 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
690 #define PAS_OP(pfx) \
691 switch (op1) { \
692 case 0: gen_pas_helper(glue(pfx,add8)); break; \
693 case 1: gen_pas_helper(glue(pfx,add16)); break; \
694 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
695 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
696 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
697 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
699 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
701 TCGv_ptr tmp;
703 switch (op2) {
704 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
705 case 0:
706 tmp = tcg_temp_new_ptr();
707 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
708 PAS_OP(s)
709 tcg_temp_free_ptr(tmp);
710 break;
711 case 4:
712 tmp = tcg_temp_new_ptr();
713 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
714 PAS_OP(u)
715 tcg_temp_free_ptr(tmp);
716 break;
717 #undef gen_pas_helper
718 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
719 case 1:
720 PAS_OP(q);
721 break;
722 case 2:
723 PAS_OP(sh);
724 break;
725 case 5:
726 PAS_OP(uq);
727 break;
728 case 6:
729 PAS_OP(uh);
730 break;
731 #undef gen_pas_helper
734 #undef PAS_OP
737 * Generate a conditional based on ARM condition code cc.
738 * This is common between ARM and Aarch64 targets.
740 void arm_test_cc(DisasCompare *cmp, int cc)
742 TCGv_i32 value;
743 TCGCond cond;
744 bool global = true;
746 switch (cc) {
747 case 0: /* eq: Z */
748 case 1: /* ne: !Z */
749 cond = TCG_COND_EQ;
750 value = cpu_ZF;
751 break;
753 case 2: /* cs: C */
754 case 3: /* cc: !C */
755 cond = TCG_COND_NE;
756 value = cpu_CF;
757 break;
759 case 4: /* mi: N */
760 case 5: /* pl: !N */
761 cond = TCG_COND_LT;
762 value = cpu_NF;
763 break;
765 case 6: /* vs: V */
766 case 7: /* vc: !V */
767 cond = TCG_COND_LT;
768 value = cpu_VF;
769 break;
771 case 8: /* hi: C && !Z */
772 case 9: /* ls: !C || Z -> !(C && !Z) */
773 cond = TCG_COND_NE;
774 value = tcg_temp_new_i32();
775 global = false;
776 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
777 ZF is non-zero for !Z; so AND the two subexpressions. */
778 tcg_gen_neg_i32(value, cpu_CF);
779 tcg_gen_and_i32(value, value, cpu_ZF);
780 break;
782 case 10: /* ge: N == V -> N ^ V == 0 */
783 case 11: /* lt: N != V -> N ^ V != 0 */
784 /* Since we're only interested in the sign bit, == 0 is >= 0. */
785 cond = TCG_COND_GE;
786 value = tcg_temp_new_i32();
787 global = false;
788 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
789 break;
791 case 12: /* gt: !Z && N == V */
792 case 13: /* le: Z || N != V */
793 cond = TCG_COND_NE;
794 value = tcg_temp_new_i32();
795 global = false;
796 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
797 * the sign bit then AND with ZF to yield the result. */
798 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
799 tcg_gen_sari_i32(value, value, 31);
800 tcg_gen_andc_i32(value, cpu_ZF, value);
801 break;
803 case 14: /* always */
804 case 15: /* always */
805 /* Use the ALWAYS condition, which will fold early.
806 * It doesn't matter what we use for the value. */
807 cond = TCG_COND_ALWAYS;
808 value = cpu_ZF;
809 goto no_invert;
811 default:
812 fprintf(stderr, "Bad condition code 0x%x\n", cc);
813 abort();
816 if (cc & 1) {
817 cond = tcg_invert_cond(cond);
820 no_invert:
821 cmp->cond = cond;
822 cmp->value = value;
823 cmp->value_global = global;
826 void arm_free_cc(DisasCompare *cmp)
828 if (!cmp->value_global) {
829 tcg_temp_free_i32(cmp->value);
833 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
835 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
838 void arm_gen_test_cc(int cc, TCGLabel *label)
840 DisasCompare cmp;
841 arm_test_cc(&cmp, cc);
842 arm_jump_cc(&cmp, label);
843 arm_free_cc(&cmp);
846 static const uint8_t table_logic_cc[16] = {
847 1, /* and */
848 1, /* xor */
849 0, /* sub */
850 0, /* rsb */
851 0, /* add */
852 0, /* adc */
853 0, /* sbc */
854 0, /* rsc */
855 1, /* andl */
856 1, /* xorl */
857 0, /* cmp */
858 0, /* cmn */
859 1, /* orr */
860 1, /* mov */
861 1, /* bic */
862 1, /* mvn */
865 /* Set PC and Thumb state from an immediate address. */
866 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
868 TCGv_i32 tmp;
870 s->is_jmp = DISAS_UPDATE;
871 if (s->thumb != (addr & 1)) {
872 tmp = tcg_temp_new_i32();
873 tcg_gen_movi_i32(tmp, addr & 1);
874 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
875 tcg_temp_free_i32(tmp);
877 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
880 /* Set PC and Thumb state from var. var is marked as dead. */
881 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
883 s->is_jmp = DISAS_UPDATE;
884 tcg_gen_andi_i32(cpu_R[15], var, ~1);
885 tcg_gen_andi_i32(var, var, 1);
886 store_cpu_field(var, thumb);
889 /* Variant of store_reg which uses branch&exchange logic when storing
890 to r15 in ARM architecture v7 and above. The source must be a temporary
891 and will be marked as dead. */
892 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
894 if (reg == 15 && ENABLE_ARCH_7) {
895 gen_bx(s, var);
896 } else {
897 store_reg(s, reg, var);
901 /* Variant of store_reg which uses branch&exchange logic when storing
902 * to r15 in ARM architecture v5T and above. This is used for storing
903 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
904 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
905 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
907 if (reg == 15 && ENABLE_ARCH_5) {
908 gen_bx(s, var);
909 } else {
910 store_reg(s, reg, var);
914 /* Abstractions of "generate code to do a guest load/store for
915 * AArch32", where a vaddr is always 32 bits (and is zero
916 * extended if we're a 64 bit core) and data is also
917 * 32 bits unless specifically doing a 64 bit access.
918 * These functions work like tcg_gen_qemu_{ld,st}* except
919 * that the address argument is TCGv_i32 rather than TCGv.
921 #if TARGET_LONG_BITS == 32
923 #define DO_GEN_LD(SUFF, OPC) \
924 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
926 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
929 #define DO_GEN_ST(SUFF, OPC) \
930 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
932 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
935 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
937 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
940 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
942 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
945 #else
947 #define DO_GEN_LD(SUFF, OPC) \
948 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
950 TCGv addr64 = tcg_temp_new(); \
951 tcg_gen_extu_i32_i64(addr64, addr); \
952 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
953 tcg_temp_free(addr64); \
956 #define DO_GEN_ST(SUFF, OPC) \
957 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
959 TCGv addr64 = tcg_temp_new(); \
960 tcg_gen_extu_i32_i64(addr64, addr); \
961 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
962 tcg_temp_free(addr64); \
965 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
967 TCGv addr64 = tcg_temp_new();
968 tcg_gen_extu_i32_i64(addr64, addr);
969 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
970 tcg_temp_free(addr64);
973 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
975 TCGv addr64 = tcg_temp_new();
976 tcg_gen_extu_i32_i64(addr64, addr);
977 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
978 tcg_temp_free(addr64);
981 #endif
983 DO_GEN_LD(8s, MO_SB)
984 DO_GEN_LD(8u, MO_UB)
985 DO_GEN_LD(16s, MO_TESW)
986 DO_GEN_LD(16u, MO_TEUW)
987 DO_GEN_LD(32u, MO_TEUL)
988 DO_GEN_ST(8, MO_UB)
989 DO_GEN_ST(16, MO_TEUW)
990 DO_GEN_ST(32, MO_TEUL)
992 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
994 tcg_gen_movi_i32(cpu_R[15], val);
997 static inline void gen_hvc(DisasContext *s, int imm16)
999 /* The pre HVC helper handles cases when HVC gets trapped
1000 * as an undefined insn by runtime configuration (ie before
1001 * the insn really executes).
1003 gen_set_pc_im(s, s->pc - 4);
1004 gen_helper_pre_hvc(cpu_env);
1005 /* Otherwise we will treat this as a real exception which
1006 * happens after execution of the insn. (The distinction matters
1007 * for the PC value reported to the exception handler and also
1008 * for single stepping.)
1010 s->svc_imm = imm16;
1011 gen_set_pc_im(s, s->pc);
1012 s->is_jmp = DISAS_HVC;
1015 static inline void gen_smc(DisasContext *s)
1017 /* As with HVC, we may take an exception either before or after
1018 * the insn executes.
1020 TCGv_i32 tmp;
1022 gen_set_pc_im(s, s->pc - 4);
1023 tmp = tcg_const_i32(syn_aa32_smc());
1024 gen_helper_pre_smc(cpu_env, tmp);
1025 tcg_temp_free_i32(tmp);
1026 gen_set_pc_im(s, s->pc);
1027 s->is_jmp = DISAS_SMC;
1030 static inline void
1031 gen_set_condexec (DisasContext *s)
1033 if (s->condexec_mask) {
1034 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1035 TCGv_i32 tmp = tcg_temp_new_i32();
1036 tcg_gen_movi_i32(tmp, val);
1037 store_cpu_field(tmp, condexec_bits);
1041 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1043 gen_set_condexec(s);
1044 gen_set_pc_im(s, s->pc - offset);
1045 gen_exception_internal(excp);
1046 s->is_jmp = DISAS_JUMP;
1049 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1050 int syn, uint32_t target_el)
1052 gen_set_condexec(s);
1053 gen_set_pc_im(s, s->pc - offset);
1054 gen_exception(excp, syn, target_el);
1055 s->is_jmp = DISAS_JUMP;
1058 /* Force a TB lookup after an instruction that changes the CPU state. */
1059 static inline void gen_lookup_tb(DisasContext *s)
1061 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1062 s->is_jmp = DISAS_UPDATE;
1065 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1066 TCGv_i32 var)
1068 int val, rm, shift, shiftop;
1069 TCGv_i32 offset;
1071 if (!(insn & (1 << 25))) {
1072 /* immediate */
1073 val = insn & 0xfff;
1074 if (!(insn & (1 << 23)))
1075 val = -val;
1076 if (val != 0)
1077 tcg_gen_addi_i32(var, var, val);
1078 } else {
1079 /* shift/register */
1080 rm = (insn) & 0xf;
1081 shift = (insn >> 7) & 0x1f;
1082 shiftop = (insn >> 5) & 3;
1083 offset = load_reg(s, rm);
1084 gen_arm_shift_im(offset, shiftop, shift, 0);
1085 if (!(insn & (1 << 23)))
1086 tcg_gen_sub_i32(var, var, offset);
1087 else
1088 tcg_gen_add_i32(var, var, offset);
1089 tcg_temp_free_i32(offset);
1093 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1094 int extra, TCGv_i32 var)
1096 int val, rm;
1097 TCGv_i32 offset;
1099 if (insn & (1 << 22)) {
1100 /* immediate */
1101 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1102 if (!(insn & (1 << 23)))
1103 val = -val;
1104 val += extra;
1105 if (val != 0)
1106 tcg_gen_addi_i32(var, var, val);
1107 } else {
1108 /* register */
1109 if (extra)
1110 tcg_gen_addi_i32(var, var, extra);
1111 rm = (insn) & 0xf;
1112 offset = load_reg(s, rm);
1113 if (!(insn & (1 << 23)))
1114 tcg_gen_sub_i32(var, var, offset);
1115 else
1116 tcg_gen_add_i32(var, var, offset);
1117 tcg_temp_free_i32(offset);
1121 static TCGv_ptr get_fpstatus_ptr(int neon)
1123 TCGv_ptr statusptr = tcg_temp_new_ptr();
1124 int offset;
1125 if (neon) {
1126 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1127 } else {
1128 offset = offsetof(CPUARMState, vfp.fp_status);
1130 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1131 return statusptr;
1134 #define VFP_OP2(name) \
1135 static inline void gen_vfp_##name(int dp) \
1137 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1138 if (dp) { \
1139 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1140 } else { \
1141 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1143 tcg_temp_free_ptr(fpst); \
1146 VFP_OP2(add)
1147 VFP_OP2(sub)
1148 VFP_OP2(mul)
1149 VFP_OP2(div)
1151 #undef VFP_OP2
1153 static inline void gen_vfp_F1_mul(int dp)
1155 /* Like gen_vfp_mul() but put result in F1 */
1156 TCGv_ptr fpst = get_fpstatus_ptr(0);
1157 if (dp) {
1158 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1159 } else {
1160 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1162 tcg_temp_free_ptr(fpst);
1165 static inline void gen_vfp_F1_neg(int dp)
1167 /* Like gen_vfp_neg() but put result in F1 */
1168 if (dp) {
1169 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1170 } else {
1171 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1175 static inline void gen_vfp_abs(int dp)
1177 if (dp)
1178 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1179 else
1180 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1183 static inline void gen_vfp_neg(int dp)
1185 if (dp)
1186 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1187 else
1188 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1191 static inline void gen_vfp_sqrt(int dp)
1193 if (dp)
1194 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1195 else
1196 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1199 static inline void gen_vfp_cmp(int dp)
1201 if (dp)
1202 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1203 else
1204 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1207 static inline void gen_vfp_cmpe(int dp)
1209 if (dp)
1210 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1211 else
1212 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1215 static inline void gen_vfp_F1_ld0(int dp)
1217 if (dp)
1218 tcg_gen_movi_i64(cpu_F1d, 0);
1219 else
1220 tcg_gen_movi_i32(cpu_F1s, 0);
1223 #define VFP_GEN_ITOF(name) \
1224 static inline void gen_vfp_##name(int dp, int neon) \
1226 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1227 if (dp) { \
1228 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1229 } else { \
1230 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1232 tcg_temp_free_ptr(statusptr); \
1235 VFP_GEN_ITOF(uito)
1236 VFP_GEN_ITOF(sito)
1237 #undef VFP_GEN_ITOF
1239 #define VFP_GEN_FTOI(name) \
1240 static inline void gen_vfp_##name(int dp, int neon) \
1242 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1243 if (dp) { \
1244 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1245 } else { \
1246 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1248 tcg_temp_free_ptr(statusptr); \
1251 VFP_GEN_FTOI(toui)
1252 VFP_GEN_FTOI(touiz)
1253 VFP_GEN_FTOI(tosi)
1254 VFP_GEN_FTOI(tosiz)
1255 #undef VFP_GEN_FTOI
1257 #define VFP_GEN_FIX(name, round) \
1258 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1260 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1261 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1262 if (dp) { \
1263 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1264 statusptr); \
1265 } else { \
1266 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1267 statusptr); \
1269 tcg_temp_free_i32(tmp_shift); \
1270 tcg_temp_free_ptr(statusptr); \
1272 VFP_GEN_FIX(tosh, _round_to_zero)
1273 VFP_GEN_FIX(tosl, _round_to_zero)
1274 VFP_GEN_FIX(touh, _round_to_zero)
1275 VFP_GEN_FIX(toul, _round_to_zero)
1276 VFP_GEN_FIX(shto, )
1277 VFP_GEN_FIX(slto, )
1278 VFP_GEN_FIX(uhto, )
1279 VFP_GEN_FIX(ulto, )
1280 #undef VFP_GEN_FIX
1282 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1284 if (dp) {
1285 gen_aa32_ld64(cpu_F0d, addr, get_mem_index(s));
1286 } else {
1287 gen_aa32_ld32u(cpu_F0s, addr, get_mem_index(s));
1291 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1293 if (dp) {
1294 gen_aa32_st64(cpu_F0d, addr, get_mem_index(s));
1295 } else {
1296 gen_aa32_st32(cpu_F0s, addr, get_mem_index(s));
1300 static inline long
1301 vfp_reg_offset (int dp, int reg)
1303 if (dp)
1304 return offsetof(CPUARMState, vfp.regs[reg]);
1305 else if (reg & 1) {
1306 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1307 + offsetof(CPU_DoubleU, l.upper);
1308 } else {
1309 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1310 + offsetof(CPU_DoubleU, l.lower);
1314 /* Return the offset of a 32-bit piece of a NEON register.
1315 zero is the least significant end of the register. */
1316 static inline long
1317 neon_reg_offset (int reg, int n)
1319 int sreg;
1320 sreg = reg * 2 + n;
1321 return vfp_reg_offset(0, sreg);
1324 static TCGv_i32 neon_load_reg(int reg, int pass)
1326 TCGv_i32 tmp = tcg_temp_new_i32();
1327 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1328 return tmp;
1331 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1333 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1334 tcg_temp_free_i32(var);
1337 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1339 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1342 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1344 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1347 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1348 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1349 #define tcg_gen_st_f32 tcg_gen_st_i32
1350 #define tcg_gen_st_f64 tcg_gen_st_i64
1352 static inline void gen_mov_F0_vreg(int dp, int reg)
1354 if (dp)
1355 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1356 else
1357 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1360 static inline void gen_mov_F1_vreg(int dp, int reg)
1362 if (dp)
1363 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1364 else
1365 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1368 static inline void gen_mov_vreg_F0(int dp, int reg)
1370 if (dp)
1371 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1372 else
1373 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1376 #define ARM_CP_RW_BIT (1 << 20)
1378 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1380 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1383 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1385 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1388 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1390 TCGv_i32 var = tcg_temp_new_i32();
1391 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1392 return var;
1395 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1397 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1398 tcg_temp_free_i32(var);
1401 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1403 iwmmxt_store_reg(cpu_M0, rn);
1406 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1408 iwmmxt_load_reg(cpu_M0, rn);
1411 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1413 iwmmxt_load_reg(cpu_V1, rn);
1414 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1417 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1419 iwmmxt_load_reg(cpu_V1, rn);
1420 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1423 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1425 iwmmxt_load_reg(cpu_V1, rn);
1426 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1429 #define IWMMXT_OP(name) \
1430 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1432 iwmmxt_load_reg(cpu_V1, rn); \
1433 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1436 #define IWMMXT_OP_ENV(name) \
1437 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1439 iwmmxt_load_reg(cpu_V1, rn); \
1440 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1443 #define IWMMXT_OP_ENV_SIZE(name) \
1444 IWMMXT_OP_ENV(name##b) \
1445 IWMMXT_OP_ENV(name##w) \
1446 IWMMXT_OP_ENV(name##l)
1448 #define IWMMXT_OP_ENV1(name) \
1449 static inline void gen_op_iwmmxt_##name##_M0(void) \
1451 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1454 IWMMXT_OP(maddsq)
1455 IWMMXT_OP(madduq)
1456 IWMMXT_OP(sadb)
1457 IWMMXT_OP(sadw)
1458 IWMMXT_OP(mulslw)
1459 IWMMXT_OP(mulshw)
1460 IWMMXT_OP(mululw)
1461 IWMMXT_OP(muluhw)
1462 IWMMXT_OP(macsw)
1463 IWMMXT_OP(macuw)
1465 IWMMXT_OP_ENV_SIZE(unpackl)
1466 IWMMXT_OP_ENV_SIZE(unpackh)
1468 IWMMXT_OP_ENV1(unpacklub)
1469 IWMMXT_OP_ENV1(unpackluw)
1470 IWMMXT_OP_ENV1(unpacklul)
1471 IWMMXT_OP_ENV1(unpackhub)
1472 IWMMXT_OP_ENV1(unpackhuw)
1473 IWMMXT_OP_ENV1(unpackhul)
1474 IWMMXT_OP_ENV1(unpacklsb)
1475 IWMMXT_OP_ENV1(unpacklsw)
1476 IWMMXT_OP_ENV1(unpacklsl)
1477 IWMMXT_OP_ENV1(unpackhsb)
1478 IWMMXT_OP_ENV1(unpackhsw)
1479 IWMMXT_OP_ENV1(unpackhsl)
1481 IWMMXT_OP_ENV_SIZE(cmpeq)
1482 IWMMXT_OP_ENV_SIZE(cmpgtu)
1483 IWMMXT_OP_ENV_SIZE(cmpgts)
1485 IWMMXT_OP_ENV_SIZE(mins)
1486 IWMMXT_OP_ENV_SIZE(minu)
1487 IWMMXT_OP_ENV_SIZE(maxs)
1488 IWMMXT_OP_ENV_SIZE(maxu)
1490 IWMMXT_OP_ENV_SIZE(subn)
1491 IWMMXT_OP_ENV_SIZE(addn)
1492 IWMMXT_OP_ENV_SIZE(subu)
1493 IWMMXT_OP_ENV_SIZE(addu)
1494 IWMMXT_OP_ENV_SIZE(subs)
1495 IWMMXT_OP_ENV_SIZE(adds)
1497 IWMMXT_OP_ENV(avgb0)
1498 IWMMXT_OP_ENV(avgb1)
1499 IWMMXT_OP_ENV(avgw0)
1500 IWMMXT_OP_ENV(avgw1)
1502 IWMMXT_OP_ENV(packuw)
1503 IWMMXT_OP_ENV(packul)
1504 IWMMXT_OP_ENV(packuq)
1505 IWMMXT_OP_ENV(packsw)
1506 IWMMXT_OP_ENV(packsl)
1507 IWMMXT_OP_ENV(packsq)
1509 static void gen_op_iwmmxt_set_mup(void)
1511 TCGv_i32 tmp;
1512 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1513 tcg_gen_ori_i32(tmp, tmp, 2);
1514 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1517 static void gen_op_iwmmxt_set_cup(void)
1519 TCGv_i32 tmp;
1520 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1521 tcg_gen_ori_i32(tmp, tmp, 1);
1522 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1525 static void gen_op_iwmmxt_setpsr_nz(void)
1527 TCGv_i32 tmp = tcg_temp_new_i32();
1528 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1529 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1532 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1534 iwmmxt_load_reg(cpu_V1, rn);
1535 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1536 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1539 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1540 TCGv_i32 dest)
1542 int rd;
1543 uint32_t offset;
1544 TCGv_i32 tmp;
1546 rd = (insn >> 16) & 0xf;
1547 tmp = load_reg(s, rd);
1549 offset = (insn & 0xff) << ((insn >> 7) & 2);
1550 if (insn & (1 << 24)) {
1551 /* Pre indexed */
1552 if (insn & (1 << 23))
1553 tcg_gen_addi_i32(tmp, tmp, offset);
1554 else
1555 tcg_gen_addi_i32(tmp, tmp, -offset);
1556 tcg_gen_mov_i32(dest, tmp);
1557 if (insn & (1 << 21))
1558 store_reg(s, rd, tmp);
1559 else
1560 tcg_temp_free_i32(tmp);
1561 } else if (insn & (1 << 21)) {
1562 /* Post indexed */
1563 tcg_gen_mov_i32(dest, tmp);
1564 if (insn & (1 << 23))
1565 tcg_gen_addi_i32(tmp, tmp, offset);
1566 else
1567 tcg_gen_addi_i32(tmp, tmp, -offset);
1568 store_reg(s, rd, tmp);
1569 } else if (!(insn & (1 << 23)))
1570 return 1;
1571 return 0;
1574 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1576 int rd = (insn >> 0) & 0xf;
1577 TCGv_i32 tmp;
1579 if (insn & (1 << 8)) {
1580 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1581 return 1;
1582 } else {
1583 tmp = iwmmxt_load_creg(rd);
1585 } else {
1586 tmp = tcg_temp_new_i32();
1587 iwmmxt_load_reg(cpu_V0, rd);
1588 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1590 tcg_gen_andi_i32(tmp, tmp, mask);
1591 tcg_gen_mov_i32(dest, tmp);
1592 tcg_temp_free_i32(tmp);
1593 return 0;
1596 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1597 (ie. an undefined instruction). */
1598 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1600 int rd, wrd;
1601 int rdhi, rdlo, rd0, rd1, i;
1602 TCGv_i32 addr;
1603 TCGv_i32 tmp, tmp2, tmp3;
1605 if ((insn & 0x0e000e00) == 0x0c000000) {
1606 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1607 wrd = insn & 0xf;
1608 rdlo = (insn >> 12) & 0xf;
1609 rdhi = (insn >> 16) & 0xf;
1610 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1611 iwmmxt_load_reg(cpu_V0, wrd);
1612 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1613 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1614 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1615 } else { /* TMCRR */
1616 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1617 iwmmxt_store_reg(cpu_V0, wrd);
1618 gen_op_iwmmxt_set_mup();
1620 return 0;
1623 wrd = (insn >> 12) & 0xf;
1624 addr = tcg_temp_new_i32();
1625 if (gen_iwmmxt_address(s, insn, addr)) {
1626 tcg_temp_free_i32(addr);
1627 return 1;
1629 if (insn & ARM_CP_RW_BIT) {
1630 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1631 tmp = tcg_temp_new_i32();
1632 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1633 iwmmxt_store_creg(wrd, tmp);
1634 } else {
1635 i = 1;
1636 if (insn & (1 << 8)) {
1637 if (insn & (1 << 22)) { /* WLDRD */
1638 gen_aa32_ld64(cpu_M0, addr, get_mem_index(s));
1639 i = 0;
1640 } else { /* WLDRW wRd */
1641 tmp = tcg_temp_new_i32();
1642 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1644 } else {
1645 tmp = tcg_temp_new_i32();
1646 if (insn & (1 << 22)) { /* WLDRH */
1647 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
1648 } else { /* WLDRB */
1649 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
1652 if (i) {
1653 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1654 tcg_temp_free_i32(tmp);
1656 gen_op_iwmmxt_movq_wRn_M0(wrd);
1658 } else {
1659 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1660 tmp = iwmmxt_load_creg(wrd);
1661 gen_aa32_st32(tmp, addr, get_mem_index(s));
1662 } else {
1663 gen_op_iwmmxt_movq_M0_wRn(wrd);
1664 tmp = tcg_temp_new_i32();
1665 if (insn & (1 << 8)) {
1666 if (insn & (1 << 22)) { /* WSTRD */
1667 gen_aa32_st64(cpu_M0, addr, get_mem_index(s));
1668 } else { /* WSTRW wRd */
1669 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1670 gen_aa32_st32(tmp, addr, get_mem_index(s));
1672 } else {
1673 if (insn & (1 << 22)) { /* WSTRH */
1674 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1675 gen_aa32_st16(tmp, addr, get_mem_index(s));
1676 } else { /* WSTRB */
1677 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1678 gen_aa32_st8(tmp, addr, get_mem_index(s));
1682 tcg_temp_free_i32(tmp);
1684 tcg_temp_free_i32(addr);
1685 return 0;
1688 if ((insn & 0x0f000000) != 0x0e000000)
1689 return 1;
1691 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1692 case 0x000: /* WOR */
1693 wrd = (insn >> 12) & 0xf;
1694 rd0 = (insn >> 0) & 0xf;
1695 rd1 = (insn >> 16) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0);
1697 gen_op_iwmmxt_orq_M0_wRn(rd1);
1698 gen_op_iwmmxt_setpsr_nz();
1699 gen_op_iwmmxt_movq_wRn_M0(wrd);
1700 gen_op_iwmmxt_set_mup();
1701 gen_op_iwmmxt_set_cup();
1702 break;
1703 case 0x011: /* TMCR */
1704 if (insn & 0xf)
1705 return 1;
1706 rd = (insn >> 12) & 0xf;
1707 wrd = (insn >> 16) & 0xf;
1708 switch (wrd) {
1709 case ARM_IWMMXT_wCID:
1710 case ARM_IWMMXT_wCASF:
1711 break;
1712 case ARM_IWMMXT_wCon:
1713 gen_op_iwmmxt_set_cup();
1714 /* Fall through. */
1715 case ARM_IWMMXT_wCSSF:
1716 tmp = iwmmxt_load_creg(wrd);
1717 tmp2 = load_reg(s, rd);
1718 tcg_gen_andc_i32(tmp, tmp, tmp2);
1719 tcg_temp_free_i32(tmp2);
1720 iwmmxt_store_creg(wrd, tmp);
1721 break;
1722 case ARM_IWMMXT_wCGR0:
1723 case ARM_IWMMXT_wCGR1:
1724 case ARM_IWMMXT_wCGR2:
1725 case ARM_IWMMXT_wCGR3:
1726 gen_op_iwmmxt_set_cup();
1727 tmp = load_reg(s, rd);
1728 iwmmxt_store_creg(wrd, tmp);
1729 break;
1730 default:
1731 return 1;
1733 break;
1734 case 0x100: /* WXOR */
1735 wrd = (insn >> 12) & 0xf;
1736 rd0 = (insn >> 0) & 0xf;
1737 rd1 = (insn >> 16) & 0xf;
1738 gen_op_iwmmxt_movq_M0_wRn(rd0);
1739 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1740 gen_op_iwmmxt_setpsr_nz();
1741 gen_op_iwmmxt_movq_wRn_M0(wrd);
1742 gen_op_iwmmxt_set_mup();
1743 gen_op_iwmmxt_set_cup();
1744 break;
1745 case 0x111: /* TMRC */
1746 if (insn & 0xf)
1747 return 1;
1748 rd = (insn >> 12) & 0xf;
1749 wrd = (insn >> 16) & 0xf;
1750 tmp = iwmmxt_load_creg(wrd);
1751 store_reg(s, rd, tmp);
1752 break;
1753 case 0x300: /* WANDN */
1754 wrd = (insn >> 12) & 0xf;
1755 rd0 = (insn >> 0) & 0xf;
1756 rd1 = (insn >> 16) & 0xf;
1757 gen_op_iwmmxt_movq_M0_wRn(rd0);
1758 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1759 gen_op_iwmmxt_andq_M0_wRn(rd1);
1760 gen_op_iwmmxt_setpsr_nz();
1761 gen_op_iwmmxt_movq_wRn_M0(wrd);
1762 gen_op_iwmmxt_set_mup();
1763 gen_op_iwmmxt_set_cup();
1764 break;
1765 case 0x200: /* WAND */
1766 wrd = (insn >> 12) & 0xf;
1767 rd0 = (insn >> 0) & 0xf;
1768 rd1 = (insn >> 16) & 0xf;
1769 gen_op_iwmmxt_movq_M0_wRn(rd0);
1770 gen_op_iwmmxt_andq_M0_wRn(rd1);
1771 gen_op_iwmmxt_setpsr_nz();
1772 gen_op_iwmmxt_movq_wRn_M0(wrd);
1773 gen_op_iwmmxt_set_mup();
1774 gen_op_iwmmxt_set_cup();
1775 break;
1776 case 0x810: case 0xa10: /* WMADD */
1777 wrd = (insn >> 12) & 0xf;
1778 rd0 = (insn >> 0) & 0xf;
1779 rd1 = (insn >> 16) & 0xf;
1780 gen_op_iwmmxt_movq_M0_wRn(rd0);
1781 if (insn & (1 << 21))
1782 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1783 else
1784 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd);
1786 gen_op_iwmmxt_set_mup();
1787 break;
1788 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1789 wrd = (insn >> 12) & 0xf;
1790 rd0 = (insn >> 16) & 0xf;
1791 rd1 = (insn >> 0) & 0xf;
1792 gen_op_iwmmxt_movq_M0_wRn(rd0);
1793 switch ((insn >> 22) & 3) {
1794 case 0:
1795 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1796 break;
1797 case 1:
1798 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1799 break;
1800 case 2:
1801 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1802 break;
1803 case 3:
1804 return 1;
1806 gen_op_iwmmxt_movq_wRn_M0(wrd);
1807 gen_op_iwmmxt_set_mup();
1808 gen_op_iwmmxt_set_cup();
1809 break;
1810 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1811 wrd = (insn >> 12) & 0xf;
1812 rd0 = (insn >> 16) & 0xf;
1813 rd1 = (insn >> 0) & 0xf;
1814 gen_op_iwmmxt_movq_M0_wRn(rd0);
1815 switch ((insn >> 22) & 3) {
1816 case 0:
1817 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1818 break;
1819 case 1:
1820 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1821 break;
1822 case 2:
1823 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1824 break;
1825 case 3:
1826 return 1;
1828 gen_op_iwmmxt_movq_wRn_M0(wrd);
1829 gen_op_iwmmxt_set_mup();
1830 gen_op_iwmmxt_set_cup();
1831 break;
1832 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1833 wrd = (insn >> 12) & 0xf;
1834 rd0 = (insn >> 16) & 0xf;
1835 rd1 = (insn >> 0) & 0xf;
1836 gen_op_iwmmxt_movq_M0_wRn(rd0);
1837 if (insn & (1 << 22))
1838 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1839 else
1840 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1841 if (!(insn & (1 << 20)))
1842 gen_op_iwmmxt_addl_M0_wRn(wrd);
1843 gen_op_iwmmxt_movq_wRn_M0(wrd);
1844 gen_op_iwmmxt_set_mup();
1845 break;
1846 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1847 wrd = (insn >> 12) & 0xf;
1848 rd0 = (insn >> 16) & 0xf;
1849 rd1 = (insn >> 0) & 0xf;
1850 gen_op_iwmmxt_movq_M0_wRn(rd0);
1851 if (insn & (1 << 21)) {
1852 if (insn & (1 << 20))
1853 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1854 else
1855 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1856 } else {
1857 if (insn & (1 << 20))
1858 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1859 else
1860 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1862 gen_op_iwmmxt_movq_wRn_M0(wrd);
1863 gen_op_iwmmxt_set_mup();
1864 break;
1865 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1866 wrd = (insn >> 12) & 0xf;
1867 rd0 = (insn >> 16) & 0xf;
1868 rd1 = (insn >> 0) & 0xf;
1869 gen_op_iwmmxt_movq_M0_wRn(rd0);
1870 if (insn & (1 << 21))
1871 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1872 else
1873 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1874 if (!(insn & (1 << 20))) {
1875 iwmmxt_load_reg(cpu_V1, wrd);
1876 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd);
1879 gen_op_iwmmxt_set_mup();
1880 break;
1881 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1882 wrd = (insn >> 12) & 0xf;
1883 rd0 = (insn >> 16) & 0xf;
1884 rd1 = (insn >> 0) & 0xf;
1885 gen_op_iwmmxt_movq_M0_wRn(rd0);
1886 switch ((insn >> 22) & 3) {
1887 case 0:
1888 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1889 break;
1890 case 1:
1891 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1892 break;
1893 case 2:
1894 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1895 break;
1896 case 3:
1897 return 1;
1899 gen_op_iwmmxt_movq_wRn_M0(wrd);
1900 gen_op_iwmmxt_set_mup();
1901 gen_op_iwmmxt_set_cup();
1902 break;
1903 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1904 wrd = (insn >> 12) & 0xf;
1905 rd0 = (insn >> 16) & 0xf;
1906 rd1 = (insn >> 0) & 0xf;
1907 gen_op_iwmmxt_movq_M0_wRn(rd0);
1908 if (insn & (1 << 22)) {
1909 if (insn & (1 << 20))
1910 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1911 else
1912 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1913 } else {
1914 if (insn & (1 << 20))
1915 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1916 else
1917 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1919 gen_op_iwmmxt_movq_wRn_M0(wrd);
1920 gen_op_iwmmxt_set_mup();
1921 gen_op_iwmmxt_set_cup();
1922 break;
1923 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1924 wrd = (insn >> 12) & 0xf;
1925 rd0 = (insn >> 16) & 0xf;
1926 rd1 = (insn >> 0) & 0xf;
1927 gen_op_iwmmxt_movq_M0_wRn(rd0);
1928 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1929 tcg_gen_andi_i32(tmp, tmp, 7);
1930 iwmmxt_load_reg(cpu_V1, rd1);
1931 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1932 tcg_temp_free_i32(tmp);
1933 gen_op_iwmmxt_movq_wRn_M0(wrd);
1934 gen_op_iwmmxt_set_mup();
1935 break;
1936 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1937 if (((insn >> 6) & 3) == 3)
1938 return 1;
1939 rd = (insn >> 12) & 0xf;
1940 wrd = (insn >> 16) & 0xf;
1941 tmp = load_reg(s, rd);
1942 gen_op_iwmmxt_movq_M0_wRn(wrd);
1943 switch ((insn >> 6) & 3) {
1944 case 0:
1945 tmp2 = tcg_const_i32(0xff);
1946 tmp3 = tcg_const_i32((insn & 7) << 3);
1947 break;
1948 case 1:
1949 tmp2 = tcg_const_i32(0xffff);
1950 tmp3 = tcg_const_i32((insn & 3) << 4);
1951 break;
1952 case 2:
1953 tmp2 = tcg_const_i32(0xffffffff);
1954 tmp3 = tcg_const_i32((insn & 1) << 5);
1955 break;
1956 default:
1957 TCGV_UNUSED_I32(tmp2);
1958 TCGV_UNUSED_I32(tmp3);
1960 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1961 tcg_temp_free_i32(tmp3);
1962 tcg_temp_free_i32(tmp2);
1963 tcg_temp_free_i32(tmp);
1964 gen_op_iwmmxt_movq_wRn_M0(wrd);
1965 gen_op_iwmmxt_set_mup();
1966 break;
1967 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1968 rd = (insn >> 12) & 0xf;
1969 wrd = (insn >> 16) & 0xf;
1970 if (rd == 15 || ((insn >> 22) & 3) == 3)
1971 return 1;
1972 gen_op_iwmmxt_movq_M0_wRn(wrd);
1973 tmp = tcg_temp_new_i32();
1974 switch ((insn >> 22) & 3) {
1975 case 0:
1976 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1977 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1978 if (insn & 8) {
1979 tcg_gen_ext8s_i32(tmp, tmp);
1980 } else {
1981 tcg_gen_andi_i32(tmp, tmp, 0xff);
1983 break;
1984 case 1:
1985 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1986 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1987 if (insn & 8) {
1988 tcg_gen_ext16s_i32(tmp, tmp);
1989 } else {
1990 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1992 break;
1993 case 2:
1994 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1995 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1996 break;
1998 store_reg(s, rd, tmp);
1999 break;
2000 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2001 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2002 return 1;
2003 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2004 switch ((insn >> 22) & 3) {
2005 case 0:
2006 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2007 break;
2008 case 1:
2009 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2010 break;
2011 case 2:
2012 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2013 break;
2015 tcg_gen_shli_i32(tmp, tmp, 28);
2016 gen_set_nzcv(tmp);
2017 tcg_temp_free_i32(tmp);
2018 break;
2019 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2020 if (((insn >> 6) & 3) == 3)
2021 return 1;
2022 rd = (insn >> 12) & 0xf;
2023 wrd = (insn >> 16) & 0xf;
2024 tmp = load_reg(s, rd);
2025 switch ((insn >> 6) & 3) {
2026 case 0:
2027 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2028 break;
2029 case 1:
2030 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2031 break;
2032 case 2:
2033 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2034 break;
2036 tcg_temp_free_i32(tmp);
2037 gen_op_iwmmxt_movq_wRn_M0(wrd);
2038 gen_op_iwmmxt_set_mup();
2039 break;
2040 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2041 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2042 return 1;
2043 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2044 tmp2 = tcg_temp_new_i32();
2045 tcg_gen_mov_i32(tmp2, tmp);
2046 switch ((insn >> 22) & 3) {
2047 case 0:
2048 for (i = 0; i < 7; i ++) {
2049 tcg_gen_shli_i32(tmp2, tmp2, 4);
2050 tcg_gen_and_i32(tmp, tmp, tmp2);
2052 break;
2053 case 1:
2054 for (i = 0; i < 3; i ++) {
2055 tcg_gen_shli_i32(tmp2, tmp2, 8);
2056 tcg_gen_and_i32(tmp, tmp, tmp2);
2058 break;
2059 case 2:
2060 tcg_gen_shli_i32(tmp2, tmp2, 16);
2061 tcg_gen_and_i32(tmp, tmp, tmp2);
2062 break;
2064 gen_set_nzcv(tmp);
2065 tcg_temp_free_i32(tmp2);
2066 tcg_temp_free_i32(tmp);
2067 break;
2068 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2069 wrd = (insn >> 12) & 0xf;
2070 rd0 = (insn >> 16) & 0xf;
2071 gen_op_iwmmxt_movq_M0_wRn(rd0);
2072 switch ((insn >> 22) & 3) {
2073 case 0:
2074 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2075 break;
2076 case 1:
2077 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2078 break;
2079 case 2:
2080 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2081 break;
2082 case 3:
2083 return 1;
2085 gen_op_iwmmxt_movq_wRn_M0(wrd);
2086 gen_op_iwmmxt_set_mup();
2087 break;
2088 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2089 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2090 return 1;
2091 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2092 tmp2 = tcg_temp_new_i32();
2093 tcg_gen_mov_i32(tmp2, tmp);
2094 switch ((insn >> 22) & 3) {
2095 case 0:
2096 for (i = 0; i < 7; i ++) {
2097 tcg_gen_shli_i32(tmp2, tmp2, 4);
2098 tcg_gen_or_i32(tmp, tmp, tmp2);
2100 break;
2101 case 1:
2102 for (i = 0; i < 3; i ++) {
2103 tcg_gen_shli_i32(tmp2, tmp2, 8);
2104 tcg_gen_or_i32(tmp, tmp, tmp2);
2106 break;
2107 case 2:
2108 tcg_gen_shli_i32(tmp2, tmp2, 16);
2109 tcg_gen_or_i32(tmp, tmp, tmp2);
2110 break;
2112 gen_set_nzcv(tmp);
2113 tcg_temp_free_i32(tmp2);
2114 tcg_temp_free_i32(tmp);
2115 break;
2116 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2117 rd = (insn >> 12) & 0xf;
2118 rd0 = (insn >> 16) & 0xf;
2119 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2120 return 1;
2121 gen_op_iwmmxt_movq_M0_wRn(rd0);
2122 tmp = tcg_temp_new_i32();
2123 switch ((insn >> 22) & 3) {
2124 case 0:
2125 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2126 break;
2127 case 1:
2128 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2129 break;
2130 case 2:
2131 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2132 break;
2134 store_reg(s, rd, tmp);
2135 break;
2136 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2137 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2138 wrd = (insn >> 12) & 0xf;
2139 rd0 = (insn >> 16) & 0xf;
2140 rd1 = (insn >> 0) & 0xf;
2141 gen_op_iwmmxt_movq_M0_wRn(rd0);
2142 switch ((insn >> 22) & 3) {
2143 case 0:
2144 if (insn & (1 << 21))
2145 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2146 else
2147 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2148 break;
2149 case 1:
2150 if (insn & (1 << 21))
2151 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2152 else
2153 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2154 break;
2155 case 2:
2156 if (insn & (1 << 21))
2157 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2158 else
2159 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2160 break;
2161 case 3:
2162 return 1;
2164 gen_op_iwmmxt_movq_wRn_M0(wrd);
2165 gen_op_iwmmxt_set_mup();
2166 gen_op_iwmmxt_set_cup();
2167 break;
2168 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2169 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2170 wrd = (insn >> 12) & 0xf;
2171 rd0 = (insn >> 16) & 0xf;
2172 gen_op_iwmmxt_movq_M0_wRn(rd0);
2173 switch ((insn >> 22) & 3) {
2174 case 0:
2175 if (insn & (1 << 21))
2176 gen_op_iwmmxt_unpacklsb_M0();
2177 else
2178 gen_op_iwmmxt_unpacklub_M0();
2179 break;
2180 case 1:
2181 if (insn & (1 << 21))
2182 gen_op_iwmmxt_unpacklsw_M0();
2183 else
2184 gen_op_iwmmxt_unpackluw_M0();
2185 break;
2186 case 2:
2187 if (insn & (1 << 21))
2188 gen_op_iwmmxt_unpacklsl_M0();
2189 else
2190 gen_op_iwmmxt_unpacklul_M0();
2191 break;
2192 case 3:
2193 return 1;
2195 gen_op_iwmmxt_movq_wRn_M0(wrd);
2196 gen_op_iwmmxt_set_mup();
2197 gen_op_iwmmxt_set_cup();
2198 break;
2199 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2200 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2201 wrd = (insn >> 12) & 0xf;
2202 rd0 = (insn >> 16) & 0xf;
2203 gen_op_iwmmxt_movq_M0_wRn(rd0);
2204 switch ((insn >> 22) & 3) {
2205 case 0:
2206 if (insn & (1 << 21))
2207 gen_op_iwmmxt_unpackhsb_M0();
2208 else
2209 gen_op_iwmmxt_unpackhub_M0();
2210 break;
2211 case 1:
2212 if (insn & (1 << 21))
2213 gen_op_iwmmxt_unpackhsw_M0();
2214 else
2215 gen_op_iwmmxt_unpackhuw_M0();
2216 break;
2217 case 2:
2218 if (insn & (1 << 21))
2219 gen_op_iwmmxt_unpackhsl_M0();
2220 else
2221 gen_op_iwmmxt_unpackhul_M0();
2222 break;
2223 case 3:
2224 return 1;
2226 gen_op_iwmmxt_movq_wRn_M0(wrd);
2227 gen_op_iwmmxt_set_mup();
2228 gen_op_iwmmxt_set_cup();
2229 break;
2230 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2231 case 0x214: case 0x614: case 0xa14: case 0xe14:
2232 if (((insn >> 22) & 3) == 0)
2233 return 1;
2234 wrd = (insn >> 12) & 0xf;
2235 rd0 = (insn >> 16) & 0xf;
2236 gen_op_iwmmxt_movq_M0_wRn(rd0);
2237 tmp = tcg_temp_new_i32();
2238 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2239 tcg_temp_free_i32(tmp);
2240 return 1;
2242 switch ((insn >> 22) & 3) {
2243 case 1:
2244 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2245 break;
2246 case 2:
2247 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2248 break;
2249 case 3:
2250 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2251 break;
2253 tcg_temp_free_i32(tmp);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2257 break;
2258 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2259 case 0x014: case 0x414: case 0x814: case 0xc14:
2260 if (((insn >> 22) & 3) == 0)
2261 return 1;
2262 wrd = (insn >> 12) & 0xf;
2263 rd0 = (insn >> 16) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0);
2265 tmp = tcg_temp_new_i32();
2266 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2267 tcg_temp_free_i32(tmp);
2268 return 1;
2270 switch ((insn >> 22) & 3) {
2271 case 1:
2272 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2273 break;
2274 case 2:
2275 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2276 break;
2277 case 3:
2278 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2279 break;
2281 tcg_temp_free_i32(tmp);
2282 gen_op_iwmmxt_movq_wRn_M0(wrd);
2283 gen_op_iwmmxt_set_mup();
2284 gen_op_iwmmxt_set_cup();
2285 break;
2286 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2287 case 0x114: case 0x514: case 0x914: case 0xd14:
2288 if (((insn >> 22) & 3) == 0)
2289 return 1;
2290 wrd = (insn >> 12) & 0xf;
2291 rd0 = (insn >> 16) & 0xf;
2292 gen_op_iwmmxt_movq_M0_wRn(rd0);
2293 tmp = tcg_temp_new_i32();
2294 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2295 tcg_temp_free_i32(tmp);
2296 return 1;
2298 switch ((insn >> 22) & 3) {
2299 case 1:
2300 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2301 break;
2302 case 2:
2303 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2304 break;
2305 case 3:
2306 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2307 break;
2309 tcg_temp_free_i32(tmp);
2310 gen_op_iwmmxt_movq_wRn_M0(wrd);
2311 gen_op_iwmmxt_set_mup();
2312 gen_op_iwmmxt_set_cup();
2313 break;
2314 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2315 case 0x314: case 0x714: case 0xb14: case 0xf14:
2316 if (((insn >> 22) & 3) == 0)
2317 return 1;
2318 wrd = (insn >> 12) & 0xf;
2319 rd0 = (insn >> 16) & 0xf;
2320 gen_op_iwmmxt_movq_M0_wRn(rd0);
2321 tmp = tcg_temp_new_i32();
2322 switch ((insn >> 22) & 3) {
2323 case 1:
2324 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2325 tcg_temp_free_i32(tmp);
2326 return 1;
2328 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2329 break;
2330 case 2:
2331 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2332 tcg_temp_free_i32(tmp);
2333 return 1;
2335 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2336 break;
2337 case 3:
2338 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2339 tcg_temp_free_i32(tmp);
2340 return 1;
2342 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2343 break;
2345 tcg_temp_free_i32(tmp);
2346 gen_op_iwmmxt_movq_wRn_M0(wrd);
2347 gen_op_iwmmxt_set_mup();
2348 gen_op_iwmmxt_set_cup();
2349 break;
2350 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2351 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2352 wrd = (insn >> 12) & 0xf;
2353 rd0 = (insn >> 16) & 0xf;
2354 rd1 = (insn >> 0) & 0xf;
2355 gen_op_iwmmxt_movq_M0_wRn(rd0);
2356 switch ((insn >> 22) & 3) {
2357 case 0:
2358 if (insn & (1 << 21))
2359 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2360 else
2361 gen_op_iwmmxt_minub_M0_wRn(rd1);
2362 break;
2363 case 1:
2364 if (insn & (1 << 21))
2365 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2366 else
2367 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2368 break;
2369 case 2:
2370 if (insn & (1 << 21))
2371 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2372 else
2373 gen_op_iwmmxt_minul_M0_wRn(rd1);
2374 break;
2375 case 3:
2376 return 1;
2378 gen_op_iwmmxt_movq_wRn_M0(wrd);
2379 gen_op_iwmmxt_set_mup();
2380 break;
2381 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2382 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2383 wrd = (insn >> 12) & 0xf;
2384 rd0 = (insn >> 16) & 0xf;
2385 rd1 = (insn >> 0) & 0xf;
2386 gen_op_iwmmxt_movq_M0_wRn(rd0);
2387 switch ((insn >> 22) & 3) {
2388 case 0:
2389 if (insn & (1 << 21))
2390 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2391 else
2392 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2393 break;
2394 case 1:
2395 if (insn & (1 << 21))
2396 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2397 else
2398 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2399 break;
2400 case 2:
2401 if (insn & (1 << 21))
2402 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2403 else
2404 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2405 break;
2406 case 3:
2407 return 1;
2409 gen_op_iwmmxt_movq_wRn_M0(wrd);
2410 gen_op_iwmmxt_set_mup();
2411 break;
2412 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2413 case 0x402: case 0x502: case 0x602: case 0x702:
2414 wrd = (insn >> 12) & 0xf;
2415 rd0 = (insn >> 16) & 0xf;
2416 rd1 = (insn >> 0) & 0xf;
2417 gen_op_iwmmxt_movq_M0_wRn(rd0);
2418 tmp = tcg_const_i32((insn >> 20) & 3);
2419 iwmmxt_load_reg(cpu_V1, rd1);
2420 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2421 tcg_temp_free_i32(tmp);
2422 gen_op_iwmmxt_movq_wRn_M0(wrd);
2423 gen_op_iwmmxt_set_mup();
2424 break;
2425 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2426 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2427 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2428 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2429 wrd = (insn >> 12) & 0xf;
2430 rd0 = (insn >> 16) & 0xf;
2431 rd1 = (insn >> 0) & 0xf;
2432 gen_op_iwmmxt_movq_M0_wRn(rd0);
2433 switch ((insn >> 20) & 0xf) {
2434 case 0x0:
2435 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2436 break;
2437 case 0x1:
2438 gen_op_iwmmxt_subub_M0_wRn(rd1);
2439 break;
2440 case 0x3:
2441 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2442 break;
2443 case 0x4:
2444 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2445 break;
2446 case 0x5:
2447 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2448 break;
2449 case 0x7:
2450 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2451 break;
2452 case 0x8:
2453 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2454 break;
2455 case 0x9:
2456 gen_op_iwmmxt_subul_M0_wRn(rd1);
2457 break;
2458 case 0xb:
2459 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2460 break;
2461 default:
2462 return 1;
2464 gen_op_iwmmxt_movq_wRn_M0(wrd);
2465 gen_op_iwmmxt_set_mup();
2466 gen_op_iwmmxt_set_cup();
2467 break;
2468 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2469 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2470 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2471 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2472 wrd = (insn >> 12) & 0xf;
2473 rd0 = (insn >> 16) & 0xf;
2474 gen_op_iwmmxt_movq_M0_wRn(rd0);
2475 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2476 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2477 tcg_temp_free_i32(tmp);
2478 gen_op_iwmmxt_movq_wRn_M0(wrd);
2479 gen_op_iwmmxt_set_mup();
2480 gen_op_iwmmxt_set_cup();
2481 break;
2482 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2483 case 0x418: case 0x518: case 0x618: case 0x718:
2484 case 0x818: case 0x918: case 0xa18: case 0xb18:
2485 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2486 wrd = (insn >> 12) & 0xf;
2487 rd0 = (insn >> 16) & 0xf;
2488 rd1 = (insn >> 0) & 0xf;
2489 gen_op_iwmmxt_movq_M0_wRn(rd0);
2490 switch ((insn >> 20) & 0xf) {
2491 case 0x0:
2492 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2493 break;
2494 case 0x1:
2495 gen_op_iwmmxt_addub_M0_wRn(rd1);
2496 break;
2497 case 0x3:
2498 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2499 break;
2500 case 0x4:
2501 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2502 break;
2503 case 0x5:
2504 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2505 break;
2506 case 0x7:
2507 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2508 break;
2509 case 0x8:
2510 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2511 break;
2512 case 0x9:
2513 gen_op_iwmmxt_addul_M0_wRn(rd1);
2514 break;
2515 case 0xb:
2516 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2517 break;
2518 default:
2519 return 1;
2521 gen_op_iwmmxt_movq_wRn_M0(wrd);
2522 gen_op_iwmmxt_set_mup();
2523 gen_op_iwmmxt_set_cup();
2524 break;
2525 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2526 case 0x408: case 0x508: case 0x608: case 0x708:
2527 case 0x808: case 0x908: case 0xa08: case 0xb08:
2528 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2529 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2530 return 1;
2531 wrd = (insn >> 12) & 0xf;
2532 rd0 = (insn >> 16) & 0xf;
2533 rd1 = (insn >> 0) & 0xf;
2534 gen_op_iwmmxt_movq_M0_wRn(rd0);
2535 switch ((insn >> 22) & 3) {
2536 case 1:
2537 if (insn & (1 << 21))
2538 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2539 else
2540 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2541 break;
2542 case 2:
2543 if (insn & (1 << 21))
2544 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2545 else
2546 gen_op_iwmmxt_packul_M0_wRn(rd1);
2547 break;
2548 case 3:
2549 if (insn & (1 << 21))
2550 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2551 else
2552 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2553 break;
2555 gen_op_iwmmxt_movq_wRn_M0(wrd);
2556 gen_op_iwmmxt_set_mup();
2557 gen_op_iwmmxt_set_cup();
2558 break;
2559 case 0x201: case 0x203: case 0x205: case 0x207:
2560 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2561 case 0x211: case 0x213: case 0x215: case 0x217:
2562 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2563 wrd = (insn >> 5) & 0xf;
2564 rd0 = (insn >> 12) & 0xf;
2565 rd1 = (insn >> 0) & 0xf;
2566 if (rd0 == 0xf || rd1 == 0xf)
2567 return 1;
2568 gen_op_iwmmxt_movq_M0_wRn(wrd);
2569 tmp = load_reg(s, rd0);
2570 tmp2 = load_reg(s, rd1);
2571 switch ((insn >> 16) & 0xf) {
2572 case 0x0: /* TMIA */
2573 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2574 break;
2575 case 0x8: /* TMIAPH */
2576 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2577 break;
2578 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2579 if (insn & (1 << 16))
2580 tcg_gen_shri_i32(tmp, tmp, 16);
2581 if (insn & (1 << 17))
2582 tcg_gen_shri_i32(tmp2, tmp2, 16);
2583 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2584 break;
2585 default:
2586 tcg_temp_free_i32(tmp2);
2587 tcg_temp_free_i32(tmp);
2588 return 1;
2590 tcg_temp_free_i32(tmp2);
2591 tcg_temp_free_i32(tmp);
2592 gen_op_iwmmxt_movq_wRn_M0(wrd);
2593 gen_op_iwmmxt_set_mup();
2594 break;
2595 default:
2596 return 1;
2599 return 0;
2602 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2603 (ie. an undefined instruction). */
2604 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2606 int acc, rd0, rd1, rdhi, rdlo;
2607 TCGv_i32 tmp, tmp2;
2609 if ((insn & 0x0ff00f10) == 0x0e200010) {
2610 /* Multiply with Internal Accumulate Format */
2611 rd0 = (insn >> 12) & 0xf;
2612 rd1 = insn & 0xf;
2613 acc = (insn >> 5) & 7;
2615 if (acc != 0)
2616 return 1;
2618 tmp = load_reg(s, rd0);
2619 tmp2 = load_reg(s, rd1);
2620 switch ((insn >> 16) & 0xf) {
2621 case 0x0: /* MIA */
2622 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2623 break;
2624 case 0x8: /* MIAPH */
2625 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2626 break;
2627 case 0xc: /* MIABB */
2628 case 0xd: /* MIABT */
2629 case 0xe: /* MIATB */
2630 case 0xf: /* MIATT */
2631 if (insn & (1 << 16))
2632 tcg_gen_shri_i32(tmp, tmp, 16);
2633 if (insn & (1 << 17))
2634 tcg_gen_shri_i32(tmp2, tmp2, 16);
2635 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2636 break;
2637 default:
2638 return 1;
2640 tcg_temp_free_i32(tmp2);
2641 tcg_temp_free_i32(tmp);
2643 gen_op_iwmmxt_movq_wRn_M0(acc);
2644 return 0;
2647 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2648 /* Internal Accumulator Access Format */
2649 rdhi = (insn >> 16) & 0xf;
2650 rdlo = (insn >> 12) & 0xf;
2651 acc = insn & 7;
2653 if (acc != 0)
2654 return 1;
2656 if (insn & ARM_CP_RW_BIT) { /* MRA */
2657 iwmmxt_load_reg(cpu_V0, acc);
2658 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2659 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2660 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2661 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2662 } else { /* MAR */
2663 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2664 iwmmxt_store_reg(cpu_V0, acc);
2666 return 0;
2669 return 1;
2672 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2673 #define VFP_SREG(insn, bigbit, smallbit) \
2674 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2675 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2676 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2677 reg = (((insn) >> (bigbit)) & 0x0f) \
2678 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2679 } else { \
2680 if (insn & (1 << (smallbit))) \
2681 return 1; \
2682 reg = ((insn) >> (bigbit)) & 0x0f; \
2683 }} while (0)
2685 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2686 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2687 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2688 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2689 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2690 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2692 /* Move between integer and VFP cores. */
2693 static TCGv_i32 gen_vfp_mrs(void)
2695 TCGv_i32 tmp = tcg_temp_new_i32();
2696 tcg_gen_mov_i32(tmp, cpu_F0s);
2697 return tmp;
2700 static void gen_vfp_msr(TCGv_i32 tmp)
2702 tcg_gen_mov_i32(cpu_F0s, tmp);
2703 tcg_temp_free_i32(tmp);
2706 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2708 TCGv_i32 tmp = tcg_temp_new_i32();
2709 if (shift)
2710 tcg_gen_shri_i32(var, var, shift);
2711 tcg_gen_ext8u_i32(var, var);
2712 tcg_gen_shli_i32(tmp, var, 8);
2713 tcg_gen_or_i32(var, var, tmp);
2714 tcg_gen_shli_i32(tmp, var, 16);
2715 tcg_gen_or_i32(var, var, tmp);
2716 tcg_temp_free_i32(tmp);
2719 static void gen_neon_dup_low16(TCGv_i32 var)
2721 TCGv_i32 tmp = tcg_temp_new_i32();
2722 tcg_gen_ext16u_i32(var, var);
2723 tcg_gen_shli_i32(tmp, var, 16);
2724 tcg_gen_or_i32(var, var, tmp);
2725 tcg_temp_free_i32(tmp);
2728 static void gen_neon_dup_high16(TCGv_i32 var)
2730 TCGv_i32 tmp = tcg_temp_new_i32();
2731 tcg_gen_andi_i32(var, var, 0xffff0000);
2732 tcg_gen_shri_i32(tmp, var, 16);
2733 tcg_gen_or_i32(var, var, tmp);
2734 tcg_temp_free_i32(tmp);
2737 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2739 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2740 TCGv_i32 tmp = tcg_temp_new_i32();
2741 switch (size) {
2742 case 0:
2743 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
2744 gen_neon_dup_u8(tmp, 0);
2745 break;
2746 case 1:
2747 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
2748 gen_neon_dup_low16(tmp);
2749 break;
2750 case 2:
2751 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
2752 break;
2753 default: /* Avoid compiler warnings. */
2754 abort();
2756 return tmp;
2759 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2760 uint32_t dp)
2762 uint32_t cc = extract32(insn, 20, 2);
2764 if (dp) {
2765 TCGv_i64 frn, frm, dest;
2766 TCGv_i64 tmp, zero, zf, nf, vf;
2768 zero = tcg_const_i64(0);
2770 frn = tcg_temp_new_i64();
2771 frm = tcg_temp_new_i64();
2772 dest = tcg_temp_new_i64();
2774 zf = tcg_temp_new_i64();
2775 nf = tcg_temp_new_i64();
2776 vf = tcg_temp_new_i64();
2778 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2779 tcg_gen_ext_i32_i64(nf, cpu_NF);
2780 tcg_gen_ext_i32_i64(vf, cpu_VF);
2782 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2783 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2784 switch (cc) {
2785 case 0: /* eq: Z */
2786 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2787 frn, frm);
2788 break;
2789 case 1: /* vs: V */
2790 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2791 frn, frm);
2792 break;
2793 case 2: /* ge: N == V -> N ^ V == 0 */
2794 tmp = tcg_temp_new_i64();
2795 tcg_gen_xor_i64(tmp, vf, nf);
2796 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2797 frn, frm);
2798 tcg_temp_free_i64(tmp);
2799 break;
2800 case 3: /* gt: !Z && N == V */
2801 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2802 frn, frm);
2803 tmp = tcg_temp_new_i64();
2804 tcg_gen_xor_i64(tmp, vf, nf);
2805 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2806 dest, frm);
2807 tcg_temp_free_i64(tmp);
2808 break;
2810 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2811 tcg_temp_free_i64(frn);
2812 tcg_temp_free_i64(frm);
2813 tcg_temp_free_i64(dest);
2815 tcg_temp_free_i64(zf);
2816 tcg_temp_free_i64(nf);
2817 tcg_temp_free_i64(vf);
2819 tcg_temp_free_i64(zero);
2820 } else {
2821 TCGv_i32 frn, frm, dest;
2822 TCGv_i32 tmp, zero;
2824 zero = tcg_const_i32(0);
2826 frn = tcg_temp_new_i32();
2827 frm = tcg_temp_new_i32();
2828 dest = tcg_temp_new_i32();
2829 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2830 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2831 switch (cc) {
2832 case 0: /* eq: Z */
2833 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2834 frn, frm);
2835 break;
2836 case 1: /* vs: V */
2837 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2838 frn, frm);
2839 break;
2840 case 2: /* ge: N == V -> N ^ V == 0 */
2841 tmp = tcg_temp_new_i32();
2842 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2843 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2844 frn, frm);
2845 tcg_temp_free_i32(tmp);
2846 break;
2847 case 3: /* gt: !Z && N == V */
2848 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2849 frn, frm);
2850 tmp = tcg_temp_new_i32();
2851 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2852 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2853 dest, frm);
2854 tcg_temp_free_i32(tmp);
2855 break;
2857 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2858 tcg_temp_free_i32(frn);
2859 tcg_temp_free_i32(frm);
2860 tcg_temp_free_i32(dest);
2862 tcg_temp_free_i32(zero);
2865 return 0;
2868 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2869 uint32_t rm, uint32_t dp)
2871 uint32_t vmin = extract32(insn, 6, 1);
2872 TCGv_ptr fpst = get_fpstatus_ptr(0);
2874 if (dp) {
2875 TCGv_i64 frn, frm, dest;
2877 frn = tcg_temp_new_i64();
2878 frm = tcg_temp_new_i64();
2879 dest = tcg_temp_new_i64();
2881 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2882 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2883 if (vmin) {
2884 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2885 } else {
2886 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2888 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2889 tcg_temp_free_i64(frn);
2890 tcg_temp_free_i64(frm);
2891 tcg_temp_free_i64(dest);
2892 } else {
2893 TCGv_i32 frn, frm, dest;
2895 frn = tcg_temp_new_i32();
2896 frm = tcg_temp_new_i32();
2897 dest = tcg_temp_new_i32();
2899 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2900 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2901 if (vmin) {
2902 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2903 } else {
2904 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2906 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2907 tcg_temp_free_i32(frn);
2908 tcg_temp_free_i32(frm);
2909 tcg_temp_free_i32(dest);
2912 tcg_temp_free_ptr(fpst);
2913 return 0;
2916 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2917 int rounding)
2919 TCGv_ptr fpst = get_fpstatus_ptr(0);
2920 TCGv_i32 tcg_rmode;
2922 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2923 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2925 if (dp) {
2926 TCGv_i64 tcg_op;
2927 TCGv_i64 tcg_res;
2928 tcg_op = tcg_temp_new_i64();
2929 tcg_res = tcg_temp_new_i64();
2930 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2931 gen_helper_rintd(tcg_res, tcg_op, fpst);
2932 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2933 tcg_temp_free_i64(tcg_op);
2934 tcg_temp_free_i64(tcg_res);
2935 } else {
2936 TCGv_i32 tcg_op;
2937 TCGv_i32 tcg_res;
2938 tcg_op = tcg_temp_new_i32();
2939 tcg_res = tcg_temp_new_i32();
2940 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2941 gen_helper_rints(tcg_res, tcg_op, fpst);
2942 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2943 tcg_temp_free_i32(tcg_op);
2944 tcg_temp_free_i32(tcg_res);
2947 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2948 tcg_temp_free_i32(tcg_rmode);
2950 tcg_temp_free_ptr(fpst);
2951 return 0;
2954 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2955 int rounding)
2957 bool is_signed = extract32(insn, 7, 1);
2958 TCGv_ptr fpst = get_fpstatus_ptr(0);
2959 TCGv_i32 tcg_rmode, tcg_shift;
2961 tcg_shift = tcg_const_i32(0);
2963 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2964 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2966 if (dp) {
2967 TCGv_i64 tcg_double, tcg_res;
2968 TCGv_i32 tcg_tmp;
2969 /* Rd is encoded as a single precision register even when the source
2970 * is double precision.
2972 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2973 tcg_double = tcg_temp_new_i64();
2974 tcg_res = tcg_temp_new_i64();
2975 tcg_tmp = tcg_temp_new_i32();
2976 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2977 if (is_signed) {
2978 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2979 } else {
2980 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2982 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
2983 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2984 tcg_temp_free_i32(tcg_tmp);
2985 tcg_temp_free_i64(tcg_res);
2986 tcg_temp_free_i64(tcg_double);
2987 } else {
2988 TCGv_i32 tcg_single, tcg_res;
2989 tcg_single = tcg_temp_new_i32();
2990 tcg_res = tcg_temp_new_i32();
2991 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2992 if (is_signed) {
2993 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2994 } else {
2995 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2997 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2998 tcg_temp_free_i32(tcg_res);
2999 tcg_temp_free_i32(tcg_single);
3002 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3003 tcg_temp_free_i32(tcg_rmode);
3005 tcg_temp_free_i32(tcg_shift);
3007 tcg_temp_free_ptr(fpst);
3009 return 0;
3012 /* Table for converting the most common AArch32 encoding of
3013 * rounding mode to arm_fprounding order (which matches the
3014 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3016 static const uint8_t fp_decode_rm[] = {
3017 FPROUNDING_TIEAWAY,
3018 FPROUNDING_TIEEVEN,
3019 FPROUNDING_POSINF,
3020 FPROUNDING_NEGINF,
3023 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3025 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3027 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3028 return 1;
3031 if (dp) {
3032 VFP_DREG_D(rd, insn);
3033 VFP_DREG_N(rn, insn);
3034 VFP_DREG_M(rm, insn);
3035 } else {
3036 rd = VFP_SREG_D(insn);
3037 rn = VFP_SREG_N(insn);
3038 rm = VFP_SREG_M(insn);
3041 if ((insn & 0x0f800e50) == 0x0e000a00) {
3042 return handle_vsel(insn, rd, rn, rm, dp);
3043 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3044 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3045 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3046 /* VRINTA, VRINTN, VRINTP, VRINTM */
3047 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3048 return handle_vrint(insn, rd, rm, dp, rounding);
3049 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3050 /* VCVTA, VCVTN, VCVTP, VCVTM */
3051 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3052 return handle_vcvt(insn, rd, rm, dp, rounding);
3054 return 1;
3057 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3058 (ie. an undefined instruction). */
3059 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3061 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3062 int dp, veclen;
3063 TCGv_i32 addr;
3064 TCGv_i32 tmp;
3065 TCGv_i32 tmp2;
3067 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3068 return 1;
3071 /* FIXME: this access check should not take precedence over UNDEF
3072 * for invalid encodings; we will generate incorrect syndrome information
3073 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3075 if (s->fp_excp_el) {
3076 gen_exception_insn(s, 4, EXCP_UDEF,
3077 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
3078 return 0;
3081 if (!s->vfp_enabled) {
3082 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3083 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3084 return 1;
3085 rn = (insn >> 16) & 0xf;
3086 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3087 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3088 return 1;
3092 if (extract32(insn, 28, 4) == 0xf) {
3093 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3094 * only used in v8 and above.
3096 return disas_vfp_v8_insn(s, insn);
3099 dp = ((insn & 0xf00) == 0xb00);
3100 switch ((insn >> 24) & 0xf) {
3101 case 0xe:
3102 if (insn & (1 << 4)) {
3103 /* single register transfer */
3104 rd = (insn >> 12) & 0xf;
3105 if (dp) {
3106 int size;
3107 int pass;
3109 VFP_DREG_N(rn, insn);
3110 if (insn & 0xf)
3111 return 1;
3112 if (insn & 0x00c00060
3113 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3114 return 1;
3117 pass = (insn >> 21) & 1;
3118 if (insn & (1 << 22)) {
3119 size = 0;
3120 offset = ((insn >> 5) & 3) * 8;
3121 } else if (insn & (1 << 5)) {
3122 size = 1;
3123 offset = (insn & (1 << 6)) ? 16 : 0;
3124 } else {
3125 size = 2;
3126 offset = 0;
3128 if (insn & ARM_CP_RW_BIT) {
3129 /* vfp->arm */
3130 tmp = neon_load_reg(rn, pass);
3131 switch (size) {
3132 case 0:
3133 if (offset)
3134 tcg_gen_shri_i32(tmp, tmp, offset);
3135 if (insn & (1 << 23))
3136 gen_uxtb(tmp);
3137 else
3138 gen_sxtb(tmp);
3139 break;
3140 case 1:
3141 if (insn & (1 << 23)) {
3142 if (offset) {
3143 tcg_gen_shri_i32(tmp, tmp, 16);
3144 } else {
3145 gen_uxth(tmp);
3147 } else {
3148 if (offset) {
3149 tcg_gen_sari_i32(tmp, tmp, 16);
3150 } else {
3151 gen_sxth(tmp);
3154 break;
3155 case 2:
3156 break;
3158 store_reg(s, rd, tmp);
3159 } else {
3160 /* arm->vfp */
3161 tmp = load_reg(s, rd);
3162 if (insn & (1 << 23)) {
3163 /* VDUP */
3164 if (size == 0) {
3165 gen_neon_dup_u8(tmp, 0);
3166 } else if (size == 1) {
3167 gen_neon_dup_low16(tmp);
3169 for (n = 0; n <= pass * 2; n++) {
3170 tmp2 = tcg_temp_new_i32();
3171 tcg_gen_mov_i32(tmp2, tmp);
3172 neon_store_reg(rn, n, tmp2);
3174 neon_store_reg(rn, n, tmp);
3175 } else {
3176 /* VMOV */
3177 switch (size) {
3178 case 0:
3179 tmp2 = neon_load_reg(rn, pass);
3180 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3181 tcg_temp_free_i32(tmp2);
3182 break;
3183 case 1:
3184 tmp2 = neon_load_reg(rn, pass);
3185 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3186 tcg_temp_free_i32(tmp2);
3187 break;
3188 case 2:
3189 break;
3191 neon_store_reg(rn, pass, tmp);
3194 } else { /* !dp */
3195 if ((insn & 0x6f) != 0x00)
3196 return 1;
3197 rn = VFP_SREG_N(insn);
3198 if (insn & ARM_CP_RW_BIT) {
3199 /* vfp->arm */
3200 if (insn & (1 << 21)) {
3201 /* system register */
3202 rn >>= 1;
3204 switch (rn) {
3205 case ARM_VFP_FPSID:
3206 /* VFP2 allows access to FSID from userspace.
3207 VFP3 restricts all id registers to privileged
3208 accesses. */
3209 if (IS_USER(s)
3210 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3211 return 1;
3213 tmp = load_cpu_field(vfp.xregs[rn]);
3214 break;
3215 case ARM_VFP_FPEXC:
3216 if (IS_USER(s))
3217 return 1;
3218 tmp = load_cpu_field(vfp.xregs[rn]);
3219 break;
3220 case ARM_VFP_FPINST:
3221 case ARM_VFP_FPINST2:
3222 /* Not present in VFP3. */
3223 if (IS_USER(s)
3224 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3225 return 1;
3227 tmp = load_cpu_field(vfp.xregs[rn]);
3228 break;
3229 case ARM_VFP_FPSCR:
3230 if (rd == 15) {
3231 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3232 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3233 } else {
3234 tmp = tcg_temp_new_i32();
3235 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3237 break;
3238 case ARM_VFP_MVFR2:
3239 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3240 return 1;
3242 /* fall through */
3243 case ARM_VFP_MVFR0:
3244 case ARM_VFP_MVFR1:
3245 if (IS_USER(s)
3246 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3247 return 1;
3249 tmp = load_cpu_field(vfp.xregs[rn]);
3250 break;
3251 default:
3252 return 1;
3254 } else {
3255 gen_mov_F0_vreg(0, rn);
3256 tmp = gen_vfp_mrs();
3258 if (rd == 15) {
3259 /* Set the 4 flag bits in the CPSR. */
3260 gen_set_nzcv(tmp);
3261 tcg_temp_free_i32(tmp);
3262 } else {
3263 store_reg(s, rd, tmp);
3265 } else {
3266 /* arm->vfp */
3267 if (insn & (1 << 21)) {
3268 rn >>= 1;
3269 /* system register */
3270 switch (rn) {
3271 case ARM_VFP_FPSID:
3272 case ARM_VFP_MVFR0:
3273 case ARM_VFP_MVFR1:
3274 /* Writes are ignored. */
3275 break;
3276 case ARM_VFP_FPSCR:
3277 tmp = load_reg(s, rd);
3278 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3279 tcg_temp_free_i32(tmp);
3280 gen_lookup_tb(s);
3281 break;
3282 case ARM_VFP_FPEXC:
3283 if (IS_USER(s))
3284 return 1;
3285 /* TODO: VFP subarchitecture support.
3286 * For now, keep the EN bit only */
3287 tmp = load_reg(s, rd);
3288 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3289 store_cpu_field(tmp, vfp.xregs[rn]);
3290 gen_lookup_tb(s);
3291 break;
3292 case ARM_VFP_FPINST:
3293 case ARM_VFP_FPINST2:
3294 if (IS_USER(s)) {
3295 return 1;
3297 tmp = load_reg(s, rd);
3298 store_cpu_field(tmp, vfp.xregs[rn]);
3299 break;
3300 default:
3301 return 1;
3303 } else {
3304 tmp = load_reg(s, rd);
3305 gen_vfp_msr(tmp);
3306 gen_mov_vreg_F0(0, rn);
3310 } else {
3311 /* data processing */
3312 /* The opcode is in bits 23, 21, 20 and 6. */
3313 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3314 if (dp) {
3315 if (op == 15) {
3316 /* rn is opcode */
3317 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3318 } else {
3319 /* rn is register number */
3320 VFP_DREG_N(rn, insn);
3323 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3324 ((rn & 0x1e) == 0x6))) {
3325 /* Integer or single/half precision destination. */
3326 rd = VFP_SREG_D(insn);
3327 } else {
3328 VFP_DREG_D(rd, insn);
3330 if (op == 15 &&
3331 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3332 ((rn & 0x1e) == 0x4))) {
3333 /* VCVT from int or half precision is always from S reg
3334 * regardless of dp bit. VCVT with immediate frac_bits
3335 * has same format as SREG_M.
3337 rm = VFP_SREG_M(insn);
3338 } else {
3339 VFP_DREG_M(rm, insn);
3341 } else {
3342 rn = VFP_SREG_N(insn);
3343 if (op == 15 && rn == 15) {
3344 /* Double precision destination. */
3345 VFP_DREG_D(rd, insn);
3346 } else {
3347 rd = VFP_SREG_D(insn);
3349 /* NB that we implicitly rely on the encoding for the frac_bits
3350 * in VCVT of fixed to float being the same as that of an SREG_M
3352 rm = VFP_SREG_M(insn);
3355 veclen = s->vec_len;
3356 if (op == 15 && rn > 3)
3357 veclen = 0;
3359 /* Shut up compiler warnings. */
3360 delta_m = 0;
3361 delta_d = 0;
3362 bank_mask = 0;
3364 if (veclen > 0) {
3365 if (dp)
3366 bank_mask = 0xc;
3367 else
3368 bank_mask = 0x18;
3370 /* Figure out what type of vector operation this is. */
3371 if ((rd & bank_mask) == 0) {
3372 /* scalar */
3373 veclen = 0;
3374 } else {
3375 if (dp)
3376 delta_d = (s->vec_stride >> 1) + 1;
3377 else
3378 delta_d = s->vec_stride + 1;
3380 if ((rm & bank_mask) == 0) {
3381 /* mixed scalar/vector */
3382 delta_m = 0;
3383 } else {
3384 /* vector */
3385 delta_m = delta_d;
3390 /* Load the initial operands. */
3391 if (op == 15) {
3392 switch (rn) {
3393 case 16:
3394 case 17:
3395 /* Integer source */
3396 gen_mov_F0_vreg(0, rm);
3397 break;
3398 case 8:
3399 case 9:
3400 /* Compare */
3401 gen_mov_F0_vreg(dp, rd);
3402 gen_mov_F1_vreg(dp, rm);
3403 break;
3404 case 10:
3405 case 11:
3406 /* Compare with zero */
3407 gen_mov_F0_vreg(dp, rd);
3408 gen_vfp_F1_ld0(dp);
3409 break;
3410 case 20:
3411 case 21:
3412 case 22:
3413 case 23:
3414 case 28:
3415 case 29:
3416 case 30:
3417 case 31:
3418 /* Source and destination the same. */
3419 gen_mov_F0_vreg(dp, rd);
3420 break;
3421 case 4:
3422 case 5:
3423 case 6:
3424 case 7:
3425 /* VCVTB, VCVTT: only present with the halfprec extension
3426 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3427 * (we choose to UNDEF)
3429 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3430 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3431 return 1;
3433 if (!extract32(rn, 1, 1)) {
3434 /* Half precision source. */
3435 gen_mov_F0_vreg(0, rm);
3436 break;
3438 /* Otherwise fall through */
3439 default:
3440 /* One source operand. */
3441 gen_mov_F0_vreg(dp, rm);
3442 break;
3444 } else {
3445 /* Two source operands. */
3446 gen_mov_F0_vreg(dp, rn);
3447 gen_mov_F1_vreg(dp, rm);
3450 for (;;) {
3451 /* Perform the calculation. */
3452 switch (op) {
3453 case 0: /* VMLA: fd + (fn * fm) */
3454 /* Note that order of inputs to the add matters for NaNs */
3455 gen_vfp_F1_mul(dp);
3456 gen_mov_F0_vreg(dp, rd);
3457 gen_vfp_add(dp);
3458 break;
3459 case 1: /* VMLS: fd + -(fn * fm) */
3460 gen_vfp_mul(dp);
3461 gen_vfp_F1_neg(dp);
3462 gen_mov_F0_vreg(dp, rd);
3463 gen_vfp_add(dp);
3464 break;
3465 case 2: /* VNMLS: -fd + (fn * fm) */
3466 /* Note that it isn't valid to replace (-A + B) with (B - A)
3467 * or similar plausible looking simplifications
3468 * because this will give wrong results for NaNs.
3470 gen_vfp_F1_mul(dp);
3471 gen_mov_F0_vreg(dp, rd);
3472 gen_vfp_neg(dp);
3473 gen_vfp_add(dp);
3474 break;
3475 case 3: /* VNMLA: -fd + -(fn * fm) */
3476 gen_vfp_mul(dp);
3477 gen_vfp_F1_neg(dp);
3478 gen_mov_F0_vreg(dp, rd);
3479 gen_vfp_neg(dp);
3480 gen_vfp_add(dp);
3481 break;
3482 case 4: /* mul: fn * fm */
3483 gen_vfp_mul(dp);
3484 break;
3485 case 5: /* nmul: -(fn * fm) */
3486 gen_vfp_mul(dp);
3487 gen_vfp_neg(dp);
3488 break;
3489 case 6: /* add: fn + fm */
3490 gen_vfp_add(dp);
3491 break;
3492 case 7: /* sub: fn - fm */
3493 gen_vfp_sub(dp);
3494 break;
3495 case 8: /* div: fn / fm */
3496 gen_vfp_div(dp);
3497 break;
3498 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3499 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3500 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3501 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3502 /* These are fused multiply-add, and must be done as one
3503 * floating point operation with no rounding between the
3504 * multiplication and addition steps.
3505 * NB that doing the negations here as separate steps is
3506 * correct : an input NaN should come out with its sign bit
3507 * flipped if it is a negated-input.
3509 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3510 return 1;
3512 if (dp) {
3513 TCGv_ptr fpst;
3514 TCGv_i64 frd;
3515 if (op & 1) {
3516 /* VFNMS, VFMS */
3517 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3519 frd = tcg_temp_new_i64();
3520 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3521 if (op & 2) {
3522 /* VFNMA, VFNMS */
3523 gen_helper_vfp_negd(frd, frd);
3525 fpst = get_fpstatus_ptr(0);
3526 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3527 cpu_F1d, frd, fpst);
3528 tcg_temp_free_ptr(fpst);
3529 tcg_temp_free_i64(frd);
3530 } else {
3531 TCGv_ptr fpst;
3532 TCGv_i32 frd;
3533 if (op & 1) {
3534 /* VFNMS, VFMS */
3535 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3537 frd = tcg_temp_new_i32();
3538 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3539 if (op & 2) {
3540 gen_helper_vfp_negs(frd, frd);
3542 fpst = get_fpstatus_ptr(0);
3543 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3544 cpu_F1s, frd, fpst);
3545 tcg_temp_free_ptr(fpst);
3546 tcg_temp_free_i32(frd);
3548 break;
3549 case 14: /* fconst */
3550 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3551 return 1;
3554 n = (insn << 12) & 0x80000000;
3555 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3556 if (dp) {
3557 if (i & 0x40)
3558 i |= 0x3f80;
3559 else
3560 i |= 0x4000;
3561 n |= i << 16;
3562 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3563 } else {
3564 if (i & 0x40)
3565 i |= 0x780;
3566 else
3567 i |= 0x800;
3568 n |= i << 19;
3569 tcg_gen_movi_i32(cpu_F0s, n);
3571 break;
3572 case 15: /* extension space */
3573 switch (rn) {
3574 case 0: /* cpy */
3575 /* no-op */
3576 break;
3577 case 1: /* abs */
3578 gen_vfp_abs(dp);
3579 break;
3580 case 2: /* neg */
3581 gen_vfp_neg(dp);
3582 break;
3583 case 3: /* sqrt */
3584 gen_vfp_sqrt(dp);
3585 break;
3586 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3587 tmp = gen_vfp_mrs();
3588 tcg_gen_ext16u_i32(tmp, tmp);
3589 if (dp) {
3590 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3591 cpu_env);
3592 } else {
3593 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3594 cpu_env);
3596 tcg_temp_free_i32(tmp);
3597 break;
3598 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3599 tmp = gen_vfp_mrs();
3600 tcg_gen_shri_i32(tmp, tmp, 16);
3601 if (dp) {
3602 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3603 cpu_env);
3604 } else {
3605 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3606 cpu_env);
3608 tcg_temp_free_i32(tmp);
3609 break;
3610 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3611 tmp = tcg_temp_new_i32();
3612 if (dp) {
3613 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3614 cpu_env);
3615 } else {
3616 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3617 cpu_env);
3619 gen_mov_F0_vreg(0, rd);
3620 tmp2 = gen_vfp_mrs();
3621 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3622 tcg_gen_or_i32(tmp, tmp, tmp2);
3623 tcg_temp_free_i32(tmp2);
3624 gen_vfp_msr(tmp);
3625 break;
3626 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3627 tmp = tcg_temp_new_i32();
3628 if (dp) {
3629 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3630 cpu_env);
3631 } else {
3632 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3633 cpu_env);
3635 tcg_gen_shli_i32(tmp, tmp, 16);
3636 gen_mov_F0_vreg(0, rd);
3637 tmp2 = gen_vfp_mrs();
3638 tcg_gen_ext16u_i32(tmp2, tmp2);
3639 tcg_gen_or_i32(tmp, tmp, tmp2);
3640 tcg_temp_free_i32(tmp2);
3641 gen_vfp_msr(tmp);
3642 break;
3643 case 8: /* cmp */
3644 gen_vfp_cmp(dp);
3645 break;
3646 case 9: /* cmpe */
3647 gen_vfp_cmpe(dp);
3648 break;
3649 case 10: /* cmpz */
3650 gen_vfp_cmp(dp);
3651 break;
3652 case 11: /* cmpez */
3653 gen_vfp_F1_ld0(dp);
3654 gen_vfp_cmpe(dp);
3655 break;
3656 case 12: /* vrintr */
3658 TCGv_ptr fpst = get_fpstatus_ptr(0);
3659 if (dp) {
3660 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3661 } else {
3662 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3664 tcg_temp_free_ptr(fpst);
3665 break;
3667 case 13: /* vrintz */
3669 TCGv_ptr fpst = get_fpstatus_ptr(0);
3670 TCGv_i32 tcg_rmode;
3671 tcg_rmode = tcg_const_i32(float_round_to_zero);
3672 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3673 if (dp) {
3674 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3675 } else {
3676 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3678 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3679 tcg_temp_free_i32(tcg_rmode);
3680 tcg_temp_free_ptr(fpst);
3681 break;
3683 case 14: /* vrintx */
3685 TCGv_ptr fpst = get_fpstatus_ptr(0);
3686 if (dp) {
3687 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3688 } else {
3689 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3691 tcg_temp_free_ptr(fpst);
3692 break;
3694 case 15: /* single<->double conversion */
3695 if (dp)
3696 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3697 else
3698 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3699 break;
3700 case 16: /* fuito */
3701 gen_vfp_uito(dp, 0);
3702 break;
3703 case 17: /* fsito */
3704 gen_vfp_sito(dp, 0);
3705 break;
3706 case 20: /* fshto */
3707 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3708 return 1;
3710 gen_vfp_shto(dp, 16 - rm, 0);
3711 break;
3712 case 21: /* fslto */
3713 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3714 return 1;
3716 gen_vfp_slto(dp, 32 - rm, 0);
3717 break;
3718 case 22: /* fuhto */
3719 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3720 return 1;
3722 gen_vfp_uhto(dp, 16 - rm, 0);
3723 break;
3724 case 23: /* fulto */
3725 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3726 return 1;
3728 gen_vfp_ulto(dp, 32 - rm, 0);
3729 break;
3730 case 24: /* ftoui */
3731 gen_vfp_toui(dp, 0);
3732 break;
3733 case 25: /* ftouiz */
3734 gen_vfp_touiz(dp, 0);
3735 break;
3736 case 26: /* ftosi */
3737 gen_vfp_tosi(dp, 0);
3738 break;
3739 case 27: /* ftosiz */
3740 gen_vfp_tosiz(dp, 0);
3741 break;
3742 case 28: /* ftosh */
3743 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3744 return 1;
3746 gen_vfp_tosh(dp, 16 - rm, 0);
3747 break;
3748 case 29: /* ftosl */
3749 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3750 return 1;
3752 gen_vfp_tosl(dp, 32 - rm, 0);
3753 break;
3754 case 30: /* ftouh */
3755 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3756 return 1;
3758 gen_vfp_touh(dp, 16 - rm, 0);
3759 break;
3760 case 31: /* ftoul */
3761 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3762 return 1;
3764 gen_vfp_toul(dp, 32 - rm, 0);
3765 break;
3766 default: /* undefined */
3767 return 1;
3769 break;
3770 default: /* undefined */
3771 return 1;
3774 /* Write back the result. */
3775 if (op == 15 && (rn >= 8 && rn <= 11)) {
3776 /* Comparison, do nothing. */
3777 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3778 (rn & 0x1e) == 0x6)) {
3779 /* VCVT double to int: always integer result.
3780 * VCVT double to half precision is always a single
3781 * precision result.
3783 gen_mov_vreg_F0(0, rd);
3784 } else if (op == 15 && rn == 15) {
3785 /* conversion */
3786 gen_mov_vreg_F0(!dp, rd);
3787 } else {
3788 gen_mov_vreg_F0(dp, rd);
3791 /* break out of the loop if we have finished */
3792 if (veclen == 0)
3793 break;
3795 if (op == 15 && delta_m == 0) {
3796 /* single source one-many */
3797 while (veclen--) {
3798 rd = ((rd + delta_d) & (bank_mask - 1))
3799 | (rd & bank_mask);
3800 gen_mov_vreg_F0(dp, rd);
3802 break;
3804 /* Setup the next operands. */
3805 veclen--;
3806 rd = ((rd + delta_d) & (bank_mask - 1))
3807 | (rd & bank_mask);
3809 if (op == 15) {
3810 /* One source operand. */
3811 rm = ((rm + delta_m) & (bank_mask - 1))
3812 | (rm & bank_mask);
3813 gen_mov_F0_vreg(dp, rm);
3814 } else {
3815 /* Two source operands. */
3816 rn = ((rn + delta_d) & (bank_mask - 1))
3817 | (rn & bank_mask);
3818 gen_mov_F0_vreg(dp, rn);
3819 if (delta_m) {
3820 rm = ((rm + delta_m) & (bank_mask - 1))
3821 | (rm & bank_mask);
3822 gen_mov_F1_vreg(dp, rm);
3827 break;
3828 case 0xc:
3829 case 0xd:
3830 if ((insn & 0x03e00000) == 0x00400000) {
3831 /* two-register transfer */
3832 rn = (insn >> 16) & 0xf;
3833 rd = (insn >> 12) & 0xf;
3834 if (dp) {
3835 VFP_DREG_M(rm, insn);
3836 } else {
3837 rm = VFP_SREG_M(insn);
3840 if (insn & ARM_CP_RW_BIT) {
3841 /* vfp->arm */
3842 if (dp) {
3843 gen_mov_F0_vreg(0, rm * 2);
3844 tmp = gen_vfp_mrs();
3845 store_reg(s, rd, tmp);
3846 gen_mov_F0_vreg(0, rm * 2 + 1);
3847 tmp = gen_vfp_mrs();
3848 store_reg(s, rn, tmp);
3849 } else {
3850 gen_mov_F0_vreg(0, rm);
3851 tmp = gen_vfp_mrs();
3852 store_reg(s, rd, tmp);
3853 gen_mov_F0_vreg(0, rm + 1);
3854 tmp = gen_vfp_mrs();
3855 store_reg(s, rn, tmp);
3857 } else {
3858 /* arm->vfp */
3859 if (dp) {
3860 tmp = load_reg(s, rd);
3861 gen_vfp_msr(tmp);
3862 gen_mov_vreg_F0(0, rm * 2);
3863 tmp = load_reg(s, rn);
3864 gen_vfp_msr(tmp);
3865 gen_mov_vreg_F0(0, rm * 2 + 1);
3866 } else {
3867 tmp = load_reg(s, rd);
3868 gen_vfp_msr(tmp);
3869 gen_mov_vreg_F0(0, rm);
3870 tmp = load_reg(s, rn);
3871 gen_vfp_msr(tmp);
3872 gen_mov_vreg_F0(0, rm + 1);
3875 } else {
3876 /* Load/store */
3877 rn = (insn >> 16) & 0xf;
3878 if (dp)
3879 VFP_DREG_D(rd, insn);
3880 else
3881 rd = VFP_SREG_D(insn);
3882 if ((insn & 0x01200000) == 0x01000000) {
3883 /* Single load/store */
3884 offset = (insn & 0xff) << 2;
3885 if ((insn & (1 << 23)) == 0)
3886 offset = -offset;
3887 if (s->thumb && rn == 15) {
3888 /* This is actually UNPREDICTABLE */
3889 addr = tcg_temp_new_i32();
3890 tcg_gen_movi_i32(addr, s->pc & ~2);
3891 } else {
3892 addr = load_reg(s, rn);
3894 tcg_gen_addi_i32(addr, addr, offset);
3895 if (insn & (1 << 20)) {
3896 gen_vfp_ld(s, dp, addr);
3897 gen_mov_vreg_F0(dp, rd);
3898 } else {
3899 gen_mov_F0_vreg(dp, rd);
3900 gen_vfp_st(s, dp, addr);
3902 tcg_temp_free_i32(addr);
3903 } else {
3904 /* load/store multiple */
3905 int w = insn & (1 << 21);
3906 if (dp)
3907 n = (insn >> 1) & 0x7f;
3908 else
3909 n = insn & 0xff;
3911 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3912 /* P == U , W == 1 => UNDEF */
3913 return 1;
3915 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3916 /* UNPREDICTABLE cases for bad immediates: we choose to
3917 * UNDEF to avoid generating huge numbers of TCG ops
3919 return 1;
3921 if (rn == 15 && w) {
3922 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3923 return 1;
3926 if (s->thumb && rn == 15) {
3927 /* This is actually UNPREDICTABLE */
3928 addr = tcg_temp_new_i32();
3929 tcg_gen_movi_i32(addr, s->pc & ~2);
3930 } else {
3931 addr = load_reg(s, rn);
3933 if (insn & (1 << 24)) /* pre-decrement */
3934 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3936 if (dp)
3937 offset = 8;
3938 else
3939 offset = 4;
3940 for (i = 0; i < n; i++) {
3941 if (insn & ARM_CP_RW_BIT) {
3942 /* load */
3943 gen_vfp_ld(s, dp, addr);
3944 gen_mov_vreg_F0(dp, rd + i);
3945 } else {
3946 /* store */
3947 gen_mov_F0_vreg(dp, rd + i);
3948 gen_vfp_st(s, dp, addr);
3950 tcg_gen_addi_i32(addr, addr, offset);
3952 if (w) {
3953 /* writeback */
3954 if (insn & (1 << 24))
3955 offset = -offset * n;
3956 else if (dp && (insn & 1))
3957 offset = 4;
3958 else
3959 offset = 0;
3961 if (offset != 0)
3962 tcg_gen_addi_i32(addr, addr, offset);
3963 store_reg(s, rn, addr);
3964 } else {
3965 tcg_temp_free_i32(addr);
3969 break;
3970 default:
3971 /* Should never happen. */
3972 return 1;
3974 return 0;
3977 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3979 TranslationBlock *tb;
3981 tb = s->tb;
3982 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3983 tcg_gen_goto_tb(n);
3984 gen_set_pc_im(s, dest);
3985 tcg_gen_exit_tb((uintptr_t)tb + n);
3986 } else {
3987 gen_set_pc_im(s, dest);
3988 tcg_gen_exit_tb(0);
3992 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3994 if (unlikely(s->singlestep_enabled || s->ss_active)) {
3995 /* An indirect jump so that we still trigger the debug exception. */
3996 if (s->thumb)
3997 dest |= 1;
3998 gen_bx_im(s, dest);
3999 } else {
4000 gen_goto_tb(s, 0, dest);
4001 s->is_jmp = DISAS_TB_JUMP;
4005 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4007 if (x)
4008 tcg_gen_sari_i32(t0, t0, 16);
4009 else
4010 gen_sxth(t0);
4011 if (y)
4012 tcg_gen_sari_i32(t1, t1, 16);
4013 else
4014 gen_sxth(t1);
4015 tcg_gen_mul_i32(t0, t0, t1);
4018 /* Return the mask of PSR bits set by a MSR instruction. */
4019 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4021 uint32_t mask;
4023 mask = 0;
4024 if (flags & (1 << 0))
4025 mask |= 0xff;
4026 if (flags & (1 << 1))
4027 mask |= 0xff00;
4028 if (flags & (1 << 2))
4029 mask |= 0xff0000;
4030 if (flags & (1 << 3))
4031 mask |= 0xff000000;
4033 /* Mask out undefined bits. */
4034 mask &= ~CPSR_RESERVED;
4035 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4036 mask &= ~CPSR_T;
4038 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4039 mask &= ~CPSR_Q; /* V5TE in reality*/
4041 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4042 mask &= ~(CPSR_E | CPSR_GE);
4044 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4045 mask &= ~CPSR_IT;
4047 /* Mask out execution state and reserved bits. */
4048 if (!spsr) {
4049 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4051 /* Mask out privileged bits. */
4052 if (IS_USER(s))
4053 mask &= CPSR_USER;
4054 return mask;
4057 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4058 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4060 TCGv_i32 tmp;
4061 if (spsr) {
4062 /* ??? This is also undefined in system mode. */
4063 if (IS_USER(s))
4064 return 1;
4066 tmp = load_cpu_field(spsr);
4067 tcg_gen_andi_i32(tmp, tmp, ~mask);
4068 tcg_gen_andi_i32(t0, t0, mask);
4069 tcg_gen_or_i32(tmp, tmp, t0);
4070 store_cpu_field(tmp, spsr);
4071 } else {
4072 gen_set_cpsr(t0, mask);
4074 tcg_temp_free_i32(t0);
4075 gen_lookup_tb(s);
4076 return 0;
4079 /* Returns nonzero if access to the PSR is not permitted. */
4080 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4082 TCGv_i32 tmp;
4083 tmp = tcg_temp_new_i32();
4084 tcg_gen_movi_i32(tmp, val);
4085 return gen_set_psr(s, mask, spsr, tmp);
4088 /* Generate an old-style exception return. Marks pc as dead. */
4089 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4091 TCGv_i32 tmp;
4092 store_reg(s, 15, pc);
4093 tmp = load_cpu_field(spsr);
4094 gen_set_cpsr(tmp, CPSR_ERET_MASK);
4095 tcg_temp_free_i32(tmp);
4096 s->is_jmp = DISAS_UPDATE;
4099 /* Generate a v6 exception return. Marks both values as dead. */
4100 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4102 gen_set_cpsr(cpsr, CPSR_ERET_MASK);
4103 tcg_temp_free_i32(cpsr);
4104 store_reg(s, 15, pc);
4105 s->is_jmp = DISAS_UPDATE;
4108 static void gen_nop_hint(DisasContext *s, int val)
4110 switch (val) {
4111 case 1: /* yield */
4112 gen_set_pc_im(s, s->pc);
4113 s->is_jmp = DISAS_YIELD;
4114 break;
4115 case 3: /* wfi */
4116 gen_set_pc_im(s, s->pc);
4117 s->is_jmp = DISAS_WFI;
4118 break;
4119 case 2: /* wfe */
4120 gen_set_pc_im(s, s->pc);
4121 s->is_jmp = DISAS_WFE;
4122 break;
4123 case 4: /* sev */
4124 case 5: /* sevl */
4125 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4126 default: /* nop */
4127 break;
4131 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4133 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4135 switch (size) {
4136 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4137 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4138 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4139 default: abort();
4143 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4145 switch (size) {
4146 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4147 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4148 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4149 default: return;
4153 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4154 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4155 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4156 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4157 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4159 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4160 switch ((size << 1) | u) { \
4161 case 0: \
4162 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4163 break; \
4164 case 1: \
4165 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4166 break; \
4167 case 2: \
4168 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4169 break; \
4170 case 3: \
4171 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4172 break; \
4173 case 4: \
4174 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4175 break; \
4176 case 5: \
4177 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4178 break; \
4179 default: return 1; \
4180 }} while (0)
4182 #define GEN_NEON_INTEGER_OP(name) do { \
4183 switch ((size << 1) | u) { \
4184 case 0: \
4185 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4186 break; \
4187 case 1: \
4188 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4189 break; \
4190 case 2: \
4191 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4192 break; \
4193 case 3: \
4194 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4195 break; \
4196 case 4: \
4197 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4198 break; \
4199 case 5: \
4200 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4201 break; \
4202 default: return 1; \
4203 }} while (0)
4205 static TCGv_i32 neon_load_scratch(int scratch)
4207 TCGv_i32 tmp = tcg_temp_new_i32();
4208 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4209 return tmp;
4212 static void neon_store_scratch(int scratch, TCGv_i32 var)
4214 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4215 tcg_temp_free_i32(var);
4218 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4220 TCGv_i32 tmp;
4221 if (size == 1) {
4222 tmp = neon_load_reg(reg & 7, reg >> 4);
4223 if (reg & 8) {
4224 gen_neon_dup_high16(tmp);
4225 } else {
4226 gen_neon_dup_low16(tmp);
4228 } else {
4229 tmp = neon_load_reg(reg & 15, reg >> 4);
4231 return tmp;
4234 static int gen_neon_unzip(int rd, int rm, int size, int q)
4236 TCGv_i32 tmp, tmp2;
4237 if (!q && size == 2) {
4238 return 1;
4240 tmp = tcg_const_i32(rd);
4241 tmp2 = tcg_const_i32(rm);
4242 if (q) {
4243 switch (size) {
4244 case 0:
4245 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4246 break;
4247 case 1:
4248 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4249 break;
4250 case 2:
4251 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4252 break;
4253 default:
4254 abort();
4256 } else {
4257 switch (size) {
4258 case 0:
4259 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4260 break;
4261 case 1:
4262 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4263 break;
4264 default:
4265 abort();
4268 tcg_temp_free_i32(tmp);
4269 tcg_temp_free_i32(tmp2);
4270 return 0;
4273 static int gen_neon_zip(int rd, int rm, int size, int q)
4275 TCGv_i32 tmp, tmp2;
4276 if (!q && size == 2) {
4277 return 1;
4279 tmp = tcg_const_i32(rd);
4280 tmp2 = tcg_const_i32(rm);
4281 if (q) {
4282 switch (size) {
4283 case 0:
4284 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4285 break;
4286 case 1:
4287 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4288 break;
4289 case 2:
4290 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4291 break;
4292 default:
4293 abort();
4295 } else {
4296 switch (size) {
4297 case 0:
4298 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4299 break;
4300 case 1:
4301 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4302 break;
4303 default:
4304 abort();
4307 tcg_temp_free_i32(tmp);
4308 tcg_temp_free_i32(tmp2);
4309 return 0;
4312 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4314 TCGv_i32 rd, tmp;
4316 rd = tcg_temp_new_i32();
4317 tmp = tcg_temp_new_i32();
4319 tcg_gen_shli_i32(rd, t0, 8);
4320 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4321 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4322 tcg_gen_or_i32(rd, rd, tmp);
4324 tcg_gen_shri_i32(t1, t1, 8);
4325 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4326 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4327 tcg_gen_or_i32(t1, t1, tmp);
4328 tcg_gen_mov_i32(t0, rd);
4330 tcg_temp_free_i32(tmp);
4331 tcg_temp_free_i32(rd);
4334 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4336 TCGv_i32 rd, tmp;
4338 rd = tcg_temp_new_i32();
4339 tmp = tcg_temp_new_i32();
4341 tcg_gen_shli_i32(rd, t0, 16);
4342 tcg_gen_andi_i32(tmp, t1, 0xffff);
4343 tcg_gen_or_i32(rd, rd, tmp);
4344 tcg_gen_shri_i32(t1, t1, 16);
4345 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4346 tcg_gen_or_i32(t1, t1, tmp);
4347 tcg_gen_mov_i32(t0, rd);
4349 tcg_temp_free_i32(tmp);
4350 tcg_temp_free_i32(rd);
4354 static struct {
4355 int nregs;
4356 int interleave;
4357 int spacing;
4358 } neon_ls_element_type[11] = {
4359 {4, 4, 1},
4360 {4, 4, 2},
4361 {4, 1, 1},
4362 {4, 2, 1},
4363 {3, 3, 1},
4364 {3, 3, 2},
4365 {3, 1, 1},
4366 {1, 1, 1},
4367 {2, 2, 1},
4368 {2, 2, 2},
4369 {2, 1, 1}
4372 /* Translate a NEON load/store element instruction. Return nonzero if the
4373 instruction is invalid. */
4374 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4376 int rd, rn, rm;
4377 int op;
4378 int nregs;
4379 int interleave;
4380 int spacing;
4381 int stride;
4382 int size;
4383 int reg;
4384 int pass;
4385 int load;
4386 int shift;
4387 int n;
4388 TCGv_i32 addr;
4389 TCGv_i32 tmp;
4390 TCGv_i32 tmp2;
4391 TCGv_i64 tmp64;
4393 /* FIXME: this access check should not take precedence over UNDEF
4394 * for invalid encodings; we will generate incorrect syndrome information
4395 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4397 if (s->fp_excp_el) {
4398 gen_exception_insn(s, 4, EXCP_UDEF,
4399 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
4400 return 0;
4403 if (!s->vfp_enabled)
4404 return 1;
4405 VFP_DREG_D(rd, insn);
4406 rn = (insn >> 16) & 0xf;
4407 rm = insn & 0xf;
4408 load = (insn & (1 << 21)) != 0;
4409 if ((insn & (1 << 23)) == 0) {
4410 /* Load store all elements. */
4411 op = (insn >> 8) & 0xf;
4412 size = (insn >> 6) & 3;
4413 if (op > 10)
4414 return 1;
4415 /* Catch UNDEF cases for bad values of align field */
4416 switch (op & 0xc) {
4417 case 4:
4418 if (((insn >> 5) & 1) == 1) {
4419 return 1;
4421 break;
4422 case 8:
4423 if (((insn >> 4) & 3) == 3) {
4424 return 1;
4426 break;
4427 default:
4428 break;
4430 nregs = neon_ls_element_type[op].nregs;
4431 interleave = neon_ls_element_type[op].interleave;
4432 spacing = neon_ls_element_type[op].spacing;
4433 if (size == 3 && (interleave | spacing) != 1)
4434 return 1;
4435 addr = tcg_temp_new_i32();
4436 load_reg_var(s, addr, rn);
4437 stride = (1 << size) * interleave;
4438 for (reg = 0; reg < nregs; reg++) {
4439 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4440 load_reg_var(s, addr, rn);
4441 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4442 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4443 load_reg_var(s, addr, rn);
4444 tcg_gen_addi_i32(addr, addr, 1 << size);
4446 if (size == 3) {
4447 tmp64 = tcg_temp_new_i64();
4448 if (load) {
4449 gen_aa32_ld64(tmp64, addr, get_mem_index(s));
4450 neon_store_reg64(tmp64, rd);
4451 } else {
4452 neon_load_reg64(tmp64, rd);
4453 gen_aa32_st64(tmp64, addr, get_mem_index(s));
4455 tcg_temp_free_i64(tmp64);
4456 tcg_gen_addi_i32(addr, addr, stride);
4457 } else {
4458 for (pass = 0; pass < 2; pass++) {
4459 if (size == 2) {
4460 if (load) {
4461 tmp = tcg_temp_new_i32();
4462 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4463 neon_store_reg(rd, pass, tmp);
4464 } else {
4465 tmp = neon_load_reg(rd, pass);
4466 gen_aa32_st32(tmp, addr, get_mem_index(s));
4467 tcg_temp_free_i32(tmp);
4469 tcg_gen_addi_i32(addr, addr, stride);
4470 } else if (size == 1) {
4471 if (load) {
4472 tmp = tcg_temp_new_i32();
4473 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4474 tcg_gen_addi_i32(addr, addr, stride);
4475 tmp2 = tcg_temp_new_i32();
4476 gen_aa32_ld16u(tmp2, addr, get_mem_index(s));
4477 tcg_gen_addi_i32(addr, addr, stride);
4478 tcg_gen_shli_i32(tmp2, tmp2, 16);
4479 tcg_gen_or_i32(tmp, tmp, tmp2);
4480 tcg_temp_free_i32(tmp2);
4481 neon_store_reg(rd, pass, tmp);
4482 } else {
4483 tmp = neon_load_reg(rd, pass);
4484 tmp2 = tcg_temp_new_i32();
4485 tcg_gen_shri_i32(tmp2, tmp, 16);
4486 gen_aa32_st16(tmp, addr, get_mem_index(s));
4487 tcg_temp_free_i32(tmp);
4488 tcg_gen_addi_i32(addr, addr, stride);
4489 gen_aa32_st16(tmp2, addr, get_mem_index(s));
4490 tcg_temp_free_i32(tmp2);
4491 tcg_gen_addi_i32(addr, addr, stride);
4493 } else /* size == 0 */ {
4494 if (load) {
4495 TCGV_UNUSED_I32(tmp2);
4496 for (n = 0; n < 4; n++) {
4497 tmp = tcg_temp_new_i32();
4498 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4499 tcg_gen_addi_i32(addr, addr, stride);
4500 if (n == 0) {
4501 tmp2 = tmp;
4502 } else {
4503 tcg_gen_shli_i32(tmp, tmp, n * 8);
4504 tcg_gen_or_i32(tmp2, tmp2, tmp);
4505 tcg_temp_free_i32(tmp);
4508 neon_store_reg(rd, pass, tmp2);
4509 } else {
4510 tmp2 = neon_load_reg(rd, pass);
4511 for (n = 0; n < 4; n++) {
4512 tmp = tcg_temp_new_i32();
4513 if (n == 0) {
4514 tcg_gen_mov_i32(tmp, tmp2);
4515 } else {
4516 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4518 gen_aa32_st8(tmp, addr, get_mem_index(s));
4519 tcg_temp_free_i32(tmp);
4520 tcg_gen_addi_i32(addr, addr, stride);
4522 tcg_temp_free_i32(tmp2);
4527 rd += spacing;
4529 tcg_temp_free_i32(addr);
4530 stride = nregs * 8;
4531 } else {
4532 size = (insn >> 10) & 3;
4533 if (size == 3) {
4534 /* Load single element to all lanes. */
4535 int a = (insn >> 4) & 1;
4536 if (!load) {
4537 return 1;
4539 size = (insn >> 6) & 3;
4540 nregs = ((insn >> 8) & 3) + 1;
4542 if (size == 3) {
4543 if (nregs != 4 || a == 0) {
4544 return 1;
4546 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4547 size = 2;
4549 if (nregs == 1 && a == 1 && size == 0) {
4550 return 1;
4552 if (nregs == 3 && a == 1) {
4553 return 1;
4555 addr = tcg_temp_new_i32();
4556 load_reg_var(s, addr, rn);
4557 if (nregs == 1) {
4558 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4559 tmp = gen_load_and_replicate(s, addr, size);
4560 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4561 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4562 if (insn & (1 << 5)) {
4563 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4564 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4566 tcg_temp_free_i32(tmp);
4567 } else {
4568 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4569 stride = (insn & (1 << 5)) ? 2 : 1;
4570 for (reg = 0; reg < nregs; reg++) {
4571 tmp = gen_load_and_replicate(s, addr, size);
4572 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4573 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4574 tcg_temp_free_i32(tmp);
4575 tcg_gen_addi_i32(addr, addr, 1 << size);
4576 rd += stride;
4579 tcg_temp_free_i32(addr);
4580 stride = (1 << size) * nregs;
4581 } else {
4582 /* Single element. */
4583 int idx = (insn >> 4) & 0xf;
4584 pass = (insn >> 7) & 1;
4585 switch (size) {
4586 case 0:
4587 shift = ((insn >> 5) & 3) * 8;
4588 stride = 1;
4589 break;
4590 case 1:
4591 shift = ((insn >> 6) & 1) * 16;
4592 stride = (insn & (1 << 5)) ? 2 : 1;
4593 break;
4594 case 2:
4595 shift = 0;
4596 stride = (insn & (1 << 6)) ? 2 : 1;
4597 break;
4598 default:
4599 abort();
4601 nregs = ((insn >> 8) & 3) + 1;
4602 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4603 switch (nregs) {
4604 case 1:
4605 if (((idx & (1 << size)) != 0) ||
4606 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4607 return 1;
4609 break;
4610 case 3:
4611 if ((idx & 1) != 0) {
4612 return 1;
4614 /* fall through */
4615 case 2:
4616 if (size == 2 && (idx & 2) != 0) {
4617 return 1;
4619 break;
4620 case 4:
4621 if ((size == 2) && ((idx & 3) == 3)) {
4622 return 1;
4624 break;
4625 default:
4626 abort();
4628 if ((rd + stride * (nregs - 1)) > 31) {
4629 /* Attempts to write off the end of the register file
4630 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4631 * the neon_load_reg() would write off the end of the array.
4633 return 1;
4635 addr = tcg_temp_new_i32();
4636 load_reg_var(s, addr, rn);
4637 for (reg = 0; reg < nregs; reg++) {
4638 if (load) {
4639 tmp = tcg_temp_new_i32();
4640 switch (size) {
4641 case 0:
4642 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4643 break;
4644 case 1:
4645 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4646 break;
4647 case 2:
4648 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4649 break;
4650 default: /* Avoid compiler warnings. */
4651 abort();
4653 if (size != 2) {
4654 tmp2 = neon_load_reg(rd, pass);
4655 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4656 shift, size ? 16 : 8);
4657 tcg_temp_free_i32(tmp2);
4659 neon_store_reg(rd, pass, tmp);
4660 } else { /* Store */
4661 tmp = neon_load_reg(rd, pass);
4662 if (shift)
4663 tcg_gen_shri_i32(tmp, tmp, shift);
4664 switch (size) {
4665 case 0:
4666 gen_aa32_st8(tmp, addr, get_mem_index(s));
4667 break;
4668 case 1:
4669 gen_aa32_st16(tmp, addr, get_mem_index(s));
4670 break;
4671 case 2:
4672 gen_aa32_st32(tmp, addr, get_mem_index(s));
4673 break;
4675 tcg_temp_free_i32(tmp);
4677 rd += stride;
4678 tcg_gen_addi_i32(addr, addr, 1 << size);
4680 tcg_temp_free_i32(addr);
4681 stride = nregs * (1 << size);
4684 if (rm != 15) {
4685 TCGv_i32 base;
4687 base = load_reg(s, rn);
4688 if (rm == 13) {
4689 tcg_gen_addi_i32(base, base, stride);
4690 } else {
4691 TCGv_i32 index;
4692 index = load_reg(s, rm);
4693 tcg_gen_add_i32(base, base, index);
4694 tcg_temp_free_i32(index);
4696 store_reg(s, rn, base);
4698 return 0;
4701 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4702 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4704 tcg_gen_and_i32(t, t, c);
4705 tcg_gen_andc_i32(f, f, c);
4706 tcg_gen_or_i32(dest, t, f);
4709 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4711 switch (size) {
4712 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4713 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4714 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4715 default: abort();
4719 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4721 switch (size) {
4722 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4723 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4724 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4725 default: abort();
4729 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4731 switch (size) {
4732 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4733 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4734 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4735 default: abort();
4739 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4741 switch (size) {
4742 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4743 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4744 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4745 default: abort();
4749 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4750 int q, int u)
4752 if (q) {
4753 if (u) {
4754 switch (size) {
4755 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4756 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4757 default: abort();
4759 } else {
4760 switch (size) {
4761 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4762 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4763 default: abort();
4766 } else {
4767 if (u) {
4768 switch (size) {
4769 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4770 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4771 default: abort();
4773 } else {
4774 switch (size) {
4775 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4776 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4777 default: abort();
4783 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4785 if (u) {
4786 switch (size) {
4787 case 0: gen_helper_neon_widen_u8(dest, src); break;
4788 case 1: gen_helper_neon_widen_u16(dest, src); break;
4789 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4790 default: abort();
4792 } else {
4793 switch (size) {
4794 case 0: gen_helper_neon_widen_s8(dest, src); break;
4795 case 1: gen_helper_neon_widen_s16(dest, src); break;
4796 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4797 default: abort();
4800 tcg_temp_free_i32(src);
4803 static inline void gen_neon_addl(int size)
4805 switch (size) {
4806 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4807 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4808 case 2: tcg_gen_add_i64(CPU_V001); break;
4809 default: abort();
4813 static inline void gen_neon_subl(int size)
4815 switch (size) {
4816 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4817 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4818 case 2: tcg_gen_sub_i64(CPU_V001); break;
4819 default: abort();
4823 static inline void gen_neon_negl(TCGv_i64 var, int size)
4825 switch (size) {
4826 case 0: gen_helper_neon_negl_u16(var, var); break;
4827 case 1: gen_helper_neon_negl_u32(var, var); break;
4828 case 2:
4829 tcg_gen_neg_i64(var, var);
4830 break;
4831 default: abort();
4835 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4837 switch (size) {
4838 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4839 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4840 default: abort();
4844 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4845 int size, int u)
4847 TCGv_i64 tmp;
4849 switch ((size << 1) | u) {
4850 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4851 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4852 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4853 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4854 case 4:
4855 tmp = gen_muls_i64_i32(a, b);
4856 tcg_gen_mov_i64(dest, tmp);
4857 tcg_temp_free_i64(tmp);
4858 break;
4859 case 5:
4860 tmp = gen_mulu_i64_i32(a, b);
4861 tcg_gen_mov_i64(dest, tmp);
4862 tcg_temp_free_i64(tmp);
4863 break;
4864 default: abort();
4867 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4868 Don't forget to clean them now. */
4869 if (size < 2) {
4870 tcg_temp_free_i32(a);
4871 tcg_temp_free_i32(b);
4875 static void gen_neon_narrow_op(int op, int u, int size,
4876 TCGv_i32 dest, TCGv_i64 src)
4878 if (op) {
4879 if (u) {
4880 gen_neon_unarrow_sats(size, dest, src);
4881 } else {
4882 gen_neon_narrow(size, dest, src);
4884 } else {
4885 if (u) {
4886 gen_neon_narrow_satu(size, dest, src);
4887 } else {
4888 gen_neon_narrow_sats(size, dest, src);
4893 /* Symbolic constants for op fields for Neon 3-register same-length.
4894 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4895 * table A7-9.
4897 #define NEON_3R_VHADD 0
4898 #define NEON_3R_VQADD 1
4899 #define NEON_3R_VRHADD 2
4900 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4901 #define NEON_3R_VHSUB 4
4902 #define NEON_3R_VQSUB 5
4903 #define NEON_3R_VCGT 6
4904 #define NEON_3R_VCGE 7
4905 #define NEON_3R_VSHL 8
4906 #define NEON_3R_VQSHL 9
4907 #define NEON_3R_VRSHL 10
4908 #define NEON_3R_VQRSHL 11
4909 #define NEON_3R_VMAX 12
4910 #define NEON_3R_VMIN 13
4911 #define NEON_3R_VABD 14
4912 #define NEON_3R_VABA 15
4913 #define NEON_3R_VADD_VSUB 16
4914 #define NEON_3R_VTST_VCEQ 17
4915 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4916 #define NEON_3R_VMUL 19
4917 #define NEON_3R_VPMAX 20
4918 #define NEON_3R_VPMIN 21
4919 #define NEON_3R_VQDMULH_VQRDMULH 22
4920 #define NEON_3R_VPADD 23
4921 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4922 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4923 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4924 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4925 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4926 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4927 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4928 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4930 static const uint8_t neon_3r_sizes[] = {
4931 [NEON_3R_VHADD] = 0x7,
4932 [NEON_3R_VQADD] = 0xf,
4933 [NEON_3R_VRHADD] = 0x7,
4934 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4935 [NEON_3R_VHSUB] = 0x7,
4936 [NEON_3R_VQSUB] = 0xf,
4937 [NEON_3R_VCGT] = 0x7,
4938 [NEON_3R_VCGE] = 0x7,
4939 [NEON_3R_VSHL] = 0xf,
4940 [NEON_3R_VQSHL] = 0xf,
4941 [NEON_3R_VRSHL] = 0xf,
4942 [NEON_3R_VQRSHL] = 0xf,
4943 [NEON_3R_VMAX] = 0x7,
4944 [NEON_3R_VMIN] = 0x7,
4945 [NEON_3R_VABD] = 0x7,
4946 [NEON_3R_VABA] = 0x7,
4947 [NEON_3R_VADD_VSUB] = 0xf,
4948 [NEON_3R_VTST_VCEQ] = 0x7,
4949 [NEON_3R_VML] = 0x7,
4950 [NEON_3R_VMUL] = 0x7,
4951 [NEON_3R_VPMAX] = 0x7,
4952 [NEON_3R_VPMIN] = 0x7,
4953 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4954 [NEON_3R_VPADD] = 0x7,
4955 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4956 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4957 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4958 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4959 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4960 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4961 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4962 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4965 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4966 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4967 * table A7-13.
4969 #define NEON_2RM_VREV64 0
4970 #define NEON_2RM_VREV32 1
4971 #define NEON_2RM_VREV16 2
4972 #define NEON_2RM_VPADDL 4
4973 #define NEON_2RM_VPADDL_U 5
4974 #define NEON_2RM_AESE 6 /* Includes AESD */
4975 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4976 #define NEON_2RM_VCLS 8
4977 #define NEON_2RM_VCLZ 9
4978 #define NEON_2RM_VCNT 10
4979 #define NEON_2RM_VMVN 11
4980 #define NEON_2RM_VPADAL 12
4981 #define NEON_2RM_VPADAL_U 13
4982 #define NEON_2RM_VQABS 14
4983 #define NEON_2RM_VQNEG 15
4984 #define NEON_2RM_VCGT0 16
4985 #define NEON_2RM_VCGE0 17
4986 #define NEON_2RM_VCEQ0 18
4987 #define NEON_2RM_VCLE0 19
4988 #define NEON_2RM_VCLT0 20
4989 #define NEON_2RM_SHA1H 21
4990 #define NEON_2RM_VABS 22
4991 #define NEON_2RM_VNEG 23
4992 #define NEON_2RM_VCGT0_F 24
4993 #define NEON_2RM_VCGE0_F 25
4994 #define NEON_2RM_VCEQ0_F 26
4995 #define NEON_2RM_VCLE0_F 27
4996 #define NEON_2RM_VCLT0_F 28
4997 #define NEON_2RM_VABS_F 30
4998 #define NEON_2RM_VNEG_F 31
4999 #define NEON_2RM_VSWP 32
5000 #define NEON_2RM_VTRN 33
5001 #define NEON_2RM_VUZP 34
5002 #define NEON_2RM_VZIP 35
5003 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5004 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5005 #define NEON_2RM_VSHLL 38
5006 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5007 #define NEON_2RM_VRINTN 40
5008 #define NEON_2RM_VRINTX 41
5009 #define NEON_2RM_VRINTA 42
5010 #define NEON_2RM_VRINTZ 43
5011 #define NEON_2RM_VCVT_F16_F32 44
5012 #define NEON_2RM_VRINTM 45
5013 #define NEON_2RM_VCVT_F32_F16 46
5014 #define NEON_2RM_VRINTP 47
5015 #define NEON_2RM_VCVTAU 48
5016 #define NEON_2RM_VCVTAS 49
5017 #define NEON_2RM_VCVTNU 50
5018 #define NEON_2RM_VCVTNS 51
5019 #define NEON_2RM_VCVTPU 52
5020 #define NEON_2RM_VCVTPS 53
5021 #define NEON_2RM_VCVTMU 54
5022 #define NEON_2RM_VCVTMS 55
5023 #define NEON_2RM_VRECPE 56
5024 #define NEON_2RM_VRSQRTE 57
5025 #define NEON_2RM_VRECPE_F 58
5026 #define NEON_2RM_VRSQRTE_F 59
5027 #define NEON_2RM_VCVT_FS 60
5028 #define NEON_2RM_VCVT_FU 61
5029 #define NEON_2RM_VCVT_SF 62
5030 #define NEON_2RM_VCVT_UF 63
5032 static int neon_2rm_is_float_op(int op)
5034 /* Return true if this neon 2reg-misc op is float-to-float */
5035 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5036 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5037 op == NEON_2RM_VRINTM ||
5038 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5039 op >= NEON_2RM_VRECPE_F);
5042 /* Each entry in this array has bit n set if the insn allows
5043 * size value n (otherwise it will UNDEF). Since unallocated
5044 * op values will have no bits set they always UNDEF.
5046 static const uint8_t neon_2rm_sizes[] = {
5047 [NEON_2RM_VREV64] = 0x7,
5048 [NEON_2RM_VREV32] = 0x3,
5049 [NEON_2RM_VREV16] = 0x1,
5050 [NEON_2RM_VPADDL] = 0x7,
5051 [NEON_2RM_VPADDL_U] = 0x7,
5052 [NEON_2RM_AESE] = 0x1,
5053 [NEON_2RM_AESMC] = 0x1,
5054 [NEON_2RM_VCLS] = 0x7,
5055 [NEON_2RM_VCLZ] = 0x7,
5056 [NEON_2RM_VCNT] = 0x1,
5057 [NEON_2RM_VMVN] = 0x1,
5058 [NEON_2RM_VPADAL] = 0x7,
5059 [NEON_2RM_VPADAL_U] = 0x7,
5060 [NEON_2RM_VQABS] = 0x7,
5061 [NEON_2RM_VQNEG] = 0x7,
5062 [NEON_2RM_VCGT0] = 0x7,
5063 [NEON_2RM_VCGE0] = 0x7,
5064 [NEON_2RM_VCEQ0] = 0x7,
5065 [NEON_2RM_VCLE0] = 0x7,
5066 [NEON_2RM_VCLT0] = 0x7,
5067 [NEON_2RM_SHA1H] = 0x4,
5068 [NEON_2RM_VABS] = 0x7,
5069 [NEON_2RM_VNEG] = 0x7,
5070 [NEON_2RM_VCGT0_F] = 0x4,
5071 [NEON_2RM_VCGE0_F] = 0x4,
5072 [NEON_2RM_VCEQ0_F] = 0x4,
5073 [NEON_2RM_VCLE0_F] = 0x4,
5074 [NEON_2RM_VCLT0_F] = 0x4,
5075 [NEON_2RM_VABS_F] = 0x4,
5076 [NEON_2RM_VNEG_F] = 0x4,
5077 [NEON_2RM_VSWP] = 0x1,
5078 [NEON_2RM_VTRN] = 0x7,
5079 [NEON_2RM_VUZP] = 0x7,
5080 [NEON_2RM_VZIP] = 0x7,
5081 [NEON_2RM_VMOVN] = 0x7,
5082 [NEON_2RM_VQMOVN] = 0x7,
5083 [NEON_2RM_VSHLL] = 0x7,
5084 [NEON_2RM_SHA1SU1] = 0x4,
5085 [NEON_2RM_VRINTN] = 0x4,
5086 [NEON_2RM_VRINTX] = 0x4,
5087 [NEON_2RM_VRINTA] = 0x4,
5088 [NEON_2RM_VRINTZ] = 0x4,
5089 [NEON_2RM_VCVT_F16_F32] = 0x2,
5090 [NEON_2RM_VRINTM] = 0x4,
5091 [NEON_2RM_VCVT_F32_F16] = 0x2,
5092 [NEON_2RM_VRINTP] = 0x4,
5093 [NEON_2RM_VCVTAU] = 0x4,
5094 [NEON_2RM_VCVTAS] = 0x4,
5095 [NEON_2RM_VCVTNU] = 0x4,
5096 [NEON_2RM_VCVTNS] = 0x4,
5097 [NEON_2RM_VCVTPU] = 0x4,
5098 [NEON_2RM_VCVTPS] = 0x4,
5099 [NEON_2RM_VCVTMU] = 0x4,
5100 [NEON_2RM_VCVTMS] = 0x4,
5101 [NEON_2RM_VRECPE] = 0x4,
5102 [NEON_2RM_VRSQRTE] = 0x4,
5103 [NEON_2RM_VRECPE_F] = 0x4,
5104 [NEON_2RM_VRSQRTE_F] = 0x4,
5105 [NEON_2RM_VCVT_FS] = 0x4,
5106 [NEON_2RM_VCVT_FU] = 0x4,
5107 [NEON_2RM_VCVT_SF] = 0x4,
5108 [NEON_2RM_VCVT_UF] = 0x4,
5111 /* Translate a NEON data processing instruction. Return nonzero if the
5112 instruction is invalid.
5113 We process data in a mixture of 32-bit and 64-bit chunks.
5114 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5116 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5118 int op;
5119 int q;
5120 int rd, rn, rm;
5121 int size;
5122 int shift;
5123 int pass;
5124 int count;
5125 int pairwise;
5126 int u;
5127 uint32_t imm, mask;
5128 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5129 TCGv_i64 tmp64;
5131 /* FIXME: this access check should not take precedence over UNDEF
5132 * for invalid encodings; we will generate incorrect syndrome information
5133 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5135 if (s->fp_excp_el) {
5136 gen_exception_insn(s, 4, EXCP_UDEF,
5137 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
5138 return 0;
5141 if (!s->vfp_enabled)
5142 return 1;
5143 q = (insn & (1 << 6)) != 0;
5144 u = (insn >> 24) & 1;
5145 VFP_DREG_D(rd, insn);
5146 VFP_DREG_N(rn, insn);
5147 VFP_DREG_M(rm, insn);
5148 size = (insn >> 20) & 3;
5149 if ((insn & (1 << 23)) == 0) {
5150 /* Three register same length. */
5151 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5152 /* Catch invalid op and bad size combinations: UNDEF */
5153 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5154 return 1;
5156 /* All insns of this form UNDEF for either this condition or the
5157 * superset of cases "Q==1"; we catch the latter later.
5159 if (q && ((rd | rn | rm) & 1)) {
5160 return 1;
5163 * The SHA-1/SHA-256 3-register instructions require special treatment
5164 * here, as their size field is overloaded as an op type selector, and
5165 * they all consume their input in a single pass.
5167 if (op == NEON_3R_SHA) {
5168 if (!q) {
5169 return 1;
5171 if (!u) { /* SHA-1 */
5172 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5173 return 1;
5175 tmp = tcg_const_i32(rd);
5176 tmp2 = tcg_const_i32(rn);
5177 tmp3 = tcg_const_i32(rm);
5178 tmp4 = tcg_const_i32(size);
5179 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5180 tcg_temp_free_i32(tmp4);
5181 } else { /* SHA-256 */
5182 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5183 return 1;
5185 tmp = tcg_const_i32(rd);
5186 tmp2 = tcg_const_i32(rn);
5187 tmp3 = tcg_const_i32(rm);
5188 switch (size) {
5189 case 0:
5190 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5191 break;
5192 case 1:
5193 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5194 break;
5195 case 2:
5196 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5197 break;
5200 tcg_temp_free_i32(tmp);
5201 tcg_temp_free_i32(tmp2);
5202 tcg_temp_free_i32(tmp3);
5203 return 0;
5205 if (size == 3 && op != NEON_3R_LOGIC) {
5206 /* 64-bit element instructions. */
5207 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5208 neon_load_reg64(cpu_V0, rn + pass);
5209 neon_load_reg64(cpu_V1, rm + pass);
5210 switch (op) {
5211 case NEON_3R_VQADD:
5212 if (u) {
5213 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5214 cpu_V0, cpu_V1);
5215 } else {
5216 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5217 cpu_V0, cpu_V1);
5219 break;
5220 case NEON_3R_VQSUB:
5221 if (u) {
5222 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5223 cpu_V0, cpu_V1);
5224 } else {
5225 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5226 cpu_V0, cpu_V1);
5228 break;
5229 case NEON_3R_VSHL:
5230 if (u) {
5231 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5232 } else {
5233 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5235 break;
5236 case NEON_3R_VQSHL:
5237 if (u) {
5238 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5239 cpu_V1, cpu_V0);
5240 } else {
5241 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5242 cpu_V1, cpu_V0);
5244 break;
5245 case NEON_3R_VRSHL:
5246 if (u) {
5247 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5248 } else {
5249 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5251 break;
5252 case NEON_3R_VQRSHL:
5253 if (u) {
5254 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5255 cpu_V1, cpu_V0);
5256 } else {
5257 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5258 cpu_V1, cpu_V0);
5260 break;
5261 case NEON_3R_VADD_VSUB:
5262 if (u) {
5263 tcg_gen_sub_i64(CPU_V001);
5264 } else {
5265 tcg_gen_add_i64(CPU_V001);
5267 break;
5268 default:
5269 abort();
5271 neon_store_reg64(cpu_V0, rd + pass);
5273 return 0;
5275 pairwise = 0;
5276 switch (op) {
5277 case NEON_3R_VSHL:
5278 case NEON_3R_VQSHL:
5279 case NEON_3R_VRSHL:
5280 case NEON_3R_VQRSHL:
5282 int rtmp;
5283 /* Shift instruction operands are reversed. */
5284 rtmp = rn;
5285 rn = rm;
5286 rm = rtmp;
5288 break;
5289 case NEON_3R_VPADD:
5290 if (u) {
5291 return 1;
5293 /* Fall through */
5294 case NEON_3R_VPMAX:
5295 case NEON_3R_VPMIN:
5296 pairwise = 1;
5297 break;
5298 case NEON_3R_FLOAT_ARITH:
5299 pairwise = (u && size < 2); /* if VPADD (float) */
5300 break;
5301 case NEON_3R_FLOAT_MINMAX:
5302 pairwise = u; /* if VPMIN/VPMAX (float) */
5303 break;
5304 case NEON_3R_FLOAT_CMP:
5305 if (!u && size) {
5306 /* no encoding for U=0 C=1x */
5307 return 1;
5309 break;
5310 case NEON_3R_FLOAT_ACMP:
5311 if (!u) {
5312 return 1;
5314 break;
5315 case NEON_3R_FLOAT_MISC:
5316 /* VMAXNM/VMINNM in ARMv8 */
5317 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5318 return 1;
5320 break;
5321 case NEON_3R_VMUL:
5322 if (u && (size != 0)) {
5323 /* UNDEF on invalid size for polynomial subcase */
5324 return 1;
5326 break;
5327 case NEON_3R_VFM:
5328 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5329 return 1;
5331 break;
5332 default:
5333 break;
5336 if (pairwise && q) {
5337 /* All the pairwise insns UNDEF if Q is set */
5338 return 1;
5341 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5343 if (pairwise) {
5344 /* Pairwise. */
5345 if (pass < 1) {
5346 tmp = neon_load_reg(rn, 0);
5347 tmp2 = neon_load_reg(rn, 1);
5348 } else {
5349 tmp = neon_load_reg(rm, 0);
5350 tmp2 = neon_load_reg(rm, 1);
5352 } else {
5353 /* Elementwise. */
5354 tmp = neon_load_reg(rn, pass);
5355 tmp2 = neon_load_reg(rm, pass);
5357 switch (op) {
5358 case NEON_3R_VHADD:
5359 GEN_NEON_INTEGER_OP(hadd);
5360 break;
5361 case NEON_3R_VQADD:
5362 GEN_NEON_INTEGER_OP_ENV(qadd);
5363 break;
5364 case NEON_3R_VRHADD:
5365 GEN_NEON_INTEGER_OP(rhadd);
5366 break;
5367 case NEON_3R_LOGIC: /* Logic ops. */
5368 switch ((u << 2) | size) {
5369 case 0: /* VAND */
5370 tcg_gen_and_i32(tmp, tmp, tmp2);
5371 break;
5372 case 1: /* BIC */
5373 tcg_gen_andc_i32(tmp, tmp, tmp2);
5374 break;
5375 case 2: /* VORR */
5376 tcg_gen_or_i32(tmp, tmp, tmp2);
5377 break;
5378 case 3: /* VORN */
5379 tcg_gen_orc_i32(tmp, tmp, tmp2);
5380 break;
5381 case 4: /* VEOR */
5382 tcg_gen_xor_i32(tmp, tmp, tmp2);
5383 break;
5384 case 5: /* VBSL */
5385 tmp3 = neon_load_reg(rd, pass);
5386 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5387 tcg_temp_free_i32(tmp3);
5388 break;
5389 case 6: /* VBIT */
5390 tmp3 = neon_load_reg(rd, pass);
5391 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5392 tcg_temp_free_i32(tmp3);
5393 break;
5394 case 7: /* VBIF */
5395 tmp3 = neon_load_reg(rd, pass);
5396 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5397 tcg_temp_free_i32(tmp3);
5398 break;
5400 break;
5401 case NEON_3R_VHSUB:
5402 GEN_NEON_INTEGER_OP(hsub);
5403 break;
5404 case NEON_3R_VQSUB:
5405 GEN_NEON_INTEGER_OP_ENV(qsub);
5406 break;
5407 case NEON_3R_VCGT:
5408 GEN_NEON_INTEGER_OP(cgt);
5409 break;
5410 case NEON_3R_VCGE:
5411 GEN_NEON_INTEGER_OP(cge);
5412 break;
5413 case NEON_3R_VSHL:
5414 GEN_NEON_INTEGER_OP(shl);
5415 break;
5416 case NEON_3R_VQSHL:
5417 GEN_NEON_INTEGER_OP_ENV(qshl);
5418 break;
5419 case NEON_3R_VRSHL:
5420 GEN_NEON_INTEGER_OP(rshl);
5421 break;
5422 case NEON_3R_VQRSHL:
5423 GEN_NEON_INTEGER_OP_ENV(qrshl);
5424 break;
5425 case NEON_3R_VMAX:
5426 GEN_NEON_INTEGER_OP(max);
5427 break;
5428 case NEON_3R_VMIN:
5429 GEN_NEON_INTEGER_OP(min);
5430 break;
5431 case NEON_3R_VABD:
5432 GEN_NEON_INTEGER_OP(abd);
5433 break;
5434 case NEON_3R_VABA:
5435 GEN_NEON_INTEGER_OP(abd);
5436 tcg_temp_free_i32(tmp2);
5437 tmp2 = neon_load_reg(rd, pass);
5438 gen_neon_add(size, tmp, tmp2);
5439 break;
5440 case NEON_3R_VADD_VSUB:
5441 if (!u) { /* VADD */
5442 gen_neon_add(size, tmp, tmp2);
5443 } else { /* VSUB */
5444 switch (size) {
5445 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5446 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5447 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5448 default: abort();
5451 break;
5452 case NEON_3R_VTST_VCEQ:
5453 if (!u) { /* VTST */
5454 switch (size) {
5455 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5456 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5457 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5458 default: abort();
5460 } else { /* VCEQ */
5461 switch (size) {
5462 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5463 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5464 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5465 default: abort();
5468 break;
5469 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5470 switch (size) {
5471 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5472 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5473 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5474 default: abort();
5476 tcg_temp_free_i32(tmp2);
5477 tmp2 = neon_load_reg(rd, pass);
5478 if (u) { /* VMLS */
5479 gen_neon_rsb(size, tmp, tmp2);
5480 } else { /* VMLA */
5481 gen_neon_add(size, tmp, tmp2);
5483 break;
5484 case NEON_3R_VMUL:
5485 if (u) { /* polynomial */
5486 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5487 } else { /* Integer */
5488 switch (size) {
5489 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5490 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5491 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5492 default: abort();
5495 break;
5496 case NEON_3R_VPMAX:
5497 GEN_NEON_INTEGER_OP(pmax);
5498 break;
5499 case NEON_3R_VPMIN:
5500 GEN_NEON_INTEGER_OP(pmin);
5501 break;
5502 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5503 if (!u) { /* VQDMULH */
5504 switch (size) {
5505 case 1:
5506 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5507 break;
5508 case 2:
5509 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5510 break;
5511 default: abort();
5513 } else { /* VQRDMULH */
5514 switch (size) {
5515 case 1:
5516 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5517 break;
5518 case 2:
5519 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5520 break;
5521 default: abort();
5524 break;
5525 case NEON_3R_VPADD:
5526 switch (size) {
5527 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5528 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5529 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5530 default: abort();
5532 break;
5533 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5535 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5536 switch ((u << 2) | size) {
5537 case 0: /* VADD */
5538 case 4: /* VPADD */
5539 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5540 break;
5541 case 2: /* VSUB */
5542 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5543 break;
5544 case 6: /* VABD */
5545 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5546 break;
5547 default:
5548 abort();
5550 tcg_temp_free_ptr(fpstatus);
5551 break;
5553 case NEON_3R_FLOAT_MULTIPLY:
5555 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5556 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5557 if (!u) {
5558 tcg_temp_free_i32(tmp2);
5559 tmp2 = neon_load_reg(rd, pass);
5560 if (size == 0) {
5561 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5562 } else {
5563 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5566 tcg_temp_free_ptr(fpstatus);
5567 break;
5569 case NEON_3R_FLOAT_CMP:
5571 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5572 if (!u) {
5573 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5574 } else {
5575 if (size == 0) {
5576 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5577 } else {
5578 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5581 tcg_temp_free_ptr(fpstatus);
5582 break;
5584 case NEON_3R_FLOAT_ACMP:
5586 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5587 if (size == 0) {
5588 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5589 } else {
5590 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5592 tcg_temp_free_ptr(fpstatus);
5593 break;
5595 case NEON_3R_FLOAT_MINMAX:
5597 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5598 if (size == 0) {
5599 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5600 } else {
5601 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5603 tcg_temp_free_ptr(fpstatus);
5604 break;
5606 case NEON_3R_FLOAT_MISC:
5607 if (u) {
5608 /* VMAXNM/VMINNM */
5609 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5610 if (size == 0) {
5611 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5612 } else {
5613 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5615 tcg_temp_free_ptr(fpstatus);
5616 } else {
5617 if (size == 0) {
5618 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5619 } else {
5620 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5623 break;
5624 case NEON_3R_VFM:
5626 /* VFMA, VFMS: fused multiply-add */
5627 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5628 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5629 if (size) {
5630 /* VFMS */
5631 gen_helper_vfp_negs(tmp, tmp);
5633 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5634 tcg_temp_free_i32(tmp3);
5635 tcg_temp_free_ptr(fpstatus);
5636 break;
5638 default:
5639 abort();
5641 tcg_temp_free_i32(tmp2);
5643 /* Save the result. For elementwise operations we can put it
5644 straight into the destination register. For pairwise operations
5645 we have to be careful to avoid clobbering the source operands. */
5646 if (pairwise && rd == rm) {
5647 neon_store_scratch(pass, tmp);
5648 } else {
5649 neon_store_reg(rd, pass, tmp);
5652 } /* for pass */
5653 if (pairwise && rd == rm) {
5654 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5655 tmp = neon_load_scratch(pass);
5656 neon_store_reg(rd, pass, tmp);
5659 /* End of 3 register same size operations. */
5660 } else if (insn & (1 << 4)) {
5661 if ((insn & 0x00380080) != 0) {
5662 /* Two registers and shift. */
5663 op = (insn >> 8) & 0xf;
5664 if (insn & (1 << 7)) {
5665 /* 64-bit shift. */
5666 if (op > 7) {
5667 return 1;
5669 size = 3;
5670 } else {
5671 size = 2;
5672 while ((insn & (1 << (size + 19))) == 0)
5673 size--;
5675 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5676 /* To avoid excessive duplication of ops we implement shift
5677 by immediate using the variable shift operations. */
5678 if (op < 8) {
5679 /* Shift by immediate:
5680 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5681 if (q && ((rd | rm) & 1)) {
5682 return 1;
5684 if (!u && (op == 4 || op == 6)) {
5685 return 1;
5687 /* Right shifts are encoded as N - shift, where N is the
5688 element size in bits. */
5689 if (op <= 4)
5690 shift = shift - (1 << (size + 3));
5691 if (size == 3) {
5692 count = q + 1;
5693 } else {
5694 count = q ? 4: 2;
5696 switch (size) {
5697 case 0:
5698 imm = (uint8_t) shift;
5699 imm |= imm << 8;
5700 imm |= imm << 16;
5701 break;
5702 case 1:
5703 imm = (uint16_t) shift;
5704 imm |= imm << 16;
5705 break;
5706 case 2:
5707 case 3:
5708 imm = shift;
5709 break;
5710 default:
5711 abort();
5714 for (pass = 0; pass < count; pass++) {
5715 if (size == 3) {
5716 neon_load_reg64(cpu_V0, rm + pass);
5717 tcg_gen_movi_i64(cpu_V1, imm);
5718 switch (op) {
5719 case 0: /* VSHR */
5720 case 1: /* VSRA */
5721 if (u)
5722 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5723 else
5724 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5725 break;
5726 case 2: /* VRSHR */
5727 case 3: /* VRSRA */
5728 if (u)
5729 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5730 else
5731 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5732 break;
5733 case 4: /* VSRI */
5734 case 5: /* VSHL, VSLI */
5735 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5736 break;
5737 case 6: /* VQSHLU */
5738 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5739 cpu_V0, cpu_V1);
5740 break;
5741 case 7: /* VQSHL */
5742 if (u) {
5743 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5744 cpu_V0, cpu_V1);
5745 } else {
5746 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5747 cpu_V0, cpu_V1);
5749 break;
5751 if (op == 1 || op == 3) {
5752 /* Accumulate. */
5753 neon_load_reg64(cpu_V1, rd + pass);
5754 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5755 } else if (op == 4 || (op == 5 && u)) {
5756 /* Insert */
5757 neon_load_reg64(cpu_V1, rd + pass);
5758 uint64_t mask;
5759 if (shift < -63 || shift > 63) {
5760 mask = 0;
5761 } else {
5762 if (op == 4) {
5763 mask = 0xffffffffffffffffull >> -shift;
5764 } else {
5765 mask = 0xffffffffffffffffull << shift;
5768 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5769 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5771 neon_store_reg64(cpu_V0, rd + pass);
5772 } else { /* size < 3 */
5773 /* Operands in T0 and T1. */
5774 tmp = neon_load_reg(rm, pass);
5775 tmp2 = tcg_temp_new_i32();
5776 tcg_gen_movi_i32(tmp2, imm);
5777 switch (op) {
5778 case 0: /* VSHR */
5779 case 1: /* VSRA */
5780 GEN_NEON_INTEGER_OP(shl);
5781 break;
5782 case 2: /* VRSHR */
5783 case 3: /* VRSRA */
5784 GEN_NEON_INTEGER_OP(rshl);
5785 break;
5786 case 4: /* VSRI */
5787 case 5: /* VSHL, VSLI */
5788 switch (size) {
5789 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5790 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5791 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5792 default: abort();
5794 break;
5795 case 6: /* VQSHLU */
5796 switch (size) {
5797 case 0:
5798 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5799 tmp, tmp2);
5800 break;
5801 case 1:
5802 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5803 tmp, tmp2);
5804 break;
5805 case 2:
5806 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5807 tmp, tmp2);
5808 break;
5809 default:
5810 abort();
5812 break;
5813 case 7: /* VQSHL */
5814 GEN_NEON_INTEGER_OP_ENV(qshl);
5815 break;
5817 tcg_temp_free_i32(tmp2);
5819 if (op == 1 || op == 3) {
5820 /* Accumulate. */
5821 tmp2 = neon_load_reg(rd, pass);
5822 gen_neon_add(size, tmp, tmp2);
5823 tcg_temp_free_i32(tmp2);
5824 } else if (op == 4 || (op == 5 && u)) {
5825 /* Insert */
5826 switch (size) {
5827 case 0:
5828 if (op == 4)
5829 mask = 0xff >> -shift;
5830 else
5831 mask = (uint8_t)(0xff << shift);
5832 mask |= mask << 8;
5833 mask |= mask << 16;
5834 break;
5835 case 1:
5836 if (op == 4)
5837 mask = 0xffff >> -shift;
5838 else
5839 mask = (uint16_t)(0xffff << shift);
5840 mask |= mask << 16;
5841 break;
5842 case 2:
5843 if (shift < -31 || shift > 31) {
5844 mask = 0;
5845 } else {
5846 if (op == 4)
5847 mask = 0xffffffffu >> -shift;
5848 else
5849 mask = 0xffffffffu << shift;
5851 break;
5852 default:
5853 abort();
5855 tmp2 = neon_load_reg(rd, pass);
5856 tcg_gen_andi_i32(tmp, tmp, mask);
5857 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5858 tcg_gen_or_i32(tmp, tmp, tmp2);
5859 tcg_temp_free_i32(tmp2);
5861 neon_store_reg(rd, pass, tmp);
5863 } /* for pass */
5864 } else if (op < 10) {
5865 /* Shift by immediate and narrow:
5866 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5867 int input_unsigned = (op == 8) ? !u : u;
5868 if (rm & 1) {
5869 return 1;
5871 shift = shift - (1 << (size + 3));
5872 size++;
5873 if (size == 3) {
5874 tmp64 = tcg_const_i64(shift);
5875 neon_load_reg64(cpu_V0, rm);
5876 neon_load_reg64(cpu_V1, rm + 1);
5877 for (pass = 0; pass < 2; pass++) {
5878 TCGv_i64 in;
5879 if (pass == 0) {
5880 in = cpu_V0;
5881 } else {
5882 in = cpu_V1;
5884 if (q) {
5885 if (input_unsigned) {
5886 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5887 } else {
5888 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5890 } else {
5891 if (input_unsigned) {
5892 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5893 } else {
5894 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5897 tmp = tcg_temp_new_i32();
5898 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5899 neon_store_reg(rd, pass, tmp);
5900 } /* for pass */
5901 tcg_temp_free_i64(tmp64);
5902 } else {
5903 if (size == 1) {
5904 imm = (uint16_t)shift;
5905 imm |= imm << 16;
5906 } else {
5907 /* size == 2 */
5908 imm = (uint32_t)shift;
5910 tmp2 = tcg_const_i32(imm);
5911 tmp4 = neon_load_reg(rm + 1, 0);
5912 tmp5 = neon_load_reg(rm + 1, 1);
5913 for (pass = 0; pass < 2; pass++) {
5914 if (pass == 0) {
5915 tmp = neon_load_reg(rm, 0);
5916 } else {
5917 tmp = tmp4;
5919 gen_neon_shift_narrow(size, tmp, tmp2, q,
5920 input_unsigned);
5921 if (pass == 0) {
5922 tmp3 = neon_load_reg(rm, 1);
5923 } else {
5924 tmp3 = tmp5;
5926 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5927 input_unsigned);
5928 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5929 tcg_temp_free_i32(tmp);
5930 tcg_temp_free_i32(tmp3);
5931 tmp = tcg_temp_new_i32();
5932 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5933 neon_store_reg(rd, pass, tmp);
5934 } /* for pass */
5935 tcg_temp_free_i32(tmp2);
5937 } else if (op == 10) {
5938 /* VSHLL, VMOVL */
5939 if (q || (rd & 1)) {
5940 return 1;
5942 tmp = neon_load_reg(rm, 0);
5943 tmp2 = neon_load_reg(rm, 1);
5944 for (pass = 0; pass < 2; pass++) {
5945 if (pass == 1)
5946 tmp = tmp2;
5948 gen_neon_widen(cpu_V0, tmp, size, u);
5950 if (shift != 0) {
5951 /* The shift is less than the width of the source
5952 type, so we can just shift the whole register. */
5953 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5954 /* Widen the result of shift: we need to clear
5955 * the potential overflow bits resulting from
5956 * left bits of the narrow input appearing as
5957 * right bits of left the neighbour narrow
5958 * input. */
5959 if (size < 2 || !u) {
5960 uint64_t imm64;
5961 if (size == 0) {
5962 imm = (0xffu >> (8 - shift));
5963 imm |= imm << 16;
5964 } else if (size == 1) {
5965 imm = 0xffff >> (16 - shift);
5966 } else {
5967 /* size == 2 */
5968 imm = 0xffffffff >> (32 - shift);
5970 if (size < 2) {
5971 imm64 = imm | (((uint64_t)imm) << 32);
5972 } else {
5973 imm64 = imm;
5975 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5978 neon_store_reg64(cpu_V0, rd + pass);
5980 } else if (op >= 14) {
5981 /* VCVT fixed-point. */
5982 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5983 return 1;
5985 /* We have already masked out the must-be-1 top bit of imm6,
5986 * hence this 32-shift where the ARM ARM has 64-imm6.
5988 shift = 32 - shift;
5989 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5990 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5991 if (!(op & 1)) {
5992 if (u)
5993 gen_vfp_ulto(0, shift, 1);
5994 else
5995 gen_vfp_slto(0, shift, 1);
5996 } else {
5997 if (u)
5998 gen_vfp_toul(0, shift, 1);
5999 else
6000 gen_vfp_tosl(0, shift, 1);
6002 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6004 } else {
6005 return 1;
6007 } else { /* (insn & 0x00380080) == 0 */
6008 int invert;
6009 if (q && (rd & 1)) {
6010 return 1;
6013 op = (insn >> 8) & 0xf;
6014 /* One register and immediate. */
6015 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6016 invert = (insn & (1 << 5)) != 0;
6017 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6018 * We choose to not special-case this and will behave as if a
6019 * valid constant encoding of 0 had been given.
6021 switch (op) {
6022 case 0: case 1:
6023 /* no-op */
6024 break;
6025 case 2: case 3:
6026 imm <<= 8;
6027 break;
6028 case 4: case 5:
6029 imm <<= 16;
6030 break;
6031 case 6: case 7:
6032 imm <<= 24;
6033 break;
6034 case 8: case 9:
6035 imm |= imm << 16;
6036 break;
6037 case 10: case 11:
6038 imm = (imm << 8) | (imm << 24);
6039 break;
6040 case 12:
6041 imm = (imm << 8) | 0xff;
6042 break;
6043 case 13:
6044 imm = (imm << 16) | 0xffff;
6045 break;
6046 case 14:
6047 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6048 if (invert)
6049 imm = ~imm;
6050 break;
6051 case 15:
6052 if (invert) {
6053 return 1;
6055 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6056 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6057 break;
6059 if (invert)
6060 imm = ~imm;
6062 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6063 if (op & 1 && op < 12) {
6064 tmp = neon_load_reg(rd, pass);
6065 if (invert) {
6066 /* The immediate value has already been inverted, so
6067 BIC becomes AND. */
6068 tcg_gen_andi_i32(tmp, tmp, imm);
6069 } else {
6070 tcg_gen_ori_i32(tmp, tmp, imm);
6072 } else {
6073 /* VMOV, VMVN. */
6074 tmp = tcg_temp_new_i32();
6075 if (op == 14 && invert) {
6076 int n;
6077 uint32_t val;
6078 val = 0;
6079 for (n = 0; n < 4; n++) {
6080 if (imm & (1 << (n + (pass & 1) * 4)))
6081 val |= 0xff << (n * 8);
6083 tcg_gen_movi_i32(tmp, val);
6084 } else {
6085 tcg_gen_movi_i32(tmp, imm);
6088 neon_store_reg(rd, pass, tmp);
6091 } else { /* (insn & 0x00800010 == 0x00800000) */
6092 if (size != 3) {
6093 op = (insn >> 8) & 0xf;
6094 if ((insn & (1 << 6)) == 0) {
6095 /* Three registers of different lengths. */
6096 int src1_wide;
6097 int src2_wide;
6098 int prewiden;
6099 /* undefreq: bit 0 : UNDEF if size == 0
6100 * bit 1 : UNDEF if size == 1
6101 * bit 2 : UNDEF if size == 2
6102 * bit 3 : UNDEF if U == 1
6103 * Note that [2:0] set implies 'always UNDEF'
6105 int undefreq;
6106 /* prewiden, src1_wide, src2_wide, undefreq */
6107 static const int neon_3reg_wide[16][4] = {
6108 {1, 0, 0, 0}, /* VADDL */
6109 {1, 1, 0, 0}, /* VADDW */
6110 {1, 0, 0, 0}, /* VSUBL */
6111 {1, 1, 0, 0}, /* VSUBW */
6112 {0, 1, 1, 0}, /* VADDHN */
6113 {0, 0, 0, 0}, /* VABAL */
6114 {0, 1, 1, 0}, /* VSUBHN */
6115 {0, 0, 0, 0}, /* VABDL */
6116 {0, 0, 0, 0}, /* VMLAL */
6117 {0, 0, 0, 9}, /* VQDMLAL */
6118 {0, 0, 0, 0}, /* VMLSL */
6119 {0, 0, 0, 9}, /* VQDMLSL */
6120 {0, 0, 0, 0}, /* Integer VMULL */
6121 {0, 0, 0, 1}, /* VQDMULL */
6122 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6123 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6126 prewiden = neon_3reg_wide[op][0];
6127 src1_wide = neon_3reg_wide[op][1];
6128 src2_wide = neon_3reg_wide[op][2];
6129 undefreq = neon_3reg_wide[op][3];
6131 if ((undefreq & (1 << size)) ||
6132 ((undefreq & 8) && u)) {
6133 return 1;
6135 if ((src1_wide && (rn & 1)) ||
6136 (src2_wide && (rm & 1)) ||
6137 (!src2_wide && (rd & 1))) {
6138 return 1;
6141 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6142 * outside the loop below as it only performs a single pass.
6144 if (op == 14 && size == 2) {
6145 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6147 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6148 return 1;
6150 tcg_rn = tcg_temp_new_i64();
6151 tcg_rm = tcg_temp_new_i64();
6152 tcg_rd = tcg_temp_new_i64();
6153 neon_load_reg64(tcg_rn, rn);
6154 neon_load_reg64(tcg_rm, rm);
6155 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6156 neon_store_reg64(tcg_rd, rd);
6157 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6158 neon_store_reg64(tcg_rd, rd + 1);
6159 tcg_temp_free_i64(tcg_rn);
6160 tcg_temp_free_i64(tcg_rm);
6161 tcg_temp_free_i64(tcg_rd);
6162 return 0;
6165 /* Avoid overlapping operands. Wide source operands are
6166 always aligned so will never overlap with wide
6167 destinations in problematic ways. */
6168 if (rd == rm && !src2_wide) {
6169 tmp = neon_load_reg(rm, 1);
6170 neon_store_scratch(2, tmp);
6171 } else if (rd == rn && !src1_wide) {
6172 tmp = neon_load_reg(rn, 1);
6173 neon_store_scratch(2, tmp);
6175 TCGV_UNUSED_I32(tmp3);
6176 for (pass = 0; pass < 2; pass++) {
6177 if (src1_wide) {
6178 neon_load_reg64(cpu_V0, rn + pass);
6179 TCGV_UNUSED_I32(tmp);
6180 } else {
6181 if (pass == 1 && rd == rn) {
6182 tmp = neon_load_scratch(2);
6183 } else {
6184 tmp = neon_load_reg(rn, pass);
6186 if (prewiden) {
6187 gen_neon_widen(cpu_V0, tmp, size, u);
6190 if (src2_wide) {
6191 neon_load_reg64(cpu_V1, rm + pass);
6192 TCGV_UNUSED_I32(tmp2);
6193 } else {
6194 if (pass == 1 && rd == rm) {
6195 tmp2 = neon_load_scratch(2);
6196 } else {
6197 tmp2 = neon_load_reg(rm, pass);
6199 if (prewiden) {
6200 gen_neon_widen(cpu_V1, tmp2, size, u);
6203 switch (op) {
6204 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6205 gen_neon_addl(size);
6206 break;
6207 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6208 gen_neon_subl(size);
6209 break;
6210 case 5: case 7: /* VABAL, VABDL */
6211 switch ((size << 1) | u) {
6212 case 0:
6213 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6214 break;
6215 case 1:
6216 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6217 break;
6218 case 2:
6219 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6220 break;
6221 case 3:
6222 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6223 break;
6224 case 4:
6225 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6226 break;
6227 case 5:
6228 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6229 break;
6230 default: abort();
6232 tcg_temp_free_i32(tmp2);
6233 tcg_temp_free_i32(tmp);
6234 break;
6235 case 8: case 9: case 10: case 11: case 12: case 13:
6236 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6237 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6238 break;
6239 case 14: /* Polynomial VMULL */
6240 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6241 tcg_temp_free_i32(tmp2);
6242 tcg_temp_free_i32(tmp);
6243 break;
6244 default: /* 15 is RESERVED: caught earlier */
6245 abort();
6247 if (op == 13) {
6248 /* VQDMULL */
6249 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6250 neon_store_reg64(cpu_V0, rd + pass);
6251 } else if (op == 5 || (op >= 8 && op <= 11)) {
6252 /* Accumulate. */
6253 neon_load_reg64(cpu_V1, rd + pass);
6254 switch (op) {
6255 case 10: /* VMLSL */
6256 gen_neon_negl(cpu_V0, size);
6257 /* Fall through */
6258 case 5: case 8: /* VABAL, VMLAL */
6259 gen_neon_addl(size);
6260 break;
6261 case 9: case 11: /* VQDMLAL, VQDMLSL */
6262 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6263 if (op == 11) {
6264 gen_neon_negl(cpu_V0, size);
6266 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6267 break;
6268 default:
6269 abort();
6271 neon_store_reg64(cpu_V0, rd + pass);
6272 } else if (op == 4 || op == 6) {
6273 /* Narrowing operation. */
6274 tmp = tcg_temp_new_i32();
6275 if (!u) {
6276 switch (size) {
6277 case 0:
6278 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6279 break;
6280 case 1:
6281 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6282 break;
6283 case 2:
6284 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6285 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6286 break;
6287 default: abort();
6289 } else {
6290 switch (size) {
6291 case 0:
6292 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6293 break;
6294 case 1:
6295 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6296 break;
6297 case 2:
6298 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6299 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6300 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6301 break;
6302 default: abort();
6305 if (pass == 0) {
6306 tmp3 = tmp;
6307 } else {
6308 neon_store_reg(rd, 0, tmp3);
6309 neon_store_reg(rd, 1, tmp);
6311 } else {
6312 /* Write back the result. */
6313 neon_store_reg64(cpu_V0, rd + pass);
6316 } else {
6317 /* Two registers and a scalar. NB that for ops of this form
6318 * the ARM ARM labels bit 24 as Q, but it is in our variable
6319 * 'u', not 'q'.
6321 if (size == 0) {
6322 return 1;
6324 switch (op) {
6325 case 1: /* Float VMLA scalar */
6326 case 5: /* Floating point VMLS scalar */
6327 case 9: /* Floating point VMUL scalar */
6328 if (size == 1) {
6329 return 1;
6331 /* fall through */
6332 case 0: /* Integer VMLA scalar */
6333 case 4: /* Integer VMLS scalar */
6334 case 8: /* Integer VMUL scalar */
6335 case 12: /* VQDMULH scalar */
6336 case 13: /* VQRDMULH scalar */
6337 if (u && ((rd | rn) & 1)) {
6338 return 1;
6340 tmp = neon_get_scalar(size, rm);
6341 neon_store_scratch(0, tmp);
6342 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6343 tmp = neon_load_scratch(0);
6344 tmp2 = neon_load_reg(rn, pass);
6345 if (op == 12) {
6346 if (size == 1) {
6347 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6348 } else {
6349 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6351 } else if (op == 13) {
6352 if (size == 1) {
6353 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6354 } else {
6355 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6357 } else if (op & 1) {
6358 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6359 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6360 tcg_temp_free_ptr(fpstatus);
6361 } else {
6362 switch (size) {
6363 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6364 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6365 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6366 default: abort();
6369 tcg_temp_free_i32(tmp2);
6370 if (op < 8) {
6371 /* Accumulate. */
6372 tmp2 = neon_load_reg(rd, pass);
6373 switch (op) {
6374 case 0:
6375 gen_neon_add(size, tmp, tmp2);
6376 break;
6377 case 1:
6379 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6380 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6381 tcg_temp_free_ptr(fpstatus);
6382 break;
6384 case 4:
6385 gen_neon_rsb(size, tmp, tmp2);
6386 break;
6387 case 5:
6389 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6390 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6391 tcg_temp_free_ptr(fpstatus);
6392 break;
6394 default:
6395 abort();
6397 tcg_temp_free_i32(tmp2);
6399 neon_store_reg(rd, pass, tmp);
6401 break;
6402 case 3: /* VQDMLAL scalar */
6403 case 7: /* VQDMLSL scalar */
6404 case 11: /* VQDMULL scalar */
6405 if (u == 1) {
6406 return 1;
6408 /* fall through */
6409 case 2: /* VMLAL sclar */
6410 case 6: /* VMLSL scalar */
6411 case 10: /* VMULL scalar */
6412 if (rd & 1) {
6413 return 1;
6415 tmp2 = neon_get_scalar(size, rm);
6416 /* We need a copy of tmp2 because gen_neon_mull
6417 * deletes it during pass 0. */
6418 tmp4 = tcg_temp_new_i32();
6419 tcg_gen_mov_i32(tmp4, tmp2);
6420 tmp3 = neon_load_reg(rn, 1);
6422 for (pass = 0; pass < 2; pass++) {
6423 if (pass == 0) {
6424 tmp = neon_load_reg(rn, 0);
6425 } else {
6426 tmp = tmp3;
6427 tmp2 = tmp4;
6429 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6430 if (op != 11) {
6431 neon_load_reg64(cpu_V1, rd + pass);
6433 switch (op) {
6434 case 6:
6435 gen_neon_negl(cpu_V0, size);
6436 /* Fall through */
6437 case 2:
6438 gen_neon_addl(size);
6439 break;
6440 case 3: case 7:
6441 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6442 if (op == 7) {
6443 gen_neon_negl(cpu_V0, size);
6445 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6446 break;
6447 case 10:
6448 /* no-op */
6449 break;
6450 case 11:
6451 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6452 break;
6453 default:
6454 abort();
6456 neon_store_reg64(cpu_V0, rd + pass);
6460 break;
6461 default: /* 14 and 15 are RESERVED */
6462 return 1;
6465 } else { /* size == 3 */
6466 if (!u) {
6467 /* Extract. */
6468 imm = (insn >> 8) & 0xf;
6470 if (imm > 7 && !q)
6471 return 1;
6473 if (q && ((rd | rn | rm) & 1)) {
6474 return 1;
6477 if (imm == 0) {
6478 neon_load_reg64(cpu_V0, rn);
6479 if (q) {
6480 neon_load_reg64(cpu_V1, rn + 1);
6482 } else if (imm == 8) {
6483 neon_load_reg64(cpu_V0, rn + 1);
6484 if (q) {
6485 neon_load_reg64(cpu_V1, rm);
6487 } else if (q) {
6488 tmp64 = tcg_temp_new_i64();
6489 if (imm < 8) {
6490 neon_load_reg64(cpu_V0, rn);
6491 neon_load_reg64(tmp64, rn + 1);
6492 } else {
6493 neon_load_reg64(cpu_V0, rn + 1);
6494 neon_load_reg64(tmp64, rm);
6496 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6497 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6498 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6499 if (imm < 8) {
6500 neon_load_reg64(cpu_V1, rm);
6501 } else {
6502 neon_load_reg64(cpu_V1, rm + 1);
6503 imm -= 8;
6505 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6506 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6507 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6508 tcg_temp_free_i64(tmp64);
6509 } else {
6510 /* BUGFIX */
6511 neon_load_reg64(cpu_V0, rn);
6512 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6513 neon_load_reg64(cpu_V1, rm);
6514 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6515 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6517 neon_store_reg64(cpu_V0, rd);
6518 if (q) {
6519 neon_store_reg64(cpu_V1, rd + 1);
6521 } else if ((insn & (1 << 11)) == 0) {
6522 /* Two register misc. */
6523 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6524 size = (insn >> 18) & 3;
6525 /* UNDEF for unknown op values and bad op-size combinations */
6526 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6527 return 1;
6529 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6530 q && ((rm | rd) & 1)) {
6531 return 1;
6533 switch (op) {
6534 case NEON_2RM_VREV64:
6535 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6536 tmp = neon_load_reg(rm, pass * 2);
6537 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6538 switch (size) {
6539 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6540 case 1: gen_swap_half(tmp); break;
6541 case 2: /* no-op */ break;
6542 default: abort();
6544 neon_store_reg(rd, pass * 2 + 1, tmp);
6545 if (size == 2) {
6546 neon_store_reg(rd, pass * 2, tmp2);
6547 } else {
6548 switch (size) {
6549 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6550 case 1: gen_swap_half(tmp2); break;
6551 default: abort();
6553 neon_store_reg(rd, pass * 2, tmp2);
6556 break;
6557 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6558 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6559 for (pass = 0; pass < q + 1; pass++) {
6560 tmp = neon_load_reg(rm, pass * 2);
6561 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6562 tmp = neon_load_reg(rm, pass * 2 + 1);
6563 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6564 switch (size) {
6565 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6566 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6567 case 2: tcg_gen_add_i64(CPU_V001); break;
6568 default: abort();
6570 if (op >= NEON_2RM_VPADAL) {
6571 /* Accumulate. */
6572 neon_load_reg64(cpu_V1, rd + pass);
6573 gen_neon_addl(size);
6575 neon_store_reg64(cpu_V0, rd + pass);
6577 break;
6578 case NEON_2RM_VTRN:
6579 if (size == 2) {
6580 int n;
6581 for (n = 0; n < (q ? 4 : 2); n += 2) {
6582 tmp = neon_load_reg(rm, n);
6583 tmp2 = neon_load_reg(rd, n + 1);
6584 neon_store_reg(rm, n, tmp2);
6585 neon_store_reg(rd, n + 1, tmp);
6587 } else {
6588 goto elementwise;
6590 break;
6591 case NEON_2RM_VUZP:
6592 if (gen_neon_unzip(rd, rm, size, q)) {
6593 return 1;
6595 break;
6596 case NEON_2RM_VZIP:
6597 if (gen_neon_zip(rd, rm, size, q)) {
6598 return 1;
6600 break;
6601 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6602 /* also VQMOVUN; op field and mnemonics don't line up */
6603 if (rm & 1) {
6604 return 1;
6606 TCGV_UNUSED_I32(tmp2);
6607 for (pass = 0; pass < 2; pass++) {
6608 neon_load_reg64(cpu_V0, rm + pass);
6609 tmp = tcg_temp_new_i32();
6610 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6611 tmp, cpu_V0);
6612 if (pass == 0) {
6613 tmp2 = tmp;
6614 } else {
6615 neon_store_reg(rd, 0, tmp2);
6616 neon_store_reg(rd, 1, tmp);
6619 break;
6620 case NEON_2RM_VSHLL:
6621 if (q || (rd & 1)) {
6622 return 1;
6624 tmp = neon_load_reg(rm, 0);
6625 tmp2 = neon_load_reg(rm, 1);
6626 for (pass = 0; pass < 2; pass++) {
6627 if (pass == 1)
6628 tmp = tmp2;
6629 gen_neon_widen(cpu_V0, tmp, size, 1);
6630 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6631 neon_store_reg64(cpu_V0, rd + pass);
6633 break;
6634 case NEON_2RM_VCVT_F16_F32:
6635 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6636 q || (rm & 1)) {
6637 return 1;
6639 tmp = tcg_temp_new_i32();
6640 tmp2 = tcg_temp_new_i32();
6641 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6642 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6643 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6644 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6645 tcg_gen_shli_i32(tmp2, tmp2, 16);
6646 tcg_gen_or_i32(tmp2, tmp2, tmp);
6647 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6648 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6649 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6650 neon_store_reg(rd, 0, tmp2);
6651 tmp2 = tcg_temp_new_i32();
6652 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6653 tcg_gen_shli_i32(tmp2, tmp2, 16);
6654 tcg_gen_or_i32(tmp2, tmp2, tmp);
6655 neon_store_reg(rd, 1, tmp2);
6656 tcg_temp_free_i32(tmp);
6657 break;
6658 case NEON_2RM_VCVT_F32_F16:
6659 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6660 q || (rd & 1)) {
6661 return 1;
6663 tmp3 = tcg_temp_new_i32();
6664 tmp = neon_load_reg(rm, 0);
6665 tmp2 = neon_load_reg(rm, 1);
6666 tcg_gen_ext16u_i32(tmp3, tmp);
6667 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6668 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6669 tcg_gen_shri_i32(tmp3, tmp, 16);
6670 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6671 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6672 tcg_temp_free_i32(tmp);
6673 tcg_gen_ext16u_i32(tmp3, tmp2);
6674 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6675 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6676 tcg_gen_shri_i32(tmp3, tmp2, 16);
6677 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6678 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6679 tcg_temp_free_i32(tmp2);
6680 tcg_temp_free_i32(tmp3);
6681 break;
6682 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6683 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6684 || ((rm | rd) & 1)) {
6685 return 1;
6687 tmp = tcg_const_i32(rd);
6688 tmp2 = tcg_const_i32(rm);
6690 /* Bit 6 is the lowest opcode bit; it distinguishes between
6691 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6693 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6695 if (op == NEON_2RM_AESE) {
6696 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6697 } else {
6698 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6700 tcg_temp_free_i32(tmp);
6701 tcg_temp_free_i32(tmp2);
6702 tcg_temp_free_i32(tmp3);
6703 break;
6704 case NEON_2RM_SHA1H:
6705 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
6706 || ((rm | rd) & 1)) {
6707 return 1;
6709 tmp = tcg_const_i32(rd);
6710 tmp2 = tcg_const_i32(rm);
6712 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
6714 tcg_temp_free_i32(tmp);
6715 tcg_temp_free_i32(tmp2);
6716 break;
6717 case NEON_2RM_SHA1SU1:
6718 if ((rm | rd) & 1) {
6719 return 1;
6721 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6722 if (q) {
6723 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
6724 return 1;
6726 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
6727 return 1;
6729 tmp = tcg_const_i32(rd);
6730 tmp2 = tcg_const_i32(rm);
6731 if (q) {
6732 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
6733 } else {
6734 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
6736 tcg_temp_free_i32(tmp);
6737 tcg_temp_free_i32(tmp2);
6738 break;
6739 default:
6740 elementwise:
6741 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6742 if (neon_2rm_is_float_op(op)) {
6743 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6744 neon_reg_offset(rm, pass));
6745 TCGV_UNUSED_I32(tmp);
6746 } else {
6747 tmp = neon_load_reg(rm, pass);
6749 switch (op) {
6750 case NEON_2RM_VREV32:
6751 switch (size) {
6752 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6753 case 1: gen_swap_half(tmp); break;
6754 default: abort();
6756 break;
6757 case NEON_2RM_VREV16:
6758 gen_rev16(tmp);
6759 break;
6760 case NEON_2RM_VCLS:
6761 switch (size) {
6762 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6763 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6764 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6765 default: abort();
6767 break;
6768 case NEON_2RM_VCLZ:
6769 switch (size) {
6770 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6771 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6772 case 2: gen_helper_clz(tmp, tmp); break;
6773 default: abort();
6775 break;
6776 case NEON_2RM_VCNT:
6777 gen_helper_neon_cnt_u8(tmp, tmp);
6778 break;
6779 case NEON_2RM_VMVN:
6780 tcg_gen_not_i32(tmp, tmp);
6781 break;
6782 case NEON_2RM_VQABS:
6783 switch (size) {
6784 case 0:
6785 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6786 break;
6787 case 1:
6788 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6789 break;
6790 case 2:
6791 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6792 break;
6793 default: abort();
6795 break;
6796 case NEON_2RM_VQNEG:
6797 switch (size) {
6798 case 0:
6799 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6800 break;
6801 case 1:
6802 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6803 break;
6804 case 2:
6805 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6806 break;
6807 default: abort();
6809 break;
6810 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6811 tmp2 = tcg_const_i32(0);
6812 switch(size) {
6813 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6814 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6815 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6816 default: abort();
6818 tcg_temp_free_i32(tmp2);
6819 if (op == NEON_2RM_VCLE0) {
6820 tcg_gen_not_i32(tmp, tmp);
6822 break;
6823 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6824 tmp2 = tcg_const_i32(0);
6825 switch(size) {
6826 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6827 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6828 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6829 default: abort();
6831 tcg_temp_free_i32(tmp2);
6832 if (op == NEON_2RM_VCLT0) {
6833 tcg_gen_not_i32(tmp, tmp);
6835 break;
6836 case NEON_2RM_VCEQ0:
6837 tmp2 = tcg_const_i32(0);
6838 switch(size) {
6839 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6840 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6841 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6842 default: abort();
6844 tcg_temp_free_i32(tmp2);
6845 break;
6846 case NEON_2RM_VABS:
6847 switch(size) {
6848 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6849 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6850 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6851 default: abort();
6853 break;
6854 case NEON_2RM_VNEG:
6855 tmp2 = tcg_const_i32(0);
6856 gen_neon_rsb(size, tmp, tmp2);
6857 tcg_temp_free_i32(tmp2);
6858 break;
6859 case NEON_2RM_VCGT0_F:
6861 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6862 tmp2 = tcg_const_i32(0);
6863 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6864 tcg_temp_free_i32(tmp2);
6865 tcg_temp_free_ptr(fpstatus);
6866 break;
6868 case NEON_2RM_VCGE0_F:
6870 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6871 tmp2 = tcg_const_i32(0);
6872 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6873 tcg_temp_free_i32(tmp2);
6874 tcg_temp_free_ptr(fpstatus);
6875 break;
6877 case NEON_2RM_VCEQ0_F:
6879 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6880 tmp2 = tcg_const_i32(0);
6881 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6882 tcg_temp_free_i32(tmp2);
6883 tcg_temp_free_ptr(fpstatus);
6884 break;
6886 case NEON_2RM_VCLE0_F:
6888 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6889 tmp2 = tcg_const_i32(0);
6890 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6891 tcg_temp_free_i32(tmp2);
6892 tcg_temp_free_ptr(fpstatus);
6893 break;
6895 case NEON_2RM_VCLT0_F:
6897 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6898 tmp2 = tcg_const_i32(0);
6899 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6900 tcg_temp_free_i32(tmp2);
6901 tcg_temp_free_ptr(fpstatus);
6902 break;
6904 case NEON_2RM_VABS_F:
6905 gen_vfp_abs(0);
6906 break;
6907 case NEON_2RM_VNEG_F:
6908 gen_vfp_neg(0);
6909 break;
6910 case NEON_2RM_VSWP:
6911 tmp2 = neon_load_reg(rd, pass);
6912 neon_store_reg(rm, pass, tmp2);
6913 break;
6914 case NEON_2RM_VTRN:
6915 tmp2 = neon_load_reg(rd, pass);
6916 switch (size) {
6917 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6918 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6919 default: abort();
6921 neon_store_reg(rm, pass, tmp2);
6922 break;
6923 case NEON_2RM_VRINTN:
6924 case NEON_2RM_VRINTA:
6925 case NEON_2RM_VRINTM:
6926 case NEON_2RM_VRINTP:
6927 case NEON_2RM_VRINTZ:
6929 TCGv_i32 tcg_rmode;
6930 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6931 int rmode;
6933 if (op == NEON_2RM_VRINTZ) {
6934 rmode = FPROUNDING_ZERO;
6935 } else {
6936 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6939 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6940 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6941 cpu_env);
6942 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6943 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6944 cpu_env);
6945 tcg_temp_free_ptr(fpstatus);
6946 tcg_temp_free_i32(tcg_rmode);
6947 break;
6949 case NEON_2RM_VRINTX:
6951 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6952 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6953 tcg_temp_free_ptr(fpstatus);
6954 break;
6956 case NEON_2RM_VCVTAU:
6957 case NEON_2RM_VCVTAS:
6958 case NEON_2RM_VCVTNU:
6959 case NEON_2RM_VCVTNS:
6960 case NEON_2RM_VCVTPU:
6961 case NEON_2RM_VCVTPS:
6962 case NEON_2RM_VCVTMU:
6963 case NEON_2RM_VCVTMS:
6965 bool is_signed = !extract32(insn, 7, 1);
6966 TCGv_ptr fpst = get_fpstatus_ptr(1);
6967 TCGv_i32 tcg_rmode, tcg_shift;
6968 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6970 tcg_shift = tcg_const_i32(0);
6971 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6972 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6973 cpu_env);
6975 if (is_signed) {
6976 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6977 tcg_shift, fpst);
6978 } else {
6979 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6980 tcg_shift, fpst);
6983 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6984 cpu_env);
6985 tcg_temp_free_i32(tcg_rmode);
6986 tcg_temp_free_i32(tcg_shift);
6987 tcg_temp_free_ptr(fpst);
6988 break;
6990 case NEON_2RM_VRECPE:
6992 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6993 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6994 tcg_temp_free_ptr(fpstatus);
6995 break;
6997 case NEON_2RM_VRSQRTE:
6999 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7000 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7001 tcg_temp_free_ptr(fpstatus);
7002 break;
7004 case NEON_2RM_VRECPE_F:
7006 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7007 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7008 tcg_temp_free_ptr(fpstatus);
7009 break;
7011 case NEON_2RM_VRSQRTE_F:
7013 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7014 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7015 tcg_temp_free_ptr(fpstatus);
7016 break;
7018 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7019 gen_vfp_sito(0, 1);
7020 break;
7021 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7022 gen_vfp_uito(0, 1);
7023 break;
7024 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7025 gen_vfp_tosiz(0, 1);
7026 break;
7027 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7028 gen_vfp_touiz(0, 1);
7029 break;
7030 default:
7031 /* Reserved op values were caught by the
7032 * neon_2rm_sizes[] check earlier.
7034 abort();
7036 if (neon_2rm_is_float_op(op)) {
7037 tcg_gen_st_f32(cpu_F0s, cpu_env,
7038 neon_reg_offset(rd, pass));
7039 } else {
7040 neon_store_reg(rd, pass, tmp);
7043 break;
7045 } else if ((insn & (1 << 10)) == 0) {
7046 /* VTBL, VTBX. */
7047 int n = ((insn >> 8) & 3) + 1;
7048 if ((rn + n) > 32) {
7049 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7050 * helper function running off the end of the register file.
7052 return 1;
7054 n <<= 3;
7055 if (insn & (1 << 6)) {
7056 tmp = neon_load_reg(rd, 0);
7057 } else {
7058 tmp = tcg_temp_new_i32();
7059 tcg_gen_movi_i32(tmp, 0);
7061 tmp2 = neon_load_reg(rm, 0);
7062 tmp4 = tcg_const_i32(rn);
7063 tmp5 = tcg_const_i32(n);
7064 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7065 tcg_temp_free_i32(tmp);
7066 if (insn & (1 << 6)) {
7067 tmp = neon_load_reg(rd, 1);
7068 } else {
7069 tmp = tcg_temp_new_i32();
7070 tcg_gen_movi_i32(tmp, 0);
7072 tmp3 = neon_load_reg(rm, 1);
7073 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7074 tcg_temp_free_i32(tmp5);
7075 tcg_temp_free_i32(tmp4);
7076 neon_store_reg(rd, 0, tmp2);
7077 neon_store_reg(rd, 1, tmp3);
7078 tcg_temp_free_i32(tmp);
7079 } else if ((insn & 0x380) == 0) {
7080 /* VDUP */
7081 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7082 return 1;
7084 if (insn & (1 << 19)) {
7085 tmp = neon_load_reg(rm, 1);
7086 } else {
7087 tmp = neon_load_reg(rm, 0);
7089 if (insn & (1 << 16)) {
7090 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7091 } else if (insn & (1 << 17)) {
7092 if ((insn >> 18) & 1)
7093 gen_neon_dup_high16(tmp);
7094 else
7095 gen_neon_dup_low16(tmp);
7097 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7098 tmp2 = tcg_temp_new_i32();
7099 tcg_gen_mov_i32(tmp2, tmp);
7100 neon_store_reg(rd, pass, tmp2);
7102 tcg_temp_free_i32(tmp);
7103 } else {
7104 return 1;
7108 return 0;
7111 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7113 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7114 const ARMCPRegInfo *ri;
7116 cpnum = (insn >> 8) & 0xf;
7118 /* First check for coprocessor space used for XScale/iwMMXt insns */
7119 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7120 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7121 return 1;
7123 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7124 return disas_iwmmxt_insn(s, insn);
7125 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7126 return disas_dsp_insn(s, insn);
7128 return 1;
7131 /* Otherwise treat as a generic register access */
7132 is64 = (insn & (1 << 25)) == 0;
7133 if (!is64 && ((insn & (1 << 4)) == 0)) {
7134 /* cdp */
7135 return 1;
7138 crm = insn & 0xf;
7139 if (is64) {
7140 crn = 0;
7141 opc1 = (insn >> 4) & 0xf;
7142 opc2 = 0;
7143 rt2 = (insn >> 16) & 0xf;
7144 } else {
7145 crn = (insn >> 16) & 0xf;
7146 opc1 = (insn >> 21) & 7;
7147 opc2 = (insn >> 5) & 7;
7148 rt2 = 0;
7150 isread = (insn >> 20) & 1;
7151 rt = (insn >> 12) & 0xf;
7153 ri = get_arm_cp_reginfo(s->cp_regs,
7154 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7155 if (ri) {
7156 /* Check access permissions */
7157 if (!cp_access_ok(s->current_el, ri, isread)) {
7158 return 1;
7161 if (ri->accessfn ||
7162 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7163 /* Emit code to perform further access permissions checks at
7164 * runtime; this may result in an exception.
7165 * Note that on XScale all cp0..c13 registers do an access check
7166 * call in order to handle c15_cpar.
7168 TCGv_ptr tmpptr;
7169 TCGv_i32 tcg_syn;
7170 uint32_t syndrome;
7172 /* Note that since we are an implementation which takes an
7173 * exception on a trapped conditional instruction only if the
7174 * instruction passes its condition code check, we can take
7175 * advantage of the clause in the ARM ARM that allows us to set
7176 * the COND field in the instruction to 0xE in all cases.
7177 * We could fish the actual condition out of the insn (ARM)
7178 * or the condexec bits (Thumb) but it isn't necessary.
7180 switch (cpnum) {
7181 case 14:
7182 if (is64) {
7183 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7184 isread, s->thumb);
7185 } else {
7186 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7187 rt, isread, s->thumb);
7189 break;
7190 case 15:
7191 if (is64) {
7192 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7193 isread, s->thumb);
7194 } else {
7195 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7196 rt, isread, s->thumb);
7198 break;
7199 default:
7200 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7201 * so this can only happen if this is an ARMv7 or earlier CPU,
7202 * in which case the syndrome information won't actually be
7203 * guest visible.
7205 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7206 syndrome = syn_uncategorized();
7207 break;
7210 gen_set_pc_im(s, s->pc - 4);
7211 tmpptr = tcg_const_ptr(ri);
7212 tcg_syn = tcg_const_i32(syndrome);
7213 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
7214 tcg_temp_free_ptr(tmpptr);
7215 tcg_temp_free_i32(tcg_syn);
7218 /* Handle special cases first */
7219 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7220 case ARM_CP_NOP:
7221 return 0;
7222 case ARM_CP_WFI:
7223 if (isread) {
7224 return 1;
7226 gen_set_pc_im(s, s->pc);
7227 s->is_jmp = DISAS_WFI;
7228 return 0;
7229 default:
7230 break;
7233 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7234 gen_io_start();
7237 if (isread) {
7238 /* Read */
7239 if (is64) {
7240 TCGv_i64 tmp64;
7241 TCGv_i32 tmp;
7242 if (ri->type & ARM_CP_CONST) {
7243 tmp64 = tcg_const_i64(ri->resetvalue);
7244 } else if (ri->readfn) {
7245 TCGv_ptr tmpptr;
7246 tmp64 = tcg_temp_new_i64();
7247 tmpptr = tcg_const_ptr(ri);
7248 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7249 tcg_temp_free_ptr(tmpptr);
7250 } else {
7251 tmp64 = tcg_temp_new_i64();
7252 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7254 tmp = tcg_temp_new_i32();
7255 tcg_gen_extrl_i64_i32(tmp, tmp64);
7256 store_reg(s, rt, tmp);
7257 tcg_gen_shri_i64(tmp64, tmp64, 32);
7258 tmp = tcg_temp_new_i32();
7259 tcg_gen_extrl_i64_i32(tmp, tmp64);
7260 tcg_temp_free_i64(tmp64);
7261 store_reg(s, rt2, tmp);
7262 } else {
7263 TCGv_i32 tmp;
7264 if (ri->type & ARM_CP_CONST) {
7265 tmp = tcg_const_i32(ri->resetvalue);
7266 } else if (ri->readfn) {
7267 TCGv_ptr tmpptr;
7268 tmp = tcg_temp_new_i32();
7269 tmpptr = tcg_const_ptr(ri);
7270 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7271 tcg_temp_free_ptr(tmpptr);
7272 } else {
7273 tmp = load_cpu_offset(ri->fieldoffset);
7275 if (rt == 15) {
7276 /* Destination register of r15 for 32 bit loads sets
7277 * the condition codes from the high 4 bits of the value
7279 gen_set_nzcv(tmp);
7280 tcg_temp_free_i32(tmp);
7281 } else {
7282 store_reg(s, rt, tmp);
7285 } else {
7286 /* Write */
7287 if (ri->type & ARM_CP_CONST) {
7288 /* If not forbidden by access permissions, treat as WI */
7289 return 0;
7292 if (is64) {
7293 TCGv_i32 tmplo, tmphi;
7294 TCGv_i64 tmp64 = tcg_temp_new_i64();
7295 tmplo = load_reg(s, rt);
7296 tmphi = load_reg(s, rt2);
7297 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7298 tcg_temp_free_i32(tmplo);
7299 tcg_temp_free_i32(tmphi);
7300 if (ri->writefn) {
7301 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7302 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7303 tcg_temp_free_ptr(tmpptr);
7304 } else {
7305 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7307 tcg_temp_free_i64(tmp64);
7308 } else {
7309 if (ri->writefn) {
7310 TCGv_i32 tmp;
7311 TCGv_ptr tmpptr;
7312 tmp = load_reg(s, rt);
7313 tmpptr = tcg_const_ptr(ri);
7314 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7315 tcg_temp_free_ptr(tmpptr);
7316 tcg_temp_free_i32(tmp);
7317 } else {
7318 TCGv_i32 tmp = load_reg(s, rt);
7319 store_cpu_offset(tmp, ri->fieldoffset);
7324 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7325 /* I/O operations must end the TB here (whether read or write) */
7326 gen_io_end();
7327 gen_lookup_tb(s);
7328 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7329 /* We default to ending the TB on a coprocessor register write,
7330 * but allow this to be suppressed by the register definition
7331 * (usually only necessary to work around guest bugs).
7333 gen_lookup_tb(s);
7336 return 0;
7339 /* Unknown register; this might be a guest error or a QEMU
7340 * unimplemented feature.
7342 if (is64) {
7343 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7344 "64 bit system register cp:%d opc1: %d crm:%d "
7345 "(%s)\n",
7346 isread ? "read" : "write", cpnum, opc1, crm,
7347 s->ns ? "non-secure" : "secure");
7348 } else {
7349 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7350 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7351 "(%s)\n",
7352 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7353 s->ns ? "non-secure" : "secure");
7356 return 1;
7360 /* Store a 64-bit value to a register pair. Clobbers val. */
7361 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7363 TCGv_i32 tmp;
7364 tmp = tcg_temp_new_i32();
7365 tcg_gen_extrl_i64_i32(tmp, val);
7366 store_reg(s, rlow, tmp);
7367 tmp = tcg_temp_new_i32();
7368 tcg_gen_shri_i64(val, val, 32);
7369 tcg_gen_extrl_i64_i32(tmp, val);
7370 store_reg(s, rhigh, tmp);
7373 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7374 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7376 TCGv_i64 tmp;
7377 TCGv_i32 tmp2;
7379 /* Load value and extend to 64 bits. */
7380 tmp = tcg_temp_new_i64();
7381 tmp2 = load_reg(s, rlow);
7382 tcg_gen_extu_i32_i64(tmp, tmp2);
7383 tcg_temp_free_i32(tmp2);
7384 tcg_gen_add_i64(val, val, tmp);
7385 tcg_temp_free_i64(tmp);
7388 /* load and add a 64-bit value from a register pair. */
7389 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7391 TCGv_i64 tmp;
7392 TCGv_i32 tmpl;
7393 TCGv_i32 tmph;
7395 /* Load 64-bit value rd:rn. */
7396 tmpl = load_reg(s, rlow);
7397 tmph = load_reg(s, rhigh);
7398 tmp = tcg_temp_new_i64();
7399 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7400 tcg_temp_free_i32(tmpl);
7401 tcg_temp_free_i32(tmph);
7402 tcg_gen_add_i64(val, val, tmp);
7403 tcg_temp_free_i64(tmp);
7406 /* Set N and Z flags from hi|lo. */
7407 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7409 tcg_gen_mov_i32(cpu_NF, hi);
7410 tcg_gen_or_i32(cpu_ZF, lo, hi);
7413 /* Load/Store exclusive instructions are implemented by remembering
7414 the value/address loaded, and seeing if these are the same
7415 when the store is performed. This should be sufficient to implement
7416 the architecturally mandated semantics, and avoids having to monitor
7417 regular stores.
7419 In system emulation mode only one CPU will be running at once, so
7420 this sequence is effectively atomic. In user emulation mode we
7421 throw an exception and handle the atomic operation elsewhere. */
7422 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7423 TCGv_i32 addr, int size)
7425 TCGv_i32 tmp = tcg_temp_new_i32();
7427 s->is_ldex = true;
7429 switch (size) {
7430 case 0:
7431 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7432 break;
7433 case 1:
7434 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7435 break;
7436 case 2:
7437 case 3:
7438 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7439 break;
7440 default:
7441 abort();
7444 if (size == 3) {
7445 TCGv_i32 tmp2 = tcg_temp_new_i32();
7446 TCGv_i32 tmp3 = tcg_temp_new_i32();
7448 tcg_gen_addi_i32(tmp2, addr, 4);
7449 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7450 tcg_temp_free_i32(tmp2);
7451 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7452 store_reg(s, rt2, tmp3);
7453 } else {
7454 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7457 store_reg(s, rt, tmp);
7458 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7461 static void gen_clrex(DisasContext *s)
7463 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7466 #ifdef CONFIG_USER_ONLY
7467 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7468 TCGv_i32 addr, int size)
7470 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7471 tcg_gen_movi_i32(cpu_exclusive_info,
7472 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7473 gen_exception_internal_insn(s, 4, EXCP_STREX);
7475 #else
7476 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7477 TCGv_i32 addr, int size)
7479 TCGv_i32 tmp;
7480 TCGv_i64 val64, extaddr;
7481 TCGLabel *done_label;
7482 TCGLabel *fail_label;
7484 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7485 [addr] = {Rt};
7486 {Rd} = 0;
7487 } else {
7488 {Rd} = 1;
7489 } */
7490 fail_label = gen_new_label();
7491 done_label = gen_new_label();
7492 extaddr = tcg_temp_new_i64();
7493 tcg_gen_extu_i32_i64(extaddr, addr);
7494 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7495 tcg_temp_free_i64(extaddr);
7497 tmp = tcg_temp_new_i32();
7498 switch (size) {
7499 case 0:
7500 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7501 break;
7502 case 1:
7503 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7504 break;
7505 case 2:
7506 case 3:
7507 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7508 break;
7509 default:
7510 abort();
7513 val64 = tcg_temp_new_i64();
7514 if (size == 3) {
7515 TCGv_i32 tmp2 = tcg_temp_new_i32();
7516 TCGv_i32 tmp3 = tcg_temp_new_i32();
7517 tcg_gen_addi_i32(tmp2, addr, 4);
7518 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7519 tcg_temp_free_i32(tmp2);
7520 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7521 tcg_temp_free_i32(tmp3);
7522 } else {
7523 tcg_gen_extu_i32_i64(val64, tmp);
7525 tcg_temp_free_i32(tmp);
7527 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7528 tcg_temp_free_i64(val64);
7530 tmp = load_reg(s, rt);
7531 switch (size) {
7532 case 0:
7533 gen_aa32_st8(tmp, addr, get_mem_index(s));
7534 break;
7535 case 1:
7536 gen_aa32_st16(tmp, addr, get_mem_index(s));
7537 break;
7538 case 2:
7539 case 3:
7540 gen_aa32_st32(tmp, addr, get_mem_index(s));
7541 break;
7542 default:
7543 abort();
7545 tcg_temp_free_i32(tmp);
7546 if (size == 3) {
7547 tcg_gen_addi_i32(addr, addr, 4);
7548 tmp = load_reg(s, rt2);
7549 gen_aa32_st32(tmp, addr, get_mem_index(s));
7550 tcg_temp_free_i32(tmp);
7552 tcg_gen_movi_i32(cpu_R[rd], 0);
7553 tcg_gen_br(done_label);
7554 gen_set_label(fail_label);
7555 tcg_gen_movi_i32(cpu_R[rd], 1);
7556 gen_set_label(done_label);
7557 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7559 #endif
7561 /* gen_srs:
7562 * @env: CPUARMState
7563 * @s: DisasContext
7564 * @mode: mode field from insn (which stack to store to)
7565 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7566 * @writeback: true if writeback bit set
7568 * Generate code for the SRS (Store Return State) insn.
7570 static void gen_srs(DisasContext *s,
7571 uint32_t mode, uint32_t amode, bool writeback)
7573 int32_t offset;
7574 TCGv_i32 addr = tcg_temp_new_i32();
7575 TCGv_i32 tmp = tcg_const_i32(mode);
7576 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7577 tcg_temp_free_i32(tmp);
7578 switch (amode) {
7579 case 0: /* DA */
7580 offset = -4;
7581 break;
7582 case 1: /* IA */
7583 offset = 0;
7584 break;
7585 case 2: /* DB */
7586 offset = -8;
7587 break;
7588 case 3: /* IB */
7589 offset = 4;
7590 break;
7591 default:
7592 abort();
7594 tcg_gen_addi_i32(addr, addr, offset);
7595 tmp = load_reg(s, 14);
7596 gen_aa32_st32(tmp, addr, get_mem_index(s));
7597 tcg_temp_free_i32(tmp);
7598 tmp = load_cpu_field(spsr);
7599 tcg_gen_addi_i32(addr, addr, 4);
7600 gen_aa32_st32(tmp, addr, get_mem_index(s));
7601 tcg_temp_free_i32(tmp);
7602 if (writeback) {
7603 switch (amode) {
7604 case 0:
7605 offset = -8;
7606 break;
7607 case 1:
7608 offset = 4;
7609 break;
7610 case 2:
7611 offset = -4;
7612 break;
7613 case 3:
7614 offset = 0;
7615 break;
7616 default:
7617 abort();
7619 tcg_gen_addi_i32(addr, addr, offset);
7620 tmp = tcg_const_i32(mode);
7621 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7622 tcg_temp_free_i32(tmp);
7624 tcg_temp_free_i32(addr);
7627 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7629 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7630 TCGv_i32 tmp;
7631 TCGv_i32 tmp2;
7632 TCGv_i32 tmp3;
7633 TCGv_i32 addr;
7634 TCGv_i64 tmp64;
7636 /* M variants do not implement ARM mode. */
7637 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7638 goto illegal_op;
7640 cond = insn >> 28;
7641 if (cond == 0xf){
7642 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7643 * choose to UNDEF. In ARMv5 and above the space is used
7644 * for miscellaneous unconditional instructions.
7646 ARCH(5);
7648 /* Unconditional instructions. */
7649 if (((insn >> 25) & 7) == 1) {
7650 /* NEON Data processing. */
7651 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7652 goto illegal_op;
7655 if (disas_neon_data_insn(s, insn)) {
7656 goto illegal_op;
7658 return;
7660 if ((insn & 0x0f100000) == 0x04000000) {
7661 /* NEON load/store. */
7662 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7663 goto illegal_op;
7666 if (disas_neon_ls_insn(s, insn)) {
7667 goto illegal_op;
7669 return;
7671 if ((insn & 0x0f000e10) == 0x0e000a00) {
7672 /* VFP. */
7673 if (disas_vfp_insn(s, insn)) {
7674 goto illegal_op;
7676 return;
7678 if (((insn & 0x0f30f000) == 0x0510f000) ||
7679 ((insn & 0x0f30f010) == 0x0710f000)) {
7680 if ((insn & (1 << 22)) == 0) {
7681 /* PLDW; v7MP */
7682 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7683 goto illegal_op;
7686 /* Otherwise PLD; v5TE+ */
7687 ARCH(5TE);
7688 return;
7690 if (((insn & 0x0f70f000) == 0x0450f000) ||
7691 ((insn & 0x0f70f010) == 0x0650f000)) {
7692 ARCH(7);
7693 return; /* PLI; V7 */
7695 if (((insn & 0x0f700000) == 0x04100000) ||
7696 ((insn & 0x0f700010) == 0x06100000)) {
7697 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7698 goto illegal_op;
7700 return; /* v7MP: Unallocated memory hint: must NOP */
7703 if ((insn & 0x0ffffdff) == 0x01010000) {
7704 ARCH(6);
7705 /* setend */
7706 if (((insn >> 9) & 1) != s->bswap_code) {
7707 /* Dynamic endianness switching not implemented. */
7708 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7709 g_assert_not_reached();
7711 return;
7712 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7713 switch ((insn >> 4) & 0xf) {
7714 case 1: /* clrex */
7715 ARCH(6K);
7716 gen_clrex(s);
7717 return;
7718 case 4: /* dsb */
7719 case 5: /* dmb */
7720 case 6: /* isb */
7721 ARCH(7);
7722 /* We don't emulate caches so these are a no-op. */
7723 return;
7724 default:
7725 goto illegal_op;
7727 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7728 /* srs */
7729 if (IS_USER(s)) {
7730 goto illegal_op;
7732 ARCH(6);
7733 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7734 return;
7735 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7736 /* rfe */
7737 int32_t offset;
7738 if (IS_USER(s))
7739 goto illegal_op;
7740 ARCH(6);
7741 rn = (insn >> 16) & 0xf;
7742 addr = load_reg(s, rn);
7743 i = (insn >> 23) & 3;
7744 switch (i) {
7745 case 0: offset = -4; break; /* DA */
7746 case 1: offset = 0; break; /* IA */
7747 case 2: offset = -8; break; /* DB */
7748 case 3: offset = 4; break; /* IB */
7749 default: abort();
7751 if (offset)
7752 tcg_gen_addi_i32(addr, addr, offset);
7753 /* Load PC into tmp and CPSR into tmp2. */
7754 tmp = tcg_temp_new_i32();
7755 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7756 tcg_gen_addi_i32(addr, addr, 4);
7757 tmp2 = tcg_temp_new_i32();
7758 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
7759 if (insn & (1 << 21)) {
7760 /* Base writeback. */
7761 switch (i) {
7762 case 0: offset = -8; break;
7763 case 1: offset = 4; break;
7764 case 2: offset = -4; break;
7765 case 3: offset = 0; break;
7766 default: abort();
7768 if (offset)
7769 tcg_gen_addi_i32(addr, addr, offset);
7770 store_reg(s, rn, addr);
7771 } else {
7772 tcg_temp_free_i32(addr);
7774 gen_rfe(s, tmp, tmp2);
7775 return;
7776 } else if ((insn & 0x0e000000) == 0x0a000000) {
7777 /* branch link and change to thumb (blx <offset>) */
7778 int32_t offset;
7780 val = (uint32_t)s->pc;
7781 tmp = tcg_temp_new_i32();
7782 tcg_gen_movi_i32(tmp, val);
7783 store_reg(s, 14, tmp);
7784 /* Sign-extend the 24-bit offset */
7785 offset = (((int32_t)insn) << 8) >> 8;
7786 /* offset * 4 + bit24 * 2 + (thumb bit) */
7787 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7788 /* pipeline offset */
7789 val += 4;
7790 /* protected by ARCH(5); above, near the start of uncond block */
7791 gen_bx_im(s, val);
7792 return;
7793 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7794 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7795 /* iWMMXt register transfer. */
7796 if (extract32(s->c15_cpar, 1, 1)) {
7797 if (!disas_iwmmxt_insn(s, insn)) {
7798 return;
7802 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7803 /* Coprocessor double register transfer. */
7804 ARCH(5TE);
7805 } else if ((insn & 0x0f000010) == 0x0e000010) {
7806 /* Additional coprocessor register transfer. */
7807 } else if ((insn & 0x0ff10020) == 0x01000000) {
7808 uint32_t mask;
7809 uint32_t val;
7810 /* cps (privileged) */
7811 if (IS_USER(s))
7812 return;
7813 mask = val = 0;
7814 if (insn & (1 << 19)) {
7815 if (insn & (1 << 8))
7816 mask |= CPSR_A;
7817 if (insn & (1 << 7))
7818 mask |= CPSR_I;
7819 if (insn & (1 << 6))
7820 mask |= CPSR_F;
7821 if (insn & (1 << 18))
7822 val |= mask;
7824 if (insn & (1 << 17)) {
7825 mask |= CPSR_M;
7826 val |= (insn & 0x1f);
7828 if (mask) {
7829 gen_set_psr_im(s, mask, 0, val);
7831 return;
7833 goto illegal_op;
7835 if (cond != 0xe) {
7836 /* if not always execute, we generate a conditional jump to
7837 next instruction */
7838 s->condlabel = gen_new_label();
7839 arm_gen_test_cc(cond ^ 1, s->condlabel);
7840 s->condjmp = 1;
7842 if ((insn & 0x0f900000) == 0x03000000) {
7843 if ((insn & (1 << 21)) == 0) {
7844 ARCH(6T2);
7845 rd = (insn >> 12) & 0xf;
7846 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7847 if ((insn & (1 << 22)) == 0) {
7848 /* MOVW */
7849 tmp = tcg_temp_new_i32();
7850 tcg_gen_movi_i32(tmp, val);
7851 } else {
7852 /* MOVT */
7853 tmp = load_reg(s, rd);
7854 tcg_gen_ext16u_i32(tmp, tmp);
7855 tcg_gen_ori_i32(tmp, tmp, val << 16);
7857 store_reg(s, rd, tmp);
7858 } else {
7859 if (((insn >> 12) & 0xf) != 0xf)
7860 goto illegal_op;
7861 if (((insn >> 16) & 0xf) == 0) {
7862 gen_nop_hint(s, insn & 0xff);
7863 } else {
7864 /* CPSR = immediate */
7865 val = insn & 0xff;
7866 shift = ((insn >> 8) & 0xf) * 2;
7867 if (shift)
7868 val = (val >> shift) | (val << (32 - shift));
7869 i = ((insn & (1 << 22)) != 0);
7870 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7871 i, val)) {
7872 goto illegal_op;
7876 } else if ((insn & 0x0f900000) == 0x01000000
7877 && (insn & 0x00000090) != 0x00000090) {
7878 /* miscellaneous instructions */
7879 op1 = (insn >> 21) & 3;
7880 sh = (insn >> 4) & 0xf;
7881 rm = insn & 0xf;
7882 switch (sh) {
7883 case 0x0: /* move program status register */
7884 if (op1 & 1) {
7885 /* PSR = reg */
7886 tmp = load_reg(s, rm);
7887 i = ((op1 & 2) != 0);
7888 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7889 goto illegal_op;
7890 } else {
7891 /* reg = PSR */
7892 rd = (insn >> 12) & 0xf;
7893 if (op1 & 2) {
7894 if (IS_USER(s))
7895 goto illegal_op;
7896 tmp = load_cpu_field(spsr);
7897 } else {
7898 tmp = tcg_temp_new_i32();
7899 gen_helper_cpsr_read(tmp, cpu_env);
7901 store_reg(s, rd, tmp);
7903 break;
7904 case 0x1:
7905 if (op1 == 1) {
7906 /* branch/exchange thumb (bx). */
7907 ARCH(4T);
7908 tmp = load_reg(s, rm);
7909 gen_bx(s, tmp);
7910 } else if (op1 == 3) {
7911 /* clz */
7912 ARCH(5);
7913 rd = (insn >> 12) & 0xf;
7914 tmp = load_reg(s, rm);
7915 gen_helper_clz(tmp, tmp);
7916 store_reg(s, rd, tmp);
7917 } else {
7918 goto illegal_op;
7920 break;
7921 case 0x2:
7922 if (op1 == 1) {
7923 ARCH(5J); /* bxj */
7924 /* Trivial implementation equivalent to bx. */
7925 tmp = load_reg(s, rm);
7926 gen_bx(s, tmp);
7927 } else {
7928 goto illegal_op;
7930 break;
7931 case 0x3:
7932 if (op1 != 1)
7933 goto illegal_op;
7935 ARCH(5);
7936 /* branch link/exchange thumb (blx) */
7937 tmp = load_reg(s, rm);
7938 tmp2 = tcg_temp_new_i32();
7939 tcg_gen_movi_i32(tmp2, s->pc);
7940 store_reg(s, 14, tmp2);
7941 gen_bx(s, tmp);
7942 break;
7943 case 0x4:
7945 /* crc32/crc32c */
7946 uint32_t c = extract32(insn, 8, 4);
7948 /* Check this CPU supports ARMv8 CRC instructions.
7949 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7950 * Bits 8, 10 and 11 should be zero.
7952 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
7953 (c & 0xd) != 0) {
7954 goto illegal_op;
7957 rn = extract32(insn, 16, 4);
7958 rd = extract32(insn, 12, 4);
7960 tmp = load_reg(s, rn);
7961 tmp2 = load_reg(s, rm);
7962 if (op1 == 0) {
7963 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
7964 } else if (op1 == 1) {
7965 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
7967 tmp3 = tcg_const_i32(1 << op1);
7968 if (c & 0x2) {
7969 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7970 } else {
7971 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7973 tcg_temp_free_i32(tmp2);
7974 tcg_temp_free_i32(tmp3);
7975 store_reg(s, rd, tmp);
7976 break;
7978 case 0x5: /* saturating add/subtract */
7979 ARCH(5TE);
7980 rd = (insn >> 12) & 0xf;
7981 rn = (insn >> 16) & 0xf;
7982 tmp = load_reg(s, rm);
7983 tmp2 = load_reg(s, rn);
7984 if (op1 & 2)
7985 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7986 if (op1 & 1)
7987 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7988 else
7989 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7990 tcg_temp_free_i32(tmp2);
7991 store_reg(s, rd, tmp);
7992 break;
7993 case 7:
7995 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
7996 switch (op1) {
7997 case 1:
7998 /* bkpt */
7999 ARCH(5);
8000 gen_exception_insn(s, 4, EXCP_BKPT,
8001 syn_aa32_bkpt(imm16, false),
8002 default_exception_el(s));
8003 break;
8004 case 2:
8005 /* Hypervisor call (v7) */
8006 ARCH(7);
8007 if (IS_USER(s)) {
8008 goto illegal_op;
8010 gen_hvc(s, imm16);
8011 break;
8012 case 3:
8013 /* Secure monitor call (v6+) */
8014 ARCH(6K);
8015 if (IS_USER(s)) {
8016 goto illegal_op;
8018 gen_smc(s);
8019 break;
8020 default:
8021 goto illegal_op;
8023 break;
8025 case 0x8: /* signed multiply */
8026 case 0xa:
8027 case 0xc:
8028 case 0xe:
8029 ARCH(5TE);
8030 rs = (insn >> 8) & 0xf;
8031 rn = (insn >> 12) & 0xf;
8032 rd = (insn >> 16) & 0xf;
8033 if (op1 == 1) {
8034 /* (32 * 16) >> 16 */
8035 tmp = load_reg(s, rm);
8036 tmp2 = load_reg(s, rs);
8037 if (sh & 4)
8038 tcg_gen_sari_i32(tmp2, tmp2, 16);
8039 else
8040 gen_sxth(tmp2);
8041 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8042 tcg_gen_shri_i64(tmp64, tmp64, 16);
8043 tmp = tcg_temp_new_i32();
8044 tcg_gen_extrl_i64_i32(tmp, tmp64);
8045 tcg_temp_free_i64(tmp64);
8046 if ((sh & 2) == 0) {
8047 tmp2 = load_reg(s, rn);
8048 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8049 tcg_temp_free_i32(tmp2);
8051 store_reg(s, rd, tmp);
8052 } else {
8053 /* 16 * 16 */
8054 tmp = load_reg(s, rm);
8055 tmp2 = load_reg(s, rs);
8056 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8057 tcg_temp_free_i32(tmp2);
8058 if (op1 == 2) {
8059 tmp64 = tcg_temp_new_i64();
8060 tcg_gen_ext_i32_i64(tmp64, tmp);
8061 tcg_temp_free_i32(tmp);
8062 gen_addq(s, tmp64, rn, rd);
8063 gen_storeq_reg(s, rn, rd, tmp64);
8064 tcg_temp_free_i64(tmp64);
8065 } else {
8066 if (op1 == 0) {
8067 tmp2 = load_reg(s, rn);
8068 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8069 tcg_temp_free_i32(tmp2);
8071 store_reg(s, rd, tmp);
8074 break;
8075 default:
8076 goto illegal_op;
8078 } else if (((insn & 0x0e000000) == 0 &&
8079 (insn & 0x00000090) != 0x90) ||
8080 ((insn & 0x0e000000) == (1 << 25))) {
8081 int set_cc, logic_cc, shiftop;
8083 op1 = (insn >> 21) & 0xf;
8084 set_cc = (insn >> 20) & 1;
8085 logic_cc = table_logic_cc[op1] & set_cc;
8087 /* data processing instruction */
8088 if (insn & (1 << 25)) {
8089 /* immediate operand */
8090 val = insn & 0xff;
8091 shift = ((insn >> 8) & 0xf) * 2;
8092 if (shift) {
8093 val = (val >> shift) | (val << (32 - shift));
8095 tmp2 = tcg_temp_new_i32();
8096 tcg_gen_movi_i32(tmp2, val);
8097 if (logic_cc && shift) {
8098 gen_set_CF_bit31(tmp2);
8100 } else {
8101 /* register */
8102 rm = (insn) & 0xf;
8103 tmp2 = load_reg(s, rm);
8104 shiftop = (insn >> 5) & 3;
8105 if (!(insn & (1 << 4))) {
8106 shift = (insn >> 7) & 0x1f;
8107 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8108 } else {
8109 rs = (insn >> 8) & 0xf;
8110 tmp = load_reg(s, rs);
8111 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8114 if (op1 != 0x0f && op1 != 0x0d) {
8115 rn = (insn >> 16) & 0xf;
8116 tmp = load_reg(s, rn);
8117 } else {
8118 TCGV_UNUSED_I32(tmp);
8120 rd = (insn >> 12) & 0xf;
8121 switch(op1) {
8122 case 0x00:
8123 tcg_gen_and_i32(tmp, tmp, tmp2);
8124 if (logic_cc) {
8125 gen_logic_CC(tmp);
8127 store_reg_bx(s, rd, tmp);
8128 break;
8129 case 0x01:
8130 tcg_gen_xor_i32(tmp, tmp, tmp2);
8131 if (logic_cc) {
8132 gen_logic_CC(tmp);
8134 store_reg_bx(s, rd, tmp);
8135 break;
8136 case 0x02:
8137 if (set_cc && rd == 15) {
8138 /* SUBS r15, ... is used for exception return. */
8139 if (IS_USER(s)) {
8140 goto illegal_op;
8142 gen_sub_CC(tmp, tmp, tmp2);
8143 gen_exception_return(s, tmp);
8144 } else {
8145 if (set_cc) {
8146 gen_sub_CC(tmp, tmp, tmp2);
8147 } else {
8148 tcg_gen_sub_i32(tmp, tmp, tmp2);
8150 store_reg_bx(s, rd, tmp);
8152 break;
8153 case 0x03:
8154 if (set_cc) {
8155 gen_sub_CC(tmp, tmp2, tmp);
8156 } else {
8157 tcg_gen_sub_i32(tmp, tmp2, tmp);
8159 store_reg_bx(s, rd, tmp);
8160 break;
8161 case 0x04:
8162 if (set_cc) {
8163 gen_add_CC(tmp, tmp, tmp2);
8164 } else {
8165 tcg_gen_add_i32(tmp, tmp, tmp2);
8167 store_reg_bx(s, rd, tmp);
8168 break;
8169 case 0x05:
8170 if (set_cc) {
8171 gen_adc_CC(tmp, tmp, tmp2);
8172 } else {
8173 gen_add_carry(tmp, tmp, tmp2);
8175 store_reg_bx(s, rd, tmp);
8176 break;
8177 case 0x06:
8178 if (set_cc) {
8179 gen_sbc_CC(tmp, tmp, tmp2);
8180 } else {
8181 gen_sub_carry(tmp, tmp, tmp2);
8183 store_reg_bx(s, rd, tmp);
8184 break;
8185 case 0x07:
8186 if (set_cc) {
8187 gen_sbc_CC(tmp, tmp2, tmp);
8188 } else {
8189 gen_sub_carry(tmp, tmp2, tmp);
8191 store_reg_bx(s, rd, tmp);
8192 break;
8193 case 0x08:
8194 if (set_cc) {
8195 tcg_gen_and_i32(tmp, tmp, tmp2);
8196 gen_logic_CC(tmp);
8198 tcg_temp_free_i32(tmp);
8199 break;
8200 case 0x09:
8201 if (set_cc) {
8202 tcg_gen_xor_i32(tmp, tmp, tmp2);
8203 gen_logic_CC(tmp);
8205 tcg_temp_free_i32(tmp);
8206 break;
8207 case 0x0a:
8208 if (set_cc) {
8209 gen_sub_CC(tmp, tmp, tmp2);
8211 tcg_temp_free_i32(tmp);
8212 break;
8213 case 0x0b:
8214 if (set_cc) {
8215 gen_add_CC(tmp, tmp, tmp2);
8217 tcg_temp_free_i32(tmp);
8218 break;
8219 case 0x0c:
8220 tcg_gen_or_i32(tmp, tmp, tmp2);
8221 if (logic_cc) {
8222 gen_logic_CC(tmp);
8224 store_reg_bx(s, rd, tmp);
8225 break;
8226 case 0x0d:
8227 if (logic_cc && rd == 15) {
8228 /* MOVS r15, ... is used for exception return. */
8229 if (IS_USER(s)) {
8230 goto illegal_op;
8232 gen_exception_return(s, tmp2);
8233 } else {
8234 if (logic_cc) {
8235 gen_logic_CC(tmp2);
8237 store_reg_bx(s, rd, tmp2);
8239 break;
8240 case 0x0e:
8241 tcg_gen_andc_i32(tmp, tmp, tmp2);
8242 if (logic_cc) {
8243 gen_logic_CC(tmp);
8245 store_reg_bx(s, rd, tmp);
8246 break;
8247 default:
8248 case 0x0f:
8249 tcg_gen_not_i32(tmp2, tmp2);
8250 if (logic_cc) {
8251 gen_logic_CC(tmp2);
8253 store_reg_bx(s, rd, tmp2);
8254 break;
8256 if (op1 != 0x0f && op1 != 0x0d) {
8257 tcg_temp_free_i32(tmp2);
8259 } else {
8260 /* other instructions */
8261 op1 = (insn >> 24) & 0xf;
8262 switch(op1) {
8263 case 0x0:
8264 case 0x1:
8265 /* multiplies, extra load/stores */
8266 sh = (insn >> 5) & 3;
8267 if (sh == 0) {
8268 if (op1 == 0x0) {
8269 rd = (insn >> 16) & 0xf;
8270 rn = (insn >> 12) & 0xf;
8271 rs = (insn >> 8) & 0xf;
8272 rm = (insn) & 0xf;
8273 op1 = (insn >> 20) & 0xf;
8274 switch (op1) {
8275 case 0: case 1: case 2: case 3: case 6:
8276 /* 32 bit mul */
8277 tmp = load_reg(s, rs);
8278 tmp2 = load_reg(s, rm);
8279 tcg_gen_mul_i32(tmp, tmp, tmp2);
8280 tcg_temp_free_i32(tmp2);
8281 if (insn & (1 << 22)) {
8282 /* Subtract (mls) */
8283 ARCH(6T2);
8284 tmp2 = load_reg(s, rn);
8285 tcg_gen_sub_i32(tmp, tmp2, tmp);
8286 tcg_temp_free_i32(tmp2);
8287 } else if (insn & (1 << 21)) {
8288 /* Add */
8289 tmp2 = load_reg(s, rn);
8290 tcg_gen_add_i32(tmp, tmp, tmp2);
8291 tcg_temp_free_i32(tmp2);
8293 if (insn & (1 << 20))
8294 gen_logic_CC(tmp);
8295 store_reg(s, rd, tmp);
8296 break;
8297 case 4:
8298 /* 64 bit mul double accumulate (UMAAL) */
8299 ARCH(6);
8300 tmp = load_reg(s, rs);
8301 tmp2 = load_reg(s, rm);
8302 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8303 gen_addq_lo(s, tmp64, rn);
8304 gen_addq_lo(s, tmp64, rd);
8305 gen_storeq_reg(s, rn, rd, tmp64);
8306 tcg_temp_free_i64(tmp64);
8307 break;
8308 case 8: case 9: case 10: case 11:
8309 case 12: case 13: case 14: case 15:
8310 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8311 tmp = load_reg(s, rs);
8312 tmp2 = load_reg(s, rm);
8313 if (insn & (1 << 22)) {
8314 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8315 } else {
8316 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8318 if (insn & (1 << 21)) { /* mult accumulate */
8319 TCGv_i32 al = load_reg(s, rn);
8320 TCGv_i32 ah = load_reg(s, rd);
8321 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8322 tcg_temp_free_i32(al);
8323 tcg_temp_free_i32(ah);
8325 if (insn & (1 << 20)) {
8326 gen_logicq_cc(tmp, tmp2);
8328 store_reg(s, rn, tmp);
8329 store_reg(s, rd, tmp2);
8330 break;
8331 default:
8332 goto illegal_op;
8334 } else {
8335 rn = (insn >> 16) & 0xf;
8336 rd = (insn >> 12) & 0xf;
8337 if (insn & (1 << 23)) {
8338 /* load/store exclusive */
8339 int op2 = (insn >> 8) & 3;
8340 op1 = (insn >> 21) & 0x3;
8342 switch (op2) {
8343 case 0: /* lda/stl */
8344 if (op1 == 1) {
8345 goto illegal_op;
8347 ARCH(8);
8348 break;
8349 case 1: /* reserved */
8350 goto illegal_op;
8351 case 2: /* ldaex/stlex */
8352 ARCH(8);
8353 break;
8354 case 3: /* ldrex/strex */
8355 if (op1) {
8356 ARCH(6K);
8357 } else {
8358 ARCH(6);
8360 break;
8363 addr = tcg_temp_local_new_i32();
8364 load_reg_var(s, addr, rn);
8366 /* Since the emulation does not have barriers,
8367 the acquire/release semantics need no special
8368 handling */
8369 if (op2 == 0) {
8370 if (insn & (1 << 20)) {
8371 tmp = tcg_temp_new_i32();
8372 switch (op1) {
8373 case 0: /* lda */
8374 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8375 break;
8376 case 2: /* ldab */
8377 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
8378 break;
8379 case 3: /* ldah */
8380 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8381 break;
8382 default:
8383 abort();
8385 store_reg(s, rd, tmp);
8386 } else {
8387 rm = insn & 0xf;
8388 tmp = load_reg(s, rm);
8389 switch (op1) {
8390 case 0: /* stl */
8391 gen_aa32_st32(tmp, addr, get_mem_index(s));
8392 break;
8393 case 2: /* stlb */
8394 gen_aa32_st8(tmp, addr, get_mem_index(s));
8395 break;
8396 case 3: /* stlh */
8397 gen_aa32_st16(tmp, addr, get_mem_index(s));
8398 break;
8399 default:
8400 abort();
8402 tcg_temp_free_i32(tmp);
8404 } else if (insn & (1 << 20)) {
8405 switch (op1) {
8406 case 0: /* ldrex */
8407 gen_load_exclusive(s, rd, 15, addr, 2);
8408 break;
8409 case 1: /* ldrexd */
8410 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8411 break;
8412 case 2: /* ldrexb */
8413 gen_load_exclusive(s, rd, 15, addr, 0);
8414 break;
8415 case 3: /* ldrexh */
8416 gen_load_exclusive(s, rd, 15, addr, 1);
8417 break;
8418 default:
8419 abort();
8421 } else {
8422 rm = insn & 0xf;
8423 switch (op1) {
8424 case 0: /* strex */
8425 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8426 break;
8427 case 1: /* strexd */
8428 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8429 break;
8430 case 2: /* strexb */
8431 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8432 break;
8433 case 3: /* strexh */
8434 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8435 break;
8436 default:
8437 abort();
8440 tcg_temp_free_i32(addr);
8441 } else {
8442 /* SWP instruction */
8443 rm = (insn) & 0xf;
8445 /* ??? This is not really atomic. However we know
8446 we never have multiple CPUs running in parallel,
8447 so it is good enough. */
8448 addr = load_reg(s, rn);
8449 tmp = load_reg(s, rm);
8450 tmp2 = tcg_temp_new_i32();
8451 if (insn & (1 << 22)) {
8452 gen_aa32_ld8u(tmp2, addr, get_mem_index(s));
8453 gen_aa32_st8(tmp, addr, get_mem_index(s));
8454 } else {
8455 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
8456 gen_aa32_st32(tmp, addr, get_mem_index(s));
8458 tcg_temp_free_i32(tmp);
8459 tcg_temp_free_i32(addr);
8460 store_reg(s, rd, tmp2);
8463 } else {
8464 int address_offset;
8465 bool load = insn & (1 << 20);
8466 bool doubleword = false;
8467 /* Misc load/store */
8468 rn = (insn >> 16) & 0xf;
8469 rd = (insn >> 12) & 0xf;
8471 if (!load && (sh & 2)) {
8472 /* doubleword */
8473 ARCH(5TE);
8474 if (rd & 1) {
8475 /* UNPREDICTABLE; we choose to UNDEF */
8476 goto illegal_op;
8478 load = (sh & 1) == 0;
8479 doubleword = true;
8482 addr = load_reg(s, rn);
8483 if (insn & (1 << 24))
8484 gen_add_datah_offset(s, insn, 0, addr);
8485 address_offset = 0;
8487 if (doubleword) {
8488 if (!load) {
8489 /* store */
8490 tmp = load_reg(s, rd);
8491 gen_aa32_st32(tmp, addr, get_mem_index(s));
8492 tcg_temp_free_i32(tmp);
8493 tcg_gen_addi_i32(addr, addr, 4);
8494 tmp = load_reg(s, rd + 1);
8495 gen_aa32_st32(tmp, addr, get_mem_index(s));
8496 tcg_temp_free_i32(tmp);
8497 } else {
8498 /* load */
8499 tmp = tcg_temp_new_i32();
8500 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8501 store_reg(s, rd, tmp);
8502 tcg_gen_addi_i32(addr, addr, 4);
8503 tmp = tcg_temp_new_i32();
8504 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8505 rd++;
8507 address_offset = -4;
8508 } else if (load) {
8509 /* load */
8510 tmp = tcg_temp_new_i32();
8511 switch (sh) {
8512 case 1:
8513 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8514 break;
8515 case 2:
8516 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
8517 break;
8518 default:
8519 case 3:
8520 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
8521 break;
8523 } else {
8524 /* store */
8525 tmp = load_reg(s, rd);
8526 gen_aa32_st16(tmp, addr, get_mem_index(s));
8527 tcg_temp_free_i32(tmp);
8529 /* Perform base writeback before the loaded value to
8530 ensure correct behavior with overlapping index registers.
8531 ldrd with base writeback is undefined if the
8532 destination and index registers overlap. */
8533 if (!(insn & (1 << 24))) {
8534 gen_add_datah_offset(s, insn, address_offset, addr);
8535 store_reg(s, rn, addr);
8536 } else if (insn & (1 << 21)) {
8537 if (address_offset)
8538 tcg_gen_addi_i32(addr, addr, address_offset);
8539 store_reg(s, rn, addr);
8540 } else {
8541 tcg_temp_free_i32(addr);
8543 if (load) {
8544 /* Complete the load. */
8545 store_reg(s, rd, tmp);
8548 break;
8549 case 0x4:
8550 case 0x5:
8551 goto do_ldst;
8552 case 0x6:
8553 case 0x7:
8554 if (insn & (1 << 4)) {
8555 ARCH(6);
8556 /* Armv6 Media instructions. */
8557 rm = insn & 0xf;
8558 rn = (insn >> 16) & 0xf;
8559 rd = (insn >> 12) & 0xf;
8560 rs = (insn >> 8) & 0xf;
8561 switch ((insn >> 23) & 3) {
8562 case 0: /* Parallel add/subtract. */
8563 op1 = (insn >> 20) & 7;
8564 tmp = load_reg(s, rn);
8565 tmp2 = load_reg(s, rm);
8566 sh = (insn >> 5) & 7;
8567 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8568 goto illegal_op;
8569 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8570 tcg_temp_free_i32(tmp2);
8571 store_reg(s, rd, tmp);
8572 break;
8573 case 1:
8574 if ((insn & 0x00700020) == 0) {
8575 /* Halfword pack. */
8576 tmp = load_reg(s, rn);
8577 tmp2 = load_reg(s, rm);
8578 shift = (insn >> 7) & 0x1f;
8579 if (insn & (1 << 6)) {
8580 /* pkhtb */
8581 if (shift == 0)
8582 shift = 31;
8583 tcg_gen_sari_i32(tmp2, tmp2, shift);
8584 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8585 tcg_gen_ext16u_i32(tmp2, tmp2);
8586 } else {
8587 /* pkhbt */
8588 if (shift)
8589 tcg_gen_shli_i32(tmp2, tmp2, shift);
8590 tcg_gen_ext16u_i32(tmp, tmp);
8591 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8593 tcg_gen_or_i32(tmp, tmp, tmp2);
8594 tcg_temp_free_i32(tmp2);
8595 store_reg(s, rd, tmp);
8596 } else if ((insn & 0x00200020) == 0x00200000) {
8597 /* [us]sat */
8598 tmp = load_reg(s, rm);
8599 shift = (insn >> 7) & 0x1f;
8600 if (insn & (1 << 6)) {
8601 if (shift == 0)
8602 shift = 31;
8603 tcg_gen_sari_i32(tmp, tmp, shift);
8604 } else {
8605 tcg_gen_shli_i32(tmp, tmp, shift);
8607 sh = (insn >> 16) & 0x1f;
8608 tmp2 = tcg_const_i32(sh);
8609 if (insn & (1 << 22))
8610 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8611 else
8612 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8613 tcg_temp_free_i32(tmp2);
8614 store_reg(s, rd, tmp);
8615 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8616 /* [us]sat16 */
8617 tmp = load_reg(s, rm);
8618 sh = (insn >> 16) & 0x1f;
8619 tmp2 = tcg_const_i32(sh);
8620 if (insn & (1 << 22))
8621 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8622 else
8623 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8624 tcg_temp_free_i32(tmp2);
8625 store_reg(s, rd, tmp);
8626 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8627 /* Select bytes. */
8628 tmp = load_reg(s, rn);
8629 tmp2 = load_reg(s, rm);
8630 tmp3 = tcg_temp_new_i32();
8631 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8632 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8633 tcg_temp_free_i32(tmp3);
8634 tcg_temp_free_i32(tmp2);
8635 store_reg(s, rd, tmp);
8636 } else if ((insn & 0x000003e0) == 0x00000060) {
8637 tmp = load_reg(s, rm);
8638 shift = (insn >> 10) & 3;
8639 /* ??? In many cases it's not necessary to do a
8640 rotate, a shift is sufficient. */
8641 if (shift != 0)
8642 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8643 op1 = (insn >> 20) & 7;
8644 switch (op1) {
8645 case 0: gen_sxtb16(tmp); break;
8646 case 2: gen_sxtb(tmp); break;
8647 case 3: gen_sxth(tmp); break;
8648 case 4: gen_uxtb16(tmp); break;
8649 case 6: gen_uxtb(tmp); break;
8650 case 7: gen_uxth(tmp); break;
8651 default: goto illegal_op;
8653 if (rn != 15) {
8654 tmp2 = load_reg(s, rn);
8655 if ((op1 & 3) == 0) {
8656 gen_add16(tmp, tmp2);
8657 } else {
8658 tcg_gen_add_i32(tmp, tmp, tmp2);
8659 tcg_temp_free_i32(tmp2);
8662 store_reg(s, rd, tmp);
8663 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8664 /* rev */
8665 tmp = load_reg(s, rm);
8666 if (insn & (1 << 22)) {
8667 if (insn & (1 << 7)) {
8668 gen_revsh(tmp);
8669 } else {
8670 ARCH(6T2);
8671 gen_helper_rbit(tmp, tmp);
8673 } else {
8674 if (insn & (1 << 7))
8675 gen_rev16(tmp);
8676 else
8677 tcg_gen_bswap32_i32(tmp, tmp);
8679 store_reg(s, rd, tmp);
8680 } else {
8681 goto illegal_op;
8683 break;
8684 case 2: /* Multiplies (Type 3). */
8685 switch ((insn >> 20) & 0x7) {
8686 case 5:
8687 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8688 /* op2 not 00x or 11x : UNDEF */
8689 goto illegal_op;
8691 /* Signed multiply most significant [accumulate].
8692 (SMMUL, SMMLA, SMMLS) */
8693 tmp = load_reg(s, rm);
8694 tmp2 = load_reg(s, rs);
8695 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8697 if (rd != 15) {
8698 tmp = load_reg(s, rd);
8699 if (insn & (1 << 6)) {
8700 tmp64 = gen_subq_msw(tmp64, tmp);
8701 } else {
8702 tmp64 = gen_addq_msw(tmp64, tmp);
8705 if (insn & (1 << 5)) {
8706 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8708 tcg_gen_shri_i64(tmp64, tmp64, 32);
8709 tmp = tcg_temp_new_i32();
8710 tcg_gen_extrl_i64_i32(tmp, tmp64);
8711 tcg_temp_free_i64(tmp64);
8712 store_reg(s, rn, tmp);
8713 break;
8714 case 0:
8715 case 4:
8716 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8717 if (insn & (1 << 7)) {
8718 goto illegal_op;
8720 tmp = load_reg(s, rm);
8721 tmp2 = load_reg(s, rs);
8722 if (insn & (1 << 5))
8723 gen_swap_half(tmp2);
8724 gen_smul_dual(tmp, tmp2);
8725 if (insn & (1 << 22)) {
8726 /* smlald, smlsld */
8727 TCGv_i64 tmp64_2;
8729 tmp64 = tcg_temp_new_i64();
8730 tmp64_2 = tcg_temp_new_i64();
8731 tcg_gen_ext_i32_i64(tmp64, tmp);
8732 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8733 tcg_temp_free_i32(tmp);
8734 tcg_temp_free_i32(tmp2);
8735 if (insn & (1 << 6)) {
8736 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8737 } else {
8738 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8740 tcg_temp_free_i64(tmp64_2);
8741 gen_addq(s, tmp64, rd, rn);
8742 gen_storeq_reg(s, rd, rn, tmp64);
8743 tcg_temp_free_i64(tmp64);
8744 } else {
8745 /* smuad, smusd, smlad, smlsd */
8746 if (insn & (1 << 6)) {
8747 /* This subtraction cannot overflow. */
8748 tcg_gen_sub_i32(tmp, tmp, tmp2);
8749 } else {
8750 /* This addition cannot overflow 32 bits;
8751 * however it may overflow considered as a
8752 * signed operation, in which case we must set
8753 * the Q flag.
8755 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8757 tcg_temp_free_i32(tmp2);
8758 if (rd != 15)
8760 tmp2 = load_reg(s, rd);
8761 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8762 tcg_temp_free_i32(tmp2);
8764 store_reg(s, rn, tmp);
8766 break;
8767 case 1:
8768 case 3:
8769 /* SDIV, UDIV */
8770 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
8771 goto illegal_op;
8773 if (((insn >> 5) & 7) || (rd != 15)) {
8774 goto illegal_op;
8776 tmp = load_reg(s, rm);
8777 tmp2 = load_reg(s, rs);
8778 if (insn & (1 << 21)) {
8779 gen_helper_udiv(tmp, tmp, tmp2);
8780 } else {
8781 gen_helper_sdiv(tmp, tmp, tmp2);
8783 tcg_temp_free_i32(tmp2);
8784 store_reg(s, rn, tmp);
8785 break;
8786 default:
8787 goto illegal_op;
8789 break;
8790 case 3:
8791 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8792 switch (op1) {
8793 case 0: /* Unsigned sum of absolute differences. */
8794 ARCH(6);
8795 tmp = load_reg(s, rm);
8796 tmp2 = load_reg(s, rs);
8797 gen_helper_usad8(tmp, tmp, tmp2);
8798 tcg_temp_free_i32(tmp2);
8799 if (rd != 15) {
8800 tmp2 = load_reg(s, rd);
8801 tcg_gen_add_i32(tmp, tmp, tmp2);
8802 tcg_temp_free_i32(tmp2);
8804 store_reg(s, rn, tmp);
8805 break;
8806 case 0x20: case 0x24: case 0x28: case 0x2c:
8807 /* Bitfield insert/clear. */
8808 ARCH(6T2);
8809 shift = (insn >> 7) & 0x1f;
8810 i = (insn >> 16) & 0x1f;
8811 if (i < shift) {
8812 /* UNPREDICTABLE; we choose to UNDEF */
8813 goto illegal_op;
8815 i = i + 1 - shift;
8816 if (rm == 15) {
8817 tmp = tcg_temp_new_i32();
8818 tcg_gen_movi_i32(tmp, 0);
8819 } else {
8820 tmp = load_reg(s, rm);
8822 if (i != 32) {
8823 tmp2 = load_reg(s, rd);
8824 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8825 tcg_temp_free_i32(tmp2);
8827 store_reg(s, rd, tmp);
8828 break;
8829 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8830 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8831 ARCH(6T2);
8832 tmp = load_reg(s, rm);
8833 shift = (insn >> 7) & 0x1f;
8834 i = ((insn >> 16) & 0x1f) + 1;
8835 if (shift + i > 32)
8836 goto illegal_op;
8837 if (i < 32) {
8838 if (op1 & 0x20) {
8839 gen_ubfx(tmp, shift, (1u << i) - 1);
8840 } else {
8841 gen_sbfx(tmp, shift, i);
8844 store_reg(s, rd, tmp);
8845 break;
8846 default:
8847 goto illegal_op;
8849 break;
8851 break;
8853 do_ldst:
8854 /* Check for undefined extension instructions
8855 * per the ARM Bible IE:
8856 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8858 sh = (0xf << 20) | (0xf << 4);
8859 if (op1 == 0x7 && ((insn & sh) == sh))
8861 goto illegal_op;
8863 /* load/store byte/word */
8864 rn = (insn >> 16) & 0xf;
8865 rd = (insn >> 12) & 0xf;
8866 tmp2 = load_reg(s, rn);
8867 if ((insn & 0x01200000) == 0x00200000) {
8868 /* ldrt/strt */
8869 i = get_a32_user_mem_index(s);
8870 } else {
8871 i = get_mem_index(s);
8873 if (insn & (1 << 24))
8874 gen_add_data_offset(s, insn, tmp2);
8875 if (insn & (1 << 20)) {
8876 /* load */
8877 tmp = tcg_temp_new_i32();
8878 if (insn & (1 << 22)) {
8879 gen_aa32_ld8u(tmp, tmp2, i);
8880 } else {
8881 gen_aa32_ld32u(tmp, tmp2, i);
8883 } else {
8884 /* store */
8885 tmp = load_reg(s, rd);
8886 if (insn & (1 << 22)) {
8887 gen_aa32_st8(tmp, tmp2, i);
8888 } else {
8889 gen_aa32_st32(tmp, tmp2, i);
8891 tcg_temp_free_i32(tmp);
8893 if (!(insn & (1 << 24))) {
8894 gen_add_data_offset(s, insn, tmp2);
8895 store_reg(s, rn, tmp2);
8896 } else if (insn & (1 << 21)) {
8897 store_reg(s, rn, tmp2);
8898 } else {
8899 tcg_temp_free_i32(tmp2);
8901 if (insn & (1 << 20)) {
8902 /* Complete the load. */
8903 store_reg_from_load(s, rd, tmp);
8905 break;
8906 case 0x08:
8907 case 0x09:
8909 int j, n, loaded_base;
8910 bool exc_return = false;
8911 bool is_load = extract32(insn, 20, 1);
8912 bool user = false;
8913 TCGv_i32 loaded_var;
8914 /* load/store multiple words */
8915 /* XXX: store correct base if write back */
8916 if (insn & (1 << 22)) {
8917 /* LDM (user), LDM (exception return) and STM (user) */
8918 if (IS_USER(s))
8919 goto illegal_op; /* only usable in supervisor mode */
8921 if (is_load && extract32(insn, 15, 1)) {
8922 exc_return = true;
8923 } else {
8924 user = true;
8927 rn = (insn >> 16) & 0xf;
8928 addr = load_reg(s, rn);
8930 /* compute total size */
8931 loaded_base = 0;
8932 TCGV_UNUSED_I32(loaded_var);
8933 n = 0;
8934 for(i=0;i<16;i++) {
8935 if (insn & (1 << i))
8936 n++;
8938 /* XXX: test invalid n == 0 case ? */
8939 if (insn & (1 << 23)) {
8940 if (insn & (1 << 24)) {
8941 /* pre increment */
8942 tcg_gen_addi_i32(addr, addr, 4);
8943 } else {
8944 /* post increment */
8946 } else {
8947 if (insn & (1 << 24)) {
8948 /* pre decrement */
8949 tcg_gen_addi_i32(addr, addr, -(n * 4));
8950 } else {
8951 /* post decrement */
8952 if (n != 1)
8953 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8956 j = 0;
8957 for(i=0;i<16;i++) {
8958 if (insn & (1 << i)) {
8959 if (is_load) {
8960 /* load */
8961 tmp = tcg_temp_new_i32();
8962 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8963 if (user) {
8964 tmp2 = tcg_const_i32(i);
8965 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8966 tcg_temp_free_i32(tmp2);
8967 tcg_temp_free_i32(tmp);
8968 } else if (i == rn) {
8969 loaded_var = tmp;
8970 loaded_base = 1;
8971 } else {
8972 store_reg_from_load(s, i, tmp);
8974 } else {
8975 /* store */
8976 if (i == 15) {
8977 /* special case: r15 = PC + 8 */
8978 val = (long)s->pc + 4;
8979 tmp = tcg_temp_new_i32();
8980 tcg_gen_movi_i32(tmp, val);
8981 } else if (user) {
8982 tmp = tcg_temp_new_i32();
8983 tmp2 = tcg_const_i32(i);
8984 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8985 tcg_temp_free_i32(tmp2);
8986 } else {
8987 tmp = load_reg(s, i);
8989 gen_aa32_st32(tmp, addr, get_mem_index(s));
8990 tcg_temp_free_i32(tmp);
8992 j++;
8993 /* no need to add after the last transfer */
8994 if (j != n)
8995 tcg_gen_addi_i32(addr, addr, 4);
8998 if (insn & (1 << 21)) {
8999 /* write back */
9000 if (insn & (1 << 23)) {
9001 if (insn & (1 << 24)) {
9002 /* pre increment */
9003 } else {
9004 /* post increment */
9005 tcg_gen_addi_i32(addr, addr, 4);
9007 } else {
9008 if (insn & (1 << 24)) {
9009 /* pre decrement */
9010 if (n != 1)
9011 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9012 } else {
9013 /* post decrement */
9014 tcg_gen_addi_i32(addr, addr, -(n * 4));
9017 store_reg(s, rn, addr);
9018 } else {
9019 tcg_temp_free_i32(addr);
9021 if (loaded_base) {
9022 store_reg(s, rn, loaded_var);
9024 if (exc_return) {
9025 /* Restore CPSR from SPSR. */
9026 tmp = load_cpu_field(spsr);
9027 gen_set_cpsr(tmp, CPSR_ERET_MASK);
9028 tcg_temp_free_i32(tmp);
9029 s->is_jmp = DISAS_UPDATE;
9032 break;
9033 case 0xa:
9034 case 0xb:
9036 int32_t offset;
9038 /* branch (and link) */
9039 val = (int32_t)s->pc;
9040 if (insn & (1 << 24)) {
9041 tmp = tcg_temp_new_i32();
9042 tcg_gen_movi_i32(tmp, val);
9043 store_reg(s, 14, tmp);
9045 offset = sextract32(insn << 2, 0, 26);
9046 val += offset + 4;
9047 gen_jmp(s, val);
9049 break;
9050 case 0xc:
9051 case 0xd:
9052 case 0xe:
9053 if (((insn >> 8) & 0xe) == 10) {
9054 /* VFP. */
9055 if (disas_vfp_insn(s, insn)) {
9056 goto illegal_op;
9058 } else if (disas_coproc_insn(s, insn)) {
9059 /* Coprocessor. */
9060 goto illegal_op;
9062 break;
9063 case 0xf:
9064 /* swi */
9065 gen_set_pc_im(s, s->pc);
9066 s->svc_imm = extract32(insn, 0, 24);
9067 s->is_jmp = DISAS_SWI;
9068 break;
9069 default:
9070 illegal_op:
9071 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9072 default_exception_el(s));
9073 break;
9078 /* Return true if this is a Thumb-2 logical op. */
9079 static int
9080 thumb2_logic_op(int op)
9082 return (op < 8);
9085 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9086 then set condition code flags based on the result of the operation.
9087 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9088 to the high bit of T1.
9089 Returns zero if the opcode is valid. */
9091 static int
9092 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9093 TCGv_i32 t0, TCGv_i32 t1)
9095 int logic_cc;
9097 logic_cc = 0;
9098 switch (op) {
9099 case 0: /* and */
9100 tcg_gen_and_i32(t0, t0, t1);
9101 logic_cc = conds;
9102 break;
9103 case 1: /* bic */
9104 tcg_gen_andc_i32(t0, t0, t1);
9105 logic_cc = conds;
9106 break;
9107 case 2: /* orr */
9108 tcg_gen_or_i32(t0, t0, t1);
9109 logic_cc = conds;
9110 break;
9111 case 3: /* orn */
9112 tcg_gen_orc_i32(t0, t0, t1);
9113 logic_cc = conds;
9114 break;
9115 case 4: /* eor */
9116 tcg_gen_xor_i32(t0, t0, t1);
9117 logic_cc = conds;
9118 break;
9119 case 8: /* add */
9120 if (conds)
9121 gen_add_CC(t0, t0, t1);
9122 else
9123 tcg_gen_add_i32(t0, t0, t1);
9124 break;
9125 case 10: /* adc */
9126 if (conds)
9127 gen_adc_CC(t0, t0, t1);
9128 else
9129 gen_adc(t0, t1);
9130 break;
9131 case 11: /* sbc */
9132 if (conds) {
9133 gen_sbc_CC(t0, t0, t1);
9134 } else {
9135 gen_sub_carry(t0, t0, t1);
9137 break;
9138 case 13: /* sub */
9139 if (conds)
9140 gen_sub_CC(t0, t0, t1);
9141 else
9142 tcg_gen_sub_i32(t0, t0, t1);
9143 break;
9144 case 14: /* rsb */
9145 if (conds)
9146 gen_sub_CC(t0, t1, t0);
9147 else
9148 tcg_gen_sub_i32(t0, t1, t0);
9149 break;
9150 default: /* 5, 6, 7, 9, 12, 15. */
9151 return 1;
9153 if (logic_cc) {
9154 gen_logic_CC(t0);
9155 if (shifter_out)
9156 gen_set_CF_bit31(t1);
9158 return 0;
9161 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9162 is not legal. */
9163 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9165 uint32_t insn, imm, shift, offset;
9166 uint32_t rd, rn, rm, rs;
9167 TCGv_i32 tmp;
9168 TCGv_i32 tmp2;
9169 TCGv_i32 tmp3;
9170 TCGv_i32 addr;
9171 TCGv_i64 tmp64;
9172 int op;
9173 int shiftop;
9174 int conds;
9175 int logic_cc;
9177 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9178 || arm_dc_feature(s, ARM_FEATURE_M))) {
9179 /* Thumb-1 cores may need to treat bl and blx as a pair of
9180 16-bit instructions to get correct prefetch abort behavior. */
9181 insn = insn_hw1;
9182 if ((insn & (1 << 12)) == 0) {
9183 ARCH(5);
9184 /* Second half of blx. */
9185 offset = ((insn & 0x7ff) << 1);
9186 tmp = load_reg(s, 14);
9187 tcg_gen_addi_i32(tmp, tmp, offset);
9188 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9190 tmp2 = tcg_temp_new_i32();
9191 tcg_gen_movi_i32(tmp2, s->pc | 1);
9192 store_reg(s, 14, tmp2);
9193 gen_bx(s, tmp);
9194 return 0;
9196 if (insn & (1 << 11)) {
9197 /* Second half of bl. */
9198 offset = ((insn & 0x7ff) << 1) | 1;
9199 tmp = load_reg(s, 14);
9200 tcg_gen_addi_i32(tmp, tmp, offset);
9202 tmp2 = tcg_temp_new_i32();
9203 tcg_gen_movi_i32(tmp2, s->pc | 1);
9204 store_reg(s, 14, tmp2);
9205 gen_bx(s, tmp);
9206 return 0;
9208 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9209 /* Instruction spans a page boundary. Implement it as two
9210 16-bit instructions in case the second half causes an
9211 prefetch abort. */
9212 offset = ((int32_t)insn << 21) >> 9;
9213 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9214 return 0;
9216 /* Fall through to 32-bit decode. */
9219 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9220 s->pc += 2;
9221 insn |= (uint32_t)insn_hw1 << 16;
9223 if ((insn & 0xf800e800) != 0xf000e800) {
9224 ARCH(6T2);
9227 rn = (insn >> 16) & 0xf;
9228 rs = (insn >> 12) & 0xf;
9229 rd = (insn >> 8) & 0xf;
9230 rm = insn & 0xf;
9231 switch ((insn >> 25) & 0xf) {
9232 case 0: case 1: case 2: case 3:
9233 /* 16-bit instructions. Should never happen. */
9234 abort();
9235 case 4:
9236 if (insn & (1 << 22)) {
9237 /* Other load/store, table branch. */
9238 if (insn & 0x01200000) {
9239 ARCH(5); /* Load/store doubleword. */
9240 if (rn == 15) {
9241 addr = tcg_temp_new_i32();
9242 tcg_gen_movi_i32(addr, s->pc & ~3);
9243 } else {
9244 addr = load_reg(s, rn);
9246 offset = (insn & 0xff) * 4;
9247 if ((insn & (1 << 23)) == 0)
9248 offset = -offset;
9249 if (insn & (1 << 24)) {
9250 tcg_gen_addi_i32(addr, addr, offset);
9251 offset = 0;
9253 if (insn & (1 << 20)) {
9254 /* ldrd */
9255 tmp = tcg_temp_new_i32();
9256 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9257 store_reg(s, rs, tmp);
9258 tcg_gen_addi_i32(addr, addr, 4);
9259 tmp = tcg_temp_new_i32();
9260 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9261 store_reg(s, rd, tmp);
9262 } else {
9263 /* strd */
9264 tmp = load_reg(s, rs);
9265 gen_aa32_st32(tmp, addr, get_mem_index(s));
9266 tcg_temp_free_i32(tmp);
9267 tcg_gen_addi_i32(addr, addr, 4);
9268 tmp = load_reg(s, rd);
9269 gen_aa32_st32(tmp, addr, get_mem_index(s));
9270 tcg_temp_free_i32(tmp);
9272 if (insn & (1 << 21)) {
9273 /* Base writeback. */
9274 if (rn == 15)
9275 goto illegal_op;
9276 tcg_gen_addi_i32(addr, addr, offset - 4);
9277 store_reg(s, rn, addr);
9278 } else {
9279 tcg_temp_free_i32(addr);
9281 } else if ((insn & (1 << 23)) == 0) {
9282 /* Load/store exclusive word. */
9283 addr = tcg_temp_local_new_i32();
9284 load_reg_var(s, addr, rn);
9285 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9286 if (insn & (1 << 20)) {
9287 gen_load_exclusive(s, rs, 15, addr, 2);
9288 } else {
9289 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9291 tcg_temp_free_i32(addr);
9292 } else if ((insn & (7 << 5)) == 0) {
9293 /* Table Branch. */
9294 if (rn == 15) {
9295 addr = tcg_temp_new_i32();
9296 tcg_gen_movi_i32(addr, s->pc);
9297 } else {
9298 addr = load_reg(s, rn);
9300 tmp = load_reg(s, rm);
9301 tcg_gen_add_i32(addr, addr, tmp);
9302 if (insn & (1 << 4)) {
9303 /* tbh */
9304 tcg_gen_add_i32(addr, addr, tmp);
9305 tcg_temp_free_i32(tmp);
9306 tmp = tcg_temp_new_i32();
9307 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9308 } else { /* tbb */
9309 tcg_temp_free_i32(tmp);
9310 tmp = tcg_temp_new_i32();
9311 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9313 tcg_temp_free_i32(addr);
9314 tcg_gen_shli_i32(tmp, tmp, 1);
9315 tcg_gen_addi_i32(tmp, tmp, s->pc);
9316 store_reg(s, 15, tmp);
9317 } else {
9318 int op2 = (insn >> 6) & 0x3;
9319 op = (insn >> 4) & 0x3;
9320 switch (op2) {
9321 case 0:
9322 goto illegal_op;
9323 case 1:
9324 /* Load/store exclusive byte/halfword/doubleword */
9325 if (op == 2) {
9326 goto illegal_op;
9328 ARCH(7);
9329 break;
9330 case 2:
9331 /* Load-acquire/store-release */
9332 if (op == 3) {
9333 goto illegal_op;
9335 /* Fall through */
9336 case 3:
9337 /* Load-acquire/store-release exclusive */
9338 ARCH(8);
9339 break;
9341 addr = tcg_temp_local_new_i32();
9342 load_reg_var(s, addr, rn);
9343 if (!(op2 & 1)) {
9344 if (insn & (1 << 20)) {
9345 tmp = tcg_temp_new_i32();
9346 switch (op) {
9347 case 0: /* ldab */
9348 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9349 break;
9350 case 1: /* ldah */
9351 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9352 break;
9353 case 2: /* lda */
9354 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9355 break;
9356 default:
9357 abort();
9359 store_reg(s, rs, tmp);
9360 } else {
9361 tmp = load_reg(s, rs);
9362 switch (op) {
9363 case 0: /* stlb */
9364 gen_aa32_st8(tmp, addr, get_mem_index(s));
9365 break;
9366 case 1: /* stlh */
9367 gen_aa32_st16(tmp, addr, get_mem_index(s));
9368 break;
9369 case 2: /* stl */
9370 gen_aa32_st32(tmp, addr, get_mem_index(s));
9371 break;
9372 default:
9373 abort();
9375 tcg_temp_free_i32(tmp);
9377 } else if (insn & (1 << 20)) {
9378 gen_load_exclusive(s, rs, rd, addr, op);
9379 } else {
9380 gen_store_exclusive(s, rm, rs, rd, addr, op);
9382 tcg_temp_free_i32(addr);
9384 } else {
9385 /* Load/store multiple, RFE, SRS. */
9386 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9387 /* RFE, SRS: not available in user mode or on M profile */
9388 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9389 goto illegal_op;
9391 if (insn & (1 << 20)) {
9392 /* rfe */
9393 addr = load_reg(s, rn);
9394 if ((insn & (1 << 24)) == 0)
9395 tcg_gen_addi_i32(addr, addr, -8);
9396 /* Load PC into tmp and CPSR into tmp2. */
9397 tmp = tcg_temp_new_i32();
9398 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9399 tcg_gen_addi_i32(addr, addr, 4);
9400 tmp2 = tcg_temp_new_i32();
9401 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
9402 if (insn & (1 << 21)) {
9403 /* Base writeback. */
9404 if (insn & (1 << 24)) {
9405 tcg_gen_addi_i32(addr, addr, 4);
9406 } else {
9407 tcg_gen_addi_i32(addr, addr, -4);
9409 store_reg(s, rn, addr);
9410 } else {
9411 tcg_temp_free_i32(addr);
9413 gen_rfe(s, tmp, tmp2);
9414 } else {
9415 /* srs */
9416 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9417 insn & (1 << 21));
9419 } else {
9420 int i, loaded_base = 0;
9421 TCGv_i32 loaded_var;
9422 /* Load/store multiple. */
9423 addr = load_reg(s, rn);
9424 offset = 0;
9425 for (i = 0; i < 16; i++) {
9426 if (insn & (1 << i))
9427 offset += 4;
9429 if (insn & (1 << 24)) {
9430 tcg_gen_addi_i32(addr, addr, -offset);
9433 TCGV_UNUSED_I32(loaded_var);
9434 for (i = 0; i < 16; i++) {
9435 if ((insn & (1 << i)) == 0)
9436 continue;
9437 if (insn & (1 << 20)) {
9438 /* Load. */
9439 tmp = tcg_temp_new_i32();
9440 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9441 if (i == 15) {
9442 gen_bx(s, tmp);
9443 } else if (i == rn) {
9444 loaded_var = tmp;
9445 loaded_base = 1;
9446 } else {
9447 store_reg(s, i, tmp);
9449 } else {
9450 /* Store. */
9451 tmp = load_reg(s, i);
9452 gen_aa32_st32(tmp, addr, get_mem_index(s));
9453 tcg_temp_free_i32(tmp);
9455 tcg_gen_addi_i32(addr, addr, 4);
9457 if (loaded_base) {
9458 store_reg(s, rn, loaded_var);
9460 if (insn & (1 << 21)) {
9461 /* Base register writeback. */
9462 if (insn & (1 << 24)) {
9463 tcg_gen_addi_i32(addr, addr, -offset);
9465 /* Fault if writeback register is in register list. */
9466 if (insn & (1 << rn))
9467 goto illegal_op;
9468 store_reg(s, rn, addr);
9469 } else {
9470 tcg_temp_free_i32(addr);
9474 break;
9475 case 5:
9477 op = (insn >> 21) & 0xf;
9478 if (op == 6) {
9479 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9480 goto illegal_op;
9482 /* Halfword pack. */
9483 tmp = load_reg(s, rn);
9484 tmp2 = load_reg(s, rm);
9485 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9486 if (insn & (1 << 5)) {
9487 /* pkhtb */
9488 if (shift == 0)
9489 shift = 31;
9490 tcg_gen_sari_i32(tmp2, tmp2, shift);
9491 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9492 tcg_gen_ext16u_i32(tmp2, tmp2);
9493 } else {
9494 /* pkhbt */
9495 if (shift)
9496 tcg_gen_shli_i32(tmp2, tmp2, shift);
9497 tcg_gen_ext16u_i32(tmp, tmp);
9498 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9500 tcg_gen_or_i32(tmp, tmp, tmp2);
9501 tcg_temp_free_i32(tmp2);
9502 store_reg(s, rd, tmp);
9503 } else {
9504 /* Data processing register constant shift. */
9505 if (rn == 15) {
9506 tmp = tcg_temp_new_i32();
9507 tcg_gen_movi_i32(tmp, 0);
9508 } else {
9509 tmp = load_reg(s, rn);
9511 tmp2 = load_reg(s, rm);
9513 shiftop = (insn >> 4) & 3;
9514 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9515 conds = (insn & (1 << 20)) != 0;
9516 logic_cc = (conds && thumb2_logic_op(op));
9517 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9518 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9519 goto illegal_op;
9520 tcg_temp_free_i32(tmp2);
9521 if (rd != 15) {
9522 store_reg(s, rd, tmp);
9523 } else {
9524 tcg_temp_free_i32(tmp);
9527 break;
9528 case 13: /* Misc data processing. */
9529 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9530 if (op < 4 && (insn & 0xf000) != 0xf000)
9531 goto illegal_op;
9532 switch (op) {
9533 case 0: /* Register controlled shift. */
9534 tmp = load_reg(s, rn);
9535 tmp2 = load_reg(s, rm);
9536 if ((insn & 0x70) != 0)
9537 goto illegal_op;
9538 op = (insn >> 21) & 3;
9539 logic_cc = (insn & (1 << 20)) != 0;
9540 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9541 if (logic_cc)
9542 gen_logic_CC(tmp);
9543 store_reg_bx(s, rd, tmp);
9544 break;
9545 case 1: /* Sign/zero extend. */
9546 op = (insn >> 20) & 7;
9547 switch (op) {
9548 case 0: /* SXTAH, SXTH */
9549 case 1: /* UXTAH, UXTH */
9550 case 4: /* SXTAB, SXTB */
9551 case 5: /* UXTAB, UXTB */
9552 break;
9553 case 2: /* SXTAB16, SXTB16 */
9554 case 3: /* UXTAB16, UXTB16 */
9555 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9556 goto illegal_op;
9558 break;
9559 default:
9560 goto illegal_op;
9562 if (rn != 15) {
9563 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9564 goto illegal_op;
9567 tmp = load_reg(s, rm);
9568 shift = (insn >> 4) & 3;
9569 /* ??? In many cases it's not necessary to do a
9570 rotate, a shift is sufficient. */
9571 if (shift != 0)
9572 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9573 op = (insn >> 20) & 7;
9574 switch (op) {
9575 case 0: gen_sxth(tmp); break;
9576 case 1: gen_uxth(tmp); break;
9577 case 2: gen_sxtb16(tmp); break;
9578 case 3: gen_uxtb16(tmp); break;
9579 case 4: gen_sxtb(tmp); break;
9580 case 5: gen_uxtb(tmp); break;
9581 default:
9582 g_assert_not_reached();
9584 if (rn != 15) {
9585 tmp2 = load_reg(s, rn);
9586 if ((op >> 1) == 1) {
9587 gen_add16(tmp, tmp2);
9588 } else {
9589 tcg_gen_add_i32(tmp, tmp, tmp2);
9590 tcg_temp_free_i32(tmp2);
9593 store_reg(s, rd, tmp);
9594 break;
9595 case 2: /* SIMD add/subtract. */
9596 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9597 goto illegal_op;
9599 op = (insn >> 20) & 7;
9600 shift = (insn >> 4) & 7;
9601 if ((op & 3) == 3 || (shift & 3) == 3)
9602 goto illegal_op;
9603 tmp = load_reg(s, rn);
9604 tmp2 = load_reg(s, rm);
9605 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9606 tcg_temp_free_i32(tmp2);
9607 store_reg(s, rd, tmp);
9608 break;
9609 case 3: /* Other data processing. */
9610 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9611 if (op < 4) {
9612 /* Saturating add/subtract. */
9613 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9614 goto illegal_op;
9616 tmp = load_reg(s, rn);
9617 tmp2 = load_reg(s, rm);
9618 if (op & 1)
9619 gen_helper_double_saturate(tmp, cpu_env, tmp);
9620 if (op & 2)
9621 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9622 else
9623 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9624 tcg_temp_free_i32(tmp2);
9625 } else {
9626 switch (op) {
9627 case 0x0a: /* rbit */
9628 case 0x08: /* rev */
9629 case 0x09: /* rev16 */
9630 case 0x0b: /* revsh */
9631 case 0x18: /* clz */
9632 break;
9633 case 0x10: /* sel */
9634 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9635 goto illegal_op;
9637 break;
9638 case 0x20: /* crc32/crc32c */
9639 case 0x21:
9640 case 0x22:
9641 case 0x28:
9642 case 0x29:
9643 case 0x2a:
9644 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
9645 goto illegal_op;
9647 break;
9648 default:
9649 goto illegal_op;
9651 tmp = load_reg(s, rn);
9652 switch (op) {
9653 case 0x0a: /* rbit */
9654 gen_helper_rbit(tmp, tmp);
9655 break;
9656 case 0x08: /* rev */
9657 tcg_gen_bswap32_i32(tmp, tmp);
9658 break;
9659 case 0x09: /* rev16 */
9660 gen_rev16(tmp);
9661 break;
9662 case 0x0b: /* revsh */
9663 gen_revsh(tmp);
9664 break;
9665 case 0x10: /* sel */
9666 tmp2 = load_reg(s, rm);
9667 tmp3 = tcg_temp_new_i32();
9668 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9669 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9670 tcg_temp_free_i32(tmp3);
9671 tcg_temp_free_i32(tmp2);
9672 break;
9673 case 0x18: /* clz */
9674 gen_helper_clz(tmp, tmp);
9675 break;
9676 case 0x20:
9677 case 0x21:
9678 case 0x22:
9679 case 0x28:
9680 case 0x29:
9681 case 0x2a:
9683 /* crc32/crc32c */
9684 uint32_t sz = op & 0x3;
9685 uint32_t c = op & 0x8;
9687 tmp2 = load_reg(s, rm);
9688 if (sz == 0) {
9689 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9690 } else if (sz == 1) {
9691 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9693 tmp3 = tcg_const_i32(1 << sz);
9694 if (c) {
9695 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9696 } else {
9697 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9699 tcg_temp_free_i32(tmp2);
9700 tcg_temp_free_i32(tmp3);
9701 break;
9703 default:
9704 g_assert_not_reached();
9707 store_reg(s, rd, tmp);
9708 break;
9709 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9710 switch ((insn >> 20) & 7) {
9711 case 0: /* 32 x 32 -> 32 */
9712 case 7: /* Unsigned sum of absolute differences. */
9713 break;
9714 case 1: /* 16 x 16 -> 32 */
9715 case 2: /* Dual multiply add. */
9716 case 3: /* 32 * 16 -> 32msb */
9717 case 4: /* Dual multiply subtract. */
9718 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9719 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9720 goto illegal_op;
9722 break;
9724 op = (insn >> 4) & 0xf;
9725 tmp = load_reg(s, rn);
9726 tmp2 = load_reg(s, rm);
9727 switch ((insn >> 20) & 7) {
9728 case 0: /* 32 x 32 -> 32 */
9729 tcg_gen_mul_i32(tmp, tmp, tmp2);
9730 tcg_temp_free_i32(tmp2);
9731 if (rs != 15) {
9732 tmp2 = load_reg(s, rs);
9733 if (op)
9734 tcg_gen_sub_i32(tmp, tmp2, tmp);
9735 else
9736 tcg_gen_add_i32(tmp, tmp, tmp2);
9737 tcg_temp_free_i32(tmp2);
9739 break;
9740 case 1: /* 16 x 16 -> 32 */
9741 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9742 tcg_temp_free_i32(tmp2);
9743 if (rs != 15) {
9744 tmp2 = load_reg(s, rs);
9745 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9746 tcg_temp_free_i32(tmp2);
9748 break;
9749 case 2: /* Dual multiply add. */
9750 case 4: /* Dual multiply subtract. */
9751 if (op)
9752 gen_swap_half(tmp2);
9753 gen_smul_dual(tmp, tmp2);
9754 if (insn & (1 << 22)) {
9755 /* This subtraction cannot overflow. */
9756 tcg_gen_sub_i32(tmp, tmp, tmp2);
9757 } else {
9758 /* This addition cannot overflow 32 bits;
9759 * however it may overflow considered as a signed
9760 * operation, in which case we must set the Q flag.
9762 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9764 tcg_temp_free_i32(tmp2);
9765 if (rs != 15)
9767 tmp2 = load_reg(s, rs);
9768 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9769 tcg_temp_free_i32(tmp2);
9771 break;
9772 case 3: /* 32 * 16 -> 32msb */
9773 if (op)
9774 tcg_gen_sari_i32(tmp2, tmp2, 16);
9775 else
9776 gen_sxth(tmp2);
9777 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9778 tcg_gen_shri_i64(tmp64, tmp64, 16);
9779 tmp = tcg_temp_new_i32();
9780 tcg_gen_extrl_i64_i32(tmp, tmp64);
9781 tcg_temp_free_i64(tmp64);
9782 if (rs != 15)
9784 tmp2 = load_reg(s, rs);
9785 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9786 tcg_temp_free_i32(tmp2);
9788 break;
9789 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9790 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9791 if (rs != 15) {
9792 tmp = load_reg(s, rs);
9793 if (insn & (1 << 20)) {
9794 tmp64 = gen_addq_msw(tmp64, tmp);
9795 } else {
9796 tmp64 = gen_subq_msw(tmp64, tmp);
9799 if (insn & (1 << 4)) {
9800 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9802 tcg_gen_shri_i64(tmp64, tmp64, 32);
9803 tmp = tcg_temp_new_i32();
9804 tcg_gen_extrl_i64_i32(tmp, tmp64);
9805 tcg_temp_free_i64(tmp64);
9806 break;
9807 case 7: /* Unsigned sum of absolute differences. */
9808 gen_helper_usad8(tmp, tmp, tmp2);
9809 tcg_temp_free_i32(tmp2);
9810 if (rs != 15) {
9811 tmp2 = load_reg(s, rs);
9812 tcg_gen_add_i32(tmp, tmp, tmp2);
9813 tcg_temp_free_i32(tmp2);
9815 break;
9817 store_reg(s, rd, tmp);
9818 break;
9819 case 6: case 7: /* 64-bit multiply, Divide. */
9820 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9821 tmp = load_reg(s, rn);
9822 tmp2 = load_reg(s, rm);
9823 if ((op & 0x50) == 0x10) {
9824 /* sdiv, udiv */
9825 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
9826 goto illegal_op;
9828 if (op & 0x20)
9829 gen_helper_udiv(tmp, tmp, tmp2);
9830 else
9831 gen_helper_sdiv(tmp, tmp, tmp2);
9832 tcg_temp_free_i32(tmp2);
9833 store_reg(s, rd, tmp);
9834 } else if ((op & 0xe) == 0xc) {
9835 /* Dual multiply accumulate long. */
9836 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9837 tcg_temp_free_i32(tmp);
9838 tcg_temp_free_i32(tmp2);
9839 goto illegal_op;
9841 if (op & 1)
9842 gen_swap_half(tmp2);
9843 gen_smul_dual(tmp, tmp2);
9844 if (op & 0x10) {
9845 tcg_gen_sub_i32(tmp, tmp, tmp2);
9846 } else {
9847 tcg_gen_add_i32(tmp, tmp, tmp2);
9849 tcg_temp_free_i32(tmp2);
9850 /* BUGFIX */
9851 tmp64 = tcg_temp_new_i64();
9852 tcg_gen_ext_i32_i64(tmp64, tmp);
9853 tcg_temp_free_i32(tmp);
9854 gen_addq(s, tmp64, rs, rd);
9855 gen_storeq_reg(s, rs, rd, tmp64);
9856 tcg_temp_free_i64(tmp64);
9857 } else {
9858 if (op & 0x20) {
9859 /* Unsigned 64-bit multiply */
9860 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9861 } else {
9862 if (op & 8) {
9863 /* smlalxy */
9864 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9865 tcg_temp_free_i32(tmp2);
9866 tcg_temp_free_i32(tmp);
9867 goto illegal_op;
9869 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9870 tcg_temp_free_i32(tmp2);
9871 tmp64 = tcg_temp_new_i64();
9872 tcg_gen_ext_i32_i64(tmp64, tmp);
9873 tcg_temp_free_i32(tmp);
9874 } else {
9875 /* Signed 64-bit multiply */
9876 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9879 if (op & 4) {
9880 /* umaal */
9881 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9882 tcg_temp_free_i64(tmp64);
9883 goto illegal_op;
9885 gen_addq_lo(s, tmp64, rs);
9886 gen_addq_lo(s, tmp64, rd);
9887 } else if (op & 0x40) {
9888 /* 64-bit accumulate. */
9889 gen_addq(s, tmp64, rs, rd);
9891 gen_storeq_reg(s, rs, rd, tmp64);
9892 tcg_temp_free_i64(tmp64);
9894 break;
9896 break;
9897 case 6: case 7: case 14: case 15:
9898 /* Coprocessor. */
9899 if (((insn >> 24) & 3) == 3) {
9900 /* Translate into the equivalent ARM encoding. */
9901 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9902 if (disas_neon_data_insn(s, insn)) {
9903 goto illegal_op;
9905 } else if (((insn >> 8) & 0xe) == 10) {
9906 if (disas_vfp_insn(s, insn)) {
9907 goto illegal_op;
9909 } else {
9910 if (insn & (1 << 28))
9911 goto illegal_op;
9912 if (disas_coproc_insn(s, insn)) {
9913 goto illegal_op;
9916 break;
9917 case 8: case 9: case 10: case 11:
9918 if (insn & (1 << 15)) {
9919 /* Branches, misc control. */
9920 if (insn & 0x5000) {
9921 /* Unconditional branch. */
9922 /* signextend(hw1[10:0]) -> offset[:12]. */
9923 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9924 /* hw1[10:0] -> offset[11:1]. */
9925 offset |= (insn & 0x7ff) << 1;
9926 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9927 offset[24:22] already have the same value because of the
9928 sign extension above. */
9929 offset ^= ((~insn) & (1 << 13)) << 10;
9930 offset ^= ((~insn) & (1 << 11)) << 11;
9932 if (insn & (1 << 14)) {
9933 /* Branch and link. */
9934 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9937 offset += s->pc;
9938 if (insn & (1 << 12)) {
9939 /* b/bl */
9940 gen_jmp(s, offset);
9941 } else {
9942 /* blx */
9943 offset &= ~(uint32_t)2;
9944 /* thumb2 bx, no need to check */
9945 gen_bx_im(s, offset);
9947 } else if (((insn >> 23) & 7) == 7) {
9948 /* Misc control */
9949 if (insn & (1 << 13))
9950 goto illegal_op;
9952 if (insn & (1 << 26)) {
9953 if (!(insn & (1 << 20))) {
9954 /* Hypervisor call (v7) */
9955 int imm16 = extract32(insn, 16, 4) << 12
9956 | extract32(insn, 0, 12);
9957 ARCH(7);
9958 if (IS_USER(s)) {
9959 goto illegal_op;
9961 gen_hvc(s, imm16);
9962 } else {
9963 /* Secure monitor call (v6+) */
9964 ARCH(6K);
9965 if (IS_USER(s)) {
9966 goto illegal_op;
9968 gen_smc(s);
9970 } else {
9971 op = (insn >> 20) & 7;
9972 switch (op) {
9973 case 0: /* msr cpsr. */
9974 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9975 tmp = load_reg(s, rn);
9976 addr = tcg_const_i32(insn & 0xff);
9977 gen_helper_v7m_msr(cpu_env, addr, tmp);
9978 tcg_temp_free_i32(addr);
9979 tcg_temp_free_i32(tmp);
9980 gen_lookup_tb(s);
9981 break;
9983 /* fall through */
9984 case 1: /* msr spsr. */
9985 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9986 goto illegal_op;
9988 tmp = load_reg(s, rn);
9989 if (gen_set_psr(s,
9990 msr_mask(s, (insn >> 8) & 0xf, op == 1),
9991 op == 1, tmp))
9992 goto illegal_op;
9993 break;
9994 case 2: /* cps, nop-hint. */
9995 if (((insn >> 8) & 7) == 0) {
9996 gen_nop_hint(s, insn & 0xff);
9998 /* Implemented as NOP in user mode. */
9999 if (IS_USER(s))
10000 break;
10001 offset = 0;
10002 imm = 0;
10003 if (insn & (1 << 10)) {
10004 if (insn & (1 << 7))
10005 offset |= CPSR_A;
10006 if (insn & (1 << 6))
10007 offset |= CPSR_I;
10008 if (insn & (1 << 5))
10009 offset |= CPSR_F;
10010 if (insn & (1 << 9))
10011 imm = CPSR_A | CPSR_I | CPSR_F;
10013 if (insn & (1 << 8)) {
10014 offset |= 0x1f;
10015 imm |= (insn & 0x1f);
10017 if (offset) {
10018 gen_set_psr_im(s, offset, 0, imm);
10020 break;
10021 case 3: /* Special control operations. */
10022 ARCH(7);
10023 op = (insn >> 4) & 0xf;
10024 switch (op) {
10025 case 2: /* clrex */
10026 gen_clrex(s);
10027 break;
10028 case 4: /* dsb */
10029 case 5: /* dmb */
10030 case 6: /* isb */
10031 /* These execute as NOPs. */
10032 break;
10033 default:
10034 goto illegal_op;
10036 break;
10037 case 4: /* bxj */
10038 /* Trivial implementation equivalent to bx. */
10039 tmp = load_reg(s, rn);
10040 gen_bx(s, tmp);
10041 break;
10042 case 5: /* Exception return. */
10043 if (IS_USER(s)) {
10044 goto illegal_op;
10046 if (rn != 14 || rd != 15) {
10047 goto illegal_op;
10049 tmp = load_reg(s, rn);
10050 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10051 gen_exception_return(s, tmp);
10052 break;
10053 case 6: /* mrs cpsr. */
10054 tmp = tcg_temp_new_i32();
10055 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10056 addr = tcg_const_i32(insn & 0xff);
10057 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10058 tcg_temp_free_i32(addr);
10059 } else {
10060 gen_helper_cpsr_read(tmp, cpu_env);
10062 store_reg(s, rd, tmp);
10063 break;
10064 case 7: /* mrs spsr. */
10065 /* Not accessible in user mode. */
10066 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10067 goto illegal_op;
10069 tmp = load_cpu_field(spsr);
10070 store_reg(s, rd, tmp);
10071 break;
10074 } else {
10075 /* Conditional branch. */
10076 op = (insn >> 22) & 0xf;
10077 /* Generate a conditional jump to next instruction. */
10078 s->condlabel = gen_new_label();
10079 arm_gen_test_cc(op ^ 1, s->condlabel);
10080 s->condjmp = 1;
10082 /* offset[11:1] = insn[10:0] */
10083 offset = (insn & 0x7ff) << 1;
10084 /* offset[17:12] = insn[21:16]. */
10085 offset |= (insn & 0x003f0000) >> 4;
10086 /* offset[31:20] = insn[26]. */
10087 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10088 /* offset[18] = insn[13]. */
10089 offset |= (insn & (1 << 13)) << 5;
10090 /* offset[19] = insn[11]. */
10091 offset |= (insn & (1 << 11)) << 8;
10093 /* jump to the offset */
10094 gen_jmp(s, s->pc + offset);
10096 } else {
10097 /* Data processing immediate. */
10098 if (insn & (1 << 25)) {
10099 if (insn & (1 << 24)) {
10100 if (insn & (1 << 20))
10101 goto illegal_op;
10102 /* Bitfield/Saturate. */
10103 op = (insn >> 21) & 7;
10104 imm = insn & 0x1f;
10105 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10106 if (rn == 15) {
10107 tmp = tcg_temp_new_i32();
10108 tcg_gen_movi_i32(tmp, 0);
10109 } else {
10110 tmp = load_reg(s, rn);
10112 switch (op) {
10113 case 2: /* Signed bitfield extract. */
10114 imm++;
10115 if (shift + imm > 32)
10116 goto illegal_op;
10117 if (imm < 32)
10118 gen_sbfx(tmp, shift, imm);
10119 break;
10120 case 6: /* Unsigned bitfield extract. */
10121 imm++;
10122 if (shift + imm > 32)
10123 goto illegal_op;
10124 if (imm < 32)
10125 gen_ubfx(tmp, shift, (1u << imm) - 1);
10126 break;
10127 case 3: /* Bitfield insert/clear. */
10128 if (imm < shift)
10129 goto illegal_op;
10130 imm = imm + 1 - shift;
10131 if (imm != 32) {
10132 tmp2 = load_reg(s, rd);
10133 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10134 tcg_temp_free_i32(tmp2);
10136 break;
10137 case 7:
10138 goto illegal_op;
10139 default: /* Saturate. */
10140 if (shift) {
10141 if (op & 1)
10142 tcg_gen_sari_i32(tmp, tmp, shift);
10143 else
10144 tcg_gen_shli_i32(tmp, tmp, shift);
10146 tmp2 = tcg_const_i32(imm);
10147 if (op & 4) {
10148 /* Unsigned. */
10149 if ((op & 1) && shift == 0) {
10150 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10151 tcg_temp_free_i32(tmp);
10152 tcg_temp_free_i32(tmp2);
10153 goto illegal_op;
10155 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10156 } else {
10157 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10159 } else {
10160 /* Signed. */
10161 if ((op & 1) && shift == 0) {
10162 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10163 tcg_temp_free_i32(tmp);
10164 tcg_temp_free_i32(tmp2);
10165 goto illegal_op;
10167 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10168 } else {
10169 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10172 tcg_temp_free_i32(tmp2);
10173 break;
10175 store_reg(s, rd, tmp);
10176 } else {
10177 imm = ((insn & 0x04000000) >> 15)
10178 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10179 if (insn & (1 << 22)) {
10180 /* 16-bit immediate. */
10181 imm |= (insn >> 4) & 0xf000;
10182 if (insn & (1 << 23)) {
10183 /* movt */
10184 tmp = load_reg(s, rd);
10185 tcg_gen_ext16u_i32(tmp, tmp);
10186 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10187 } else {
10188 /* movw */
10189 tmp = tcg_temp_new_i32();
10190 tcg_gen_movi_i32(tmp, imm);
10192 } else {
10193 /* Add/sub 12-bit immediate. */
10194 if (rn == 15) {
10195 offset = s->pc & ~(uint32_t)3;
10196 if (insn & (1 << 23))
10197 offset -= imm;
10198 else
10199 offset += imm;
10200 tmp = tcg_temp_new_i32();
10201 tcg_gen_movi_i32(tmp, offset);
10202 } else {
10203 tmp = load_reg(s, rn);
10204 if (insn & (1 << 23))
10205 tcg_gen_subi_i32(tmp, tmp, imm);
10206 else
10207 tcg_gen_addi_i32(tmp, tmp, imm);
10210 store_reg(s, rd, tmp);
10212 } else {
10213 int shifter_out = 0;
10214 /* modified 12-bit immediate. */
10215 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10216 imm = (insn & 0xff);
10217 switch (shift) {
10218 case 0: /* XY */
10219 /* Nothing to do. */
10220 break;
10221 case 1: /* 00XY00XY */
10222 imm |= imm << 16;
10223 break;
10224 case 2: /* XY00XY00 */
10225 imm |= imm << 16;
10226 imm <<= 8;
10227 break;
10228 case 3: /* XYXYXYXY */
10229 imm |= imm << 16;
10230 imm |= imm << 8;
10231 break;
10232 default: /* Rotated constant. */
10233 shift = (shift << 1) | (imm >> 7);
10234 imm |= 0x80;
10235 imm = imm << (32 - shift);
10236 shifter_out = 1;
10237 break;
10239 tmp2 = tcg_temp_new_i32();
10240 tcg_gen_movi_i32(tmp2, imm);
10241 rn = (insn >> 16) & 0xf;
10242 if (rn == 15) {
10243 tmp = tcg_temp_new_i32();
10244 tcg_gen_movi_i32(tmp, 0);
10245 } else {
10246 tmp = load_reg(s, rn);
10248 op = (insn >> 21) & 0xf;
10249 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10250 shifter_out, tmp, tmp2))
10251 goto illegal_op;
10252 tcg_temp_free_i32(tmp2);
10253 rd = (insn >> 8) & 0xf;
10254 if (rd != 15) {
10255 store_reg(s, rd, tmp);
10256 } else {
10257 tcg_temp_free_i32(tmp);
10261 break;
10262 case 12: /* Load/store single data item. */
10264 int postinc = 0;
10265 int writeback = 0;
10266 int memidx;
10267 if ((insn & 0x01100000) == 0x01000000) {
10268 if (disas_neon_ls_insn(s, insn)) {
10269 goto illegal_op;
10271 break;
10273 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10274 if (rs == 15) {
10275 if (!(insn & (1 << 20))) {
10276 goto illegal_op;
10278 if (op != 2) {
10279 /* Byte or halfword load space with dest == r15 : memory hints.
10280 * Catch them early so we don't emit pointless addressing code.
10281 * This space is a mix of:
10282 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10283 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10284 * cores)
10285 * unallocated hints, which must be treated as NOPs
10286 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10287 * which is easiest for the decoding logic
10288 * Some space which must UNDEF
10290 int op1 = (insn >> 23) & 3;
10291 int op2 = (insn >> 6) & 0x3f;
10292 if (op & 2) {
10293 goto illegal_op;
10295 if (rn == 15) {
10296 /* UNPREDICTABLE, unallocated hint or
10297 * PLD/PLDW/PLI (literal)
10299 return 0;
10301 if (op1 & 1) {
10302 return 0; /* PLD/PLDW/PLI or unallocated hint */
10304 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10305 return 0; /* PLD/PLDW/PLI or unallocated hint */
10307 /* UNDEF space, or an UNPREDICTABLE */
10308 return 1;
10311 memidx = get_mem_index(s);
10312 if (rn == 15) {
10313 addr = tcg_temp_new_i32();
10314 /* PC relative. */
10315 /* s->pc has already been incremented by 4. */
10316 imm = s->pc & 0xfffffffc;
10317 if (insn & (1 << 23))
10318 imm += insn & 0xfff;
10319 else
10320 imm -= insn & 0xfff;
10321 tcg_gen_movi_i32(addr, imm);
10322 } else {
10323 addr = load_reg(s, rn);
10324 if (insn & (1 << 23)) {
10325 /* Positive offset. */
10326 imm = insn & 0xfff;
10327 tcg_gen_addi_i32(addr, addr, imm);
10328 } else {
10329 imm = insn & 0xff;
10330 switch ((insn >> 8) & 0xf) {
10331 case 0x0: /* Shifted Register. */
10332 shift = (insn >> 4) & 0xf;
10333 if (shift > 3) {
10334 tcg_temp_free_i32(addr);
10335 goto illegal_op;
10337 tmp = load_reg(s, rm);
10338 if (shift)
10339 tcg_gen_shli_i32(tmp, tmp, shift);
10340 tcg_gen_add_i32(addr, addr, tmp);
10341 tcg_temp_free_i32(tmp);
10342 break;
10343 case 0xc: /* Negative offset. */
10344 tcg_gen_addi_i32(addr, addr, -imm);
10345 break;
10346 case 0xe: /* User privilege. */
10347 tcg_gen_addi_i32(addr, addr, imm);
10348 memidx = get_a32_user_mem_index(s);
10349 break;
10350 case 0x9: /* Post-decrement. */
10351 imm = -imm;
10352 /* Fall through. */
10353 case 0xb: /* Post-increment. */
10354 postinc = 1;
10355 writeback = 1;
10356 break;
10357 case 0xd: /* Pre-decrement. */
10358 imm = -imm;
10359 /* Fall through. */
10360 case 0xf: /* Pre-increment. */
10361 tcg_gen_addi_i32(addr, addr, imm);
10362 writeback = 1;
10363 break;
10364 default:
10365 tcg_temp_free_i32(addr);
10366 goto illegal_op;
10370 if (insn & (1 << 20)) {
10371 /* Load. */
10372 tmp = tcg_temp_new_i32();
10373 switch (op) {
10374 case 0:
10375 gen_aa32_ld8u(tmp, addr, memidx);
10376 break;
10377 case 4:
10378 gen_aa32_ld8s(tmp, addr, memidx);
10379 break;
10380 case 1:
10381 gen_aa32_ld16u(tmp, addr, memidx);
10382 break;
10383 case 5:
10384 gen_aa32_ld16s(tmp, addr, memidx);
10385 break;
10386 case 2:
10387 gen_aa32_ld32u(tmp, addr, memidx);
10388 break;
10389 default:
10390 tcg_temp_free_i32(tmp);
10391 tcg_temp_free_i32(addr);
10392 goto illegal_op;
10394 if (rs == 15) {
10395 gen_bx(s, tmp);
10396 } else {
10397 store_reg(s, rs, tmp);
10399 } else {
10400 /* Store. */
10401 tmp = load_reg(s, rs);
10402 switch (op) {
10403 case 0:
10404 gen_aa32_st8(tmp, addr, memidx);
10405 break;
10406 case 1:
10407 gen_aa32_st16(tmp, addr, memidx);
10408 break;
10409 case 2:
10410 gen_aa32_st32(tmp, addr, memidx);
10411 break;
10412 default:
10413 tcg_temp_free_i32(tmp);
10414 tcg_temp_free_i32(addr);
10415 goto illegal_op;
10417 tcg_temp_free_i32(tmp);
10419 if (postinc)
10420 tcg_gen_addi_i32(addr, addr, imm);
10421 if (writeback) {
10422 store_reg(s, rn, addr);
10423 } else {
10424 tcg_temp_free_i32(addr);
10427 break;
10428 default:
10429 goto illegal_op;
10431 return 0;
10432 illegal_op:
10433 return 1;
10436 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10438 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10439 int32_t offset;
10440 int i;
10441 TCGv_i32 tmp;
10442 TCGv_i32 tmp2;
10443 TCGv_i32 addr;
10445 if (s->condexec_mask) {
10446 cond = s->condexec_cond;
10447 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10448 s->condlabel = gen_new_label();
10449 arm_gen_test_cc(cond ^ 1, s->condlabel);
10450 s->condjmp = 1;
10454 insn = arm_lduw_code(env, s->pc, s->bswap_code);
10455 s->pc += 2;
10457 switch (insn >> 12) {
10458 case 0: case 1:
10460 rd = insn & 7;
10461 op = (insn >> 11) & 3;
10462 if (op == 3) {
10463 /* add/subtract */
10464 rn = (insn >> 3) & 7;
10465 tmp = load_reg(s, rn);
10466 if (insn & (1 << 10)) {
10467 /* immediate */
10468 tmp2 = tcg_temp_new_i32();
10469 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10470 } else {
10471 /* reg */
10472 rm = (insn >> 6) & 7;
10473 tmp2 = load_reg(s, rm);
10475 if (insn & (1 << 9)) {
10476 if (s->condexec_mask)
10477 tcg_gen_sub_i32(tmp, tmp, tmp2);
10478 else
10479 gen_sub_CC(tmp, tmp, tmp2);
10480 } else {
10481 if (s->condexec_mask)
10482 tcg_gen_add_i32(tmp, tmp, tmp2);
10483 else
10484 gen_add_CC(tmp, tmp, tmp2);
10486 tcg_temp_free_i32(tmp2);
10487 store_reg(s, rd, tmp);
10488 } else {
10489 /* shift immediate */
10490 rm = (insn >> 3) & 7;
10491 shift = (insn >> 6) & 0x1f;
10492 tmp = load_reg(s, rm);
10493 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10494 if (!s->condexec_mask)
10495 gen_logic_CC(tmp);
10496 store_reg(s, rd, tmp);
10498 break;
10499 case 2: case 3:
10500 /* arithmetic large immediate */
10501 op = (insn >> 11) & 3;
10502 rd = (insn >> 8) & 0x7;
10503 if (op == 0) { /* mov */
10504 tmp = tcg_temp_new_i32();
10505 tcg_gen_movi_i32(tmp, insn & 0xff);
10506 if (!s->condexec_mask)
10507 gen_logic_CC(tmp);
10508 store_reg(s, rd, tmp);
10509 } else {
10510 tmp = load_reg(s, rd);
10511 tmp2 = tcg_temp_new_i32();
10512 tcg_gen_movi_i32(tmp2, insn & 0xff);
10513 switch (op) {
10514 case 1: /* cmp */
10515 gen_sub_CC(tmp, tmp, tmp2);
10516 tcg_temp_free_i32(tmp);
10517 tcg_temp_free_i32(tmp2);
10518 break;
10519 case 2: /* add */
10520 if (s->condexec_mask)
10521 tcg_gen_add_i32(tmp, tmp, tmp2);
10522 else
10523 gen_add_CC(tmp, tmp, tmp2);
10524 tcg_temp_free_i32(tmp2);
10525 store_reg(s, rd, tmp);
10526 break;
10527 case 3: /* sub */
10528 if (s->condexec_mask)
10529 tcg_gen_sub_i32(tmp, tmp, tmp2);
10530 else
10531 gen_sub_CC(tmp, tmp, tmp2);
10532 tcg_temp_free_i32(tmp2);
10533 store_reg(s, rd, tmp);
10534 break;
10537 break;
10538 case 4:
10539 if (insn & (1 << 11)) {
10540 rd = (insn >> 8) & 7;
10541 /* load pc-relative. Bit 1 of PC is ignored. */
10542 val = s->pc + 2 + ((insn & 0xff) * 4);
10543 val &= ~(uint32_t)2;
10544 addr = tcg_temp_new_i32();
10545 tcg_gen_movi_i32(addr, val);
10546 tmp = tcg_temp_new_i32();
10547 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10548 tcg_temp_free_i32(addr);
10549 store_reg(s, rd, tmp);
10550 break;
10552 if (insn & (1 << 10)) {
10553 /* data processing extended or blx */
10554 rd = (insn & 7) | ((insn >> 4) & 8);
10555 rm = (insn >> 3) & 0xf;
10556 op = (insn >> 8) & 3;
10557 switch (op) {
10558 case 0: /* add */
10559 tmp = load_reg(s, rd);
10560 tmp2 = load_reg(s, rm);
10561 tcg_gen_add_i32(tmp, tmp, tmp2);
10562 tcg_temp_free_i32(tmp2);
10563 store_reg(s, rd, tmp);
10564 break;
10565 case 1: /* cmp */
10566 tmp = load_reg(s, rd);
10567 tmp2 = load_reg(s, rm);
10568 gen_sub_CC(tmp, tmp, tmp2);
10569 tcg_temp_free_i32(tmp2);
10570 tcg_temp_free_i32(tmp);
10571 break;
10572 case 2: /* mov/cpy */
10573 tmp = load_reg(s, rm);
10574 store_reg(s, rd, tmp);
10575 break;
10576 case 3:/* branch [and link] exchange thumb register */
10577 tmp = load_reg(s, rm);
10578 if (insn & (1 << 7)) {
10579 ARCH(5);
10580 val = (uint32_t)s->pc | 1;
10581 tmp2 = tcg_temp_new_i32();
10582 tcg_gen_movi_i32(tmp2, val);
10583 store_reg(s, 14, tmp2);
10585 /* already thumb, no need to check */
10586 gen_bx(s, tmp);
10587 break;
10589 break;
10592 /* data processing register */
10593 rd = insn & 7;
10594 rm = (insn >> 3) & 7;
10595 op = (insn >> 6) & 0xf;
10596 if (op == 2 || op == 3 || op == 4 || op == 7) {
10597 /* the shift/rotate ops want the operands backwards */
10598 val = rm;
10599 rm = rd;
10600 rd = val;
10601 val = 1;
10602 } else {
10603 val = 0;
10606 if (op == 9) { /* neg */
10607 tmp = tcg_temp_new_i32();
10608 tcg_gen_movi_i32(tmp, 0);
10609 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10610 tmp = load_reg(s, rd);
10611 } else {
10612 TCGV_UNUSED_I32(tmp);
10615 tmp2 = load_reg(s, rm);
10616 switch (op) {
10617 case 0x0: /* and */
10618 tcg_gen_and_i32(tmp, tmp, tmp2);
10619 if (!s->condexec_mask)
10620 gen_logic_CC(tmp);
10621 break;
10622 case 0x1: /* eor */
10623 tcg_gen_xor_i32(tmp, tmp, tmp2);
10624 if (!s->condexec_mask)
10625 gen_logic_CC(tmp);
10626 break;
10627 case 0x2: /* lsl */
10628 if (s->condexec_mask) {
10629 gen_shl(tmp2, tmp2, tmp);
10630 } else {
10631 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10632 gen_logic_CC(tmp2);
10634 break;
10635 case 0x3: /* lsr */
10636 if (s->condexec_mask) {
10637 gen_shr(tmp2, tmp2, tmp);
10638 } else {
10639 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10640 gen_logic_CC(tmp2);
10642 break;
10643 case 0x4: /* asr */
10644 if (s->condexec_mask) {
10645 gen_sar(tmp2, tmp2, tmp);
10646 } else {
10647 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10648 gen_logic_CC(tmp2);
10650 break;
10651 case 0x5: /* adc */
10652 if (s->condexec_mask) {
10653 gen_adc(tmp, tmp2);
10654 } else {
10655 gen_adc_CC(tmp, tmp, tmp2);
10657 break;
10658 case 0x6: /* sbc */
10659 if (s->condexec_mask) {
10660 gen_sub_carry(tmp, tmp, tmp2);
10661 } else {
10662 gen_sbc_CC(tmp, tmp, tmp2);
10664 break;
10665 case 0x7: /* ror */
10666 if (s->condexec_mask) {
10667 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10668 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10669 } else {
10670 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10671 gen_logic_CC(tmp2);
10673 break;
10674 case 0x8: /* tst */
10675 tcg_gen_and_i32(tmp, tmp, tmp2);
10676 gen_logic_CC(tmp);
10677 rd = 16;
10678 break;
10679 case 0x9: /* neg */
10680 if (s->condexec_mask)
10681 tcg_gen_neg_i32(tmp, tmp2);
10682 else
10683 gen_sub_CC(tmp, tmp, tmp2);
10684 break;
10685 case 0xa: /* cmp */
10686 gen_sub_CC(tmp, tmp, tmp2);
10687 rd = 16;
10688 break;
10689 case 0xb: /* cmn */
10690 gen_add_CC(tmp, tmp, tmp2);
10691 rd = 16;
10692 break;
10693 case 0xc: /* orr */
10694 tcg_gen_or_i32(tmp, tmp, tmp2);
10695 if (!s->condexec_mask)
10696 gen_logic_CC(tmp);
10697 break;
10698 case 0xd: /* mul */
10699 tcg_gen_mul_i32(tmp, tmp, tmp2);
10700 if (!s->condexec_mask)
10701 gen_logic_CC(tmp);
10702 break;
10703 case 0xe: /* bic */
10704 tcg_gen_andc_i32(tmp, tmp, tmp2);
10705 if (!s->condexec_mask)
10706 gen_logic_CC(tmp);
10707 break;
10708 case 0xf: /* mvn */
10709 tcg_gen_not_i32(tmp2, tmp2);
10710 if (!s->condexec_mask)
10711 gen_logic_CC(tmp2);
10712 val = 1;
10713 rm = rd;
10714 break;
10716 if (rd != 16) {
10717 if (val) {
10718 store_reg(s, rm, tmp2);
10719 if (op != 0xf)
10720 tcg_temp_free_i32(tmp);
10721 } else {
10722 store_reg(s, rd, tmp);
10723 tcg_temp_free_i32(tmp2);
10725 } else {
10726 tcg_temp_free_i32(tmp);
10727 tcg_temp_free_i32(tmp2);
10729 break;
10731 case 5:
10732 /* load/store register offset. */
10733 rd = insn & 7;
10734 rn = (insn >> 3) & 7;
10735 rm = (insn >> 6) & 7;
10736 op = (insn >> 9) & 7;
10737 addr = load_reg(s, rn);
10738 tmp = load_reg(s, rm);
10739 tcg_gen_add_i32(addr, addr, tmp);
10740 tcg_temp_free_i32(tmp);
10742 if (op < 3) { /* store */
10743 tmp = load_reg(s, rd);
10744 } else {
10745 tmp = tcg_temp_new_i32();
10748 switch (op) {
10749 case 0: /* str */
10750 gen_aa32_st32(tmp, addr, get_mem_index(s));
10751 break;
10752 case 1: /* strh */
10753 gen_aa32_st16(tmp, addr, get_mem_index(s));
10754 break;
10755 case 2: /* strb */
10756 gen_aa32_st8(tmp, addr, get_mem_index(s));
10757 break;
10758 case 3: /* ldrsb */
10759 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
10760 break;
10761 case 4: /* ldr */
10762 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10763 break;
10764 case 5: /* ldrh */
10765 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10766 break;
10767 case 6: /* ldrb */
10768 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10769 break;
10770 case 7: /* ldrsh */
10771 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
10772 break;
10774 if (op >= 3) { /* load */
10775 store_reg(s, rd, tmp);
10776 } else {
10777 tcg_temp_free_i32(tmp);
10779 tcg_temp_free_i32(addr);
10780 break;
10782 case 6:
10783 /* load/store word immediate offset */
10784 rd = insn & 7;
10785 rn = (insn >> 3) & 7;
10786 addr = load_reg(s, rn);
10787 val = (insn >> 4) & 0x7c;
10788 tcg_gen_addi_i32(addr, addr, val);
10790 if (insn & (1 << 11)) {
10791 /* load */
10792 tmp = tcg_temp_new_i32();
10793 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10794 store_reg(s, rd, tmp);
10795 } else {
10796 /* store */
10797 tmp = load_reg(s, rd);
10798 gen_aa32_st32(tmp, addr, get_mem_index(s));
10799 tcg_temp_free_i32(tmp);
10801 tcg_temp_free_i32(addr);
10802 break;
10804 case 7:
10805 /* load/store byte immediate offset */
10806 rd = insn & 7;
10807 rn = (insn >> 3) & 7;
10808 addr = load_reg(s, rn);
10809 val = (insn >> 6) & 0x1f;
10810 tcg_gen_addi_i32(addr, addr, val);
10812 if (insn & (1 << 11)) {
10813 /* load */
10814 tmp = tcg_temp_new_i32();
10815 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10816 store_reg(s, rd, tmp);
10817 } else {
10818 /* store */
10819 tmp = load_reg(s, rd);
10820 gen_aa32_st8(tmp, addr, get_mem_index(s));
10821 tcg_temp_free_i32(tmp);
10823 tcg_temp_free_i32(addr);
10824 break;
10826 case 8:
10827 /* load/store halfword immediate offset */
10828 rd = insn & 7;
10829 rn = (insn >> 3) & 7;
10830 addr = load_reg(s, rn);
10831 val = (insn >> 5) & 0x3e;
10832 tcg_gen_addi_i32(addr, addr, val);
10834 if (insn & (1 << 11)) {
10835 /* load */
10836 tmp = tcg_temp_new_i32();
10837 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10838 store_reg(s, rd, tmp);
10839 } else {
10840 /* store */
10841 tmp = load_reg(s, rd);
10842 gen_aa32_st16(tmp, addr, get_mem_index(s));
10843 tcg_temp_free_i32(tmp);
10845 tcg_temp_free_i32(addr);
10846 break;
10848 case 9:
10849 /* load/store from stack */
10850 rd = (insn >> 8) & 7;
10851 addr = load_reg(s, 13);
10852 val = (insn & 0xff) * 4;
10853 tcg_gen_addi_i32(addr, addr, val);
10855 if (insn & (1 << 11)) {
10856 /* load */
10857 tmp = tcg_temp_new_i32();
10858 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10859 store_reg(s, rd, tmp);
10860 } else {
10861 /* store */
10862 tmp = load_reg(s, rd);
10863 gen_aa32_st32(tmp, addr, get_mem_index(s));
10864 tcg_temp_free_i32(tmp);
10866 tcg_temp_free_i32(addr);
10867 break;
10869 case 10:
10870 /* add to high reg */
10871 rd = (insn >> 8) & 7;
10872 if (insn & (1 << 11)) {
10873 /* SP */
10874 tmp = load_reg(s, 13);
10875 } else {
10876 /* PC. bit 1 is ignored. */
10877 tmp = tcg_temp_new_i32();
10878 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10880 val = (insn & 0xff) * 4;
10881 tcg_gen_addi_i32(tmp, tmp, val);
10882 store_reg(s, rd, tmp);
10883 break;
10885 case 11:
10886 /* misc */
10887 op = (insn >> 8) & 0xf;
10888 switch (op) {
10889 case 0:
10890 /* adjust stack pointer */
10891 tmp = load_reg(s, 13);
10892 val = (insn & 0x7f) * 4;
10893 if (insn & (1 << 7))
10894 val = -(int32_t)val;
10895 tcg_gen_addi_i32(tmp, tmp, val);
10896 store_reg(s, 13, tmp);
10897 break;
10899 case 2: /* sign/zero extend. */
10900 ARCH(6);
10901 rd = insn & 7;
10902 rm = (insn >> 3) & 7;
10903 tmp = load_reg(s, rm);
10904 switch ((insn >> 6) & 3) {
10905 case 0: gen_sxth(tmp); break;
10906 case 1: gen_sxtb(tmp); break;
10907 case 2: gen_uxth(tmp); break;
10908 case 3: gen_uxtb(tmp); break;
10910 store_reg(s, rd, tmp);
10911 break;
10912 case 4: case 5: case 0xc: case 0xd:
10913 /* push/pop */
10914 addr = load_reg(s, 13);
10915 if (insn & (1 << 8))
10916 offset = 4;
10917 else
10918 offset = 0;
10919 for (i = 0; i < 8; i++) {
10920 if (insn & (1 << i))
10921 offset += 4;
10923 if ((insn & (1 << 11)) == 0) {
10924 tcg_gen_addi_i32(addr, addr, -offset);
10926 for (i = 0; i < 8; i++) {
10927 if (insn & (1 << i)) {
10928 if (insn & (1 << 11)) {
10929 /* pop */
10930 tmp = tcg_temp_new_i32();
10931 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10932 store_reg(s, i, tmp);
10933 } else {
10934 /* push */
10935 tmp = load_reg(s, i);
10936 gen_aa32_st32(tmp, addr, get_mem_index(s));
10937 tcg_temp_free_i32(tmp);
10939 /* advance to the next address. */
10940 tcg_gen_addi_i32(addr, addr, 4);
10943 TCGV_UNUSED_I32(tmp);
10944 if (insn & (1 << 8)) {
10945 if (insn & (1 << 11)) {
10946 /* pop pc */
10947 tmp = tcg_temp_new_i32();
10948 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10949 /* don't set the pc until the rest of the instruction
10950 has completed */
10951 } else {
10952 /* push lr */
10953 tmp = load_reg(s, 14);
10954 gen_aa32_st32(tmp, addr, get_mem_index(s));
10955 tcg_temp_free_i32(tmp);
10957 tcg_gen_addi_i32(addr, addr, 4);
10959 if ((insn & (1 << 11)) == 0) {
10960 tcg_gen_addi_i32(addr, addr, -offset);
10962 /* write back the new stack pointer */
10963 store_reg(s, 13, addr);
10964 /* set the new PC value */
10965 if ((insn & 0x0900) == 0x0900) {
10966 store_reg_from_load(s, 15, tmp);
10968 break;
10970 case 1: case 3: case 9: case 11: /* czb */
10971 rm = insn & 7;
10972 tmp = load_reg(s, rm);
10973 s->condlabel = gen_new_label();
10974 s->condjmp = 1;
10975 if (insn & (1 << 11))
10976 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10977 else
10978 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10979 tcg_temp_free_i32(tmp);
10980 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10981 val = (uint32_t)s->pc + 2;
10982 val += offset;
10983 gen_jmp(s, val);
10984 break;
10986 case 15: /* IT, nop-hint. */
10987 if ((insn & 0xf) == 0) {
10988 gen_nop_hint(s, (insn >> 4) & 0xf);
10989 break;
10991 /* If Then. */
10992 s->condexec_cond = (insn >> 4) & 0xe;
10993 s->condexec_mask = insn & 0x1f;
10994 /* No actual code generated for this insn, just setup state. */
10995 break;
10997 case 0xe: /* bkpt */
10999 int imm8 = extract32(insn, 0, 8);
11000 ARCH(5);
11001 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11002 default_exception_el(s));
11003 break;
11006 case 0xa: /* rev */
11007 ARCH(6);
11008 rn = (insn >> 3) & 0x7;
11009 rd = insn & 0x7;
11010 tmp = load_reg(s, rn);
11011 switch ((insn >> 6) & 3) {
11012 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11013 case 1: gen_rev16(tmp); break;
11014 case 3: gen_revsh(tmp); break;
11015 default: goto illegal_op;
11017 store_reg(s, rd, tmp);
11018 break;
11020 case 6:
11021 switch ((insn >> 5) & 7) {
11022 case 2:
11023 /* setend */
11024 ARCH(6);
11025 if (((insn >> 3) & 1) != s->bswap_code) {
11026 /* Dynamic endianness switching not implemented. */
11027 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
11028 g_assert_not_reached();
11030 break;
11031 case 3:
11032 /* cps */
11033 ARCH(6);
11034 if (IS_USER(s)) {
11035 break;
11037 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11038 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11039 /* FAULTMASK */
11040 if (insn & 1) {
11041 addr = tcg_const_i32(19);
11042 gen_helper_v7m_msr(cpu_env, addr, tmp);
11043 tcg_temp_free_i32(addr);
11045 /* PRIMASK */
11046 if (insn & 2) {
11047 addr = tcg_const_i32(16);
11048 gen_helper_v7m_msr(cpu_env, addr, tmp);
11049 tcg_temp_free_i32(addr);
11051 tcg_temp_free_i32(tmp);
11052 gen_lookup_tb(s);
11053 } else {
11054 if (insn & (1 << 4)) {
11055 shift = CPSR_A | CPSR_I | CPSR_F;
11056 } else {
11057 shift = 0;
11059 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11061 break;
11062 default:
11063 goto undef;
11065 break;
11067 default:
11068 goto undef;
11070 break;
11072 case 12:
11074 /* load/store multiple */
11075 TCGv_i32 loaded_var;
11076 TCGV_UNUSED_I32(loaded_var);
11077 rn = (insn >> 8) & 0x7;
11078 addr = load_reg(s, rn);
11079 for (i = 0; i < 8; i++) {
11080 if (insn & (1 << i)) {
11081 if (insn & (1 << 11)) {
11082 /* load */
11083 tmp = tcg_temp_new_i32();
11084 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
11085 if (i == rn) {
11086 loaded_var = tmp;
11087 } else {
11088 store_reg(s, i, tmp);
11090 } else {
11091 /* store */
11092 tmp = load_reg(s, i);
11093 gen_aa32_st32(tmp, addr, get_mem_index(s));
11094 tcg_temp_free_i32(tmp);
11096 /* advance to the next address */
11097 tcg_gen_addi_i32(addr, addr, 4);
11100 if ((insn & (1 << rn)) == 0) {
11101 /* base reg not in list: base register writeback */
11102 store_reg(s, rn, addr);
11103 } else {
11104 /* base reg in list: if load, complete it now */
11105 if (insn & (1 << 11)) {
11106 store_reg(s, rn, loaded_var);
11108 tcg_temp_free_i32(addr);
11110 break;
11112 case 13:
11113 /* conditional branch or swi */
11114 cond = (insn >> 8) & 0xf;
11115 if (cond == 0xe)
11116 goto undef;
11118 if (cond == 0xf) {
11119 /* swi */
11120 gen_set_pc_im(s, s->pc);
11121 s->svc_imm = extract32(insn, 0, 8);
11122 s->is_jmp = DISAS_SWI;
11123 break;
11125 /* generate a conditional jump to next instruction */
11126 s->condlabel = gen_new_label();
11127 arm_gen_test_cc(cond ^ 1, s->condlabel);
11128 s->condjmp = 1;
11130 /* jump to the offset */
11131 val = (uint32_t)s->pc + 2;
11132 offset = ((int32_t)insn << 24) >> 24;
11133 val += offset << 1;
11134 gen_jmp(s, val);
11135 break;
11137 case 14:
11138 if (insn & (1 << 11)) {
11139 if (disas_thumb2_insn(env, s, insn))
11140 goto undef32;
11141 break;
11143 /* unconditional branch */
11144 val = (uint32_t)s->pc;
11145 offset = ((int32_t)insn << 21) >> 21;
11146 val += (offset << 1) + 2;
11147 gen_jmp(s, val);
11148 break;
11150 case 15:
11151 if (disas_thumb2_insn(env, s, insn))
11152 goto undef32;
11153 break;
11155 return;
11156 undef32:
11157 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11158 default_exception_el(s));
11159 return;
11160 illegal_op:
11161 undef:
11162 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11163 default_exception_el(s));
11166 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11167 basic block 'tb'. If search_pc is TRUE, also generate PC
11168 information for each intermediate instruction. */
11169 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
11170 TranslationBlock *tb,
11171 bool search_pc)
11173 CPUState *cs = CPU(cpu);
11174 CPUARMState *env = &cpu->env;
11175 DisasContext dc1, *dc = &dc1;
11176 CPUBreakpoint *bp;
11177 int j, lj;
11178 target_ulong pc_start;
11179 target_ulong next_page_start;
11180 int num_insns;
11181 int max_insns;
11183 /* generate intermediate code */
11185 /* The A64 decoder has its own top level loop, because it doesn't need
11186 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11188 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11189 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
11190 return;
11193 pc_start = tb->pc;
11195 dc->tb = tb;
11197 dc->is_jmp = DISAS_NEXT;
11198 dc->pc = pc_start;
11199 dc->singlestep_enabled = cs->singlestep_enabled;
11200 dc->condjmp = 0;
11202 dc->aarch64 = 0;
11203 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11204 * there is no secure EL1, so we route exceptions to EL3.
11206 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11207 !arm_el_is_aa64(env, 3);
11208 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11209 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
11210 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11211 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11212 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11213 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11214 #if !defined(CONFIG_USER_ONLY)
11215 dc->user = (dc->current_el == 0);
11216 #endif
11217 dc->ns = ARM_TBFLAG_NS(tb->flags);
11218 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11219 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11220 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11221 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11222 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11223 dc->cp_regs = cpu->cp_regs;
11224 dc->features = env->features;
11226 /* Single step state. The code-generation logic here is:
11227 * SS_ACTIVE == 0:
11228 * generate code with no special handling for single-stepping (except
11229 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11230 * this happens anyway because those changes are all system register or
11231 * PSTATE writes).
11232 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11233 * emit code for one insn
11234 * emit code to clear PSTATE.SS
11235 * emit code to generate software step exception for completed step
11236 * end TB (as usual for having generated an exception)
11237 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11238 * emit code to generate a software step exception
11239 * end the TB
11241 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11242 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11243 dc->is_ldex = false;
11244 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11246 cpu_F0s = tcg_temp_new_i32();
11247 cpu_F1s = tcg_temp_new_i32();
11248 cpu_F0d = tcg_temp_new_i64();
11249 cpu_F1d = tcg_temp_new_i64();
11250 cpu_V0 = cpu_F0d;
11251 cpu_V1 = cpu_F1d;
11252 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11253 cpu_M0 = tcg_temp_new_i64();
11254 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11255 lj = -1;
11256 num_insns = 0;
11257 max_insns = tb->cflags & CF_COUNT_MASK;
11258 if (max_insns == 0)
11259 max_insns = CF_COUNT_MASK;
11261 gen_tb_start(tb);
11263 tcg_clear_temp_count();
11265 /* A note on handling of the condexec (IT) bits:
11267 * We want to avoid the overhead of having to write the updated condexec
11268 * bits back to the CPUARMState for every instruction in an IT block. So:
11269 * (1) if the condexec bits are not already zero then we write
11270 * zero back into the CPUARMState now. This avoids complications trying
11271 * to do it at the end of the block. (For example if we don't do this
11272 * it's hard to identify whether we can safely skip writing condexec
11273 * at the end of the TB, which we definitely want to do for the case
11274 * where a TB doesn't do anything with the IT state at all.)
11275 * (2) if we are going to leave the TB then we call gen_set_condexec()
11276 * which will write the correct value into CPUARMState if zero is wrong.
11277 * This is done both for leaving the TB at the end, and for leaving
11278 * it because of an exception we know will happen, which is done in
11279 * gen_exception_insn(). The latter is necessary because we need to
11280 * leave the TB with the PC/IT state just prior to execution of the
11281 * instruction which caused the exception.
11282 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11283 * then the CPUARMState will be wrong and we need to reset it.
11284 * This is handled in the same way as restoration of the
11285 * PC in these situations: we will be called again with search_pc=1
11286 * and generate a mapping of the condexec bits for each PC in
11287 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11288 * this to restore the condexec bits.
11290 * Note that there are no instructions which can read the condexec
11291 * bits, and none which can write non-static values to them, so
11292 * we don't need to care about whether CPUARMState is correct in the
11293 * middle of a TB.
11296 /* Reset the conditional execution bits immediately. This avoids
11297 complications trying to do it at the end of the block. */
11298 if (dc->condexec_mask || dc->condexec_cond)
11300 TCGv_i32 tmp = tcg_temp_new_i32();
11301 tcg_gen_movi_i32(tmp, 0);
11302 store_cpu_field(tmp, condexec_bits);
11304 do {
11305 #ifdef CONFIG_USER_ONLY
11306 /* Intercept jump to the magic kernel page. */
11307 if (dc->pc >= 0xffff0000) {
11308 /* We always get here via a jump, so know we are not in a
11309 conditional execution block. */
11310 gen_exception_internal(EXCP_KERNEL_TRAP);
11311 dc->is_jmp = DISAS_UPDATE;
11312 break;
11314 #else
11315 if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
11316 /* We always get here via a jump, so know we are not in a
11317 conditional execution block. */
11318 gen_exception_internal(EXCP_EXCEPTION_EXIT);
11319 dc->is_jmp = DISAS_UPDATE;
11320 break;
11322 #endif
11324 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11325 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11326 if (bp->pc == dc->pc) {
11327 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11328 /* Advance PC so that clearing the breakpoint will
11329 invalidate this TB. */
11330 dc->pc += 2;
11331 goto done_generating;
11335 if (search_pc) {
11336 j = tcg_op_buf_count();
11337 if (lj < j) {
11338 lj++;
11339 while (lj < j)
11340 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11342 tcg_ctx.gen_opc_pc[lj] = dc->pc;
11343 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
11344 tcg_ctx.gen_opc_instr_start[lj] = 1;
11345 tcg_ctx.gen_opc_icount[lj] = num_insns;
11348 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
11349 gen_io_start();
11351 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
11352 tcg_gen_debug_insn_start(dc->pc);
11355 if (dc->ss_active && !dc->pstate_ss) {
11356 /* Singlestep state is Active-pending.
11357 * If we're in this state at the start of a TB then either
11358 * a) we just took an exception to an EL which is being debugged
11359 * and this is the first insn in the exception handler
11360 * b) debug exceptions were masked and we just unmasked them
11361 * without changing EL (eg by clearing PSTATE.D)
11362 * In either case we're going to take a swstep exception in the
11363 * "did not step an insn" case, and so the syndrome ISV and EX
11364 * bits should be zero.
11366 assert(num_insns == 0);
11367 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11368 default_exception_el(dc));
11369 goto done_generating;
11372 if (dc->thumb) {
11373 disas_thumb_insn(env, dc);
11374 if (dc->condexec_mask) {
11375 dc->condexec_cond = (dc->condexec_cond & 0xe)
11376 | ((dc->condexec_mask >> 4) & 1);
11377 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11378 if (dc->condexec_mask == 0) {
11379 dc->condexec_cond = 0;
11382 } else {
11383 unsigned int insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
11384 dc->pc += 4;
11385 disas_arm_insn(dc, insn);
11388 if (dc->condjmp && !dc->is_jmp) {
11389 gen_set_label(dc->condlabel);
11390 dc->condjmp = 0;
11393 if (tcg_check_temp_count()) {
11394 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11395 dc->pc);
11398 /* Translation stops when a conditional branch is encountered.
11399 * Otherwise the subsequent code could get translated several times.
11400 * Also stop translation when a page boundary is reached. This
11401 * ensures prefetch aborts occur at the right place. */
11402 num_insns ++;
11403 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11404 !cs->singlestep_enabled &&
11405 !singlestep &&
11406 !dc->ss_active &&
11407 dc->pc < next_page_start &&
11408 num_insns < max_insns);
11410 if (tb->cflags & CF_LAST_IO) {
11411 if (dc->condjmp) {
11412 /* FIXME: This can theoretically happen with self-modifying
11413 code. */
11414 cpu_abort(cs, "IO on conditional branch instruction");
11416 gen_io_end();
11419 /* At this stage dc->condjmp will only be set when the skipped
11420 instruction was a conditional branch or trap, and the PC has
11421 already been written. */
11422 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11423 /* Make sure the pc is updated, and raise a debug exception. */
11424 if (dc->condjmp) {
11425 gen_set_condexec(dc);
11426 if (dc->is_jmp == DISAS_SWI) {
11427 gen_ss_advance(dc);
11428 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11429 default_exception_el(dc));
11430 } else if (dc->is_jmp == DISAS_HVC) {
11431 gen_ss_advance(dc);
11432 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11433 } else if (dc->is_jmp == DISAS_SMC) {
11434 gen_ss_advance(dc);
11435 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11436 } else if (dc->ss_active) {
11437 gen_step_complete_exception(dc);
11438 } else {
11439 gen_exception_internal(EXCP_DEBUG);
11441 gen_set_label(dc->condlabel);
11443 if (dc->condjmp || !dc->is_jmp) {
11444 gen_set_pc_im(dc, dc->pc);
11445 dc->condjmp = 0;
11447 gen_set_condexec(dc);
11448 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
11449 gen_ss_advance(dc);
11450 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11451 default_exception_el(dc));
11452 } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
11453 gen_ss_advance(dc);
11454 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11455 } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
11456 gen_ss_advance(dc);
11457 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11458 } else if (dc->ss_active) {
11459 gen_step_complete_exception(dc);
11460 } else {
11461 /* FIXME: Single stepping a WFI insn will not halt
11462 the CPU. */
11463 gen_exception_internal(EXCP_DEBUG);
11465 } else {
11466 /* While branches must always occur at the end of an IT block,
11467 there are a few other things that can cause us to terminate
11468 the TB in the middle of an IT block:
11469 - Exception generating instructions (bkpt, swi, undefined).
11470 - Page boundaries.
11471 - Hardware watchpoints.
11472 Hardware breakpoints have already been handled and skip this code.
11474 gen_set_condexec(dc);
11475 switch(dc->is_jmp) {
11476 case DISAS_NEXT:
11477 gen_goto_tb(dc, 1, dc->pc);
11478 break;
11479 default:
11480 case DISAS_JUMP:
11481 case DISAS_UPDATE:
11482 /* indicate that the hash table must be used to find the next TB */
11483 tcg_gen_exit_tb(0);
11484 break;
11485 case DISAS_TB_JUMP:
11486 /* nothing more to generate */
11487 break;
11488 case DISAS_WFI:
11489 gen_helper_wfi(cpu_env);
11490 /* The helper doesn't necessarily throw an exception, but we
11491 * must go back to the main loop to check for interrupts anyway.
11493 tcg_gen_exit_tb(0);
11494 break;
11495 case DISAS_WFE:
11496 gen_helper_wfe(cpu_env);
11497 break;
11498 case DISAS_YIELD:
11499 gen_helper_yield(cpu_env);
11500 break;
11501 case DISAS_SWI:
11502 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11503 default_exception_el(dc));
11504 break;
11505 case DISAS_HVC:
11506 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11507 break;
11508 case DISAS_SMC:
11509 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11510 break;
11512 if (dc->condjmp) {
11513 gen_set_label(dc->condlabel);
11514 gen_set_condexec(dc);
11515 gen_goto_tb(dc, 1, dc->pc);
11516 dc->condjmp = 0;
11520 done_generating:
11521 gen_tb_end(tb, num_insns);
11523 #ifdef DEBUG_DISAS
11524 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11525 qemu_log("----------------\n");
11526 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11527 log_target_disas(cs, pc_start, dc->pc - pc_start,
11528 dc->thumb | (dc->bswap_code << 1));
11529 qemu_log("\n");
11531 #endif
11532 if (search_pc) {
11533 j = tcg_op_buf_count();
11534 lj++;
11535 while (lj <= j)
11536 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11537 } else {
11538 tb->size = dc->pc - pc_start;
11539 tb->icount = num_insns;
11543 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11545 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
11548 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
11550 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
11553 static const char *cpu_mode_names[16] = {
11554 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11555 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11558 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11559 int flags)
11561 ARMCPU *cpu = ARM_CPU(cs);
11562 CPUARMState *env = &cpu->env;
11563 int i;
11564 uint32_t psr;
11566 if (is_a64(env)) {
11567 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11568 return;
11571 for(i=0;i<16;i++) {
11572 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11573 if ((i % 4) == 3)
11574 cpu_fprintf(f, "\n");
11575 else
11576 cpu_fprintf(f, " ");
11578 psr = cpsr_read(env);
11579 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11580 psr,
11581 psr & (1 << 31) ? 'N' : '-',
11582 psr & (1 << 30) ? 'Z' : '-',
11583 psr & (1 << 29) ? 'C' : '-',
11584 psr & (1 << 28) ? 'V' : '-',
11585 psr & CPSR_T ? 'T' : 'A',
11586 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11588 if (flags & CPU_DUMP_FPU) {
11589 int numvfpregs = 0;
11590 if (arm_feature(env, ARM_FEATURE_VFP)) {
11591 numvfpregs += 16;
11593 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11594 numvfpregs += 16;
11596 for (i = 0; i < numvfpregs; i++) {
11597 uint64_t v = float64_val(env->vfp.regs[i]);
11598 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11599 i * 2, (uint32_t)v,
11600 i * 2 + 1, (uint32_t)(v >> 32),
11601 i, v);
11603 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11607 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11609 if (is_a64(env)) {
11610 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
11611 env->condexec_bits = 0;
11612 } else {
11613 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
11614 env->condexec_bits = gen_opc_condexec_bits[pc_pos];