qapi: Drop useless 'data' member of unions
[qemu/ar7.git] / target-arm / translate.c
blob025c7a53eb1946c0affd5bb9bc66ab62784e4d0d
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/>.
21 #include "qemu/osdep.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"
35 #include "exec/log.h"
38 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
39 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
40 /* currently all emulated v5 cores are also v5TE, so don't bother */
41 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
42 #define ENABLE_ARCH_5J 0
43 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
44 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
45 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
46 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
47 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
49 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
51 #include "translate.h"
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_env 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(cpu_env,
90 offsetof(CPUARMState, regs[i]),
91 regnames[i]);
93 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test = tcg_global_mem_new_i64(cpu_env,
104 offsetof(CPUARMState, exclusive_test), "exclusive_test");
105 cpu_exclusive_info = tcg_global_mem_new_i32(cpu_env,
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_JUMP;
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_JUMP;
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 #ifdef CONFIG_USER_ONLY
915 #define IS_USER_ONLY 1
916 #else
917 #define IS_USER_ONLY 0
918 #endif
920 /* Abstractions of "generate code to do a guest load/store for
921 * AArch32", where a vaddr is always 32 bits (and is zero
922 * extended if we're a 64 bit core) and data is also
923 * 32 bits unless specifically doing a 64 bit access.
924 * These functions work like tcg_gen_qemu_{ld,st}* except
925 * that the address argument is TCGv_i32 rather than TCGv.
927 #if TARGET_LONG_BITS == 32
929 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
930 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
931 TCGv_i32 addr, int index) \
933 TCGMemOp opc = (OPC) | s->be_data; \
934 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
935 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
936 TCGv addr_be = tcg_temp_new(); \
937 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
938 tcg_gen_qemu_ld_i32(val, addr_be, index, opc); \
939 tcg_temp_free(addr_be); \
940 return; \
942 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
945 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
946 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
947 TCGv_i32 addr, int index) \
949 TCGMemOp opc = (OPC) | s->be_data; \
950 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
951 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
952 TCGv addr_be = tcg_temp_new(); \
953 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
954 tcg_gen_qemu_st_i32(val, addr_be, index, opc); \
955 tcg_temp_free(addr_be); \
956 return; \
958 tcg_gen_qemu_st_i32(val, addr, index, opc); \
961 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
962 TCGv_i32 addr, int index)
964 TCGMemOp opc = MO_Q | s->be_data;
965 tcg_gen_qemu_ld_i64(val, addr, index, opc);
966 /* Not needed for user-mode BE32, where we use MO_BE instead. */
967 if (!IS_USER_ONLY && s->sctlr_b) {
968 tcg_gen_rotri_i64(val, val, 32);
972 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
973 TCGv_i32 addr, int index)
975 TCGMemOp opc = MO_Q | s->be_data;
976 /* Not needed for user-mode BE32, where we use MO_BE instead. */
977 if (!IS_USER_ONLY && s->sctlr_b) {
978 TCGv_i64 tmp = tcg_temp_new_i64();
979 tcg_gen_rotri_i64(tmp, val, 32);
980 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
981 tcg_temp_free_i64(tmp);
982 return;
984 tcg_gen_qemu_st_i64(val, addr, index, opc);
987 #else
989 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
990 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
991 TCGv_i32 addr, int index) \
993 TCGMemOp opc = (OPC) | s->be_data; \
994 TCGv addr64 = tcg_temp_new(); \
995 tcg_gen_extu_i32_i64(addr64, addr); \
996 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
997 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
998 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1000 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
1001 tcg_temp_free(addr64); \
1004 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
1005 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1006 TCGv_i32 addr, int index) \
1008 TCGMemOp opc = (OPC) | s->be_data; \
1009 TCGv addr64 = tcg_temp_new(); \
1010 tcg_gen_extu_i32_i64(addr64, addr); \
1011 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
1012 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1013 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1015 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
1016 tcg_temp_free(addr64); \
1019 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1020 TCGv_i32 addr, int index)
1022 TCGMemOp opc = MO_Q | s->be_data;
1023 TCGv addr64 = tcg_temp_new();
1024 tcg_gen_extu_i32_i64(addr64, addr);
1025 tcg_gen_qemu_ld_i64(val, addr64, index, opc);
1027 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1028 if (!IS_USER_ONLY && s->sctlr_b) {
1029 tcg_gen_rotri_i64(val, val, 32);
1031 tcg_temp_free(addr64);
1034 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1035 TCGv_i32 addr, int index)
1037 TCGMemOp opc = MO_Q | s->be_data;
1038 TCGv addr64 = tcg_temp_new();
1039 tcg_gen_extu_i32_i64(addr64, addr);
1041 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1042 if (!IS_USER_ONLY && s->sctlr_b) {
1043 TCGv tmp = tcg_temp_new();
1044 tcg_gen_rotri_i64(tmp, val, 32);
1045 tcg_gen_qemu_st_i64(tmp, addr64, index, opc);
1046 tcg_temp_free(tmp);
1047 } else {
1048 tcg_gen_qemu_st_i64(val, addr64, index, opc);
1050 tcg_temp_free(addr64);
1053 #endif
1055 DO_GEN_LD(8s, MO_SB, 3)
1056 DO_GEN_LD(8u, MO_UB, 3)
1057 DO_GEN_LD(16s, MO_SW, 2)
1058 DO_GEN_LD(16u, MO_UW, 2)
1059 DO_GEN_LD(32u, MO_UL, 0)
1060 /* 'a' variants include an alignment check */
1061 DO_GEN_LD(16ua, MO_UW | MO_ALIGN, 2)
1062 DO_GEN_LD(32ua, MO_UL | MO_ALIGN, 0)
1063 DO_GEN_ST(8, MO_UB, 3)
1064 DO_GEN_ST(16, MO_UW, 2)
1065 DO_GEN_ST(32, MO_UL, 0)
1067 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
1069 tcg_gen_movi_i32(cpu_R[15], val);
1072 static inline void gen_hvc(DisasContext *s, int imm16)
1074 /* The pre HVC helper handles cases when HVC gets trapped
1075 * as an undefined insn by runtime configuration (ie before
1076 * the insn really executes).
1078 gen_set_pc_im(s, s->pc - 4);
1079 gen_helper_pre_hvc(cpu_env);
1080 /* Otherwise we will treat this as a real exception which
1081 * happens after execution of the insn. (The distinction matters
1082 * for the PC value reported to the exception handler and also
1083 * for single stepping.)
1085 s->svc_imm = imm16;
1086 gen_set_pc_im(s, s->pc);
1087 s->is_jmp = DISAS_HVC;
1090 static inline void gen_smc(DisasContext *s)
1092 /* As with HVC, we may take an exception either before or after
1093 * the insn executes.
1095 TCGv_i32 tmp;
1097 gen_set_pc_im(s, s->pc - 4);
1098 tmp = tcg_const_i32(syn_aa32_smc());
1099 gen_helper_pre_smc(cpu_env, tmp);
1100 tcg_temp_free_i32(tmp);
1101 gen_set_pc_im(s, s->pc);
1102 s->is_jmp = DISAS_SMC;
1105 static inline void
1106 gen_set_condexec (DisasContext *s)
1108 if (s->condexec_mask) {
1109 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1110 TCGv_i32 tmp = tcg_temp_new_i32();
1111 tcg_gen_movi_i32(tmp, val);
1112 store_cpu_field(tmp, condexec_bits);
1116 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1118 gen_set_condexec(s);
1119 gen_set_pc_im(s, s->pc - offset);
1120 gen_exception_internal(excp);
1121 s->is_jmp = DISAS_JUMP;
1124 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1125 int syn, uint32_t target_el)
1127 gen_set_condexec(s);
1128 gen_set_pc_im(s, s->pc - offset);
1129 gen_exception(excp, syn, target_el);
1130 s->is_jmp = DISAS_JUMP;
1133 /* Force a TB lookup after an instruction that changes the CPU state. */
1134 static inline void gen_lookup_tb(DisasContext *s)
1136 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1137 s->is_jmp = DISAS_JUMP;
1140 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1141 TCGv_i32 var)
1143 int val, rm, shift, shiftop;
1144 TCGv_i32 offset;
1146 if (!(insn & (1 << 25))) {
1147 /* immediate */
1148 val = insn & 0xfff;
1149 if (!(insn & (1 << 23)))
1150 val = -val;
1151 if (val != 0)
1152 tcg_gen_addi_i32(var, var, val);
1153 } else {
1154 /* shift/register */
1155 rm = (insn) & 0xf;
1156 shift = (insn >> 7) & 0x1f;
1157 shiftop = (insn >> 5) & 3;
1158 offset = load_reg(s, rm);
1159 gen_arm_shift_im(offset, shiftop, shift, 0);
1160 if (!(insn & (1 << 23)))
1161 tcg_gen_sub_i32(var, var, offset);
1162 else
1163 tcg_gen_add_i32(var, var, offset);
1164 tcg_temp_free_i32(offset);
1168 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1169 int extra, TCGv_i32 var)
1171 int val, rm;
1172 TCGv_i32 offset;
1174 if (insn & (1 << 22)) {
1175 /* immediate */
1176 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1177 if (!(insn & (1 << 23)))
1178 val = -val;
1179 val += extra;
1180 if (val != 0)
1181 tcg_gen_addi_i32(var, var, val);
1182 } else {
1183 /* register */
1184 if (extra)
1185 tcg_gen_addi_i32(var, var, extra);
1186 rm = (insn) & 0xf;
1187 offset = load_reg(s, rm);
1188 if (!(insn & (1 << 23)))
1189 tcg_gen_sub_i32(var, var, offset);
1190 else
1191 tcg_gen_add_i32(var, var, offset);
1192 tcg_temp_free_i32(offset);
1196 static TCGv_ptr get_fpstatus_ptr(int neon)
1198 TCGv_ptr statusptr = tcg_temp_new_ptr();
1199 int offset;
1200 if (neon) {
1201 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1202 } else {
1203 offset = offsetof(CPUARMState, vfp.fp_status);
1205 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1206 return statusptr;
1209 #define VFP_OP2(name) \
1210 static inline void gen_vfp_##name(int dp) \
1212 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1213 if (dp) { \
1214 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1215 } else { \
1216 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1218 tcg_temp_free_ptr(fpst); \
1221 VFP_OP2(add)
1222 VFP_OP2(sub)
1223 VFP_OP2(mul)
1224 VFP_OP2(div)
1226 #undef VFP_OP2
1228 static inline void gen_vfp_F1_mul(int dp)
1230 /* Like gen_vfp_mul() but put result in F1 */
1231 TCGv_ptr fpst = get_fpstatus_ptr(0);
1232 if (dp) {
1233 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1234 } else {
1235 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1237 tcg_temp_free_ptr(fpst);
1240 static inline void gen_vfp_F1_neg(int dp)
1242 /* Like gen_vfp_neg() but put result in F1 */
1243 if (dp) {
1244 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1245 } else {
1246 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1250 static inline void gen_vfp_abs(int dp)
1252 if (dp)
1253 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1254 else
1255 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1258 static inline void gen_vfp_neg(int dp)
1260 if (dp)
1261 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1262 else
1263 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1266 static inline void gen_vfp_sqrt(int dp)
1268 if (dp)
1269 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1270 else
1271 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1274 static inline void gen_vfp_cmp(int dp)
1276 if (dp)
1277 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1278 else
1279 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1282 static inline void gen_vfp_cmpe(int dp)
1284 if (dp)
1285 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1286 else
1287 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1290 static inline void gen_vfp_F1_ld0(int dp)
1292 if (dp)
1293 tcg_gen_movi_i64(cpu_F1d, 0);
1294 else
1295 tcg_gen_movi_i32(cpu_F1s, 0);
1298 #define VFP_GEN_ITOF(name) \
1299 static inline void gen_vfp_##name(int dp, int neon) \
1301 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1302 if (dp) { \
1303 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1304 } else { \
1305 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1307 tcg_temp_free_ptr(statusptr); \
1310 VFP_GEN_ITOF(uito)
1311 VFP_GEN_ITOF(sito)
1312 #undef VFP_GEN_ITOF
1314 #define VFP_GEN_FTOI(name) \
1315 static inline void gen_vfp_##name(int dp, int neon) \
1317 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1318 if (dp) { \
1319 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1320 } else { \
1321 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1323 tcg_temp_free_ptr(statusptr); \
1326 VFP_GEN_FTOI(toui)
1327 VFP_GEN_FTOI(touiz)
1328 VFP_GEN_FTOI(tosi)
1329 VFP_GEN_FTOI(tosiz)
1330 #undef VFP_GEN_FTOI
1332 #define VFP_GEN_FIX(name, round) \
1333 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1335 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1336 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1337 if (dp) { \
1338 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1339 statusptr); \
1340 } else { \
1341 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1342 statusptr); \
1344 tcg_temp_free_i32(tmp_shift); \
1345 tcg_temp_free_ptr(statusptr); \
1347 VFP_GEN_FIX(tosh, _round_to_zero)
1348 VFP_GEN_FIX(tosl, _round_to_zero)
1349 VFP_GEN_FIX(touh, _round_to_zero)
1350 VFP_GEN_FIX(toul, _round_to_zero)
1351 VFP_GEN_FIX(shto, )
1352 VFP_GEN_FIX(slto, )
1353 VFP_GEN_FIX(uhto, )
1354 VFP_GEN_FIX(ulto, )
1355 #undef VFP_GEN_FIX
1357 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1359 if (dp) {
1360 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1361 } else {
1362 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1366 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1368 if (dp) {
1369 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1370 } else {
1371 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1375 static inline long
1376 vfp_reg_offset (int dp, int reg)
1378 if (dp)
1379 return offsetof(CPUARMState, vfp.regs[reg]);
1380 else if (reg & 1) {
1381 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1382 + offsetof(CPU_DoubleU, l.upper);
1383 } else {
1384 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1385 + offsetof(CPU_DoubleU, l.lower);
1389 /* Return the offset of a 32-bit piece of a NEON register.
1390 zero is the least significant end of the register. */
1391 static inline long
1392 neon_reg_offset (int reg, int n)
1394 int sreg;
1395 sreg = reg * 2 + n;
1396 return vfp_reg_offset(0, sreg);
1399 static TCGv_i32 neon_load_reg(int reg, int pass)
1401 TCGv_i32 tmp = tcg_temp_new_i32();
1402 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1403 return tmp;
1406 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1408 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1409 tcg_temp_free_i32(var);
1412 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1414 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1417 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1419 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1422 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1423 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1424 #define tcg_gen_st_f32 tcg_gen_st_i32
1425 #define tcg_gen_st_f64 tcg_gen_st_i64
1427 static inline void gen_mov_F0_vreg(int dp, int reg)
1429 if (dp)
1430 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1431 else
1432 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1435 static inline void gen_mov_F1_vreg(int dp, int reg)
1437 if (dp)
1438 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1439 else
1440 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1443 static inline void gen_mov_vreg_F0(int dp, int reg)
1445 if (dp)
1446 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1447 else
1448 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1451 #define ARM_CP_RW_BIT (1 << 20)
1453 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1455 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1458 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1460 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1463 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1465 TCGv_i32 var = tcg_temp_new_i32();
1466 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1467 return var;
1470 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1472 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1473 tcg_temp_free_i32(var);
1476 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1478 iwmmxt_store_reg(cpu_M0, rn);
1481 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1483 iwmmxt_load_reg(cpu_M0, rn);
1486 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1488 iwmmxt_load_reg(cpu_V1, rn);
1489 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1492 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1494 iwmmxt_load_reg(cpu_V1, rn);
1495 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1498 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1500 iwmmxt_load_reg(cpu_V1, rn);
1501 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1504 #define IWMMXT_OP(name) \
1505 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1507 iwmmxt_load_reg(cpu_V1, rn); \
1508 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1511 #define IWMMXT_OP_ENV(name) \
1512 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1514 iwmmxt_load_reg(cpu_V1, rn); \
1515 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1518 #define IWMMXT_OP_ENV_SIZE(name) \
1519 IWMMXT_OP_ENV(name##b) \
1520 IWMMXT_OP_ENV(name##w) \
1521 IWMMXT_OP_ENV(name##l)
1523 #define IWMMXT_OP_ENV1(name) \
1524 static inline void gen_op_iwmmxt_##name##_M0(void) \
1526 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1529 IWMMXT_OP(maddsq)
1530 IWMMXT_OP(madduq)
1531 IWMMXT_OP(sadb)
1532 IWMMXT_OP(sadw)
1533 IWMMXT_OP(mulslw)
1534 IWMMXT_OP(mulshw)
1535 IWMMXT_OP(mululw)
1536 IWMMXT_OP(muluhw)
1537 IWMMXT_OP(macsw)
1538 IWMMXT_OP(macuw)
1540 IWMMXT_OP_ENV_SIZE(unpackl)
1541 IWMMXT_OP_ENV_SIZE(unpackh)
1543 IWMMXT_OP_ENV1(unpacklub)
1544 IWMMXT_OP_ENV1(unpackluw)
1545 IWMMXT_OP_ENV1(unpacklul)
1546 IWMMXT_OP_ENV1(unpackhub)
1547 IWMMXT_OP_ENV1(unpackhuw)
1548 IWMMXT_OP_ENV1(unpackhul)
1549 IWMMXT_OP_ENV1(unpacklsb)
1550 IWMMXT_OP_ENV1(unpacklsw)
1551 IWMMXT_OP_ENV1(unpacklsl)
1552 IWMMXT_OP_ENV1(unpackhsb)
1553 IWMMXT_OP_ENV1(unpackhsw)
1554 IWMMXT_OP_ENV1(unpackhsl)
1556 IWMMXT_OP_ENV_SIZE(cmpeq)
1557 IWMMXT_OP_ENV_SIZE(cmpgtu)
1558 IWMMXT_OP_ENV_SIZE(cmpgts)
1560 IWMMXT_OP_ENV_SIZE(mins)
1561 IWMMXT_OP_ENV_SIZE(minu)
1562 IWMMXT_OP_ENV_SIZE(maxs)
1563 IWMMXT_OP_ENV_SIZE(maxu)
1565 IWMMXT_OP_ENV_SIZE(subn)
1566 IWMMXT_OP_ENV_SIZE(addn)
1567 IWMMXT_OP_ENV_SIZE(subu)
1568 IWMMXT_OP_ENV_SIZE(addu)
1569 IWMMXT_OP_ENV_SIZE(subs)
1570 IWMMXT_OP_ENV_SIZE(adds)
1572 IWMMXT_OP_ENV(avgb0)
1573 IWMMXT_OP_ENV(avgb1)
1574 IWMMXT_OP_ENV(avgw0)
1575 IWMMXT_OP_ENV(avgw1)
1577 IWMMXT_OP_ENV(packuw)
1578 IWMMXT_OP_ENV(packul)
1579 IWMMXT_OP_ENV(packuq)
1580 IWMMXT_OP_ENV(packsw)
1581 IWMMXT_OP_ENV(packsl)
1582 IWMMXT_OP_ENV(packsq)
1584 static void gen_op_iwmmxt_set_mup(void)
1586 TCGv_i32 tmp;
1587 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1588 tcg_gen_ori_i32(tmp, tmp, 2);
1589 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1592 static void gen_op_iwmmxt_set_cup(void)
1594 TCGv_i32 tmp;
1595 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1596 tcg_gen_ori_i32(tmp, tmp, 1);
1597 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1600 static void gen_op_iwmmxt_setpsr_nz(void)
1602 TCGv_i32 tmp = tcg_temp_new_i32();
1603 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1604 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1607 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1609 iwmmxt_load_reg(cpu_V1, rn);
1610 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1611 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1614 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1615 TCGv_i32 dest)
1617 int rd;
1618 uint32_t offset;
1619 TCGv_i32 tmp;
1621 rd = (insn >> 16) & 0xf;
1622 tmp = load_reg(s, rd);
1624 offset = (insn & 0xff) << ((insn >> 7) & 2);
1625 if (insn & (1 << 24)) {
1626 /* Pre indexed */
1627 if (insn & (1 << 23))
1628 tcg_gen_addi_i32(tmp, tmp, offset);
1629 else
1630 tcg_gen_addi_i32(tmp, tmp, -offset);
1631 tcg_gen_mov_i32(dest, tmp);
1632 if (insn & (1 << 21))
1633 store_reg(s, rd, tmp);
1634 else
1635 tcg_temp_free_i32(tmp);
1636 } else if (insn & (1 << 21)) {
1637 /* Post indexed */
1638 tcg_gen_mov_i32(dest, tmp);
1639 if (insn & (1 << 23))
1640 tcg_gen_addi_i32(tmp, tmp, offset);
1641 else
1642 tcg_gen_addi_i32(tmp, tmp, -offset);
1643 store_reg(s, rd, tmp);
1644 } else if (!(insn & (1 << 23)))
1645 return 1;
1646 return 0;
1649 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1651 int rd = (insn >> 0) & 0xf;
1652 TCGv_i32 tmp;
1654 if (insn & (1 << 8)) {
1655 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1656 return 1;
1657 } else {
1658 tmp = iwmmxt_load_creg(rd);
1660 } else {
1661 tmp = tcg_temp_new_i32();
1662 iwmmxt_load_reg(cpu_V0, rd);
1663 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1665 tcg_gen_andi_i32(tmp, tmp, mask);
1666 tcg_gen_mov_i32(dest, tmp);
1667 tcg_temp_free_i32(tmp);
1668 return 0;
1671 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1672 (ie. an undefined instruction). */
1673 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1675 int rd, wrd;
1676 int rdhi, rdlo, rd0, rd1, i;
1677 TCGv_i32 addr;
1678 TCGv_i32 tmp, tmp2, tmp3;
1680 if ((insn & 0x0e000e00) == 0x0c000000) {
1681 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1682 wrd = insn & 0xf;
1683 rdlo = (insn >> 12) & 0xf;
1684 rdhi = (insn >> 16) & 0xf;
1685 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1686 iwmmxt_load_reg(cpu_V0, wrd);
1687 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1688 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1689 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1690 } else { /* TMCRR */
1691 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1692 iwmmxt_store_reg(cpu_V0, wrd);
1693 gen_op_iwmmxt_set_mup();
1695 return 0;
1698 wrd = (insn >> 12) & 0xf;
1699 addr = tcg_temp_new_i32();
1700 if (gen_iwmmxt_address(s, insn, addr)) {
1701 tcg_temp_free_i32(addr);
1702 return 1;
1704 if (insn & ARM_CP_RW_BIT) {
1705 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1706 tmp = tcg_temp_new_i32();
1707 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1708 iwmmxt_store_creg(wrd, tmp);
1709 } else {
1710 i = 1;
1711 if (insn & (1 << 8)) {
1712 if (insn & (1 << 22)) { /* WLDRD */
1713 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1714 i = 0;
1715 } else { /* WLDRW wRd */
1716 tmp = tcg_temp_new_i32();
1717 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1719 } else {
1720 tmp = tcg_temp_new_i32();
1721 if (insn & (1 << 22)) { /* WLDRH */
1722 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1723 } else { /* WLDRB */
1724 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1727 if (i) {
1728 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1729 tcg_temp_free_i32(tmp);
1731 gen_op_iwmmxt_movq_wRn_M0(wrd);
1733 } else {
1734 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1735 tmp = iwmmxt_load_creg(wrd);
1736 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1737 } else {
1738 gen_op_iwmmxt_movq_M0_wRn(wrd);
1739 tmp = tcg_temp_new_i32();
1740 if (insn & (1 << 8)) {
1741 if (insn & (1 << 22)) { /* WSTRD */
1742 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1743 } else { /* WSTRW wRd */
1744 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1745 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1747 } else {
1748 if (insn & (1 << 22)) { /* WSTRH */
1749 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1750 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1751 } else { /* WSTRB */
1752 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1753 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1757 tcg_temp_free_i32(tmp);
1759 tcg_temp_free_i32(addr);
1760 return 0;
1763 if ((insn & 0x0f000000) != 0x0e000000)
1764 return 1;
1766 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1767 case 0x000: /* WOR */
1768 wrd = (insn >> 12) & 0xf;
1769 rd0 = (insn >> 0) & 0xf;
1770 rd1 = (insn >> 16) & 0xf;
1771 gen_op_iwmmxt_movq_M0_wRn(rd0);
1772 gen_op_iwmmxt_orq_M0_wRn(rd1);
1773 gen_op_iwmmxt_setpsr_nz();
1774 gen_op_iwmmxt_movq_wRn_M0(wrd);
1775 gen_op_iwmmxt_set_mup();
1776 gen_op_iwmmxt_set_cup();
1777 break;
1778 case 0x011: /* TMCR */
1779 if (insn & 0xf)
1780 return 1;
1781 rd = (insn >> 12) & 0xf;
1782 wrd = (insn >> 16) & 0xf;
1783 switch (wrd) {
1784 case ARM_IWMMXT_wCID:
1785 case ARM_IWMMXT_wCASF:
1786 break;
1787 case ARM_IWMMXT_wCon:
1788 gen_op_iwmmxt_set_cup();
1789 /* Fall through. */
1790 case ARM_IWMMXT_wCSSF:
1791 tmp = iwmmxt_load_creg(wrd);
1792 tmp2 = load_reg(s, rd);
1793 tcg_gen_andc_i32(tmp, tmp, tmp2);
1794 tcg_temp_free_i32(tmp2);
1795 iwmmxt_store_creg(wrd, tmp);
1796 break;
1797 case ARM_IWMMXT_wCGR0:
1798 case ARM_IWMMXT_wCGR1:
1799 case ARM_IWMMXT_wCGR2:
1800 case ARM_IWMMXT_wCGR3:
1801 gen_op_iwmmxt_set_cup();
1802 tmp = load_reg(s, rd);
1803 iwmmxt_store_creg(wrd, tmp);
1804 break;
1805 default:
1806 return 1;
1808 break;
1809 case 0x100: /* WXOR */
1810 wrd = (insn >> 12) & 0xf;
1811 rd0 = (insn >> 0) & 0xf;
1812 rd1 = (insn >> 16) & 0xf;
1813 gen_op_iwmmxt_movq_M0_wRn(rd0);
1814 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1815 gen_op_iwmmxt_setpsr_nz();
1816 gen_op_iwmmxt_movq_wRn_M0(wrd);
1817 gen_op_iwmmxt_set_mup();
1818 gen_op_iwmmxt_set_cup();
1819 break;
1820 case 0x111: /* TMRC */
1821 if (insn & 0xf)
1822 return 1;
1823 rd = (insn >> 12) & 0xf;
1824 wrd = (insn >> 16) & 0xf;
1825 tmp = iwmmxt_load_creg(wrd);
1826 store_reg(s, rd, tmp);
1827 break;
1828 case 0x300: /* WANDN */
1829 wrd = (insn >> 12) & 0xf;
1830 rd0 = (insn >> 0) & 0xf;
1831 rd1 = (insn >> 16) & 0xf;
1832 gen_op_iwmmxt_movq_M0_wRn(rd0);
1833 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1834 gen_op_iwmmxt_andq_M0_wRn(rd1);
1835 gen_op_iwmmxt_setpsr_nz();
1836 gen_op_iwmmxt_movq_wRn_M0(wrd);
1837 gen_op_iwmmxt_set_mup();
1838 gen_op_iwmmxt_set_cup();
1839 break;
1840 case 0x200: /* WAND */
1841 wrd = (insn >> 12) & 0xf;
1842 rd0 = (insn >> 0) & 0xf;
1843 rd1 = (insn >> 16) & 0xf;
1844 gen_op_iwmmxt_movq_M0_wRn(rd0);
1845 gen_op_iwmmxt_andq_M0_wRn(rd1);
1846 gen_op_iwmmxt_setpsr_nz();
1847 gen_op_iwmmxt_movq_wRn_M0(wrd);
1848 gen_op_iwmmxt_set_mup();
1849 gen_op_iwmmxt_set_cup();
1850 break;
1851 case 0x810: case 0xa10: /* WMADD */
1852 wrd = (insn >> 12) & 0xf;
1853 rd0 = (insn >> 0) & 0xf;
1854 rd1 = (insn >> 16) & 0xf;
1855 gen_op_iwmmxt_movq_M0_wRn(rd0);
1856 if (insn & (1 << 21))
1857 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1858 else
1859 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1860 gen_op_iwmmxt_movq_wRn_M0(wrd);
1861 gen_op_iwmmxt_set_mup();
1862 break;
1863 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1864 wrd = (insn >> 12) & 0xf;
1865 rd0 = (insn >> 16) & 0xf;
1866 rd1 = (insn >> 0) & 0xf;
1867 gen_op_iwmmxt_movq_M0_wRn(rd0);
1868 switch ((insn >> 22) & 3) {
1869 case 0:
1870 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1871 break;
1872 case 1:
1873 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1874 break;
1875 case 2:
1876 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1877 break;
1878 case 3:
1879 return 1;
1881 gen_op_iwmmxt_movq_wRn_M0(wrd);
1882 gen_op_iwmmxt_set_mup();
1883 gen_op_iwmmxt_set_cup();
1884 break;
1885 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1886 wrd = (insn >> 12) & 0xf;
1887 rd0 = (insn >> 16) & 0xf;
1888 rd1 = (insn >> 0) & 0xf;
1889 gen_op_iwmmxt_movq_M0_wRn(rd0);
1890 switch ((insn >> 22) & 3) {
1891 case 0:
1892 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1893 break;
1894 case 1:
1895 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1896 break;
1897 case 2:
1898 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1899 break;
1900 case 3:
1901 return 1;
1903 gen_op_iwmmxt_movq_wRn_M0(wrd);
1904 gen_op_iwmmxt_set_mup();
1905 gen_op_iwmmxt_set_cup();
1906 break;
1907 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1908 wrd = (insn >> 12) & 0xf;
1909 rd0 = (insn >> 16) & 0xf;
1910 rd1 = (insn >> 0) & 0xf;
1911 gen_op_iwmmxt_movq_M0_wRn(rd0);
1912 if (insn & (1 << 22))
1913 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1914 else
1915 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1916 if (!(insn & (1 << 20)))
1917 gen_op_iwmmxt_addl_M0_wRn(wrd);
1918 gen_op_iwmmxt_movq_wRn_M0(wrd);
1919 gen_op_iwmmxt_set_mup();
1920 break;
1921 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1922 wrd = (insn >> 12) & 0xf;
1923 rd0 = (insn >> 16) & 0xf;
1924 rd1 = (insn >> 0) & 0xf;
1925 gen_op_iwmmxt_movq_M0_wRn(rd0);
1926 if (insn & (1 << 21)) {
1927 if (insn & (1 << 20))
1928 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1929 else
1930 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1931 } else {
1932 if (insn & (1 << 20))
1933 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1934 else
1935 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd);
1938 gen_op_iwmmxt_set_mup();
1939 break;
1940 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1941 wrd = (insn >> 12) & 0xf;
1942 rd0 = (insn >> 16) & 0xf;
1943 rd1 = (insn >> 0) & 0xf;
1944 gen_op_iwmmxt_movq_M0_wRn(rd0);
1945 if (insn & (1 << 21))
1946 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1947 else
1948 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1949 if (!(insn & (1 << 20))) {
1950 iwmmxt_load_reg(cpu_V1, wrd);
1951 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1953 gen_op_iwmmxt_movq_wRn_M0(wrd);
1954 gen_op_iwmmxt_set_mup();
1955 break;
1956 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1957 wrd = (insn >> 12) & 0xf;
1958 rd0 = (insn >> 16) & 0xf;
1959 rd1 = (insn >> 0) & 0xf;
1960 gen_op_iwmmxt_movq_M0_wRn(rd0);
1961 switch ((insn >> 22) & 3) {
1962 case 0:
1963 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1964 break;
1965 case 1:
1966 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1967 break;
1968 case 2:
1969 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1970 break;
1971 case 3:
1972 return 1;
1974 gen_op_iwmmxt_movq_wRn_M0(wrd);
1975 gen_op_iwmmxt_set_mup();
1976 gen_op_iwmmxt_set_cup();
1977 break;
1978 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1979 wrd = (insn >> 12) & 0xf;
1980 rd0 = (insn >> 16) & 0xf;
1981 rd1 = (insn >> 0) & 0xf;
1982 gen_op_iwmmxt_movq_M0_wRn(rd0);
1983 if (insn & (1 << 22)) {
1984 if (insn & (1 << 20))
1985 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1986 else
1987 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1988 } else {
1989 if (insn & (1 << 20))
1990 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1991 else
1992 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1994 gen_op_iwmmxt_movq_wRn_M0(wrd);
1995 gen_op_iwmmxt_set_mup();
1996 gen_op_iwmmxt_set_cup();
1997 break;
1998 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1999 wrd = (insn >> 12) & 0xf;
2000 rd0 = (insn >> 16) & 0xf;
2001 rd1 = (insn >> 0) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0);
2003 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2004 tcg_gen_andi_i32(tmp, tmp, 7);
2005 iwmmxt_load_reg(cpu_V1, rd1);
2006 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2007 tcg_temp_free_i32(tmp);
2008 gen_op_iwmmxt_movq_wRn_M0(wrd);
2009 gen_op_iwmmxt_set_mup();
2010 break;
2011 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2012 if (((insn >> 6) & 3) == 3)
2013 return 1;
2014 rd = (insn >> 12) & 0xf;
2015 wrd = (insn >> 16) & 0xf;
2016 tmp = load_reg(s, rd);
2017 gen_op_iwmmxt_movq_M0_wRn(wrd);
2018 switch ((insn >> 6) & 3) {
2019 case 0:
2020 tmp2 = tcg_const_i32(0xff);
2021 tmp3 = tcg_const_i32((insn & 7) << 3);
2022 break;
2023 case 1:
2024 tmp2 = tcg_const_i32(0xffff);
2025 tmp3 = tcg_const_i32((insn & 3) << 4);
2026 break;
2027 case 2:
2028 tmp2 = tcg_const_i32(0xffffffff);
2029 tmp3 = tcg_const_i32((insn & 1) << 5);
2030 break;
2031 default:
2032 TCGV_UNUSED_I32(tmp2);
2033 TCGV_UNUSED_I32(tmp3);
2035 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2036 tcg_temp_free_i32(tmp3);
2037 tcg_temp_free_i32(tmp2);
2038 tcg_temp_free_i32(tmp);
2039 gen_op_iwmmxt_movq_wRn_M0(wrd);
2040 gen_op_iwmmxt_set_mup();
2041 break;
2042 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2043 rd = (insn >> 12) & 0xf;
2044 wrd = (insn >> 16) & 0xf;
2045 if (rd == 15 || ((insn >> 22) & 3) == 3)
2046 return 1;
2047 gen_op_iwmmxt_movq_M0_wRn(wrd);
2048 tmp = tcg_temp_new_i32();
2049 switch ((insn >> 22) & 3) {
2050 case 0:
2051 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2052 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2053 if (insn & 8) {
2054 tcg_gen_ext8s_i32(tmp, tmp);
2055 } else {
2056 tcg_gen_andi_i32(tmp, tmp, 0xff);
2058 break;
2059 case 1:
2060 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2061 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2062 if (insn & 8) {
2063 tcg_gen_ext16s_i32(tmp, tmp);
2064 } else {
2065 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2067 break;
2068 case 2:
2069 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2070 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2071 break;
2073 store_reg(s, rd, tmp);
2074 break;
2075 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2076 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2077 return 1;
2078 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2079 switch ((insn >> 22) & 3) {
2080 case 0:
2081 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2082 break;
2083 case 1:
2084 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2085 break;
2086 case 2:
2087 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2088 break;
2090 tcg_gen_shli_i32(tmp, tmp, 28);
2091 gen_set_nzcv(tmp);
2092 tcg_temp_free_i32(tmp);
2093 break;
2094 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2095 if (((insn >> 6) & 3) == 3)
2096 return 1;
2097 rd = (insn >> 12) & 0xf;
2098 wrd = (insn >> 16) & 0xf;
2099 tmp = load_reg(s, rd);
2100 switch ((insn >> 6) & 3) {
2101 case 0:
2102 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2103 break;
2104 case 1:
2105 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2106 break;
2107 case 2:
2108 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2109 break;
2111 tcg_temp_free_i32(tmp);
2112 gen_op_iwmmxt_movq_wRn_M0(wrd);
2113 gen_op_iwmmxt_set_mup();
2114 break;
2115 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2116 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2117 return 1;
2118 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2119 tmp2 = tcg_temp_new_i32();
2120 tcg_gen_mov_i32(tmp2, tmp);
2121 switch ((insn >> 22) & 3) {
2122 case 0:
2123 for (i = 0; i < 7; i ++) {
2124 tcg_gen_shli_i32(tmp2, tmp2, 4);
2125 tcg_gen_and_i32(tmp, tmp, tmp2);
2127 break;
2128 case 1:
2129 for (i = 0; i < 3; i ++) {
2130 tcg_gen_shli_i32(tmp2, tmp2, 8);
2131 tcg_gen_and_i32(tmp, tmp, tmp2);
2133 break;
2134 case 2:
2135 tcg_gen_shli_i32(tmp2, tmp2, 16);
2136 tcg_gen_and_i32(tmp, tmp, tmp2);
2137 break;
2139 gen_set_nzcv(tmp);
2140 tcg_temp_free_i32(tmp2);
2141 tcg_temp_free_i32(tmp);
2142 break;
2143 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2144 wrd = (insn >> 12) & 0xf;
2145 rd0 = (insn >> 16) & 0xf;
2146 gen_op_iwmmxt_movq_M0_wRn(rd0);
2147 switch ((insn >> 22) & 3) {
2148 case 0:
2149 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2150 break;
2151 case 1:
2152 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2153 break;
2154 case 2:
2155 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2156 break;
2157 case 3:
2158 return 1;
2160 gen_op_iwmmxt_movq_wRn_M0(wrd);
2161 gen_op_iwmmxt_set_mup();
2162 break;
2163 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2164 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2165 return 1;
2166 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2167 tmp2 = tcg_temp_new_i32();
2168 tcg_gen_mov_i32(tmp2, tmp);
2169 switch ((insn >> 22) & 3) {
2170 case 0:
2171 for (i = 0; i < 7; i ++) {
2172 tcg_gen_shli_i32(tmp2, tmp2, 4);
2173 tcg_gen_or_i32(tmp, tmp, tmp2);
2175 break;
2176 case 1:
2177 for (i = 0; i < 3; i ++) {
2178 tcg_gen_shli_i32(tmp2, tmp2, 8);
2179 tcg_gen_or_i32(tmp, tmp, tmp2);
2181 break;
2182 case 2:
2183 tcg_gen_shli_i32(tmp2, tmp2, 16);
2184 tcg_gen_or_i32(tmp, tmp, tmp2);
2185 break;
2187 gen_set_nzcv(tmp);
2188 tcg_temp_free_i32(tmp2);
2189 tcg_temp_free_i32(tmp);
2190 break;
2191 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2192 rd = (insn >> 12) & 0xf;
2193 rd0 = (insn >> 16) & 0xf;
2194 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2195 return 1;
2196 gen_op_iwmmxt_movq_M0_wRn(rd0);
2197 tmp = tcg_temp_new_i32();
2198 switch ((insn >> 22) & 3) {
2199 case 0:
2200 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2201 break;
2202 case 1:
2203 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2204 break;
2205 case 2:
2206 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2207 break;
2209 store_reg(s, rd, tmp);
2210 break;
2211 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2212 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2213 wrd = (insn >> 12) & 0xf;
2214 rd0 = (insn >> 16) & 0xf;
2215 rd1 = (insn >> 0) & 0xf;
2216 gen_op_iwmmxt_movq_M0_wRn(rd0);
2217 switch ((insn >> 22) & 3) {
2218 case 0:
2219 if (insn & (1 << 21))
2220 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2221 else
2222 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2223 break;
2224 case 1:
2225 if (insn & (1 << 21))
2226 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2227 else
2228 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2229 break;
2230 case 2:
2231 if (insn & (1 << 21))
2232 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2233 else
2234 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2235 break;
2236 case 3:
2237 return 1;
2239 gen_op_iwmmxt_movq_wRn_M0(wrd);
2240 gen_op_iwmmxt_set_mup();
2241 gen_op_iwmmxt_set_cup();
2242 break;
2243 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2244 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2245 wrd = (insn >> 12) & 0xf;
2246 rd0 = (insn >> 16) & 0xf;
2247 gen_op_iwmmxt_movq_M0_wRn(rd0);
2248 switch ((insn >> 22) & 3) {
2249 case 0:
2250 if (insn & (1 << 21))
2251 gen_op_iwmmxt_unpacklsb_M0();
2252 else
2253 gen_op_iwmmxt_unpacklub_M0();
2254 break;
2255 case 1:
2256 if (insn & (1 << 21))
2257 gen_op_iwmmxt_unpacklsw_M0();
2258 else
2259 gen_op_iwmmxt_unpackluw_M0();
2260 break;
2261 case 2:
2262 if (insn & (1 << 21))
2263 gen_op_iwmmxt_unpacklsl_M0();
2264 else
2265 gen_op_iwmmxt_unpacklul_M0();
2266 break;
2267 case 3:
2268 return 1;
2270 gen_op_iwmmxt_movq_wRn_M0(wrd);
2271 gen_op_iwmmxt_set_mup();
2272 gen_op_iwmmxt_set_cup();
2273 break;
2274 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2275 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2276 wrd = (insn >> 12) & 0xf;
2277 rd0 = (insn >> 16) & 0xf;
2278 gen_op_iwmmxt_movq_M0_wRn(rd0);
2279 switch ((insn >> 22) & 3) {
2280 case 0:
2281 if (insn & (1 << 21))
2282 gen_op_iwmmxt_unpackhsb_M0();
2283 else
2284 gen_op_iwmmxt_unpackhub_M0();
2285 break;
2286 case 1:
2287 if (insn & (1 << 21))
2288 gen_op_iwmmxt_unpackhsw_M0();
2289 else
2290 gen_op_iwmmxt_unpackhuw_M0();
2291 break;
2292 case 2:
2293 if (insn & (1 << 21))
2294 gen_op_iwmmxt_unpackhsl_M0();
2295 else
2296 gen_op_iwmmxt_unpackhul_M0();
2297 break;
2298 case 3:
2299 return 1;
2301 gen_op_iwmmxt_movq_wRn_M0(wrd);
2302 gen_op_iwmmxt_set_mup();
2303 gen_op_iwmmxt_set_cup();
2304 break;
2305 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2306 case 0x214: case 0x614: case 0xa14: case 0xe14:
2307 if (((insn >> 22) & 3) == 0)
2308 return 1;
2309 wrd = (insn >> 12) & 0xf;
2310 rd0 = (insn >> 16) & 0xf;
2311 gen_op_iwmmxt_movq_M0_wRn(rd0);
2312 tmp = tcg_temp_new_i32();
2313 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2314 tcg_temp_free_i32(tmp);
2315 return 1;
2317 switch ((insn >> 22) & 3) {
2318 case 1:
2319 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2320 break;
2321 case 2:
2322 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2323 break;
2324 case 3:
2325 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2326 break;
2328 tcg_temp_free_i32(tmp);
2329 gen_op_iwmmxt_movq_wRn_M0(wrd);
2330 gen_op_iwmmxt_set_mup();
2331 gen_op_iwmmxt_set_cup();
2332 break;
2333 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2334 case 0x014: case 0x414: case 0x814: case 0xc14:
2335 if (((insn >> 22) & 3) == 0)
2336 return 1;
2337 wrd = (insn >> 12) & 0xf;
2338 rd0 = (insn >> 16) & 0xf;
2339 gen_op_iwmmxt_movq_M0_wRn(rd0);
2340 tmp = tcg_temp_new_i32();
2341 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2342 tcg_temp_free_i32(tmp);
2343 return 1;
2345 switch ((insn >> 22) & 3) {
2346 case 1:
2347 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2348 break;
2349 case 2:
2350 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2351 break;
2352 case 3:
2353 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2354 break;
2356 tcg_temp_free_i32(tmp);
2357 gen_op_iwmmxt_movq_wRn_M0(wrd);
2358 gen_op_iwmmxt_set_mup();
2359 gen_op_iwmmxt_set_cup();
2360 break;
2361 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2362 case 0x114: case 0x514: case 0x914: case 0xd14:
2363 if (((insn >> 22) & 3) == 0)
2364 return 1;
2365 wrd = (insn >> 12) & 0xf;
2366 rd0 = (insn >> 16) & 0xf;
2367 gen_op_iwmmxt_movq_M0_wRn(rd0);
2368 tmp = tcg_temp_new_i32();
2369 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2370 tcg_temp_free_i32(tmp);
2371 return 1;
2373 switch ((insn >> 22) & 3) {
2374 case 1:
2375 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2376 break;
2377 case 2:
2378 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2379 break;
2380 case 3:
2381 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2382 break;
2384 tcg_temp_free_i32(tmp);
2385 gen_op_iwmmxt_movq_wRn_M0(wrd);
2386 gen_op_iwmmxt_set_mup();
2387 gen_op_iwmmxt_set_cup();
2388 break;
2389 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2390 case 0x314: case 0x714: case 0xb14: case 0xf14:
2391 if (((insn >> 22) & 3) == 0)
2392 return 1;
2393 wrd = (insn >> 12) & 0xf;
2394 rd0 = (insn >> 16) & 0xf;
2395 gen_op_iwmmxt_movq_M0_wRn(rd0);
2396 tmp = tcg_temp_new_i32();
2397 switch ((insn >> 22) & 3) {
2398 case 1:
2399 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2400 tcg_temp_free_i32(tmp);
2401 return 1;
2403 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2404 break;
2405 case 2:
2406 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2407 tcg_temp_free_i32(tmp);
2408 return 1;
2410 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2411 break;
2412 case 3:
2413 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2414 tcg_temp_free_i32(tmp);
2415 return 1;
2417 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2418 break;
2420 tcg_temp_free_i32(tmp);
2421 gen_op_iwmmxt_movq_wRn_M0(wrd);
2422 gen_op_iwmmxt_set_mup();
2423 gen_op_iwmmxt_set_cup();
2424 break;
2425 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2426 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2427 wrd = (insn >> 12) & 0xf;
2428 rd0 = (insn >> 16) & 0xf;
2429 rd1 = (insn >> 0) & 0xf;
2430 gen_op_iwmmxt_movq_M0_wRn(rd0);
2431 switch ((insn >> 22) & 3) {
2432 case 0:
2433 if (insn & (1 << 21))
2434 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2435 else
2436 gen_op_iwmmxt_minub_M0_wRn(rd1);
2437 break;
2438 case 1:
2439 if (insn & (1 << 21))
2440 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2441 else
2442 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2443 break;
2444 case 2:
2445 if (insn & (1 << 21))
2446 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2447 else
2448 gen_op_iwmmxt_minul_M0_wRn(rd1);
2449 break;
2450 case 3:
2451 return 1;
2453 gen_op_iwmmxt_movq_wRn_M0(wrd);
2454 gen_op_iwmmxt_set_mup();
2455 break;
2456 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2457 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2458 wrd = (insn >> 12) & 0xf;
2459 rd0 = (insn >> 16) & 0xf;
2460 rd1 = (insn >> 0) & 0xf;
2461 gen_op_iwmmxt_movq_M0_wRn(rd0);
2462 switch ((insn >> 22) & 3) {
2463 case 0:
2464 if (insn & (1 << 21))
2465 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2466 else
2467 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2468 break;
2469 case 1:
2470 if (insn & (1 << 21))
2471 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2472 else
2473 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2474 break;
2475 case 2:
2476 if (insn & (1 << 21))
2477 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2478 else
2479 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2480 break;
2481 case 3:
2482 return 1;
2484 gen_op_iwmmxt_movq_wRn_M0(wrd);
2485 gen_op_iwmmxt_set_mup();
2486 break;
2487 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2488 case 0x402: case 0x502: case 0x602: case 0x702:
2489 wrd = (insn >> 12) & 0xf;
2490 rd0 = (insn >> 16) & 0xf;
2491 rd1 = (insn >> 0) & 0xf;
2492 gen_op_iwmmxt_movq_M0_wRn(rd0);
2493 tmp = tcg_const_i32((insn >> 20) & 3);
2494 iwmmxt_load_reg(cpu_V1, rd1);
2495 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2496 tcg_temp_free_i32(tmp);
2497 gen_op_iwmmxt_movq_wRn_M0(wrd);
2498 gen_op_iwmmxt_set_mup();
2499 break;
2500 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2501 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2502 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2503 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2504 wrd = (insn >> 12) & 0xf;
2505 rd0 = (insn >> 16) & 0xf;
2506 rd1 = (insn >> 0) & 0xf;
2507 gen_op_iwmmxt_movq_M0_wRn(rd0);
2508 switch ((insn >> 20) & 0xf) {
2509 case 0x0:
2510 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2511 break;
2512 case 0x1:
2513 gen_op_iwmmxt_subub_M0_wRn(rd1);
2514 break;
2515 case 0x3:
2516 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2517 break;
2518 case 0x4:
2519 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2520 break;
2521 case 0x5:
2522 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2523 break;
2524 case 0x7:
2525 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2526 break;
2527 case 0x8:
2528 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2529 break;
2530 case 0x9:
2531 gen_op_iwmmxt_subul_M0_wRn(rd1);
2532 break;
2533 case 0xb:
2534 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2535 break;
2536 default:
2537 return 1;
2539 gen_op_iwmmxt_movq_wRn_M0(wrd);
2540 gen_op_iwmmxt_set_mup();
2541 gen_op_iwmmxt_set_cup();
2542 break;
2543 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2544 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2545 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2546 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2547 wrd = (insn >> 12) & 0xf;
2548 rd0 = (insn >> 16) & 0xf;
2549 gen_op_iwmmxt_movq_M0_wRn(rd0);
2550 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2551 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2552 tcg_temp_free_i32(tmp);
2553 gen_op_iwmmxt_movq_wRn_M0(wrd);
2554 gen_op_iwmmxt_set_mup();
2555 gen_op_iwmmxt_set_cup();
2556 break;
2557 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2558 case 0x418: case 0x518: case 0x618: case 0x718:
2559 case 0x818: case 0x918: case 0xa18: case 0xb18:
2560 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2561 wrd = (insn >> 12) & 0xf;
2562 rd0 = (insn >> 16) & 0xf;
2563 rd1 = (insn >> 0) & 0xf;
2564 gen_op_iwmmxt_movq_M0_wRn(rd0);
2565 switch ((insn >> 20) & 0xf) {
2566 case 0x0:
2567 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2568 break;
2569 case 0x1:
2570 gen_op_iwmmxt_addub_M0_wRn(rd1);
2571 break;
2572 case 0x3:
2573 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2574 break;
2575 case 0x4:
2576 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2577 break;
2578 case 0x5:
2579 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2580 break;
2581 case 0x7:
2582 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2583 break;
2584 case 0x8:
2585 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2586 break;
2587 case 0x9:
2588 gen_op_iwmmxt_addul_M0_wRn(rd1);
2589 break;
2590 case 0xb:
2591 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2592 break;
2593 default:
2594 return 1;
2596 gen_op_iwmmxt_movq_wRn_M0(wrd);
2597 gen_op_iwmmxt_set_mup();
2598 gen_op_iwmmxt_set_cup();
2599 break;
2600 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2601 case 0x408: case 0x508: case 0x608: case 0x708:
2602 case 0x808: case 0x908: case 0xa08: case 0xb08:
2603 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2604 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2605 return 1;
2606 wrd = (insn >> 12) & 0xf;
2607 rd0 = (insn >> 16) & 0xf;
2608 rd1 = (insn >> 0) & 0xf;
2609 gen_op_iwmmxt_movq_M0_wRn(rd0);
2610 switch ((insn >> 22) & 3) {
2611 case 1:
2612 if (insn & (1 << 21))
2613 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2614 else
2615 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2616 break;
2617 case 2:
2618 if (insn & (1 << 21))
2619 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2620 else
2621 gen_op_iwmmxt_packul_M0_wRn(rd1);
2622 break;
2623 case 3:
2624 if (insn & (1 << 21))
2625 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2626 else
2627 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2628 break;
2630 gen_op_iwmmxt_movq_wRn_M0(wrd);
2631 gen_op_iwmmxt_set_mup();
2632 gen_op_iwmmxt_set_cup();
2633 break;
2634 case 0x201: case 0x203: case 0x205: case 0x207:
2635 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2636 case 0x211: case 0x213: case 0x215: case 0x217:
2637 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2638 wrd = (insn >> 5) & 0xf;
2639 rd0 = (insn >> 12) & 0xf;
2640 rd1 = (insn >> 0) & 0xf;
2641 if (rd0 == 0xf || rd1 == 0xf)
2642 return 1;
2643 gen_op_iwmmxt_movq_M0_wRn(wrd);
2644 tmp = load_reg(s, rd0);
2645 tmp2 = load_reg(s, rd1);
2646 switch ((insn >> 16) & 0xf) {
2647 case 0x0: /* TMIA */
2648 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2649 break;
2650 case 0x8: /* TMIAPH */
2651 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2652 break;
2653 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2654 if (insn & (1 << 16))
2655 tcg_gen_shri_i32(tmp, tmp, 16);
2656 if (insn & (1 << 17))
2657 tcg_gen_shri_i32(tmp2, tmp2, 16);
2658 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2659 break;
2660 default:
2661 tcg_temp_free_i32(tmp2);
2662 tcg_temp_free_i32(tmp);
2663 return 1;
2665 tcg_temp_free_i32(tmp2);
2666 tcg_temp_free_i32(tmp);
2667 gen_op_iwmmxt_movq_wRn_M0(wrd);
2668 gen_op_iwmmxt_set_mup();
2669 break;
2670 default:
2671 return 1;
2674 return 0;
2677 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2678 (ie. an undefined instruction). */
2679 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2681 int acc, rd0, rd1, rdhi, rdlo;
2682 TCGv_i32 tmp, tmp2;
2684 if ((insn & 0x0ff00f10) == 0x0e200010) {
2685 /* Multiply with Internal Accumulate Format */
2686 rd0 = (insn >> 12) & 0xf;
2687 rd1 = insn & 0xf;
2688 acc = (insn >> 5) & 7;
2690 if (acc != 0)
2691 return 1;
2693 tmp = load_reg(s, rd0);
2694 tmp2 = load_reg(s, rd1);
2695 switch ((insn >> 16) & 0xf) {
2696 case 0x0: /* MIA */
2697 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2698 break;
2699 case 0x8: /* MIAPH */
2700 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2701 break;
2702 case 0xc: /* MIABB */
2703 case 0xd: /* MIABT */
2704 case 0xe: /* MIATB */
2705 case 0xf: /* MIATT */
2706 if (insn & (1 << 16))
2707 tcg_gen_shri_i32(tmp, tmp, 16);
2708 if (insn & (1 << 17))
2709 tcg_gen_shri_i32(tmp2, tmp2, 16);
2710 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2711 break;
2712 default:
2713 return 1;
2715 tcg_temp_free_i32(tmp2);
2716 tcg_temp_free_i32(tmp);
2718 gen_op_iwmmxt_movq_wRn_M0(acc);
2719 return 0;
2722 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2723 /* Internal Accumulator Access Format */
2724 rdhi = (insn >> 16) & 0xf;
2725 rdlo = (insn >> 12) & 0xf;
2726 acc = insn & 7;
2728 if (acc != 0)
2729 return 1;
2731 if (insn & ARM_CP_RW_BIT) { /* MRA */
2732 iwmmxt_load_reg(cpu_V0, acc);
2733 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2734 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2735 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2736 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2737 } else { /* MAR */
2738 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2739 iwmmxt_store_reg(cpu_V0, acc);
2741 return 0;
2744 return 1;
2747 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2748 #define VFP_SREG(insn, bigbit, smallbit) \
2749 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2750 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2751 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2752 reg = (((insn) >> (bigbit)) & 0x0f) \
2753 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2754 } else { \
2755 if (insn & (1 << (smallbit))) \
2756 return 1; \
2757 reg = ((insn) >> (bigbit)) & 0x0f; \
2758 }} while (0)
2760 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2761 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2762 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2763 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2764 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2765 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2767 /* Move between integer and VFP cores. */
2768 static TCGv_i32 gen_vfp_mrs(void)
2770 TCGv_i32 tmp = tcg_temp_new_i32();
2771 tcg_gen_mov_i32(tmp, cpu_F0s);
2772 return tmp;
2775 static void gen_vfp_msr(TCGv_i32 tmp)
2777 tcg_gen_mov_i32(cpu_F0s, tmp);
2778 tcg_temp_free_i32(tmp);
2781 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2783 TCGv_i32 tmp = tcg_temp_new_i32();
2784 if (shift)
2785 tcg_gen_shri_i32(var, var, shift);
2786 tcg_gen_ext8u_i32(var, var);
2787 tcg_gen_shli_i32(tmp, var, 8);
2788 tcg_gen_or_i32(var, var, tmp);
2789 tcg_gen_shli_i32(tmp, var, 16);
2790 tcg_gen_or_i32(var, var, tmp);
2791 tcg_temp_free_i32(tmp);
2794 static void gen_neon_dup_low16(TCGv_i32 var)
2796 TCGv_i32 tmp = tcg_temp_new_i32();
2797 tcg_gen_ext16u_i32(var, var);
2798 tcg_gen_shli_i32(tmp, var, 16);
2799 tcg_gen_or_i32(var, var, tmp);
2800 tcg_temp_free_i32(tmp);
2803 static void gen_neon_dup_high16(TCGv_i32 var)
2805 TCGv_i32 tmp = tcg_temp_new_i32();
2806 tcg_gen_andi_i32(var, var, 0xffff0000);
2807 tcg_gen_shri_i32(tmp, var, 16);
2808 tcg_gen_or_i32(var, var, tmp);
2809 tcg_temp_free_i32(tmp);
2812 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2814 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2815 TCGv_i32 tmp = tcg_temp_new_i32();
2816 switch (size) {
2817 case 0:
2818 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2819 gen_neon_dup_u8(tmp, 0);
2820 break;
2821 case 1:
2822 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2823 gen_neon_dup_low16(tmp);
2824 break;
2825 case 2:
2826 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2827 break;
2828 default: /* Avoid compiler warnings. */
2829 abort();
2831 return tmp;
2834 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2835 uint32_t dp)
2837 uint32_t cc = extract32(insn, 20, 2);
2839 if (dp) {
2840 TCGv_i64 frn, frm, dest;
2841 TCGv_i64 tmp, zero, zf, nf, vf;
2843 zero = tcg_const_i64(0);
2845 frn = tcg_temp_new_i64();
2846 frm = tcg_temp_new_i64();
2847 dest = tcg_temp_new_i64();
2849 zf = tcg_temp_new_i64();
2850 nf = tcg_temp_new_i64();
2851 vf = tcg_temp_new_i64();
2853 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2854 tcg_gen_ext_i32_i64(nf, cpu_NF);
2855 tcg_gen_ext_i32_i64(vf, cpu_VF);
2857 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2858 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2859 switch (cc) {
2860 case 0: /* eq: Z */
2861 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2862 frn, frm);
2863 break;
2864 case 1: /* vs: V */
2865 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2866 frn, frm);
2867 break;
2868 case 2: /* ge: N == V -> N ^ V == 0 */
2869 tmp = tcg_temp_new_i64();
2870 tcg_gen_xor_i64(tmp, vf, nf);
2871 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2872 frn, frm);
2873 tcg_temp_free_i64(tmp);
2874 break;
2875 case 3: /* gt: !Z && N == V */
2876 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2877 frn, frm);
2878 tmp = tcg_temp_new_i64();
2879 tcg_gen_xor_i64(tmp, vf, nf);
2880 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2881 dest, frm);
2882 tcg_temp_free_i64(tmp);
2883 break;
2885 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2886 tcg_temp_free_i64(frn);
2887 tcg_temp_free_i64(frm);
2888 tcg_temp_free_i64(dest);
2890 tcg_temp_free_i64(zf);
2891 tcg_temp_free_i64(nf);
2892 tcg_temp_free_i64(vf);
2894 tcg_temp_free_i64(zero);
2895 } else {
2896 TCGv_i32 frn, frm, dest;
2897 TCGv_i32 tmp, zero;
2899 zero = tcg_const_i32(0);
2901 frn = tcg_temp_new_i32();
2902 frm = tcg_temp_new_i32();
2903 dest = tcg_temp_new_i32();
2904 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2905 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2906 switch (cc) {
2907 case 0: /* eq: Z */
2908 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2909 frn, frm);
2910 break;
2911 case 1: /* vs: V */
2912 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2913 frn, frm);
2914 break;
2915 case 2: /* ge: N == V -> N ^ V == 0 */
2916 tmp = tcg_temp_new_i32();
2917 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2918 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2919 frn, frm);
2920 tcg_temp_free_i32(tmp);
2921 break;
2922 case 3: /* gt: !Z && N == V */
2923 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2924 frn, frm);
2925 tmp = tcg_temp_new_i32();
2926 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2927 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2928 dest, frm);
2929 tcg_temp_free_i32(tmp);
2930 break;
2932 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2933 tcg_temp_free_i32(frn);
2934 tcg_temp_free_i32(frm);
2935 tcg_temp_free_i32(dest);
2937 tcg_temp_free_i32(zero);
2940 return 0;
2943 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2944 uint32_t rm, uint32_t dp)
2946 uint32_t vmin = extract32(insn, 6, 1);
2947 TCGv_ptr fpst = get_fpstatus_ptr(0);
2949 if (dp) {
2950 TCGv_i64 frn, frm, dest;
2952 frn = tcg_temp_new_i64();
2953 frm = tcg_temp_new_i64();
2954 dest = tcg_temp_new_i64();
2956 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2957 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2958 if (vmin) {
2959 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2960 } else {
2961 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2963 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2964 tcg_temp_free_i64(frn);
2965 tcg_temp_free_i64(frm);
2966 tcg_temp_free_i64(dest);
2967 } else {
2968 TCGv_i32 frn, frm, dest;
2970 frn = tcg_temp_new_i32();
2971 frm = tcg_temp_new_i32();
2972 dest = tcg_temp_new_i32();
2974 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2975 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2976 if (vmin) {
2977 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2978 } else {
2979 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2981 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2982 tcg_temp_free_i32(frn);
2983 tcg_temp_free_i32(frm);
2984 tcg_temp_free_i32(dest);
2987 tcg_temp_free_ptr(fpst);
2988 return 0;
2991 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2992 int rounding)
2994 TCGv_ptr fpst = get_fpstatus_ptr(0);
2995 TCGv_i32 tcg_rmode;
2997 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2998 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3000 if (dp) {
3001 TCGv_i64 tcg_op;
3002 TCGv_i64 tcg_res;
3003 tcg_op = tcg_temp_new_i64();
3004 tcg_res = tcg_temp_new_i64();
3005 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3006 gen_helper_rintd(tcg_res, tcg_op, fpst);
3007 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3008 tcg_temp_free_i64(tcg_op);
3009 tcg_temp_free_i64(tcg_res);
3010 } else {
3011 TCGv_i32 tcg_op;
3012 TCGv_i32 tcg_res;
3013 tcg_op = tcg_temp_new_i32();
3014 tcg_res = tcg_temp_new_i32();
3015 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3016 gen_helper_rints(tcg_res, tcg_op, fpst);
3017 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3018 tcg_temp_free_i32(tcg_op);
3019 tcg_temp_free_i32(tcg_res);
3022 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3023 tcg_temp_free_i32(tcg_rmode);
3025 tcg_temp_free_ptr(fpst);
3026 return 0;
3029 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3030 int rounding)
3032 bool is_signed = extract32(insn, 7, 1);
3033 TCGv_ptr fpst = get_fpstatus_ptr(0);
3034 TCGv_i32 tcg_rmode, tcg_shift;
3036 tcg_shift = tcg_const_i32(0);
3038 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3039 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3041 if (dp) {
3042 TCGv_i64 tcg_double, tcg_res;
3043 TCGv_i32 tcg_tmp;
3044 /* Rd is encoded as a single precision register even when the source
3045 * is double precision.
3047 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3048 tcg_double = tcg_temp_new_i64();
3049 tcg_res = tcg_temp_new_i64();
3050 tcg_tmp = tcg_temp_new_i32();
3051 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3052 if (is_signed) {
3053 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3054 } else {
3055 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3057 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3058 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3059 tcg_temp_free_i32(tcg_tmp);
3060 tcg_temp_free_i64(tcg_res);
3061 tcg_temp_free_i64(tcg_double);
3062 } else {
3063 TCGv_i32 tcg_single, tcg_res;
3064 tcg_single = tcg_temp_new_i32();
3065 tcg_res = tcg_temp_new_i32();
3066 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3067 if (is_signed) {
3068 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3069 } else {
3070 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3072 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3073 tcg_temp_free_i32(tcg_res);
3074 tcg_temp_free_i32(tcg_single);
3077 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3078 tcg_temp_free_i32(tcg_rmode);
3080 tcg_temp_free_i32(tcg_shift);
3082 tcg_temp_free_ptr(fpst);
3084 return 0;
3087 /* Table for converting the most common AArch32 encoding of
3088 * rounding mode to arm_fprounding order (which matches the
3089 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3091 static const uint8_t fp_decode_rm[] = {
3092 FPROUNDING_TIEAWAY,
3093 FPROUNDING_TIEEVEN,
3094 FPROUNDING_POSINF,
3095 FPROUNDING_NEGINF,
3098 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3100 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3102 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3103 return 1;
3106 if (dp) {
3107 VFP_DREG_D(rd, insn);
3108 VFP_DREG_N(rn, insn);
3109 VFP_DREG_M(rm, insn);
3110 } else {
3111 rd = VFP_SREG_D(insn);
3112 rn = VFP_SREG_N(insn);
3113 rm = VFP_SREG_M(insn);
3116 if ((insn & 0x0f800e50) == 0x0e000a00) {
3117 return handle_vsel(insn, rd, rn, rm, dp);
3118 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3119 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3120 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3121 /* VRINTA, VRINTN, VRINTP, VRINTM */
3122 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3123 return handle_vrint(insn, rd, rm, dp, rounding);
3124 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3125 /* VCVTA, VCVTN, VCVTP, VCVTM */
3126 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3127 return handle_vcvt(insn, rd, rm, dp, rounding);
3129 return 1;
3132 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3133 (ie. an undefined instruction). */
3134 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3136 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3137 int dp, veclen;
3138 TCGv_i32 addr;
3139 TCGv_i32 tmp;
3140 TCGv_i32 tmp2;
3142 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3143 return 1;
3146 /* FIXME: this access check should not take precedence over UNDEF
3147 * for invalid encodings; we will generate incorrect syndrome information
3148 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3150 if (s->fp_excp_el) {
3151 gen_exception_insn(s, 4, EXCP_UDEF,
3152 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3153 return 0;
3156 if (!s->vfp_enabled) {
3157 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3158 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3159 return 1;
3160 rn = (insn >> 16) & 0xf;
3161 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3162 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3163 return 1;
3167 if (extract32(insn, 28, 4) == 0xf) {
3168 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3169 * only used in v8 and above.
3171 return disas_vfp_v8_insn(s, insn);
3174 dp = ((insn & 0xf00) == 0xb00);
3175 switch ((insn >> 24) & 0xf) {
3176 case 0xe:
3177 if (insn & (1 << 4)) {
3178 /* single register transfer */
3179 rd = (insn >> 12) & 0xf;
3180 if (dp) {
3181 int size;
3182 int pass;
3184 VFP_DREG_N(rn, insn);
3185 if (insn & 0xf)
3186 return 1;
3187 if (insn & 0x00c00060
3188 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3189 return 1;
3192 pass = (insn >> 21) & 1;
3193 if (insn & (1 << 22)) {
3194 size = 0;
3195 offset = ((insn >> 5) & 3) * 8;
3196 } else if (insn & (1 << 5)) {
3197 size = 1;
3198 offset = (insn & (1 << 6)) ? 16 : 0;
3199 } else {
3200 size = 2;
3201 offset = 0;
3203 if (insn & ARM_CP_RW_BIT) {
3204 /* vfp->arm */
3205 tmp = neon_load_reg(rn, pass);
3206 switch (size) {
3207 case 0:
3208 if (offset)
3209 tcg_gen_shri_i32(tmp, tmp, offset);
3210 if (insn & (1 << 23))
3211 gen_uxtb(tmp);
3212 else
3213 gen_sxtb(tmp);
3214 break;
3215 case 1:
3216 if (insn & (1 << 23)) {
3217 if (offset) {
3218 tcg_gen_shri_i32(tmp, tmp, 16);
3219 } else {
3220 gen_uxth(tmp);
3222 } else {
3223 if (offset) {
3224 tcg_gen_sari_i32(tmp, tmp, 16);
3225 } else {
3226 gen_sxth(tmp);
3229 break;
3230 case 2:
3231 break;
3233 store_reg(s, rd, tmp);
3234 } else {
3235 /* arm->vfp */
3236 tmp = load_reg(s, rd);
3237 if (insn & (1 << 23)) {
3238 /* VDUP */
3239 if (size == 0) {
3240 gen_neon_dup_u8(tmp, 0);
3241 } else if (size == 1) {
3242 gen_neon_dup_low16(tmp);
3244 for (n = 0; n <= pass * 2; n++) {
3245 tmp2 = tcg_temp_new_i32();
3246 tcg_gen_mov_i32(tmp2, tmp);
3247 neon_store_reg(rn, n, tmp2);
3249 neon_store_reg(rn, n, tmp);
3250 } else {
3251 /* VMOV */
3252 switch (size) {
3253 case 0:
3254 tmp2 = neon_load_reg(rn, pass);
3255 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3256 tcg_temp_free_i32(tmp2);
3257 break;
3258 case 1:
3259 tmp2 = neon_load_reg(rn, pass);
3260 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3261 tcg_temp_free_i32(tmp2);
3262 break;
3263 case 2:
3264 break;
3266 neon_store_reg(rn, pass, tmp);
3269 } else { /* !dp */
3270 if ((insn & 0x6f) != 0x00)
3271 return 1;
3272 rn = VFP_SREG_N(insn);
3273 if (insn & ARM_CP_RW_BIT) {
3274 /* vfp->arm */
3275 if (insn & (1 << 21)) {
3276 /* system register */
3277 rn >>= 1;
3279 switch (rn) {
3280 case ARM_VFP_FPSID:
3281 /* VFP2 allows access to FSID from userspace.
3282 VFP3 restricts all id registers to privileged
3283 accesses. */
3284 if (IS_USER(s)
3285 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3286 return 1;
3288 tmp = load_cpu_field(vfp.xregs[rn]);
3289 break;
3290 case ARM_VFP_FPEXC:
3291 if (IS_USER(s))
3292 return 1;
3293 tmp = load_cpu_field(vfp.xregs[rn]);
3294 break;
3295 case ARM_VFP_FPINST:
3296 case ARM_VFP_FPINST2:
3297 /* Not present in VFP3. */
3298 if (IS_USER(s)
3299 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3300 return 1;
3302 tmp = load_cpu_field(vfp.xregs[rn]);
3303 break;
3304 case ARM_VFP_FPSCR:
3305 if (rd == 15) {
3306 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3307 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3308 } else {
3309 tmp = tcg_temp_new_i32();
3310 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3312 break;
3313 case ARM_VFP_MVFR2:
3314 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3315 return 1;
3317 /* fall through */
3318 case ARM_VFP_MVFR0:
3319 case ARM_VFP_MVFR1:
3320 if (IS_USER(s)
3321 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3322 return 1;
3324 tmp = load_cpu_field(vfp.xregs[rn]);
3325 break;
3326 default:
3327 return 1;
3329 } else {
3330 gen_mov_F0_vreg(0, rn);
3331 tmp = gen_vfp_mrs();
3333 if (rd == 15) {
3334 /* Set the 4 flag bits in the CPSR. */
3335 gen_set_nzcv(tmp);
3336 tcg_temp_free_i32(tmp);
3337 } else {
3338 store_reg(s, rd, tmp);
3340 } else {
3341 /* arm->vfp */
3342 if (insn & (1 << 21)) {
3343 rn >>= 1;
3344 /* system register */
3345 switch (rn) {
3346 case ARM_VFP_FPSID:
3347 case ARM_VFP_MVFR0:
3348 case ARM_VFP_MVFR1:
3349 /* Writes are ignored. */
3350 break;
3351 case ARM_VFP_FPSCR:
3352 tmp = load_reg(s, rd);
3353 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3354 tcg_temp_free_i32(tmp);
3355 gen_lookup_tb(s);
3356 break;
3357 case ARM_VFP_FPEXC:
3358 if (IS_USER(s))
3359 return 1;
3360 /* TODO: VFP subarchitecture support.
3361 * For now, keep the EN bit only */
3362 tmp = load_reg(s, rd);
3363 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3364 store_cpu_field(tmp, vfp.xregs[rn]);
3365 gen_lookup_tb(s);
3366 break;
3367 case ARM_VFP_FPINST:
3368 case ARM_VFP_FPINST2:
3369 if (IS_USER(s)) {
3370 return 1;
3372 tmp = load_reg(s, rd);
3373 store_cpu_field(tmp, vfp.xregs[rn]);
3374 break;
3375 default:
3376 return 1;
3378 } else {
3379 tmp = load_reg(s, rd);
3380 gen_vfp_msr(tmp);
3381 gen_mov_vreg_F0(0, rn);
3385 } else {
3386 /* data processing */
3387 /* The opcode is in bits 23, 21, 20 and 6. */
3388 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3389 if (dp) {
3390 if (op == 15) {
3391 /* rn is opcode */
3392 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3393 } else {
3394 /* rn is register number */
3395 VFP_DREG_N(rn, insn);
3398 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3399 ((rn & 0x1e) == 0x6))) {
3400 /* Integer or single/half precision destination. */
3401 rd = VFP_SREG_D(insn);
3402 } else {
3403 VFP_DREG_D(rd, insn);
3405 if (op == 15 &&
3406 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3407 ((rn & 0x1e) == 0x4))) {
3408 /* VCVT from int or half precision is always from S reg
3409 * regardless of dp bit. VCVT with immediate frac_bits
3410 * has same format as SREG_M.
3412 rm = VFP_SREG_M(insn);
3413 } else {
3414 VFP_DREG_M(rm, insn);
3416 } else {
3417 rn = VFP_SREG_N(insn);
3418 if (op == 15 && rn == 15) {
3419 /* Double precision destination. */
3420 VFP_DREG_D(rd, insn);
3421 } else {
3422 rd = VFP_SREG_D(insn);
3424 /* NB that we implicitly rely on the encoding for the frac_bits
3425 * in VCVT of fixed to float being the same as that of an SREG_M
3427 rm = VFP_SREG_M(insn);
3430 veclen = s->vec_len;
3431 if (op == 15 && rn > 3)
3432 veclen = 0;
3434 /* Shut up compiler warnings. */
3435 delta_m = 0;
3436 delta_d = 0;
3437 bank_mask = 0;
3439 if (veclen > 0) {
3440 if (dp)
3441 bank_mask = 0xc;
3442 else
3443 bank_mask = 0x18;
3445 /* Figure out what type of vector operation this is. */
3446 if ((rd & bank_mask) == 0) {
3447 /* scalar */
3448 veclen = 0;
3449 } else {
3450 if (dp)
3451 delta_d = (s->vec_stride >> 1) + 1;
3452 else
3453 delta_d = s->vec_stride + 1;
3455 if ((rm & bank_mask) == 0) {
3456 /* mixed scalar/vector */
3457 delta_m = 0;
3458 } else {
3459 /* vector */
3460 delta_m = delta_d;
3465 /* Load the initial operands. */
3466 if (op == 15) {
3467 switch (rn) {
3468 case 16:
3469 case 17:
3470 /* Integer source */
3471 gen_mov_F0_vreg(0, rm);
3472 break;
3473 case 8:
3474 case 9:
3475 /* Compare */
3476 gen_mov_F0_vreg(dp, rd);
3477 gen_mov_F1_vreg(dp, rm);
3478 break;
3479 case 10:
3480 case 11:
3481 /* Compare with zero */
3482 gen_mov_F0_vreg(dp, rd);
3483 gen_vfp_F1_ld0(dp);
3484 break;
3485 case 20:
3486 case 21:
3487 case 22:
3488 case 23:
3489 case 28:
3490 case 29:
3491 case 30:
3492 case 31:
3493 /* Source and destination the same. */
3494 gen_mov_F0_vreg(dp, rd);
3495 break;
3496 case 4:
3497 case 5:
3498 case 6:
3499 case 7:
3500 /* VCVTB, VCVTT: only present with the halfprec extension
3501 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3502 * (we choose to UNDEF)
3504 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3505 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3506 return 1;
3508 if (!extract32(rn, 1, 1)) {
3509 /* Half precision source. */
3510 gen_mov_F0_vreg(0, rm);
3511 break;
3513 /* Otherwise fall through */
3514 default:
3515 /* One source operand. */
3516 gen_mov_F0_vreg(dp, rm);
3517 break;
3519 } else {
3520 /* Two source operands. */
3521 gen_mov_F0_vreg(dp, rn);
3522 gen_mov_F1_vreg(dp, rm);
3525 for (;;) {
3526 /* Perform the calculation. */
3527 switch (op) {
3528 case 0: /* VMLA: fd + (fn * fm) */
3529 /* Note that order of inputs to the add matters for NaNs */
3530 gen_vfp_F1_mul(dp);
3531 gen_mov_F0_vreg(dp, rd);
3532 gen_vfp_add(dp);
3533 break;
3534 case 1: /* VMLS: fd + -(fn * fm) */
3535 gen_vfp_mul(dp);
3536 gen_vfp_F1_neg(dp);
3537 gen_mov_F0_vreg(dp, rd);
3538 gen_vfp_add(dp);
3539 break;
3540 case 2: /* VNMLS: -fd + (fn * fm) */
3541 /* Note that it isn't valid to replace (-A + B) with (B - A)
3542 * or similar plausible looking simplifications
3543 * because this will give wrong results for NaNs.
3545 gen_vfp_F1_mul(dp);
3546 gen_mov_F0_vreg(dp, rd);
3547 gen_vfp_neg(dp);
3548 gen_vfp_add(dp);
3549 break;
3550 case 3: /* VNMLA: -fd + -(fn * fm) */
3551 gen_vfp_mul(dp);
3552 gen_vfp_F1_neg(dp);
3553 gen_mov_F0_vreg(dp, rd);
3554 gen_vfp_neg(dp);
3555 gen_vfp_add(dp);
3556 break;
3557 case 4: /* mul: fn * fm */
3558 gen_vfp_mul(dp);
3559 break;
3560 case 5: /* nmul: -(fn * fm) */
3561 gen_vfp_mul(dp);
3562 gen_vfp_neg(dp);
3563 break;
3564 case 6: /* add: fn + fm */
3565 gen_vfp_add(dp);
3566 break;
3567 case 7: /* sub: fn - fm */
3568 gen_vfp_sub(dp);
3569 break;
3570 case 8: /* div: fn / fm */
3571 gen_vfp_div(dp);
3572 break;
3573 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3574 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3575 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3576 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3577 /* These are fused multiply-add, and must be done as one
3578 * floating point operation with no rounding between the
3579 * multiplication and addition steps.
3580 * NB that doing the negations here as separate steps is
3581 * correct : an input NaN should come out with its sign bit
3582 * flipped if it is a negated-input.
3584 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3585 return 1;
3587 if (dp) {
3588 TCGv_ptr fpst;
3589 TCGv_i64 frd;
3590 if (op & 1) {
3591 /* VFNMS, VFMS */
3592 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3594 frd = tcg_temp_new_i64();
3595 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3596 if (op & 2) {
3597 /* VFNMA, VFNMS */
3598 gen_helper_vfp_negd(frd, frd);
3600 fpst = get_fpstatus_ptr(0);
3601 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3602 cpu_F1d, frd, fpst);
3603 tcg_temp_free_ptr(fpst);
3604 tcg_temp_free_i64(frd);
3605 } else {
3606 TCGv_ptr fpst;
3607 TCGv_i32 frd;
3608 if (op & 1) {
3609 /* VFNMS, VFMS */
3610 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3612 frd = tcg_temp_new_i32();
3613 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3614 if (op & 2) {
3615 gen_helper_vfp_negs(frd, frd);
3617 fpst = get_fpstatus_ptr(0);
3618 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3619 cpu_F1s, frd, fpst);
3620 tcg_temp_free_ptr(fpst);
3621 tcg_temp_free_i32(frd);
3623 break;
3624 case 14: /* fconst */
3625 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3626 return 1;
3629 n = (insn << 12) & 0x80000000;
3630 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3631 if (dp) {
3632 if (i & 0x40)
3633 i |= 0x3f80;
3634 else
3635 i |= 0x4000;
3636 n |= i << 16;
3637 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3638 } else {
3639 if (i & 0x40)
3640 i |= 0x780;
3641 else
3642 i |= 0x800;
3643 n |= i << 19;
3644 tcg_gen_movi_i32(cpu_F0s, n);
3646 break;
3647 case 15: /* extension space */
3648 switch (rn) {
3649 case 0: /* cpy */
3650 /* no-op */
3651 break;
3652 case 1: /* abs */
3653 gen_vfp_abs(dp);
3654 break;
3655 case 2: /* neg */
3656 gen_vfp_neg(dp);
3657 break;
3658 case 3: /* sqrt */
3659 gen_vfp_sqrt(dp);
3660 break;
3661 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3662 tmp = gen_vfp_mrs();
3663 tcg_gen_ext16u_i32(tmp, tmp);
3664 if (dp) {
3665 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3666 cpu_env);
3667 } else {
3668 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3669 cpu_env);
3671 tcg_temp_free_i32(tmp);
3672 break;
3673 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3674 tmp = gen_vfp_mrs();
3675 tcg_gen_shri_i32(tmp, tmp, 16);
3676 if (dp) {
3677 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3678 cpu_env);
3679 } else {
3680 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3681 cpu_env);
3683 tcg_temp_free_i32(tmp);
3684 break;
3685 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3686 tmp = tcg_temp_new_i32();
3687 if (dp) {
3688 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3689 cpu_env);
3690 } else {
3691 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3692 cpu_env);
3694 gen_mov_F0_vreg(0, rd);
3695 tmp2 = gen_vfp_mrs();
3696 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3697 tcg_gen_or_i32(tmp, tmp, tmp2);
3698 tcg_temp_free_i32(tmp2);
3699 gen_vfp_msr(tmp);
3700 break;
3701 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3702 tmp = tcg_temp_new_i32();
3703 if (dp) {
3704 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3705 cpu_env);
3706 } else {
3707 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3708 cpu_env);
3710 tcg_gen_shli_i32(tmp, tmp, 16);
3711 gen_mov_F0_vreg(0, rd);
3712 tmp2 = gen_vfp_mrs();
3713 tcg_gen_ext16u_i32(tmp2, tmp2);
3714 tcg_gen_or_i32(tmp, tmp, tmp2);
3715 tcg_temp_free_i32(tmp2);
3716 gen_vfp_msr(tmp);
3717 break;
3718 case 8: /* cmp */
3719 gen_vfp_cmp(dp);
3720 break;
3721 case 9: /* cmpe */
3722 gen_vfp_cmpe(dp);
3723 break;
3724 case 10: /* cmpz */
3725 gen_vfp_cmp(dp);
3726 break;
3727 case 11: /* cmpez */
3728 gen_vfp_F1_ld0(dp);
3729 gen_vfp_cmpe(dp);
3730 break;
3731 case 12: /* vrintr */
3733 TCGv_ptr fpst = get_fpstatus_ptr(0);
3734 if (dp) {
3735 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3736 } else {
3737 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3739 tcg_temp_free_ptr(fpst);
3740 break;
3742 case 13: /* vrintz */
3744 TCGv_ptr fpst = get_fpstatus_ptr(0);
3745 TCGv_i32 tcg_rmode;
3746 tcg_rmode = tcg_const_i32(float_round_to_zero);
3747 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3748 if (dp) {
3749 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3750 } else {
3751 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3753 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3754 tcg_temp_free_i32(tcg_rmode);
3755 tcg_temp_free_ptr(fpst);
3756 break;
3758 case 14: /* vrintx */
3760 TCGv_ptr fpst = get_fpstatus_ptr(0);
3761 if (dp) {
3762 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3763 } else {
3764 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3766 tcg_temp_free_ptr(fpst);
3767 break;
3769 case 15: /* single<->double conversion */
3770 if (dp)
3771 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3772 else
3773 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3774 break;
3775 case 16: /* fuito */
3776 gen_vfp_uito(dp, 0);
3777 break;
3778 case 17: /* fsito */
3779 gen_vfp_sito(dp, 0);
3780 break;
3781 case 20: /* fshto */
3782 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3783 return 1;
3785 gen_vfp_shto(dp, 16 - rm, 0);
3786 break;
3787 case 21: /* fslto */
3788 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3789 return 1;
3791 gen_vfp_slto(dp, 32 - rm, 0);
3792 break;
3793 case 22: /* fuhto */
3794 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3795 return 1;
3797 gen_vfp_uhto(dp, 16 - rm, 0);
3798 break;
3799 case 23: /* fulto */
3800 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3801 return 1;
3803 gen_vfp_ulto(dp, 32 - rm, 0);
3804 break;
3805 case 24: /* ftoui */
3806 gen_vfp_toui(dp, 0);
3807 break;
3808 case 25: /* ftouiz */
3809 gen_vfp_touiz(dp, 0);
3810 break;
3811 case 26: /* ftosi */
3812 gen_vfp_tosi(dp, 0);
3813 break;
3814 case 27: /* ftosiz */
3815 gen_vfp_tosiz(dp, 0);
3816 break;
3817 case 28: /* ftosh */
3818 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3819 return 1;
3821 gen_vfp_tosh(dp, 16 - rm, 0);
3822 break;
3823 case 29: /* ftosl */
3824 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3825 return 1;
3827 gen_vfp_tosl(dp, 32 - rm, 0);
3828 break;
3829 case 30: /* ftouh */
3830 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3831 return 1;
3833 gen_vfp_touh(dp, 16 - rm, 0);
3834 break;
3835 case 31: /* ftoul */
3836 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3837 return 1;
3839 gen_vfp_toul(dp, 32 - rm, 0);
3840 break;
3841 default: /* undefined */
3842 return 1;
3844 break;
3845 default: /* undefined */
3846 return 1;
3849 /* Write back the result. */
3850 if (op == 15 && (rn >= 8 && rn <= 11)) {
3851 /* Comparison, do nothing. */
3852 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3853 (rn & 0x1e) == 0x6)) {
3854 /* VCVT double to int: always integer result.
3855 * VCVT double to half precision is always a single
3856 * precision result.
3858 gen_mov_vreg_F0(0, rd);
3859 } else if (op == 15 && rn == 15) {
3860 /* conversion */
3861 gen_mov_vreg_F0(!dp, rd);
3862 } else {
3863 gen_mov_vreg_F0(dp, rd);
3866 /* break out of the loop if we have finished */
3867 if (veclen == 0)
3868 break;
3870 if (op == 15 && delta_m == 0) {
3871 /* single source one-many */
3872 while (veclen--) {
3873 rd = ((rd + delta_d) & (bank_mask - 1))
3874 | (rd & bank_mask);
3875 gen_mov_vreg_F0(dp, rd);
3877 break;
3879 /* Setup the next operands. */
3880 veclen--;
3881 rd = ((rd + delta_d) & (bank_mask - 1))
3882 | (rd & bank_mask);
3884 if (op == 15) {
3885 /* One source operand. */
3886 rm = ((rm + delta_m) & (bank_mask - 1))
3887 | (rm & bank_mask);
3888 gen_mov_F0_vreg(dp, rm);
3889 } else {
3890 /* Two source operands. */
3891 rn = ((rn + delta_d) & (bank_mask - 1))
3892 | (rn & bank_mask);
3893 gen_mov_F0_vreg(dp, rn);
3894 if (delta_m) {
3895 rm = ((rm + delta_m) & (bank_mask - 1))
3896 | (rm & bank_mask);
3897 gen_mov_F1_vreg(dp, rm);
3902 break;
3903 case 0xc:
3904 case 0xd:
3905 if ((insn & 0x03e00000) == 0x00400000) {
3906 /* two-register transfer */
3907 rn = (insn >> 16) & 0xf;
3908 rd = (insn >> 12) & 0xf;
3909 if (dp) {
3910 VFP_DREG_M(rm, insn);
3911 } else {
3912 rm = VFP_SREG_M(insn);
3915 if (insn & ARM_CP_RW_BIT) {
3916 /* vfp->arm */
3917 if (dp) {
3918 gen_mov_F0_vreg(0, rm * 2);
3919 tmp = gen_vfp_mrs();
3920 store_reg(s, rd, tmp);
3921 gen_mov_F0_vreg(0, rm * 2 + 1);
3922 tmp = gen_vfp_mrs();
3923 store_reg(s, rn, tmp);
3924 } else {
3925 gen_mov_F0_vreg(0, rm);
3926 tmp = gen_vfp_mrs();
3927 store_reg(s, rd, tmp);
3928 gen_mov_F0_vreg(0, rm + 1);
3929 tmp = gen_vfp_mrs();
3930 store_reg(s, rn, tmp);
3932 } else {
3933 /* arm->vfp */
3934 if (dp) {
3935 tmp = load_reg(s, rd);
3936 gen_vfp_msr(tmp);
3937 gen_mov_vreg_F0(0, rm * 2);
3938 tmp = load_reg(s, rn);
3939 gen_vfp_msr(tmp);
3940 gen_mov_vreg_F0(0, rm * 2 + 1);
3941 } else {
3942 tmp = load_reg(s, rd);
3943 gen_vfp_msr(tmp);
3944 gen_mov_vreg_F0(0, rm);
3945 tmp = load_reg(s, rn);
3946 gen_vfp_msr(tmp);
3947 gen_mov_vreg_F0(0, rm + 1);
3950 } else {
3951 /* Load/store */
3952 rn = (insn >> 16) & 0xf;
3953 if (dp)
3954 VFP_DREG_D(rd, insn);
3955 else
3956 rd = VFP_SREG_D(insn);
3957 if ((insn & 0x01200000) == 0x01000000) {
3958 /* Single load/store */
3959 offset = (insn & 0xff) << 2;
3960 if ((insn & (1 << 23)) == 0)
3961 offset = -offset;
3962 if (s->thumb && rn == 15) {
3963 /* This is actually UNPREDICTABLE */
3964 addr = tcg_temp_new_i32();
3965 tcg_gen_movi_i32(addr, s->pc & ~2);
3966 } else {
3967 addr = load_reg(s, rn);
3969 tcg_gen_addi_i32(addr, addr, offset);
3970 if (insn & (1 << 20)) {
3971 gen_vfp_ld(s, dp, addr);
3972 gen_mov_vreg_F0(dp, rd);
3973 } else {
3974 gen_mov_F0_vreg(dp, rd);
3975 gen_vfp_st(s, dp, addr);
3977 tcg_temp_free_i32(addr);
3978 } else {
3979 /* load/store multiple */
3980 int w = insn & (1 << 21);
3981 if (dp)
3982 n = (insn >> 1) & 0x7f;
3983 else
3984 n = insn & 0xff;
3986 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3987 /* P == U , W == 1 => UNDEF */
3988 return 1;
3990 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3991 /* UNPREDICTABLE cases for bad immediates: we choose to
3992 * UNDEF to avoid generating huge numbers of TCG ops
3994 return 1;
3996 if (rn == 15 && w) {
3997 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3998 return 1;
4001 if (s->thumb && rn == 15) {
4002 /* This is actually UNPREDICTABLE */
4003 addr = tcg_temp_new_i32();
4004 tcg_gen_movi_i32(addr, s->pc & ~2);
4005 } else {
4006 addr = load_reg(s, rn);
4008 if (insn & (1 << 24)) /* pre-decrement */
4009 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4011 if (dp)
4012 offset = 8;
4013 else
4014 offset = 4;
4015 for (i = 0; i < n; i++) {
4016 if (insn & ARM_CP_RW_BIT) {
4017 /* load */
4018 gen_vfp_ld(s, dp, addr);
4019 gen_mov_vreg_F0(dp, rd + i);
4020 } else {
4021 /* store */
4022 gen_mov_F0_vreg(dp, rd + i);
4023 gen_vfp_st(s, dp, addr);
4025 tcg_gen_addi_i32(addr, addr, offset);
4027 if (w) {
4028 /* writeback */
4029 if (insn & (1 << 24))
4030 offset = -offset * n;
4031 else if (dp && (insn & 1))
4032 offset = 4;
4033 else
4034 offset = 0;
4036 if (offset != 0)
4037 tcg_gen_addi_i32(addr, addr, offset);
4038 store_reg(s, rn, addr);
4039 } else {
4040 tcg_temp_free_i32(addr);
4044 break;
4045 default:
4046 /* Should never happen. */
4047 return 1;
4049 return 0;
4052 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4054 TranslationBlock *tb;
4056 tb = s->tb;
4057 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
4058 tcg_gen_goto_tb(n);
4059 gen_set_pc_im(s, dest);
4060 tcg_gen_exit_tb((uintptr_t)tb + n);
4061 } else {
4062 gen_set_pc_im(s, dest);
4063 tcg_gen_exit_tb(0);
4067 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4069 if (unlikely(s->singlestep_enabled || s->ss_active)) {
4070 /* An indirect jump so that we still trigger the debug exception. */
4071 if (s->thumb)
4072 dest |= 1;
4073 gen_bx_im(s, dest);
4074 } else {
4075 gen_goto_tb(s, 0, dest);
4076 s->is_jmp = DISAS_TB_JUMP;
4080 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4082 if (x)
4083 tcg_gen_sari_i32(t0, t0, 16);
4084 else
4085 gen_sxth(t0);
4086 if (y)
4087 tcg_gen_sari_i32(t1, t1, 16);
4088 else
4089 gen_sxth(t1);
4090 tcg_gen_mul_i32(t0, t0, t1);
4093 /* Return the mask of PSR bits set by a MSR instruction. */
4094 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4096 uint32_t mask;
4098 mask = 0;
4099 if (flags & (1 << 0))
4100 mask |= 0xff;
4101 if (flags & (1 << 1))
4102 mask |= 0xff00;
4103 if (flags & (1 << 2))
4104 mask |= 0xff0000;
4105 if (flags & (1 << 3))
4106 mask |= 0xff000000;
4108 /* Mask out undefined bits. */
4109 mask &= ~CPSR_RESERVED;
4110 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4111 mask &= ~CPSR_T;
4113 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4114 mask &= ~CPSR_Q; /* V5TE in reality*/
4116 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4117 mask &= ~(CPSR_E | CPSR_GE);
4119 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4120 mask &= ~CPSR_IT;
4122 /* Mask out execution state and reserved bits. */
4123 if (!spsr) {
4124 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4126 /* Mask out privileged bits. */
4127 if (IS_USER(s))
4128 mask &= CPSR_USER;
4129 return mask;
4132 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4133 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4135 TCGv_i32 tmp;
4136 if (spsr) {
4137 /* ??? This is also undefined in system mode. */
4138 if (IS_USER(s))
4139 return 1;
4141 tmp = load_cpu_field(spsr);
4142 tcg_gen_andi_i32(tmp, tmp, ~mask);
4143 tcg_gen_andi_i32(t0, t0, mask);
4144 tcg_gen_or_i32(tmp, tmp, t0);
4145 store_cpu_field(tmp, spsr);
4146 } else {
4147 gen_set_cpsr(t0, mask);
4149 tcg_temp_free_i32(t0);
4150 gen_lookup_tb(s);
4151 return 0;
4154 /* Returns nonzero if access to the PSR is not permitted. */
4155 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4157 TCGv_i32 tmp;
4158 tmp = tcg_temp_new_i32();
4159 tcg_gen_movi_i32(tmp, val);
4160 return gen_set_psr(s, mask, spsr, tmp);
4163 /* Generate an old-style exception return. Marks pc as dead. */
4164 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4166 TCGv_i32 tmp;
4167 store_reg(s, 15, pc);
4168 tmp = load_cpu_field(spsr);
4169 gen_helper_cpsr_write_eret(cpu_env, tmp);
4170 tcg_temp_free_i32(tmp);
4171 s->is_jmp = DISAS_JUMP;
4174 /* Generate a v6 exception return. Marks both values as dead. */
4175 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4177 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4178 tcg_temp_free_i32(cpsr);
4179 store_reg(s, 15, pc);
4180 s->is_jmp = DISAS_JUMP;
4183 static void gen_nop_hint(DisasContext *s, int val)
4185 switch (val) {
4186 case 1: /* yield */
4187 gen_set_pc_im(s, s->pc);
4188 s->is_jmp = DISAS_YIELD;
4189 break;
4190 case 3: /* wfi */
4191 gen_set_pc_im(s, s->pc);
4192 s->is_jmp = DISAS_WFI;
4193 break;
4194 case 2: /* wfe */
4195 gen_set_pc_im(s, s->pc);
4196 s->is_jmp = DISAS_WFE;
4197 break;
4198 case 4: /* sev */
4199 case 5: /* sevl */
4200 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4201 default: /* nop */
4202 break;
4206 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4208 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4210 switch (size) {
4211 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4212 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4213 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4214 default: abort();
4218 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4220 switch (size) {
4221 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4222 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4223 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4224 default: return;
4228 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4229 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4230 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4231 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4232 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4234 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4235 switch ((size << 1) | u) { \
4236 case 0: \
4237 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4238 break; \
4239 case 1: \
4240 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4241 break; \
4242 case 2: \
4243 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4244 break; \
4245 case 3: \
4246 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4247 break; \
4248 case 4: \
4249 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4250 break; \
4251 case 5: \
4252 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4253 break; \
4254 default: return 1; \
4255 }} while (0)
4257 #define GEN_NEON_INTEGER_OP(name) do { \
4258 switch ((size << 1) | u) { \
4259 case 0: \
4260 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4261 break; \
4262 case 1: \
4263 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4264 break; \
4265 case 2: \
4266 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4267 break; \
4268 case 3: \
4269 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4270 break; \
4271 case 4: \
4272 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4273 break; \
4274 case 5: \
4275 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4276 break; \
4277 default: return 1; \
4278 }} while (0)
4280 static TCGv_i32 neon_load_scratch(int scratch)
4282 TCGv_i32 tmp = tcg_temp_new_i32();
4283 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4284 return tmp;
4287 static void neon_store_scratch(int scratch, TCGv_i32 var)
4289 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4290 tcg_temp_free_i32(var);
4293 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4295 TCGv_i32 tmp;
4296 if (size == 1) {
4297 tmp = neon_load_reg(reg & 7, reg >> 4);
4298 if (reg & 8) {
4299 gen_neon_dup_high16(tmp);
4300 } else {
4301 gen_neon_dup_low16(tmp);
4303 } else {
4304 tmp = neon_load_reg(reg & 15, reg >> 4);
4306 return tmp;
4309 static int gen_neon_unzip(int rd, int rm, int size, int q)
4311 TCGv_i32 tmp, tmp2;
4312 if (!q && size == 2) {
4313 return 1;
4315 tmp = tcg_const_i32(rd);
4316 tmp2 = tcg_const_i32(rm);
4317 if (q) {
4318 switch (size) {
4319 case 0:
4320 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4321 break;
4322 case 1:
4323 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4324 break;
4325 case 2:
4326 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4327 break;
4328 default:
4329 abort();
4331 } else {
4332 switch (size) {
4333 case 0:
4334 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4335 break;
4336 case 1:
4337 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4338 break;
4339 default:
4340 abort();
4343 tcg_temp_free_i32(tmp);
4344 tcg_temp_free_i32(tmp2);
4345 return 0;
4348 static int gen_neon_zip(int rd, int rm, int size, int q)
4350 TCGv_i32 tmp, tmp2;
4351 if (!q && size == 2) {
4352 return 1;
4354 tmp = tcg_const_i32(rd);
4355 tmp2 = tcg_const_i32(rm);
4356 if (q) {
4357 switch (size) {
4358 case 0:
4359 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4360 break;
4361 case 1:
4362 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4363 break;
4364 case 2:
4365 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4366 break;
4367 default:
4368 abort();
4370 } else {
4371 switch (size) {
4372 case 0:
4373 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4374 break;
4375 case 1:
4376 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4377 break;
4378 default:
4379 abort();
4382 tcg_temp_free_i32(tmp);
4383 tcg_temp_free_i32(tmp2);
4384 return 0;
4387 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4389 TCGv_i32 rd, tmp;
4391 rd = tcg_temp_new_i32();
4392 tmp = tcg_temp_new_i32();
4394 tcg_gen_shli_i32(rd, t0, 8);
4395 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4396 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4397 tcg_gen_or_i32(rd, rd, tmp);
4399 tcg_gen_shri_i32(t1, t1, 8);
4400 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4401 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4402 tcg_gen_or_i32(t1, t1, tmp);
4403 tcg_gen_mov_i32(t0, rd);
4405 tcg_temp_free_i32(tmp);
4406 tcg_temp_free_i32(rd);
4409 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4411 TCGv_i32 rd, tmp;
4413 rd = tcg_temp_new_i32();
4414 tmp = tcg_temp_new_i32();
4416 tcg_gen_shli_i32(rd, t0, 16);
4417 tcg_gen_andi_i32(tmp, t1, 0xffff);
4418 tcg_gen_or_i32(rd, rd, tmp);
4419 tcg_gen_shri_i32(t1, t1, 16);
4420 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4421 tcg_gen_or_i32(t1, t1, tmp);
4422 tcg_gen_mov_i32(t0, rd);
4424 tcg_temp_free_i32(tmp);
4425 tcg_temp_free_i32(rd);
4429 static struct {
4430 int nregs;
4431 int interleave;
4432 int spacing;
4433 } neon_ls_element_type[11] = {
4434 {4, 4, 1},
4435 {4, 4, 2},
4436 {4, 1, 1},
4437 {4, 2, 1},
4438 {3, 3, 1},
4439 {3, 3, 2},
4440 {3, 1, 1},
4441 {1, 1, 1},
4442 {2, 2, 1},
4443 {2, 2, 2},
4444 {2, 1, 1}
4447 /* Translate a NEON load/store element instruction. Return nonzero if the
4448 instruction is invalid. */
4449 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4451 int rd, rn, rm;
4452 int op;
4453 int nregs;
4454 int interleave;
4455 int spacing;
4456 int stride;
4457 int size;
4458 int reg;
4459 int pass;
4460 int load;
4461 int shift;
4462 int n;
4463 TCGv_i32 addr;
4464 TCGv_i32 tmp;
4465 TCGv_i32 tmp2;
4466 TCGv_i64 tmp64;
4468 /* FIXME: this access check should not take precedence over UNDEF
4469 * for invalid encodings; we will generate incorrect syndrome information
4470 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4472 if (s->fp_excp_el) {
4473 gen_exception_insn(s, 4, EXCP_UDEF,
4474 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4475 return 0;
4478 if (!s->vfp_enabled)
4479 return 1;
4480 VFP_DREG_D(rd, insn);
4481 rn = (insn >> 16) & 0xf;
4482 rm = insn & 0xf;
4483 load = (insn & (1 << 21)) != 0;
4484 if ((insn & (1 << 23)) == 0) {
4485 /* Load store all elements. */
4486 op = (insn >> 8) & 0xf;
4487 size = (insn >> 6) & 3;
4488 if (op > 10)
4489 return 1;
4490 /* Catch UNDEF cases for bad values of align field */
4491 switch (op & 0xc) {
4492 case 4:
4493 if (((insn >> 5) & 1) == 1) {
4494 return 1;
4496 break;
4497 case 8:
4498 if (((insn >> 4) & 3) == 3) {
4499 return 1;
4501 break;
4502 default:
4503 break;
4505 nregs = neon_ls_element_type[op].nregs;
4506 interleave = neon_ls_element_type[op].interleave;
4507 spacing = neon_ls_element_type[op].spacing;
4508 if (size == 3 && (interleave | spacing) != 1)
4509 return 1;
4510 addr = tcg_temp_new_i32();
4511 load_reg_var(s, addr, rn);
4512 stride = (1 << size) * interleave;
4513 for (reg = 0; reg < nregs; reg++) {
4514 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4515 load_reg_var(s, addr, rn);
4516 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4517 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4518 load_reg_var(s, addr, rn);
4519 tcg_gen_addi_i32(addr, addr, 1 << size);
4521 if (size == 3) {
4522 tmp64 = tcg_temp_new_i64();
4523 if (load) {
4524 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4525 neon_store_reg64(tmp64, rd);
4526 } else {
4527 neon_load_reg64(tmp64, rd);
4528 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4530 tcg_temp_free_i64(tmp64);
4531 tcg_gen_addi_i32(addr, addr, stride);
4532 } else {
4533 for (pass = 0; pass < 2; pass++) {
4534 if (size == 2) {
4535 if (load) {
4536 tmp = tcg_temp_new_i32();
4537 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4538 neon_store_reg(rd, pass, tmp);
4539 } else {
4540 tmp = neon_load_reg(rd, pass);
4541 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4542 tcg_temp_free_i32(tmp);
4544 tcg_gen_addi_i32(addr, addr, stride);
4545 } else if (size == 1) {
4546 if (load) {
4547 tmp = tcg_temp_new_i32();
4548 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4549 tcg_gen_addi_i32(addr, addr, stride);
4550 tmp2 = tcg_temp_new_i32();
4551 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4552 tcg_gen_addi_i32(addr, addr, stride);
4553 tcg_gen_shli_i32(tmp2, tmp2, 16);
4554 tcg_gen_or_i32(tmp, tmp, tmp2);
4555 tcg_temp_free_i32(tmp2);
4556 neon_store_reg(rd, pass, tmp);
4557 } else {
4558 tmp = neon_load_reg(rd, pass);
4559 tmp2 = tcg_temp_new_i32();
4560 tcg_gen_shri_i32(tmp2, tmp, 16);
4561 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4562 tcg_temp_free_i32(tmp);
4563 tcg_gen_addi_i32(addr, addr, stride);
4564 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4565 tcg_temp_free_i32(tmp2);
4566 tcg_gen_addi_i32(addr, addr, stride);
4568 } else /* size == 0 */ {
4569 if (load) {
4570 TCGV_UNUSED_I32(tmp2);
4571 for (n = 0; n < 4; n++) {
4572 tmp = tcg_temp_new_i32();
4573 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4574 tcg_gen_addi_i32(addr, addr, stride);
4575 if (n == 0) {
4576 tmp2 = tmp;
4577 } else {
4578 tcg_gen_shli_i32(tmp, tmp, n * 8);
4579 tcg_gen_or_i32(tmp2, tmp2, tmp);
4580 tcg_temp_free_i32(tmp);
4583 neon_store_reg(rd, pass, tmp2);
4584 } else {
4585 tmp2 = neon_load_reg(rd, pass);
4586 for (n = 0; n < 4; n++) {
4587 tmp = tcg_temp_new_i32();
4588 if (n == 0) {
4589 tcg_gen_mov_i32(tmp, tmp2);
4590 } else {
4591 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4593 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4594 tcg_temp_free_i32(tmp);
4595 tcg_gen_addi_i32(addr, addr, stride);
4597 tcg_temp_free_i32(tmp2);
4602 rd += spacing;
4604 tcg_temp_free_i32(addr);
4605 stride = nregs * 8;
4606 } else {
4607 size = (insn >> 10) & 3;
4608 if (size == 3) {
4609 /* Load single element to all lanes. */
4610 int a = (insn >> 4) & 1;
4611 if (!load) {
4612 return 1;
4614 size = (insn >> 6) & 3;
4615 nregs = ((insn >> 8) & 3) + 1;
4617 if (size == 3) {
4618 if (nregs != 4 || a == 0) {
4619 return 1;
4621 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4622 size = 2;
4624 if (nregs == 1 && a == 1 && size == 0) {
4625 return 1;
4627 if (nregs == 3 && a == 1) {
4628 return 1;
4630 addr = tcg_temp_new_i32();
4631 load_reg_var(s, addr, rn);
4632 if (nregs == 1) {
4633 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4634 tmp = gen_load_and_replicate(s, addr, size);
4635 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4636 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4637 if (insn & (1 << 5)) {
4638 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4639 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4641 tcg_temp_free_i32(tmp);
4642 } else {
4643 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4644 stride = (insn & (1 << 5)) ? 2 : 1;
4645 for (reg = 0; reg < nregs; reg++) {
4646 tmp = gen_load_and_replicate(s, addr, size);
4647 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4648 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4649 tcg_temp_free_i32(tmp);
4650 tcg_gen_addi_i32(addr, addr, 1 << size);
4651 rd += stride;
4654 tcg_temp_free_i32(addr);
4655 stride = (1 << size) * nregs;
4656 } else {
4657 /* Single element. */
4658 int idx = (insn >> 4) & 0xf;
4659 pass = (insn >> 7) & 1;
4660 switch (size) {
4661 case 0:
4662 shift = ((insn >> 5) & 3) * 8;
4663 stride = 1;
4664 break;
4665 case 1:
4666 shift = ((insn >> 6) & 1) * 16;
4667 stride = (insn & (1 << 5)) ? 2 : 1;
4668 break;
4669 case 2:
4670 shift = 0;
4671 stride = (insn & (1 << 6)) ? 2 : 1;
4672 break;
4673 default:
4674 abort();
4676 nregs = ((insn >> 8) & 3) + 1;
4677 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4678 switch (nregs) {
4679 case 1:
4680 if (((idx & (1 << size)) != 0) ||
4681 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4682 return 1;
4684 break;
4685 case 3:
4686 if ((idx & 1) != 0) {
4687 return 1;
4689 /* fall through */
4690 case 2:
4691 if (size == 2 && (idx & 2) != 0) {
4692 return 1;
4694 break;
4695 case 4:
4696 if ((size == 2) && ((idx & 3) == 3)) {
4697 return 1;
4699 break;
4700 default:
4701 abort();
4703 if ((rd + stride * (nregs - 1)) > 31) {
4704 /* Attempts to write off the end of the register file
4705 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4706 * the neon_load_reg() would write off the end of the array.
4708 return 1;
4710 addr = tcg_temp_new_i32();
4711 load_reg_var(s, addr, rn);
4712 for (reg = 0; reg < nregs; reg++) {
4713 if (load) {
4714 tmp = tcg_temp_new_i32();
4715 switch (size) {
4716 case 0:
4717 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4718 break;
4719 case 1:
4720 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4721 break;
4722 case 2:
4723 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4724 break;
4725 default: /* Avoid compiler warnings. */
4726 abort();
4728 if (size != 2) {
4729 tmp2 = neon_load_reg(rd, pass);
4730 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4731 shift, size ? 16 : 8);
4732 tcg_temp_free_i32(tmp2);
4734 neon_store_reg(rd, pass, tmp);
4735 } else { /* Store */
4736 tmp = neon_load_reg(rd, pass);
4737 if (shift)
4738 tcg_gen_shri_i32(tmp, tmp, shift);
4739 switch (size) {
4740 case 0:
4741 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4742 break;
4743 case 1:
4744 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4745 break;
4746 case 2:
4747 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4748 break;
4750 tcg_temp_free_i32(tmp);
4752 rd += stride;
4753 tcg_gen_addi_i32(addr, addr, 1 << size);
4755 tcg_temp_free_i32(addr);
4756 stride = nregs * (1 << size);
4759 if (rm != 15) {
4760 TCGv_i32 base;
4762 base = load_reg(s, rn);
4763 if (rm == 13) {
4764 tcg_gen_addi_i32(base, base, stride);
4765 } else {
4766 TCGv_i32 index;
4767 index = load_reg(s, rm);
4768 tcg_gen_add_i32(base, base, index);
4769 tcg_temp_free_i32(index);
4771 store_reg(s, rn, base);
4773 return 0;
4776 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4777 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4779 tcg_gen_and_i32(t, t, c);
4780 tcg_gen_andc_i32(f, f, c);
4781 tcg_gen_or_i32(dest, t, f);
4784 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4786 switch (size) {
4787 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4788 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4789 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4790 default: abort();
4794 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4796 switch (size) {
4797 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4798 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4799 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4800 default: abort();
4804 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4806 switch (size) {
4807 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4808 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4809 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4810 default: abort();
4814 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4816 switch (size) {
4817 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4818 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4819 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4820 default: abort();
4824 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4825 int q, int u)
4827 if (q) {
4828 if (u) {
4829 switch (size) {
4830 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4831 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4832 default: abort();
4834 } else {
4835 switch (size) {
4836 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4837 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4838 default: abort();
4841 } else {
4842 if (u) {
4843 switch (size) {
4844 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4845 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4846 default: abort();
4848 } else {
4849 switch (size) {
4850 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4851 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4852 default: abort();
4858 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4860 if (u) {
4861 switch (size) {
4862 case 0: gen_helper_neon_widen_u8(dest, src); break;
4863 case 1: gen_helper_neon_widen_u16(dest, src); break;
4864 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4865 default: abort();
4867 } else {
4868 switch (size) {
4869 case 0: gen_helper_neon_widen_s8(dest, src); break;
4870 case 1: gen_helper_neon_widen_s16(dest, src); break;
4871 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4872 default: abort();
4875 tcg_temp_free_i32(src);
4878 static inline void gen_neon_addl(int size)
4880 switch (size) {
4881 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4882 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4883 case 2: tcg_gen_add_i64(CPU_V001); break;
4884 default: abort();
4888 static inline void gen_neon_subl(int size)
4890 switch (size) {
4891 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4892 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4893 case 2: tcg_gen_sub_i64(CPU_V001); break;
4894 default: abort();
4898 static inline void gen_neon_negl(TCGv_i64 var, int size)
4900 switch (size) {
4901 case 0: gen_helper_neon_negl_u16(var, var); break;
4902 case 1: gen_helper_neon_negl_u32(var, var); break;
4903 case 2:
4904 tcg_gen_neg_i64(var, var);
4905 break;
4906 default: abort();
4910 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4912 switch (size) {
4913 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4914 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4915 default: abort();
4919 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4920 int size, int u)
4922 TCGv_i64 tmp;
4924 switch ((size << 1) | u) {
4925 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4926 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4927 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4928 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4929 case 4:
4930 tmp = gen_muls_i64_i32(a, b);
4931 tcg_gen_mov_i64(dest, tmp);
4932 tcg_temp_free_i64(tmp);
4933 break;
4934 case 5:
4935 tmp = gen_mulu_i64_i32(a, b);
4936 tcg_gen_mov_i64(dest, tmp);
4937 tcg_temp_free_i64(tmp);
4938 break;
4939 default: abort();
4942 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4943 Don't forget to clean them now. */
4944 if (size < 2) {
4945 tcg_temp_free_i32(a);
4946 tcg_temp_free_i32(b);
4950 static void gen_neon_narrow_op(int op, int u, int size,
4951 TCGv_i32 dest, TCGv_i64 src)
4953 if (op) {
4954 if (u) {
4955 gen_neon_unarrow_sats(size, dest, src);
4956 } else {
4957 gen_neon_narrow(size, dest, src);
4959 } else {
4960 if (u) {
4961 gen_neon_narrow_satu(size, dest, src);
4962 } else {
4963 gen_neon_narrow_sats(size, dest, src);
4968 /* Symbolic constants for op fields for Neon 3-register same-length.
4969 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4970 * table A7-9.
4972 #define NEON_3R_VHADD 0
4973 #define NEON_3R_VQADD 1
4974 #define NEON_3R_VRHADD 2
4975 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4976 #define NEON_3R_VHSUB 4
4977 #define NEON_3R_VQSUB 5
4978 #define NEON_3R_VCGT 6
4979 #define NEON_3R_VCGE 7
4980 #define NEON_3R_VSHL 8
4981 #define NEON_3R_VQSHL 9
4982 #define NEON_3R_VRSHL 10
4983 #define NEON_3R_VQRSHL 11
4984 #define NEON_3R_VMAX 12
4985 #define NEON_3R_VMIN 13
4986 #define NEON_3R_VABD 14
4987 #define NEON_3R_VABA 15
4988 #define NEON_3R_VADD_VSUB 16
4989 #define NEON_3R_VTST_VCEQ 17
4990 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4991 #define NEON_3R_VMUL 19
4992 #define NEON_3R_VPMAX 20
4993 #define NEON_3R_VPMIN 21
4994 #define NEON_3R_VQDMULH_VQRDMULH 22
4995 #define NEON_3R_VPADD 23
4996 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4997 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4998 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4999 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5000 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5001 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5002 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5003 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5005 static const uint8_t neon_3r_sizes[] = {
5006 [NEON_3R_VHADD] = 0x7,
5007 [NEON_3R_VQADD] = 0xf,
5008 [NEON_3R_VRHADD] = 0x7,
5009 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5010 [NEON_3R_VHSUB] = 0x7,
5011 [NEON_3R_VQSUB] = 0xf,
5012 [NEON_3R_VCGT] = 0x7,
5013 [NEON_3R_VCGE] = 0x7,
5014 [NEON_3R_VSHL] = 0xf,
5015 [NEON_3R_VQSHL] = 0xf,
5016 [NEON_3R_VRSHL] = 0xf,
5017 [NEON_3R_VQRSHL] = 0xf,
5018 [NEON_3R_VMAX] = 0x7,
5019 [NEON_3R_VMIN] = 0x7,
5020 [NEON_3R_VABD] = 0x7,
5021 [NEON_3R_VABA] = 0x7,
5022 [NEON_3R_VADD_VSUB] = 0xf,
5023 [NEON_3R_VTST_VCEQ] = 0x7,
5024 [NEON_3R_VML] = 0x7,
5025 [NEON_3R_VMUL] = 0x7,
5026 [NEON_3R_VPMAX] = 0x7,
5027 [NEON_3R_VPMIN] = 0x7,
5028 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5029 [NEON_3R_VPADD] = 0x7,
5030 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5031 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5032 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5033 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5034 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5035 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5036 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5037 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5040 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5041 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5042 * table A7-13.
5044 #define NEON_2RM_VREV64 0
5045 #define NEON_2RM_VREV32 1
5046 #define NEON_2RM_VREV16 2
5047 #define NEON_2RM_VPADDL 4
5048 #define NEON_2RM_VPADDL_U 5
5049 #define NEON_2RM_AESE 6 /* Includes AESD */
5050 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5051 #define NEON_2RM_VCLS 8
5052 #define NEON_2RM_VCLZ 9
5053 #define NEON_2RM_VCNT 10
5054 #define NEON_2RM_VMVN 11
5055 #define NEON_2RM_VPADAL 12
5056 #define NEON_2RM_VPADAL_U 13
5057 #define NEON_2RM_VQABS 14
5058 #define NEON_2RM_VQNEG 15
5059 #define NEON_2RM_VCGT0 16
5060 #define NEON_2RM_VCGE0 17
5061 #define NEON_2RM_VCEQ0 18
5062 #define NEON_2RM_VCLE0 19
5063 #define NEON_2RM_VCLT0 20
5064 #define NEON_2RM_SHA1H 21
5065 #define NEON_2RM_VABS 22
5066 #define NEON_2RM_VNEG 23
5067 #define NEON_2RM_VCGT0_F 24
5068 #define NEON_2RM_VCGE0_F 25
5069 #define NEON_2RM_VCEQ0_F 26
5070 #define NEON_2RM_VCLE0_F 27
5071 #define NEON_2RM_VCLT0_F 28
5072 #define NEON_2RM_VABS_F 30
5073 #define NEON_2RM_VNEG_F 31
5074 #define NEON_2RM_VSWP 32
5075 #define NEON_2RM_VTRN 33
5076 #define NEON_2RM_VUZP 34
5077 #define NEON_2RM_VZIP 35
5078 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5079 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5080 #define NEON_2RM_VSHLL 38
5081 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5082 #define NEON_2RM_VRINTN 40
5083 #define NEON_2RM_VRINTX 41
5084 #define NEON_2RM_VRINTA 42
5085 #define NEON_2RM_VRINTZ 43
5086 #define NEON_2RM_VCVT_F16_F32 44
5087 #define NEON_2RM_VRINTM 45
5088 #define NEON_2RM_VCVT_F32_F16 46
5089 #define NEON_2RM_VRINTP 47
5090 #define NEON_2RM_VCVTAU 48
5091 #define NEON_2RM_VCVTAS 49
5092 #define NEON_2RM_VCVTNU 50
5093 #define NEON_2RM_VCVTNS 51
5094 #define NEON_2RM_VCVTPU 52
5095 #define NEON_2RM_VCVTPS 53
5096 #define NEON_2RM_VCVTMU 54
5097 #define NEON_2RM_VCVTMS 55
5098 #define NEON_2RM_VRECPE 56
5099 #define NEON_2RM_VRSQRTE 57
5100 #define NEON_2RM_VRECPE_F 58
5101 #define NEON_2RM_VRSQRTE_F 59
5102 #define NEON_2RM_VCVT_FS 60
5103 #define NEON_2RM_VCVT_FU 61
5104 #define NEON_2RM_VCVT_SF 62
5105 #define NEON_2RM_VCVT_UF 63
5107 static int neon_2rm_is_float_op(int op)
5109 /* Return true if this neon 2reg-misc op is float-to-float */
5110 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5111 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5112 op == NEON_2RM_VRINTM ||
5113 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5114 op >= NEON_2RM_VRECPE_F);
5117 /* Each entry in this array has bit n set if the insn allows
5118 * size value n (otherwise it will UNDEF). Since unallocated
5119 * op values will have no bits set they always UNDEF.
5121 static const uint8_t neon_2rm_sizes[] = {
5122 [NEON_2RM_VREV64] = 0x7,
5123 [NEON_2RM_VREV32] = 0x3,
5124 [NEON_2RM_VREV16] = 0x1,
5125 [NEON_2RM_VPADDL] = 0x7,
5126 [NEON_2RM_VPADDL_U] = 0x7,
5127 [NEON_2RM_AESE] = 0x1,
5128 [NEON_2RM_AESMC] = 0x1,
5129 [NEON_2RM_VCLS] = 0x7,
5130 [NEON_2RM_VCLZ] = 0x7,
5131 [NEON_2RM_VCNT] = 0x1,
5132 [NEON_2RM_VMVN] = 0x1,
5133 [NEON_2RM_VPADAL] = 0x7,
5134 [NEON_2RM_VPADAL_U] = 0x7,
5135 [NEON_2RM_VQABS] = 0x7,
5136 [NEON_2RM_VQNEG] = 0x7,
5137 [NEON_2RM_VCGT0] = 0x7,
5138 [NEON_2RM_VCGE0] = 0x7,
5139 [NEON_2RM_VCEQ0] = 0x7,
5140 [NEON_2RM_VCLE0] = 0x7,
5141 [NEON_2RM_VCLT0] = 0x7,
5142 [NEON_2RM_SHA1H] = 0x4,
5143 [NEON_2RM_VABS] = 0x7,
5144 [NEON_2RM_VNEG] = 0x7,
5145 [NEON_2RM_VCGT0_F] = 0x4,
5146 [NEON_2RM_VCGE0_F] = 0x4,
5147 [NEON_2RM_VCEQ0_F] = 0x4,
5148 [NEON_2RM_VCLE0_F] = 0x4,
5149 [NEON_2RM_VCLT0_F] = 0x4,
5150 [NEON_2RM_VABS_F] = 0x4,
5151 [NEON_2RM_VNEG_F] = 0x4,
5152 [NEON_2RM_VSWP] = 0x1,
5153 [NEON_2RM_VTRN] = 0x7,
5154 [NEON_2RM_VUZP] = 0x7,
5155 [NEON_2RM_VZIP] = 0x7,
5156 [NEON_2RM_VMOVN] = 0x7,
5157 [NEON_2RM_VQMOVN] = 0x7,
5158 [NEON_2RM_VSHLL] = 0x7,
5159 [NEON_2RM_SHA1SU1] = 0x4,
5160 [NEON_2RM_VRINTN] = 0x4,
5161 [NEON_2RM_VRINTX] = 0x4,
5162 [NEON_2RM_VRINTA] = 0x4,
5163 [NEON_2RM_VRINTZ] = 0x4,
5164 [NEON_2RM_VCVT_F16_F32] = 0x2,
5165 [NEON_2RM_VRINTM] = 0x4,
5166 [NEON_2RM_VCVT_F32_F16] = 0x2,
5167 [NEON_2RM_VRINTP] = 0x4,
5168 [NEON_2RM_VCVTAU] = 0x4,
5169 [NEON_2RM_VCVTAS] = 0x4,
5170 [NEON_2RM_VCVTNU] = 0x4,
5171 [NEON_2RM_VCVTNS] = 0x4,
5172 [NEON_2RM_VCVTPU] = 0x4,
5173 [NEON_2RM_VCVTPS] = 0x4,
5174 [NEON_2RM_VCVTMU] = 0x4,
5175 [NEON_2RM_VCVTMS] = 0x4,
5176 [NEON_2RM_VRECPE] = 0x4,
5177 [NEON_2RM_VRSQRTE] = 0x4,
5178 [NEON_2RM_VRECPE_F] = 0x4,
5179 [NEON_2RM_VRSQRTE_F] = 0x4,
5180 [NEON_2RM_VCVT_FS] = 0x4,
5181 [NEON_2RM_VCVT_FU] = 0x4,
5182 [NEON_2RM_VCVT_SF] = 0x4,
5183 [NEON_2RM_VCVT_UF] = 0x4,
5186 /* Translate a NEON data processing instruction. Return nonzero if the
5187 instruction is invalid.
5188 We process data in a mixture of 32-bit and 64-bit chunks.
5189 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5191 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5193 int op;
5194 int q;
5195 int rd, rn, rm;
5196 int size;
5197 int shift;
5198 int pass;
5199 int count;
5200 int pairwise;
5201 int u;
5202 uint32_t imm, mask;
5203 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5204 TCGv_i64 tmp64;
5206 /* FIXME: this access check should not take precedence over UNDEF
5207 * for invalid encodings; we will generate incorrect syndrome information
5208 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5210 if (s->fp_excp_el) {
5211 gen_exception_insn(s, 4, EXCP_UDEF,
5212 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5213 return 0;
5216 if (!s->vfp_enabled)
5217 return 1;
5218 q = (insn & (1 << 6)) != 0;
5219 u = (insn >> 24) & 1;
5220 VFP_DREG_D(rd, insn);
5221 VFP_DREG_N(rn, insn);
5222 VFP_DREG_M(rm, insn);
5223 size = (insn >> 20) & 3;
5224 if ((insn & (1 << 23)) == 0) {
5225 /* Three register same length. */
5226 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5227 /* Catch invalid op and bad size combinations: UNDEF */
5228 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5229 return 1;
5231 /* All insns of this form UNDEF for either this condition or the
5232 * superset of cases "Q==1"; we catch the latter later.
5234 if (q && ((rd | rn | rm) & 1)) {
5235 return 1;
5238 * The SHA-1/SHA-256 3-register instructions require special treatment
5239 * here, as their size field is overloaded as an op type selector, and
5240 * they all consume their input in a single pass.
5242 if (op == NEON_3R_SHA) {
5243 if (!q) {
5244 return 1;
5246 if (!u) { /* SHA-1 */
5247 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5248 return 1;
5250 tmp = tcg_const_i32(rd);
5251 tmp2 = tcg_const_i32(rn);
5252 tmp3 = tcg_const_i32(rm);
5253 tmp4 = tcg_const_i32(size);
5254 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5255 tcg_temp_free_i32(tmp4);
5256 } else { /* SHA-256 */
5257 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5258 return 1;
5260 tmp = tcg_const_i32(rd);
5261 tmp2 = tcg_const_i32(rn);
5262 tmp3 = tcg_const_i32(rm);
5263 switch (size) {
5264 case 0:
5265 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5266 break;
5267 case 1:
5268 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5269 break;
5270 case 2:
5271 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5272 break;
5275 tcg_temp_free_i32(tmp);
5276 tcg_temp_free_i32(tmp2);
5277 tcg_temp_free_i32(tmp3);
5278 return 0;
5280 if (size == 3 && op != NEON_3R_LOGIC) {
5281 /* 64-bit element instructions. */
5282 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5283 neon_load_reg64(cpu_V0, rn + pass);
5284 neon_load_reg64(cpu_V1, rm + pass);
5285 switch (op) {
5286 case NEON_3R_VQADD:
5287 if (u) {
5288 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5289 cpu_V0, cpu_V1);
5290 } else {
5291 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5292 cpu_V0, cpu_V1);
5294 break;
5295 case NEON_3R_VQSUB:
5296 if (u) {
5297 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5298 cpu_V0, cpu_V1);
5299 } else {
5300 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5301 cpu_V0, cpu_V1);
5303 break;
5304 case NEON_3R_VSHL:
5305 if (u) {
5306 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5307 } else {
5308 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5310 break;
5311 case NEON_3R_VQSHL:
5312 if (u) {
5313 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5314 cpu_V1, cpu_V0);
5315 } else {
5316 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5317 cpu_V1, cpu_V0);
5319 break;
5320 case NEON_3R_VRSHL:
5321 if (u) {
5322 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5323 } else {
5324 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5326 break;
5327 case NEON_3R_VQRSHL:
5328 if (u) {
5329 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5330 cpu_V1, cpu_V0);
5331 } else {
5332 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5333 cpu_V1, cpu_V0);
5335 break;
5336 case NEON_3R_VADD_VSUB:
5337 if (u) {
5338 tcg_gen_sub_i64(CPU_V001);
5339 } else {
5340 tcg_gen_add_i64(CPU_V001);
5342 break;
5343 default:
5344 abort();
5346 neon_store_reg64(cpu_V0, rd + pass);
5348 return 0;
5350 pairwise = 0;
5351 switch (op) {
5352 case NEON_3R_VSHL:
5353 case NEON_3R_VQSHL:
5354 case NEON_3R_VRSHL:
5355 case NEON_3R_VQRSHL:
5357 int rtmp;
5358 /* Shift instruction operands are reversed. */
5359 rtmp = rn;
5360 rn = rm;
5361 rm = rtmp;
5363 break;
5364 case NEON_3R_VPADD:
5365 if (u) {
5366 return 1;
5368 /* Fall through */
5369 case NEON_3R_VPMAX:
5370 case NEON_3R_VPMIN:
5371 pairwise = 1;
5372 break;
5373 case NEON_3R_FLOAT_ARITH:
5374 pairwise = (u && size < 2); /* if VPADD (float) */
5375 break;
5376 case NEON_3R_FLOAT_MINMAX:
5377 pairwise = u; /* if VPMIN/VPMAX (float) */
5378 break;
5379 case NEON_3R_FLOAT_CMP:
5380 if (!u && size) {
5381 /* no encoding for U=0 C=1x */
5382 return 1;
5384 break;
5385 case NEON_3R_FLOAT_ACMP:
5386 if (!u) {
5387 return 1;
5389 break;
5390 case NEON_3R_FLOAT_MISC:
5391 /* VMAXNM/VMINNM in ARMv8 */
5392 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5393 return 1;
5395 break;
5396 case NEON_3R_VMUL:
5397 if (u && (size != 0)) {
5398 /* UNDEF on invalid size for polynomial subcase */
5399 return 1;
5401 break;
5402 case NEON_3R_VFM:
5403 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5404 return 1;
5406 break;
5407 default:
5408 break;
5411 if (pairwise && q) {
5412 /* All the pairwise insns UNDEF if Q is set */
5413 return 1;
5416 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5418 if (pairwise) {
5419 /* Pairwise. */
5420 if (pass < 1) {
5421 tmp = neon_load_reg(rn, 0);
5422 tmp2 = neon_load_reg(rn, 1);
5423 } else {
5424 tmp = neon_load_reg(rm, 0);
5425 tmp2 = neon_load_reg(rm, 1);
5427 } else {
5428 /* Elementwise. */
5429 tmp = neon_load_reg(rn, pass);
5430 tmp2 = neon_load_reg(rm, pass);
5432 switch (op) {
5433 case NEON_3R_VHADD:
5434 GEN_NEON_INTEGER_OP(hadd);
5435 break;
5436 case NEON_3R_VQADD:
5437 GEN_NEON_INTEGER_OP_ENV(qadd);
5438 break;
5439 case NEON_3R_VRHADD:
5440 GEN_NEON_INTEGER_OP(rhadd);
5441 break;
5442 case NEON_3R_LOGIC: /* Logic ops. */
5443 switch ((u << 2) | size) {
5444 case 0: /* VAND */
5445 tcg_gen_and_i32(tmp, tmp, tmp2);
5446 break;
5447 case 1: /* BIC */
5448 tcg_gen_andc_i32(tmp, tmp, tmp2);
5449 break;
5450 case 2: /* VORR */
5451 tcg_gen_or_i32(tmp, tmp, tmp2);
5452 break;
5453 case 3: /* VORN */
5454 tcg_gen_orc_i32(tmp, tmp, tmp2);
5455 break;
5456 case 4: /* VEOR */
5457 tcg_gen_xor_i32(tmp, tmp, tmp2);
5458 break;
5459 case 5: /* VBSL */
5460 tmp3 = neon_load_reg(rd, pass);
5461 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5462 tcg_temp_free_i32(tmp3);
5463 break;
5464 case 6: /* VBIT */
5465 tmp3 = neon_load_reg(rd, pass);
5466 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5467 tcg_temp_free_i32(tmp3);
5468 break;
5469 case 7: /* VBIF */
5470 tmp3 = neon_load_reg(rd, pass);
5471 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5472 tcg_temp_free_i32(tmp3);
5473 break;
5475 break;
5476 case NEON_3R_VHSUB:
5477 GEN_NEON_INTEGER_OP(hsub);
5478 break;
5479 case NEON_3R_VQSUB:
5480 GEN_NEON_INTEGER_OP_ENV(qsub);
5481 break;
5482 case NEON_3R_VCGT:
5483 GEN_NEON_INTEGER_OP(cgt);
5484 break;
5485 case NEON_3R_VCGE:
5486 GEN_NEON_INTEGER_OP(cge);
5487 break;
5488 case NEON_3R_VSHL:
5489 GEN_NEON_INTEGER_OP(shl);
5490 break;
5491 case NEON_3R_VQSHL:
5492 GEN_NEON_INTEGER_OP_ENV(qshl);
5493 break;
5494 case NEON_3R_VRSHL:
5495 GEN_NEON_INTEGER_OP(rshl);
5496 break;
5497 case NEON_3R_VQRSHL:
5498 GEN_NEON_INTEGER_OP_ENV(qrshl);
5499 break;
5500 case NEON_3R_VMAX:
5501 GEN_NEON_INTEGER_OP(max);
5502 break;
5503 case NEON_3R_VMIN:
5504 GEN_NEON_INTEGER_OP(min);
5505 break;
5506 case NEON_3R_VABD:
5507 GEN_NEON_INTEGER_OP(abd);
5508 break;
5509 case NEON_3R_VABA:
5510 GEN_NEON_INTEGER_OP(abd);
5511 tcg_temp_free_i32(tmp2);
5512 tmp2 = neon_load_reg(rd, pass);
5513 gen_neon_add(size, tmp, tmp2);
5514 break;
5515 case NEON_3R_VADD_VSUB:
5516 if (!u) { /* VADD */
5517 gen_neon_add(size, tmp, tmp2);
5518 } else { /* VSUB */
5519 switch (size) {
5520 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5521 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5522 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5523 default: abort();
5526 break;
5527 case NEON_3R_VTST_VCEQ:
5528 if (!u) { /* VTST */
5529 switch (size) {
5530 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5531 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5532 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5533 default: abort();
5535 } else { /* VCEQ */
5536 switch (size) {
5537 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5538 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5539 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5540 default: abort();
5543 break;
5544 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5545 switch (size) {
5546 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5547 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5548 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5549 default: abort();
5551 tcg_temp_free_i32(tmp2);
5552 tmp2 = neon_load_reg(rd, pass);
5553 if (u) { /* VMLS */
5554 gen_neon_rsb(size, tmp, tmp2);
5555 } else { /* VMLA */
5556 gen_neon_add(size, tmp, tmp2);
5558 break;
5559 case NEON_3R_VMUL:
5560 if (u) { /* polynomial */
5561 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5562 } else { /* Integer */
5563 switch (size) {
5564 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5565 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5566 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5567 default: abort();
5570 break;
5571 case NEON_3R_VPMAX:
5572 GEN_NEON_INTEGER_OP(pmax);
5573 break;
5574 case NEON_3R_VPMIN:
5575 GEN_NEON_INTEGER_OP(pmin);
5576 break;
5577 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5578 if (!u) { /* VQDMULH */
5579 switch (size) {
5580 case 1:
5581 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5582 break;
5583 case 2:
5584 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5585 break;
5586 default: abort();
5588 } else { /* VQRDMULH */
5589 switch (size) {
5590 case 1:
5591 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5592 break;
5593 case 2:
5594 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5595 break;
5596 default: abort();
5599 break;
5600 case NEON_3R_VPADD:
5601 switch (size) {
5602 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5603 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5604 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5605 default: abort();
5607 break;
5608 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5610 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5611 switch ((u << 2) | size) {
5612 case 0: /* VADD */
5613 case 4: /* VPADD */
5614 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5615 break;
5616 case 2: /* VSUB */
5617 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5618 break;
5619 case 6: /* VABD */
5620 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5621 break;
5622 default:
5623 abort();
5625 tcg_temp_free_ptr(fpstatus);
5626 break;
5628 case NEON_3R_FLOAT_MULTIPLY:
5630 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5631 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5632 if (!u) {
5633 tcg_temp_free_i32(tmp2);
5634 tmp2 = neon_load_reg(rd, pass);
5635 if (size == 0) {
5636 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5637 } else {
5638 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5641 tcg_temp_free_ptr(fpstatus);
5642 break;
5644 case NEON_3R_FLOAT_CMP:
5646 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5647 if (!u) {
5648 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5649 } else {
5650 if (size == 0) {
5651 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5652 } else {
5653 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5656 tcg_temp_free_ptr(fpstatus);
5657 break;
5659 case NEON_3R_FLOAT_ACMP:
5661 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5662 if (size == 0) {
5663 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5664 } else {
5665 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5667 tcg_temp_free_ptr(fpstatus);
5668 break;
5670 case NEON_3R_FLOAT_MINMAX:
5672 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5673 if (size == 0) {
5674 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5675 } else {
5676 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5678 tcg_temp_free_ptr(fpstatus);
5679 break;
5681 case NEON_3R_FLOAT_MISC:
5682 if (u) {
5683 /* VMAXNM/VMINNM */
5684 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5685 if (size == 0) {
5686 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5687 } else {
5688 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5690 tcg_temp_free_ptr(fpstatus);
5691 } else {
5692 if (size == 0) {
5693 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5694 } else {
5695 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5698 break;
5699 case NEON_3R_VFM:
5701 /* VFMA, VFMS: fused multiply-add */
5702 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5703 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5704 if (size) {
5705 /* VFMS */
5706 gen_helper_vfp_negs(tmp, tmp);
5708 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5709 tcg_temp_free_i32(tmp3);
5710 tcg_temp_free_ptr(fpstatus);
5711 break;
5713 default:
5714 abort();
5716 tcg_temp_free_i32(tmp2);
5718 /* Save the result. For elementwise operations we can put it
5719 straight into the destination register. For pairwise operations
5720 we have to be careful to avoid clobbering the source operands. */
5721 if (pairwise && rd == rm) {
5722 neon_store_scratch(pass, tmp);
5723 } else {
5724 neon_store_reg(rd, pass, tmp);
5727 } /* for pass */
5728 if (pairwise && rd == rm) {
5729 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5730 tmp = neon_load_scratch(pass);
5731 neon_store_reg(rd, pass, tmp);
5734 /* End of 3 register same size operations. */
5735 } else if (insn & (1 << 4)) {
5736 if ((insn & 0x00380080) != 0) {
5737 /* Two registers and shift. */
5738 op = (insn >> 8) & 0xf;
5739 if (insn & (1 << 7)) {
5740 /* 64-bit shift. */
5741 if (op > 7) {
5742 return 1;
5744 size = 3;
5745 } else {
5746 size = 2;
5747 while ((insn & (1 << (size + 19))) == 0)
5748 size--;
5750 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5751 /* To avoid excessive duplication of ops we implement shift
5752 by immediate using the variable shift operations. */
5753 if (op < 8) {
5754 /* Shift by immediate:
5755 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5756 if (q && ((rd | rm) & 1)) {
5757 return 1;
5759 if (!u && (op == 4 || op == 6)) {
5760 return 1;
5762 /* Right shifts are encoded as N - shift, where N is the
5763 element size in bits. */
5764 if (op <= 4)
5765 shift = shift - (1 << (size + 3));
5766 if (size == 3) {
5767 count = q + 1;
5768 } else {
5769 count = q ? 4: 2;
5771 switch (size) {
5772 case 0:
5773 imm = (uint8_t) shift;
5774 imm |= imm << 8;
5775 imm |= imm << 16;
5776 break;
5777 case 1:
5778 imm = (uint16_t) shift;
5779 imm |= imm << 16;
5780 break;
5781 case 2:
5782 case 3:
5783 imm = shift;
5784 break;
5785 default:
5786 abort();
5789 for (pass = 0; pass < count; pass++) {
5790 if (size == 3) {
5791 neon_load_reg64(cpu_V0, rm + pass);
5792 tcg_gen_movi_i64(cpu_V1, imm);
5793 switch (op) {
5794 case 0: /* VSHR */
5795 case 1: /* VSRA */
5796 if (u)
5797 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5798 else
5799 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5800 break;
5801 case 2: /* VRSHR */
5802 case 3: /* VRSRA */
5803 if (u)
5804 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5805 else
5806 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5807 break;
5808 case 4: /* VSRI */
5809 case 5: /* VSHL, VSLI */
5810 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5811 break;
5812 case 6: /* VQSHLU */
5813 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5814 cpu_V0, cpu_V1);
5815 break;
5816 case 7: /* VQSHL */
5817 if (u) {
5818 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5819 cpu_V0, cpu_V1);
5820 } else {
5821 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5822 cpu_V0, cpu_V1);
5824 break;
5826 if (op == 1 || op == 3) {
5827 /* Accumulate. */
5828 neon_load_reg64(cpu_V1, rd + pass);
5829 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5830 } else if (op == 4 || (op == 5 && u)) {
5831 /* Insert */
5832 neon_load_reg64(cpu_V1, rd + pass);
5833 uint64_t mask;
5834 if (shift < -63 || shift > 63) {
5835 mask = 0;
5836 } else {
5837 if (op == 4) {
5838 mask = 0xffffffffffffffffull >> -shift;
5839 } else {
5840 mask = 0xffffffffffffffffull << shift;
5843 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5844 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5846 neon_store_reg64(cpu_V0, rd + pass);
5847 } else { /* size < 3 */
5848 /* Operands in T0 and T1. */
5849 tmp = neon_load_reg(rm, pass);
5850 tmp2 = tcg_temp_new_i32();
5851 tcg_gen_movi_i32(tmp2, imm);
5852 switch (op) {
5853 case 0: /* VSHR */
5854 case 1: /* VSRA */
5855 GEN_NEON_INTEGER_OP(shl);
5856 break;
5857 case 2: /* VRSHR */
5858 case 3: /* VRSRA */
5859 GEN_NEON_INTEGER_OP(rshl);
5860 break;
5861 case 4: /* VSRI */
5862 case 5: /* VSHL, VSLI */
5863 switch (size) {
5864 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5865 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5866 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5867 default: abort();
5869 break;
5870 case 6: /* VQSHLU */
5871 switch (size) {
5872 case 0:
5873 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5874 tmp, tmp2);
5875 break;
5876 case 1:
5877 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5878 tmp, tmp2);
5879 break;
5880 case 2:
5881 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5882 tmp, tmp2);
5883 break;
5884 default:
5885 abort();
5887 break;
5888 case 7: /* VQSHL */
5889 GEN_NEON_INTEGER_OP_ENV(qshl);
5890 break;
5892 tcg_temp_free_i32(tmp2);
5894 if (op == 1 || op == 3) {
5895 /* Accumulate. */
5896 tmp2 = neon_load_reg(rd, pass);
5897 gen_neon_add(size, tmp, tmp2);
5898 tcg_temp_free_i32(tmp2);
5899 } else if (op == 4 || (op == 5 && u)) {
5900 /* Insert */
5901 switch (size) {
5902 case 0:
5903 if (op == 4)
5904 mask = 0xff >> -shift;
5905 else
5906 mask = (uint8_t)(0xff << shift);
5907 mask |= mask << 8;
5908 mask |= mask << 16;
5909 break;
5910 case 1:
5911 if (op == 4)
5912 mask = 0xffff >> -shift;
5913 else
5914 mask = (uint16_t)(0xffff << shift);
5915 mask |= mask << 16;
5916 break;
5917 case 2:
5918 if (shift < -31 || shift > 31) {
5919 mask = 0;
5920 } else {
5921 if (op == 4)
5922 mask = 0xffffffffu >> -shift;
5923 else
5924 mask = 0xffffffffu << shift;
5926 break;
5927 default:
5928 abort();
5930 tmp2 = neon_load_reg(rd, pass);
5931 tcg_gen_andi_i32(tmp, tmp, mask);
5932 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5933 tcg_gen_or_i32(tmp, tmp, tmp2);
5934 tcg_temp_free_i32(tmp2);
5936 neon_store_reg(rd, pass, tmp);
5938 } /* for pass */
5939 } else if (op < 10) {
5940 /* Shift by immediate and narrow:
5941 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5942 int input_unsigned = (op == 8) ? !u : u;
5943 if (rm & 1) {
5944 return 1;
5946 shift = shift - (1 << (size + 3));
5947 size++;
5948 if (size == 3) {
5949 tmp64 = tcg_const_i64(shift);
5950 neon_load_reg64(cpu_V0, rm);
5951 neon_load_reg64(cpu_V1, rm + 1);
5952 for (pass = 0; pass < 2; pass++) {
5953 TCGv_i64 in;
5954 if (pass == 0) {
5955 in = cpu_V0;
5956 } else {
5957 in = cpu_V1;
5959 if (q) {
5960 if (input_unsigned) {
5961 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5962 } else {
5963 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5965 } else {
5966 if (input_unsigned) {
5967 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5968 } else {
5969 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5972 tmp = tcg_temp_new_i32();
5973 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5974 neon_store_reg(rd, pass, tmp);
5975 } /* for pass */
5976 tcg_temp_free_i64(tmp64);
5977 } else {
5978 if (size == 1) {
5979 imm = (uint16_t)shift;
5980 imm |= imm << 16;
5981 } else {
5982 /* size == 2 */
5983 imm = (uint32_t)shift;
5985 tmp2 = tcg_const_i32(imm);
5986 tmp4 = neon_load_reg(rm + 1, 0);
5987 tmp5 = neon_load_reg(rm + 1, 1);
5988 for (pass = 0; pass < 2; pass++) {
5989 if (pass == 0) {
5990 tmp = neon_load_reg(rm, 0);
5991 } else {
5992 tmp = tmp4;
5994 gen_neon_shift_narrow(size, tmp, tmp2, q,
5995 input_unsigned);
5996 if (pass == 0) {
5997 tmp3 = neon_load_reg(rm, 1);
5998 } else {
5999 tmp3 = tmp5;
6001 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6002 input_unsigned);
6003 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6004 tcg_temp_free_i32(tmp);
6005 tcg_temp_free_i32(tmp3);
6006 tmp = tcg_temp_new_i32();
6007 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6008 neon_store_reg(rd, pass, tmp);
6009 } /* for pass */
6010 tcg_temp_free_i32(tmp2);
6012 } else if (op == 10) {
6013 /* VSHLL, VMOVL */
6014 if (q || (rd & 1)) {
6015 return 1;
6017 tmp = neon_load_reg(rm, 0);
6018 tmp2 = neon_load_reg(rm, 1);
6019 for (pass = 0; pass < 2; pass++) {
6020 if (pass == 1)
6021 tmp = tmp2;
6023 gen_neon_widen(cpu_V0, tmp, size, u);
6025 if (shift != 0) {
6026 /* The shift is less than the width of the source
6027 type, so we can just shift the whole register. */
6028 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6029 /* Widen the result of shift: we need to clear
6030 * the potential overflow bits resulting from
6031 * left bits of the narrow input appearing as
6032 * right bits of left the neighbour narrow
6033 * input. */
6034 if (size < 2 || !u) {
6035 uint64_t imm64;
6036 if (size == 0) {
6037 imm = (0xffu >> (8 - shift));
6038 imm |= imm << 16;
6039 } else if (size == 1) {
6040 imm = 0xffff >> (16 - shift);
6041 } else {
6042 /* size == 2 */
6043 imm = 0xffffffff >> (32 - shift);
6045 if (size < 2) {
6046 imm64 = imm | (((uint64_t)imm) << 32);
6047 } else {
6048 imm64 = imm;
6050 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6053 neon_store_reg64(cpu_V0, rd + pass);
6055 } else if (op >= 14) {
6056 /* VCVT fixed-point. */
6057 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6058 return 1;
6060 /* We have already masked out the must-be-1 top bit of imm6,
6061 * hence this 32-shift where the ARM ARM has 64-imm6.
6063 shift = 32 - shift;
6064 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6065 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6066 if (!(op & 1)) {
6067 if (u)
6068 gen_vfp_ulto(0, shift, 1);
6069 else
6070 gen_vfp_slto(0, shift, 1);
6071 } else {
6072 if (u)
6073 gen_vfp_toul(0, shift, 1);
6074 else
6075 gen_vfp_tosl(0, shift, 1);
6077 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6079 } else {
6080 return 1;
6082 } else { /* (insn & 0x00380080) == 0 */
6083 int invert;
6084 if (q && (rd & 1)) {
6085 return 1;
6088 op = (insn >> 8) & 0xf;
6089 /* One register and immediate. */
6090 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6091 invert = (insn & (1 << 5)) != 0;
6092 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6093 * We choose to not special-case this and will behave as if a
6094 * valid constant encoding of 0 had been given.
6096 switch (op) {
6097 case 0: case 1:
6098 /* no-op */
6099 break;
6100 case 2: case 3:
6101 imm <<= 8;
6102 break;
6103 case 4: case 5:
6104 imm <<= 16;
6105 break;
6106 case 6: case 7:
6107 imm <<= 24;
6108 break;
6109 case 8: case 9:
6110 imm |= imm << 16;
6111 break;
6112 case 10: case 11:
6113 imm = (imm << 8) | (imm << 24);
6114 break;
6115 case 12:
6116 imm = (imm << 8) | 0xff;
6117 break;
6118 case 13:
6119 imm = (imm << 16) | 0xffff;
6120 break;
6121 case 14:
6122 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6123 if (invert)
6124 imm = ~imm;
6125 break;
6126 case 15:
6127 if (invert) {
6128 return 1;
6130 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6131 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6132 break;
6134 if (invert)
6135 imm = ~imm;
6137 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6138 if (op & 1 && op < 12) {
6139 tmp = neon_load_reg(rd, pass);
6140 if (invert) {
6141 /* The immediate value has already been inverted, so
6142 BIC becomes AND. */
6143 tcg_gen_andi_i32(tmp, tmp, imm);
6144 } else {
6145 tcg_gen_ori_i32(tmp, tmp, imm);
6147 } else {
6148 /* VMOV, VMVN. */
6149 tmp = tcg_temp_new_i32();
6150 if (op == 14 && invert) {
6151 int n;
6152 uint32_t val;
6153 val = 0;
6154 for (n = 0; n < 4; n++) {
6155 if (imm & (1 << (n + (pass & 1) * 4)))
6156 val |= 0xff << (n * 8);
6158 tcg_gen_movi_i32(tmp, val);
6159 } else {
6160 tcg_gen_movi_i32(tmp, imm);
6163 neon_store_reg(rd, pass, tmp);
6166 } else { /* (insn & 0x00800010 == 0x00800000) */
6167 if (size != 3) {
6168 op = (insn >> 8) & 0xf;
6169 if ((insn & (1 << 6)) == 0) {
6170 /* Three registers of different lengths. */
6171 int src1_wide;
6172 int src2_wide;
6173 int prewiden;
6174 /* undefreq: bit 0 : UNDEF if size == 0
6175 * bit 1 : UNDEF if size == 1
6176 * bit 2 : UNDEF if size == 2
6177 * bit 3 : UNDEF if U == 1
6178 * Note that [2:0] set implies 'always UNDEF'
6180 int undefreq;
6181 /* prewiden, src1_wide, src2_wide, undefreq */
6182 static const int neon_3reg_wide[16][4] = {
6183 {1, 0, 0, 0}, /* VADDL */
6184 {1, 1, 0, 0}, /* VADDW */
6185 {1, 0, 0, 0}, /* VSUBL */
6186 {1, 1, 0, 0}, /* VSUBW */
6187 {0, 1, 1, 0}, /* VADDHN */
6188 {0, 0, 0, 0}, /* VABAL */
6189 {0, 1, 1, 0}, /* VSUBHN */
6190 {0, 0, 0, 0}, /* VABDL */
6191 {0, 0, 0, 0}, /* VMLAL */
6192 {0, 0, 0, 9}, /* VQDMLAL */
6193 {0, 0, 0, 0}, /* VMLSL */
6194 {0, 0, 0, 9}, /* VQDMLSL */
6195 {0, 0, 0, 0}, /* Integer VMULL */
6196 {0, 0, 0, 1}, /* VQDMULL */
6197 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6198 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6201 prewiden = neon_3reg_wide[op][0];
6202 src1_wide = neon_3reg_wide[op][1];
6203 src2_wide = neon_3reg_wide[op][2];
6204 undefreq = neon_3reg_wide[op][3];
6206 if ((undefreq & (1 << size)) ||
6207 ((undefreq & 8) && u)) {
6208 return 1;
6210 if ((src1_wide && (rn & 1)) ||
6211 (src2_wide && (rm & 1)) ||
6212 (!src2_wide && (rd & 1))) {
6213 return 1;
6216 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6217 * outside the loop below as it only performs a single pass.
6219 if (op == 14 && size == 2) {
6220 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6222 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6223 return 1;
6225 tcg_rn = tcg_temp_new_i64();
6226 tcg_rm = tcg_temp_new_i64();
6227 tcg_rd = tcg_temp_new_i64();
6228 neon_load_reg64(tcg_rn, rn);
6229 neon_load_reg64(tcg_rm, rm);
6230 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6231 neon_store_reg64(tcg_rd, rd);
6232 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6233 neon_store_reg64(tcg_rd, rd + 1);
6234 tcg_temp_free_i64(tcg_rn);
6235 tcg_temp_free_i64(tcg_rm);
6236 tcg_temp_free_i64(tcg_rd);
6237 return 0;
6240 /* Avoid overlapping operands. Wide source operands are
6241 always aligned so will never overlap with wide
6242 destinations in problematic ways. */
6243 if (rd == rm && !src2_wide) {
6244 tmp = neon_load_reg(rm, 1);
6245 neon_store_scratch(2, tmp);
6246 } else if (rd == rn && !src1_wide) {
6247 tmp = neon_load_reg(rn, 1);
6248 neon_store_scratch(2, tmp);
6250 TCGV_UNUSED_I32(tmp3);
6251 for (pass = 0; pass < 2; pass++) {
6252 if (src1_wide) {
6253 neon_load_reg64(cpu_V0, rn + pass);
6254 TCGV_UNUSED_I32(tmp);
6255 } else {
6256 if (pass == 1 && rd == rn) {
6257 tmp = neon_load_scratch(2);
6258 } else {
6259 tmp = neon_load_reg(rn, pass);
6261 if (prewiden) {
6262 gen_neon_widen(cpu_V0, tmp, size, u);
6265 if (src2_wide) {
6266 neon_load_reg64(cpu_V1, rm + pass);
6267 TCGV_UNUSED_I32(tmp2);
6268 } else {
6269 if (pass == 1 && rd == rm) {
6270 tmp2 = neon_load_scratch(2);
6271 } else {
6272 tmp2 = neon_load_reg(rm, pass);
6274 if (prewiden) {
6275 gen_neon_widen(cpu_V1, tmp2, size, u);
6278 switch (op) {
6279 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6280 gen_neon_addl(size);
6281 break;
6282 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6283 gen_neon_subl(size);
6284 break;
6285 case 5: case 7: /* VABAL, VABDL */
6286 switch ((size << 1) | u) {
6287 case 0:
6288 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6289 break;
6290 case 1:
6291 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6292 break;
6293 case 2:
6294 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6295 break;
6296 case 3:
6297 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6298 break;
6299 case 4:
6300 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6301 break;
6302 case 5:
6303 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6304 break;
6305 default: abort();
6307 tcg_temp_free_i32(tmp2);
6308 tcg_temp_free_i32(tmp);
6309 break;
6310 case 8: case 9: case 10: case 11: case 12: case 13:
6311 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6312 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6313 break;
6314 case 14: /* Polynomial VMULL */
6315 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6316 tcg_temp_free_i32(tmp2);
6317 tcg_temp_free_i32(tmp);
6318 break;
6319 default: /* 15 is RESERVED: caught earlier */
6320 abort();
6322 if (op == 13) {
6323 /* VQDMULL */
6324 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6325 neon_store_reg64(cpu_V0, rd + pass);
6326 } else if (op == 5 || (op >= 8 && op <= 11)) {
6327 /* Accumulate. */
6328 neon_load_reg64(cpu_V1, rd + pass);
6329 switch (op) {
6330 case 10: /* VMLSL */
6331 gen_neon_negl(cpu_V0, size);
6332 /* Fall through */
6333 case 5: case 8: /* VABAL, VMLAL */
6334 gen_neon_addl(size);
6335 break;
6336 case 9: case 11: /* VQDMLAL, VQDMLSL */
6337 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6338 if (op == 11) {
6339 gen_neon_negl(cpu_V0, size);
6341 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6342 break;
6343 default:
6344 abort();
6346 neon_store_reg64(cpu_V0, rd + pass);
6347 } else if (op == 4 || op == 6) {
6348 /* Narrowing operation. */
6349 tmp = tcg_temp_new_i32();
6350 if (!u) {
6351 switch (size) {
6352 case 0:
6353 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6354 break;
6355 case 1:
6356 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6357 break;
6358 case 2:
6359 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6360 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6361 break;
6362 default: abort();
6364 } else {
6365 switch (size) {
6366 case 0:
6367 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6368 break;
6369 case 1:
6370 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6371 break;
6372 case 2:
6373 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6374 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6375 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6376 break;
6377 default: abort();
6380 if (pass == 0) {
6381 tmp3 = tmp;
6382 } else {
6383 neon_store_reg(rd, 0, tmp3);
6384 neon_store_reg(rd, 1, tmp);
6386 } else {
6387 /* Write back the result. */
6388 neon_store_reg64(cpu_V0, rd + pass);
6391 } else {
6392 /* Two registers and a scalar. NB that for ops of this form
6393 * the ARM ARM labels bit 24 as Q, but it is in our variable
6394 * 'u', not 'q'.
6396 if (size == 0) {
6397 return 1;
6399 switch (op) {
6400 case 1: /* Float VMLA scalar */
6401 case 5: /* Floating point VMLS scalar */
6402 case 9: /* Floating point VMUL scalar */
6403 if (size == 1) {
6404 return 1;
6406 /* fall through */
6407 case 0: /* Integer VMLA scalar */
6408 case 4: /* Integer VMLS scalar */
6409 case 8: /* Integer VMUL scalar */
6410 case 12: /* VQDMULH scalar */
6411 case 13: /* VQRDMULH scalar */
6412 if (u && ((rd | rn) & 1)) {
6413 return 1;
6415 tmp = neon_get_scalar(size, rm);
6416 neon_store_scratch(0, tmp);
6417 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6418 tmp = neon_load_scratch(0);
6419 tmp2 = neon_load_reg(rn, pass);
6420 if (op == 12) {
6421 if (size == 1) {
6422 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6423 } else {
6424 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6426 } else if (op == 13) {
6427 if (size == 1) {
6428 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6429 } else {
6430 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6432 } else if (op & 1) {
6433 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6434 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6435 tcg_temp_free_ptr(fpstatus);
6436 } else {
6437 switch (size) {
6438 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6439 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6440 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6441 default: abort();
6444 tcg_temp_free_i32(tmp2);
6445 if (op < 8) {
6446 /* Accumulate. */
6447 tmp2 = neon_load_reg(rd, pass);
6448 switch (op) {
6449 case 0:
6450 gen_neon_add(size, tmp, tmp2);
6451 break;
6452 case 1:
6454 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6455 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6456 tcg_temp_free_ptr(fpstatus);
6457 break;
6459 case 4:
6460 gen_neon_rsb(size, tmp, tmp2);
6461 break;
6462 case 5:
6464 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6465 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6466 tcg_temp_free_ptr(fpstatus);
6467 break;
6469 default:
6470 abort();
6472 tcg_temp_free_i32(tmp2);
6474 neon_store_reg(rd, pass, tmp);
6476 break;
6477 case 3: /* VQDMLAL scalar */
6478 case 7: /* VQDMLSL scalar */
6479 case 11: /* VQDMULL scalar */
6480 if (u == 1) {
6481 return 1;
6483 /* fall through */
6484 case 2: /* VMLAL sclar */
6485 case 6: /* VMLSL scalar */
6486 case 10: /* VMULL scalar */
6487 if (rd & 1) {
6488 return 1;
6490 tmp2 = neon_get_scalar(size, rm);
6491 /* We need a copy of tmp2 because gen_neon_mull
6492 * deletes it during pass 0. */
6493 tmp4 = tcg_temp_new_i32();
6494 tcg_gen_mov_i32(tmp4, tmp2);
6495 tmp3 = neon_load_reg(rn, 1);
6497 for (pass = 0; pass < 2; pass++) {
6498 if (pass == 0) {
6499 tmp = neon_load_reg(rn, 0);
6500 } else {
6501 tmp = tmp3;
6502 tmp2 = tmp4;
6504 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6505 if (op != 11) {
6506 neon_load_reg64(cpu_V1, rd + pass);
6508 switch (op) {
6509 case 6:
6510 gen_neon_negl(cpu_V0, size);
6511 /* Fall through */
6512 case 2:
6513 gen_neon_addl(size);
6514 break;
6515 case 3: case 7:
6516 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6517 if (op == 7) {
6518 gen_neon_negl(cpu_V0, size);
6520 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6521 break;
6522 case 10:
6523 /* no-op */
6524 break;
6525 case 11:
6526 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6527 break;
6528 default:
6529 abort();
6531 neon_store_reg64(cpu_V0, rd + pass);
6535 break;
6536 default: /* 14 and 15 are RESERVED */
6537 return 1;
6540 } else { /* size == 3 */
6541 if (!u) {
6542 /* Extract. */
6543 imm = (insn >> 8) & 0xf;
6545 if (imm > 7 && !q)
6546 return 1;
6548 if (q && ((rd | rn | rm) & 1)) {
6549 return 1;
6552 if (imm == 0) {
6553 neon_load_reg64(cpu_V0, rn);
6554 if (q) {
6555 neon_load_reg64(cpu_V1, rn + 1);
6557 } else if (imm == 8) {
6558 neon_load_reg64(cpu_V0, rn + 1);
6559 if (q) {
6560 neon_load_reg64(cpu_V1, rm);
6562 } else if (q) {
6563 tmp64 = tcg_temp_new_i64();
6564 if (imm < 8) {
6565 neon_load_reg64(cpu_V0, rn);
6566 neon_load_reg64(tmp64, rn + 1);
6567 } else {
6568 neon_load_reg64(cpu_V0, rn + 1);
6569 neon_load_reg64(tmp64, rm);
6571 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6572 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6573 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6574 if (imm < 8) {
6575 neon_load_reg64(cpu_V1, rm);
6576 } else {
6577 neon_load_reg64(cpu_V1, rm + 1);
6578 imm -= 8;
6580 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6581 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6582 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6583 tcg_temp_free_i64(tmp64);
6584 } else {
6585 /* BUGFIX */
6586 neon_load_reg64(cpu_V0, rn);
6587 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6588 neon_load_reg64(cpu_V1, rm);
6589 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6590 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6592 neon_store_reg64(cpu_V0, rd);
6593 if (q) {
6594 neon_store_reg64(cpu_V1, rd + 1);
6596 } else if ((insn & (1 << 11)) == 0) {
6597 /* Two register misc. */
6598 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6599 size = (insn >> 18) & 3;
6600 /* UNDEF for unknown op values and bad op-size combinations */
6601 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6602 return 1;
6604 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6605 q && ((rm | rd) & 1)) {
6606 return 1;
6608 switch (op) {
6609 case NEON_2RM_VREV64:
6610 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6611 tmp = neon_load_reg(rm, pass * 2);
6612 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6613 switch (size) {
6614 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6615 case 1: gen_swap_half(tmp); break;
6616 case 2: /* no-op */ break;
6617 default: abort();
6619 neon_store_reg(rd, pass * 2 + 1, tmp);
6620 if (size == 2) {
6621 neon_store_reg(rd, pass * 2, tmp2);
6622 } else {
6623 switch (size) {
6624 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6625 case 1: gen_swap_half(tmp2); break;
6626 default: abort();
6628 neon_store_reg(rd, pass * 2, tmp2);
6631 break;
6632 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6633 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6634 for (pass = 0; pass < q + 1; pass++) {
6635 tmp = neon_load_reg(rm, pass * 2);
6636 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6637 tmp = neon_load_reg(rm, pass * 2 + 1);
6638 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6639 switch (size) {
6640 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6641 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6642 case 2: tcg_gen_add_i64(CPU_V001); break;
6643 default: abort();
6645 if (op >= NEON_2RM_VPADAL) {
6646 /* Accumulate. */
6647 neon_load_reg64(cpu_V1, rd + pass);
6648 gen_neon_addl(size);
6650 neon_store_reg64(cpu_V0, rd + pass);
6652 break;
6653 case NEON_2RM_VTRN:
6654 if (size == 2) {
6655 int n;
6656 for (n = 0; n < (q ? 4 : 2); n += 2) {
6657 tmp = neon_load_reg(rm, n);
6658 tmp2 = neon_load_reg(rd, n + 1);
6659 neon_store_reg(rm, n, tmp2);
6660 neon_store_reg(rd, n + 1, tmp);
6662 } else {
6663 goto elementwise;
6665 break;
6666 case NEON_2RM_VUZP:
6667 if (gen_neon_unzip(rd, rm, size, q)) {
6668 return 1;
6670 break;
6671 case NEON_2RM_VZIP:
6672 if (gen_neon_zip(rd, rm, size, q)) {
6673 return 1;
6675 break;
6676 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6677 /* also VQMOVUN; op field and mnemonics don't line up */
6678 if (rm & 1) {
6679 return 1;
6681 TCGV_UNUSED_I32(tmp2);
6682 for (pass = 0; pass < 2; pass++) {
6683 neon_load_reg64(cpu_V0, rm + pass);
6684 tmp = tcg_temp_new_i32();
6685 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6686 tmp, cpu_V0);
6687 if (pass == 0) {
6688 tmp2 = tmp;
6689 } else {
6690 neon_store_reg(rd, 0, tmp2);
6691 neon_store_reg(rd, 1, tmp);
6694 break;
6695 case NEON_2RM_VSHLL:
6696 if (q || (rd & 1)) {
6697 return 1;
6699 tmp = neon_load_reg(rm, 0);
6700 tmp2 = neon_load_reg(rm, 1);
6701 for (pass = 0; pass < 2; pass++) {
6702 if (pass == 1)
6703 tmp = tmp2;
6704 gen_neon_widen(cpu_V0, tmp, size, 1);
6705 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6706 neon_store_reg64(cpu_V0, rd + pass);
6708 break;
6709 case NEON_2RM_VCVT_F16_F32:
6710 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6711 q || (rm & 1)) {
6712 return 1;
6714 tmp = tcg_temp_new_i32();
6715 tmp2 = tcg_temp_new_i32();
6716 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6717 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6718 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6719 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6720 tcg_gen_shli_i32(tmp2, tmp2, 16);
6721 tcg_gen_or_i32(tmp2, tmp2, tmp);
6722 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6723 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6724 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6725 neon_store_reg(rd, 0, tmp2);
6726 tmp2 = tcg_temp_new_i32();
6727 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6728 tcg_gen_shli_i32(tmp2, tmp2, 16);
6729 tcg_gen_or_i32(tmp2, tmp2, tmp);
6730 neon_store_reg(rd, 1, tmp2);
6731 tcg_temp_free_i32(tmp);
6732 break;
6733 case NEON_2RM_VCVT_F32_F16:
6734 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6735 q || (rd & 1)) {
6736 return 1;
6738 tmp3 = tcg_temp_new_i32();
6739 tmp = neon_load_reg(rm, 0);
6740 tmp2 = neon_load_reg(rm, 1);
6741 tcg_gen_ext16u_i32(tmp3, tmp);
6742 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6743 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6744 tcg_gen_shri_i32(tmp3, tmp, 16);
6745 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6746 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6747 tcg_temp_free_i32(tmp);
6748 tcg_gen_ext16u_i32(tmp3, tmp2);
6749 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6750 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6751 tcg_gen_shri_i32(tmp3, tmp2, 16);
6752 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6753 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6754 tcg_temp_free_i32(tmp2);
6755 tcg_temp_free_i32(tmp3);
6756 break;
6757 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6758 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6759 || ((rm | rd) & 1)) {
6760 return 1;
6762 tmp = tcg_const_i32(rd);
6763 tmp2 = tcg_const_i32(rm);
6765 /* Bit 6 is the lowest opcode bit; it distinguishes between
6766 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6768 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6770 if (op == NEON_2RM_AESE) {
6771 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6772 } else {
6773 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6775 tcg_temp_free_i32(tmp);
6776 tcg_temp_free_i32(tmp2);
6777 tcg_temp_free_i32(tmp3);
6778 break;
6779 case NEON_2RM_SHA1H:
6780 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
6781 || ((rm | rd) & 1)) {
6782 return 1;
6784 tmp = tcg_const_i32(rd);
6785 tmp2 = tcg_const_i32(rm);
6787 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
6789 tcg_temp_free_i32(tmp);
6790 tcg_temp_free_i32(tmp2);
6791 break;
6792 case NEON_2RM_SHA1SU1:
6793 if ((rm | rd) & 1) {
6794 return 1;
6796 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6797 if (q) {
6798 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
6799 return 1;
6801 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
6802 return 1;
6804 tmp = tcg_const_i32(rd);
6805 tmp2 = tcg_const_i32(rm);
6806 if (q) {
6807 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
6808 } else {
6809 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
6811 tcg_temp_free_i32(tmp);
6812 tcg_temp_free_i32(tmp2);
6813 break;
6814 default:
6815 elementwise:
6816 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6817 if (neon_2rm_is_float_op(op)) {
6818 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6819 neon_reg_offset(rm, pass));
6820 TCGV_UNUSED_I32(tmp);
6821 } else {
6822 tmp = neon_load_reg(rm, pass);
6824 switch (op) {
6825 case NEON_2RM_VREV32:
6826 switch (size) {
6827 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6828 case 1: gen_swap_half(tmp); break;
6829 default: abort();
6831 break;
6832 case NEON_2RM_VREV16:
6833 gen_rev16(tmp);
6834 break;
6835 case NEON_2RM_VCLS:
6836 switch (size) {
6837 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6838 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6839 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6840 default: abort();
6842 break;
6843 case NEON_2RM_VCLZ:
6844 switch (size) {
6845 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6846 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6847 case 2: gen_helper_clz(tmp, tmp); break;
6848 default: abort();
6850 break;
6851 case NEON_2RM_VCNT:
6852 gen_helper_neon_cnt_u8(tmp, tmp);
6853 break;
6854 case NEON_2RM_VMVN:
6855 tcg_gen_not_i32(tmp, tmp);
6856 break;
6857 case NEON_2RM_VQABS:
6858 switch (size) {
6859 case 0:
6860 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6861 break;
6862 case 1:
6863 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6864 break;
6865 case 2:
6866 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6867 break;
6868 default: abort();
6870 break;
6871 case NEON_2RM_VQNEG:
6872 switch (size) {
6873 case 0:
6874 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6875 break;
6876 case 1:
6877 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6878 break;
6879 case 2:
6880 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6881 break;
6882 default: abort();
6884 break;
6885 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6886 tmp2 = tcg_const_i32(0);
6887 switch(size) {
6888 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6889 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6890 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6891 default: abort();
6893 tcg_temp_free_i32(tmp2);
6894 if (op == NEON_2RM_VCLE0) {
6895 tcg_gen_not_i32(tmp, tmp);
6897 break;
6898 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6899 tmp2 = tcg_const_i32(0);
6900 switch(size) {
6901 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6902 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6903 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6904 default: abort();
6906 tcg_temp_free_i32(tmp2);
6907 if (op == NEON_2RM_VCLT0) {
6908 tcg_gen_not_i32(tmp, tmp);
6910 break;
6911 case NEON_2RM_VCEQ0:
6912 tmp2 = tcg_const_i32(0);
6913 switch(size) {
6914 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6915 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6916 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6917 default: abort();
6919 tcg_temp_free_i32(tmp2);
6920 break;
6921 case NEON_2RM_VABS:
6922 switch(size) {
6923 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6924 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6925 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6926 default: abort();
6928 break;
6929 case NEON_2RM_VNEG:
6930 tmp2 = tcg_const_i32(0);
6931 gen_neon_rsb(size, tmp, tmp2);
6932 tcg_temp_free_i32(tmp2);
6933 break;
6934 case NEON_2RM_VCGT0_F:
6936 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6937 tmp2 = tcg_const_i32(0);
6938 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6939 tcg_temp_free_i32(tmp2);
6940 tcg_temp_free_ptr(fpstatus);
6941 break;
6943 case NEON_2RM_VCGE0_F:
6945 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6946 tmp2 = tcg_const_i32(0);
6947 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6948 tcg_temp_free_i32(tmp2);
6949 tcg_temp_free_ptr(fpstatus);
6950 break;
6952 case NEON_2RM_VCEQ0_F:
6954 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6955 tmp2 = tcg_const_i32(0);
6956 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6957 tcg_temp_free_i32(tmp2);
6958 tcg_temp_free_ptr(fpstatus);
6959 break;
6961 case NEON_2RM_VCLE0_F:
6963 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6964 tmp2 = tcg_const_i32(0);
6965 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6966 tcg_temp_free_i32(tmp2);
6967 tcg_temp_free_ptr(fpstatus);
6968 break;
6970 case NEON_2RM_VCLT0_F:
6972 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6973 tmp2 = tcg_const_i32(0);
6974 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6975 tcg_temp_free_i32(tmp2);
6976 tcg_temp_free_ptr(fpstatus);
6977 break;
6979 case NEON_2RM_VABS_F:
6980 gen_vfp_abs(0);
6981 break;
6982 case NEON_2RM_VNEG_F:
6983 gen_vfp_neg(0);
6984 break;
6985 case NEON_2RM_VSWP:
6986 tmp2 = neon_load_reg(rd, pass);
6987 neon_store_reg(rm, pass, tmp2);
6988 break;
6989 case NEON_2RM_VTRN:
6990 tmp2 = neon_load_reg(rd, pass);
6991 switch (size) {
6992 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6993 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6994 default: abort();
6996 neon_store_reg(rm, pass, tmp2);
6997 break;
6998 case NEON_2RM_VRINTN:
6999 case NEON_2RM_VRINTA:
7000 case NEON_2RM_VRINTM:
7001 case NEON_2RM_VRINTP:
7002 case NEON_2RM_VRINTZ:
7004 TCGv_i32 tcg_rmode;
7005 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7006 int rmode;
7008 if (op == NEON_2RM_VRINTZ) {
7009 rmode = FPROUNDING_ZERO;
7010 } else {
7011 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7014 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7015 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7016 cpu_env);
7017 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7018 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7019 cpu_env);
7020 tcg_temp_free_ptr(fpstatus);
7021 tcg_temp_free_i32(tcg_rmode);
7022 break;
7024 case NEON_2RM_VRINTX:
7026 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7027 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7028 tcg_temp_free_ptr(fpstatus);
7029 break;
7031 case NEON_2RM_VCVTAU:
7032 case NEON_2RM_VCVTAS:
7033 case NEON_2RM_VCVTNU:
7034 case NEON_2RM_VCVTNS:
7035 case NEON_2RM_VCVTPU:
7036 case NEON_2RM_VCVTPS:
7037 case NEON_2RM_VCVTMU:
7038 case NEON_2RM_VCVTMS:
7040 bool is_signed = !extract32(insn, 7, 1);
7041 TCGv_ptr fpst = get_fpstatus_ptr(1);
7042 TCGv_i32 tcg_rmode, tcg_shift;
7043 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7045 tcg_shift = tcg_const_i32(0);
7046 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7047 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7048 cpu_env);
7050 if (is_signed) {
7051 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7052 tcg_shift, fpst);
7053 } else {
7054 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7055 tcg_shift, fpst);
7058 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7059 cpu_env);
7060 tcg_temp_free_i32(tcg_rmode);
7061 tcg_temp_free_i32(tcg_shift);
7062 tcg_temp_free_ptr(fpst);
7063 break;
7065 case NEON_2RM_VRECPE:
7067 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7068 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7069 tcg_temp_free_ptr(fpstatus);
7070 break;
7072 case NEON_2RM_VRSQRTE:
7074 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7075 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7076 tcg_temp_free_ptr(fpstatus);
7077 break;
7079 case NEON_2RM_VRECPE_F:
7081 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7082 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7083 tcg_temp_free_ptr(fpstatus);
7084 break;
7086 case NEON_2RM_VRSQRTE_F:
7088 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7089 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7090 tcg_temp_free_ptr(fpstatus);
7091 break;
7093 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7094 gen_vfp_sito(0, 1);
7095 break;
7096 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7097 gen_vfp_uito(0, 1);
7098 break;
7099 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7100 gen_vfp_tosiz(0, 1);
7101 break;
7102 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7103 gen_vfp_touiz(0, 1);
7104 break;
7105 default:
7106 /* Reserved op values were caught by the
7107 * neon_2rm_sizes[] check earlier.
7109 abort();
7111 if (neon_2rm_is_float_op(op)) {
7112 tcg_gen_st_f32(cpu_F0s, cpu_env,
7113 neon_reg_offset(rd, pass));
7114 } else {
7115 neon_store_reg(rd, pass, tmp);
7118 break;
7120 } else if ((insn & (1 << 10)) == 0) {
7121 /* VTBL, VTBX. */
7122 int n = ((insn >> 8) & 3) + 1;
7123 if ((rn + n) > 32) {
7124 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7125 * helper function running off the end of the register file.
7127 return 1;
7129 n <<= 3;
7130 if (insn & (1 << 6)) {
7131 tmp = neon_load_reg(rd, 0);
7132 } else {
7133 tmp = tcg_temp_new_i32();
7134 tcg_gen_movi_i32(tmp, 0);
7136 tmp2 = neon_load_reg(rm, 0);
7137 tmp4 = tcg_const_i32(rn);
7138 tmp5 = tcg_const_i32(n);
7139 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7140 tcg_temp_free_i32(tmp);
7141 if (insn & (1 << 6)) {
7142 tmp = neon_load_reg(rd, 1);
7143 } else {
7144 tmp = tcg_temp_new_i32();
7145 tcg_gen_movi_i32(tmp, 0);
7147 tmp3 = neon_load_reg(rm, 1);
7148 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7149 tcg_temp_free_i32(tmp5);
7150 tcg_temp_free_i32(tmp4);
7151 neon_store_reg(rd, 0, tmp2);
7152 neon_store_reg(rd, 1, tmp3);
7153 tcg_temp_free_i32(tmp);
7154 } else if ((insn & 0x380) == 0) {
7155 /* VDUP */
7156 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7157 return 1;
7159 if (insn & (1 << 19)) {
7160 tmp = neon_load_reg(rm, 1);
7161 } else {
7162 tmp = neon_load_reg(rm, 0);
7164 if (insn & (1 << 16)) {
7165 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7166 } else if (insn & (1 << 17)) {
7167 if ((insn >> 18) & 1)
7168 gen_neon_dup_high16(tmp);
7169 else
7170 gen_neon_dup_low16(tmp);
7172 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7173 tmp2 = tcg_temp_new_i32();
7174 tcg_gen_mov_i32(tmp2, tmp);
7175 neon_store_reg(rd, pass, tmp2);
7177 tcg_temp_free_i32(tmp);
7178 } else {
7179 return 1;
7183 return 0;
7186 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7188 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7189 const ARMCPRegInfo *ri;
7191 cpnum = (insn >> 8) & 0xf;
7193 /* First check for coprocessor space used for XScale/iwMMXt insns */
7194 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7195 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7196 return 1;
7198 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7199 return disas_iwmmxt_insn(s, insn);
7200 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7201 return disas_dsp_insn(s, insn);
7203 return 1;
7206 /* Otherwise treat as a generic register access */
7207 is64 = (insn & (1 << 25)) == 0;
7208 if (!is64 && ((insn & (1 << 4)) == 0)) {
7209 /* cdp */
7210 return 1;
7213 crm = insn & 0xf;
7214 if (is64) {
7215 crn = 0;
7216 opc1 = (insn >> 4) & 0xf;
7217 opc2 = 0;
7218 rt2 = (insn >> 16) & 0xf;
7219 } else {
7220 crn = (insn >> 16) & 0xf;
7221 opc1 = (insn >> 21) & 7;
7222 opc2 = (insn >> 5) & 7;
7223 rt2 = 0;
7225 isread = (insn >> 20) & 1;
7226 rt = (insn >> 12) & 0xf;
7228 ri = get_arm_cp_reginfo(s->cp_regs,
7229 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7230 if (ri) {
7231 /* Check access permissions */
7232 if (!cp_access_ok(s->current_el, ri, isread)) {
7233 return 1;
7236 if (ri->accessfn ||
7237 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7238 /* Emit code to perform further access permissions checks at
7239 * runtime; this may result in an exception.
7240 * Note that on XScale all cp0..c13 registers do an access check
7241 * call in order to handle c15_cpar.
7243 TCGv_ptr tmpptr;
7244 TCGv_i32 tcg_syn, tcg_isread;
7245 uint32_t syndrome;
7247 /* Note that since we are an implementation which takes an
7248 * exception on a trapped conditional instruction only if the
7249 * instruction passes its condition code check, we can take
7250 * advantage of the clause in the ARM ARM that allows us to set
7251 * the COND field in the instruction to 0xE in all cases.
7252 * We could fish the actual condition out of the insn (ARM)
7253 * or the condexec bits (Thumb) but it isn't necessary.
7255 switch (cpnum) {
7256 case 14:
7257 if (is64) {
7258 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7259 isread, false);
7260 } else {
7261 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7262 rt, isread, false);
7264 break;
7265 case 15:
7266 if (is64) {
7267 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7268 isread, false);
7269 } else {
7270 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7271 rt, isread, false);
7273 break;
7274 default:
7275 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7276 * so this can only happen if this is an ARMv7 or earlier CPU,
7277 * in which case the syndrome information won't actually be
7278 * guest visible.
7280 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7281 syndrome = syn_uncategorized();
7282 break;
7285 gen_set_condexec(s);
7286 gen_set_pc_im(s, s->pc - 4);
7287 tmpptr = tcg_const_ptr(ri);
7288 tcg_syn = tcg_const_i32(syndrome);
7289 tcg_isread = tcg_const_i32(isread);
7290 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7291 tcg_isread);
7292 tcg_temp_free_ptr(tmpptr);
7293 tcg_temp_free_i32(tcg_syn);
7294 tcg_temp_free_i32(tcg_isread);
7297 /* Handle special cases first */
7298 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7299 case ARM_CP_NOP:
7300 return 0;
7301 case ARM_CP_WFI:
7302 if (isread) {
7303 return 1;
7305 gen_set_pc_im(s, s->pc);
7306 s->is_jmp = DISAS_WFI;
7307 return 0;
7308 default:
7309 break;
7312 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7313 gen_io_start();
7316 if (isread) {
7317 /* Read */
7318 if (is64) {
7319 TCGv_i64 tmp64;
7320 TCGv_i32 tmp;
7321 if (ri->type & ARM_CP_CONST) {
7322 tmp64 = tcg_const_i64(ri->resetvalue);
7323 } else if (ri->readfn) {
7324 TCGv_ptr tmpptr;
7325 tmp64 = tcg_temp_new_i64();
7326 tmpptr = tcg_const_ptr(ri);
7327 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7328 tcg_temp_free_ptr(tmpptr);
7329 } else {
7330 tmp64 = tcg_temp_new_i64();
7331 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7333 tmp = tcg_temp_new_i32();
7334 tcg_gen_extrl_i64_i32(tmp, tmp64);
7335 store_reg(s, rt, tmp);
7336 tcg_gen_shri_i64(tmp64, tmp64, 32);
7337 tmp = tcg_temp_new_i32();
7338 tcg_gen_extrl_i64_i32(tmp, tmp64);
7339 tcg_temp_free_i64(tmp64);
7340 store_reg(s, rt2, tmp);
7341 } else {
7342 TCGv_i32 tmp;
7343 if (ri->type & ARM_CP_CONST) {
7344 tmp = tcg_const_i32(ri->resetvalue);
7345 } else if (ri->readfn) {
7346 TCGv_ptr tmpptr;
7347 tmp = tcg_temp_new_i32();
7348 tmpptr = tcg_const_ptr(ri);
7349 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7350 tcg_temp_free_ptr(tmpptr);
7351 } else {
7352 tmp = load_cpu_offset(ri->fieldoffset);
7354 if (rt == 15) {
7355 /* Destination register of r15 for 32 bit loads sets
7356 * the condition codes from the high 4 bits of the value
7358 gen_set_nzcv(tmp);
7359 tcg_temp_free_i32(tmp);
7360 } else {
7361 store_reg(s, rt, tmp);
7364 } else {
7365 /* Write */
7366 if (ri->type & ARM_CP_CONST) {
7367 /* If not forbidden by access permissions, treat as WI */
7368 return 0;
7371 if (is64) {
7372 TCGv_i32 tmplo, tmphi;
7373 TCGv_i64 tmp64 = tcg_temp_new_i64();
7374 tmplo = load_reg(s, rt);
7375 tmphi = load_reg(s, rt2);
7376 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7377 tcg_temp_free_i32(tmplo);
7378 tcg_temp_free_i32(tmphi);
7379 if (ri->writefn) {
7380 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7381 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7382 tcg_temp_free_ptr(tmpptr);
7383 } else {
7384 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7386 tcg_temp_free_i64(tmp64);
7387 } else {
7388 if (ri->writefn) {
7389 TCGv_i32 tmp;
7390 TCGv_ptr tmpptr;
7391 tmp = load_reg(s, rt);
7392 tmpptr = tcg_const_ptr(ri);
7393 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7394 tcg_temp_free_ptr(tmpptr);
7395 tcg_temp_free_i32(tmp);
7396 } else {
7397 TCGv_i32 tmp = load_reg(s, rt);
7398 store_cpu_offset(tmp, ri->fieldoffset);
7403 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7404 /* I/O operations must end the TB here (whether read or write) */
7405 gen_io_end();
7406 gen_lookup_tb(s);
7407 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7408 /* We default to ending the TB on a coprocessor register write,
7409 * but allow this to be suppressed by the register definition
7410 * (usually only necessary to work around guest bugs).
7412 gen_lookup_tb(s);
7415 return 0;
7418 /* Unknown register; this might be a guest error or a QEMU
7419 * unimplemented feature.
7421 if (is64) {
7422 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7423 "64 bit system register cp:%d opc1: %d crm:%d "
7424 "(%s)\n",
7425 isread ? "read" : "write", cpnum, opc1, crm,
7426 s->ns ? "non-secure" : "secure");
7427 } else {
7428 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7429 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7430 "(%s)\n",
7431 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7432 s->ns ? "non-secure" : "secure");
7435 return 1;
7439 /* Store a 64-bit value to a register pair. Clobbers val. */
7440 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7442 TCGv_i32 tmp;
7443 tmp = tcg_temp_new_i32();
7444 tcg_gen_extrl_i64_i32(tmp, val);
7445 store_reg(s, rlow, tmp);
7446 tmp = tcg_temp_new_i32();
7447 tcg_gen_shri_i64(val, val, 32);
7448 tcg_gen_extrl_i64_i32(tmp, val);
7449 store_reg(s, rhigh, tmp);
7452 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7453 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7455 TCGv_i64 tmp;
7456 TCGv_i32 tmp2;
7458 /* Load value and extend to 64 bits. */
7459 tmp = tcg_temp_new_i64();
7460 tmp2 = load_reg(s, rlow);
7461 tcg_gen_extu_i32_i64(tmp, tmp2);
7462 tcg_temp_free_i32(tmp2);
7463 tcg_gen_add_i64(val, val, tmp);
7464 tcg_temp_free_i64(tmp);
7467 /* load and add a 64-bit value from a register pair. */
7468 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7470 TCGv_i64 tmp;
7471 TCGv_i32 tmpl;
7472 TCGv_i32 tmph;
7474 /* Load 64-bit value rd:rn. */
7475 tmpl = load_reg(s, rlow);
7476 tmph = load_reg(s, rhigh);
7477 tmp = tcg_temp_new_i64();
7478 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7479 tcg_temp_free_i32(tmpl);
7480 tcg_temp_free_i32(tmph);
7481 tcg_gen_add_i64(val, val, tmp);
7482 tcg_temp_free_i64(tmp);
7485 /* Set N and Z flags from hi|lo. */
7486 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7488 tcg_gen_mov_i32(cpu_NF, hi);
7489 tcg_gen_or_i32(cpu_ZF, lo, hi);
7492 /* Load/Store exclusive instructions are implemented by remembering
7493 the value/address loaded, and seeing if these are the same
7494 when the store is performed. This should be sufficient to implement
7495 the architecturally mandated semantics, and avoids having to monitor
7496 regular stores.
7498 In system emulation mode only one CPU will be running at once, so
7499 this sequence is effectively atomic. In user emulation mode we
7500 throw an exception and handle the atomic operation elsewhere. */
7501 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7502 TCGv_i32 addr, int size)
7504 TCGv_i32 tmp = tcg_temp_new_i32();
7506 s->is_ldex = true;
7508 switch (size) {
7509 case 0:
7510 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7511 break;
7512 case 1:
7513 gen_aa32_ld16ua(s, tmp, addr, get_mem_index(s));
7514 break;
7515 case 2:
7516 case 3:
7517 gen_aa32_ld32ua(s, tmp, addr, get_mem_index(s));
7518 break;
7519 default:
7520 abort();
7523 if (size == 3) {
7524 TCGv_i32 tmp2 = tcg_temp_new_i32();
7525 TCGv_i32 tmp3 = tcg_temp_new_i32();
7527 tcg_gen_addi_i32(tmp2, addr, 4);
7528 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7529 tcg_temp_free_i32(tmp2);
7530 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7531 store_reg(s, rt2, tmp3);
7532 } else {
7533 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7536 store_reg(s, rt, tmp);
7537 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7540 static void gen_clrex(DisasContext *s)
7542 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7545 #ifdef CONFIG_USER_ONLY
7546 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7547 TCGv_i32 addr, int size)
7549 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7550 tcg_gen_movi_i32(cpu_exclusive_info,
7551 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7552 gen_exception_internal_insn(s, 4, EXCP_STREX);
7554 #else
7555 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7556 TCGv_i32 addr, int size)
7558 TCGv_i32 tmp;
7559 TCGv_i64 val64, extaddr;
7560 TCGLabel *done_label;
7561 TCGLabel *fail_label;
7563 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7564 [addr] = {Rt};
7565 {Rd} = 0;
7566 } else {
7567 {Rd} = 1;
7568 } */
7569 fail_label = gen_new_label();
7570 done_label = gen_new_label();
7571 extaddr = tcg_temp_new_i64();
7572 tcg_gen_extu_i32_i64(extaddr, addr);
7573 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7574 tcg_temp_free_i64(extaddr);
7576 tmp = tcg_temp_new_i32();
7577 switch (size) {
7578 case 0:
7579 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7580 break;
7581 case 1:
7582 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7583 break;
7584 case 2:
7585 case 3:
7586 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7587 break;
7588 default:
7589 abort();
7592 val64 = tcg_temp_new_i64();
7593 if (size == 3) {
7594 TCGv_i32 tmp2 = tcg_temp_new_i32();
7595 TCGv_i32 tmp3 = tcg_temp_new_i32();
7596 tcg_gen_addi_i32(tmp2, addr, 4);
7597 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7598 tcg_temp_free_i32(tmp2);
7599 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7600 tcg_temp_free_i32(tmp3);
7601 } else {
7602 tcg_gen_extu_i32_i64(val64, tmp);
7604 tcg_temp_free_i32(tmp);
7606 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7607 tcg_temp_free_i64(val64);
7609 tmp = load_reg(s, rt);
7610 switch (size) {
7611 case 0:
7612 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
7613 break;
7614 case 1:
7615 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
7616 break;
7617 case 2:
7618 case 3:
7619 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7620 break;
7621 default:
7622 abort();
7624 tcg_temp_free_i32(tmp);
7625 if (size == 3) {
7626 tcg_gen_addi_i32(addr, addr, 4);
7627 tmp = load_reg(s, rt2);
7628 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7629 tcg_temp_free_i32(tmp);
7631 tcg_gen_movi_i32(cpu_R[rd], 0);
7632 tcg_gen_br(done_label);
7633 gen_set_label(fail_label);
7634 tcg_gen_movi_i32(cpu_R[rd], 1);
7635 gen_set_label(done_label);
7636 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7638 #endif
7640 /* gen_srs:
7641 * @env: CPUARMState
7642 * @s: DisasContext
7643 * @mode: mode field from insn (which stack to store to)
7644 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7645 * @writeback: true if writeback bit set
7647 * Generate code for the SRS (Store Return State) insn.
7649 static void gen_srs(DisasContext *s,
7650 uint32_t mode, uint32_t amode, bool writeback)
7652 int32_t offset;
7653 TCGv_i32 addr, tmp;
7654 bool undef = false;
7656 /* SRS is:
7657 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7658 * and specified mode is monitor mode
7659 * - UNDEFINED in Hyp mode
7660 * - UNPREDICTABLE in User or System mode
7661 * - UNPREDICTABLE if the specified mode is:
7662 * -- not implemented
7663 * -- not a valid mode number
7664 * -- a mode that's at a higher exception level
7665 * -- Monitor, if we are Non-secure
7666 * For the UNPREDICTABLE cases we choose to UNDEF.
7668 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7669 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7670 return;
7673 if (s->current_el == 0 || s->current_el == 2) {
7674 undef = true;
7677 switch (mode) {
7678 case ARM_CPU_MODE_USR:
7679 case ARM_CPU_MODE_FIQ:
7680 case ARM_CPU_MODE_IRQ:
7681 case ARM_CPU_MODE_SVC:
7682 case ARM_CPU_MODE_ABT:
7683 case ARM_CPU_MODE_UND:
7684 case ARM_CPU_MODE_SYS:
7685 break;
7686 case ARM_CPU_MODE_HYP:
7687 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7688 undef = true;
7690 break;
7691 case ARM_CPU_MODE_MON:
7692 /* No need to check specifically for "are we non-secure" because
7693 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7694 * so if this isn't EL3 then we must be non-secure.
7696 if (s->current_el != 3) {
7697 undef = true;
7699 break;
7700 default:
7701 undef = true;
7704 if (undef) {
7705 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
7706 default_exception_el(s));
7707 return;
7710 addr = tcg_temp_new_i32();
7711 tmp = tcg_const_i32(mode);
7712 /* get_r13_banked() will raise an exception if called from System mode */
7713 gen_set_condexec(s);
7714 gen_set_pc_im(s, s->pc - 4);
7715 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7716 tcg_temp_free_i32(tmp);
7717 switch (amode) {
7718 case 0: /* DA */
7719 offset = -4;
7720 break;
7721 case 1: /* IA */
7722 offset = 0;
7723 break;
7724 case 2: /* DB */
7725 offset = -8;
7726 break;
7727 case 3: /* IB */
7728 offset = 4;
7729 break;
7730 default:
7731 abort();
7733 tcg_gen_addi_i32(addr, addr, offset);
7734 tmp = load_reg(s, 14);
7735 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7736 tcg_temp_free_i32(tmp);
7737 tmp = load_cpu_field(spsr);
7738 tcg_gen_addi_i32(addr, addr, 4);
7739 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7740 tcg_temp_free_i32(tmp);
7741 if (writeback) {
7742 switch (amode) {
7743 case 0:
7744 offset = -8;
7745 break;
7746 case 1:
7747 offset = 4;
7748 break;
7749 case 2:
7750 offset = -4;
7751 break;
7752 case 3:
7753 offset = 0;
7754 break;
7755 default:
7756 abort();
7758 tcg_gen_addi_i32(addr, addr, offset);
7759 tmp = tcg_const_i32(mode);
7760 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7761 tcg_temp_free_i32(tmp);
7763 tcg_temp_free_i32(addr);
7764 s->is_jmp = DISAS_UPDATE;
7767 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7769 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7770 TCGv_i32 tmp;
7771 TCGv_i32 tmp2;
7772 TCGv_i32 tmp3;
7773 TCGv_i32 addr;
7774 TCGv_i64 tmp64;
7776 /* M variants do not implement ARM mode. */
7777 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7778 goto illegal_op;
7780 cond = insn >> 28;
7781 if (cond == 0xf){
7782 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7783 * choose to UNDEF. In ARMv5 and above the space is used
7784 * for miscellaneous unconditional instructions.
7786 ARCH(5);
7788 /* Unconditional instructions. */
7789 if (((insn >> 25) & 7) == 1) {
7790 /* NEON Data processing. */
7791 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7792 goto illegal_op;
7795 if (disas_neon_data_insn(s, insn)) {
7796 goto illegal_op;
7798 return;
7800 if ((insn & 0x0f100000) == 0x04000000) {
7801 /* NEON load/store. */
7802 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7803 goto illegal_op;
7806 if (disas_neon_ls_insn(s, insn)) {
7807 goto illegal_op;
7809 return;
7811 if ((insn & 0x0f000e10) == 0x0e000a00) {
7812 /* VFP. */
7813 if (disas_vfp_insn(s, insn)) {
7814 goto illegal_op;
7816 return;
7818 if (((insn & 0x0f30f000) == 0x0510f000) ||
7819 ((insn & 0x0f30f010) == 0x0710f000)) {
7820 if ((insn & (1 << 22)) == 0) {
7821 /* PLDW; v7MP */
7822 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7823 goto illegal_op;
7826 /* Otherwise PLD; v5TE+ */
7827 ARCH(5TE);
7828 return;
7830 if (((insn & 0x0f70f000) == 0x0450f000) ||
7831 ((insn & 0x0f70f010) == 0x0650f000)) {
7832 ARCH(7);
7833 return; /* PLI; V7 */
7835 if (((insn & 0x0f700000) == 0x04100000) ||
7836 ((insn & 0x0f700010) == 0x06100000)) {
7837 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7838 goto illegal_op;
7840 return; /* v7MP: Unallocated memory hint: must NOP */
7843 if ((insn & 0x0ffffdff) == 0x01010000) {
7844 ARCH(6);
7845 /* setend */
7846 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7847 gen_helper_setend(cpu_env);
7848 s->is_jmp = DISAS_UPDATE;
7850 return;
7851 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7852 switch ((insn >> 4) & 0xf) {
7853 case 1: /* clrex */
7854 ARCH(6K);
7855 gen_clrex(s);
7856 return;
7857 case 4: /* dsb */
7858 case 5: /* dmb */
7859 ARCH(7);
7860 /* We don't emulate caches so these are a no-op. */
7861 return;
7862 case 6: /* isb */
7863 /* We need to break the TB after this insn to execute
7864 * self-modifying code correctly and also to take
7865 * any pending interrupts immediately.
7867 gen_lookup_tb(s);
7868 return;
7869 default:
7870 goto illegal_op;
7872 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7873 /* srs */
7874 ARCH(6);
7875 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7876 return;
7877 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7878 /* rfe */
7879 int32_t offset;
7880 if (IS_USER(s))
7881 goto illegal_op;
7882 ARCH(6);
7883 rn = (insn >> 16) & 0xf;
7884 addr = load_reg(s, rn);
7885 i = (insn >> 23) & 3;
7886 switch (i) {
7887 case 0: offset = -4; break; /* DA */
7888 case 1: offset = 0; break; /* IA */
7889 case 2: offset = -8; break; /* DB */
7890 case 3: offset = 4; break; /* IB */
7891 default: abort();
7893 if (offset)
7894 tcg_gen_addi_i32(addr, addr, offset);
7895 /* Load PC into tmp and CPSR into tmp2. */
7896 tmp = tcg_temp_new_i32();
7897 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7898 tcg_gen_addi_i32(addr, addr, 4);
7899 tmp2 = tcg_temp_new_i32();
7900 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7901 if (insn & (1 << 21)) {
7902 /* Base writeback. */
7903 switch (i) {
7904 case 0: offset = -8; break;
7905 case 1: offset = 4; break;
7906 case 2: offset = -4; break;
7907 case 3: offset = 0; break;
7908 default: abort();
7910 if (offset)
7911 tcg_gen_addi_i32(addr, addr, offset);
7912 store_reg(s, rn, addr);
7913 } else {
7914 tcg_temp_free_i32(addr);
7916 gen_rfe(s, tmp, tmp2);
7917 return;
7918 } else if ((insn & 0x0e000000) == 0x0a000000) {
7919 /* branch link and change to thumb (blx <offset>) */
7920 int32_t offset;
7922 val = (uint32_t)s->pc;
7923 tmp = tcg_temp_new_i32();
7924 tcg_gen_movi_i32(tmp, val);
7925 store_reg(s, 14, tmp);
7926 /* Sign-extend the 24-bit offset */
7927 offset = (((int32_t)insn) << 8) >> 8;
7928 /* offset * 4 + bit24 * 2 + (thumb bit) */
7929 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7930 /* pipeline offset */
7931 val += 4;
7932 /* protected by ARCH(5); above, near the start of uncond block */
7933 gen_bx_im(s, val);
7934 return;
7935 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7936 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7937 /* iWMMXt register transfer. */
7938 if (extract32(s->c15_cpar, 1, 1)) {
7939 if (!disas_iwmmxt_insn(s, insn)) {
7940 return;
7944 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7945 /* Coprocessor double register transfer. */
7946 ARCH(5TE);
7947 } else if ((insn & 0x0f000010) == 0x0e000010) {
7948 /* Additional coprocessor register transfer. */
7949 } else if ((insn & 0x0ff10020) == 0x01000000) {
7950 uint32_t mask;
7951 uint32_t val;
7952 /* cps (privileged) */
7953 if (IS_USER(s))
7954 return;
7955 mask = val = 0;
7956 if (insn & (1 << 19)) {
7957 if (insn & (1 << 8))
7958 mask |= CPSR_A;
7959 if (insn & (1 << 7))
7960 mask |= CPSR_I;
7961 if (insn & (1 << 6))
7962 mask |= CPSR_F;
7963 if (insn & (1 << 18))
7964 val |= mask;
7966 if (insn & (1 << 17)) {
7967 mask |= CPSR_M;
7968 val |= (insn & 0x1f);
7970 if (mask) {
7971 gen_set_psr_im(s, mask, 0, val);
7973 return;
7975 goto illegal_op;
7977 if (cond != 0xe) {
7978 /* if not always execute, we generate a conditional jump to
7979 next instruction */
7980 s->condlabel = gen_new_label();
7981 arm_gen_test_cc(cond ^ 1, s->condlabel);
7982 s->condjmp = 1;
7984 if ((insn & 0x0f900000) == 0x03000000) {
7985 if ((insn & (1 << 21)) == 0) {
7986 ARCH(6T2);
7987 rd = (insn >> 12) & 0xf;
7988 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7989 if ((insn & (1 << 22)) == 0) {
7990 /* MOVW */
7991 tmp = tcg_temp_new_i32();
7992 tcg_gen_movi_i32(tmp, val);
7993 } else {
7994 /* MOVT */
7995 tmp = load_reg(s, rd);
7996 tcg_gen_ext16u_i32(tmp, tmp);
7997 tcg_gen_ori_i32(tmp, tmp, val << 16);
7999 store_reg(s, rd, tmp);
8000 } else {
8001 if (((insn >> 12) & 0xf) != 0xf)
8002 goto illegal_op;
8003 if (((insn >> 16) & 0xf) == 0) {
8004 gen_nop_hint(s, insn & 0xff);
8005 } else {
8006 /* CPSR = immediate */
8007 val = insn & 0xff;
8008 shift = ((insn >> 8) & 0xf) * 2;
8009 if (shift)
8010 val = (val >> shift) | (val << (32 - shift));
8011 i = ((insn & (1 << 22)) != 0);
8012 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8013 i, val)) {
8014 goto illegal_op;
8018 } else if ((insn & 0x0f900000) == 0x01000000
8019 && (insn & 0x00000090) != 0x00000090) {
8020 /* miscellaneous instructions */
8021 op1 = (insn >> 21) & 3;
8022 sh = (insn >> 4) & 0xf;
8023 rm = insn & 0xf;
8024 switch (sh) {
8025 case 0x0: /* move program status register */
8026 if (op1 & 1) {
8027 /* PSR = reg */
8028 tmp = load_reg(s, rm);
8029 i = ((op1 & 2) != 0);
8030 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8031 goto illegal_op;
8032 } else {
8033 /* reg = PSR */
8034 rd = (insn >> 12) & 0xf;
8035 if (op1 & 2) {
8036 if (IS_USER(s))
8037 goto illegal_op;
8038 tmp = load_cpu_field(spsr);
8039 } else {
8040 tmp = tcg_temp_new_i32();
8041 gen_helper_cpsr_read(tmp, cpu_env);
8043 store_reg(s, rd, tmp);
8045 break;
8046 case 0x1:
8047 if (op1 == 1) {
8048 /* branch/exchange thumb (bx). */
8049 ARCH(4T);
8050 tmp = load_reg(s, rm);
8051 gen_bx(s, tmp);
8052 } else if (op1 == 3) {
8053 /* clz */
8054 ARCH(5);
8055 rd = (insn >> 12) & 0xf;
8056 tmp = load_reg(s, rm);
8057 gen_helper_clz(tmp, tmp);
8058 store_reg(s, rd, tmp);
8059 } else {
8060 goto illegal_op;
8062 break;
8063 case 0x2:
8064 if (op1 == 1) {
8065 ARCH(5J); /* bxj */
8066 /* Trivial implementation equivalent to bx. */
8067 tmp = load_reg(s, rm);
8068 gen_bx(s, tmp);
8069 } else {
8070 goto illegal_op;
8072 break;
8073 case 0x3:
8074 if (op1 != 1)
8075 goto illegal_op;
8077 ARCH(5);
8078 /* branch link/exchange thumb (blx) */
8079 tmp = load_reg(s, rm);
8080 tmp2 = tcg_temp_new_i32();
8081 tcg_gen_movi_i32(tmp2, s->pc);
8082 store_reg(s, 14, tmp2);
8083 gen_bx(s, tmp);
8084 break;
8085 case 0x4:
8087 /* crc32/crc32c */
8088 uint32_t c = extract32(insn, 8, 4);
8090 /* Check this CPU supports ARMv8 CRC instructions.
8091 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8092 * Bits 8, 10 and 11 should be zero.
8094 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8095 (c & 0xd) != 0) {
8096 goto illegal_op;
8099 rn = extract32(insn, 16, 4);
8100 rd = extract32(insn, 12, 4);
8102 tmp = load_reg(s, rn);
8103 tmp2 = load_reg(s, rm);
8104 if (op1 == 0) {
8105 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8106 } else if (op1 == 1) {
8107 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8109 tmp3 = tcg_const_i32(1 << op1);
8110 if (c & 0x2) {
8111 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8112 } else {
8113 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8115 tcg_temp_free_i32(tmp2);
8116 tcg_temp_free_i32(tmp3);
8117 store_reg(s, rd, tmp);
8118 break;
8120 case 0x5: /* saturating add/subtract */
8121 ARCH(5TE);
8122 rd = (insn >> 12) & 0xf;
8123 rn = (insn >> 16) & 0xf;
8124 tmp = load_reg(s, rm);
8125 tmp2 = load_reg(s, rn);
8126 if (op1 & 2)
8127 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8128 if (op1 & 1)
8129 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8130 else
8131 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8132 tcg_temp_free_i32(tmp2);
8133 store_reg(s, rd, tmp);
8134 break;
8135 case 7:
8137 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8138 switch (op1) {
8139 case 1:
8140 /* bkpt */
8141 ARCH(5);
8142 gen_exception_insn(s, 4, EXCP_BKPT,
8143 syn_aa32_bkpt(imm16, false),
8144 default_exception_el(s));
8145 break;
8146 case 2:
8147 /* Hypervisor call (v7) */
8148 ARCH(7);
8149 if (IS_USER(s)) {
8150 goto illegal_op;
8152 gen_hvc(s, imm16);
8153 break;
8154 case 3:
8155 /* Secure monitor call (v6+) */
8156 ARCH(6K);
8157 if (IS_USER(s)) {
8158 goto illegal_op;
8160 gen_smc(s);
8161 break;
8162 default:
8163 goto illegal_op;
8165 break;
8167 case 0x8: /* signed multiply */
8168 case 0xa:
8169 case 0xc:
8170 case 0xe:
8171 ARCH(5TE);
8172 rs = (insn >> 8) & 0xf;
8173 rn = (insn >> 12) & 0xf;
8174 rd = (insn >> 16) & 0xf;
8175 if (op1 == 1) {
8176 /* (32 * 16) >> 16 */
8177 tmp = load_reg(s, rm);
8178 tmp2 = load_reg(s, rs);
8179 if (sh & 4)
8180 tcg_gen_sari_i32(tmp2, tmp2, 16);
8181 else
8182 gen_sxth(tmp2);
8183 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8184 tcg_gen_shri_i64(tmp64, tmp64, 16);
8185 tmp = tcg_temp_new_i32();
8186 tcg_gen_extrl_i64_i32(tmp, tmp64);
8187 tcg_temp_free_i64(tmp64);
8188 if ((sh & 2) == 0) {
8189 tmp2 = load_reg(s, rn);
8190 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8191 tcg_temp_free_i32(tmp2);
8193 store_reg(s, rd, tmp);
8194 } else {
8195 /* 16 * 16 */
8196 tmp = load_reg(s, rm);
8197 tmp2 = load_reg(s, rs);
8198 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8199 tcg_temp_free_i32(tmp2);
8200 if (op1 == 2) {
8201 tmp64 = tcg_temp_new_i64();
8202 tcg_gen_ext_i32_i64(tmp64, tmp);
8203 tcg_temp_free_i32(tmp);
8204 gen_addq(s, tmp64, rn, rd);
8205 gen_storeq_reg(s, rn, rd, tmp64);
8206 tcg_temp_free_i64(tmp64);
8207 } else {
8208 if (op1 == 0) {
8209 tmp2 = load_reg(s, rn);
8210 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8211 tcg_temp_free_i32(tmp2);
8213 store_reg(s, rd, tmp);
8216 break;
8217 default:
8218 goto illegal_op;
8220 } else if (((insn & 0x0e000000) == 0 &&
8221 (insn & 0x00000090) != 0x90) ||
8222 ((insn & 0x0e000000) == (1 << 25))) {
8223 int set_cc, logic_cc, shiftop;
8225 op1 = (insn >> 21) & 0xf;
8226 set_cc = (insn >> 20) & 1;
8227 logic_cc = table_logic_cc[op1] & set_cc;
8229 /* data processing instruction */
8230 if (insn & (1 << 25)) {
8231 /* immediate operand */
8232 val = insn & 0xff;
8233 shift = ((insn >> 8) & 0xf) * 2;
8234 if (shift) {
8235 val = (val >> shift) | (val << (32 - shift));
8237 tmp2 = tcg_temp_new_i32();
8238 tcg_gen_movi_i32(tmp2, val);
8239 if (logic_cc && shift) {
8240 gen_set_CF_bit31(tmp2);
8242 } else {
8243 /* register */
8244 rm = (insn) & 0xf;
8245 tmp2 = load_reg(s, rm);
8246 shiftop = (insn >> 5) & 3;
8247 if (!(insn & (1 << 4))) {
8248 shift = (insn >> 7) & 0x1f;
8249 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8250 } else {
8251 rs = (insn >> 8) & 0xf;
8252 tmp = load_reg(s, rs);
8253 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8256 if (op1 != 0x0f && op1 != 0x0d) {
8257 rn = (insn >> 16) & 0xf;
8258 tmp = load_reg(s, rn);
8259 } else {
8260 TCGV_UNUSED_I32(tmp);
8262 rd = (insn >> 12) & 0xf;
8263 switch(op1) {
8264 case 0x00:
8265 tcg_gen_and_i32(tmp, tmp, tmp2);
8266 if (logic_cc) {
8267 gen_logic_CC(tmp);
8269 store_reg_bx(s, rd, tmp);
8270 break;
8271 case 0x01:
8272 tcg_gen_xor_i32(tmp, tmp, tmp2);
8273 if (logic_cc) {
8274 gen_logic_CC(tmp);
8276 store_reg_bx(s, rd, tmp);
8277 break;
8278 case 0x02:
8279 if (set_cc && rd == 15) {
8280 /* SUBS r15, ... is used for exception return. */
8281 if (IS_USER(s)) {
8282 goto illegal_op;
8284 gen_sub_CC(tmp, tmp, tmp2);
8285 gen_exception_return(s, tmp);
8286 } else {
8287 if (set_cc) {
8288 gen_sub_CC(tmp, tmp, tmp2);
8289 } else {
8290 tcg_gen_sub_i32(tmp, tmp, tmp2);
8292 store_reg_bx(s, rd, tmp);
8294 break;
8295 case 0x03:
8296 if (set_cc) {
8297 gen_sub_CC(tmp, tmp2, tmp);
8298 } else {
8299 tcg_gen_sub_i32(tmp, tmp2, tmp);
8301 store_reg_bx(s, rd, tmp);
8302 break;
8303 case 0x04:
8304 if (set_cc) {
8305 gen_add_CC(tmp, tmp, tmp2);
8306 } else {
8307 tcg_gen_add_i32(tmp, tmp, tmp2);
8309 store_reg_bx(s, rd, tmp);
8310 break;
8311 case 0x05:
8312 if (set_cc) {
8313 gen_adc_CC(tmp, tmp, tmp2);
8314 } else {
8315 gen_add_carry(tmp, tmp, tmp2);
8317 store_reg_bx(s, rd, tmp);
8318 break;
8319 case 0x06:
8320 if (set_cc) {
8321 gen_sbc_CC(tmp, tmp, tmp2);
8322 } else {
8323 gen_sub_carry(tmp, tmp, tmp2);
8325 store_reg_bx(s, rd, tmp);
8326 break;
8327 case 0x07:
8328 if (set_cc) {
8329 gen_sbc_CC(tmp, tmp2, tmp);
8330 } else {
8331 gen_sub_carry(tmp, tmp2, tmp);
8333 store_reg_bx(s, rd, tmp);
8334 break;
8335 case 0x08:
8336 if (set_cc) {
8337 tcg_gen_and_i32(tmp, tmp, tmp2);
8338 gen_logic_CC(tmp);
8340 tcg_temp_free_i32(tmp);
8341 break;
8342 case 0x09:
8343 if (set_cc) {
8344 tcg_gen_xor_i32(tmp, tmp, tmp2);
8345 gen_logic_CC(tmp);
8347 tcg_temp_free_i32(tmp);
8348 break;
8349 case 0x0a:
8350 if (set_cc) {
8351 gen_sub_CC(tmp, tmp, tmp2);
8353 tcg_temp_free_i32(tmp);
8354 break;
8355 case 0x0b:
8356 if (set_cc) {
8357 gen_add_CC(tmp, tmp, tmp2);
8359 tcg_temp_free_i32(tmp);
8360 break;
8361 case 0x0c:
8362 tcg_gen_or_i32(tmp, tmp, tmp2);
8363 if (logic_cc) {
8364 gen_logic_CC(tmp);
8366 store_reg_bx(s, rd, tmp);
8367 break;
8368 case 0x0d:
8369 if (logic_cc && rd == 15) {
8370 /* MOVS r15, ... is used for exception return. */
8371 if (IS_USER(s)) {
8372 goto illegal_op;
8374 gen_exception_return(s, tmp2);
8375 } else {
8376 if (logic_cc) {
8377 gen_logic_CC(tmp2);
8379 store_reg_bx(s, rd, tmp2);
8381 break;
8382 case 0x0e:
8383 tcg_gen_andc_i32(tmp, tmp, tmp2);
8384 if (logic_cc) {
8385 gen_logic_CC(tmp);
8387 store_reg_bx(s, rd, tmp);
8388 break;
8389 default:
8390 case 0x0f:
8391 tcg_gen_not_i32(tmp2, tmp2);
8392 if (logic_cc) {
8393 gen_logic_CC(tmp2);
8395 store_reg_bx(s, rd, tmp2);
8396 break;
8398 if (op1 != 0x0f && op1 != 0x0d) {
8399 tcg_temp_free_i32(tmp2);
8401 } else {
8402 /* other instructions */
8403 op1 = (insn >> 24) & 0xf;
8404 switch(op1) {
8405 case 0x0:
8406 case 0x1:
8407 /* multiplies, extra load/stores */
8408 sh = (insn >> 5) & 3;
8409 if (sh == 0) {
8410 if (op1 == 0x0) {
8411 rd = (insn >> 16) & 0xf;
8412 rn = (insn >> 12) & 0xf;
8413 rs = (insn >> 8) & 0xf;
8414 rm = (insn) & 0xf;
8415 op1 = (insn >> 20) & 0xf;
8416 switch (op1) {
8417 case 0: case 1: case 2: case 3: case 6:
8418 /* 32 bit mul */
8419 tmp = load_reg(s, rs);
8420 tmp2 = load_reg(s, rm);
8421 tcg_gen_mul_i32(tmp, tmp, tmp2);
8422 tcg_temp_free_i32(tmp2);
8423 if (insn & (1 << 22)) {
8424 /* Subtract (mls) */
8425 ARCH(6T2);
8426 tmp2 = load_reg(s, rn);
8427 tcg_gen_sub_i32(tmp, tmp2, tmp);
8428 tcg_temp_free_i32(tmp2);
8429 } else if (insn & (1 << 21)) {
8430 /* Add */
8431 tmp2 = load_reg(s, rn);
8432 tcg_gen_add_i32(tmp, tmp, tmp2);
8433 tcg_temp_free_i32(tmp2);
8435 if (insn & (1 << 20))
8436 gen_logic_CC(tmp);
8437 store_reg(s, rd, tmp);
8438 break;
8439 case 4:
8440 /* 64 bit mul double accumulate (UMAAL) */
8441 ARCH(6);
8442 tmp = load_reg(s, rs);
8443 tmp2 = load_reg(s, rm);
8444 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8445 gen_addq_lo(s, tmp64, rn);
8446 gen_addq_lo(s, tmp64, rd);
8447 gen_storeq_reg(s, rn, rd, tmp64);
8448 tcg_temp_free_i64(tmp64);
8449 break;
8450 case 8: case 9: case 10: case 11:
8451 case 12: case 13: case 14: case 15:
8452 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8453 tmp = load_reg(s, rs);
8454 tmp2 = load_reg(s, rm);
8455 if (insn & (1 << 22)) {
8456 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8457 } else {
8458 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8460 if (insn & (1 << 21)) { /* mult accumulate */
8461 TCGv_i32 al = load_reg(s, rn);
8462 TCGv_i32 ah = load_reg(s, rd);
8463 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8464 tcg_temp_free_i32(al);
8465 tcg_temp_free_i32(ah);
8467 if (insn & (1 << 20)) {
8468 gen_logicq_cc(tmp, tmp2);
8470 store_reg(s, rn, tmp);
8471 store_reg(s, rd, tmp2);
8472 break;
8473 default:
8474 goto illegal_op;
8476 } else {
8477 rn = (insn >> 16) & 0xf;
8478 rd = (insn >> 12) & 0xf;
8479 if (insn & (1 << 23)) {
8480 /* load/store exclusive */
8481 int op2 = (insn >> 8) & 3;
8482 op1 = (insn >> 21) & 0x3;
8484 switch (op2) {
8485 case 0: /* lda/stl */
8486 if (op1 == 1) {
8487 goto illegal_op;
8489 ARCH(8);
8490 break;
8491 case 1: /* reserved */
8492 goto illegal_op;
8493 case 2: /* ldaex/stlex */
8494 ARCH(8);
8495 break;
8496 case 3: /* ldrex/strex */
8497 if (op1) {
8498 ARCH(6K);
8499 } else {
8500 ARCH(6);
8502 break;
8505 addr = tcg_temp_local_new_i32();
8506 load_reg_var(s, addr, rn);
8508 /* Since the emulation does not have barriers,
8509 the acquire/release semantics need no special
8510 handling */
8511 if (op2 == 0) {
8512 if (insn & (1 << 20)) {
8513 tmp = tcg_temp_new_i32();
8514 switch (op1) {
8515 case 0: /* lda */
8516 gen_aa32_ld32u(s, tmp, addr,
8517 get_mem_index(s));
8518 break;
8519 case 2: /* ldab */
8520 gen_aa32_ld8u(s, tmp, addr,
8521 get_mem_index(s));
8522 break;
8523 case 3: /* ldah */
8524 gen_aa32_ld16u(s, tmp, addr,
8525 get_mem_index(s));
8526 break;
8527 default:
8528 abort();
8530 store_reg(s, rd, tmp);
8531 } else {
8532 rm = insn & 0xf;
8533 tmp = load_reg(s, rm);
8534 switch (op1) {
8535 case 0: /* stl */
8536 gen_aa32_st32(s, tmp, addr,
8537 get_mem_index(s));
8538 break;
8539 case 2: /* stlb */
8540 gen_aa32_st8(s, tmp, addr,
8541 get_mem_index(s));
8542 break;
8543 case 3: /* stlh */
8544 gen_aa32_st16(s, tmp, addr,
8545 get_mem_index(s));
8546 break;
8547 default:
8548 abort();
8550 tcg_temp_free_i32(tmp);
8552 } else if (insn & (1 << 20)) {
8553 switch (op1) {
8554 case 0: /* ldrex */
8555 gen_load_exclusive(s, rd, 15, addr, 2);
8556 break;
8557 case 1: /* ldrexd */
8558 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8559 break;
8560 case 2: /* ldrexb */
8561 gen_load_exclusive(s, rd, 15, addr, 0);
8562 break;
8563 case 3: /* ldrexh */
8564 gen_load_exclusive(s, rd, 15, addr, 1);
8565 break;
8566 default:
8567 abort();
8569 } else {
8570 rm = insn & 0xf;
8571 switch (op1) {
8572 case 0: /* strex */
8573 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8574 break;
8575 case 1: /* strexd */
8576 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8577 break;
8578 case 2: /* strexb */
8579 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8580 break;
8581 case 3: /* strexh */
8582 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8583 break;
8584 default:
8585 abort();
8588 tcg_temp_free_i32(addr);
8589 } else {
8590 /* SWP instruction */
8591 rm = (insn) & 0xf;
8593 /* ??? This is not really atomic. However we know
8594 we never have multiple CPUs running in parallel,
8595 so it is good enough. */
8596 addr = load_reg(s, rn);
8597 tmp = load_reg(s, rm);
8598 tmp2 = tcg_temp_new_i32();
8599 if (insn & (1 << 22)) {
8600 gen_aa32_ld8u(s, tmp2, addr, get_mem_index(s));
8601 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8602 } else {
8603 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8604 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8606 tcg_temp_free_i32(tmp);
8607 tcg_temp_free_i32(addr);
8608 store_reg(s, rd, tmp2);
8611 } else {
8612 int address_offset;
8613 bool load = insn & (1 << 20);
8614 bool doubleword = false;
8615 /* Misc load/store */
8616 rn = (insn >> 16) & 0xf;
8617 rd = (insn >> 12) & 0xf;
8619 if (!load && (sh & 2)) {
8620 /* doubleword */
8621 ARCH(5TE);
8622 if (rd & 1) {
8623 /* UNPREDICTABLE; we choose to UNDEF */
8624 goto illegal_op;
8626 load = (sh & 1) == 0;
8627 doubleword = true;
8630 addr = load_reg(s, rn);
8631 if (insn & (1 << 24))
8632 gen_add_datah_offset(s, insn, 0, addr);
8633 address_offset = 0;
8635 if (doubleword) {
8636 if (!load) {
8637 /* store */
8638 tmp = load_reg(s, rd);
8639 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8640 tcg_temp_free_i32(tmp);
8641 tcg_gen_addi_i32(addr, addr, 4);
8642 tmp = load_reg(s, rd + 1);
8643 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8644 tcg_temp_free_i32(tmp);
8645 } else {
8646 /* load */
8647 tmp = tcg_temp_new_i32();
8648 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8649 store_reg(s, rd, tmp);
8650 tcg_gen_addi_i32(addr, addr, 4);
8651 tmp = tcg_temp_new_i32();
8652 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8653 rd++;
8655 address_offset = -4;
8656 } else if (load) {
8657 /* load */
8658 tmp = tcg_temp_new_i32();
8659 switch (sh) {
8660 case 1:
8661 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8662 break;
8663 case 2:
8664 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
8665 break;
8666 default:
8667 case 3:
8668 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
8669 break;
8671 } else {
8672 /* store */
8673 tmp = load_reg(s, rd);
8674 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8675 tcg_temp_free_i32(tmp);
8677 /* Perform base writeback before the loaded value to
8678 ensure correct behavior with overlapping index registers.
8679 ldrd with base writeback is undefined if the
8680 destination and index registers overlap. */
8681 if (!(insn & (1 << 24))) {
8682 gen_add_datah_offset(s, insn, address_offset, addr);
8683 store_reg(s, rn, addr);
8684 } else if (insn & (1 << 21)) {
8685 if (address_offset)
8686 tcg_gen_addi_i32(addr, addr, address_offset);
8687 store_reg(s, rn, addr);
8688 } else {
8689 tcg_temp_free_i32(addr);
8691 if (load) {
8692 /* Complete the load. */
8693 store_reg(s, rd, tmp);
8696 break;
8697 case 0x4:
8698 case 0x5:
8699 goto do_ldst;
8700 case 0x6:
8701 case 0x7:
8702 if (insn & (1 << 4)) {
8703 ARCH(6);
8704 /* Armv6 Media instructions. */
8705 rm = insn & 0xf;
8706 rn = (insn >> 16) & 0xf;
8707 rd = (insn >> 12) & 0xf;
8708 rs = (insn >> 8) & 0xf;
8709 switch ((insn >> 23) & 3) {
8710 case 0: /* Parallel add/subtract. */
8711 op1 = (insn >> 20) & 7;
8712 tmp = load_reg(s, rn);
8713 tmp2 = load_reg(s, rm);
8714 sh = (insn >> 5) & 7;
8715 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8716 goto illegal_op;
8717 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8718 tcg_temp_free_i32(tmp2);
8719 store_reg(s, rd, tmp);
8720 break;
8721 case 1:
8722 if ((insn & 0x00700020) == 0) {
8723 /* Halfword pack. */
8724 tmp = load_reg(s, rn);
8725 tmp2 = load_reg(s, rm);
8726 shift = (insn >> 7) & 0x1f;
8727 if (insn & (1 << 6)) {
8728 /* pkhtb */
8729 if (shift == 0)
8730 shift = 31;
8731 tcg_gen_sari_i32(tmp2, tmp2, shift);
8732 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8733 tcg_gen_ext16u_i32(tmp2, tmp2);
8734 } else {
8735 /* pkhbt */
8736 if (shift)
8737 tcg_gen_shli_i32(tmp2, tmp2, shift);
8738 tcg_gen_ext16u_i32(tmp, tmp);
8739 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8741 tcg_gen_or_i32(tmp, tmp, tmp2);
8742 tcg_temp_free_i32(tmp2);
8743 store_reg(s, rd, tmp);
8744 } else if ((insn & 0x00200020) == 0x00200000) {
8745 /* [us]sat */
8746 tmp = load_reg(s, rm);
8747 shift = (insn >> 7) & 0x1f;
8748 if (insn & (1 << 6)) {
8749 if (shift == 0)
8750 shift = 31;
8751 tcg_gen_sari_i32(tmp, tmp, shift);
8752 } else {
8753 tcg_gen_shli_i32(tmp, tmp, shift);
8755 sh = (insn >> 16) & 0x1f;
8756 tmp2 = tcg_const_i32(sh);
8757 if (insn & (1 << 22))
8758 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8759 else
8760 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8761 tcg_temp_free_i32(tmp2);
8762 store_reg(s, rd, tmp);
8763 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8764 /* [us]sat16 */
8765 tmp = load_reg(s, rm);
8766 sh = (insn >> 16) & 0x1f;
8767 tmp2 = tcg_const_i32(sh);
8768 if (insn & (1 << 22))
8769 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8770 else
8771 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8772 tcg_temp_free_i32(tmp2);
8773 store_reg(s, rd, tmp);
8774 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8775 /* Select bytes. */
8776 tmp = load_reg(s, rn);
8777 tmp2 = load_reg(s, rm);
8778 tmp3 = tcg_temp_new_i32();
8779 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8780 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8781 tcg_temp_free_i32(tmp3);
8782 tcg_temp_free_i32(tmp2);
8783 store_reg(s, rd, tmp);
8784 } else if ((insn & 0x000003e0) == 0x00000060) {
8785 tmp = load_reg(s, rm);
8786 shift = (insn >> 10) & 3;
8787 /* ??? In many cases it's not necessary to do a
8788 rotate, a shift is sufficient. */
8789 if (shift != 0)
8790 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8791 op1 = (insn >> 20) & 7;
8792 switch (op1) {
8793 case 0: gen_sxtb16(tmp); break;
8794 case 2: gen_sxtb(tmp); break;
8795 case 3: gen_sxth(tmp); break;
8796 case 4: gen_uxtb16(tmp); break;
8797 case 6: gen_uxtb(tmp); break;
8798 case 7: gen_uxth(tmp); break;
8799 default: goto illegal_op;
8801 if (rn != 15) {
8802 tmp2 = load_reg(s, rn);
8803 if ((op1 & 3) == 0) {
8804 gen_add16(tmp, tmp2);
8805 } else {
8806 tcg_gen_add_i32(tmp, tmp, tmp2);
8807 tcg_temp_free_i32(tmp2);
8810 store_reg(s, rd, tmp);
8811 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8812 /* rev */
8813 tmp = load_reg(s, rm);
8814 if (insn & (1 << 22)) {
8815 if (insn & (1 << 7)) {
8816 gen_revsh(tmp);
8817 } else {
8818 ARCH(6T2);
8819 gen_helper_rbit(tmp, tmp);
8821 } else {
8822 if (insn & (1 << 7))
8823 gen_rev16(tmp);
8824 else
8825 tcg_gen_bswap32_i32(tmp, tmp);
8827 store_reg(s, rd, tmp);
8828 } else {
8829 goto illegal_op;
8831 break;
8832 case 2: /* Multiplies (Type 3). */
8833 switch ((insn >> 20) & 0x7) {
8834 case 5:
8835 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8836 /* op2 not 00x or 11x : UNDEF */
8837 goto illegal_op;
8839 /* Signed multiply most significant [accumulate].
8840 (SMMUL, SMMLA, SMMLS) */
8841 tmp = load_reg(s, rm);
8842 tmp2 = load_reg(s, rs);
8843 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8845 if (rd != 15) {
8846 tmp = load_reg(s, rd);
8847 if (insn & (1 << 6)) {
8848 tmp64 = gen_subq_msw(tmp64, tmp);
8849 } else {
8850 tmp64 = gen_addq_msw(tmp64, tmp);
8853 if (insn & (1 << 5)) {
8854 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8856 tcg_gen_shri_i64(tmp64, tmp64, 32);
8857 tmp = tcg_temp_new_i32();
8858 tcg_gen_extrl_i64_i32(tmp, tmp64);
8859 tcg_temp_free_i64(tmp64);
8860 store_reg(s, rn, tmp);
8861 break;
8862 case 0:
8863 case 4:
8864 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8865 if (insn & (1 << 7)) {
8866 goto illegal_op;
8868 tmp = load_reg(s, rm);
8869 tmp2 = load_reg(s, rs);
8870 if (insn & (1 << 5))
8871 gen_swap_half(tmp2);
8872 gen_smul_dual(tmp, tmp2);
8873 if (insn & (1 << 22)) {
8874 /* smlald, smlsld */
8875 TCGv_i64 tmp64_2;
8877 tmp64 = tcg_temp_new_i64();
8878 tmp64_2 = tcg_temp_new_i64();
8879 tcg_gen_ext_i32_i64(tmp64, tmp);
8880 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8881 tcg_temp_free_i32(tmp);
8882 tcg_temp_free_i32(tmp2);
8883 if (insn & (1 << 6)) {
8884 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8885 } else {
8886 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8888 tcg_temp_free_i64(tmp64_2);
8889 gen_addq(s, tmp64, rd, rn);
8890 gen_storeq_reg(s, rd, rn, tmp64);
8891 tcg_temp_free_i64(tmp64);
8892 } else {
8893 /* smuad, smusd, smlad, smlsd */
8894 if (insn & (1 << 6)) {
8895 /* This subtraction cannot overflow. */
8896 tcg_gen_sub_i32(tmp, tmp, tmp2);
8897 } else {
8898 /* This addition cannot overflow 32 bits;
8899 * however it may overflow considered as a
8900 * signed operation, in which case we must set
8901 * the Q flag.
8903 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8905 tcg_temp_free_i32(tmp2);
8906 if (rd != 15)
8908 tmp2 = load_reg(s, rd);
8909 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8910 tcg_temp_free_i32(tmp2);
8912 store_reg(s, rn, tmp);
8914 break;
8915 case 1:
8916 case 3:
8917 /* SDIV, UDIV */
8918 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
8919 goto illegal_op;
8921 if (((insn >> 5) & 7) || (rd != 15)) {
8922 goto illegal_op;
8924 tmp = load_reg(s, rm);
8925 tmp2 = load_reg(s, rs);
8926 if (insn & (1 << 21)) {
8927 gen_helper_udiv(tmp, tmp, tmp2);
8928 } else {
8929 gen_helper_sdiv(tmp, tmp, tmp2);
8931 tcg_temp_free_i32(tmp2);
8932 store_reg(s, rn, tmp);
8933 break;
8934 default:
8935 goto illegal_op;
8937 break;
8938 case 3:
8939 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8940 switch (op1) {
8941 case 0: /* Unsigned sum of absolute differences. */
8942 ARCH(6);
8943 tmp = load_reg(s, rm);
8944 tmp2 = load_reg(s, rs);
8945 gen_helper_usad8(tmp, tmp, tmp2);
8946 tcg_temp_free_i32(tmp2);
8947 if (rd != 15) {
8948 tmp2 = load_reg(s, rd);
8949 tcg_gen_add_i32(tmp, tmp, tmp2);
8950 tcg_temp_free_i32(tmp2);
8952 store_reg(s, rn, tmp);
8953 break;
8954 case 0x20: case 0x24: case 0x28: case 0x2c:
8955 /* Bitfield insert/clear. */
8956 ARCH(6T2);
8957 shift = (insn >> 7) & 0x1f;
8958 i = (insn >> 16) & 0x1f;
8959 if (i < shift) {
8960 /* UNPREDICTABLE; we choose to UNDEF */
8961 goto illegal_op;
8963 i = i + 1 - shift;
8964 if (rm == 15) {
8965 tmp = tcg_temp_new_i32();
8966 tcg_gen_movi_i32(tmp, 0);
8967 } else {
8968 tmp = load_reg(s, rm);
8970 if (i != 32) {
8971 tmp2 = load_reg(s, rd);
8972 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8973 tcg_temp_free_i32(tmp2);
8975 store_reg(s, rd, tmp);
8976 break;
8977 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8978 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8979 ARCH(6T2);
8980 tmp = load_reg(s, rm);
8981 shift = (insn >> 7) & 0x1f;
8982 i = ((insn >> 16) & 0x1f) + 1;
8983 if (shift + i > 32)
8984 goto illegal_op;
8985 if (i < 32) {
8986 if (op1 & 0x20) {
8987 gen_ubfx(tmp, shift, (1u << i) - 1);
8988 } else {
8989 gen_sbfx(tmp, shift, i);
8992 store_reg(s, rd, tmp);
8993 break;
8994 default:
8995 goto illegal_op;
8997 break;
8999 break;
9001 do_ldst:
9002 /* Check for undefined extension instructions
9003 * per the ARM Bible IE:
9004 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9006 sh = (0xf << 20) | (0xf << 4);
9007 if (op1 == 0x7 && ((insn & sh) == sh))
9009 goto illegal_op;
9011 /* load/store byte/word */
9012 rn = (insn >> 16) & 0xf;
9013 rd = (insn >> 12) & 0xf;
9014 tmp2 = load_reg(s, rn);
9015 if ((insn & 0x01200000) == 0x00200000) {
9016 /* ldrt/strt */
9017 i = get_a32_user_mem_index(s);
9018 } else {
9019 i = get_mem_index(s);
9021 if (insn & (1 << 24))
9022 gen_add_data_offset(s, insn, tmp2);
9023 if (insn & (1 << 20)) {
9024 /* load */
9025 tmp = tcg_temp_new_i32();
9026 if (insn & (1 << 22)) {
9027 gen_aa32_ld8u(s, tmp, tmp2, i);
9028 } else {
9029 gen_aa32_ld32u(s, tmp, tmp2, i);
9031 } else {
9032 /* store */
9033 tmp = load_reg(s, rd);
9034 if (insn & (1 << 22)) {
9035 gen_aa32_st8(s, tmp, tmp2, i);
9036 } else {
9037 gen_aa32_st32(s, tmp, tmp2, i);
9039 tcg_temp_free_i32(tmp);
9041 if (!(insn & (1 << 24))) {
9042 gen_add_data_offset(s, insn, tmp2);
9043 store_reg(s, rn, tmp2);
9044 } else if (insn & (1 << 21)) {
9045 store_reg(s, rn, tmp2);
9046 } else {
9047 tcg_temp_free_i32(tmp2);
9049 if (insn & (1 << 20)) {
9050 /* Complete the load. */
9051 store_reg_from_load(s, rd, tmp);
9053 break;
9054 case 0x08:
9055 case 0x09:
9057 int j, n, loaded_base;
9058 bool exc_return = false;
9059 bool is_load = extract32(insn, 20, 1);
9060 bool user = false;
9061 TCGv_i32 loaded_var;
9062 /* load/store multiple words */
9063 /* XXX: store correct base if write back */
9064 if (insn & (1 << 22)) {
9065 /* LDM (user), LDM (exception return) and STM (user) */
9066 if (IS_USER(s))
9067 goto illegal_op; /* only usable in supervisor mode */
9069 if (is_load && extract32(insn, 15, 1)) {
9070 exc_return = true;
9071 } else {
9072 user = true;
9075 rn = (insn >> 16) & 0xf;
9076 addr = load_reg(s, rn);
9078 /* compute total size */
9079 loaded_base = 0;
9080 TCGV_UNUSED_I32(loaded_var);
9081 n = 0;
9082 for(i=0;i<16;i++) {
9083 if (insn & (1 << i))
9084 n++;
9086 /* XXX: test invalid n == 0 case ? */
9087 if (insn & (1 << 23)) {
9088 if (insn & (1 << 24)) {
9089 /* pre increment */
9090 tcg_gen_addi_i32(addr, addr, 4);
9091 } else {
9092 /* post increment */
9094 } else {
9095 if (insn & (1 << 24)) {
9096 /* pre decrement */
9097 tcg_gen_addi_i32(addr, addr, -(n * 4));
9098 } else {
9099 /* post decrement */
9100 if (n != 1)
9101 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9104 j = 0;
9105 for(i=0;i<16;i++) {
9106 if (insn & (1 << i)) {
9107 if (is_load) {
9108 /* load */
9109 tmp = tcg_temp_new_i32();
9110 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9111 if (user) {
9112 tmp2 = tcg_const_i32(i);
9113 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9114 tcg_temp_free_i32(tmp2);
9115 tcg_temp_free_i32(tmp);
9116 } else if (i == rn) {
9117 loaded_var = tmp;
9118 loaded_base = 1;
9119 } else {
9120 store_reg_from_load(s, i, tmp);
9122 } else {
9123 /* store */
9124 if (i == 15) {
9125 /* special case: r15 = PC + 8 */
9126 val = (long)s->pc + 4;
9127 tmp = tcg_temp_new_i32();
9128 tcg_gen_movi_i32(tmp, val);
9129 } else if (user) {
9130 tmp = tcg_temp_new_i32();
9131 tmp2 = tcg_const_i32(i);
9132 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9133 tcg_temp_free_i32(tmp2);
9134 } else {
9135 tmp = load_reg(s, i);
9137 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9138 tcg_temp_free_i32(tmp);
9140 j++;
9141 /* no need to add after the last transfer */
9142 if (j != n)
9143 tcg_gen_addi_i32(addr, addr, 4);
9146 if (insn & (1 << 21)) {
9147 /* write back */
9148 if (insn & (1 << 23)) {
9149 if (insn & (1 << 24)) {
9150 /* pre increment */
9151 } else {
9152 /* post increment */
9153 tcg_gen_addi_i32(addr, addr, 4);
9155 } else {
9156 if (insn & (1 << 24)) {
9157 /* pre decrement */
9158 if (n != 1)
9159 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9160 } else {
9161 /* post decrement */
9162 tcg_gen_addi_i32(addr, addr, -(n * 4));
9165 store_reg(s, rn, addr);
9166 } else {
9167 tcg_temp_free_i32(addr);
9169 if (loaded_base) {
9170 store_reg(s, rn, loaded_var);
9172 if (exc_return) {
9173 /* Restore CPSR from SPSR. */
9174 tmp = load_cpu_field(spsr);
9175 gen_helper_cpsr_write_eret(cpu_env, tmp);
9176 tcg_temp_free_i32(tmp);
9177 s->is_jmp = DISAS_JUMP;
9180 break;
9181 case 0xa:
9182 case 0xb:
9184 int32_t offset;
9186 /* branch (and link) */
9187 val = (int32_t)s->pc;
9188 if (insn & (1 << 24)) {
9189 tmp = tcg_temp_new_i32();
9190 tcg_gen_movi_i32(tmp, val);
9191 store_reg(s, 14, tmp);
9193 offset = sextract32(insn << 2, 0, 26);
9194 val += offset + 4;
9195 gen_jmp(s, val);
9197 break;
9198 case 0xc:
9199 case 0xd:
9200 case 0xe:
9201 if (((insn >> 8) & 0xe) == 10) {
9202 /* VFP. */
9203 if (disas_vfp_insn(s, insn)) {
9204 goto illegal_op;
9206 } else if (disas_coproc_insn(s, insn)) {
9207 /* Coprocessor. */
9208 goto illegal_op;
9210 break;
9211 case 0xf:
9212 /* swi */
9213 gen_set_pc_im(s, s->pc);
9214 s->svc_imm = extract32(insn, 0, 24);
9215 s->is_jmp = DISAS_SWI;
9216 break;
9217 default:
9218 illegal_op:
9219 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9220 default_exception_el(s));
9221 break;
9226 /* Return true if this is a Thumb-2 logical op. */
9227 static int
9228 thumb2_logic_op(int op)
9230 return (op < 8);
9233 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9234 then set condition code flags based on the result of the operation.
9235 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9236 to the high bit of T1.
9237 Returns zero if the opcode is valid. */
9239 static int
9240 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9241 TCGv_i32 t0, TCGv_i32 t1)
9243 int logic_cc;
9245 logic_cc = 0;
9246 switch (op) {
9247 case 0: /* and */
9248 tcg_gen_and_i32(t0, t0, t1);
9249 logic_cc = conds;
9250 break;
9251 case 1: /* bic */
9252 tcg_gen_andc_i32(t0, t0, t1);
9253 logic_cc = conds;
9254 break;
9255 case 2: /* orr */
9256 tcg_gen_or_i32(t0, t0, t1);
9257 logic_cc = conds;
9258 break;
9259 case 3: /* orn */
9260 tcg_gen_orc_i32(t0, t0, t1);
9261 logic_cc = conds;
9262 break;
9263 case 4: /* eor */
9264 tcg_gen_xor_i32(t0, t0, t1);
9265 logic_cc = conds;
9266 break;
9267 case 8: /* add */
9268 if (conds)
9269 gen_add_CC(t0, t0, t1);
9270 else
9271 tcg_gen_add_i32(t0, t0, t1);
9272 break;
9273 case 10: /* adc */
9274 if (conds)
9275 gen_adc_CC(t0, t0, t1);
9276 else
9277 gen_adc(t0, t1);
9278 break;
9279 case 11: /* sbc */
9280 if (conds) {
9281 gen_sbc_CC(t0, t0, t1);
9282 } else {
9283 gen_sub_carry(t0, t0, t1);
9285 break;
9286 case 13: /* sub */
9287 if (conds)
9288 gen_sub_CC(t0, t0, t1);
9289 else
9290 tcg_gen_sub_i32(t0, t0, t1);
9291 break;
9292 case 14: /* rsb */
9293 if (conds)
9294 gen_sub_CC(t0, t1, t0);
9295 else
9296 tcg_gen_sub_i32(t0, t1, t0);
9297 break;
9298 default: /* 5, 6, 7, 9, 12, 15. */
9299 return 1;
9301 if (logic_cc) {
9302 gen_logic_CC(t0);
9303 if (shifter_out)
9304 gen_set_CF_bit31(t1);
9306 return 0;
9309 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9310 is not legal. */
9311 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9313 uint32_t insn, imm, shift, offset;
9314 uint32_t rd, rn, rm, rs;
9315 TCGv_i32 tmp;
9316 TCGv_i32 tmp2;
9317 TCGv_i32 tmp3;
9318 TCGv_i32 addr;
9319 TCGv_i64 tmp64;
9320 int op;
9321 int shiftop;
9322 int conds;
9323 int logic_cc;
9325 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9326 || arm_dc_feature(s, ARM_FEATURE_M))) {
9327 /* Thumb-1 cores may need to treat bl and blx as a pair of
9328 16-bit instructions to get correct prefetch abort behavior. */
9329 insn = insn_hw1;
9330 if ((insn & (1 << 12)) == 0) {
9331 ARCH(5);
9332 /* Second half of blx. */
9333 offset = ((insn & 0x7ff) << 1);
9334 tmp = load_reg(s, 14);
9335 tcg_gen_addi_i32(tmp, tmp, offset);
9336 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9338 tmp2 = tcg_temp_new_i32();
9339 tcg_gen_movi_i32(tmp2, s->pc | 1);
9340 store_reg(s, 14, tmp2);
9341 gen_bx(s, tmp);
9342 return 0;
9344 if (insn & (1 << 11)) {
9345 /* Second half of bl. */
9346 offset = ((insn & 0x7ff) << 1) | 1;
9347 tmp = load_reg(s, 14);
9348 tcg_gen_addi_i32(tmp, tmp, offset);
9350 tmp2 = tcg_temp_new_i32();
9351 tcg_gen_movi_i32(tmp2, s->pc | 1);
9352 store_reg(s, 14, tmp2);
9353 gen_bx(s, tmp);
9354 return 0;
9356 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9357 /* Instruction spans a page boundary. Implement it as two
9358 16-bit instructions in case the second half causes an
9359 prefetch abort. */
9360 offset = ((int32_t)insn << 21) >> 9;
9361 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9362 return 0;
9364 /* Fall through to 32-bit decode. */
9367 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9368 s->pc += 2;
9369 insn |= (uint32_t)insn_hw1 << 16;
9371 if ((insn & 0xf800e800) != 0xf000e800) {
9372 ARCH(6T2);
9375 rn = (insn >> 16) & 0xf;
9376 rs = (insn >> 12) & 0xf;
9377 rd = (insn >> 8) & 0xf;
9378 rm = insn & 0xf;
9379 switch ((insn >> 25) & 0xf) {
9380 case 0: case 1: case 2: case 3:
9381 /* 16-bit instructions. Should never happen. */
9382 abort();
9383 case 4:
9384 if (insn & (1 << 22)) {
9385 /* Other load/store, table branch. */
9386 if (insn & 0x01200000) {
9387 /* Load/store doubleword. */
9388 if (rn == 15) {
9389 addr = tcg_temp_new_i32();
9390 tcg_gen_movi_i32(addr, s->pc & ~3);
9391 } else {
9392 addr = load_reg(s, rn);
9394 offset = (insn & 0xff) * 4;
9395 if ((insn & (1 << 23)) == 0)
9396 offset = -offset;
9397 if (insn & (1 << 24)) {
9398 tcg_gen_addi_i32(addr, addr, offset);
9399 offset = 0;
9401 if (insn & (1 << 20)) {
9402 /* ldrd */
9403 tmp = tcg_temp_new_i32();
9404 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9405 store_reg(s, rs, tmp);
9406 tcg_gen_addi_i32(addr, addr, 4);
9407 tmp = tcg_temp_new_i32();
9408 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9409 store_reg(s, rd, tmp);
9410 } else {
9411 /* strd */
9412 tmp = load_reg(s, rs);
9413 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9414 tcg_temp_free_i32(tmp);
9415 tcg_gen_addi_i32(addr, addr, 4);
9416 tmp = load_reg(s, rd);
9417 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9418 tcg_temp_free_i32(tmp);
9420 if (insn & (1 << 21)) {
9421 /* Base writeback. */
9422 if (rn == 15)
9423 goto illegal_op;
9424 tcg_gen_addi_i32(addr, addr, offset - 4);
9425 store_reg(s, rn, addr);
9426 } else {
9427 tcg_temp_free_i32(addr);
9429 } else if ((insn & (1 << 23)) == 0) {
9430 /* Load/store exclusive word. */
9431 addr = tcg_temp_local_new_i32();
9432 load_reg_var(s, addr, rn);
9433 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9434 if (insn & (1 << 20)) {
9435 gen_load_exclusive(s, rs, 15, addr, 2);
9436 } else {
9437 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9439 tcg_temp_free_i32(addr);
9440 } else if ((insn & (7 << 5)) == 0) {
9441 /* Table Branch. */
9442 if (rn == 15) {
9443 addr = tcg_temp_new_i32();
9444 tcg_gen_movi_i32(addr, s->pc);
9445 } else {
9446 addr = load_reg(s, rn);
9448 tmp = load_reg(s, rm);
9449 tcg_gen_add_i32(addr, addr, tmp);
9450 if (insn & (1 << 4)) {
9451 /* tbh */
9452 tcg_gen_add_i32(addr, addr, tmp);
9453 tcg_temp_free_i32(tmp);
9454 tmp = tcg_temp_new_i32();
9455 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9456 } else { /* tbb */
9457 tcg_temp_free_i32(tmp);
9458 tmp = tcg_temp_new_i32();
9459 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9461 tcg_temp_free_i32(addr);
9462 tcg_gen_shli_i32(tmp, tmp, 1);
9463 tcg_gen_addi_i32(tmp, tmp, s->pc);
9464 store_reg(s, 15, tmp);
9465 } else {
9466 int op2 = (insn >> 6) & 0x3;
9467 op = (insn >> 4) & 0x3;
9468 switch (op2) {
9469 case 0:
9470 goto illegal_op;
9471 case 1:
9472 /* Load/store exclusive byte/halfword/doubleword */
9473 if (op == 2) {
9474 goto illegal_op;
9476 ARCH(7);
9477 break;
9478 case 2:
9479 /* Load-acquire/store-release */
9480 if (op == 3) {
9481 goto illegal_op;
9483 /* Fall through */
9484 case 3:
9485 /* Load-acquire/store-release exclusive */
9486 ARCH(8);
9487 break;
9489 addr = tcg_temp_local_new_i32();
9490 load_reg_var(s, addr, rn);
9491 if (!(op2 & 1)) {
9492 if (insn & (1 << 20)) {
9493 tmp = tcg_temp_new_i32();
9494 switch (op) {
9495 case 0: /* ldab */
9496 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9497 break;
9498 case 1: /* ldah */
9499 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9500 break;
9501 case 2: /* lda */
9502 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9503 break;
9504 default:
9505 abort();
9507 store_reg(s, rs, tmp);
9508 } else {
9509 tmp = load_reg(s, rs);
9510 switch (op) {
9511 case 0: /* stlb */
9512 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
9513 break;
9514 case 1: /* stlh */
9515 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
9516 break;
9517 case 2: /* stl */
9518 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9519 break;
9520 default:
9521 abort();
9523 tcg_temp_free_i32(tmp);
9525 } else if (insn & (1 << 20)) {
9526 gen_load_exclusive(s, rs, rd, addr, op);
9527 } else {
9528 gen_store_exclusive(s, rm, rs, rd, addr, op);
9530 tcg_temp_free_i32(addr);
9532 } else {
9533 /* Load/store multiple, RFE, SRS. */
9534 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9535 /* RFE, SRS: not available in user mode or on M profile */
9536 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9537 goto illegal_op;
9539 if (insn & (1 << 20)) {
9540 /* rfe */
9541 addr = load_reg(s, rn);
9542 if ((insn & (1 << 24)) == 0)
9543 tcg_gen_addi_i32(addr, addr, -8);
9544 /* Load PC into tmp and CPSR into tmp2. */
9545 tmp = tcg_temp_new_i32();
9546 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9547 tcg_gen_addi_i32(addr, addr, 4);
9548 tmp2 = tcg_temp_new_i32();
9549 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9550 if (insn & (1 << 21)) {
9551 /* Base writeback. */
9552 if (insn & (1 << 24)) {
9553 tcg_gen_addi_i32(addr, addr, 4);
9554 } else {
9555 tcg_gen_addi_i32(addr, addr, -4);
9557 store_reg(s, rn, addr);
9558 } else {
9559 tcg_temp_free_i32(addr);
9561 gen_rfe(s, tmp, tmp2);
9562 } else {
9563 /* srs */
9564 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9565 insn & (1 << 21));
9567 } else {
9568 int i, loaded_base = 0;
9569 TCGv_i32 loaded_var;
9570 /* Load/store multiple. */
9571 addr = load_reg(s, rn);
9572 offset = 0;
9573 for (i = 0; i < 16; i++) {
9574 if (insn & (1 << i))
9575 offset += 4;
9577 if (insn & (1 << 24)) {
9578 tcg_gen_addi_i32(addr, addr, -offset);
9581 TCGV_UNUSED_I32(loaded_var);
9582 for (i = 0; i < 16; i++) {
9583 if ((insn & (1 << i)) == 0)
9584 continue;
9585 if (insn & (1 << 20)) {
9586 /* Load. */
9587 tmp = tcg_temp_new_i32();
9588 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9589 if (i == 15) {
9590 gen_bx(s, tmp);
9591 } else if (i == rn) {
9592 loaded_var = tmp;
9593 loaded_base = 1;
9594 } else {
9595 store_reg(s, i, tmp);
9597 } else {
9598 /* Store. */
9599 tmp = load_reg(s, i);
9600 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9601 tcg_temp_free_i32(tmp);
9603 tcg_gen_addi_i32(addr, addr, 4);
9605 if (loaded_base) {
9606 store_reg(s, rn, loaded_var);
9608 if (insn & (1 << 21)) {
9609 /* Base register writeback. */
9610 if (insn & (1 << 24)) {
9611 tcg_gen_addi_i32(addr, addr, -offset);
9613 /* Fault if writeback register is in register list. */
9614 if (insn & (1 << rn))
9615 goto illegal_op;
9616 store_reg(s, rn, addr);
9617 } else {
9618 tcg_temp_free_i32(addr);
9622 break;
9623 case 5:
9625 op = (insn >> 21) & 0xf;
9626 if (op == 6) {
9627 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9628 goto illegal_op;
9630 /* Halfword pack. */
9631 tmp = load_reg(s, rn);
9632 tmp2 = load_reg(s, rm);
9633 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9634 if (insn & (1 << 5)) {
9635 /* pkhtb */
9636 if (shift == 0)
9637 shift = 31;
9638 tcg_gen_sari_i32(tmp2, tmp2, shift);
9639 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9640 tcg_gen_ext16u_i32(tmp2, tmp2);
9641 } else {
9642 /* pkhbt */
9643 if (shift)
9644 tcg_gen_shli_i32(tmp2, tmp2, shift);
9645 tcg_gen_ext16u_i32(tmp, tmp);
9646 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9648 tcg_gen_or_i32(tmp, tmp, tmp2);
9649 tcg_temp_free_i32(tmp2);
9650 store_reg(s, rd, tmp);
9651 } else {
9652 /* Data processing register constant shift. */
9653 if (rn == 15) {
9654 tmp = tcg_temp_new_i32();
9655 tcg_gen_movi_i32(tmp, 0);
9656 } else {
9657 tmp = load_reg(s, rn);
9659 tmp2 = load_reg(s, rm);
9661 shiftop = (insn >> 4) & 3;
9662 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9663 conds = (insn & (1 << 20)) != 0;
9664 logic_cc = (conds && thumb2_logic_op(op));
9665 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9666 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9667 goto illegal_op;
9668 tcg_temp_free_i32(tmp2);
9669 if (rd != 15) {
9670 store_reg(s, rd, tmp);
9671 } else {
9672 tcg_temp_free_i32(tmp);
9675 break;
9676 case 13: /* Misc data processing. */
9677 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9678 if (op < 4 && (insn & 0xf000) != 0xf000)
9679 goto illegal_op;
9680 switch (op) {
9681 case 0: /* Register controlled shift. */
9682 tmp = load_reg(s, rn);
9683 tmp2 = load_reg(s, rm);
9684 if ((insn & 0x70) != 0)
9685 goto illegal_op;
9686 op = (insn >> 21) & 3;
9687 logic_cc = (insn & (1 << 20)) != 0;
9688 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9689 if (logic_cc)
9690 gen_logic_CC(tmp);
9691 store_reg_bx(s, rd, tmp);
9692 break;
9693 case 1: /* Sign/zero extend. */
9694 op = (insn >> 20) & 7;
9695 switch (op) {
9696 case 0: /* SXTAH, SXTH */
9697 case 1: /* UXTAH, UXTH */
9698 case 4: /* SXTAB, SXTB */
9699 case 5: /* UXTAB, UXTB */
9700 break;
9701 case 2: /* SXTAB16, SXTB16 */
9702 case 3: /* UXTAB16, UXTB16 */
9703 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9704 goto illegal_op;
9706 break;
9707 default:
9708 goto illegal_op;
9710 if (rn != 15) {
9711 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9712 goto illegal_op;
9715 tmp = load_reg(s, rm);
9716 shift = (insn >> 4) & 3;
9717 /* ??? In many cases it's not necessary to do a
9718 rotate, a shift is sufficient. */
9719 if (shift != 0)
9720 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9721 op = (insn >> 20) & 7;
9722 switch (op) {
9723 case 0: gen_sxth(tmp); break;
9724 case 1: gen_uxth(tmp); break;
9725 case 2: gen_sxtb16(tmp); break;
9726 case 3: gen_uxtb16(tmp); break;
9727 case 4: gen_sxtb(tmp); break;
9728 case 5: gen_uxtb(tmp); break;
9729 default:
9730 g_assert_not_reached();
9732 if (rn != 15) {
9733 tmp2 = load_reg(s, rn);
9734 if ((op >> 1) == 1) {
9735 gen_add16(tmp, tmp2);
9736 } else {
9737 tcg_gen_add_i32(tmp, tmp, tmp2);
9738 tcg_temp_free_i32(tmp2);
9741 store_reg(s, rd, tmp);
9742 break;
9743 case 2: /* SIMD add/subtract. */
9744 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9745 goto illegal_op;
9747 op = (insn >> 20) & 7;
9748 shift = (insn >> 4) & 7;
9749 if ((op & 3) == 3 || (shift & 3) == 3)
9750 goto illegal_op;
9751 tmp = load_reg(s, rn);
9752 tmp2 = load_reg(s, rm);
9753 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9754 tcg_temp_free_i32(tmp2);
9755 store_reg(s, rd, tmp);
9756 break;
9757 case 3: /* Other data processing. */
9758 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9759 if (op < 4) {
9760 /* Saturating add/subtract. */
9761 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9762 goto illegal_op;
9764 tmp = load_reg(s, rn);
9765 tmp2 = load_reg(s, rm);
9766 if (op & 1)
9767 gen_helper_double_saturate(tmp, cpu_env, tmp);
9768 if (op & 2)
9769 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9770 else
9771 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9772 tcg_temp_free_i32(tmp2);
9773 } else {
9774 switch (op) {
9775 case 0x0a: /* rbit */
9776 case 0x08: /* rev */
9777 case 0x09: /* rev16 */
9778 case 0x0b: /* revsh */
9779 case 0x18: /* clz */
9780 break;
9781 case 0x10: /* sel */
9782 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9783 goto illegal_op;
9785 break;
9786 case 0x20: /* crc32/crc32c */
9787 case 0x21:
9788 case 0x22:
9789 case 0x28:
9790 case 0x29:
9791 case 0x2a:
9792 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
9793 goto illegal_op;
9795 break;
9796 default:
9797 goto illegal_op;
9799 tmp = load_reg(s, rn);
9800 switch (op) {
9801 case 0x0a: /* rbit */
9802 gen_helper_rbit(tmp, tmp);
9803 break;
9804 case 0x08: /* rev */
9805 tcg_gen_bswap32_i32(tmp, tmp);
9806 break;
9807 case 0x09: /* rev16 */
9808 gen_rev16(tmp);
9809 break;
9810 case 0x0b: /* revsh */
9811 gen_revsh(tmp);
9812 break;
9813 case 0x10: /* sel */
9814 tmp2 = load_reg(s, rm);
9815 tmp3 = tcg_temp_new_i32();
9816 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9817 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9818 tcg_temp_free_i32(tmp3);
9819 tcg_temp_free_i32(tmp2);
9820 break;
9821 case 0x18: /* clz */
9822 gen_helper_clz(tmp, tmp);
9823 break;
9824 case 0x20:
9825 case 0x21:
9826 case 0x22:
9827 case 0x28:
9828 case 0x29:
9829 case 0x2a:
9831 /* crc32/crc32c */
9832 uint32_t sz = op & 0x3;
9833 uint32_t c = op & 0x8;
9835 tmp2 = load_reg(s, rm);
9836 if (sz == 0) {
9837 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9838 } else if (sz == 1) {
9839 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9841 tmp3 = tcg_const_i32(1 << sz);
9842 if (c) {
9843 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9844 } else {
9845 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9847 tcg_temp_free_i32(tmp2);
9848 tcg_temp_free_i32(tmp3);
9849 break;
9851 default:
9852 g_assert_not_reached();
9855 store_reg(s, rd, tmp);
9856 break;
9857 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9858 switch ((insn >> 20) & 7) {
9859 case 0: /* 32 x 32 -> 32 */
9860 case 7: /* Unsigned sum of absolute differences. */
9861 break;
9862 case 1: /* 16 x 16 -> 32 */
9863 case 2: /* Dual multiply add. */
9864 case 3: /* 32 * 16 -> 32msb */
9865 case 4: /* Dual multiply subtract. */
9866 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9867 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9868 goto illegal_op;
9870 break;
9872 op = (insn >> 4) & 0xf;
9873 tmp = load_reg(s, rn);
9874 tmp2 = load_reg(s, rm);
9875 switch ((insn >> 20) & 7) {
9876 case 0: /* 32 x 32 -> 32 */
9877 tcg_gen_mul_i32(tmp, tmp, tmp2);
9878 tcg_temp_free_i32(tmp2);
9879 if (rs != 15) {
9880 tmp2 = load_reg(s, rs);
9881 if (op)
9882 tcg_gen_sub_i32(tmp, tmp2, tmp);
9883 else
9884 tcg_gen_add_i32(tmp, tmp, tmp2);
9885 tcg_temp_free_i32(tmp2);
9887 break;
9888 case 1: /* 16 x 16 -> 32 */
9889 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9890 tcg_temp_free_i32(tmp2);
9891 if (rs != 15) {
9892 tmp2 = load_reg(s, rs);
9893 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9894 tcg_temp_free_i32(tmp2);
9896 break;
9897 case 2: /* Dual multiply add. */
9898 case 4: /* Dual multiply subtract. */
9899 if (op)
9900 gen_swap_half(tmp2);
9901 gen_smul_dual(tmp, tmp2);
9902 if (insn & (1 << 22)) {
9903 /* This subtraction cannot overflow. */
9904 tcg_gen_sub_i32(tmp, tmp, tmp2);
9905 } else {
9906 /* This addition cannot overflow 32 bits;
9907 * however it may overflow considered as a signed
9908 * operation, in which case we must set the Q flag.
9910 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9912 tcg_temp_free_i32(tmp2);
9913 if (rs != 15)
9915 tmp2 = load_reg(s, rs);
9916 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9917 tcg_temp_free_i32(tmp2);
9919 break;
9920 case 3: /* 32 * 16 -> 32msb */
9921 if (op)
9922 tcg_gen_sari_i32(tmp2, tmp2, 16);
9923 else
9924 gen_sxth(tmp2);
9925 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9926 tcg_gen_shri_i64(tmp64, tmp64, 16);
9927 tmp = tcg_temp_new_i32();
9928 tcg_gen_extrl_i64_i32(tmp, tmp64);
9929 tcg_temp_free_i64(tmp64);
9930 if (rs != 15)
9932 tmp2 = load_reg(s, rs);
9933 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9934 tcg_temp_free_i32(tmp2);
9936 break;
9937 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9938 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9939 if (rs != 15) {
9940 tmp = load_reg(s, rs);
9941 if (insn & (1 << 20)) {
9942 tmp64 = gen_addq_msw(tmp64, tmp);
9943 } else {
9944 tmp64 = gen_subq_msw(tmp64, tmp);
9947 if (insn & (1 << 4)) {
9948 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9950 tcg_gen_shri_i64(tmp64, tmp64, 32);
9951 tmp = tcg_temp_new_i32();
9952 tcg_gen_extrl_i64_i32(tmp, tmp64);
9953 tcg_temp_free_i64(tmp64);
9954 break;
9955 case 7: /* Unsigned sum of absolute differences. */
9956 gen_helper_usad8(tmp, tmp, tmp2);
9957 tcg_temp_free_i32(tmp2);
9958 if (rs != 15) {
9959 tmp2 = load_reg(s, rs);
9960 tcg_gen_add_i32(tmp, tmp, tmp2);
9961 tcg_temp_free_i32(tmp2);
9963 break;
9965 store_reg(s, rd, tmp);
9966 break;
9967 case 6: case 7: /* 64-bit multiply, Divide. */
9968 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9969 tmp = load_reg(s, rn);
9970 tmp2 = load_reg(s, rm);
9971 if ((op & 0x50) == 0x10) {
9972 /* sdiv, udiv */
9973 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
9974 goto illegal_op;
9976 if (op & 0x20)
9977 gen_helper_udiv(tmp, tmp, tmp2);
9978 else
9979 gen_helper_sdiv(tmp, tmp, tmp2);
9980 tcg_temp_free_i32(tmp2);
9981 store_reg(s, rd, tmp);
9982 } else if ((op & 0xe) == 0xc) {
9983 /* Dual multiply accumulate long. */
9984 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9985 tcg_temp_free_i32(tmp);
9986 tcg_temp_free_i32(tmp2);
9987 goto illegal_op;
9989 if (op & 1)
9990 gen_swap_half(tmp2);
9991 gen_smul_dual(tmp, tmp2);
9992 if (op & 0x10) {
9993 tcg_gen_sub_i32(tmp, tmp, tmp2);
9994 } else {
9995 tcg_gen_add_i32(tmp, tmp, tmp2);
9997 tcg_temp_free_i32(tmp2);
9998 /* BUGFIX */
9999 tmp64 = tcg_temp_new_i64();
10000 tcg_gen_ext_i32_i64(tmp64, tmp);
10001 tcg_temp_free_i32(tmp);
10002 gen_addq(s, tmp64, rs, rd);
10003 gen_storeq_reg(s, rs, rd, tmp64);
10004 tcg_temp_free_i64(tmp64);
10005 } else {
10006 if (op & 0x20) {
10007 /* Unsigned 64-bit multiply */
10008 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10009 } else {
10010 if (op & 8) {
10011 /* smlalxy */
10012 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10013 tcg_temp_free_i32(tmp2);
10014 tcg_temp_free_i32(tmp);
10015 goto illegal_op;
10017 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10018 tcg_temp_free_i32(tmp2);
10019 tmp64 = tcg_temp_new_i64();
10020 tcg_gen_ext_i32_i64(tmp64, tmp);
10021 tcg_temp_free_i32(tmp);
10022 } else {
10023 /* Signed 64-bit multiply */
10024 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10027 if (op & 4) {
10028 /* umaal */
10029 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10030 tcg_temp_free_i64(tmp64);
10031 goto illegal_op;
10033 gen_addq_lo(s, tmp64, rs);
10034 gen_addq_lo(s, tmp64, rd);
10035 } else if (op & 0x40) {
10036 /* 64-bit accumulate. */
10037 gen_addq(s, tmp64, rs, rd);
10039 gen_storeq_reg(s, rs, rd, tmp64);
10040 tcg_temp_free_i64(tmp64);
10042 break;
10044 break;
10045 case 6: case 7: case 14: case 15:
10046 /* Coprocessor. */
10047 if (((insn >> 24) & 3) == 3) {
10048 /* Translate into the equivalent ARM encoding. */
10049 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10050 if (disas_neon_data_insn(s, insn)) {
10051 goto illegal_op;
10053 } else if (((insn >> 8) & 0xe) == 10) {
10054 if (disas_vfp_insn(s, insn)) {
10055 goto illegal_op;
10057 } else {
10058 if (insn & (1 << 28))
10059 goto illegal_op;
10060 if (disas_coproc_insn(s, insn)) {
10061 goto illegal_op;
10064 break;
10065 case 8: case 9: case 10: case 11:
10066 if (insn & (1 << 15)) {
10067 /* Branches, misc control. */
10068 if (insn & 0x5000) {
10069 /* Unconditional branch. */
10070 /* signextend(hw1[10:0]) -> offset[:12]. */
10071 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10072 /* hw1[10:0] -> offset[11:1]. */
10073 offset |= (insn & 0x7ff) << 1;
10074 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10075 offset[24:22] already have the same value because of the
10076 sign extension above. */
10077 offset ^= ((~insn) & (1 << 13)) << 10;
10078 offset ^= ((~insn) & (1 << 11)) << 11;
10080 if (insn & (1 << 14)) {
10081 /* Branch and link. */
10082 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10085 offset += s->pc;
10086 if (insn & (1 << 12)) {
10087 /* b/bl */
10088 gen_jmp(s, offset);
10089 } else {
10090 /* blx */
10091 offset &= ~(uint32_t)2;
10092 /* thumb2 bx, no need to check */
10093 gen_bx_im(s, offset);
10095 } else if (((insn >> 23) & 7) == 7) {
10096 /* Misc control */
10097 if (insn & (1 << 13))
10098 goto illegal_op;
10100 if (insn & (1 << 26)) {
10101 if (!(insn & (1 << 20))) {
10102 /* Hypervisor call (v7) */
10103 int imm16 = extract32(insn, 16, 4) << 12
10104 | extract32(insn, 0, 12);
10105 ARCH(7);
10106 if (IS_USER(s)) {
10107 goto illegal_op;
10109 gen_hvc(s, imm16);
10110 } else {
10111 /* Secure monitor call (v6+) */
10112 ARCH(6K);
10113 if (IS_USER(s)) {
10114 goto illegal_op;
10116 gen_smc(s);
10118 } else {
10119 op = (insn >> 20) & 7;
10120 switch (op) {
10121 case 0: /* msr cpsr. */
10122 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10123 tmp = load_reg(s, rn);
10124 addr = tcg_const_i32(insn & 0xff);
10125 gen_helper_v7m_msr(cpu_env, addr, tmp);
10126 tcg_temp_free_i32(addr);
10127 tcg_temp_free_i32(tmp);
10128 gen_lookup_tb(s);
10129 break;
10131 /* fall through */
10132 case 1: /* msr spsr. */
10133 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10134 goto illegal_op;
10136 tmp = load_reg(s, rn);
10137 if (gen_set_psr(s,
10138 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10139 op == 1, tmp))
10140 goto illegal_op;
10141 break;
10142 case 2: /* cps, nop-hint. */
10143 if (((insn >> 8) & 7) == 0) {
10144 gen_nop_hint(s, insn & 0xff);
10146 /* Implemented as NOP in user mode. */
10147 if (IS_USER(s))
10148 break;
10149 offset = 0;
10150 imm = 0;
10151 if (insn & (1 << 10)) {
10152 if (insn & (1 << 7))
10153 offset |= CPSR_A;
10154 if (insn & (1 << 6))
10155 offset |= CPSR_I;
10156 if (insn & (1 << 5))
10157 offset |= CPSR_F;
10158 if (insn & (1 << 9))
10159 imm = CPSR_A | CPSR_I | CPSR_F;
10161 if (insn & (1 << 8)) {
10162 offset |= 0x1f;
10163 imm |= (insn & 0x1f);
10165 if (offset) {
10166 gen_set_psr_im(s, offset, 0, imm);
10168 break;
10169 case 3: /* Special control operations. */
10170 ARCH(7);
10171 op = (insn >> 4) & 0xf;
10172 switch (op) {
10173 case 2: /* clrex */
10174 gen_clrex(s);
10175 break;
10176 case 4: /* dsb */
10177 case 5: /* dmb */
10178 /* These execute as NOPs. */
10179 break;
10180 case 6: /* isb */
10181 /* We need to break the TB after this insn
10182 * to execute self-modifying code correctly
10183 * and also to take any pending interrupts
10184 * immediately.
10186 gen_lookup_tb(s);
10187 break;
10188 default:
10189 goto illegal_op;
10191 break;
10192 case 4: /* bxj */
10193 /* Trivial implementation equivalent to bx. */
10194 tmp = load_reg(s, rn);
10195 gen_bx(s, tmp);
10196 break;
10197 case 5: /* Exception return. */
10198 if (IS_USER(s)) {
10199 goto illegal_op;
10201 if (rn != 14 || rd != 15) {
10202 goto illegal_op;
10204 tmp = load_reg(s, rn);
10205 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10206 gen_exception_return(s, tmp);
10207 break;
10208 case 6: /* mrs cpsr. */
10209 tmp = tcg_temp_new_i32();
10210 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10211 addr = tcg_const_i32(insn & 0xff);
10212 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10213 tcg_temp_free_i32(addr);
10214 } else {
10215 gen_helper_cpsr_read(tmp, cpu_env);
10217 store_reg(s, rd, tmp);
10218 break;
10219 case 7: /* mrs spsr. */
10220 /* Not accessible in user mode. */
10221 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10222 goto illegal_op;
10224 tmp = load_cpu_field(spsr);
10225 store_reg(s, rd, tmp);
10226 break;
10229 } else {
10230 /* Conditional branch. */
10231 op = (insn >> 22) & 0xf;
10232 /* Generate a conditional jump to next instruction. */
10233 s->condlabel = gen_new_label();
10234 arm_gen_test_cc(op ^ 1, s->condlabel);
10235 s->condjmp = 1;
10237 /* offset[11:1] = insn[10:0] */
10238 offset = (insn & 0x7ff) << 1;
10239 /* offset[17:12] = insn[21:16]. */
10240 offset |= (insn & 0x003f0000) >> 4;
10241 /* offset[31:20] = insn[26]. */
10242 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10243 /* offset[18] = insn[13]. */
10244 offset |= (insn & (1 << 13)) << 5;
10245 /* offset[19] = insn[11]. */
10246 offset |= (insn & (1 << 11)) << 8;
10248 /* jump to the offset */
10249 gen_jmp(s, s->pc + offset);
10251 } else {
10252 /* Data processing immediate. */
10253 if (insn & (1 << 25)) {
10254 if (insn & (1 << 24)) {
10255 if (insn & (1 << 20))
10256 goto illegal_op;
10257 /* Bitfield/Saturate. */
10258 op = (insn >> 21) & 7;
10259 imm = insn & 0x1f;
10260 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10261 if (rn == 15) {
10262 tmp = tcg_temp_new_i32();
10263 tcg_gen_movi_i32(tmp, 0);
10264 } else {
10265 tmp = load_reg(s, rn);
10267 switch (op) {
10268 case 2: /* Signed bitfield extract. */
10269 imm++;
10270 if (shift + imm > 32)
10271 goto illegal_op;
10272 if (imm < 32)
10273 gen_sbfx(tmp, shift, imm);
10274 break;
10275 case 6: /* Unsigned bitfield extract. */
10276 imm++;
10277 if (shift + imm > 32)
10278 goto illegal_op;
10279 if (imm < 32)
10280 gen_ubfx(tmp, shift, (1u << imm) - 1);
10281 break;
10282 case 3: /* Bitfield insert/clear. */
10283 if (imm < shift)
10284 goto illegal_op;
10285 imm = imm + 1 - shift;
10286 if (imm != 32) {
10287 tmp2 = load_reg(s, rd);
10288 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10289 tcg_temp_free_i32(tmp2);
10291 break;
10292 case 7:
10293 goto illegal_op;
10294 default: /* Saturate. */
10295 if (shift) {
10296 if (op & 1)
10297 tcg_gen_sari_i32(tmp, tmp, shift);
10298 else
10299 tcg_gen_shli_i32(tmp, tmp, shift);
10301 tmp2 = tcg_const_i32(imm);
10302 if (op & 4) {
10303 /* Unsigned. */
10304 if ((op & 1) && shift == 0) {
10305 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10306 tcg_temp_free_i32(tmp);
10307 tcg_temp_free_i32(tmp2);
10308 goto illegal_op;
10310 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10311 } else {
10312 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10314 } else {
10315 /* Signed. */
10316 if ((op & 1) && shift == 0) {
10317 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10318 tcg_temp_free_i32(tmp);
10319 tcg_temp_free_i32(tmp2);
10320 goto illegal_op;
10322 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10323 } else {
10324 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10327 tcg_temp_free_i32(tmp2);
10328 break;
10330 store_reg(s, rd, tmp);
10331 } else {
10332 imm = ((insn & 0x04000000) >> 15)
10333 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10334 if (insn & (1 << 22)) {
10335 /* 16-bit immediate. */
10336 imm |= (insn >> 4) & 0xf000;
10337 if (insn & (1 << 23)) {
10338 /* movt */
10339 tmp = load_reg(s, rd);
10340 tcg_gen_ext16u_i32(tmp, tmp);
10341 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10342 } else {
10343 /* movw */
10344 tmp = tcg_temp_new_i32();
10345 tcg_gen_movi_i32(tmp, imm);
10347 } else {
10348 /* Add/sub 12-bit immediate. */
10349 if (rn == 15) {
10350 offset = s->pc & ~(uint32_t)3;
10351 if (insn & (1 << 23))
10352 offset -= imm;
10353 else
10354 offset += imm;
10355 tmp = tcg_temp_new_i32();
10356 tcg_gen_movi_i32(tmp, offset);
10357 } else {
10358 tmp = load_reg(s, rn);
10359 if (insn & (1 << 23))
10360 tcg_gen_subi_i32(tmp, tmp, imm);
10361 else
10362 tcg_gen_addi_i32(tmp, tmp, imm);
10365 store_reg(s, rd, tmp);
10367 } else {
10368 int shifter_out = 0;
10369 /* modified 12-bit immediate. */
10370 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10371 imm = (insn & 0xff);
10372 switch (shift) {
10373 case 0: /* XY */
10374 /* Nothing to do. */
10375 break;
10376 case 1: /* 00XY00XY */
10377 imm |= imm << 16;
10378 break;
10379 case 2: /* XY00XY00 */
10380 imm |= imm << 16;
10381 imm <<= 8;
10382 break;
10383 case 3: /* XYXYXYXY */
10384 imm |= imm << 16;
10385 imm |= imm << 8;
10386 break;
10387 default: /* Rotated constant. */
10388 shift = (shift << 1) | (imm >> 7);
10389 imm |= 0x80;
10390 imm = imm << (32 - shift);
10391 shifter_out = 1;
10392 break;
10394 tmp2 = tcg_temp_new_i32();
10395 tcg_gen_movi_i32(tmp2, imm);
10396 rn = (insn >> 16) & 0xf;
10397 if (rn == 15) {
10398 tmp = tcg_temp_new_i32();
10399 tcg_gen_movi_i32(tmp, 0);
10400 } else {
10401 tmp = load_reg(s, rn);
10403 op = (insn >> 21) & 0xf;
10404 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10405 shifter_out, tmp, tmp2))
10406 goto illegal_op;
10407 tcg_temp_free_i32(tmp2);
10408 rd = (insn >> 8) & 0xf;
10409 if (rd != 15) {
10410 store_reg(s, rd, tmp);
10411 } else {
10412 tcg_temp_free_i32(tmp);
10416 break;
10417 case 12: /* Load/store single data item. */
10419 int postinc = 0;
10420 int writeback = 0;
10421 int memidx;
10422 if ((insn & 0x01100000) == 0x01000000) {
10423 if (disas_neon_ls_insn(s, insn)) {
10424 goto illegal_op;
10426 break;
10428 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10429 if (rs == 15) {
10430 if (!(insn & (1 << 20))) {
10431 goto illegal_op;
10433 if (op != 2) {
10434 /* Byte or halfword load space with dest == r15 : memory hints.
10435 * Catch them early so we don't emit pointless addressing code.
10436 * This space is a mix of:
10437 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10438 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10439 * cores)
10440 * unallocated hints, which must be treated as NOPs
10441 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10442 * which is easiest for the decoding logic
10443 * Some space which must UNDEF
10445 int op1 = (insn >> 23) & 3;
10446 int op2 = (insn >> 6) & 0x3f;
10447 if (op & 2) {
10448 goto illegal_op;
10450 if (rn == 15) {
10451 /* UNPREDICTABLE, unallocated hint or
10452 * PLD/PLDW/PLI (literal)
10454 return 0;
10456 if (op1 & 1) {
10457 return 0; /* PLD/PLDW/PLI or unallocated hint */
10459 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10460 return 0; /* PLD/PLDW/PLI or unallocated hint */
10462 /* UNDEF space, or an UNPREDICTABLE */
10463 return 1;
10466 memidx = get_mem_index(s);
10467 if (rn == 15) {
10468 addr = tcg_temp_new_i32();
10469 /* PC relative. */
10470 /* s->pc has already been incremented by 4. */
10471 imm = s->pc & 0xfffffffc;
10472 if (insn & (1 << 23))
10473 imm += insn & 0xfff;
10474 else
10475 imm -= insn & 0xfff;
10476 tcg_gen_movi_i32(addr, imm);
10477 } else {
10478 addr = load_reg(s, rn);
10479 if (insn & (1 << 23)) {
10480 /* Positive offset. */
10481 imm = insn & 0xfff;
10482 tcg_gen_addi_i32(addr, addr, imm);
10483 } else {
10484 imm = insn & 0xff;
10485 switch ((insn >> 8) & 0xf) {
10486 case 0x0: /* Shifted Register. */
10487 shift = (insn >> 4) & 0xf;
10488 if (shift > 3) {
10489 tcg_temp_free_i32(addr);
10490 goto illegal_op;
10492 tmp = load_reg(s, rm);
10493 if (shift)
10494 tcg_gen_shli_i32(tmp, tmp, shift);
10495 tcg_gen_add_i32(addr, addr, tmp);
10496 tcg_temp_free_i32(tmp);
10497 break;
10498 case 0xc: /* Negative offset. */
10499 tcg_gen_addi_i32(addr, addr, -imm);
10500 break;
10501 case 0xe: /* User privilege. */
10502 tcg_gen_addi_i32(addr, addr, imm);
10503 memidx = get_a32_user_mem_index(s);
10504 break;
10505 case 0x9: /* Post-decrement. */
10506 imm = -imm;
10507 /* Fall through. */
10508 case 0xb: /* Post-increment. */
10509 postinc = 1;
10510 writeback = 1;
10511 break;
10512 case 0xd: /* Pre-decrement. */
10513 imm = -imm;
10514 /* Fall through. */
10515 case 0xf: /* Pre-increment. */
10516 tcg_gen_addi_i32(addr, addr, imm);
10517 writeback = 1;
10518 break;
10519 default:
10520 tcg_temp_free_i32(addr);
10521 goto illegal_op;
10525 if (insn & (1 << 20)) {
10526 /* Load. */
10527 tmp = tcg_temp_new_i32();
10528 switch (op) {
10529 case 0:
10530 gen_aa32_ld8u(s, tmp, addr, memidx);
10531 break;
10532 case 4:
10533 gen_aa32_ld8s(s, tmp, addr, memidx);
10534 break;
10535 case 1:
10536 gen_aa32_ld16u(s, tmp, addr, memidx);
10537 break;
10538 case 5:
10539 gen_aa32_ld16s(s, tmp, addr, memidx);
10540 break;
10541 case 2:
10542 gen_aa32_ld32u(s, tmp, addr, memidx);
10543 break;
10544 default:
10545 tcg_temp_free_i32(tmp);
10546 tcg_temp_free_i32(addr);
10547 goto illegal_op;
10549 if (rs == 15) {
10550 gen_bx(s, tmp);
10551 } else {
10552 store_reg(s, rs, tmp);
10554 } else {
10555 /* Store. */
10556 tmp = load_reg(s, rs);
10557 switch (op) {
10558 case 0:
10559 gen_aa32_st8(s, tmp, addr, memidx);
10560 break;
10561 case 1:
10562 gen_aa32_st16(s, tmp, addr, memidx);
10563 break;
10564 case 2:
10565 gen_aa32_st32(s, tmp, addr, memidx);
10566 break;
10567 default:
10568 tcg_temp_free_i32(tmp);
10569 tcg_temp_free_i32(addr);
10570 goto illegal_op;
10572 tcg_temp_free_i32(tmp);
10574 if (postinc)
10575 tcg_gen_addi_i32(addr, addr, imm);
10576 if (writeback) {
10577 store_reg(s, rn, addr);
10578 } else {
10579 tcg_temp_free_i32(addr);
10582 break;
10583 default:
10584 goto illegal_op;
10586 return 0;
10587 illegal_op:
10588 return 1;
10591 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10593 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10594 int32_t offset;
10595 int i;
10596 TCGv_i32 tmp;
10597 TCGv_i32 tmp2;
10598 TCGv_i32 addr;
10600 if (s->condexec_mask) {
10601 cond = s->condexec_cond;
10602 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10603 s->condlabel = gen_new_label();
10604 arm_gen_test_cc(cond ^ 1, s->condlabel);
10605 s->condjmp = 1;
10609 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
10610 s->pc += 2;
10612 switch (insn >> 12) {
10613 case 0: case 1:
10615 rd = insn & 7;
10616 op = (insn >> 11) & 3;
10617 if (op == 3) {
10618 /* add/subtract */
10619 rn = (insn >> 3) & 7;
10620 tmp = load_reg(s, rn);
10621 if (insn & (1 << 10)) {
10622 /* immediate */
10623 tmp2 = tcg_temp_new_i32();
10624 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10625 } else {
10626 /* reg */
10627 rm = (insn >> 6) & 7;
10628 tmp2 = load_reg(s, rm);
10630 if (insn & (1 << 9)) {
10631 if (s->condexec_mask)
10632 tcg_gen_sub_i32(tmp, tmp, tmp2);
10633 else
10634 gen_sub_CC(tmp, tmp, tmp2);
10635 } else {
10636 if (s->condexec_mask)
10637 tcg_gen_add_i32(tmp, tmp, tmp2);
10638 else
10639 gen_add_CC(tmp, tmp, tmp2);
10641 tcg_temp_free_i32(tmp2);
10642 store_reg(s, rd, tmp);
10643 } else {
10644 /* shift immediate */
10645 rm = (insn >> 3) & 7;
10646 shift = (insn >> 6) & 0x1f;
10647 tmp = load_reg(s, rm);
10648 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10649 if (!s->condexec_mask)
10650 gen_logic_CC(tmp);
10651 store_reg(s, rd, tmp);
10653 break;
10654 case 2: case 3:
10655 /* arithmetic large immediate */
10656 op = (insn >> 11) & 3;
10657 rd = (insn >> 8) & 0x7;
10658 if (op == 0) { /* mov */
10659 tmp = tcg_temp_new_i32();
10660 tcg_gen_movi_i32(tmp, insn & 0xff);
10661 if (!s->condexec_mask)
10662 gen_logic_CC(tmp);
10663 store_reg(s, rd, tmp);
10664 } else {
10665 tmp = load_reg(s, rd);
10666 tmp2 = tcg_temp_new_i32();
10667 tcg_gen_movi_i32(tmp2, insn & 0xff);
10668 switch (op) {
10669 case 1: /* cmp */
10670 gen_sub_CC(tmp, tmp, tmp2);
10671 tcg_temp_free_i32(tmp);
10672 tcg_temp_free_i32(tmp2);
10673 break;
10674 case 2: /* add */
10675 if (s->condexec_mask)
10676 tcg_gen_add_i32(tmp, tmp, tmp2);
10677 else
10678 gen_add_CC(tmp, tmp, tmp2);
10679 tcg_temp_free_i32(tmp2);
10680 store_reg(s, rd, tmp);
10681 break;
10682 case 3: /* sub */
10683 if (s->condexec_mask)
10684 tcg_gen_sub_i32(tmp, tmp, tmp2);
10685 else
10686 gen_sub_CC(tmp, tmp, tmp2);
10687 tcg_temp_free_i32(tmp2);
10688 store_reg(s, rd, tmp);
10689 break;
10692 break;
10693 case 4:
10694 if (insn & (1 << 11)) {
10695 rd = (insn >> 8) & 7;
10696 /* load pc-relative. Bit 1 of PC is ignored. */
10697 val = s->pc + 2 + ((insn & 0xff) * 4);
10698 val &= ~(uint32_t)2;
10699 addr = tcg_temp_new_i32();
10700 tcg_gen_movi_i32(addr, val);
10701 tmp = tcg_temp_new_i32();
10702 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10703 tcg_temp_free_i32(addr);
10704 store_reg(s, rd, tmp);
10705 break;
10707 if (insn & (1 << 10)) {
10708 /* data processing extended or blx */
10709 rd = (insn & 7) | ((insn >> 4) & 8);
10710 rm = (insn >> 3) & 0xf;
10711 op = (insn >> 8) & 3;
10712 switch (op) {
10713 case 0: /* add */
10714 tmp = load_reg(s, rd);
10715 tmp2 = load_reg(s, rm);
10716 tcg_gen_add_i32(tmp, tmp, tmp2);
10717 tcg_temp_free_i32(tmp2);
10718 store_reg(s, rd, tmp);
10719 break;
10720 case 1: /* cmp */
10721 tmp = load_reg(s, rd);
10722 tmp2 = load_reg(s, rm);
10723 gen_sub_CC(tmp, tmp, tmp2);
10724 tcg_temp_free_i32(tmp2);
10725 tcg_temp_free_i32(tmp);
10726 break;
10727 case 2: /* mov/cpy */
10728 tmp = load_reg(s, rm);
10729 store_reg(s, rd, tmp);
10730 break;
10731 case 3:/* branch [and link] exchange thumb register */
10732 tmp = load_reg(s, rm);
10733 if (insn & (1 << 7)) {
10734 ARCH(5);
10735 val = (uint32_t)s->pc | 1;
10736 tmp2 = tcg_temp_new_i32();
10737 tcg_gen_movi_i32(tmp2, val);
10738 store_reg(s, 14, tmp2);
10740 /* already thumb, no need to check */
10741 gen_bx(s, tmp);
10742 break;
10744 break;
10747 /* data processing register */
10748 rd = insn & 7;
10749 rm = (insn >> 3) & 7;
10750 op = (insn >> 6) & 0xf;
10751 if (op == 2 || op == 3 || op == 4 || op == 7) {
10752 /* the shift/rotate ops want the operands backwards */
10753 val = rm;
10754 rm = rd;
10755 rd = val;
10756 val = 1;
10757 } else {
10758 val = 0;
10761 if (op == 9) { /* neg */
10762 tmp = tcg_temp_new_i32();
10763 tcg_gen_movi_i32(tmp, 0);
10764 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10765 tmp = load_reg(s, rd);
10766 } else {
10767 TCGV_UNUSED_I32(tmp);
10770 tmp2 = load_reg(s, rm);
10771 switch (op) {
10772 case 0x0: /* and */
10773 tcg_gen_and_i32(tmp, tmp, tmp2);
10774 if (!s->condexec_mask)
10775 gen_logic_CC(tmp);
10776 break;
10777 case 0x1: /* eor */
10778 tcg_gen_xor_i32(tmp, tmp, tmp2);
10779 if (!s->condexec_mask)
10780 gen_logic_CC(tmp);
10781 break;
10782 case 0x2: /* lsl */
10783 if (s->condexec_mask) {
10784 gen_shl(tmp2, tmp2, tmp);
10785 } else {
10786 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10787 gen_logic_CC(tmp2);
10789 break;
10790 case 0x3: /* lsr */
10791 if (s->condexec_mask) {
10792 gen_shr(tmp2, tmp2, tmp);
10793 } else {
10794 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10795 gen_logic_CC(tmp2);
10797 break;
10798 case 0x4: /* asr */
10799 if (s->condexec_mask) {
10800 gen_sar(tmp2, tmp2, tmp);
10801 } else {
10802 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10803 gen_logic_CC(tmp2);
10805 break;
10806 case 0x5: /* adc */
10807 if (s->condexec_mask) {
10808 gen_adc(tmp, tmp2);
10809 } else {
10810 gen_adc_CC(tmp, tmp, tmp2);
10812 break;
10813 case 0x6: /* sbc */
10814 if (s->condexec_mask) {
10815 gen_sub_carry(tmp, tmp, tmp2);
10816 } else {
10817 gen_sbc_CC(tmp, tmp, tmp2);
10819 break;
10820 case 0x7: /* ror */
10821 if (s->condexec_mask) {
10822 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10823 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10824 } else {
10825 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10826 gen_logic_CC(tmp2);
10828 break;
10829 case 0x8: /* tst */
10830 tcg_gen_and_i32(tmp, tmp, tmp2);
10831 gen_logic_CC(tmp);
10832 rd = 16;
10833 break;
10834 case 0x9: /* neg */
10835 if (s->condexec_mask)
10836 tcg_gen_neg_i32(tmp, tmp2);
10837 else
10838 gen_sub_CC(tmp, tmp, tmp2);
10839 break;
10840 case 0xa: /* cmp */
10841 gen_sub_CC(tmp, tmp, tmp2);
10842 rd = 16;
10843 break;
10844 case 0xb: /* cmn */
10845 gen_add_CC(tmp, tmp, tmp2);
10846 rd = 16;
10847 break;
10848 case 0xc: /* orr */
10849 tcg_gen_or_i32(tmp, tmp, tmp2);
10850 if (!s->condexec_mask)
10851 gen_logic_CC(tmp);
10852 break;
10853 case 0xd: /* mul */
10854 tcg_gen_mul_i32(tmp, tmp, tmp2);
10855 if (!s->condexec_mask)
10856 gen_logic_CC(tmp);
10857 break;
10858 case 0xe: /* bic */
10859 tcg_gen_andc_i32(tmp, tmp, tmp2);
10860 if (!s->condexec_mask)
10861 gen_logic_CC(tmp);
10862 break;
10863 case 0xf: /* mvn */
10864 tcg_gen_not_i32(tmp2, tmp2);
10865 if (!s->condexec_mask)
10866 gen_logic_CC(tmp2);
10867 val = 1;
10868 rm = rd;
10869 break;
10871 if (rd != 16) {
10872 if (val) {
10873 store_reg(s, rm, tmp2);
10874 if (op != 0xf)
10875 tcg_temp_free_i32(tmp);
10876 } else {
10877 store_reg(s, rd, tmp);
10878 tcg_temp_free_i32(tmp2);
10880 } else {
10881 tcg_temp_free_i32(tmp);
10882 tcg_temp_free_i32(tmp2);
10884 break;
10886 case 5:
10887 /* load/store register offset. */
10888 rd = insn & 7;
10889 rn = (insn >> 3) & 7;
10890 rm = (insn >> 6) & 7;
10891 op = (insn >> 9) & 7;
10892 addr = load_reg(s, rn);
10893 tmp = load_reg(s, rm);
10894 tcg_gen_add_i32(addr, addr, tmp);
10895 tcg_temp_free_i32(tmp);
10897 if (op < 3) { /* store */
10898 tmp = load_reg(s, rd);
10899 } else {
10900 tmp = tcg_temp_new_i32();
10903 switch (op) {
10904 case 0: /* str */
10905 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10906 break;
10907 case 1: /* strh */
10908 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10909 break;
10910 case 2: /* strb */
10911 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10912 break;
10913 case 3: /* ldrsb */
10914 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
10915 break;
10916 case 4: /* ldr */
10917 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10918 break;
10919 case 5: /* ldrh */
10920 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10921 break;
10922 case 6: /* ldrb */
10923 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10924 break;
10925 case 7: /* ldrsh */
10926 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
10927 break;
10929 if (op >= 3) { /* load */
10930 store_reg(s, rd, tmp);
10931 } else {
10932 tcg_temp_free_i32(tmp);
10934 tcg_temp_free_i32(addr);
10935 break;
10937 case 6:
10938 /* load/store word immediate offset */
10939 rd = insn & 7;
10940 rn = (insn >> 3) & 7;
10941 addr = load_reg(s, rn);
10942 val = (insn >> 4) & 0x7c;
10943 tcg_gen_addi_i32(addr, addr, val);
10945 if (insn & (1 << 11)) {
10946 /* load */
10947 tmp = tcg_temp_new_i32();
10948 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10949 store_reg(s, rd, tmp);
10950 } else {
10951 /* store */
10952 tmp = load_reg(s, rd);
10953 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10954 tcg_temp_free_i32(tmp);
10956 tcg_temp_free_i32(addr);
10957 break;
10959 case 7:
10960 /* load/store byte immediate offset */
10961 rd = insn & 7;
10962 rn = (insn >> 3) & 7;
10963 addr = load_reg(s, rn);
10964 val = (insn >> 6) & 0x1f;
10965 tcg_gen_addi_i32(addr, addr, val);
10967 if (insn & (1 << 11)) {
10968 /* load */
10969 tmp = tcg_temp_new_i32();
10970 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10971 store_reg(s, rd, tmp);
10972 } else {
10973 /* store */
10974 tmp = load_reg(s, rd);
10975 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10976 tcg_temp_free_i32(tmp);
10978 tcg_temp_free_i32(addr);
10979 break;
10981 case 8:
10982 /* load/store halfword immediate offset */
10983 rd = insn & 7;
10984 rn = (insn >> 3) & 7;
10985 addr = load_reg(s, rn);
10986 val = (insn >> 5) & 0x3e;
10987 tcg_gen_addi_i32(addr, addr, val);
10989 if (insn & (1 << 11)) {
10990 /* load */
10991 tmp = tcg_temp_new_i32();
10992 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10993 store_reg(s, rd, tmp);
10994 } else {
10995 /* store */
10996 tmp = load_reg(s, rd);
10997 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10998 tcg_temp_free_i32(tmp);
11000 tcg_temp_free_i32(addr);
11001 break;
11003 case 9:
11004 /* load/store from stack */
11005 rd = (insn >> 8) & 7;
11006 addr = load_reg(s, 13);
11007 val = (insn & 0xff) * 4;
11008 tcg_gen_addi_i32(addr, addr, val);
11010 if (insn & (1 << 11)) {
11011 /* load */
11012 tmp = tcg_temp_new_i32();
11013 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11014 store_reg(s, rd, tmp);
11015 } else {
11016 /* store */
11017 tmp = load_reg(s, rd);
11018 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11019 tcg_temp_free_i32(tmp);
11021 tcg_temp_free_i32(addr);
11022 break;
11024 case 10:
11025 /* add to high reg */
11026 rd = (insn >> 8) & 7;
11027 if (insn & (1 << 11)) {
11028 /* SP */
11029 tmp = load_reg(s, 13);
11030 } else {
11031 /* PC. bit 1 is ignored. */
11032 tmp = tcg_temp_new_i32();
11033 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11035 val = (insn & 0xff) * 4;
11036 tcg_gen_addi_i32(tmp, tmp, val);
11037 store_reg(s, rd, tmp);
11038 break;
11040 case 11:
11041 /* misc */
11042 op = (insn >> 8) & 0xf;
11043 switch (op) {
11044 case 0:
11045 /* adjust stack pointer */
11046 tmp = load_reg(s, 13);
11047 val = (insn & 0x7f) * 4;
11048 if (insn & (1 << 7))
11049 val = -(int32_t)val;
11050 tcg_gen_addi_i32(tmp, tmp, val);
11051 store_reg(s, 13, tmp);
11052 break;
11054 case 2: /* sign/zero extend. */
11055 ARCH(6);
11056 rd = insn & 7;
11057 rm = (insn >> 3) & 7;
11058 tmp = load_reg(s, rm);
11059 switch ((insn >> 6) & 3) {
11060 case 0: gen_sxth(tmp); break;
11061 case 1: gen_sxtb(tmp); break;
11062 case 2: gen_uxth(tmp); break;
11063 case 3: gen_uxtb(tmp); break;
11065 store_reg(s, rd, tmp);
11066 break;
11067 case 4: case 5: case 0xc: case 0xd:
11068 /* push/pop */
11069 addr = load_reg(s, 13);
11070 if (insn & (1 << 8))
11071 offset = 4;
11072 else
11073 offset = 0;
11074 for (i = 0; i < 8; i++) {
11075 if (insn & (1 << i))
11076 offset += 4;
11078 if ((insn & (1 << 11)) == 0) {
11079 tcg_gen_addi_i32(addr, addr, -offset);
11081 for (i = 0; i < 8; i++) {
11082 if (insn & (1 << i)) {
11083 if (insn & (1 << 11)) {
11084 /* pop */
11085 tmp = tcg_temp_new_i32();
11086 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11087 store_reg(s, i, tmp);
11088 } else {
11089 /* push */
11090 tmp = load_reg(s, i);
11091 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11092 tcg_temp_free_i32(tmp);
11094 /* advance to the next address. */
11095 tcg_gen_addi_i32(addr, addr, 4);
11098 TCGV_UNUSED_I32(tmp);
11099 if (insn & (1 << 8)) {
11100 if (insn & (1 << 11)) {
11101 /* pop pc */
11102 tmp = tcg_temp_new_i32();
11103 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11104 /* don't set the pc until the rest of the instruction
11105 has completed */
11106 } else {
11107 /* push lr */
11108 tmp = load_reg(s, 14);
11109 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11110 tcg_temp_free_i32(tmp);
11112 tcg_gen_addi_i32(addr, addr, 4);
11114 if ((insn & (1 << 11)) == 0) {
11115 tcg_gen_addi_i32(addr, addr, -offset);
11117 /* write back the new stack pointer */
11118 store_reg(s, 13, addr);
11119 /* set the new PC value */
11120 if ((insn & 0x0900) == 0x0900) {
11121 store_reg_from_load(s, 15, tmp);
11123 break;
11125 case 1: case 3: case 9: case 11: /* czb */
11126 rm = insn & 7;
11127 tmp = load_reg(s, rm);
11128 s->condlabel = gen_new_label();
11129 s->condjmp = 1;
11130 if (insn & (1 << 11))
11131 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11132 else
11133 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11134 tcg_temp_free_i32(tmp);
11135 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11136 val = (uint32_t)s->pc + 2;
11137 val += offset;
11138 gen_jmp(s, val);
11139 break;
11141 case 15: /* IT, nop-hint. */
11142 if ((insn & 0xf) == 0) {
11143 gen_nop_hint(s, (insn >> 4) & 0xf);
11144 break;
11146 /* If Then. */
11147 s->condexec_cond = (insn >> 4) & 0xe;
11148 s->condexec_mask = insn & 0x1f;
11149 /* No actual code generated for this insn, just setup state. */
11150 break;
11152 case 0xe: /* bkpt */
11154 int imm8 = extract32(insn, 0, 8);
11155 ARCH(5);
11156 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11157 default_exception_el(s));
11158 break;
11161 case 0xa: /* rev */
11162 ARCH(6);
11163 rn = (insn >> 3) & 0x7;
11164 rd = insn & 0x7;
11165 tmp = load_reg(s, rn);
11166 switch ((insn >> 6) & 3) {
11167 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11168 case 1: gen_rev16(tmp); break;
11169 case 3: gen_revsh(tmp); break;
11170 default: goto illegal_op;
11172 store_reg(s, rd, tmp);
11173 break;
11175 case 6:
11176 switch ((insn >> 5) & 7) {
11177 case 2:
11178 /* setend */
11179 ARCH(6);
11180 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11181 gen_helper_setend(cpu_env);
11182 s->is_jmp = DISAS_UPDATE;
11184 break;
11185 case 3:
11186 /* cps */
11187 ARCH(6);
11188 if (IS_USER(s)) {
11189 break;
11191 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11192 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11193 /* FAULTMASK */
11194 if (insn & 1) {
11195 addr = tcg_const_i32(19);
11196 gen_helper_v7m_msr(cpu_env, addr, tmp);
11197 tcg_temp_free_i32(addr);
11199 /* PRIMASK */
11200 if (insn & 2) {
11201 addr = tcg_const_i32(16);
11202 gen_helper_v7m_msr(cpu_env, addr, tmp);
11203 tcg_temp_free_i32(addr);
11205 tcg_temp_free_i32(tmp);
11206 gen_lookup_tb(s);
11207 } else {
11208 if (insn & (1 << 4)) {
11209 shift = CPSR_A | CPSR_I | CPSR_F;
11210 } else {
11211 shift = 0;
11213 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11215 break;
11216 default:
11217 goto undef;
11219 break;
11221 default:
11222 goto undef;
11224 break;
11226 case 12:
11228 /* load/store multiple */
11229 TCGv_i32 loaded_var;
11230 TCGV_UNUSED_I32(loaded_var);
11231 rn = (insn >> 8) & 0x7;
11232 addr = load_reg(s, rn);
11233 for (i = 0; i < 8; i++) {
11234 if (insn & (1 << i)) {
11235 if (insn & (1 << 11)) {
11236 /* load */
11237 tmp = tcg_temp_new_i32();
11238 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11239 if (i == rn) {
11240 loaded_var = tmp;
11241 } else {
11242 store_reg(s, i, tmp);
11244 } else {
11245 /* store */
11246 tmp = load_reg(s, i);
11247 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11248 tcg_temp_free_i32(tmp);
11250 /* advance to the next address */
11251 tcg_gen_addi_i32(addr, addr, 4);
11254 if ((insn & (1 << rn)) == 0) {
11255 /* base reg not in list: base register writeback */
11256 store_reg(s, rn, addr);
11257 } else {
11258 /* base reg in list: if load, complete it now */
11259 if (insn & (1 << 11)) {
11260 store_reg(s, rn, loaded_var);
11262 tcg_temp_free_i32(addr);
11264 break;
11266 case 13:
11267 /* conditional branch or swi */
11268 cond = (insn >> 8) & 0xf;
11269 if (cond == 0xe)
11270 goto undef;
11272 if (cond == 0xf) {
11273 /* swi */
11274 gen_set_pc_im(s, s->pc);
11275 s->svc_imm = extract32(insn, 0, 8);
11276 s->is_jmp = DISAS_SWI;
11277 break;
11279 /* generate a conditional jump to next instruction */
11280 s->condlabel = gen_new_label();
11281 arm_gen_test_cc(cond ^ 1, s->condlabel);
11282 s->condjmp = 1;
11284 /* jump to the offset */
11285 val = (uint32_t)s->pc + 2;
11286 offset = ((int32_t)insn << 24) >> 24;
11287 val += offset << 1;
11288 gen_jmp(s, val);
11289 break;
11291 case 14:
11292 if (insn & (1 << 11)) {
11293 if (disas_thumb2_insn(env, s, insn))
11294 goto undef32;
11295 break;
11297 /* unconditional branch */
11298 val = (uint32_t)s->pc;
11299 offset = ((int32_t)insn << 21) >> 21;
11300 val += (offset << 1) + 2;
11301 gen_jmp(s, val);
11302 break;
11304 case 15:
11305 if (disas_thumb2_insn(env, s, insn))
11306 goto undef32;
11307 break;
11309 return;
11310 undef32:
11311 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11312 default_exception_el(s));
11313 return;
11314 illegal_op:
11315 undef:
11316 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11317 default_exception_el(s));
11320 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11322 /* Return true if the insn at dc->pc might cross a page boundary.
11323 * (False positives are OK, false negatives are not.)
11325 uint16_t insn;
11327 if ((s->pc & 3) == 0) {
11328 /* At a 4-aligned address we can't be crossing a page */
11329 return false;
11332 /* This must be a Thumb insn */
11333 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11335 if ((insn >> 11) >= 0x1d) {
11336 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11337 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11338 * end up actually treating this as two 16-bit insns (see the
11339 * code at the start of disas_thumb2_insn()) but we don't bother
11340 * to check for that as it is unlikely, and false positives here
11341 * are harmless.
11343 return true;
11345 /* Definitely a 16-bit insn, can't be crossing a page. */
11346 return false;
11349 /* generate intermediate code for basic block 'tb'. */
11350 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11352 ARMCPU *cpu = arm_env_get_cpu(env);
11353 CPUState *cs = CPU(cpu);
11354 DisasContext dc1, *dc = &dc1;
11355 target_ulong pc_start;
11356 target_ulong next_page_start;
11357 int num_insns;
11358 int max_insns;
11359 bool end_of_page;
11361 /* generate intermediate code */
11363 /* The A64 decoder has its own top level loop, because it doesn't need
11364 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11366 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11367 gen_intermediate_code_a64(cpu, tb);
11368 return;
11371 pc_start = tb->pc;
11373 dc->tb = tb;
11375 dc->is_jmp = DISAS_NEXT;
11376 dc->pc = pc_start;
11377 dc->singlestep_enabled = cs->singlestep_enabled;
11378 dc->condjmp = 0;
11380 dc->aarch64 = 0;
11381 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11382 * there is no secure EL1, so we route exceptions to EL3.
11384 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11385 !arm_el_is_aa64(env, 3);
11386 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11387 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11388 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11389 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11390 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11391 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11392 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11393 #if !defined(CONFIG_USER_ONLY)
11394 dc->user = (dc->current_el == 0);
11395 #endif
11396 dc->ns = ARM_TBFLAG_NS(tb->flags);
11397 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11398 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11399 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11400 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11401 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11402 dc->cp_regs = cpu->cp_regs;
11403 dc->features = env->features;
11405 /* Single step state. The code-generation logic here is:
11406 * SS_ACTIVE == 0:
11407 * generate code with no special handling for single-stepping (except
11408 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11409 * this happens anyway because those changes are all system register or
11410 * PSTATE writes).
11411 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11412 * emit code for one insn
11413 * emit code to clear PSTATE.SS
11414 * emit code to generate software step exception for completed step
11415 * end TB (as usual for having generated an exception)
11416 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11417 * emit code to generate a software step exception
11418 * end the TB
11420 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11421 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11422 dc->is_ldex = false;
11423 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11425 cpu_F0s = tcg_temp_new_i32();
11426 cpu_F1s = tcg_temp_new_i32();
11427 cpu_F0d = tcg_temp_new_i64();
11428 cpu_F1d = tcg_temp_new_i64();
11429 cpu_V0 = cpu_F0d;
11430 cpu_V1 = cpu_F1d;
11431 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11432 cpu_M0 = tcg_temp_new_i64();
11433 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11434 num_insns = 0;
11435 max_insns = tb->cflags & CF_COUNT_MASK;
11436 if (max_insns == 0) {
11437 max_insns = CF_COUNT_MASK;
11439 if (max_insns > TCG_MAX_INSNS) {
11440 max_insns = TCG_MAX_INSNS;
11443 gen_tb_start(tb);
11445 tcg_clear_temp_count();
11447 /* A note on handling of the condexec (IT) bits:
11449 * We want to avoid the overhead of having to write the updated condexec
11450 * bits back to the CPUARMState for every instruction in an IT block. So:
11451 * (1) if the condexec bits are not already zero then we write
11452 * zero back into the CPUARMState now. This avoids complications trying
11453 * to do it at the end of the block. (For example if we don't do this
11454 * it's hard to identify whether we can safely skip writing condexec
11455 * at the end of the TB, which we definitely want to do for the case
11456 * where a TB doesn't do anything with the IT state at all.)
11457 * (2) if we are going to leave the TB then we call gen_set_condexec()
11458 * which will write the correct value into CPUARMState if zero is wrong.
11459 * This is done both for leaving the TB at the end, and for leaving
11460 * it because of an exception we know will happen, which is done in
11461 * gen_exception_insn(). The latter is necessary because we need to
11462 * leave the TB with the PC/IT state just prior to execution of the
11463 * instruction which caused the exception.
11464 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11465 * then the CPUARMState will be wrong and we need to reset it.
11466 * This is handled in the same way as restoration of the
11467 * PC in these situations; we save the value of the condexec bits
11468 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11469 * then uses this to restore them after an exception.
11471 * Note that there are no instructions which can read the condexec
11472 * bits, and none which can write non-static values to them, so
11473 * we don't need to care about whether CPUARMState is correct in the
11474 * middle of a TB.
11477 /* Reset the conditional execution bits immediately. This avoids
11478 complications trying to do it at the end of the block. */
11479 if (dc->condexec_mask || dc->condexec_cond)
11481 TCGv_i32 tmp = tcg_temp_new_i32();
11482 tcg_gen_movi_i32(tmp, 0);
11483 store_cpu_field(tmp, condexec_bits);
11485 do {
11486 tcg_gen_insn_start(dc->pc,
11487 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1));
11488 num_insns++;
11490 #ifdef CONFIG_USER_ONLY
11491 /* Intercept jump to the magic kernel page. */
11492 if (dc->pc >= 0xffff0000) {
11493 /* We always get here via a jump, so know we are not in a
11494 conditional execution block. */
11495 gen_exception_internal(EXCP_KERNEL_TRAP);
11496 dc->is_jmp = DISAS_EXC;
11497 break;
11499 #else
11500 if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
11501 /* We always get here via a jump, so know we are not in a
11502 conditional execution block. */
11503 gen_exception_internal(EXCP_EXCEPTION_EXIT);
11504 dc->is_jmp = DISAS_EXC;
11505 break;
11507 #endif
11509 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11510 CPUBreakpoint *bp;
11511 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11512 if (bp->pc == dc->pc) {
11513 if (bp->flags & BP_CPU) {
11514 gen_set_condexec(dc);
11515 gen_set_pc_im(dc, dc->pc);
11516 gen_helper_check_breakpoints(cpu_env);
11517 /* End the TB early; it's likely not going to be executed */
11518 dc->is_jmp = DISAS_UPDATE;
11519 } else {
11520 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11521 /* The address covered by the breakpoint must be
11522 included in [tb->pc, tb->pc + tb->size) in order
11523 to for it to be properly cleared -- thus we
11524 increment the PC here so that the logic setting
11525 tb->size below does the right thing. */
11526 /* TODO: Advance PC by correct instruction length to
11527 * avoid disassembler error messages */
11528 dc->pc += 2;
11529 goto done_generating;
11531 break;
11536 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11537 gen_io_start();
11540 if (dc->ss_active && !dc->pstate_ss) {
11541 /* Singlestep state is Active-pending.
11542 * If we're in this state at the start of a TB then either
11543 * a) we just took an exception to an EL which is being debugged
11544 * and this is the first insn in the exception handler
11545 * b) debug exceptions were masked and we just unmasked them
11546 * without changing EL (eg by clearing PSTATE.D)
11547 * In either case we're going to take a swstep exception in the
11548 * "did not step an insn" case, and so the syndrome ISV and EX
11549 * bits should be zero.
11551 assert(num_insns == 1);
11552 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11553 default_exception_el(dc));
11554 goto done_generating;
11557 if (dc->thumb) {
11558 disas_thumb_insn(env, dc);
11559 if (dc->condexec_mask) {
11560 dc->condexec_cond = (dc->condexec_cond & 0xe)
11561 | ((dc->condexec_mask >> 4) & 1);
11562 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11563 if (dc->condexec_mask == 0) {
11564 dc->condexec_cond = 0;
11567 } else {
11568 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
11569 dc->pc += 4;
11570 disas_arm_insn(dc, insn);
11573 if (dc->condjmp && !dc->is_jmp) {
11574 gen_set_label(dc->condlabel);
11575 dc->condjmp = 0;
11578 if (tcg_check_temp_count()) {
11579 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11580 dc->pc);
11583 /* Translation stops when a conditional branch is encountered.
11584 * Otherwise the subsequent code could get translated several times.
11585 * Also stop translation when a page boundary is reached. This
11586 * ensures prefetch aborts occur at the right place. */
11588 /* We want to stop the TB if the next insn starts in a new page,
11589 * or if it spans between this page and the next. This means that
11590 * if we're looking at the last halfword in the page we need to
11591 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11592 * or a 32-bit Thumb insn (which won't).
11593 * This is to avoid generating a silly TB with a single 16-bit insn
11594 * in it at the end of this page (which would execute correctly
11595 * but isn't very efficient).
11597 end_of_page = (dc->pc >= next_page_start) ||
11598 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
11600 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11601 !cs->singlestep_enabled &&
11602 !singlestep &&
11603 !dc->ss_active &&
11604 !end_of_page &&
11605 num_insns < max_insns);
11607 if (tb->cflags & CF_LAST_IO) {
11608 if (dc->condjmp) {
11609 /* FIXME: This can theoretically happen with self-modifying
11610 code. */
11611 cpu_abort(cs, "IO on conditional branch instruction");
11613 gen_io_end();
11616 /* At this stage dc->condjmp will only be set when the skipped
11617 instruction was a conditional branch or trap, and the PC has
11618 already been written. */
11619 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11620 /* Unconditional and "condition passed" instruction codepath. */
11621 gen_set_condexec(dc);
11622 switch (dc->is_jmp) {
11623 case DISAS_SWI:
11624 gen_ss_advance(dc);
11625 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11626 default_exception_el(dc));
11627 break;
11628 case DISAS_HVC:
11629 gen_ss_advance(dc);
11630 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11631 break;
11632 case DISAS_SMC:
11633 gen_ss_advance(dc);
11634 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11635 break;
11636 case DISAS_NEXT:
11637 case DISAS_UPDATE:
11638 gen_set_pc_im(dc, dc->pc);
11639 /* fall through */
11640 default:
11641 if (dc->ss_active) {
11642 gen_step_complete_exception(dc);
11643 } else {
11644 /* FIXME: Single stepping a WFI insn will not halt
11645 the CPU. */
11646 gen_exception_internal(EXCP_DEBUG);
11649 if (dc->condjmp) {
11650 /* "Condition failed" instruction codepath. */
11651 gen_set_label(dc->condlabel);
11652 gen_set_condexec(dc);
11653 gen_set_pc_im(dc, dc->pc);
11654 if (dc->ss_active) {
11655 gen_step_complete_exception(dc);
11656 } else {
11657 gen_exception_internal(EXCP_DEBUG);
11660 } else {
11661 /* While branches must always occur at the end of an IT block,
11662 there are a few other things that can cause us to terminate
11663 the TB in the middle of an IT block:
11664 - Exception generating instructions (bkpt, swi, undefined).
11665 - Page boundaries.
11666 - Hardware watchpoints.
11667 Hardware breakpoints have already been handled and skip this code.
11669 gen_set_condexec(dc);
11670 switch(dc->is_jmp) {
11671 case DISAS_NEXT:
11672 gen_goto_tb(dc, 1, dc->pc);
11673 break;
11674 case DISAS_UPDATE:
11675 gen_set_pc_im(dc, dc->pc);
11676 /* fall through */
11677 case DISAS_JUMP:
11678 default:
11679 /* indicate that the hash table must be used to find the next TB */
11680 tcg_gen_exit_tb(0);
11681 break;
11682 case DISAS_TB_JUMP:
11683 /* nothing more to generate */
11684 break;
11685 case DISAS_WFI:
11686 gen_helper_wfi(cpu_env);
11687 /* The helper doesn't necessarily throw an exception, but we
11688 * must go back to the main loop to check for interrupts anyway.
11690 tcg_gen_exit_tb(0);
11691 break;
11692 case DISAS_WFE:
11693 gen_helper_wfe(cpu_env);
11694 break;
11695 case DISAS_YIELD:
11696 gen_helper_yield(cpu_env);
11697 break;
11698 case DISAS_SWI:
11699 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11700 default_exception_el(dc));
11701 break;
11702 case DISAS_HVC:
11703 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11704 break;
11705 case DISAS_SMC:
11706 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11707 break;
11709 if (dc->condjmp) {
11710 gen_set_label(dc->condlabel);
11711 gen_set_condexec(dc);
11712 gen_goto_tb(dc, 1, dc->pc);
11713 dc->condjmp = 0;
11717 done_generating:
11718 gen_tb_end(tb, num_insns);
11720 #ifdef DEBUG_DISAS
11721 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11722 qemu_log("----------------\n");
11723 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11724 log_target_disas(cs, pc_start, dc->pc - pc_start,
11725 dc->thumb | (dc->sctlr_b << 1));
11726 qemu_log("\n");
11728 #endif
11729 tb->size = dc->pc - pc_start;
11730 tb->icount = num_insns;
11733 static const char *cpu_mode_names[16] = {
11734 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11735 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11738 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11739 int flags)
11741 ARMCPU *cpu = ARM_CPU(cs);
11742 CPUARMState *env = &cpu->env;
11743 int i;
11744 uint32_t psr;
11745 const char *ns_status;
11747 if (is_a64(env)) {
11748 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11749 return;
11752 for(i=0;i<16;i++) {
11753 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11754 if ((i % 4) == 3)
11755 cpu_fprintf(f, "\n");
11756 else
11757 cpu_fprintf(f, " ");
11759 psr = cpsr_read(env);
11761 if (arm_feature(env, ARM_FEATURE_EL3) &&
11762 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
11763 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
11764 } else {
11765 ns_status = "";
11768 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
11769 psr,
11770 psr & (1 << 31) ? 'N' : '-',
11771 psr & (1 << 30) ? 'Z' : '-',
11772 psr & (1 << 29) ? 'C' : '-',
11773 psr & (1 << 28) ? 'V' : '-',
11774 psr & CPSR_T ? 'T' : 'A',
11775 ns_status,
11776 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11778 if (flags & CPU_DUMP_FPU) {
11779 int numvfpregs = 0;
11780 if (arm_feature(env, ARM_FEATURE_VFP)) {
11781 numvfpregs += 16;
11783 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11784 numvfpregs += 16;
11786 for (i = 0; i < numvfpregs; i++) {
11787 uint64_t v = float64_val(env->vfp.regs[i]);
11788 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11789 i * 2, (uint32_t)v,
11790 i * 2 + 1, (uint32_t)(v >> 32),
11791 i, v);
11793 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11797 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
11798 target_ulong *data)
11800 if (is_a64(env)) {
11801 env->pc = data[0];
11802 env->condexec_bits = 0;
11803 } else {
11804 env->regs[15] = data[0];
11805 env->condexec_bits = data[1];