pci core: assert ENOSPC when add capability
[qemu/ar7.git] / target-arm / translate.c
blob3e7146769d548314f5d1f255396f870e069d44ab
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 "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "qemu/log.h"
29 #include "qemu/bitops.h"
30 #include "arm_ldst.h"
32 #include "exec/helper-proto.h"
33 #include "exec/helper-gen.h"
35 #include "trace-tcg.h"
36 #include "exec/log.h"
39 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
40 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
41 /* currently all emulated v5 cores are also v5TE, so don't bother */
42 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
43 #define ENABLE_ARCH_5J 0
44 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
45 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
46 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
47 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
48 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
50 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
52 #include "translate.h"
54 #if defined(CONFIG_USER_ONLY)
55 #define IS_USER(s) 1
56 #else
57 #define IS_USER(s) (s->user)
58 #endif
60 TCGv_env cpu_env;
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
63 static TCGv_i32 cpu_R[16];
64 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
65 TCGv_i64 cpu_exclusive_addr;
66 TCGv_i64 cpu_exclusive_val;
67 #ifdef CONFIG_USER_ONLY
68 TCGv_i64 cpu_exclusive_test;
69 TCGv_i32 cpu_exclusive_info;
70 #endif
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s, cpu_F1s;
74 static TCGv_i64 cpu_F0d, cpu_F1d;
76 #include "exec/gen-icount.h"
78 static const char *regnames[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
85 int i;
87 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
89 for (i = 0; i < 16; i++) {
90 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
91 offsetof(CPUARMState, regs[i]),
92 regnames[i]);
94 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
95 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
96 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
97 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
99 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
100 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
101 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
102 offsetof(CPUARMState, exclusive_val), "exclusive_val");
103 #ifdef CONFIG_USER_ONLY
104 cpu_exclusive_test = tcg_global_mem_new_i64(cpu_env,
105 offsetof(CPUARMState, exclusive_test), "exclusive_test");
106 cpu_exclusive_info = tcg_global_mem_new_i32(cpu_env,
107 offsetof(CPUARMState, exclusive_info), "exclusive_info");
108 #endif
110 a64_translate_init();
113 static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
115 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
116 * insns:
117 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
118 * otherwise, access as if at PL0.
120 switch (s->mmu_idx) {
121 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
122 case ARMMMUIdx_S12NSE0:
123 case ARMMMUIdx_S12NSE1:
124 return ARMMMUIdx_S12NSE0;
125 case ARMMMUIdx_S1E3:
126 case ARMMMUIdx_S1SE0:
127 case ARMMMUIdx_S1SE1:
128 return ARMMMUIdx_S1SE0;
129 case ARMMMUIdx_S2NS:
130 default:
131 g_assert_not_reached();
135 static inline TCGv_i32 load_cpu_offset(int offset)
137 TCGv_i32 tmp = tcg_temp_new_i32();
138 tcg_gen_ld_i32(tmp, cpu_env, offset);
139 return tmp;
142 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
144 static inline void store_cpu_offset(TCGv_i32 var, int offset)
146 tcg_gen_st_i32(var, cpu_env, offset);
147 tcg_temp_free_i32(var);
150 #define store_cpu_field(var, name) \
151 store_cpu_offset(var, offsetof(CPUARMState, name))
153 /* Set a variable to the value of a CPU register. */
154 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
156 if (reg == 15) {
157 uint32_t addr;
158 /* normally, since we updated PC, we need only to add one insn */
159 if (s->thumb)
160 addr = (long)s->pc + 2;
161 else
162 addr = (long)s->pc + 4;
163 tcg_gen_movi_i32(var, addr);
164 } else {
165 tcg_gen_mov_i32(var, cpu_R[reg]);
169 /* Create a new temporary and set it to the value of a CPU register. */
170 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
172 TCGv_i32 tmp = tcg_temp_new_i32();
173 load_reg_var(s, tmp, reg);
174 return tmp;
177 /* Set a CPU register. The source must be a temporary and will be
178 marked as dead. */
179 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
181 if (reg == 15) {
182 tcg_gen_andi_i32(var, var, ~1);
183 s->is_jmp = DISAS_JUMP;
185 tcg_gen_mov_i32(cpu_R[reg], var);
186 tcg_temp_free_i32(var);
189 /* Value extensions. */
190 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
191 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
192 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
193 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
195 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
196 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
199 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
201 TCGv_i32 tmp_mask = tcg_const_i32(mask);
202 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
203 tcg_temp_free_i32(tmp_mask);
205 /* Set NZCV flags from the high 4 bits of var. */
206 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
208 static void gen_exception_internal(int excp)
210 TCGv_i32 tcg_excp = tcg_const_i32(excp);
212 assert(excp_is_internal(excp));
213 gen_helper_exception_internal(cpu_env, tcg_excp);
214 tcg_temp_free_i32(tcg_excp);
217 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
219 TCGv_i32 tcg_excp = tcg_const_i32(excp);
220 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
221 TCGv_i32 tcg_el = tcg_const_i32(target_el);
223 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
224 tcg_syn, tcg_el);
226 tcg_temp_free_i32(tcg_el);
227 tcg_temp_free_i32(tcg_syn);
228 tcg_temp_free_i32(tcg_excp);
231 static void gen_ss_advance(DisasContext *s)
233 /* If the singlestep state is Active-not-pending, advance to
234 * Active-pending.
236 if (s->ss_active) {
237 s->pstate_ss = 0;
238 gen_helper_clear_pstate_ss(cpu_env);
242 static void gen_step_complete_exception(DisasContext *s)
244 /* We just completed step of an insn. Move from Active-not-pending
245 * to Active-pending, and then also take the swstep exception.
246 * This corresponds to making the (IMPDEF) choice to prioritize
247 * swstep exceptions over asynchronous exceptions taken to an exception
248 * level where debug is disabled. This choice has the advantage that
249 * we do not need to maintain internal state corresponding to the
250 * ISV/EX syndrome bits between completion of the step and generation
251 * of the exception, and our syndrome information is always correct.
253 gen_ss_advance(s);
254 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
255 default_exception_el(s));
256 s->is_jmp = DISAS_EXC;
259 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
261 TCGv_i32 tmp1 = tcg_temp_new_i32();
262 TCGv_i32 tmp2 = tcg_temp_new_i32();
263 tcg_gen_ext16s_i32(tmp1, a);
264 tcg_gen_ext16s_i32(tmp2, b);
265 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
266 tcg_temp_free_i32(tmp2);
267 tcg_gen_sari_i32(a, a, 16);
268 tcg_gen_sari_i32(b, b, 16);
269 tcg_gen_mul_i32(b, b, a);
270 tcg_gen_mov_i32(a, tmp1);
271 tcg_temp_free_i32(tmp1);
274 /* Byteswap each halfword. */
275 static void gen_rev16(TCGv_i32 var)
277 TCGv_i32 tmp = tcg_temp_new_i32();
278 tcg_gen_shri_i32(tmp, var, 8);
279 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
280 tcg_gen_shli_i32(var, var, 8);
281 tcg_gen_andi_i32(var, var, 0xff00ff00);
282 tcg_gen_or_i32(var, var, tmp);
283 tcg_temp_free_i32(tmp);
286 /* Byteswap low halfword and sign extend. */
287 static void gen_revsh(TCGv_i32 var)
289 tcg_gen_ext16u_i32(var, var);
290 tcg_gen_bswap16_i32(var, var);
291 tcg_gen_ext16s_i32(var, var);
294 /* Unsigned bitfield extract. */
295 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
297 if (shift)
298 tcg_gen_shri_i32(var, var, shift);
299 tcg_gen_andi_i32(var, var, mask);
302 /* Signed bitfield extract. */
303 static void gen_sbfx(TCGv_i32 var, int shift, int width)
305 uint32_t signbit;
307 if (shift)
308 tcg_gen_sari_i32(var, var, shift);
309 if (shift + width < 32) {
310 signbit = 1u << (width - 1);
311 tcg_gen_andi_i32(var, var, (1u << width) - 1);
312 tcg_gen_xori_i32(var, var, signbit);
313 tcg_gen_subi_i32(var, var, signbit);
317 /* Return (b << 32) + a. Mark inputs as dead */
318 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
320 TCGv_i64 tmp64 = tcg_temp_new_i64();
322 tcg_gen_extu_i32_i64(tmp64, b);
323 tcg_temp_free_i32(b);
324 tcg_gen_shli_i64(tmp64, tmp64, 32);
325 tcg_gen_add_i64(a, tmp64, a);
327 tcg_temp_free_i64(tmp64);
328 return a;
331 /* Return (b << 32) - a. Mark inputs as dead. */
332 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
334 TCGv_i64 tmp64 = tcg_temp_new_i64();
336 tcg_gen_extu_i32_i64(tmp64, b);
337 tcg_temp_free_i32(b);
338 tcg_gen_shli_i64(tmp64, tmp64, 32);
339 tcg_gen_sub_i64(a, tmp64, a);
341 tcg_temp_free_i64(tmp64);
342 return a;
345 /* 32x32->64 multiply. Marks inputs as dead. */
346 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
348 TCGv_i32 lo = tcg_temp_new_i32();
349 TCGv_i32 hi = tcg_temp_new_i32();
350 TCGv_i64 ret;
352 tcg_gen_mulu2_i32(lo, hi, a, b);
353 tcg_temp_free_i32(a);
354 tcg_temp_free_i32(b);
356 ret = tcg_temp_new_i64();
357 tcg_gen_concat_i32_i64(ret, lo, hi);
358 tcg_temp_free_i32(lo);
359 tcg_temp_free_i32(hi);
361 return ret;
364 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
366 TCGv_i32 lo = tcg_temp_new_i32();
367 TCGv_i32 hi = tcg_temp_new_i32();
368 TCGv_i64 ret;
370 tcg_gen_muls2_i32(lo, hi, a, b);
371 tcg_temp_free_i32(a);
372 tcg_temp_free_i32(b);
374 ret = tcg_temp_new_i64();
375 tcg_gen_concat_i32_i64(ret, lo, hi);
376 tcg_temp_free_i32(lo);
377 tcg_temp_free_i32(hi);
379 return ret;
382 /* Swap low and high halfwords. */
383 static void gen_swap_half(TCGv_i32 var)
385 TCGv_i32 tmp = tcg_temp_new_i32();
386 tcg_gen_shri_i32(tmp, var, 16);
387 tcg_gen_shli_i32(var, var, 16);
388 tcg_gen_or_i32(var, var, tmp);
389 tcg_temp_free_i32(tmp);
392 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
393 tmp = (t0 ^ t1) & 0x8000;
394 t0 &= ~0x8000;
395 t1 &= ~0x8000;
396 t0 = (t0 + t1) ^ tmp;
399 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
401 TCGv_i32 tmp = tcg_temp_new_i32();
402 tcg_gen_xor_i32(tmp, t0, t1);
403 tcg_gen_andi_i32(tmp, tmp, 0x8000);
404 tcg_gen_andi_i32(t0, t0, ~0x8000);
405 tcg_gen_andi_i32(t1, t1, ~0x8000);
406 tcg_gen_add_i32(t0, t0, t1);
407 tcg_gen_xor_i32(t0, t0, tmp);
408 tcg_temp_free_i32(tmp);
409 tcg_temp_free_i32(t1);
412 /* Set CF to the top bit of var. */
413 static void gen_set_CF_bit31(TCGv_i32 var)
415 tcg_gen_shri_i32(cpu_CF, var, 31);
418 /* Set N and Z flags from var. */
419 static inline void gen_logic_CC(TCGv_i32 var)
421 tcg_gen_mov_i32(cpu_NF, var);
422 tcg_gen_mov_i32(cpu_ZF, var);
425 /* T0 += T1 + CF. */
426 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
428 tcg_gen_add_i32(t0, t0, t1);
429 tcg_gen_add_i32(t0, t0, cpu_CF);
432 /* dest = T0 + T1 + CF. */
433 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
435 tcg_gen_add_i32(dest, t0, t1);
436 tcg_gen_add_i32(dest, dest, cpu_CF);
439 /* dest = T0 - T1 + CF - 1. */
440 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
442 tcg_gen_sub_i32(dest, t0, t1);
443 tcg_gen_add_i32(dest, dest, cpu_CF);
444 tcg_gen_subi_i32(dest, dest, 1);
447 /* dest = T0 + T1. Compute C, N, V and Z flags */
448 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
450 TCGv_i32 tmp = tcg_temp_new_i32();
451 tcg_gen_movi_i32(tmp, 0);
452 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
453 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
454 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
455 tcg_gen_xor_i32(tmp, t0, t1);
456 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
457 tcg_temp_free_i32(tmp);
458 tcg_gen_mov_i32(dest, cpu_NF);
461 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
462 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
464 TCGv_i32 tmp = tcg_temp_new_i32();
465 if (TCG_TARGET_HAS_add2_i32) {
466 tcg_gen_movi_i32(tmp, 0);
467 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
468 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
469 } else {
470 TCGv_i64 q0 = tcg_temp_new_i64();
471 TCGv_i64 q1 = tcg_temp_new_i64();
472 tcg_gen_extu_i32_i64(q0, t0);
473 tcg_gen_extu_i32_i64(q1, t1);
474 tcg_gen_add_i64(q0, q0, q1);
475 tcg_gen_extu_i32_i64(q1, cpu_CF);
476 tcg_gen_add_i64(q0, q0, q1);
477 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
478 tcg_temp_free_i64(q0);
479 tcg_temp_free_i64(q1);
481 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
482 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
483 tcg_gen_xor_i32(tmp, t0, t1);
484 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
485 tcg_temp_free_i32(tmp);
486 tcg_gen_mov_i32(dest, cpu_NF);
489 /* dest = T0 - T1. Compute C, N, V and Z flags */
490 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
492 TCGv_i32 tmp;
493 tcg_gen_sub_i32(cpu_NF, t0, t1);
494 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
495 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
496 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
497 tmp = tcg_temp_new_i32();
498 tcg_gen_xor_i32(tmp, t0, t1);
499 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
500 tcg_temp_free_i32(tmp);
501 tcg_gen_mov_i32(dest, cpu_NF);
504 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
505 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
507 TCGv_i32 tmp = tcg_temp_new_i32();
508 tcg_gen_not_i32(tmp, t1);
509 gen_adc_CC(dest, t0, tmp);
510 tcg_temp_free_i32(tmp);
513 #define GEN_SHIFT(name) \
514 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
516 TCGv_i32 tmp1, tmp2, tmp3; \
517 tmp1 = tcg_temp_new_i32(); \
518 tcg_gen_andi_i32(tmp1, t1, 0xff); \
519 tmp2 = tcg_const_i32(0); \
520 tmp3 = tcg_const_i32(0x1f); \
521 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
522 tcg_temp_free_i32(tmp3); \
523 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
524 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
525 tcg_temp_free_i32(tmp2); \
526 tcg_temp_free_i32(tmp1); \
528 GEN_SHIFT(shl)
529 GEN_SHIFT(shr)
530 #undef GEN_SHIFT
532 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
534 TCGv_i32 tmp1, tmp2;
535 tmp1 = tcg_temp_new_i32();
536 tcg_gen_andi_i32(tmp1, t1, 0xff);
537 tmp2 = tcg_const_i32(0x1f);
538 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
539 tcg_temp_free_i32(tmp2);
540 tcg_gen_sar_i32(dest, t0, tmp1);
541 tcg_temp_free_i32(tmp1);
544 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
546 TCGv_i32 c0 = tcg_const_i32(0);
547 TCGv_i32 tmp = tcg_temp_new_i32();
548 tcg_gen_neg_i32(tmp, src);
549 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
550 tcg_temp_free_i32(c0);
551 tcg_temp_free_i32(tmp);
554 static void shifter_out_im(TCGv_i32 var, int shift)
556 if (shift == 0) {
557 tcg_gen_andi_i32(cpu_CF, var, 1);
558 } else {
559 tcg_gen_shri_i32(cpu_CF, var, shift);
560 if (shift != 31) {
561 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
566 /* Shift by immediate. Includes special handling for shift == 0. */
567 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
568 int shift, int flags)
570 switch (shiftop) {
571 case 0: /* LSL */
572 if (shift != 0) {
573 if (flags)
574 shifter_out_im(var, 32 - shift);
575 tcg_gen_shli_i32(var, var, shift);
577 break;
578 case 1: /* LSR */
579 if (shift == 0) {
580 if (flags) {
581 tcg_gen_shri_i32(cpu_CF, var, 31);
583 tcg_gen_movi_i32(var, 0);
584 } else {
585 if (flags)
586 shifter_out_im(var, shift - 1);
587 tcg_gen_shri_i32(var, var, shift);
589 break;
590 case 2: /* ASR */
591 if (shift == 0)
592 shift = 32;
593 if (flags)
594 shifter_out_im(var, shift - 1);
595 if (shift == 32)
596 shift = 31;
597 tcg_gen_sari_i32(var, var, shift);
598 break;
599 case 3: /* ROR/RRX */
600 if (shift != 0) {
601 if (flags)
602 shifter_out_im(var, shift - 1);
603 tcg_gen_rotri_i32(var, var, shift); break;
604 } else {
605 TCGv_i32 tmp = tcg_temp_new_i32();
606 tcg_gen_shli_i32(tmp, cpu_CF, 31);
607 if (flags)
608 shifter_out_im(var, 0);
609 tcg_gen_shri_i32(var, var, 1);
610 tcg_gen_or_i32(var, var, tmp);
611 tcg_temp_free_i32(tmp);
616 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
617 TCGv_i32 shift, int flags)
619 if (flags) {
620 switch (shiftop) {
621 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
622 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
623 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
624 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
626 } else {
627 switch (shiftop) {
628 case 0:
629 gen_shl(var, var, shift);
630 break;
631 case 1:
632 gen_shr(var, var, shift);
633 break;
634 case 2:
635 gen_sar(var, var, shift);
636 break;
637 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
638 tcg_gen_rotr_i32(var, var, shift); break;
641 tcg_temp_free_i32(shift);
644 #define PAS_OP(pfx) \
645 switch (op2) { \
646 case 0: gen_pas_helper(glue(pfx,add16)); break; \
647 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
648 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
649 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
650 case 4: gen_pas_helper(glue(pfx,add8)); break; \
651 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
653 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
655 TCGv_ptr tmp;
657 switch (op1) {
658 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
659 case 1:
660 tmp = tcg_temp_new_ptr();
661 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
662 PAS_OP(s)
663 tcg_temp_free_ptr(tmp);
664 break;
665 case 5:
666 tmp = tcg_temp_new_ptr();
667 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
668 PAS_OP(u)
669 tcg_temp_free_ptr(tmp);
670 break;
671 #undef gen_pas_helper
672 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
673 case 2:
674 PAS_OP(q);
675 break;
676 case 3:
677 PAS_OP(sh);
678 break;
679 case 6:
680 PAS_OP(uq);
681 break;
682 case 7:
683 PAS_OP(uh);
684 break;
685 #undef gen_pas_helper
688 #undef PAS_OP
690 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
691 #define PAS_OP(pfx) \
692 switch (op1) { \
693 case 0: gen_pas_helper(glue(pfx,add8)); break; \
694 case 1: gen_pas_helper(glue(pfx,add16)); break; \
695 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
696 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
697 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
698 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
700 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
702 TCGv_ptr tmp;
704 switch (op2) {
705 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
706 case 0:
707 tmp = tcg_temp_new_ptr();
708 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
709 PAS_OP(s)
710 tcg_temp_free_ptr(tmp);
711 break;
712 case 4:
713 tmp = tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
715 PAS_OP(u)
716 tcg_temp_free_ptr(tmp);
717 break;
718 #undef gen_pas_helper
719 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
720 case 1:
721 PAS_OP(q);
722 break;
723 case 2:
724 PAS_OP(sh);
725 break;
726 case 5:
727 PAS_OP(uq);
728 break;
729 case 6:
730 PAS_OP(uh);
731 break;
732 #undef gen_pas_helper
735 #undef PAS_OP
738 * Generate a conditional based on ARM condition code cc.
739 * This is common between ARM and Aarch64 targets.
741 void arm_test_cc(DisasCompare *cmp, int cc)
743 TCGv_i32 value;
744 TCGCond cond;
745 bool global = true;
747 switch (cc) {
748 case 0: /* eq: Z */
749 case 1: /* ne: !Z */
750 cond = TCG_COND_EQ;
751 value = cpu_ZF;
752 break;
754 case 2: /* cs: C */
755 case 3: /* cc: !C */
756 cond = TCG_COND_NE;
757 value = cpu_CF;
758 break;
760 case 4: /* mi: N */
761 case 5: /* pl: !N */
762 cond = TCG_COND_LT;
763 value = cpu_NF;
764 break;
766 case 6: /* vs: V */
767 case 7: /* vc: !V */
768 cond = TCG_COND_LT;
769 value = cpu_VF;
770 break;
772 case 8: /* hi: C && !Z */
773 case 9: /* ls: !C || Z -> !(C && !Z) */
774 cond = TCG_COND_NE;
775 value = tcg_temp_new_i32();
776 global = false;
777 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
778 ZF is non-zero for !Z; so AND the two subexpressions. */
779 tcg_gen_neg_i32(value, cpu_CF);
780 tcg_gen_and_i32(value, value, cpu_ZF);
781 break;
783 case 10: /* ge: N == V -> N ^ V == 0 */
784 case 11: /* lt: N != V -> N ^ V != 0 */
785 /* Since we're only interested in the sign bit, == 0 is >= 0. */
786 cond = TCG_COND_GE;
787 value = tcg_temp_new_i32();
788 global = false;
789 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
790 break;
792 case 12: /* gt: !Z && N == V */
793 case 13: /* le: Z || N != V */
794 cond = TCG_COND_NE;
795 value = tcg_temp_new_i32();
796 global = false;
797 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
798 * the sign bit then AND with ZF to yield the result. */
799 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
800 tcg_gen_sari_i32(value, value, 31);
801 tcg_gen_andc_i32(value, cpu_ZF, value);
802 break;
804 case 14: /* always */
805 case 15: /* always */
806 /* Use the ALWAYS condition, which will fold early.
807 * It doesn't matter what we use for the value. */
808 cond = TCG_COND_ALWAYS;
809 value = cpu_ZF;
810 goto no_invert;
812 default:
813 fprintf(stderr, "Bad condition code 0x%x\n", cc);
814 abort();
817 if (cc & 1) {
818 cond = tcg_invert_cond(cond);
821 no_invert:
822 cmp->cond = cond;
823 cmp->value = value;
824 cmp->value_global = global;
827 void arm_free_cc(DisasCompare *cmp)
829 if (!cmp->value_global) {
830 tcg_temp_free_i32(cmp->value);
834 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
836 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
839 void arm_gen_test_cc(int cc, TCGLabel *label)
841 DisasCompare cmp;
842 arm_test_cc(&cmp, cc);
843 arm_jump_cc(&cmp, label);
844 arm_free_cc(&cmp);
847 static const uint8_t table_logic_cc[16] = {
848 1, /* and */
849 1, /* xor */
850 0, /* sub */
851 0, /* rsb */
852 0, /* add */
853 0, /* adc */
854 0, /* sbc */
855 0, /* rsc */
856 1, /* andl */
857 1, /* xorl */
858 0, /* cmp */
859 0, /* cmn */
860 1, /* orr */
861 1, /* mov */
862 1, /* bic */
863 1, /* mvn */
866 /* Set PC and Thumb state from an immediate address. */
867 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
869 TCGv_i32 tmp;
871 s->is_jmp = DISAS_JUMP;
872 if (s->thumb != (addr & 1)) {
873 tmp = tcg_temp_new_i32();
874 tcg_gen_movi_i32(tmp, addr & 1);
875 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
876 tcg_temp_free_i32(tmp);
878 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
881 /* Set PC and Thumb state from var. var is marked as dead. */
882 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
884 s->is_jmp = DISAS_JUMP;
885 tcg_gen_andi_i32(cpu_R[15], var, ~1);
886 tcg_gen_andi_i32(var, var, 1);
887 store_cpu_field(var, thumb);
890 /* Variant of store_reg which uses branch&exchange logic when storing
891 to r15 in ARM architecture v7 and above. The source must be a temporary
892 and will be marked as dead. */
893 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
895 if (reg == 15 && ENABLE_ARCH_7) {
896 gen_bx(s, var);
897 } else {
898 store_reg(s, reg, var);
902 /* Variant of store_reg which uses branch&exchange logic when storing
903 * to r15 in ARM architecture v5T and above. This is used for storing
904 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
905 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
906 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
908 if (reg == 15 && ENABLE_ARCH_5) {
909 gen_bx(s, var);
910 } else {
911 store_reg(s, reg, var);
915 #ifdef CONFIG_USER_ONLY
916 #define IS_USER_ONLY 1
917 #else
918 #define IS_USER_ONLY 0
919 #endif
921 /* Abstractions of "generate code to do a guest load/store for
922 * AArch32", where a vaddr is always 32 bits (and is zero
923 * extended if we're a 64 bit core) and data is also
924 * 32 bits unless specifically doing a 64 bit access.
925 * These functions work like tcg_gen_qemu_{ld,st}* except
926 * that the address argument is TCGv_i32 rather than TCGv.
928 #if TARGET_LONG_BITS == 32
930 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
931 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
932 TCGv_i32 addr, int index) \
934 TCGMemOp opc = (OPC) | s->be_data; \
935 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
936 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
937 TCGv addr_be = tcg_temp_new(); \
938 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
939 tcg_gen_qemu_ld_i32(val, addr_be, index, opc); \
940 tcg_temp_free(addr_be); \
941 return; \
943 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
946 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
947 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
948 TCGv_i32 addr, int index) \
950 TCGMemOp opc = (OPC) | s->be_data; \
951 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
952 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
953 TCGv addr_be = tcg_temp_new(); \
954 tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \
955 tcg_gen_qemu_st_i32(val, addr_be, index, opc); \
956 tcg_temp_free(addr_be); \
957 return; \
959 tcg_gen_qemu_st_i32(val, addr, index, opc); \
962 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
963 TCGv_i32 addr, int index)
965 TCGMemOp opc = MO_Q | s->be_data;
966 tcg_gen_qemu_ld_i64(val, addr, index, opc);
967 /* Not needed for user-mode BE32, where we use MO_BE instead. */
968 if (!IS_USER_ONLY && s->sctlr_b) {
969 tcg_gen_rotri_i64(val, val, 32);
973 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
974 TCGv_i32 addr, int index)
976 TCGMemOp opc = MO_Q | s->be_data;
977 /* Not needed for user-mode BE32, where we use MO_BE instead. */
978 if (!IS_USER_ONLY && s->sctlr_b) {
979 TCGv_i64 tmp = tcg_temp_new_i64();
980 tcg_gen_rotri_i64(tmp, val, 32);
981 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
982 tcg_temp_free_i64(tmp);
983 return;
985 tcg_gen_qemu_st_i64(val, addr, index, opc);
988 #else
990 #define DO_GEN_LD(SUFF, OPC, BE32_XOR) \
991 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
992 TCGv_i32 addr, int index) \
994 TCGMemOp opc = (OPC) | s->be_data; \
995 TCGv addr64 = tcg_temp_new(); \
996 tcg_gen_extu_i32_i64(addr64, addr); \
997 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
998 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
999 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1001 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
1002 tcg_temp_free(addr64); \
1005 #define DO_GEN_ST(SUFF, OPC, BE32_XOR) \
1006 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1007 TCGv_i32 addr, int index) \
1009 TCGMemOp opc = (OPC) | s->be_data; \
1010 TCGv addr64 = tcg_temp_new(); \
1011 tcg_gen_extu_i32_i64(addr64, addr); \
1012 /* Not needed for user-mode BE32, where we use MO_BE instead. */ \
1013 if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \
1014 tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \
1016 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
1017 tcg_temp_free(addr64); \
1020 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1021 TCGv_i32 addr, int index)
1023 TCGMemOp opc = MO_Q | s->be_data;
1024 TCGv addr64 = tcg_temp_new();
1025 tcg_gen_extu_i32_i64(addr64, addr);
1026 tcg_gen_qemu_ld_i64(val, addr64, index, opc);
1028 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1029 if (!IS_USER_ONLY && s->sctlr_b) {
1030 tcg_gen_rotri_i64(val, val, 32);
1032 tcg_temp_free(addr64);
1035 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1036 TCGv_i32 addr, int index)
1038 TCGMemOp opc = MO_Q | s->be_data;
1039 TCGv addr64 = tcg_temp_new();
1040 tcg_gen_extu_i32_i64(addr64, addr);
1042 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1043 if (!IS_USER_ONLY && s->sctlr_b) {
1044 TCGv tmp = tcg_temp_new();
1045 tcg_gen_rotri_i64(tmp, val, 32);
1046 tcg_gen_qemu_st_i64(tmp, addr64, index, opc);
1047 tcg_temp_free(tmp);
1048 } else {
1049 tcg_gen_qemu_st_i64(val, addr64, index, opc);
1051 tcg_temp_free(addr64);
1054 #endif
1056 DO_GEN_LD(8s, MO_SB, 3)
1057 DO_GEN_LD(8u, MO_UB, 3)
1058 DO_GEN_LD(16s, MO_SW, 2)
1059 DO_GEN_LD(16u, MO_UW, 2)
1060 DO_GEN_LD(32u, MO_UL, 0)
1061 /* 'a' variants include an alignment check */
1062 DO_GEN_LD(16ua, MO_UW | MO_ALIGN, 2)
1063 DO_GEN_LD(32ua, MO_UL | MO_ALIGN, 0)
1064 DO_GEN_ST(8, MO_UB, 3)
1065 DO_GEN_ST(16, MO_UW, 2)
1066 DO_GEN_ST(32, MO_UL, 0)
1068 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
1070 tcg_gen_movi_i32(cpu_R[15], val);
1073 static inline void gen_hvc(DisasContext *s, int imm16)
1075 /* The pre HVC helper handles cases when HVC gets trapped
1076 * as an undefined insn by runtime configuration (ie before
1077 * the insn really executes).
1079 gen_set_pc_im(s, s->pc - 4);
1080 gen_helper_pre_hvc(cpu_env);
1081 /* Otherwise we will treat this as a real exception which
1082 * happens after execution of the insn. (The distinction matters
1083 * for the PC value reported to the exception handler and also
1084 * for single stepping.)
1086 s->svc_imm = imm16;
1087 gen_set_pc_im(s, s->pc);
1088 s->is_jmp = DISAS_HVC;
1091 static inline void gen_smc(DisasContext *s)
1093 /* As with HVC, we may take an exception either before or after
1094 * the insn executes.
1096 TCGv_i32 tmp;
1098 gen_set_pc_im(s, s->pc - 4);
1099 tmp = tcg_const_i32(syn_aa32_smc());
1100 gen_helper_pre_smc(cpu_env, tmp);
1101 tcg_temp_free_i32(tmp);
1102 gen_set_pc_im(s, s->pc);
1103 s->is_jmp = DISAS_SMC;
1106 static inline void
1107 gen_set_condexec (DisasContext *s)
1109 if (s->condexec_mask) {
1110 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1111 TCGv_i32 tmp = tcg_temp_new_i32();
1112 tcg_gen_movi_i32(tmp, val);
1113 store_cpu_field(tmp, condexec_bits);
1117 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1119 gen_set_condexec(s);
1120 gen_set_pc_im(s, s->pc - offset);
1121 gen_exception_internal(excp);
1122 s->is_jmp = DISAS_JUMP;
1125 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1126 int syn, uint32_t target_el)
1128 gen_set_condexec(s);
1129 gen_set_pc_im(s, s->pc - offset);
1130 gen_exception(excp, syn, target_el);
1131 s->is_jmp = DISAS_JUMP;
1134 /* Force a TB lookup after an instruction that changes the CPU state. */
1135 static inline void gen_lookup_tb(DisasContext *s)
1137 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1138 s->is_jmp = DISAS_JUMP;
1141 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1142 TCGv_i32 var)
1144 int val, rm, shift, shiftop;
1145 TCGv_i32 offset;
1147 if (!(insn & (1 << 25))) {
1148 /* immediate */
1149 val = insn & 0xfff;
1150 if (!(insn & (1 << 23)))
1151 val = -val;
1152 if (val != 0)
1153 tcg_gen_addi_i32(var, var, val);
1154 } else {
1155 /* shift/register */
1156 rm = (insn) & 0xf;
1157 shift = (insn >> 7) & 0x1f;
1158 shiftop = (insn >> 5) & 3;
1159 offset = load_reg(s, rm);
1160 gen_arm_shift_im(offset, shiftop, shift, 0);
1161 if (!(insn & (1 << 23)))
1162 tcg_gen_sub_i32(var, var, offset);
1163 else
1164 tcg_gen_add_i32(var, var, offset);
1165 tcg_temp_free_i32(offset);
1169 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1170 int extra, TCGv_i32 var)
1172 int val, rm;
1173 TCGv_i32 offset;
1175 if (insn & (1 << 22)) {
1176 /* immediate */
1177 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1178 if (!(insn & (1 << 23)))
1179 val = -val;
1180 val += extra;
1181 if (val != 0)
1182 tcg_gen_addi_i32(var, var, val);
1183 } else {
1184 /* register */
1185 if (extra)
1186 tcg_gen_addi_i32(var, var, extra);
1187 rm = (insn) & 0xf;
1188 offset = load_reg(s, rm);
1189 if (!(insn & (1 << 23)))
1190 tcg_gen_sub_i32(var, var, offset);
1191 else
1192 tcg_gen_add_i32(var, var, offset);
1193 tcg_temp_free_i32(offset);
1197 static TCGv_ptr get_fpstatus_ptr(int neon)
1199 TCGv_ptr statusptr = tcg_temp_new_ptr();
1200 int offset;
1201 if (neon) {
1202 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1203 } else {
1204 offset = offsetof(CPUARMState, vfp.fp_status);
1206 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1207 return statusptr;
1210 #define VFP_OP2(name) \
1211 static inline void gen_vfp_##name(int dp) \
1213 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1214 if (dp) { \
1215 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1216 } else { \
1217 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1219 tcg_temp_free_ptr(fpst); \
1222 VFP_OP2(add)
1223 VFP_OP2(sub)
1224 VFP_OP2(mul)
1225 VFP_OP2(div)
1227 #undef VFP_OP2
1229 static inline void gen_vfp_F1_mul(int dp)
1231 /* Like gen_vfp_mul() but put result in F1 */
1232 TCGv_ptr fpst = get_fpstatus_ptr(0);
1233 if (dp) {
1234 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1235 } else {
1236 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1238 tcg_temp_free_ptr(fpst);
1241 static inline void gen_vfp_F1_neg(int dp)
1243 /* Like gen_vfp_neg() but put result in F1 */
1244 if (dp) {
1245 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1246 } else {
1247 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1251 static inline void gen_vfp_abs(int dp)
1253 if (dp)
1254 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1255 else
1256 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1259 static inline void gen_vfp_neg(int dp)
1261 if (dp)
1262 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1263 else
1264 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1267 static inline void gen_vfp_sqrt(int dp)
1269 if (dp)
1270 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1271 else
1272 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1275 static inline void gen_vfp_cmp(int dp)
1277 if (dp)
1278 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1279 else
1280 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1283 static inline void gen_vfp_cmpe(int dp)
1285 if (dp)
1286 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1287 else
1288 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1291 static inline void gen_vfp_F1_ld0(int dp)
1293 if (dp)
1294 tcg_gen_movi_i64(cpu_F1d, 0);
1295 else
1296 tcg_gen_movi_i32(cpu_F1s, 0);
1299 #define VFP_GEN_ITOF(name) \
1300 static inline void gen_vfp_##name(int dp, int neon) \
1302 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1303 if (dp) { \
1304 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1305 } else { \
1306 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1308 tcg_temp_free_ptr(statusptr); \
1311 VFP_GEN_ITOF(uito)
1312 VFP_GEN_ITOF(sito)
1313 #undef VFP_GEN_ITOF
1315 #define VFP_GEN_FTOI(name) \
1316 static inline void gen_vfp_##name(int dp, int neon) \
1318 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1319 if (dp) { \
1320 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1321 } else { \
1322 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1324 tcg_temp_free_ptr(statusptr); \
1327 VFP_GEN_FTOI(toui)
1328 VFP_GEN_FTOI(touiz)
1329 VFP_GEN_FTOI(tosi)
1330 VFP_GEN_FTOI(tosiz)
1331 #undef VFP_GEN_FTOI
1333 #define VFP_GEN_FIX(name, round) \
1334 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1336 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1337 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1338 if (dp) { \
1339 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1340 statusptr); \
1341 } else { \
1342 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1343 statusptr); \
1345 tcg_temp_free_i32(tmp_shift); \
1346 tcg_temp_free_ptr(statusptr); \
1348 VFP_GEN_FIX(tosh, _round_to_zero)
1349 VFP_GEN_FIX(tosl, _round_to_zero)
1350 VFP_GEN_FIX(touh, _round_to_zero)
1351 VFP_GEN_FIX(toul, _round_to_zero)
1352 VFP_GEN_FIX(shto, )
1353 VFP_GEN_FIX(slto, )
1354 VFP_GEN_FIX(uhto, )
1355 VFP_GEN_FIX(ulto, )
1356 #undef VFP_GEN_FIX
1358 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1360 if (dp) {
1361 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1362 } else {
1363 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1367 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1369 if (dp) {
1370 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1371 } else {
1372 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1376 static inline long
1377 vfp_reg_offset (int dp, int reg)
1379 if (dp)
1380 return offsetof(CPUARMState, vfp.regs[reg]);
1381 else if (reg & 1) {
1382 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1383 + offsetof(CPU_DoubleU, l.upper);
1384 } else {
1385 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1386 + offsetof(CPU_DoubleU, l.lower);
1390 /* Return the offset of a 32-bit piece of a NEON register.
1391 zero is the least significant end of the register. */
1392 static inline long
1393 neon_reg_offset (int reg, int n)
1395 int sreg;
1396 sreg = reg * 2 + n;
1397 return vfp_reg_offset(0, sreg);
1400 static TCGv_i32 neon_load_reg(int reg, int pass)
1402 TCGv_i32 tmp = tcg_temp_new_i32();
1403 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1404 return tmp;
1407 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1409 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1410 tcg_temp_free_i32(var);
1413 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1415 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1418 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1420 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1423 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1424 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1425 #define tcg_gen_st_f32 tcg_gen_st_i32
1426 #define tcg_gen_st_f64 tcg_gen_st_i64
1428 static inline void gen_mov_F0_vreg(int dp, int reg)
1430 if (dp)
1431 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1432 else
1433 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1436 static inline void gen_mov_F1_vreg(int dp, int reg)
1438 if (dp)
1439 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1440 else
1441 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1444 static inline void gen_mov_vreg_F0(int dp, int reg)
1446 if (dp)
1447 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1448 else
1449 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1452 #define ARM_CP_RW_BIT (1 << 20)
1454 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1456 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1459 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1461 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1464 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1466 TCGv_i32 var = tcg_temp_new_i32();
1467 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1468 return var;
1471 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1473 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1474 tcg_temp_free_i32(var);
1477 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1479 iwmmxt_store_reg(cpu_M0, rn);
1482 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1484 iwmmxt_load_reg(cpu_M0, rn);
1487 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1489 iwmmxt_load_reg(cpu_V1, rn);
1490 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1493 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1495 iwmmxt_load_reg(cpu_V1, rn);
1496 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1499 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1501 iwmmxt_load_reg(cpu_V1, rn);
1502 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1505 #define IWMMXT_OP(name) \
1506 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1508 iwmmxt_load_reg(cpu_V1, rn); \
1509 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1512 #define IWMMXT_OP_ENV(name) \
1513 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1515 iwmmxt_load_reg(cpu_V1, rn); \
1516 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1519 #define IWMMXT_OP_ENV_SIZE(name) \
1520 IWMMXT_OP_ENV(name##b) \
1521 IWMMXT_OP_ENV(name##w) \
1522 IWMMXT_OP_ENV(name##l)
1524 #define IWMMXT_OP_ENV1(name) \
1525 static inline void gen_op_iwmmxt_##name##_M0(void) \
1527 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1530 IWMMXT_OP(maddsq)
1531 IWMMXT_OP(madduq)
1532 IWMMXT_OP(sadb)
1533 IWMMXT_OP(sadw)
1534 IWMMXT_OP(mulslw)
1535 IWMMXT_OP(mulshw)
1536 IWMMXT_OP(mululw)
1537 IWMMXT_OP(muluhw)
1538 IWMMXT_OP(macsw)
1539 IWMMXT_OP(macuw)
1541 IWMMXT_OP_ENV_SIZE(unpackl)
1542 IWMMXT_OP_ENV_SIZE(unpackh)
1544 IWMMXT_OP_ENV1(unpacklub)
1545 IWMMXT_OP_ENV1(unpackluw)
1546 IWMMXT_OP_ENV1(unpacklul)
1547 IWMMXT_OP_ENV1(unpackhub)
1548 IWMMXT_OP_ENV1(unpackhuw)
1549 IWMMXT_OP_ENV1(unpackhul)
1550 IWMMXT_OP_ENV1(unpacklsb)
1551 IWMMXT_OP_ENV1(unpacklsw)
1552 IWMMXT_OP_ENV1(unpacklsl)
1553 IWMMXT_OP_ENV1(unpackhsb)
1554 IWMMXT_OP_ENV1(unpackhsw)
1555 IWMMXT_OP_ENV1(unpackhsl)
1557 IWMMXT_OP_ENV_SIZE(cmpeq)
1558 IWMMXT_OP_ENV_SIZE(cmpgtu)
1559 IWMMXT_OP_ENV_SIZE(cmpgts)
1561 IWMMXT_OP_ENV_SIZE(mins)
1562 IWMMXT_OP_ENV_SIZE(minu)
1563 IWMMXT_OP_ENV_SIZE(maxs)
1564 IWMMXT_OP_ENV_SIZE(maxu)
1566 IWMMXT_OP_ENV_SIZE(subn)
1567 IWMMXT_OP_ENV_SIZE(addn)
1568 IWMMXT_OP_ENV_SIZE(subu)
1569 IWMMXT_OP_ENV_SIZE(addu)
1570 IWMMXT_OP_ENV_SIZE(subs)
1571 IWMMXT_OP_ENV_SIZE(adds)
1573 IWMMXT_OP_ENV(avgb0)
1574 IWMMXT_OP_ENV(avgb1)
1575 IWMMXT_OP_ENV(avgw0)
1576 IWMMXT_OP_ENV(avgw1)
1578 IWMMXT_OP_ENV(packuw)
1579 IWMMXT_OP_ENV(packul)
1580 IWMMXT_OP_ENV(packuq)
1581 IWMMXT_OP_ENV(packsw)
1582 IWMMXT_OP_ENV(packsl)
1583 IWMMXT_OP_ENV(packsq)
1585 static void gen_op_iwmmxt_set_mup(void)
1587 TCGv_i32 tmp;
1588 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1589 tcg_gen_ori_i32(tmp, tmp, 2);
1590 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1593 static void gen_op_iwmmxt_set_cup(void)
1595 TCGv_i32 tmp;
1596 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1597 tcg_gen_ori_i32(tmp, tmp, 1);
1598 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1601 static void gen_op_iwmmxt_setpsr_nz(void)
1603 TCGv_i32 tmp = tcg_temp_new_i32();
1604 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1605 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1608 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1610 iwmmxt_load_reg(cpu_V1, rn);
1611 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1612 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1615 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1616 TCGv_i32 dest)
1618 int rd;
1619 uint32_t offset;
1620 TCGv_i32 tmp;
1622 rd = (insn >> 16) & 0xf;
1623 tmp = load_reg(s, rd);
1625 offset = (insn & 0xff) << ((insn >> 7) & 2);
1626 if (insn & (1 << 24)) {
1627 /* Pre indexed */
1628 if (insn & (1 << 23))
1629 tcg_gen_addi_i32(tmp, tmp, offset);
1630 else
1631 tcg_gen_addi_i32(tmp, tmp, -offset);
1632 tcg_gen_mov_i32(dest, tmp);
1633 if (insn & (1 << 21))
1634 store_reg(s, rd, tmp);
1635 else
1636 tcg_temp_free_i32(tmp);
1637 } else if (insn & (1 << 21)) {
1638 /* Post indexed */
1639 tcg_gen_mov_i32(dest, tmp);
1640 if (insn & (1 << 23))
1641 tcg_gen_addi_i32(tmp, tmp, offset);
1642 else
1643 tcg_gen_addi_i32(tmp, tmp, -offset);
1644 store_reg(s, rd, tmp);
1645 } else if (!(insn & (1 << 23)))
1646 return 1;
1647 return 0;
1650 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1652 int rd = (insn >> 0) & 0xf;
1653 TCGv_i32 tmp;
1655 if (insn & (1 << 8)) {
1656 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1657 return 1;
1658 } else {
1659 tmp = iwmmxt_load_creg(rd);
1661 } else {
1662 tmp = tcg_temp_new_i32();
1663 iwmmxt_load_reg(cpu_V0, rd);
1664 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1666 tcg_gen_andi_i32(tmp, tmp, mask);
1667 tcg_gen_mov_i32(dest, tmp);
1668 tcg_temp_free_i32(tmp);
1669 return 0;
1672 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1673 (ie. an undefined instruction). */
1674 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1676 int rd, wrd;
1677 int rdhi, rdlo, rd0, rd1, i;
1678 TCGv_i32 addr;
1679 TCGv_i32 tmp, tmp2, tmp3;
1681 if ((insn & 0x0e000e00) == 0x0c000000) {
1682 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1683 wrd = insn & 0xf;
1684 rdlo = (insn >> 12) & 0xf;
1685 rdhi = (insn >> 16) & 0xf;
1686 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1687 iwmmxt_load_reg(cpu_V0, wrd);
1688 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1689 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1690 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1691 } else { /* TMCRR */
1692 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1693 iwmmxt_store_reg(cpu_V0, wrd);
1694 gen_op_iwmmxt_set_mup();
1696 return 0;
1699 wrd = (insn >> 12) & 0xf;
1700 addr = tcg_temp_new_i32();
1701 if (gen_iwmmxt_address(s, insn, addr)) {
1702 tcg_temp_free_i32(addr);
1703 return 1;
1705 if (insn & ARM_CP_RW_BIT) {
1706 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1707 tmp = tcg_temp_new_i32();
1708 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1709 iwmmxt_store_creg(wrd, tmp);
1710 } else {
1711 i = 1;
1712 if (insn & (1 << 8)) {
1713 if (insn & (1 << 22)) { /* WLDRD */
1714 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1715 i = 0;
1716 } else { /* WLDRW wRd */
1717 tmp = tcg_temp_new_i32();
1718 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1720 } else {
1721 tmp = tcg_temp_new_i32();
1722 if (insn & (1 << 22)) { /* WLDRH */
1723 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1724 } else { /* WLDRB */
1725 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1728 if (i) {
1729 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1730 tcg_temp_free_i32(tmp);
1732 gen_op_iwmmxt_movq_wRn_M0(wrd);
1734 } else {
1735 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1736 tmp = iwmmxt_load_creg(wrd);
1737 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1738 } else {
1739 gen_op_iwmmxt_movq_M0_wRn(wrd);
1740 tmp = tcg_temp_new_i32();
1741 if (insn & (1 << 8)) {
1742 if (insn & (1 << 22)) { /* WSTRD */
1743 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1744 } else { /* WSTRW wRd */
1745 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1746 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1748 } else {
1749 if (insn & (1 << 22)) { /* WSTRH */
1750 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1751 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1752 } else { /* WSTRB */
1753 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1754 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1758 tcg_temp_free_i32(tmp);
1760 tcg_temp_free_i32(addr);
1761 return 0;
1764 if ((insn & 0x0f000000) != 0x0e000000)
1765 return 1;
1767 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1768 case 0x000: /* WOR */
1769 wrd = (insn >> 12) & 0xf;
1770 rd0 = (insn >> 0) & 0xf;
1771 rd1 = (insn >> 16) & 0xf;
1772 gen_op_iwmmxt_movq_M0_wRn(rd0);
1773 gen_op_iwmmxt_orq_M0_wRn(rd1);
1774 gen_op_iwmmxt_setpsr_nz();
1775 gen_op_iwmmxt_movq_wRn_M0(wrd);
1776 gen_op_iwmmxt_set_mup();
1777 gen_op_iwmmxt_set_cup();
1778 break;
1779 case 0x011: /* TMCR */
1780 if (insn & 0xf)
1781 return 1;
1782 rd = (insn >> 12) & 0xf;
1783 wrd = (insn >> 16) & 0xf;
1784 switch (wrd) {
1785 case ARM_IWMMXT_wCID:
1786 case ARM_IWMMXT_wCASF:
1787 break;
1788 case ARM_IWMMXT_wCon:
1789 gen_op_iwmmxt_set_cup();
1790 /* Fall through. */
1791 case ARM_IWMMXT_wCSSF:
1792 tmp = iwmmxt_load_creg(wrd);
1793 tmp2 = load_reg(s, rd);
1794 tcg_gen_andc_i32(tmp, tmp, tmp2);
1795 tcg_temp_free_i32(tmp2);
1796 iwmmxt_store_creg(wrd, tmp);
1797 break;
1798 case ARM_IWMMXT_wCGR0:
1799 case ARM_IWMMXT_wCGR1:
1800 case ARM_IWMMXT_wCGR2:
1801 case ARM_IWMMXT_wCGR3:
1802 gen_op_iwmmxt_set_cup();
1803 tmp = load_reg(s, rd);
1804 iwmmxt_store_creg(wrd, tmp);
1805 break;
1806 default:
1807 return 1;
1809 break;
1810 case 0x100: /* WXOR */
1811 wrd = (insn >> 12) & 0xf;
1812 rd0 = (insn >> 0) & 0xf;
1813 rd1 = (insn >> 16) & 0xf;
1814 gen_op_iwmmxt_movq_M0_wRn(rd0);
1815 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1816 gen_op_iwmmxt_setpsr_nz();
1817 gen_op_iwmmxt_movq_wRn_M0(wrd);
1818 gen_op_iwmmxt_set_mup();
1819 gen_op_iwmmxt_set_cup();
1820 break;
1821 case 0x111: /* TMRC */
1822 if (insn & 0xf)
1823 return 1;
1824 rd = (insn >> 12) & 0xf;
1825 wrd = (insn >> 16) & 0xf;
1826 tmp = iwmmxt_load_creg(wrd);
1827 store_reg(s, rd, tmp);
1828 break;
1829 case 0x300: /* WANDN */
1830 wrd = (insn >> 12) & 0xf;
1831 rd0 = (insn >> 0) & 0xf;
1832 rd1 = (insn >> 16) & 0xf;
1833 gen_op_iwmmxt_movq_M0_wRn(rd0);
1834 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1835 gen_op_iwmmxt_andq_M0_wRn(rd1);
1836 gen_op_iwmmxt_setpsr_nz();
1837 gen_op_iwmmxt_movq_wRn_M0(wrd);
1838 gen_op_iwmmxt_set_mup();
1839 gen_op_iwmmxt_set_cup();
1840 break;
1841 case 0x200: /* WAND */
1842 wrd = (insn >> 12) & 0xf;
1843 rd0 = (insn >> 0) & 0xf;
1844 rd1 = (insn >> 16) & 0xf;
1845 gen_op_iwmmxt_movq_M0_wRn(rd0);
1846 gen_op_iwmmxt_andq_M0_wRn(rd1);
1847 gen_op_iwmmxt_setpsr_nz();
1848 gen_op_iwmmxt_movq_wRn_M0(wrd);
1849 gen_op_iwmmxt_set_mup();
1850 gen_op_iwmmxt_set_cup();
1851 break;
1852 case 0x810: case 0xa10: /* WMADD */
1853 wrd = (insn >> 12) & 0xf;
1854 rd0 = (insn >> 0) & 0xf;
1855 rd1 = (insn >> 16) & 0xf;
1856 gen_op_iwmmxt_movq_M0_wRn(rd0);
1857 if (insn & (1 << 21))
1858 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1859 else
1860 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1861 gen_op_iwmmxt_movq_wRn_M0(wrd);
1862 gen_op_iwmmxt_set_mup();
1863 break;
1864 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1865 wrd = (insn >> 12) & 0xf;
1866 rd0 = (insn >> 16) & 0xf;
1867 rd1 = (insn >> 0) & 0xf;
1868 gen_op_iwmmxt_movq_M0_wRn(rd0);
1869 switch ((insn >> 22) & 3) {
1870 case 0:
1871 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1872 break;
1873 case 1:
1874 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1875 break;
1876 case 2:
1877 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1878 break;
1879 case 3:
1880 return 1;
1882 gen_op_iwmmxt_movq_wRn_M0(wrd);
1883 gen_op_iwmmxt_set_mup();
1884 gen_op_iwmmxt_set_cup();
1885 break;
1886 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1887 wrd = (insn >> 12) & 0xf;
1888 rd0 = (insn >> 16) & 0xf;
1889 rd1 = (insn >> 0) & 0xf;
1890 gen_op_iwmmxt_movq_M0_wRn(rd0);
1891 switch ((insn >> 22) & 3) {
1892 case 0:
1893 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1894 break;
1895 case 1:
1896 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1897 break;
1898 case 2:
1899 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1900 break;
1901 case 3:
1902 return 1;
1904 gen_op_iwmmxt_movq_wRn_M0(wrd);
1905 gen_op_iwmmxt_set_mup();
1906 gen_op_iwmmxt_set_cup();
1907 break;
1908 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1909 wrd = (insn >> 12) & 0xf;
1910 rd0 = (insn >> 16) & 0xf;
1911 rd1 = (insn >> 0) & 0xf;
1912 gen_op_iwmmxt_movq_M0_wRn(rd0);
1913 if (insn & (1 << 22))
1914 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1915 else
1916 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1917 if (!(insn & (1 << 20)))
1918 gen_op_iwmmxt_addl_M0_wRn(wrd);
1919 gen_op_iwmmxt_movq_wRn_M0(wrd);
1920 gen_op_iwmmxt_set_mup();
1921 break;
1922 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1923 wrd = (insn >> 12) & 0xf;
1924 rd0 = (insn >> 16) & 0xf;
1925 rd1 = (insn >> 0) & 0xf;
1926 gen_op_iwmmxt_movq_M0_wRn(rd0);
1927 if (insn & (1 << 21)) {
1928 if (insn & (1 << 20))
1929 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1930 else
1931 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1932 } else {
1933 if (insn & (1 << 20))
1934 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1935 else
1936 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1938 gen_op_iwmmxt_movq_wRn_M0(wrd);
1939 gen_op_iwmmxt_set_mup();
1940 break;
1941 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1942 wrd = (insn >> 12) & 0xf;
1943 rd0 = (insn >> 16) & 0xf;
1944 rd1 = (insn >> 0) & 0xf;
1945 gen_op_iwmmxt_movq_M0_wRn(rd0);
1946 if (insn & (1 << 21))
1947 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1948 else
1949 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1950 if (!(insn & (1 << 20))) {
1951 iwmmxt_load_reg(cpu_V1, wrd);
1952 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1954 gen_op_iwmmxt_movq_wRn_M0(wrd);
1955 gen_op_iwmmxt_set_mup();
1956 break;
1957 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1958 wrd = (insn >> 12) & 0xf;
1959 rd0 = (insn >> 16) & 0xf;
1960 rd1 = (insn >> 0) & 0xf;
1961 gen_op_iwmmxt_movq_M0_wRn(rd0);
1962 switch ((insn >> 22) & 3) {
1963 case 0:
1964 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1965 break;
1966 case 1:
1967 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1968 break;
1969 case 2:
1970 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1971 break;
1972 case 3:
1973 return 1;
1975 gen_op_iwmmxt_movq_wRn_M0(wrd);
1976 gen_op_iwmmxt_set_mup();
1977 gen_op_iwmmxt_set_cup();
1978 break;
1979 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1980 wrd = (insn >> 12) & 0xf;
1981 rd0 = (insn >> 16) & 0xf;
1982 rd1 = (insn >> 0) & 0xf;
1983 gen_op_iwmmxt_movq_M0_wRn(rd0);
1984 if (insn & (1 << 22)) {
1985 if (insn & (1 << 20))
1986 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1987 else
1988 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1989 } else {
1990 if (insn & (1 << 20))
1991 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1992 else
1993 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1995 gen_op_iwmmxt_movq_wRn_M0(wrd);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1998 break;
1999 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2000 wrd = (insn >> 12) & 0xf;
2001 rd0 = (insn >> 16) & 0xf;
2002 rd1 = (insn >> 0) & 0xf;
2003 gen_op_iwmmxt_movq_M0_wRn(rd0);
2004 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2005 tcg_gen_andi_i32(tmp, tmp, 7);
2006 iwmmxt_load_reg(cpu_V1, rd1);
2007 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2008 tcg_temp_free_i32(tmp);
2009 gen_op_iwmmxt_movq_wRn_M0(wrd);
2010 gen_op_iwmmxt_set_mup();
2011 break;
2012 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2013 if (((insn >> 6) & 3) == 3)
2014 return 1;
2015 rd = (insn >> 12) & 0xf;
2016 wrd = (insn >> 16) & 0xf;
2017 tmp = load_reg(s, rd);
2018 gen_op_iwmmxt_movq_M0_wRn(wrd);
2019 switch ((insn >> 6) & 3) {
2020 case 0:
2021 tmp2 = tcg_const_i32(0xff);
2022 tmp3 = tcg_const_i32((insn & 7) << 3);
2023 break;
2024 case 1:
2025 tmp2 = tcg_const_i32(0xffff);
2026 tmp3 = tcg_const_i32((insn & 3) << 4);
2027 break;
2028 case 2:
2029 tmp2 = tcg_const_i32(0xffffffff);
2030 tmp3 = tcg_const_i32((insn & 1) << 5);
2031 break;
2032 default:
2033 TCGV_UNUSED_I32(tmp2);
2034 TCGV_UNUSED_I32(tmp3);
2036 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2037 tcg_temp_free_i32(tmp3);
2038 tcg_temp_free_i32(tmp2);
2039 tcg_temp_free_i32(tmp);
2040 gen_op_iwmmxt_movq_wRn_M0(wrd);
2041 gen_op_iwmmxt_set_mup();
2042 break;
2043 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2044 rd = (insn >> 12) & 0xf;
2045 wrd = (insn >> 16) & 0xf;
2046 if (rd == 15 || ((insn >> 22) & 3) == 3)
2047 return 1;
2048 gen_op_iwmmxt_movq_M0_wRn(wrd);
2049 tmp = tcg_temp_new_i32();
2050 switch ((insn >> 22) & 3) {
2051 case 0:
2052 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2053 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2054 if (insn & 8) {
2055 tcg_gen_ext8s_i32(tmp, tmp);
2056 } else {
2057 tcg_gen_andi_i32(tmp, tmp, 0xff);
2059 break;
2060 case 1:
2061 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2062 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2063 if (insn & 8) {
2064 tcg_gen_ext16s_i32(tmp, tmp);
2065 } else {
2066 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2068 break;
2069 case 2:
2070 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2071 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2072 break;
2074 store_reg(s, rd, tmp);
2075 break;
2076 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2077 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2078 return 1;
2079 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2080 switch ((insn >> 22) & 3) {
2081 case 0:
2082 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2083 break;
2084 case 1:
2085 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2086 break;
2087 case 2:
2088 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2089 break;
2091 tcg_gen_shli_i32(tmp, tmp, 28);
2092 gen_set_nzcv(tmp);
2093 tcg_temp_free_i32(tmp);
2094 break;
2095 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2096 if (((insn >> 6) & 3) == 3)
2097 return 1;
2098 rd = (insn >> 12) & 0xf;
2099 wrd = (insn >> 16) & 0xf;
2100 tmp = load_reg(s, rd);
2101 switch ((insn >> 6) & 3) {
2102 case 0:
2103 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2104 break;
2105 case 1:
2106 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2107 break;
2108 case 2:
2109 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2110 break;
2112 tcg_temp_free_i32(tmp);
2113 gen_op_iwmmxt_movq_wRn_M0(wrd);
2114 gen_op_iwmmxt_set_mup();
2115 break;
2116 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2117 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2118 return 1;
2119 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2120 tmp2 = tcg_temp_new_i32();
2121 tcg_gen_mov_i32(tmp2, tmp);
2122 switch ((insn >> 22) & 3) {
2123 case 0:
2124 for (i = 0; i < 7; i ++) {
2125 tcg_gen_shli_i32(tmp2, tmp2, 4);
2126 tcg_gen_and_i32(tmp, tmp, tmp2);
2128 break;
2129 case 1:
2130 for (i = 0; i < 3; i ++) {
2131 tcg_gen_shli_i32(tmp2, tmp2, 8);
2132 tcg_gen_and_i32(tmp, tmp, tmp2);
2134 break;
2135 case 2:
2136 tcg_gen_shli_i32(tmp2, tmp2, 16);
2137 tcg_gen_and_i32(tmp, tmp, tmp2);
2138 break;
2140 gen_set_nzcv(tmp);
2141 tcg_temp_free_i32(tmp2);
2142 tcg_temp_free_i32(tmp);
2143 break;
2144 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2145 wrd = (insn >> 12) & 0xf;
2146 rd0 = (insn >> 16) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0);
2148 switch ((insn >> 22) & 3) {
2149 case 0:
2150 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2151 break;
2152 case 1:
2153 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2154 break;
2155 case 2:
2156 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2157 break;
2158 case 3:
2159 return 1;
2161 gen_op_iwmmxt_movq_wRn_M0(wrd);
2162 gen_op_iwmmxt_set_mup();
2163 break;
2164 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2165 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2166 return 1;
2167 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2168 tmp2 = tcg_temp_new_i32();
2169 tcg_gen_mov_i32(tmp2, tmp);
2170 switch ((insn >> 22) & 3) {
2171 case 0:
2172 for (i = 0; i < 7; i ++) {
2173 tcg_gen_shli_i32(tmp2, tmp2, 4);
2174 tcg_gen_or_i32(tmp, tmp, tmp2);
2176 break;
2177 case 1:
2178 for (i = 0; i < 3; i ++) {
2179 tcg_gen_shli_i32(tmp2, tmp2, 8);
2180 tcg_gen_or_i32(tmp, tmp, tmp2);
2182 break;
2183 case 2:
2184 tcg_gen_shli_i32(tmp2, tmp2, 16);
2185 tcg_gen_or_i32(tmp, tmp, tmp2);
2186 break;
2188 gen_set_nzcv(tmp);
2189 tcg_temp_free_i32(tmp2);
2190 tcg_temp_free_i32(tmp);
2191 break;
2192 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2193 rd = (insn >> 12) & 0xf;
2194 rd0 = (insn >> 16) & 0xf;
2195 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2196 return 1;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0);
2198 tmp = tcg_temp_new_i32();
2199 switch ((insn >> 22) & 3) {
2200 case 0:
2201 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2202 break;
2203 case 1:
2204 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2205 break;
2206 case 2:
2207 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2208 break;
2210 store_reg(s, rd, tmp);
2211 break;
2212 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2213 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2214 wrd = (insn >> 12) & 0xf;
2215 rd0 = (insn >> 16) & 0xf;
2216 rd1 = (insn >> 0) & 0xf;
2217 gen_op_iwmmxt_movq_M0_wRn(rd0);
2218 switch ((insn >> 22) & 3) {
2219 case 0:
2220 if (insn & (1 << 21))
2221 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2222 else
2223 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2224 break;
2225 case 1:
2226 if (insn & (1 << 21))
2227 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2228 else
2229 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2230 break;
2231 case 2:
2232 if (insn & (1 << 21))
2233 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2234 else
2235 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2236 break;
2237 case 3:
2238 return 1;
2240 gen_op_iwmmxt_movq_wRn_M0(wrd);
2241 gen_op_iwmmxt_set_mup();
2242 gen_op_iwmmxt_set_cup();
2243 break;
2244 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2245 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2246 wrd = (insn >> 12) & 0xf;
2247 rd0 = (insn >> 16) & 0xf;
2248 gen_op_iwmmxt_movq_M0_wRn(rd0);
2249 switch ((insn >> 22) & 3) {
2250 case 0:
2251 if (insn & (1 << 21))
2252 gen_op_iwmmxt_unpacklsb_M0();
2253 else
2254 gen_op_iwmmxt_unpacklub_M0();
2255 break;
2256 case 1:
2257 if (insn & (1 << 21))
2258 gen_op_iwmmxt_unpacklsw_M0();
2259 else
2260 gen_op_iwmmxt_unpackluw_M0();
2261 break;
2262 case 2:
2263 if (insn & (1 << 21))
2264 gen_op_iwmmxt_unpacklsl_M0();
2265 else
2266 gen_op_iwmmxt_unpacklul_M0();
2267 break;
2268 case 3:
2269 return 1;
2271 gen_op_iwmmxt_movq_wRn_M0(wrd);
2272 gen_op_iwmmxt_set_mup();
2273 gen_op_iwmmxt_set_cup();
2274 break;
2275 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2276 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2277 wrd = (insn >> 12) & 0xf;
2278 rd0 = (insn >> 16) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0);
2280 switch ((insn >> 22) & 3) {
2281 case 0:
2282 if (insn & (1 << 21))
2283 gen_op_iwmmxt_unpackhsb_M0();
2284 else
2285 gen_op_iwmmxt_unpackhub_M0();
2286 break;
2287 case 1:
2288 if (insn & (1 << 21))
2289 gen_op_iwmmxt_unpackhsw_M0();
2290 else
2291 gen_op_iwmmxt_unpackhuw_M0();
2292 break;
2293 case 2:
2294 if (insn & (1 << 21))
2295 gen_op_iwmmxt_unpackhsl_M0();
2296 else
2297 gen_op_iwmmxt_unpackhul_M0();
2298 break;
2299 case 3:
2300 return 1;
2302 gen_op_iwmmxt_movq_wRn_M0(wrd);
2303 gen_op_iwmmxt_set_mup();
2304 gen_op_iwmmxt_set_cup();
2305 break;
2306 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2307 case 0x214: case 0x614: case 0xa14: case 0xe14:
2308 if (((insn >> 22) & 3) == 0)
2309 return 1;
2310 wrd = (insn >> 12) & 0xf;
2311 rd0 = (insn >> 16) & 0xf;
2312 gen_op_iwmmxt_movq_M0_wRn(rd0);
2313 tmp = tcg_temp_new_i32();
2314 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2315 tcg_temp_free_i32(tmp);
2316 return 1;
2318 switch ((insn >> 22) & 3) {
2319 case 1:
2320 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2321 break;
2322 case 2:
2323 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2324 break;
2325 case 3:
2326 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2327 break;
2329 tcg_temp_free_i32(tmp);
2330 gen_op_iwmmxt_movq_wRn_M0(wrd);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2333 break;
2334 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2335 case 0x014: case 0x414: case 0x814: case 0xc14:
2336 if (((insn >> 22) & 3) == 0)
2337 return 1;
2338 wrd = (insn >> 12) & 0xf;
2339 rd0 = (insn >> 16) & 0xf;
2340 gen_op_iwmmxt_movq_M0_wRn(rd0);
2341 tmp = tcg_temp_new_i32();
2342 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2343 tcg_temp_free_i32(tmp);
2344 return 1;
2346 switch ((insn >> 22) & 3) {
2347 case 1:
2348 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2349 break;
2350 case 2:
2351 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2352 break;
2353 case 3:
2354 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2355 break;
2357 tcg_temp_free_i32(tmp);
2358 gen_op_iwmmxt_movq_wRn_M0(wrd);
2359 gen_op_iwmmxt_set_mup();
2360 gen_op_iwmmxt_set_cup();
2361 break;
2362 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2363 case 0x114: case 0x514: case 0x914: case 0xd14:
2364 if (((insn >> 22) & 3) == 0)
2365 return 1;
2366 wrd = (insn >> 12) & 0xf;
2367 rd0 = (insn >> 16) & 0xf;
2368 gen_op_iwmmxt_movq_M0_wRn(rd0);
2369 tmp = tcg_temp_new_i32();
2370 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2371 tcg_temp_free_i32(tmp);
2372 return 1;
2374 switch ((insn >> 22) & 3) {
2375 case 1:
2376 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2377 break;
2378 case 2:
2379 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2380 break;
2381 case 3:
2382 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2383 break;
2385 tcg_temp_free_i32(tmp);
2386 gen_op_iwmmxt_movq_wRn_M0(wrd);
2387 gen_op_iwmmxt_set_mup();
2388 gen_op_iwmmxt_set_cup();
2389 break;
2390 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2391 case 0x314: case 0x714: case 0xb14: case 0xf14:
2392 if (((insn >> 22) & 3) == 0)
2393 return 1;
2394 wrd = (insn >> 12) & 0xf;
2395 rd0 = (insn >> 16) & 0xf;
2396 gen_op_iwmmxt_movq_M0_wRn(rd0);
2397 tmp = tcg_temp_new_i32();
2398 switch ((insn >> 22) & 3) {
2399 case 1:
2400 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2401 tcg_temp_free_i32(tmp);
2402 return 1;
2404 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2405 break;
2406 case 2:
2407 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2408 tcg_temp_free_i32(tmp);
2409 return 1;
2411 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2412 break;
2413 case 3:
2414 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2415 tcg_temp_free_i32(tmp);
2416 return 1;
2418 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2419 break;
2421 tcg_temp_free_i32(tmp);
2422 gen_op_iwmmxt_movq_wRn_M0(wrd);
2423 gen_op_iwmmxt_set_mup();
2424 gen_op_iwmmxt_set_cup();
2425 break;
2426 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2427 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2428 wrd = (insn >> 12) & 0xf;
2429 rd0 = (insn >> 16) & 0xf;
2430 rd1 = (insn >> 0) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0);
2432 switch ((insn >> 22) & 3) {
2433 case 0:
2434 if (insn & (1 << 21))
2435 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2436 else
2437 gen_op_iwmmxt_minub_M0_wRn(rd1);
2438 break;
2439 case 1:
2440 if (insn & (1 << 21))
2441 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2442 else
2443 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2444 break;
2445 case 2:
2446 if (insn & (1 << 21))
2447 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2448 else
2449 gen_op_iwmmxt_minul_M0_wRn(rd1);
2450 break;
2451 case 3:
2452 return 1;
2454 gen_op_iwmmxt_movq_wRn_M0(wrd);
2455 gen_op_iwmmxt_set_mup();
2456 break;
2457 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2458 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2459 wrd = (insn >> 12) & 0xf;
2460 rd0 = (insn >> 16) & 0xf;
2461 rd1 = (insn >> 0) & 0xf;
2462 gen_op_iwmmxt_movq_M0_wRn(rd0);
2463 switch ((insn >> 22) & 3) {
2464 case 0:
2465 if (insn & (1 << 21))
2466 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2467 else
2468 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2469 break;
2470 case 1:
2471 if (insn & (1 << 21))
2472 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2473 else
2474 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2475 break;
2476 case 2:
2477 if (insn & (1 << 21))
2478 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2479 else
2480 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2481 break;
2482 case 3:
2483 return 1;
2485 gen_op_iwmmxt_movq_wRn_M0(wrd);
2486 gen_op_iwmmxt_set_mup();
2487 break;
2488 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2489 case 0x402: case 0x502: case 0x602: case 0x702:
2490 wrd = (insn >> 12) & 0xf;
2491 rd0 = (insn >> 16) & 0xf;
2492 rd1 = (insn >> 0) & 0xf;
2493 gen_op_iwmmxt_movq_M0_wRn(rd0);
2494 tmp = tcg_const_i32((insn >> 20) & 3);
2495 iwmmxt_load_reg(cpu_V1, rd1);
2496 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2497 tcg_temp_free_i32(tmp);
2498 gen_op_iwmmxt_movq_wRn_M0(wrd);
2499 gen_op_iwmmxt_set_mup();
2500 break;
2501 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2502 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2503 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2504 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2505 wrd = (insn >> 12) & 0xf;
2506 rd0 = (insn >> 16) & 0xf;
2507 rd1 = (insn >> 0) & 0xf;
2508 gen_op_iwmmxt_movq_M0_wRn(rd0);
2509 switch ((insn >> 20) & 0xf) {
2510 case 0x0:
2511 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2512 break;
2513 case 0x1:
2514 gen_op_iwmmxt_subub_M0_wRn(rd1);
2515 break;
2516 case 0x3:
2517 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2518 break;
2519 case 0x4:
2520 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2521 break;
2522 case 0x5:
2523 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2524 break;
2525 case 0x7:
2526 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2527 break;
2528 case 0x8:
2529 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2530 break;
2531 case 0x9:
2532 gen_op_iwmmxt_subul_M0_wRn(rd1);
2533 break;
2534 case 0xb:
2535 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2536 break;
2537 default:
2538 return 1;
2540 gen_op_iwmmxt_movq_wRn_M0(wrd);
2541 gen_op_iwmmxt_set_mup();
2542 gen_op_iwmmxt_set_cup();
2543 break;
2544 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2545 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2546 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2547 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2548 wrd = (insn >> 12) & 0xf;
2549 rd0 = (insn >> 16) & 0xf;
2550 gen_op_iwmmxt_movq_M0_wRn(rd0);
2551 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2552 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2553 tcg_temp_free_i32(tmp);
2554 gen_op_iwmmxt_movq_wRn_M0(wrd);
2555 gen_op_iwmmxt_set_mup();
2556 gen_op_iwmmxt_set_cup();
2557 break;
2558 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2559 case 0x418: case 0x518: case 0x618: case 0x718:
2560 case 0x818: case 0x918: case 0xa18: case 0xb18:
2561 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2562 wrd = (insn >> 12) & 0xf;
2563 rd0 = (insn >> 16) & 0xf;
2564 rd1 = (insn >> 0) & 0xf;
2565 gen_op_iwmmxt_movq_M0_wRn(rd0);
2566 switch ((insn >> 20) & 0xf) {
2567 case 0x0:
2568 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2569 break;
2570 case 0x1:
2571 gen_op_iwmmxt_addub_M0_wRn(rd1);
2572 break;
2573 case 0x3:
2574 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2575 break;
2576 case 0x4:
2577 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2578 break;
2579 case 0x5:
2580 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2581 break;
2582 case 0x7:
2583 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2584 break;
2585 case 0x8:
2586 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2587 break;
2588 case 0x9:
2589 gen_op_iwmmxt_addul_M0_wRn(rd1);
2590 break;
2591 case 0xb:
2592 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2593 break;
2594 default:
2595 return 1;
2597 gen_op_iwmmxt_movq_wRn_M0(wrd);
2598 gen_op_iwmmxt_set_mup();
2599 gen_op_iwmmxt_set_cup();
2600 break;
2601 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2602 case 0x408: case 0x508: case 0x608: case 0x708:
2603 case 0x808: case 0x908: case 0xa08: case 0xb08:
2604 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2605 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2606 return 1;
2607 wrd = (insn >> 12) & 0xf;
2608 rd0 = (insn >> 16) & 0xf;
2609 rd1 = (insn >> 0) & 0xf;
2610 gen_op_iwmmxt_movq_M0_wRn(rd0);
2611 switch ((insn >> 22) & 3) {
2612 case 1:
2613 if (insn & (1 << 21))
2614 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2615 else
2616 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2617 break;
2618 case 2:
2619 if (insn & (1 << 21))
2620 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2621 else
2622 gen_op_iwmmxt_packul_M0_wRn(rd1);
2623 break;
2624 case 3:
2625 if (insn & (1 << 21))
2626 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2627 else
2628 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2629 break;
2631 gen_op_iwmmxt_movq_wRn_M0(wrd);
2632 gen_op_iwmmxt_set_mup();
2633 gen_op_iwmmxt_set_cup();
2634 break;
2635 case 0x201: case 0x203: case 0x205: case 0x207:
2636 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2637 case 0x211: case 0x213: case 0x215: case 0x217:
2638 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2639 wrd = (insn >> 5) & 0xf;
2640 rd0 = (insn >> 12) & 0xf;
2641 rd1 = (insn >> 0) & 0xf;
2642 if (rd0 == 0xf || rd1 == 0xf)
2643 return 1;
2644 gen_op_iwmmxt_movq_M0_wRn(wrd);
2645 tmp = load_reg(s, rd0);
2646 tmp2 = load_reg(s, rd1);
2647 switch ((insn >> 16) & 0xf) {
2648 case 0x0: /* TMIA */
2649 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2650 break;
2651 case 0x8: /* TMIAPH */
2652 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2653 break;
2654 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2655 if (insn & (1 << 16))
2656 tcg_gen_shri_i32(tmp, tmp, 16);
2657 if (insn & (1 << 17))
2658 tcg_gen_shri_i32(tmp2, tmp2, 16);
2659 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2660 break;
2661 default:
2662 tcg_temp_free_i32(tmp2);
2663 tcg_temp_free_i32(tmp);
2664 return 1;
2666 tcg_temp_free_i32(tmp2);
2667 tcg_temp_free_i32(tmp);
2668 gen_op_iwmmxt_movq_wRn_M0(wrd);
2669 gen_op_iwmmxt_set_mup();
2670 break;
2671 default:
2672 return 1;
2675 return 0;
2678 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2679 (ie. an undefined instruction). */
2680 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2682 int acc, rd0, rd1, rdhi, rdlo;
2683 TCGv_i32 tmp, tmp2;
2685 if ((insn & 0x0ff00f10) == 0x0e200010) {
2686 /* Multiply with Internal Accumulate Format */
2687 rd0 = (insn >> 12) & 0xf;
2688 rd1 = insn & 0xf;
2689 acc = (insn >> 5) & 7;
2691 if (acc != 0)
2692 return 1;
2694 tmp = load_reg(s, rd0);
2695 tmp2 = load_reg(s, rd1);
2696 switch ((insn >> 16) & 0xf) {
2697 case 0x0: /* MIA */
2698 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2699 break;
2700 case 0x8: /* MIAPH */
2701 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2702 break;
2703 case 0xc: /* MIABB */
2704 case 0xd: /* MIABT */
2705 case 0xe: /* MIATB */
2706 case 0xf: /* MIATT */
2707 if (insn & (1 << 16))
2708 tcg_gen_shri_i32(tmp, tmp, 16);
2709 if (insn & (1 << 17))
2710 tcg_gen_shri_i32(tmp2, tmp2, 16);
2711 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2712 break;
2713 default:
2714 return 1;
2716 tcg_temp_free_i32(tmp2);
2717 tcg_temp_free_i32(tmp);
2719 gen_op_iwmmxt_movq_wRn_M0(acc);
2720 return 0;
2723 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2724 /* Internal Accumulator Access Format */
2725 rdhi = (insn >> 16) & 0xf;
2726 rdlo = (insn >> 12) & 0xf;
2727 acc = insn & 7;
2729 if (acc != 0)
2730 return 1;
2732 if (insn & ARM_CP_RW_BIT) { /* MRA */
2733 iwmmxt_load_reg(cpu_V0, acc);
2734 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2735 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2736 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2737 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2738 } else { /* MAR */
2739 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2740 iwmmxt_store_reg(cpu_V0, acc);
2742 return 0;
2745 return 1;
2748 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2749 #define VFP_SREG(insn, bigbit, smallbit) \
2750 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2751 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2752 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2753 reg = (((insn) >> (bigbit)) & 0x0f) \
2754 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2755 } else { \
2756 if (insn & (1 << (smallbit))) \
2757 return 1; \
2758 reg = ((insn) >> (bigbit)) & 0x0f; \
2759 }} while (0)
2761 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2762 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2763 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2764 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2765 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2766 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2768 /* Move between integer and VFP cores. */
2769 static TCGv_i32 gen_vfp_mrs(void)
2771 TCGv_i32 tmp = tcg_temp_new_i32();
2772 tcg_gen_mov_i32(tmp, cpu_F0s);
2773 return tmp;
2776 static void gen_vfp_msr(TCGv_i32 tmp)
2778 tcg_gen_mov_i32(cpu_F0s, tmp);
2779 tcg_temp_free_i32(tmp);
2782 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2784 TCGv_i32 tmp = tcg_temp_new_i32();
2785 if (shift)
2786 tcg_gen_shri_i32(var, var, shift);
2787 tcg_gen_ext8u_i32(var, var);
2788 tcg_gen_shli_i32(tmp, var, 8);
2789 tcg_gen_or_i32(var, var, tmp);
2790 tcg_gen_shli_i32(tmp, var, 16);
2791 tcg_gen_or_i32(var, var, tmp);
2792 tcg_temp_free_i32(tmp);
2795 static void gen_neon_dup_low16(TCGv_i32 var)
2797 TCGv_i32 tmp = tcg_temp_new_i32();
2798 tcg_gen_ext16u_i32(var, var);
2799 tcg_gen_shli_i32(tmp, var, 16);
2800 tcg_gen_or_i32(var, var, tmp);
2801 tcg_temp_free_i32(tmp);
2804 static void gen_neon_dup_high16(TCGv_i32 var)
2806 TCGv_i32 tmp = tcg_temp_new_i32();
2807 tcg_gen_andi_i32(var, var, 0xffff0000);
2808 tcg_gen_shri_i32(tmp, var, 16);
2809 tcg_gen_or_i32(var, var, tmp);
2810 tcg_temp_free_i32(tmp);
2813 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2815 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2816 TCGv_i32 tmp = tcg_temp_new_i32();
2817 switch (size) {
2818 case 0:
2819 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2820 gen_neon_dup_u8(tmp, 0);
2821 break;
2822 case 1:
2823 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2824 gen_neon_dup_low16(tmp);
2825 break;
2826 case 2:
2827 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2828 break;
2829 default: /* Avoid compiler warnings. */
2830 abort();
2832 return tmp;
2835 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2836 uint32_t dp)
2838 uint32_t cc = extract32(insn, 20, 2);
2840 if (dp) {
2841 TCGv_i64 frn, frm, dest;
2842 TCGv_i64 tmp, zero, zf, nf, vf;
2844 zero = tcg_const_i64(0);
2846 frn = tcg_temp_new_i64();
2847 frm = tcg_temp_new_i64();
2848 dest = tcg_temp_new_i64();
2850 zf = tcg_temp_new_i64();
2851 nf = tcg_temp_new_i64();
2852 vf = tcg_temp_new_i64();
2854 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2855 tcg_gen_ext_i32_i64(nf, cpu_NF);
2856 tcg_gen_ext_i32_i64(vf, cpu_VF);
2858 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2859 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2860 switch (cc) {
2861 case 0: /* eq: Z */
2862 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2863 frn, frm);
2864 break;
2865 case 1: /* vs: V */
2866 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2867 frn, frm);
2868 break;
2869 case 2: /* ge: N == V -> N ^ V == 0 */
2870 tmp = tcg_temp_new_i64();
2871 tcg_gen_xor_i64(tmp, vf, nf);
2872 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2873 frn, frm);
2874 tcg_temp_free_i64(tmp);
2875 break;
2876 case 3: /* gt: !Z && N == V */
2877 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2878 frn, frm);
2879 tmp = tcg_temp_new_i64();
2880 tcg_gen_xor_i64(tmp, vf, nf);
2881 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2882 dest, frm);
2883 tcg_temp_free_i64(tmp);
2884 break;
2886 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2887 tcg_temp_free_i64(frn);
2888 tcg_temp_free_i64(frm);
2889 tcg_temp_free_i64(dest);
2891 tcg_temp_free_i64(zf);
2892 tcg_temp_free_i64(nf);
2893 tcg_temp_free_i64(vf);
2895 tcg_temp_free_i64(zero);
2896 } else {
2897 TCGv_i32 frn, frm, dest;
2898 TCGv_i32 tmp, zero;
2900 zero = tcg_const_i32(0);
2902 frn = tcg_temp_new_i32();
2903 frm = tcg_temp_new_i32();
2904 dest = tcg_temp_new_i32();
2905 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2906 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2907 switch (cc) {
2908 case 0: /* eq: Z */
2909 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2910 frn, frm);
2911 break;
2912 case 1: /* vs: V */
2913 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2914 frn, frm);
2915 break;
2916 case 2: /* ge: N == V -> N ^ V == 0 */
2917 tmp = tcg_temp_new_i32();
2918 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2919 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2920 frn, frm);
2921 tcg_temp_free_i32(tmp);
2922 break;
2923 case 3: /* gt: !Z && N == V */
2924 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2925 frn, frm);
2926 tmp = tcg_temp_new_i32();
2927 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2928 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2929 dest, frm);
2930 tcg_temp_free_i32(tmp);
2931 break;
2933 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2934 tcg_temp_free_i32(frn);
2935 tcg_temp_free_i32(frm);
2936 tcg_temp_free_i32(dest);
2938 tcg_temp_free_i32(zero);
2941 return 0;
2944 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2945 uint32_t rm, uint32_t dp)
2947 uint32_t vmin = extract32(insn, 6, 1);
2948 TCGv_ptr fpst = get_fpstatus_ptr(0);
2950 if (dp) {
2951 TCGv_i64 frn, frm, dest;
2953 frn = tcg_temp_new_i64();
2954 frm = tcg_temp_new_i64();
2955 dest = tcg_temp_new_i64();
2957 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2958 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2959 if (vmin) {
2960 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2961 } else {
2962 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2964 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2965 tcg_temp_free_i64(frn);
2966 tcg_temp_free_i64(frm);
2967 tcg_temp_free_i64(dest);
2968 } else {
2969 TCGv_i32 frn, frm, dest;
2971 frn = tcg_temp_new_i32();
2972 frm = tcg_temp_new_i32();
2973 dest = tcg_temp_new_i32();
2975 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2976 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2977 if (vmin) {
2978 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2979 } else {
2980 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2982 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2983 tcg_temp_free_i32(frn);
2984 tcg_temp_free_i32(frm);
2985 tcg_temp_free_i32(dest);
2988 tcg_temp_free_ptr(fpst);
2989 return 0;
2992 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2993 int rounding)
2995 TCGv_ptr fpst = get_fpstatus_ptr(0);
2996 TCGv_i32 tcg_rmode;
2998 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2999 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3001 if (dp) {
3002 TCGv_i64 tcg_op;
3003 TCGv_i64 tcg_res;
3004 tcg_op = tcg_temp_new_i64();
3005 tcg_res = tcg_temp_new_i64();
3006 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3007 gen_helper_rintd(tcg_res, tcg_op, fpst);
3008 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3009 tcg_temp_free_i64(tcg_op);
3010 tcg_temp_free_i64(tcg_res);
3011 } else {
3012 TCGv_i32 tcg_op;
3013 TCGv_i32 tcg_res;
3014 tcg_op = tcg_temp_new_i32();
3015 tcg_res = tcg_temp_new_i32();
3016 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3017 gen_helper_rints(tcg_res, tcg_op, fpst);
3018 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3019 tcg_temp_free_i32(tcg_op);
3020 tcg_temp_free_i32(tcg_res);
3023 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3024 tcg_temp_free_i32(tcg_rmode);
3026 tcg_temp_free_ptr(fpst);
3027 return 0;
3030 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3031 int rounding)
3033 bool is_signed = extract32(insn, 7, 1);
3034 TCGv_ptr fpst = get_fpstatus_ptr(0);
3035 TCGv_i32 tcg_rmode, tcg_shift;
3037 tcg_shift = tcg_const_i32(0);
3039 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3040 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3042 if (dp) {
3043 TCGv_i64 tcg_double, tcg_res;
3044 TCGv_i32 tcg_tmp;
3045 /* Rd is encoded as a single precision register even when the source
3046 * is double precision.
3048 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3049 tcg_double = tcg_temp_new_i64();
3050 tcg_res = tcg_temp_new_i64();
3051 tcg_tmp = tcg_temp_new_i32();
3052 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3053 if (is_signed) {
3054 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3055 } else {
3056 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3058 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3059 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3060 tcg_temp_free_i32(tcg_tmp);
3061 tcg_temp_free_i64(tcg_res);
3062 tcg_temp_free_i64(tcg_double);
3063 } else {
3064 TCGv_i32 tcg_single, tcg_res;
3065 tcg_single = tcg_temp_new_i32();
3066 tcg_res = tcg_temp_new_i32();
3067 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3068 if (is_signed) {
3069 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3070 } else {
3071 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3073 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3074 tcg_temp_free_i32(tcg_res);
3075 tcg_temp_free_i32(tcg_single);
3078 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3079 tcg_temp_free_i32(tcg_rmode);
3081 tcg_temp_free_i32(tcg_shift);
3083 tcg_temp_free_ptr(fpst);
3085 return 0;
3088 /* Table for converting the most common AArch32 encoding of
3089 * rounding mode to arm_fprounding order (which matches the
3090 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3092 static const uint8_t fp_decode_rm[] = {
3093 FPROUNDING_TIEAWAY,
3094 FPROUNDING_TIEEVEN,
3095 FPROUNDING_POSINF,
3096 FPROUNDING_NEGINF,
3099 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3101 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3103 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3104 return 1;
3107 if (dp) {
3108 VFP_DREG_D(rd, insn);
3109 VFP_DREG_N(rn, insn);
3110 VFP_DREG_M(rm, insn);
3111 } else {
3112 rd = VFP_SREG_D(insn);
3113 rn = VFP_SREG_N(insn);
3114 rm = VFP_SREG_M(insn);
3117 if ((insn & 0x0f800e50) == 0x0e000a00) {
3118 return handle_vsel(insn, rd, rn, rm, dp);
3119 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3120 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3121 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3122 /* VRINTA, VRINTN, VRINTP, VRINTM */
3123 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3124 return handle_vrint(insn, rd, rm, dp, rounding);
3125 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3126 /* VCVTA, VCVTN, VCVTP, VCVTM */
3127 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3128 return handle_vcvt(insn, rd, rm, dp, rounding);
3130 return 1;
3133 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3134 (ie. an undefined instruction). */
3135 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3137 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3138 int dp, veclen;
3139 TCGv_i32 addr;
3140 TCGv_i32 tmp;
3141 TCGv_i32 tmp2;
3143 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3144 return 1;
3147 /* FIXME: this access check should not take precedence over UNDEF
3148 * for invalid encodings; we will generate incorrect syndrome information
3149 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3151 if (s->fp_excp_el) {
3152 gen_exception_insn(s, 4, EXCP_UDEF,
3153 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3154 return 0;
3157 if (!s->vfp_enabled) {
3158 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3159 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3160 return 1;
3161 rn = (insn >> 16) & 0xf;
3162 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3163 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3164 return 1;
3168 if (extract32(insn, 28, 4) == 0xf) {
3169 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3170 * only used in v8 and above.
3172 return disas_vfp_v8_insn(s, insn);
3175 dp = ((insn & 0xf00) == 0xb00);
3176 switch ((insn >> 24) & 0xf) {
3177 case 0xe:
3178 if (insn & (1 << 4)) {
3179 /* single register transfer */
3180 rd = (insn >> 12) & 0xf;
3181 if (dp) {
3182 int size;
3183 int pass;
3185 VFP_DREG_N(rn, insn);
3186 if (insn & 0xf)
3187 return 1;
3188 if (insn & 0x00c00060
3189 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3190 return 1;
3193 pass = (insn >> 21) & 1;
3194 if (insn & (1 << 22)) {
3195 size = 0;
3196 offset = ((insn >> 5) & 3) * 8;
3197 } else if (insn & (1 << 5)) {
3198 size = 1;
3199 offset = (insn & (1 << 6)) ? 16 : 0;
3200 } else {
3201 size = 2;
3202 offset = 0;
3204 if (insn & ARM_CP_RW_BIT) {
3205 /* vfp->arm */
3206 tmp = neon_load_reg(rn, pass);
3207 switch (size) {
3208 case 0:
3209 if (offset)
3210 tcg_gen_shri_i32(tmp, tmp, offset);
3211 if (insn & (1 << 23))
3212 gen_uxtb(tmp);
3213 else
3214 gen_sxtb(tmp);
3215 break;
3216 case 1:
3217 if (insn & (1 << 23)) {
3218 if (offset) {
3219 tcg_gen_shri_i32(tmp, tmp, 16);
3220 } else {
3221 gen_uxth(tmp);
3223 } else {
3224 if (offset) {
3225 tcg_gen_sari_i32(tmp, tmp, 16);
3226 } else {
3227 gen_sxth(tmp);
3230 break;
3231 case 2:
3232 break;
3234 store_reg(s, rd, tmp);
3235 } else {
3236 /* arm->vfp */
3237 tmp = load_reg(s, rd);
3238 if (insn & (1 << 23)) {
3239 /* VDUP */
3240 if (size == 0) {
3241 gen_neon_dup_u8(tmp, 0);
3242 } else if (size == 1) {
3243 gen_neon_dup_low16(tmp);
3245 for (n = 0; n <= pass * 2; n++) {
3246 tmp2 = tcg_temp_new_i32();
3247 tcg_gen_mov_i32(tmp2, tmp);
3248 neon_store_reg(rn, n, tmp2);
3250 neon_store_reg(rn, n, tmp);
3251 } else {
3252 /* VMOV */
3253 switch (size) {
3254 case 0:
3255 tmp2 = neon_load_reg(rn, pass);
3256 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3257 tcg_temp_free_i32(tmp2);
3258 break;
3259 case 1:
3260 tmp2 = neon_load_reg(rn, pass);
3261 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3262 tcg_temp_free_i32(tmp2);
3263 break;
3264 case 2:
3265 break;
3267 neon_store_reg(rn, pass, tmp);
3270 } else { /* !dp */
3271 if ((insn & 0x6f) != 0x00)
3272 return 1;
3273 rn = VFP_SREG_N(insn);
3274 if (insn & ARM_CP_RW_BIT) {
3275 /* vfp->arm */
3276 if (insn & (1 << 21)) {
3277 /* system register */
3278 rn >>= 1;
3280 switch (rn) {
3281 case ARM_VFP_FPSID:
3282 /* VFP2 allows access to FSID from userspace.
3283 VFP3 restricts all id registers to privileged
3284 accesses. */
3285 if (IS_USER(s)
3286 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3287 return 1;
3289 tmp = load_cpu_field(vfp.xregs[rn]);
3290 break;
3291 case ARM_VFP_FPEXC:
3292 if (IS_USER(s))
3293 return 1;
3294 tmp = load_cpu_field(vfp.xregs[rn]);
3295 break;
3296 case ARM_VFP_FPINST:
3297 case ARM_VFP_FPINST2:
3298 /* Not present in VFP3. */
3299 if (IS_USER(s)
3300 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3301 return 1;
3303 tmp = load_cpu_field(vfp.xregs[rn]);
3304 break;
3305 case ARM_VFP_FPSCR:
3306 if (rd == 15) {
3307 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3308 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3309 } else {
3310 tmp = tcg_temp_new_i32();
3311 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3313 break;
3314 case ARM_VFP_MVFR2:
3315 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3316 return 1;
3318 /* fall through */
3319 case ARM_VFP_MVFR0:
3320 case ARM_VFP_MVFR1:
3321 if (IS_USER(s)
3322 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3323 return 1;
3325 tmp = load_cpu_field(vfp.xregs[rn]);
3326 break;
3327 default:
3328 return 1;
3330 } else {
3331 gen_mov_F0_vreg(0, rn);
3332 tmp = gen_vfp_mrs();
3334 if (rd == 15) {
3335 /* Set the 4 flag bits in the CPSR. */
3336 gen_set_nzcv(tmp);
3337 tcg_temp_free_i32(tmp);
3338 } else {
3339 store_reg(s, rd, tmp);
3341 } else {
3342 /* arm->vfp */
3343 if (insn & (1 << 21)) {
3344 rn >>= 1;
3345 /* system register */
3346 switch (rn) {
3347 case ARM_VFP_FPSID:
3348 case ARM_VFP_MVFR0:
3349 case ARM_VFP_MVFR1:
3350 /* Writes are ignored. */
3351 break;
3352 case ARM_VFP_FPSCR:
3353 tmp = load_reg(s, rd);
3354 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3355 tcg_temp_free_i32(tmp);
3356 gen_lookup_tb(s);
3357 break;
3358 case ARM_VFP_FPEXC:
3359 if (IS_USER(s))
3360 return 1;
3361 /* TODO: VFP subarchitecture support.
3362 * For now, keep the EN bit only */
3363 tmp = load_reg(s, rd);
3364 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3365 store_cpu_field(tmp, vfp.xregs[rn]);
3366 gen_lookup_tb(s);
3367 break;
3368 case ARM_VFP_FPINST:
3369 case ARM_VFP_FPINST2:
3370 if (IS_USER(s)) {
3371 return 1;
3373 tmp = load_reg(s, rd);
3374 store_cpu_field(tmp, vfp.xregs[rn]);
3375 break;
3376 default:
3377 return 1;
3379 } else {
3380 tmp = load_reg(s, rd);
3381 gen_vfp_msr(tmp);
3382 gen_mov_vreg_F0(0, rn);
3386 } else {
3387 /* data processing */
3388 /* The opcode is in bits 23, 21, 20 and 6. */
3389 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3390 if (dp) {
3391 if (op == 15) {
3392 /* rn is opcode */
3393 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3394 } else {
3395 /* rn is register number */
3396 VFP_DREG_N(rn, insn);
3399 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3400 ((rn & 0x1e) == 0x6))) {
3401 /* Integer or single/half precision destination. */
3402 rd = VFP_SREG_D(insn);
3403 } else {
3404 VFP_DREG_D(rd, insn);
3406 if (op == 15 &&
3407 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3408 ((rn & 0x1e) == 0x4))) {
3409 /* VCVT from int or half precision is always from S reg
3410 * regardless of dp bit. VCVT with immediate frac_bits
3411 * has same format as SREG_M.
3413 rm = VFP_SREG_M(insn);
3414 } else {
3415 VFP_DREG_M(rm, insn);
3417 } else {
3418 rn = VFP_SREG_N(insn);
3419 if (op == 15 && rn == 15) {
3420 /* Double precision destination. */
3421 VFP_DREG_D(rd, insn);
3422 } else {
3423 rd = VFP_SREG_D(insn);
3425 /* NB that we implicitly rely on the encoding for the frac_bits
3426 * in VCVT of fixed to float being the same as that of an SREG_M
3428 rm = VFP_SREG_M(insn);
3431 veclen = s->vec_len;
3432 if (op == 15 && rn > 3)
3433 veclen = 0;
3435 /* Shut up compiler warnings. */
3436 delta_m = 0;
3437 delta_d = 0;
3438 bank_mask = 0;
3440 if (veclen > 0) {
3441 if (dp)
3442 bank_mask = 0xc;
3443 else
3444 bank_mask = 0x18;
3446 /* Figure out what type of vector operation this is. */
3447 if ((rd & bank_mask) == 0) {
3448 /* scalar */
3449 veclen = 0;
3450 } else {
3451 if (dp)
3452 delta_d = (s->vec_stride >> 1) + 1;
3453 else
3454 delta_d = s->vec_stride + 1;
3456 if ((rm & bank_mask) == 0) {
3457 /* mixed scalar/vector */
3458 delta_m = 0;
3459 } else {
3460 /* vector */
3461 delta_m = delta_d;
3466 /* Load the initial operands. */
3467 if (op == 15) {
3468 switch (rn) {
3469 case 16:
3470 case 17:
3471 /* Integer source */
3472 gen_mov_F0_vreg(0, rm);
3473 break;
3474 case 8:
3475 case 9:
3476 /* Compare */
3477 gen_mov_F0_vreg(dp, rd);
3478 gen_mov_F1_vreg(dp, rm);
3479 break;
3480 case 10:
3481 case 11:
3482 /* Compare with zero */
3483 gen_mov_F0_vreg(dp, rd);
3484 gen_vfp_F1_ld0(dp);
3485 break;
3486 case 20:
3487 case 21:
3488 case 22:
3489 case 23:
3490 case 28:
3491 case 29:
3492 case 30:
3493 case 31:
3494 /* Source and destination the same. */
3495 gen_mov_F0_vreg(dp, rd);
3496 break;
3497 case 4:
3498 case 5:
3499 case 6:
3500 case 7:
3501 /* VCVTB, VCVTT: only present with the halfprec extension
3502 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3503 * (we choose to UNDEF)
3505 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3506 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3507 return 1;
3509 if (!extract32(rn, 1, 1)) {
3510 /* Half precision source. */
3511 gen_mov_F0_vreg(0, rm);
3512 break;
3514 /* Otherwise fall through */
3515 default:
3516 /* One source operand. */
3517 gen_mov_F0_vreg(dp, rm);
3518 break;
3520 } else {
3521 /* Two source operands. */
3522 gen_mov_F0_vreg(dp, rn);
3523 gen_mov_F1_vreg(dp, rm);
3526 for (;;) {
3527 /* Perform the calculation. */
3528 switch (op) {
3529 case 0: /* VMLA: fd + (fn * fm) */
3530 /* Note that order of inputs to the add matters for NaNs */
3531 gen_vfp_F1_mul(dp);
3532 gen_mov_F0_vreg(dp, rd);
3533 gen_vfp_add(dp);
3534 break;
3535 case 1: /* VMLS: fd + -(fn * fm) */
3536 gen_vfp_mul(dp);
3537 gen_vfp_F1_neg(dp);
3538 gen_mov_F0_vreg(dp, rd);
3539 gen_vfp_add(dp);
3540 break;
3541 case 2: /* VNMLS: -fd + (fn * fm) */
3542 /* Note that it isn't valid to replace (-A + B) with (B - A)
3543 * or similar plausible looking simplifications
3544 * because this will give wrong results for NaNs.
3546 gen_vfp_F1_mul(dp);
3547 gen_mov_F0_vreg(dp, rd);
3548 gen_vfp_neg(dp);
3549 gen_vfp_add(dp);
3550 break;
3551 case 3: /* VNMLA: -fd + -(fn * fm) */
3552 gen_vfp_mul(dp);
3553 gen_vfp_F1_neg(dp);
3554 gen_mov_F0_vreg(dp, rd);
3555 gen_vfp_neg(dp);
3556 gen_vfp_add(dp);
3557 break;
3558 case 4: /* mul: fn * fm */
3559 gen_vfp_mul(dp);
3560 break;
3561 case 5: /* nmul: -(fn * fm) */
3562 gen_vfp_mul(dp);
3563 gen_vfp_neg(dp);
3564 break;
3565 case 6: /* add: fn + fm */
3566 gen_vfp_add(dp);
3567 break;
3568 case 7: /* sub: fn - fm */
3569 gen_vfp_sub(dp);
3570 break;
3571 case 8: /* div: fn / fm */
3572 gen_vfp_div(dp);
3573 break;
3574 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3575 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3576 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3577 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3578 /* These are fused multiply-add, and must be done as one
3579 * floating point operation with no rounding between the
3580 * multiplication and addition steps.
3581 * NB that doing the negations here as separate steps is
3582 * correct : an input NaN should come out with its sign bit
3583 * flipped if it is a negated-input.
3585 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3586 return 1;
3588 if (dp) {
3589 TCGv_ptr fpst;
3590 TCGv_i64 frd;
3591 if (op & 1) {
3592 /* VFNMS, VFMS */
3593 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3595 frd = tcg_temp_new_i64();
3596 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3597 if (op & 2) {
3598 /* VFNMA, VFNMS */
3599 gen_helper_vfp_negd(frd, frd);
3601 fpst = get_fpstatus_ptr(0);
3602 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3603 cpu_F1d, frd, fpst);
3604 tcg_temp_free_ptr(fpst);
3605 tcg_temp_free_i64(frd);
3606 } else {
3607 TCGv_ptr fpst;
3608 TCGv_i32 frd;
3609 if (op & 1) {
3610 /* VFNMS, VFMS */
3611 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3613 frd = tcg_temp_new_i32();
3614 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3615 if (op & 2) {
3616 gen_helper_vfp_negs(frd, frd);
3618 fpst = get_fpstatus_ptr(0);
3619 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3620 cpu_F1s, frd, fpst);
3621 tcg_temp_free_ptr(fpst);
3622 tcg_temp_free_i32(frd);
3624 break;
3625 case 14: /* fconst */
3626 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3627 return 1;
3630 n = (insn << 12) & 0x80000000;
3631 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3632 if (dp) {
3633 if (i & 0x40)
3634 i |= 0x3f80;
3635 else
3636 i |= 0x4000;
3637 n |= i << 16;
3638 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3639 } else {
3640 if (i & 0x40)
3641 i |= 0x780;
3642 else
3643 i |= 0x800;
3644 n |= i << 19;
3645 tcg_gen_movi_i32(cpu_F0s, n);
3647 break;
3648 case 15: /* extension space */
3649 switch (rn) {
3650 case 0: /* cpy */
3651 /* no-op */
3652 break;
3653 case 1: /* abs */
3654 gen_vfp_abs(dp);
3655 break;
3656 case 2: /* neg */
3657 gen_vfp_neg(dp);
3658 break;
3659 case 3: /* sqrt */
3660 gen_vfp_sqrt(dp);
3661 break;
3662 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3663 tmp = gen_vfp_mrs();
3664 tcg_gen_ext16u_i32(tmp, tmp);
3665 if (dp) {
3666 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3667 cpu_env);
3668 } else {
3669 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3670 cpu_env);
3672 tcg_temp_free_i32(tmp);
3673 break;
3674 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3675 tmp = gen_vfp_mrs();
3676 tcg_gen_shri_i32(tmp, tmp, 16);
3677 if (dp) {
3678 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3679 cpu_env);
3680 } else {
3681 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3682 cpu_env);
3684 tcg_temp_free_i32(tmp);
3685 break;
3686 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3687 tmp = tcg_temp_new_i32();
3688 if (dp) {
3689 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3690 cpu_env);
3691 } else {
3692 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3693 cpu_env);
3695 gen_mov_F0_vreg(0, rd);
3696 tmp2 = gen_vfp_mrs();
3697 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3698 tcg_gen_or_i32(tmp, tmp, tmp2);
3699 tcg_temp_free_i32(tmp2);
3700 gen_vfp_msr(tmp);
3701 break;
3702 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3703 tmp = tcg_temp_new_i32();
3704 if (dp) {
3705 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3706 cpu_env);
3707 } else {
3708 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3709 cpu_env);
3711 tcg_gen_shli_i32(tmp, tmp, 16);
3712 gen_mov_F0_vreg(0, rd);
3713 tmp2 = gen_vfp_mrs();
3714 tcg_gen_ext16u_i32(tmp2, tmp2);
3715 tcg_gen_or_i32(tmp, tmp, tmp2);
3716 tcg_temp_free_i32(tmp2);
3717 gen_vfp_msr(tmp);
3718 break;
3719 case 8: /* cmp */
3720 gen_vfp_cmp(dp);
3721 break;
3722 case 9: /* cmpe */
3723 gen_vfp_cmpe(dp);
3724 break;
3725 case 10: /* cmpz */
3726 gen_vfp_cmp(dp);
3727 break;
3728 case 11: /* cmpez */
3729 gen_vfp_F1_ld0(dp);
3730 gen_vfp_cmpe(dp);
3731 break;
3732 case 12: /* vrintr */
3734 TCGv_ptr fpst = get_fpstatus_ptr(0);
3735 if (dp) {
3736 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3737 } else {
3738 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3740 tcg_temp_free_ptr(fpst);
3741 break;
3743 case 13: /* vrintz */
3745 TCGv_ptr fpst = get_fpstatus_ptr(0);
3746 TCGv_i32 tcg_rmode;
3747 tcg_rmode = tcg_const_i32(float_round_to_zero);
3748 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3749 if (dp) {
3750 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3751 } else {
3752 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3754 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3755 tcg_temp_free_i32(tcg_rmode);
3756 tcg_temp_free_ptr(fpst);
3757 break;
3759 case 14: /* vrintx */
3761 TCGv_ptr fpst = get_fpstatus_ptr(0);
3762 if (dp) {
3763 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3764 } else {
3765 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3767 tcg_temp_free_ptr(fpst);
3768 break;
3770 case 15: /* single<->double conversion */
3771 if (dp)
3772 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3773 else
3774 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3775 break;
3776 case 16: /* fuito */
3777 gen_vfp_uito(dp, 0);
3778 break;
3779 case 17: /* fsito */
3780 gen_vfp_sito(dp, 0);
3781 break;
3782 case 20: /* fshto */
3783 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3784 return 1;
3786 gen_vfp_shto(dp, 16 - rm, 0);
3787 break;
3788 case 21: /* fslto */
3789 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3790 return 1;
3792 gen_vfp_slto(dp, 32 - rm, 0);
3793 break;
3794 case 22: /* fuhto */
3795 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3796 return 1;
3798 gen_vfp_uhto(dp, 16 - rm, 0);
3799 break;
3800 case 23: /* fulto */
3801 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3802 return 1;
3804 gen_vfp_ulto(dp, 32 - rm, 0);
3805 break;
3806 case 24: /* ftoui */
3807 gen_vfp_toui(dp, 0);
3808 break;
3809 case 25: /* ftouiz */
3810 gen_vfp_touiz(dp, 0);
3811 break;
3812 case 26: /* ftosi */
3813 gen_vfp_tosi(dp, 0);
3814 break;
3815 case 27: /* ftosiz */
3816 gen_vfp_tosiz(dp, 0);
3817 break;
3818 case 28: /* ftosh */
3819 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3820 return 1;
3822 gen_vfp_tosh(dp, 16 - rm, 0);
3823 break;
3824 case 29: /* ftosl */
3825 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3826 return 1;
3828 gen_vfp_tosl(dp, 32 - rm, 0);
3829 break;
3830 case 30: /* ftouh */
3831 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3832 return 1;
3834 gen_vfp_touh(dp, 16 - rm, 0);
3835 break;
3836 case 31: /* ftoul */
3837 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3838 return 1;
3840 gen_vfp_toul(dp, 32 - rm, 0);
3841 break;
3842 default: /* undefined */
3843 return 1;
3845 break;
3846 default: /* undefined */
3847 return 1;
3850 /* Write back the result. */
3851 if (op == 15 && (rn >= 8 && rn <= 11)) {
3852 /* Comparison, do nothing. */
3853 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3854 (rn & 0x1e) == 0x6)) {
3855 /* VCVT double to int: always integer result.
3856 * VCVT double to half precision is always a single
3857 * precision result.
3859 gen_mov_vreg_F0(0, rd);
3860 } else if (op == 15 && rn == 15) {
3861 /* conversion */
3862 gen_mov_vreg_F0(!dp, rd);
3863 } else {
3864 gen_mov_vreg_F0(dp, rd);
3867 /* break out of the loop if we have finished */
3868 if (veclen == 0)
3869 break;
3871 if (op == 15 && delta_m == 0) {
3872 /* single source one-many */
3873 while (veclen--) {
3874 rd = ((rd + delta_d) & (bank_mask - 1))
3875 | (rd & bank_mask);
3876 gen_mov_vreg_F0(dp, rd);
3878 break;
3880 /* Setup the next operands. */
3881 veclen--;
3882 rd = ((rd + delta_d) & (bank_mask - 1))
3883 | (rd & bank_mask);
3885 if (op == 15) {
3886 /* One source operand. */
3887 rm = ((rm + delta_m) & (bank_mask - 1))
3888 | (rm & bank_mask);
3889 gen_mov_F0_vreg(dp, rm);
3890 } else {
3891 /* Two source operands. */
3892 rn = ((rn + delta_d) & (bank_mask - 1))
3893 | (rn & bank_mask);
3894 gen_mov_F0_vreg(dp, rn);
3895 if (delta_m) {
3896 rm = ((rm + delta_m) & (bank_mask - 1))
3897 | (rm & bank_mask);
3898 gen_mov_F1_vreg(dp, rm);
3903 break;
3904 case 0xc:
3905 case 0xd:
3906 if ((insn & 0x03e00000) == 0x00400000) {
3907 /* two-register transfer */
3908 rn = (insn >> 16) & 0xf;
3909 rd = (insn >> 12) & 0xf;
3910 if (dp) {
3911 VFP_DREG_M(rm, insn);
3912 } else {
3913 rm = VFP_SREG_M(insn);
3916 if (insn & ARM_CP_RW_BIT) {
3917 /* vfp->arm */
3918 if (dp) {
3919 gen_mov_F0_vreg(0, rm * 2);
3920 tmp = gen_vfp_mrs();
3921 store_reg(s, rd, tmp);
3922 gen_mov_F0_vreg(0, rm * 2 + 1);
3923 tmp = gen_vfp_mrs();
3924 store_reg(s, rn, tmp);
3925 } else {
3926 gen_mov_F0_vreg(0, rm);
3927 tmp = gen_vfp_mrs();
3928 store_reg(s, rd, tmp);
3929 gen_mov_F0_vreg(0, rm + 1);
3930 tmp = gen_vfp_mrs();
3931 store_reg(s, rn, tmp);
3933 } else {
3934 /* arm->vfp */
3935 if (dp) {
3936 tmp = load_reg(s, rd);
3937 gen_vfp_msr(tmp);
3938 gen_mov_vreg_F0(0, rm * 2);
3939 tmp = load_reg(s, rn);
3940 gen_vfp_msr(tmp);
3941 gen_mov_vreg_F0(0, rm * 2 + 1);
3942 } else {
3943 tmp = load_reg(s, rd);
3944 gen_vfp_msr(tmp);
3945 gen_mov_vreg_F0(0, rm);
3946 tmp = load_reg(s, rn);
3947 gen_vfp_msr(tmp);
3948 gen_mov_vreg_F0(0, rm + 1);
3951 } else {
3952 /* Load/store */
3953 rn = (insn >> 16) & 0xf;
3954 if (dp)
3955 VFP_DREG_D(rd, insn);
3956 else
3957 rd = VFP_SREG_D(insn);
3958 if ((insn & 0x01200000) == 0x01000000) {
3959 /* Single load/store */
3960 offset = (insn & 0xff) << 2;
3961 if ((insn & (1 << 23)) == 0)
3962 offset = -offset;
3963 if (s->thumb && rn == 15) {
3964 /* This is actually UNPREDICTABLE */
3965 addr = tcg_temp_new_i32();
3966 tcg_gen_movi_i32(addr, s->pc & ~2);
3967 } else {
3968 addr = load_reg(s, rn);
3970 tcg_gen_addi_i32(addr, addr, offset);
3971 if (insn & (1 << 20)) {
3972 gen_vfp_ld(s, dp, addr);
3973 gen_mov_vreg_F0(dp, rd);
3974 } else {
3975 gen_mov_F0_vreg(dp, rd);
3976 gen_vfp_st(s, dp, addr);
3978 tcg_temp_free_i32(addr);
3979 } else {
3980 /* load/store multiple */
3981 int w = insn & (1 << 21);
3982 if (dp)
3983 n = (insn >> 1) & 0x7f;
3984 else
3985 n = insn & 0xff;
3987 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3988 /* P == U , W == 1 => UNDEF */
3989 return 1;
3991 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3992 /* UNPREDICTABLE cases for bad immediates: we choose to
3993 * UNDEF to avoid generating huge numbers of TCG ops
3995 return 1;
3997 if (rn == 15 && w) {
3998 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3999 return 1;
4002 if (s->thumb && rn == 15) {
4003 /* This is actually UNPREDICTABLE */
4004 addr = tcg_temp_new_i32();
4005 tcg_gen_movi_i32(addr, s->pc & ~2);
4006 } else {
4007 addr = load_reg(s, rn);
4009 if (insn & (1 << 24)) /* pre-decrement */
4010 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4012 if (dp)
4013 offset = 8;
4014 else
4015 offset = 4;
4016 for (i = 0; i < n; i++) {
4017 if (insn & ARM_CP_RW_BIT) {
4018 /* load */
4019 gen_vfp_ld(s, dp, addr);
4020 gen_mov_vreg_F0(dp, rd + i);
4021 } else {
4022 /* store */
4023 gen_mov_F0_vreg(dp, rd + i);
4024 gen_vfp_st(s, dp, addr);
4026 tcg_gen_addi_i32(addr, addr, offset);
4028 if (w) {
4029 /* writeback */
4030 if (insn & (1 << 24))
4031 offset = -offset * n;
4032 else if (dp && (insn & 1))
4033 offset = 4;
4034 else
4035 offset = 0;
4037 if (offset != 0)
4038 tcg_gen_addi_i32(addr, addr, offset);
4039 store_reg(s, rn, addr);
4040 } else {
4041 tcg_temp_free_i32(addr);
4045 break;
4046 default:
4047 /* Should never happen. */
4048 return 1;
4050 return 0;
4053 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4055 #ifndef CONFIG_USER_ONLY
4056 return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4057 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4058 #else
4059 return true;
4060 #endif
4063 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4065 if (use_goto_tb(s, dest)) {
4066 tcg_gen_goto_tb(n);
4067 gen_set_pc_im(s, dest);
4068 tcg_gen_exit_tb((uintptr_t)s->tb + n);
4069 } else {
4070 gen_set_pc_im(s, dest);
4071 tcg_gen_exit_tb(0);
4075 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4077 if (unlikely(s->singlestep_enabled || s->ss_active)) {
4078 /* An indirect jump so that we still trigger the debug exception. */
4079 if (s->thumb)
4080 dest |= 1;
4081 gen_bx_im(s, dest);
4082 } else {
4083 gen_goto_tb(s, 0, dest);
4084 s->is_jmp = DISAS_TB_JUMP;
4088 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4090 if (x)
4091 tcg_gen_sari_i32(t0, t0, 16);
4092 else
4093 gen_sxth(t0);
4094 if (y)
4095 tcg_gen_sari_i32(t1, t1, 16);
4096 else
4097 gen_sxth(t1);
4098 tcg_gen_mul_i32(t0, t0, t1);
4101 /* Return the mask of PSR bits set by a MSR instruction. */
4102 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4104 uint32_t mask;
4106 mask = 0;
4107 if (flags & (1 << 0))
4108 mask |= 0xff;
4109 if (flags & (1 << 1))
4110 mask |= 0xff00;
4111 if (flags & (1 << 2))
4112 mask |= 0xff0000;
4113 if (flags & (1 << 3))
4114 mask |= 0xff000000;
4116 /* Mask out undefined bits. */
4117 mask &= ~CPSR_RESERVED;
4118 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4119 mask &= ~CPSR_T;
4121 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4122 mask &= ~CPSR_Q; /* V5TE in reality*/
4124 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4125 mask &= ~(CPSR_E | CPSR_GE);
4127 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4128 mask &= ~CPSR_IT;
4130 /* Mask out execution state and reserved bits. */
4131 if (!spsr) {
4132 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4134 /* Mask out privileged bits. */
4135 if (IS_USER(s))
4136 mask &= CPSR_USER;
4137 return mask;
4140 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4141 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4143 TCGv_i32 tmp;
4144 if (spsr) {
4145 /* ??? This is also undefined in system mode. */
4146 if (IS_USER(s))
4147 return 1;
4149 tmp = load_cpu_field(spsr);
4150 tcg_gen_andi_i32(tmp, tmp, ~mask);
4151 tcg_gen_andi_i32(t0, t0, mask);
4152 tcg_gen_or_i32(tmp, tmp, t0);
4153 store_cpu_field(tmp, spsr);
4154 } else {
4155 gen_set_cpsr(t0, mask);
4157 tcg_temp_free_i32(t0);
4158 gen_lookup_tb(s);
4159 return 0;
4162 /* Returns nonzero if access to the PSR is not permitted. */
4163 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4165 TCGv_i32 tmp;
4166 tmp = tcg_temp_new_i32();
4167 tcg_gen_movi_i32(tmp, val);
4168 return gen_set_psr(s, mask, spsr, tmp);
4171 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4172 int *tgtmode, int *regno)
4174 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4175 * the target mode and register number, and identify the various
4176 * unpredictable cases.
4177 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4178 * + executed in user mode
4179 * + using R15 as the src/dest register
4180 * + accessing an unimplemented register
4181 * + accessing a register that's inaccessible at current PL/security state*
4182 * + accessing a register that you could access with a different insn
4183 * We choose to UNDEF in all these cases.
4184 * Since we don't know which of the various AArch32 modes we are in
4185 * we have to defer some checks to runtime.
4186 * Accesses to Monitor mode registers from Secure EL1 (which implies
4187 * that EL3 is AArch64) must trap to EL3.
4189 * If the access checks fail this function will emit code to take
4190 * an exception and return false. Otherwise it will return true,
4191 * and set *tgtmode and *regno appropriately.
4193 int exc_target = default_exception_el(s);
4195 /* These instructions are present only in ARMv8, or in ARMv7 with the
4196 * Virtualization Extensions.
4198 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4199 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4200 goto undef;
4203 if (IS_USER(s) || rn == 15) {
4204 goto undef;
4207 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4208 * of registers into (r, sysm).
4210 if (r) {
4211 /* SPSRs for other modes */
4212 switch (sysm) {
4213 case 0xe: /* SPSR_fiq */
4214 *tgtmode = ARM_CPU_MODE_FIQ;
4215 break;
4216 case 0x10: /* SPSR_irq */
4217 *tgtmode = ARM_CPU_MODE_IRQ;
4218 break;
4219 case 0x12: /* SPSR_svc */
4220 *tgtmode = ARM_CPU_MODE_SVC;
4221 break;
4222 case 0x14: /* SPSR_abt */
4223 *tgtmode = ARM_CPU_MODE_ABT;
4224 break;
4225 case 0x16: /* SPSR_und */
4226 *tgtmode = ARM_CPU_MODE_UND;
4227 break;
4228 case 0x1c: /* SPSR_mon */
4229 *tgtmode = ARM_CPU_MODE_MON;
4230 break;
4231 case 0x1e: /* SPSR_hyp */
4232 *tgtmode = ARM_CPU_MODE_HYP;
4233 break;
4234 default: /* unallocated */
4235 goto undef;
4237 /* We arbitrarily assign SPSR a register number of 16. */
4238 *regno = 16;
4239 } else {
4240 /* general purpose registers for other modes */
4241 switch (sysm) {
4242 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4243 *tgtmode = ARM_CPU_MODE_USR;
4244 *regno = sysm + 8;
4245 break;
4246 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4247 *tgtmode = ARM_CPU_MODE_FIQ;
4248 *regno = sysm;
4249 break;
4250 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4251 *tgtmode = ARM_CPU_MODE_IRQ;
4252 *regno = sysm & 1 ? 13 : 14;
4253 break;
4254 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4255 *tgtmode = ARM_CPU_MODE_SVC;
4256 *regno = sysm & 1 ? 13 : 14;
4257 break;
4258 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4259 *tgtmode = ARM_CPU_MODE_ABT;
4260 *regno = sysm & 1 ? 13 : 14;
4261 break;
4262 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4263 *tgtmode = ARM_CPU_MODE_UND;
4264 *regno = sysm & 1 ? 13 : 14;
4265 break;
4266 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4267 *tgtmode = ARM_CPU_MODE_MON;
4268 *regno = sysm & 1 ? 13 : 14;
4269 break;
4270 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4271 *tgtmode = ARM_CPU_MODE_HYP;
4272 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4273 *regno = sysm & 1 ? 13 : 17;
4274 break;
4275 default: /* unallocated */
4276 goto undef;
4280 /* Catch the 'accessing inaccessible register' cases we can detect
4281 * at translate time.
4283 switch (*tgtmode) {
4284 case ARM_CPU_MODE_MON:
4285 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4286 goto undef;
4288 if (s->current_el == 1) {
4289 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4290 * then accesses to Mon registers trap to EL3
4292 exc_target = 3;
4293 goto undef;
4295 break;
4296 case ARM_CPU_MODE_HYP:
4297 /* Note that we can forbid accesses from EL2 here because they
4298 * must be from Hyp mode itself
4300 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4301 goto undef;
4303 break;
4304 default:
4305 break;
4308 return true;
4310 undef:
4311 /* If we get here then some access check did not pass */
4312 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4313 return false;
4316 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4318 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4319 int tgtmode = 0, regno = 0;
4321 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4322 return;
4325 /* Sync state because msr_banked() can raise exceptions */
4326 gen_set_condexec(s);
4327 gen_set_pc_im(s, s->pc - 4);
4328 tcg_reg = load_reg(s, rn);
4329 tcg_tgtmode = tcg_const_i32(tgtmode);
4330 tcg_regno = tcg_const_i32(regno);
4331 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4332 tcg_temp_free_i32(tcg_tgtmode);
4333 tcg_temp_free_i32(tcg_regno);
4334 tcg_temp_free_i32(tcg_reg);
4335 s->is_jmp = DISAS_UPDATE;
4338 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4340 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4341 int tgtmode = 0, regno = 0;
4343 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4344 return;
4347 /* Sync state because mrs_banked() can raise exceptions */
4348 gen_set_condexec(s);
4349 gen_set_pc_im(s, s->pc - 4);
4350 tcg_reg = tcg_temp_new_i32();
4351 tcg_tgtmode = tcg_const_i32(tgtmode);
4352 tcg_regno = tcg_const_i32(regno);
4353 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4354 tcg_temp_free_i32(tcg_tgtmode);
4355 tcg_temp_free_i32(tcg_regno);
4356 store_reg(s, rn, tcg_reg);
4357 s->is_jmp = DISAS_UPDATE;
4360 /* Generate an old-style exception return. Marks pc as dead. */
4361 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4363 TCGv_i32 tmp;
4364 store_reg(s, 15, pc);
4365 tmp = load_cpu_field(spsr);
4366 gen_helper_cpsr_write_eret(cpu_env, tmp);
4367 tcg_temp_free_i32(tmp);
4368 s->is_jmp = DISAS_JUMP;
4371 /* Generate a v6 exception return. Marks both values as dead. */
4372 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4374 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4375 tcg_temp_free_i32(cpsr);
4376 store_reg(s, 15, pc);
4377 s->is_jmp = DISAS_JUMP;
4380 static void gen_nop_hint(DisasContext *s, int val)
4382 switch (val) {
4383 case 1: /* yield */
4384 gen_set_pc_im(s, s->pc);
4385 s->is_jmp = DISAS_YIELD;
4386 break;
4387 case 3: /* wfi */
4388 gen_set_pc_im(s, s->pc);
4389 s->is_jmp = DISAS_WFI;
4390 break;
4391 case 2: /* wfe */
4392 gen_set_pc_im(s, s->pc);
4393 s->is_jmp = DISAS_WFE;
4394 break;
4395 case 4: /* sev */
4396 case 5: /* sevl */
4397 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4398 default: /* nop */
4399 break;
4403 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4405 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4407 switch (size) {
4408 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4409 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4410 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4411 default: abort();
4415 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4417 switch (size) {
4418 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4419 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4420 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4421 default: return;
4425 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4426 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4427 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4428 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4429 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4431 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4432 switch ((size << 1) | u) { \
4433 case 0: \
4434 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4435 break; \
4436 case 1: \
4437 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4438 break; \
4439 case 2: \
4440 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4441 break; \
4442 case 3: \
4443 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4444 break; \
4445 case 4: \
4446 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4447 break; \
4448 case 5: \
4449 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4450 break; \
4451 default: return 1; \
4452 }} while (0)
4454 #define GEN_NEON_INTEGER_OP(name) do { \
4455 switch ((size << 1) | u) { \
4456 case 0: \
4457 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4458 break; \
4459 case 1: \
4460 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4461 break; \
4462 case 2: \
4463 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4464 break; \
4465 case 3: \
4466 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4467 break; \
4468 case 4: \
4469 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4470 break; \
4471 case 5: \
4472 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4473 break; \
4474 default: return 1; \
4475 }} while (0)
4477 static TCGv_i32 neon_load_scratch(int scratch)
4479 TCGv_i32 tmp = tcg_temp_new_i32();
4480 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4481 return tmp;
4484 static void neon_store_scratch(int scratch, TCGv_i32 var)
4486 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4487 tcg_temp_free_i32(var);
4490 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4492 TCGv_i32 tmp;
4493 if (size == 1) {
4494 tmp = neon_load_reg(reg & 7, reg >> 4);
4495 if (reg & 8) {
4496 gen_neon_dup_high16(tmp);
4497 } else {
4498 gen_neon_dup_low16(tmp);
4500 } else {
4501 tmp = neon_load_reg(reg & 15, reg >> 4);
4503 return tmp;
4506 static int gen_neon_unzip(int rd, int rm, int size, int q)
4508 TCGv_i32 tmp, tmp2;
4509 if (!q && size == 2) {
4510 return 1;
4512 tmp = tcg_const_i32(rd);
4513 tmp2 = tcg_const_i32(rm);
4514 if (q) {
4515 switch (size) {
4516 case 0:
4517 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4518 break;
4519 case 1:
4520 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4521 break;
4522 case 2:
4523 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4524 break;
4525 default:
4526 abort();
4528 } else {
4529 switch (size) {
4530 case 0:
4531 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4532 break;
4533 case 1:
4534 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4535 break;
4536 default:
4537 abort();
4540 tcg_temp_free_i32(tmp);
4541 tcg_temp_free_i32(tmp2);
4542 return 0;
4545 static int gen_neon_zip(int rd, int rm, int size, int q)
4547 TCGv_i32 tmp, tmp2;
4548 if (!q && size == 2) {
4549 return 1;
4551 tmp = tcg_const_i32(rd);
4552 tmp2 = tcg_const_i32(rm);
4553 if (q) {
4554 switch (size) {
4555 case 0:
4556 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4557 break;
4558 case 1:
4559 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4560 break;
4561 case 2:
4562 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4563 break;
4564 default:
4565 abort();
4567 } else {
4568 switch (size) {
4569 case 0:
4570 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4571 break;
4572 case 1:
4573 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4574 break;
4575 default:
4576 abort();
4579 tcg_temp_free_i32(tmp);
4580 tcg_temp_free_i32(tmp2);
4581 return 0;
4584 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4586 TCGv_i32 rd, tmp;
4588 rd = tcg_temp_new_i32();
4589 tmp = tcg_temp_new_i32();
4591 tcg_gen_shli_i32(rd, t0, 8);
4592 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4593 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4594 tcg_gen_or_i32(rd, rd, tmp);
4596 tcg_gen_shri_i32(t1, t1, 8);
4597 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4598 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4599 tcg_gen_or_i32(t1, t1, tmp);
4600 tcg_gen_mov_i32(t0, rd);
4602 tcg_temp_free_i32(tmp);
4603 tcg_temp_free_i32(rd);
4606 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4608 TCGv_i32 rd, tmp;
4610 rd = tcg_temp_new_i32();
4611 tmp = tcg_temp_new_i32();
4613 tcg_gen_shli_i32(rd, t0, 16);
4614 tcg_gen_andi_i32(tmp, t1, 0xffff);
4615 tcg_gen_or_i32(rd, rd, tmp);
4616 tcg_gen_shri_i32(t1, t1, 16);
4617 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4618 tcg_gen_or_i32(t1, t1, tmp);
4619 tcg_gen_mov_i32(t0, rd);
4621 tcg_temp_free_i32(tmp);
4622 tcg_temp_free_i32(rd);
4626 static struct {
4627 int nregs;
4628 int interleave;
4629 int spacing;
4630 } neon_ls_element_type[11] = {
4631 {4, 4, 1},
4632 {4, 4, 2},
4633 {4, 1, 1},
4634 {4, 2, 1},
4635 {3, 3, 1},
4636 {3, 3, 2},
4637 {3, 1, 1},
4638 {1, 1, 1},
4639 {2, 2, 1},
4640 {2, 2, 2},
4641 {2, 1, 1}
4644 /* Translate a NEON load/store element instruction. Return nonzero if the
4645 instruction is invalid. */
4646 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4648 int rd, rn, rm;
4649 int op;
4650 int nregs;
4651 int interleave;
4652 int spacing;
4653 int stride;
4654 int size;
4655 int reg;
4656 int pass;
4657 int load;
4658 int shift;
4659 int n;
4660 TCGv_i32 addr;
4661 TCGv_i32 tmp;
4662 TCGv_i32 tmp2;
4663 TCGv_i64 tmp64;
4665 /* FIXME: this access check should not take precedence over UNDEF
4666 * for invalid encodings; we will generate incorrect syndrome information
4667 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4669 if (s->fp_excp_el) {
4670 gen_exception_insn(s, 4, EXCP_UDEF,
4671 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4672 return 0;
4675 if (!s->vfp_enabled)
4676 return 1;
4677 VFP_DREG_D(rd, insn);
4678 rn = (insn >> 16) & 0xf;
4679 rm = insn & 0xf;
4680 load = (insn & (1 << 21)) != 0;
4681 if ((insn & (1 << 23)) == 0) {
4682 /* Load store all elements. */
4683 op = (insn >> 8) & 0xf;
4684 size = (insn >> 6) & 3;
4685 if (op > 10)
4686 return 1;
4687 /* Catch UNDEF cases for bad values of align field */
4688 switch (op & 0xc) {
4689 case 4:
4690 if (((insn >> 5) & 1) == 1) {
4691 return 1;
4693 break;
4694 case 8:
4695 if (((insn >> 4) & 3) == 3) {
4696 return 1;
4698 break;
4699 default:
4700 break;
4702 nregs = neon_ls_element_type[op].nregs;
4703 interleave = neon_ls_element_type[op].interleave;
4704 spacing = neon_ls_element_type[op].spacing;
4705 if (size == 3 && (interleave | spacing) != 1)
4706 return 1;
4707 addr = tcg_temp_new_i32();
4708 load_reg_var(s, addr, rn);
4709 stride = (1 << size) * interleave;
4710 for (reg = 0; reg < nregs; reg++) {
4711 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4712 load_reg_var(s, addr, rn);
4713 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4714 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4715 load_reg_var(s, addr, rn);
4716 tcg_gen_addi_i32(addr, addr, 1 << size);
4718 if (size == 3) {
4719 tmp64 = tcg_temp_new_i64();
4720 if (load) {
4721 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4722 neon_store_reg64(tmp64, rd);
4723 } else {
4724 neon_load_reg64(tmp64, rd);
4725 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4727 tcg_temp_free_i64(tmp64);
4728 tcg_gen_addi_i32(addr, addr, stride);
4729 } else {
4730 for (pass = 0; pass < 2; pass++) {
4731 if (size == 2) {
4732 if (load) {
4733 tmp = tcg_temp_new_i32();
4734 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4735 neon_store_reg(rd, pass, tmp);
4736 } else {
4737 tmp = neon_load_reg(rd, pass);
4738 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4739 tcg_temp_free_i32(tmp);
4741 tcg_gen_addi_i32(addr, addr, stride);
4742 } else if (size == 1) {
4743 if (load) {
4744 tmp = tcg_temp_new_i32();
4745 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4746 tcg_gen_addi_i32(addr, addr, stride);
4747 tmp2 = tcg_temp_new_i32();
4748 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4749 tcg_gen_addi_i32(addr, addr, stride);
4750 tcg_gen_shli_i32(tmp2, tmp2, 16);
4751 tcg_gen_or_i32(tmp, tmp, tmp2);
4752 tcg_temp_free_i32(tmp2);
4753 neon_store_reg(rd, pass, tmp);
4754 } else {
4755 tmp = neon_load_reg(rd, pass);
4756 tmp2 = tcg_temp_new_i32();
4757 tcg_gen_shri_i32(tmp2, tmp, 16);
4758 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4759 tcg_temp_free_i32(tmp);
4760 tcg_gen_addi_i32(addr, addr, stride);
4761 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4762 tcg_temp_free_i32(tmp2);
4763 tcg_gen_addi_i32(addr, addr, stride);
4765 } else /* size == 0 */ {
4766 if (load) {
4767 TCGV_UNUSED_I32(tmp2);
4768 for (n = 0; n < 4; n++) {
4769 tmp = tcg_temp_new_i32();
4770 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4771 tcg_gen_addi_i32(addr, addr, stride);
4772 if (n == 0) {
4773 tmp2 = tmp;
4774 } else {
4775 tcg_gen_shli_i32(tmp, tmp, n * 8);
4776 tcg_gen_or_i32(tmp2, tmp2, tmp);
4777 tcg_temp_free_i32(tmp);
4780 neon_store_reg(rd, pass, tmp2);
4781 } else {
4782 tmp2 = neon_load_reg(rd, pass);
4783 for (n = 0; n < 4; n++) {
4784 tmp = tcg_temp_new_i32();
4785 if (n == 0) {
4786 tcg_gen_mov_i32(tmp, tmp2);
4787 } else {
4788 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4790 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4791 tcg_temp_free_i32(tmp);
4792 tcg_gen_addi_i32(addr, addr, stride);
4794 tcg_temp_free_i32(tmp2);
4799 rd += spacing;
4801 tcg_temp_free_i32(addr);
4802 stride = nregs * 8;
4803 } else {
4804 size = (insn >> 10) & 3;
4805 if (size == 3) {
4806 /* Load single element to all lanes. */
4807 int a = (insn >> 4) & 1;
4808 if (!load) {
4809 return 1;
4811 size = (insn >> 6) & 3;
4812 nregs = ((insn >> 8) & 3) + 1;
4814 if (size == 3) {
4815 if (nregs != 4 || a == 0) {
4816 return 1;
4818 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4819 size = 2;
4821 if (nregs == 1 && a == 1 && size == 0) {
4822 return 1;
4824 if (nregs == 3 && a == 1) {
4825 return 1;
4827 addr = tcg_temp_new_i32();
4828 load_reg_var(s, addr, rn);
4829 if (nregs == 1) {
4830 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4831 tmp = gen_load_and_replicate(s, addr, size);
4832 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4833 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4834 if (insn & (1 << 5)) {
4835 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4836 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4838 tcg_temp_free_i32(tmp);
4839 } else {
4840 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4841 stride = (insn & (1 << 5)) ? 2 : 1;
4842 for (reg = 0; reg < nregs; reg++) {
4843 tmp = gen_load_and_replicate(s, addr, size);
4844 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4845 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4846 tcg_temp_free_i32(tmp);
4847 tcg_gen_addi_i32(addr, addr, 1 << size);
4848 rd += stride;
4851 tcg_temp_free_i32(addr);
4852 stride = (1 << size) * nregs;
4853 } else {
4854 /* Single element. */
4855 int idx = (insn >> 4) & 0xf;
4856 pass = (insn >> 7) & 1;
4857 switch (size) {
4858 case 0:
4859 shift = ((insn >> 5) & 3) * 8;
4860 stride = 1;
4861 break;
4862 case 1:
4863 shift = ((insn >> 6) & 1) * 16;
4864 stride = (insn & (1 << 5)) ? 2 : 1;
4865 break;
4866 case 2:
4867 shift = 0;
4868 stride = (insn & (1 << 6)) ? 2 : 1;
4869 break;
4870 default:
4871 abort();
4873 nregs = ((insn >> 8) & 3) + 1;
4874 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4875 switch (nregs) {
4876 case 1:
4877 if (((idx & (1 << size)) != 0) ||
4878 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4879 return 1;
4881 break;
4882 case 3:
4883 if ((idx & 1) != 0) {
4884 return 1;
4886 /* fall through */
4887 case 2:
4888 if (size == 2 && (idx & 2) != 0) {
4889 return 1;
4891 break;
4892 case 4:
4893 if ((size == 2) && ((idx & 3) == 3)) {
4894 return 1;
4896 break;
4897 default:
4898 abort();
4900 if ((rd + stride * (nregs - 1)) > 31) {
4901 /* Attempts to write off the end of the register file
4902 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4903 * the neon_load_reg() would write off the end of the array.
4905 return 1;
4907 addr = tcg_temp_new_i32();
4908 load_reg_var(s, addr, rn);
4909 for (reg = 0; reg < nregs; reg++) {
4910 if (load) {
4911 tmp = tcg_temp_new_i32();
4912 switch (size) {
4913 case 0:
4914 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4915 break;
4916 case 1:
4917 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4918 break;
4919 case 2:
4920 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4921 break;
4922 default: /* Avoid compiler warnings. */
4923 abort();
4925 if (size != 2) {
4926 tmp2 = neon_load_reg(rd, pass);
4927 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4928 shift, size ? 16 : 8);
4929 tcg_temp_free_i32(tmp2);
4931 neon_store_reg(rd, pass, tmp);
4932 } else { /* Store */
4933 tmp = neon_load_reg(rd, pass);
4934 if (shift)
4935 tcg_gen_shri_i32(tmp, tmp, shift);
4936 switch (size) {
4937 case 0:
4938 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4939 break;
4940 case 1:
4941 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4942 break;
4943 case 2:
4944 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4945 break;
4947 tcg_temp_free_i32(tmp);
4949 rd += stride;
4950 tcg_gen_addi_i32(addr, addr, 1 << size);
4952 tcg_temp_free_i32(addr);
4953 stride = nregs * (1 << size);
4956 if (rm != 15) {
4957 TCGv_i32 base;
4959 base = load_reg(s, rn);
4960 if (rm == 13) {
4961 tcg_gen_addi_i32(base, base, stride);
4962 } else {
4963 TCGv_i32 index;
4964 index = load_reg(s, rm);
4965 tcg_gen_add_i32(base, base, index);
4966 tcg_temp_free_i32(index);
4968 store_reg(s, rn, base);
4970 return 0;
4973 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4974 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4976 tcg_gen_and_i32(t, t, c);
4977 tcg_gen_andc_i32(f, f, c);
4978 tcg_gen_or_i32(dest, t, f);
4981 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4983 switch (size) {
4984 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4985 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4986 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4987 default: abort();
4991 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4993 switch (size) {
4994 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4995 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4996 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4997 default: abort();
5001 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5003 switch (size) {
5004 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5005 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5006 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5007 default: abort();
5011 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5013 switch (size) {
5014 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5015 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5016 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5017 default: abort();
5021 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5022 int q, int u)
5024 if (q) {
5025 if (u) {
5026 switch (size) {
5027 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5028 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5029 default: abort();
5031 } else {
5032 switch (size) {
5033 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5034 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5035 default: abort();
5038 } else {
5039 if (u) {
5040 switch (size) {
5041 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5042 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5043 default: abort();
5045 } else {
5046 switch (size) {
5047 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5048 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5049 default: abort();
5055 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5057 if (u) {
5058 switch (size) {
5059 case 0: gen_helper_neon_widen_u8(dest, src); break;
5060 case 1: gen_helper_neon_widen_u16(dest, src); break;
5061 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5062 default: abort();
5064 } else {
5065 switch (size) {
5066 case 0: gen_helper_neon_widen_s8(dest, src); break;
5067 case 1: gen_helper_neon_widen_s16(dest, src); break;
5068 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5069 default: abort();
5072 tcg_temp_free_i32(src);
5075 static inline void gen_neon_addl(int size)
5077 switch (size) {
5078 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5079 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5080 case 2: tcg_gen_add_i64(CPU_V001); break;
5081 default: abort();
5085 static inline void gen_neon_subl(int size)
5087 switch (size) {
5088 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5089 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5090 case 2: tcg_gen_sub_i64(CPU_V001); break;
5091 default: abort();
5095 static inline void gen_neon_negl(TCGv_i64 var, int size)
5097 switch (size) {
5098 case 0: gen_helper_neon_negl_u16(var, var); break;
5099 case 1: gen_helper_neon_negl_u32(var, var); break;
5100 case 2:
5101 tcg_gen_neg_i64(var, var);
5102 break;
5103 default: abort();
5107 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5109 switch (size) {
5110 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5111 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5112 default: abort();
5116 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5117 int size, int u)
5119 TCGv_i64 tmp;
5121 switch ((size << 1) | u) {
5122 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5123 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5124 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5125 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5126 case 4:
5127 tmp = gen_muls_i64_i32(a, b);
5128 tcg_gen_mov_i64(dest, tmp);
5129 tcg_temp_free_i64(tmp);
5130 break;
5131 case 5:
5132 tmp = gen_mulu_i64_i32(a, b);
5133 tcg_gen_mov_i64(dest, tmp);
5134 tcg_temp_free_i64(tmp);
5135 break;
5136 default: abort();
5139 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5140 Don't forget to clean them now. */
5141 if (size < 2) {
5142 tcg_temp_free_i32(a);
5143 tcg_temp_free_i32(b);
5147 static void gen_neon_narrow_op(int op, int u, int size,
5148 TCGv_i32 dest, TCGv_i64 src)
5150 if (op) {
5151 if (u) {
5152 gen_neon_unarrow_sats(size, dest, src);
5153 } else {
5154 gen_neon_narrow(size, dest, src);
5156 } else {
5157 if (u) {
5158 gen_neon_narrow_satu(size, dest, src);
5159 } else {
5160 gen_neon_narrow_sats(size, dest, src);
5165 /* Symbolic constants for op fields for Neon 3-register same-length.
5166 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5167 * table A7-9.
5169 #define NEON_3R_VHADD 0
5170 #define NEON_3R_VQADD 1
5171 #define NEON_3R_VRHADD 2
5172 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5173 #define NEON_3R_VHSUB 4
5174 #define NEON_3R_VQSUB 5
5175 #define NEON_3R_VCGT 6
5176 #define NEON_3R_VCGE 7
5177 #define NEON_3R_VSHL 8
5178 #define NEON_3R_VQSHL 9
5179 #define NEON_3R_VRSHL 10
5180 #define NEON_3R_VQRSHL 11
5181 #define NEON_3R_VMAX 12
5182 #define NEON_3R_VMIN 13
5183 #define NEON_3R_VABD 14
5184 #define NEON_3R_VABA 15
5185 #define NEON_3R_VADD_VSUB 16
5186 #define NEON_3R_VTST_VCEQ 17
5187 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5188 #define NEON_3R_VMUL 19
5189 #define NEON_3R_VPMAX 20
5190 #define NEON_3R_VPMIN 21
5191 #define NEON_3R_VQDMULH_VQRDMULH 22
5192 #define NEON_3R_VPADD 23
5193 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5194 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5195 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5196 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5197 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5198 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5199 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5200 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5202 static const uint8_t neon_3r_sizes[] = {
5203 [NEON_3R_VHADD] = 0x7,
5204 [NEON_3R_VQADD] = 0xf,
5205 [NEON_3R_VRHADD] = 0x7,
5206 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5207 [NEON_3R_VHSUB] = 0x7,
5208 [NEON_3R_VQSUB] = 0xf,
5209 [NEON_3R_VCGT] = 0x7,
5210 [NEON_3R_VCGE] = 0x7,
5211 [NEON_3R_VSHL] = 0xf,
5212 [NEON_3R_VQSHL] = 0xf,
5213 [NEON_3R_VRSHL] = 0xf,
5214 [NEON_3R_VQRSHL] = 0xf,
5215 [NEON_3R_VMAX] = 0x7,
5216 [NEON_3R_VMIN] = 0x7,
5217 [NEON_3R_VABD] = 0x7,
5218 [NEON_3R_VABA] = 0x7,
5219 [NEON_3R_VADD_VSUB] = 0xf,
5220 [NEON_3R_VTST_VCEQ] = 0x7,
5221 [NEON_3R_VML] = 0x7,
5222 [NEON_3R_VMUL] = 0x7,
5223 [NEON_3R_VPMAX] = 0x7,
5224 [NEON_3R_VPMIN] = 0x7,
5225 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5226 [NEON_3R_VPADD] = 0x7,
5227 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5228 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5229 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5230 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5231 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5232 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5233 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5234 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5237 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5238 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5239 * table A7-13.
5241 #define NEON_2RM_VREV64 0
5242 #define NEON_2RM_VREV32 1
5243 #define NEON_2RM_VREV16 2
5244 #define NEON_2RM_VPADDL 4
5245 #define NEON_2RM_VPADDL_U 5
5246 #define NEON_2RM_AESE 6 /* Includes AESD */
5247 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5248 #define NEON_2RM_VCLS 8
5249 #define NEON_2RM_VCLZ 9
5250 #define NEON_2RM_VCNT 10
5251 #define NEON_2RM_VMVN 11
5252 #define NEON_2RM_VPADAL 12
5253 #define NEON_2RM_VPADAL_U 13
5254 #define NEON_2RM_VQABS 14
5255 #define NEON_2RM_VQNEG 15
5256 #define NEON_2RM_VCGT0 16
5257 #define NEON_2RM_VCGE0 17
5258 #define NEON_2RM_VCEQ0 18
5259 #define NEON_2RM_VCLE0 19
5260 #define NEON_2RM_VCLT0 20
5261 #define NEON_2RM_SHA1H 21
5262 #define NEON_2RM_VABS 22
5263 #define NEON_2RM_VNEG 23
5264 #define NEON_2RM_VCGT0_F 24
5265 #define NEON_2RM_VCGE0_F 25
5266 #define NEON_2RM_VCEQ0_F 26
5267 #define NEON_2RM_VCLE0_F 27
5268 #define NEON_2RM_VCLT0_F 28
5269 #define NEON_2RM_VABS_F 30
5270 #define NEON_2RM_VNEG_F 31
5271 #define NEON_2RM_VSWP 32
5272 #define NEON_2RM_VTRN 33
5273 #define NEON_2RM_VUZP 34
5274 #define NEON_2RM_VZIP 35
5275 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5276 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5277 #define NEON_2RM_VSHLL 38
5278 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5279 #define NEON_2RM_VRINTN 40
5280 #define NEON_2RM_VRINTX 41
5281 #define NEON_2RM_VRINTA 42
5282 #define NEON_2RM_VRINTZ 43
5283 #define NEON_2RM_VCVT_F16_F32 44
5284 #define NEON_2RM_VRINTM 45
5285 #define NEON_2RM_VCVT_F32_F16 46
5286 #define NEON_2RM_VRINTP 47
5287 #define NEON_2RM_VCVTAU 48
5288 #define NEON_2RM_VCVTAS 49
5289 #define NEON_2RM_VCVTNU 50
5290 #define NEON_2RM_VCVTNS 51
5291 #define NEON_2RM_VCVTPU 52
5292 #define NEON_2RM_VCVTPS 53
5293 #define NEON_2RM_VCVTMU 54
5294 #define NEON_2RM_VCVTMS 55
5295 #define NEON_2RM_VRECPE 56
5296 #define NEON_2RM_VRSQRTE 57
5297 #define NEON_2RM_VRECPE_F 58
5298 #define NEON_2RM_VRSQRTE_F 59
5299 #define NEON_2RM_VCVT_FS 60
5300 #define NEON_2RM_VCVT_FU 61
5301 #define NEON_2RM_VCVT_SF 62
5302 #define NEON_2RM_VCVT_UF 63
5304 static int neon_2rm_is_float_op(int op)
5306 /* Return true if this neon 2reg-misc op is float-to-float */
5307 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5308 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5309 op == NEON_2RM_VRINTM ||
5310 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5311 op >= NEON_2RM_VRECPE_F);
5314 static bool neon_2rm_is_v8_op(int op)
5316 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5317 switch (op) {
5318 case NEON_2RM_VRINTN:
5319 case NEON_2RM_VRINTA:
5320 case NEON_2RM_VRINTM:
5321 case NEON_2RM_VRINTP:
5322 case NEON_2RM_VRINTZ:
5323 case NEON_2RM_VRINTX:
5324 case NEON_2RM_VCVTAU:
5325 case NEON_2RM_VCVTAS:
5326 case NEON_2RM_VCVTNU:
5327 case NEON_2RM_VCVTNS:
5328 case NEON_2RM_VCVTPU:
5329 case NEON_2RM_VCVTPS:
5330 case NEON_2RM_VCVTMU:
5331 case NEON_2RM_VCVTMS:
5332 return true;
5333 default:
5334 return false;
5338 /* Each entry in this array has bit n set if the insn allows
5339 * size value n (otherwise it will UNDEF). Since unallocated
5340 * op values will have no bits set they always UNDEF.
5342 static const uint8_t neon_2rm_sizes[] = {
5343 [NEON_2RM_VREV64] = 0x7,
5344 [NEON_2RM_VREV32] = 0x3,
5345 [NEON_2RM_VREV16] = 0x1,
5346 [NEON_2RM_VPADDL] = 0x7,
5347 [NEON_2RM_VPADDL_U] = 0x7,
5348 [NEON_2RM_AESE] = 0x1,
5349 [NEON_2RM_AESMC] = 0x1,
5350 [NEON_2RM_VCLS] = 0x7,
5351 [NEON_2RM_VCLZ] = 0x7,
5352 [NEON_2RM_VCNT] = 0x1,
5353 [NEON_2RM_VMVN] = 0x1,
5354 [NEON_2RM_VPADAL] = 0x7,
5355 [NEON_2RM_VPADAL_U] = 0x7,
5356 [NEON_2RM_VQABS] = 0x7,
5357 [NEON_2RM_VQNEG] = 0x7,
5358 [NEON_2RM_VCGT0] = 0x7,
5359 [NEON_2RM_VCGE0] = 0x7,
5360 [NEON_2RM_VCEQ0] = 0x7,
5361 [NEON_2RM_VCLE0] = 0x7,
5362 [NEON_2RM_VCLT0] = 0x7,
5363 [NEON_2RM_SHA1H] = 0x4,
5364 [NEON_2RM_VABS] = 0x7,
5365 [NEON_2RM_VNEG] = 0x7,
5366 [NEON_2RM_VCGT0_F] = 0x4,
5367 [NEON_2RM_VCGE0_F] = 0x4,
5368 [NEON_2RM_VCEQ0_F] = 0x4,
5369 [NEON_2RM_VCLE0_F] = 0x4,
5370 [NEON_2RM_VCLT0_F] = 0x4,
5371 [NEON_2RM_VABS_F] = 0x4,
5372 [NEON_2RM_VNEG_F] = 0x4,
5373 [NEON_2RM_VSWP] = 0x1,
5374 [NEON_2RM_VTRN] = 0x7,
5375 [NEON_2RM_VUZP] = 0x7,
5376 [NEON_2RM_VZIP] = 0x7,
5377 [NEON_2RM_VMOVN] = 0x7,
5378 [NEON_2RM_VQMOVN] = 0x7,
5379 [NEON_2RM_VSHLL] = 0x7,
5380 [NEON_2RM_SHA1SU1] = 0x4,
5381 [NEON_2RM_VRINTN] = 0x4,
5382 [NEON_2RM_VRINTX] = 0x4,
5383 [NEON_2RM_VRINTA] = 0x4,
5384 [NEON_2RM_VRINTZ] = 0x4,
5385 [NEON_2RM_VCVT_F16_F32] = 0x2,
5386 [NEON_2RM_VRINTM] = 0x4,
5387 [NEON_2RM_VCVT_F32_F16] = 0x2,
5388 [NEON_2RM_VRINTP] = 0x4,
5389 [NEON_2RM_VCVTAU] = 0x4,
5390 [NEON_2RM_VCVTAS] = 0x4,
5391 [NEON_2RM_VCVTNU] = 0x4,
5392 [NEON_2RM_VCVTNS] = 0x4,
5393 [NEON_2RM_VCVTPU] = 0x4,
5394 [NEON_2RM_VCVTPS] = 0x4,
5395 [NEON_2RM_VCVTMU] = 0x4,
5396 [NEON_2RM_VCVTMS] = 0x4,
5397 [NEON_2RM_VRECPE] = 0x4,
5398 [NEON_2RM_VRSQRTE] = 0x4,
5399 [NEON_2RM_VRECPE_F] = 0x4,
5400 [NEON_2RM_VRSQRTE_F] = 0x4,
5401 [NEON_2RM_VCVT_FS] = 0x4,
5402 [NEON_2RM_VCVT_FU] = 0x4,
5403 [NEON_2RM_VCVT_SF] = 0x4,
5404 [NEON_2RM_VCVT_UF] = 0x4,
5407 /* Translate a NEON data processing instruction. Return nonzero if the
5408 instruction is invalid.
5409 We process data in a mixture of 32-bit and 64-bit chunks.
5410 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5412 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5414 int op;
5415 int q;
5416 int rd, rn, rm;
5417 int size;
5418 int shift;
5419 int pass;
5420 int count;
5421 int pairwise;
5422 int u;
5423 uint32_t imm, mask;
5424 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5425 TCGv_i64 tmp64;
5427 /* FIXME: this access check should not take precedence over UNDEF
5428 * for invalid encodings; we will generate incorrect syndrome information
5429 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5431 if (s->fp_excp_el) {
5432 gen_exception_insn(s, 4, EXCP_UDEF,
5433 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5434 return 0;
5437 if (!s->vfp_enabled)
5438 return 1;
5439 q = (insn & (1 << 6)) != 0;
5440 u = (insn >> 24) & 1;
5441 VFP_DREG_D(rd, insn);
5442 VFP_DREG_N(rn, insn);
5443 VFP_DREG_M(rm, insn);
5444 size = (insn >> 20) & 3;
5445 if ((insn & (1 << 23)) == 0) {
5446 /* Three register same length. */
5447 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5448 /* Catch invalid op and bad size combinations: UNDEF */
5449 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5450 return 1;
5452 /* All insns of this form UNDEF for either this condition or the
5453 * superset of cases "Q==1"; we catch the latter later.
5455 if (q && ((rd | rn | rm) & 1)) {
5456 return 1;
5459 * The SHA-1/SHA-256 3-register instructions require special treatment
5460 * here, as their size field is overloaded as an op type selector, and
5461 * they all consume their input in a single pass.
5463 if (op == NEON_3R_SHA) {
5464 if (!q) {
5465 return 1;
5467 if (!u) { /* SHA-1 */
5468 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5469 return 1;
5471 tmp = tcg_const_i32(rd);
5472 tmp2 = tcg_const_i32(rn);
5473 tmp3 = tcg_const_i32(rm);
5474 tmp4 = tcg_const_i32(size);
5475 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5476 tcg_temp_free_i32(tmp4);
5477 } else { /* SHA-256 */
5478 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5479 return 1;
5481 tmp = tcg_const_i32(rd);
5482 tmp2 = tcg_const_i32(rn);
5483 tmp3 = tcg_const_i32(rm);
5484 switch (size) {
5485 case 0:
5486 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5487 break;
5488 case 1:
5489 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5490 break;
5491 case 2:
5492 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5493 break;
5496 tcg_temp_free_i32(tmp);
5497 tcg_temp_free_i32(tmp2);
5498 tcg_temp_free_i32(tmp3);
5499 return 0;
5501 if (size == 3 && op != NEON_3R_LOGIC) {
5502 /* 64-bit element instructions. */
5503 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5504 neon_load_reg64(cpu_V0, rn + pass);
5505 neon_load_reg64(cpu_V1, rm + pass);
5506 switch (op) {
5507 case NEON_3R_VQADD:
5508 if (u) {
5509 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5510 cpu_V0, cpu_V1);
5511 } else {
5512 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5513 cpu_V0, cpu_V1);
5515 break;
5516 case NEON_3R_VQSUB:
5517 if (u) {
5518 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5519 cpu_V0, cpu_V1);
5520 } else {
5521 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5522 cpu_V0, cpu_V1);
5524 break;
5525 case NEON_3R_VSHL:
5526 if (u) {
5527 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5528 } else {
5529 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5531 break;
5532 case NEON_3R_VQSHL:
5533 if (u) {
5534 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5535 cpu_V1, cpu_V0);
5536 } else {
5537 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5538 cpu_V1, cpu_V0);
5540 break;
5541 case NEON_3R_VRSHL:
5542 if (u) {
5543 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5544 } else {
5545 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5547 break;
5548 case NEON_3R_VQRSHL:
5549 if (u) {
5550 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5551 cpu_V1, cpu_V0);
5552 } else {
5553 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5554 cpu_V1, cpu_V0);
5556 break;
5557 case NEON_3R_VADD_VSUB:
5558 if (u) {
5559 tcg_gen_sub_i64(CPU_V001);
5560 } else {
5561 tcg_gen_add_i64(CPU_V001);
5563 break;
5564 default:
5565 abort();
5567 neon_store_reg64(cpu_V0, rd + pass);
5569 return 0;
5571 pairwise = 0;
5572 switch (op) {
5573 case NEON_3R_VSHL:
5574 case NEON_3R_VQSHL:
5575 case NEON_3R_VRSHL:
5576 case NEON_3R_VQRSHL:
5578 int rtmp;
5579 /* Shift instruction operands are reversed. */
5580 rtmp = rn;
5581 rn = rm;
5582 rm = rtmp;
5584 break;
5585 case NEON_3R_VPADD:
5586 if (u) {
5587 return 1;
5589 /* Fall through */
5590 case NEON_3R_VPMAX:
5591 case NEON_3R_VPMIN:
5592 pairwise = 1;
5593 break;
5594 case NEON_3R_FLOAT_ARITH:
5595 pairwise = (u && size < 2); /* if VPADD (float) */
5596 break;
5597 case NEON_3R_FLOAT_MINMAX:
5598 pairwise = u; /* if VPMIN/VPMAX (float) */
5599 break;
5600 case NEON_3R_FLOAT_CMP:
5601 if (!u && size) {
5602 /* no encoding for U=0 C=1x */
5603 return 1;
5605 break;
5606 case NEON_3R_FLOAT_ACMP:
5607 if (!u) {
5608 return 1;
5610 break;
5611 case NEON_3R_FLOAT_MISC:
5612 /* VMAXNM/VMINNM in ARMv8 */
5613 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5614 return 1;
5616 break;
5617 case NEON_3R_VMUL:
5618 if (u && (size != 0)) {
5619 /* UNDEF on invalid size for polynomial subcase */
5620 return 1;
5622 break;
5623 case NEON_3R_VFM:
5624 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5625 return 1;
5627 break;
5628 default:
5629 break;
5632 if (pairwise && q) {
5633 /* All the pairwise insns UNDEF if Q is set */
5634 return 1;
5637 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5639 if (pairwise) {
5640 /* Pairwise. */
5641 if (pass < 1) {
5642 tmp = neon_load_reg(rn, 0);
5643 tmp2 = neon_load_reg(rn, 1);
5644 } else {
5645 tmp = neon_load_reg(rm, 0);
5646 tmp2 = neon_load_reg(rm, 1);
5648 } else {
5649 /* Elementwise. */
5650 tmp = neon_load_reg(rn, pass);
5651 tmp2 = neon_load_reg(rm, pass);
5653 switch (op) {
5654 case NEON_3R_VHADD:
5655 GEN_NEON_INTEGER_OP(hadd);
5656 break;
5657 case NEON_3R_VQADD:
5658 GEN_NEON_INTEGER_OP_ENV(qadd);
5659 break;
5660 case NEON_3R_VRHADD:
5661 GEN_NEON_INTEGER_OP(rhadd);
5662 break;
5663 case NEON_3R_LOGIC: /* Logic ops. */
5664 switch ((u << 2) | size) {
5665 case 0: /* VAND */
5666 tcg_gen_and_i32(tmp, tmp, tmp2);
5667 break;
5668 case 1: /* BIC */
5669 tcg_gen_andc_i32(tmp, tmp, tmp2);
5670 break;
5671 case 2: /* VORR */
5672 tcg_gen_or_i32(tmp, tmp, tmp2);
5673 break;
5674 case 3: /* VORN */
5675 tcg_gen_orc_i32(tmp, tmp, tmp2);
5676 break;
5677 case 4: /* VEOR */
5678 tcg_gen_xor_i32(tmp, tmp, tmp2);
5679 break;
5680 case 5: /* VBSL */
5681 tmp3 = neon_load_reg(rd, pass);
5682 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5683 tcg_temp_free_i32(tmp3);
5684 break;
5685 case 6: /* VBIT */
5686 tmp3 = neon_load_reg(rd, pass);
5687 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5688 tcg_temp_free_i32(tmp3);
5689 break;
5690 case 7: /* VBIF */
5691 tmp3 = neon_load_reg(rd, pass);
5692 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5693 tcg_temp_free_i32(tmp3);
5694 break;
5696 break;
5697 case NEON_3R_VHSUB:
5698 GEN_NEON_INTEGER_OP(hsub);
5699 break;
5700 case NEON_3R_VQSUB:
5701 GEN_NEON_INTEGER_OP_ENV(qsub);
5702 break;
5703 case NEON_3R_VCGT:
5704 GEN_NEON_INTEGER_OP(cgt);
5705 break;
5706 case NEON_3R_VCGE:
5707 GEN_NEON_INTEGER_OP(cge);
5708 break;
5709 case NEON_3R_VSHL:
5710 GEN_NEON_INTEGER_OP(shl);
5711 break;
5712 case NEON_3R_VQSHL:
5713 GEN_NEON_INTEGER_OP_ENV(qshl);
5714 break;
5715 case NEON_3R_VRSHL:
5716 GEN_NEON_INTEGER_OP(rshl);
5717 break;
5718 case NEON_3R_VQRSHL:
5719 GEN_NEON_INTEGER_OP_ENV(qrshl);
5720 break;
5721 case NEON_3R_VMAX:
5722 GEN_NEON_INTEGER_OP(max);
5723 break;
5724 case NEON_3R_VMIN:
5725 GEN_NEON_INTEGER_OP(min);
5726 break;
5727 case NEON_3R_VABD:
5728 GEN_NEON_INTEGER_OP(abd);
5729 break;
5730 case NEON_3R_VABA:
5731 GEN_NEON_INTEGER_OP(abd);
5732 tcg_temp_free_i32(tmp2);
5733 tmp2 = neon_load_reg(rd, pass);
5734 gen_neon_add(size, tmp, tmp2);
5735 break;
5736 case NEON_3R_VADD_VSUB:
5737 if (!u) { /* VADD */
5738 gen_neon_add(size, tmp, tmp2);
5739 } else { /* VSUB */
5740 switch (size) {
5741 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5742 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5743 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5744 default: abort();
5747 break;
5748 case NEON_3R_VTST_VCEQ:
5749 if (!u) { /* VTST */
5750 switch (size) {
5751 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5752 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5753 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5754 default: abort();
5756 } else { /* VCEQ */
5757 switch (size) {
5758 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5759 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5760 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5761 default: abort();
5764 break;
5765 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5766 switch (size) {
5767 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5768 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5769 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5770 default: abort();
5772 tcg_temp_free_i32(tmp2);
5773 tmp2 = neon_load_reg(rd, pass);
5774 if (u) { /* VMLS */
5775 gen_neon_rsb(size, tmp, tmp2);
5776 } else { /* VMLA */
5777 gen_neon_add(size, tmp, tmp2);
5779 break;
5780 case NEON_3R_VMUL:
5781 if (u) { /* polynomial */
5782 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5783 } else { /* Integer */
5784 switch (size) {
5785 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5786 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5787 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5788 default: abort();
5791 break;
5792 case NEON_3R_VPMAX:
5793 GEN_NEON_INTEGER_OP(pmax);
5794 break;
5795 case NEON_3R_VPMIN:
5796 GEN_NEON_INTEGER_OP(pmin);
5797 break;
5798 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5799 if (!u) { /* VQDMULH */
5800 switch (size) {
5801 case 1:
5802 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5803 break;
5804 case 2:
5805 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5806 break;
5807 default: abort();
5809 } else { /* VQRDMULH */
5810 switch (size) {
5811 case 1:
5812 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5813 break;
5814 case 2:
5815 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5816 break;
5817 default: abort();
5820 break;
5821 case NEON_3R_VPADD:
5822 switch (size) {
5823 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5824 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5825 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5826 default: abort();
5828 break;
5829 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5831 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5832 switch ((u << 2) | size) {
5833 case 0: /* VADD */
5834 case 4: /* VPADD */
5835 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5836 break;
5837 case 2: /* VSUB */
5838 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5839 break;
5840 case 6: /* VABD */
5841 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5842 break;
5843 default:
5844 abort();
5846 tcg_temp_free_ptr(fpstatus);
5847 break;
5849 case NEON_3R_FLOAT_MULTIPLY:
5851 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5852 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5853 if (!u) {
5854 tcg_temp_free_i32(tmp2);
5855 tmp2 = neon_load_reg(rd, pass);
5856 if (size == 0) {
5857 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5858 } else {
5859 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5862 tcg_temp_free_ptr(fpstatus);
5863 break;
5865 case NEON_3R_FLOAT_CMP:
5867 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5868 if (!u) {
5869 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5870 } else {
5871 if (size == 0) {
5872 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5873 } else {
5874 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5877 tcg_temp_free_ptr(fpstatus);
5878 break;
5880 case NEON_3R_FLOAT_ACMP:
5882 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5883 if (size == 0) {
5884 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5885 } else {
5886 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5888 tcg_temp_free_ptr(fpstatus);
5889 break;
5891 case NEON_3R_FLOAT_MINMAX:
5893 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5894 if (size == 0) {
5895 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5896 } else {
5897 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5899 tcg_temp_free_ptr(fpstatus);
5900 break;
5902 case NEON_3R_FLOAT_MISC:
5903 if (u) {
5904 /* VMAXNM/VMINNM */
5905 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5906 if (size == 0) {
5907 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5908 } else {
5909 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5911 tcg_temp_free_ptr(fpstatus);
5912 } else {
5913 if (size == 0) {
5914 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5915 } else {
5916 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5919 break;
5920 case NEON_3R_VFM:
5922 /* VFMA, VFMS: fused multiply-add */
5923 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5924 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5925 if (size) {
5926 /* VFMS */
5927 gen_helper_vfp_negs(tmp, tmp);
5929 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5930 tcg_temp_free_i32(tmp3);
5931 tcg_temp_free_ptr(fpstatus);
5932 break;
5934 default:
5935 abort();
5937 tcg_temp_free_i32(tmp2);
5939 /* Save the result. For elementwise operations we can put it
5940 straight into the destination register. For pairwise operations
5941 we have to be careful to avoid clobbering the source operands. */
5942 if (pairwise && rd == rm) {
5943 neon_store_scratch(pass, tmp);
5944 } else {
5945 neon_store_reg(rd, pass, tmp);
5948 } /* for pass */
5949 if (pairwise && rd == rm) {
5950 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5951 tmp = neon_load_scratch(pass);
5952 neon_store_reg(rd, pass, tmp);
5955 /* End of 3 register same size operations. */
5956 } else if (insn & (1 << 4)) {
5957 if ((insn & 0x00380080) != 0) {
5958 /* Two registers and shift. */
5959 op = (insn >> 8) & 0xf;
5960 if (insn & (1 << 7)) {
5961 /* 64-bit shift. */
5962 if (op > 7) {
5963 return 1;
5965 size = 3;
5966 } else {
5967 size = 2;
5968 while ((insn & (1 << (size + 19))) == 0)
5969 size--;
5971 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5972 /* To avoid excessive duplication of ops we implement shift
5973 by immediate using the variable shift operations. */
5974 if (op < 8) {
5975 /* Shift by immediate:
5976 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5977 if (q && ((rd | rm) & 1)) {
5978 return 1;
5980 if (!u && (op == 4 || op == 6)) {
5981 return 1;
5983 /* Right shifts are encoded as N - shift, where N is the
5984 element size in bits. */
5985 if (op <= 4)
5986 shift = shift - (1 << (size + 3));
5987 if (size == 3) {
5988 count = q + 1;
5989 } else {
5990 count = q ? 4: 2;
5992 switch (size) {
5993 case 0:
5994 imm = (uint8_t) shift;
5995 imm |= imm << 8;
5996 imm |= imm << 16;
5997 break;
5998 case 1:
5999 imm = (uint16_t) shift;
6000 imm |= imm << 16;
6001 break;
6002 case 2:
6003 case 3:
6004 imm = shift;
6005 break;
6006 default:
6007 abort();
6010 for (pass = 0; pass < count; pass++) {
6011 if (size == 3) {
6012 neon_load_reg64(cpu_V0, rm + pass);
6013 tcg_gen_movi_i64(cpu_V1, imm);
6014 switch (op) {
6015 case 0: /* VSHR */
6016 case 1: /* VSRA */
6017 if (u)
6018 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6019 else
6020 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6021 break;
6022 case 2: /* VRSHR */
6023 case 3: /* VRSRA */
6024 if (u)
6025 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6026 else
6027 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6028 break;
6029 case 4: /* VSRI */
6030 case 5: /* VSHL, VSLI */
6031 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6032 break;
6033 case 6: /* VQSHLU */
6034 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6035 cpu_V0, cpu_V1);
6036 break;
6037 case 7: /* VQSHL */
6038 if (u) {
6039 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6040 cpu_V0, cpu_V1);
6041 } else {
6042 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6043 cpu_V0, cpu_V1);
6045 break;
6047 if (op == 1 || op == 3) {
6048 /* Accumulate. */
6049 neon_load_reg64(cpu_V1, rd + pass);
6050 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6051 } else if (op == 4 || (op == 5 && u)) {
6052 /* Insert */
6053 neon_load_reg64(cpu_V1, rd + pass);
6054 uint64_t mask;
6055 if (shift < -63 || shift > 63) {
6056 mask = 0;
6057 } else {
6058 if (op == 4) {
6059 mask = 0xffffffffffffffffull >> -shift;
6060 } else {
6061 mask = 0xffffffffffffffffull << shift;
6064 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6065 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6067 neon_store_reg64(cpu_V0, rd + pass);
6068 } else { /* size < 3 */
6069 /* Operands in T0 and T1. */
6070 tmp = neon_load_reg(rm, pass);
6071 tmp2 = tcg_temp_new_i32();
6072 tcg_gen_movi_i32(tmp2, imm);
6073 switch (op) {
6074 case 0: /* VSHR */
6075 case 1: /* VSRA */
6076 GEN_NEON_INTEGER_OP(shl);
6077 break;
6078 case 2: /* VRSHR */
6079 case 3: /* VRSRA */
6080 GEN_NEON_INTEGER_OP(rshl);
6081 break;
6082 case 4: /* VSRI */
6083 case 5: /* VSHL, VSLI */
6084 switch (size) {
6085 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6086 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6087 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6088 default: abort();
6090 break;
6091 case 6: /* VQSHLU */
6092 switch (size) {
6093 case 0:
6094 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6095 tmp, tmp2);
6096 break;
6097 case 1:
6098 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6099 tmp, tmp2);
6100 break;
6101 case 2:
6102 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6103 tmp, tmp2);
6104 break;
6105 default:
6106 abort();
6108 break;
6109 case 7: /* VQSHL */
6110 GEN_NEON_INTEGER_OP_ENV(qshl);
6111 break;
6113 tcg_temp_free_i32(tmp2);
6115 if (op == 1 || op == 3) {
6116 /* Accumulate. */
6117 tmp2 = neon_load_reg(rd, pass);
6118 gen_neon_add(size, tmp, tmp2);
6119 tcg_temp_free_i32(tmp2);
6120 } else if (op == 4 || (op == 5 && u)) {
6121 /* Insert */
6122 switch (size) {
6123 case 0:
6124 if (op == 4)
6125 mask = 0xff >> -shift;
6126 else
6127 mask = (uint8_t)(0xff << shift);
6128 mask |= mask << 8;
6129 mask |= mask << 16;
6130 break;
6131 case 1:
6132 if (op == 4)
6133 mask = 0xffff >> -shift;
6134 else
6135 mask = (uint16_t)(0xffff << shift);
6136 mask |= mask << 16;
6137 break;
6138 case 2:
6139 if (shift < -31 || shift > 31) {
6140 mask = 0;
6141 } else {
6142 if (op == 4)
6143 mask = 0xffffffffu >> -shift;
6144 else
6145 mask = 0xffffffffu << shift;
6147 break;
6148 default:
6149 abort();
6151 tmp2 = neon_load_reg(rd, pass);
6152 tcg_gen_andi_i32(tmp, tmp, mask);
6153 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6154 tcg_gen_or_i32(tmp, tmp, tmp2);
6155 tcg_temp_free_i32(tmp2);
6157 neon_store_reg(rd, pass, tmp);
6159 } /* for pass */
6160 } else if (op < 10) {
6161 /* Shift by immediate and narrow:
6162 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6163 int input_unsigned = (op == 8) ? !u : u;
6164 if (rm & 1) {
6165 return 1;
6167 shift = shift - (1 << (size + 3));
6168 size++;
6169 if (size == 3) {
6170 tmp64 = tcg_const_i64(shift);
6171 neon_load_reg64(cpu_V0, rm);
6172 neon_load_reg64(cpu_V1, rm + 1);
6173 for (pass = 0; pass < 2; pass++) {
6174 TCGv_i64 in;
6175 if (pass == 0) {
6176 in = cpu_V0;
6177 } else {
6178 in = cpu_V1;
6180 if (q) {
6181 if (input_unsigned) {
6182 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6183 } else {
6184 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6186 } else {
6187 if (input_unsigned) {
6188 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6189 } else {
6190 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6193 tmp = tcg_temp_new_i32();
6194 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6195 neon_store_reg(rd, pass, tmp);
6196 } /* for pass */
6197 tcg_temp_free_i64(tmp64);
6198 } else {
6199 if (size == 1) {
6200 imm = (uint16_t)shift;
6201 imm |= imm << 16;
6202 } else {
6203 /* size == 2 */
6204 imm = (uint32_t)shift;
6206 tmp2 = tcg_const_i32(imm);
6207 tmp4 = neon_load_reg(rm + 1, 0);
6208 tmp5 = neon_load_reg(rm + 1, 1);
6209 for (pass = 0; pass < 2; pass++) {
6210 if (pass == 0) {
6211 tmp = neon_load_reg(rm, 0);
6212 } else {
6213 tmp = tmp4;
6215 gen_neon_shift_narrow(size, tmp, tmp2, q,
6216 input_unsigned);
6217 if (pass == 0) {
6218 tmp3 = neon_load_reg(rm, 1);
6219 } else {
6220 tmp3 = tmp5;
6222 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6223 input_unsigned);
6224 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6225 tcg_temp_free_i32(tmp);
6226 tcg_temp_free_i32(tmp3);
6227 tmp = tcg_temp_new_i32();
6228 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6229 neon_store_reg(rd, pass, tmp);
6230 } /* for pass */
6231 tcg_temp_free_i32(tmp2);
6233 } else if (op == 10) {
6234 /* VSHLL, VMOVL */
6235 if (q || (rd & 1)) {
6236 return 1;
6238 tmp = neon_load_reg(rm, 0);
6239 tmp2 = neon_load_reg(rm, 1);
6240 for (pass = 0; pass < 2; pass++) {
6241 if (pass == 1)
6242 tmp = tmp2;
6244 gen_neon_widen(cpu_V0, tmp, size, u);
6246 if (shift != 0) {
6247 /* The shift is less than the width of the source
6248 type, so we can just shift the whole register. */
6249 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6250 /* Widen the result of shift: we need to clear
6251 * the potential overflow bits resulting from
6252 * left bits of the narrow input appearing as
6253 * right bits of left the neighbour narrow
6254 * input. */
6255 if (size < 2 || !u) {
6256 uint64_t imm64;
6257 if (size == 0) {
6258 imm = (0xffu >> (8 - shift));
6259 imm |= imm << 16;
6260 } else if (size == 1) {
6261 imm = 0xffff >> (16 - shift);
6262 } else {
6263 /* size == 2 */
6264 imm = 0xffffffff >> (32 - shift);
6266 if (size < 2) {
6267 imm64 = imm | (((uint64_t)imm) << 32);
6268 } else {
6269 imm64 = imm;
6271 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6274 neon_store_reg64(cpu_V0, rd + pass);
6276 } else if (op >= 14) {
6277 /* VCVT fixed-point. */
6278 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6279 return 1;
6281 /* We have already masked out the must-be-1 top bit of imm6,
6282 * hence this 32-shift where the ARM ARM has 64-imm6.
6284 shift = 32 - shift;
6285 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6286 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6287 if (!(op & 1)) {
6288 if (u)
6289 gen_vfp_ulto(0, shift, 1);
6290 else
6291 gen_vfp_slto(0, shift, 1);
6292 } else {
6293 if (u)
6294 gen_vfp_toul(0, shift, 1);
6295 else
6296 gen_vfp_tosl(0, shift, 1);
6298 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6300 } else {
6301 return 1;
6303 } else { /* (insn & 0x00380080) == 0 */
6304 int invert;
6305 if (q && (rd & 1)) {
6306 return 1;
6309 op = (insn >> 8) & 0xf;
6310 /* One register and immediate. */
6311 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6312 invert = (insn & (1 << 5)) != 0;
6313 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6314 * We choose to not special-case this and will behave as if a
6315 * valid constant encoding of 0 had been given.
6317 switch (op) {
6318 case 0: case 1:
6319 /* no-op */
6320 break;
6321 case 2: case 3:
6322 imm <<= 8;
6323 break;
6324 case 4: case 5:
6325 imm <<= 16;
6326 break;
6327 case 6: case 7:
6328 imm <<= 24;
6329 break;
6330 case 8: case 9:
6331 imm |= imm << 16;
6332 break;
6333 case 10: case 11:
6334 imm = (imm << 8) | (imm << 24);
6335 break;
6336 case 12:
6337 imm = (imm << 8) | 0xff;
6338 break;
6339 case 13:
6340 imm = (imm << 16) | 0xffff;
6341 break;
6342 case 14:
6343 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6344 if (invert)
6345 imm = ~imm;
6346 break;
6347 case 15:
6348 if (invert) {
6349 return 1;
6351 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6352 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6353 break;
6355 if (invert)
6356 imm = ~imm;
6358 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6359 if (op & 1 && op < 12) {
6360 tmp = neon_load_reg(rd, pass);
6361 if (invert) {
6362 /* The immediate value has already been inverted, so
6363 BIC becomes AND. */
6364 tcg_gen_andi_i32(tmp, tmp, imm);
6365 } else {
6366 tcg_gen_ori_i32(tmp, tmp, imm);
6368 } else {
6369 /* VMOV, VMVN. */
6370 tmp = tcg_temp_new_i32();
6371 if (op == 14 && invert) {
6372 int n;
6373 uint32_t val;
6374 val = 0;
6375 for (n = 0; n < 4; n++) {
6376 if (imm & (1 << (n + (pass & 1) * 4)))
6377 val |= 0xff << (n * 8);
6379 tcg_gen_movi_i32(tmp, val);
6380 } else {
6381 tcg_gen_movi_i32(tmp, imm);
6384 neon_store_reg(rd, pass, tmp);
6387 } else { /* (insn & 0x00800010 == 0x00800000) */
6388 if (size != 3) {
6389 op = (insn >> 8) & 0xf;
6390 if ((insn & (1 << 6)) == 0) {
6391 /* Three registers of different lengths. */
6392 int src1_wide;
6393 int src2_wide;
6394 int prewiden;
6395 /* undefreq: bit 0 : UNDEF if size == 0
6396 * bit 1 : UNDEF if size == 1
6397 * bit 2 : UNDEF if size == 2
6398 * bit 3 : UNDEF if U == 1
6399 * Note that [2:0] set implies 'always UNDEF'
6401 int undefreq;
6402 /* prewiden, src1_wide, src2_wide, undefreq */
6403 static const int neon_3reg_wide[16][4] = {
6404 {1, 0, 0, 0}, /* VADDL */
6405 {1, 1, 0, 0}, /* VADDW */
6406 {1, 0, 0, 0}, /* VSUBL */
6407 {1, 1, 0, 0}, /* VSUBW */
6408 {0, 1, 1, 0}, /* VADDHN */
6409 {0, 0, 0, 0}, /* VABAL */
6410 {0, 1, 1, 0}, /* VSUBHN */
6411 {0, 0, 0, 0}, /* VABDL */
6412 {0, 0, 0, 0}, /* VMLAL */
6413 {0, 0, 0, 9}, /* VQDMLAL */
6414 {0, 0, 0, 0}, /* VMLSL */
6415 {0, 0, 0, 9}, /* VQDMLSL */
6416 {0, 0, 0, 0}, /* Integer VMULL */
6417 {0, 0, 0, 1}, /* VQDMULL */
6418 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6419 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6422 prewiden = neon_3reg_wide[op][0];
6423 src1_wide = neon_3reg_wide[op][1];
6424 src2_wide = neon_3reg_wide[op][2];
6425 undefreq = neon_3reg_wide[op][3];
6427 if ((undefreq & (1 << size)) ||
6428 ((undefreq & 8) && u)) {
6429 return 1;
6431 if ((src1_wide && (rn & 1)) ||
6432 (src2_wide && (rm & 1)) ||
6433 (!src2_wide && (rd & 1))) {
6434 return 1;
6437 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6438 * outside the loop below as it only performs a single pass.
6440 if (op == 14 && size == 2) {
6441 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6443 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6444 return 1;
6446 tcg_rn = tcg_temp_new_i64();
6447 tcg_rm = tcg_temp_new_i64();
6448 tcg_rd = tcg_temp_new_i64();
6449 neon_load_reg64(tcg_rn, rn);
6450 neon_load_reg64(tcg_rm, rm);
6451 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6452 neon_store_reg64(tcg_rd, rd);
6453 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6454 neon_store_reg64(tcg_rd, rd + 1);
6455 tcg_temp_free_i64(tcg_rn);
6456 tcg_temp_free_i64(tcg_rm);
6457 tcg_temp_free_i64(tcg_rd);
6458 return 0;
6461 /* Avoid overlapping operands. Wide source operands are
6462 always aligned so will never overlap with wide
6463 destinations in problematic ways. */
6464 if (rd == rm && !src2_wide) {
6465 tmp = neon_load_reg(rm, 1);
6466 neon_store_scratch(2, tmp);
6467 } else if (rd == rn && !src1_wide) {
6468 tmp = neon_load_reg(rn, 1);
6469 neon_store_scratch(2, tmp);
6471 TCGV_UNUSED_I32(tmp3);
6472 for (pass = 0; pass < 2; pass++) {
6473 if (src1_wide) {
6474 neon_load_reg64(cpu_V0, rn + pass);
6475 TCGV_UNUSED_I32(tmp);
6476 } else {
6477 if (pass == 1 && rd == rn) {
6478 tmp = neon_load_scratch(2);
6479 } else {
6480 tmp = neon_load_reg(rn, pass);
6482 if (prewiden) {
6483 gen_neon_widen(cpu_V0, tmp, size, u);
6486 if (src2_wide) {
6487 neon_load_reg64(cpu_V1, rm + pass);
6488 TCGV_UNUSED_I32(tmp2);
6489 } else {
6490 if (pass == 1 && rd == rm) {
6491 tmp2 = neon_load_scratch(2);
6492 } else {
6493 tmp2 = neon_load_reg(rm, pass);
6495 if (prewiden) {
6496 gen_neon_widen(cpu_V1, tmp2, size, u);
6499 switch (op) {
6500 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6501 gen_neon_addl(size);
6502 break;
6503 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6504 gen_neon_subl(size);
6505 break;
6506 case 5: case 7: /* VABAL, VABDL */
6507 switch ((size << 1) | u) {
6508 case 0:
6509 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6510 break;
6511 case 1:
6512 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6513 break;
6514 case 2:
6515 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6516 break;
6517 case 3:
6518 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6519 break;
6520 case 4:
6521 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6522 break;
6523 case 5:
6524 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6525 break;
6526 default: abort();
6528 tcg_temp_free_i32(tmp2);
6529 tcg_temp_free_i32(tmp);
6530 break;
6531 case 8: case 9: case 10: case 11: case 12: case 13:
6532 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6533 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6534 break;
6535 case 14: /* Polynomial VMULL */
6536 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6537 tcg_temp_free_i32(tmp2);
6538 tcg_temp_free_i32(tmp);
6539 break;
6540 default: /* 15 is RESERVED: caught earlier */
6541 abort();
6543 if (op == 13) {
6544 /* VQDMULL */
6545 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6546 neon_store_reg64(cpu_V0, rd + pass);
6547 } else if (op == 5 || (op >= 8 && op <= 11)) {
6548 /* Accumulate. */
6549 neon_load_reg64(cpu_V1, rd + pass);
6550 switch (op) {
6551 case 10: /* VMLSL */
6552 gen_neon_negl(cpu_V0, size);
6553 /* Fall through */
6554 case 5: case 8: /* VABAL, VMLAL */
6555 gen_neon_addl(size);
6556 break;
6557 case 9: case 11: /* VQDMLAL, VQDMLSL */
6558 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6559 if (op == 11) {
6560 gen_neon_negl(cpu_V0, size);
6562 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6563 break;
6564 default:
6565 abort();
6567 neon_store_reg64(cpu_V0, rd + pass);
6568 } else if (op == 4 || op == 6) {
6569 /* Narrowing operation. */
6570 tmp = tcg_temp_new_i32();
6571 if (!u) {
6572 switch (size) {
6573 case 0:
6574 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6575 break;
6576 case 1:
6577 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6578 break;
6579 case 2:
6580 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6581 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6582 break;
6583 default: abort();
6585 } else {
6586 switch (size) {
6587 case 0:
6588 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6589 break;
6590 case 1:
6591 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6592 break;
6593 case 2:
6594 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6595 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6596 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6597 break;
6598 default: abort();
6601 if (pass == 0) {
6602 tmp3 = tmp;
6603 } else {
6604 neon_store_reg(rd, 0, tmp3);
6605 neon_store_reg(rd, 1, tmp);
6607 } else {
6608 /* Write back the result. */
6609 neon_store_reg64(cpu_V0, rd + pass);
6612 } else {
6613 /* Two registers and a scalar. NB that for ops of this form
6614 * the ARM ARM labels bit 24 as Q, but it is in our variable
6615 * 'u', not 'q'.
6617 if (size == 0) {
6618 return 1;
6620 switch (op) {
6621 case 1: /* Float VMLA scalar */
6622 case 5: /* Floating point VMLS scalar */
6623 case 9: /* Floating point VMUL scalar */
6624 if (size == 1) {
6625 return 1;
6627 /* fall through */
6628 case 0: /* Integer VMLA scalar */
6629 case 4: /* Integer VMLS scalar */
6630 case 8: /* Integer VMUL scalar */
6631 case 12: /* VQDMULH scalar */
6632 case 13: /* VQRDMULH scalar */
6633 if (u && ((rd | rn) & 1)) {
6634 return 1;
6636 tmp = neon_get_scalar(size, rm);
6637 neon_store_scratch(0, tmp);
6638 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6639 tmp = neon_load_scratch(0);
6640 tmp2 = neon_load_reg(rn, pass);
6641 if (op == 12) {
6642 if (size == 1) {
6643 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6644 } else {
6645 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6647 } else if (op == 13) {
6648 if (size == 1) {
6649 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6650 } else {
6651 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6653 } else if (op & 1) {
6654 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6655 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6656 tcg_temp_free_ptr(fpstatus);
6657 } else {
6658 switch (size) {
6659 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6660 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6661 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6662 default: abort();
6665 tcg_temp_free_i32(tmp2);
6666 if (op < 8) {
6667 /* Accumulate. */
6668 tmp2 = neon_load_reg(rd, pass);
6669 switch (op) {
6670 case 0:
6671 gen_neon_add(size, tmp, tmp2);
6672 break;
6673 case 1:
6675 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6676 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6677 tcg_temp_free_ptr(fpstatus);
6678 break;
6680 case 4:
6681 gen_neon_rsb(size, tmp, tmp2);
6682 break;
6683 case 5:
6685 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6686 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6687 tcg_temp_free_ptr(fpstatus);
6688 break;
6690 default:
6691 abort();
6693 tcg_temp_free_i32(tmp2);
6695 neon_store_reg(rd, pass, tmp);
6697 break;
6698 case 3: /* VQDMLAL scalar */
6699 case 7: /* VQDMLSL scalar */
6700 case 11: /* VQDMULL scalar */
6701 if (u == 1) {
6702 return 1;
6704 /* fall through */
6705 case 2: /* VMLAL sclar */
6706 case 6: /* VMLSL scalar */
6707 case 10: /* VMULL scalar */
6708 if (rd & 1) {
6709 return 1;
6711 tmp2 = neon_get_scalar(size, rm);
6712 /* We need a copy of tmp2 because gen_neon_mull
6713 * deletes it during pass 0. */
6714 tmp4 = tcg_temp_new_i32();
6715 tcg_gen_mov_i32(tmp4, tmp2);
6716 tmp3 = neon_load_reg(rn, 1);
6718 for (pass = 0; pass < 2; pass++) {
6719 if (pass == 0) {
6720 tmp = neon_load_reg(rn, 0);
6721 } else {
6722 tmp = tmp3;
6723 tmp2 = tmp4;
6725 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6726 if (op != 11) {
6727 neon_load_reg64(cpu_V1, rd + pass);
6729 switch (op) {
6730 case 6:
6731 gen_neon_negl(cpu_V0, size);
6732 /* Fall through */
6733 case 2:
6734 gen_neon_addl(size);
6735 break;
6736 case 3: case 7:
6737 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6738 if (op == 7) {
6739 gen_neon_negl(cpu_V0, size);
6741 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6742 break;
6743 case 10:
6744 /* no-op */
6745 break;
6746 case 11:
6747 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6748 break;
6749 default:
6750 abort();
6752 neon_store_reg64(cpu_V0, rd + pass);
6756 break;
6757 default: /* 14 and 15 are RESERVED */
6758 return 1;
6761 } else { /* size == 3 */
6762 if (!u) {
6763 /* Extract. */
6764 imm = (insn >> 8) & 0xf;
6766 if (imm > 7 && !q)
6767 return 1;
6769 if (q && ((rd | rn | rm) & 1)) {
6770 return 1;
6773 if (imm == 0) {
6774 neon_load_reg64(cpu_V0, rn);
6775 if (q) {
6776 neon_load_reg64(cpu_V1, rn + 1);
6778 } else if (imm == 8) {
6779 neon_load_reg64(cpu_V0, rn + 1);
6780 if (q) {
6781 neon_load_reg64(cpu_V1, rm);
6783 } else if (q) {
6784 tmp64 = tcg_temp_new_i64();
6785 if (imm < 8) {
6786 neon_load_reg64(cpu_V0, rn);
6787 neon_load_reg64(tmp64, rn + 1);
6788 } else {
6789 neon_load_reg64(cpu_V0, rn + 1);
6790 neon_load_reg64(tmp64, rm);
6792 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6793 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6794 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6795 if (imm < 8) {
6796 neon_load_reg64(cpu_V1, rm);
6797 } else {
6798 neon_load_reg64(cpu_V1, rm + 1);
6799 imm -= 8;
6801 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6802 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6803 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6804 tcg_temp_free_i64(tmp64);
6805 } else {
6806 /* BUGFIX */
6807 neon_load_reg64(cpu_V0, rn);
6808 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6809 neon_load_reg64(cpu_V1, rm);
6810 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6811 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6813 neon_store_reg64(cpu_V0, rd);
6814 if (q) {
6815 neon_store_reg64(cpu_V1, rd + 1);
6817 } else if ((insn & (1 << 11)) == 0) {
6818 /* Two register misc. */
6819 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6820 size = (insn >> 18) & 3;
6821 /* UNDEF for unknown op values and bad op-size combinations */
6822 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6823 return 1;
6825 if (neon_2rm_is_v8_op(op) &&
6826 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6827 return 1;
6829 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6830 q && ((rm | rd) & 1)) {
6831 return 1;
6833 switch (op) {
6834 case NEON_2RM_VREV64:
6835 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6836 tmp = neon_load_reg(rm, pass * 2);
6837 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6838 switch (size) {
6839 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6840 case 1: gen_swap_half(tmp); break;
6841 case 2: /* no-op */ break;
6842 default: abort();
6844 neon_store_reg(rd, pass * 2 + 1, tmp);
6845 if (size == 2) {
6846 neon_store_reg(rd, pass * 2, tmp2);
6847 } else {
6848 switch (size) {
6849 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6850 case 1: gen_swap_half(tmp2); break;
6851 default: abort();
6853 neon_store_reg(rd, pass * 2, tmp2);
6856 break;
6857 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6858 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6859 for (pass = 0; pass < q + 1; pass++) {
6860 tmp = neon_load_reg(rm, pass * 2);
6861 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6862 tmp = neon_load_reg(rm, pass * 2 + 1);
6863 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6864 switch (size) {
6865 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6866 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6867 case 2: tcg_gen_add_i64(CPU_V001); break;
6868 default: abort();
6870 if (op >= NEON_2RM_VPADAL) {
6871 /* Accumulate. */
6872 neon_load_reg64(cpu_V1, rd + pass);
6873 gen_neon_addl(size);
6875 neon_store_reg64(cpu_V0, rd + pass);
6877 break;
6878 case NEON_2RM_VTRN:
6879 if (size == 2) {
6880 int n;
6881 for (n = 0; n < (q ? 4 : 2); n += 2) {
6882 tmp = neon_load_reg(rm, n);
6883 tmp2 = neon_load_reg(rd, n + 1);
6884 neon_store_reg(rm, n, tmp2);
6885 neon_store_reg(rd, n + 1, tmp);
6887 } else {
6888 goto elementwise;
6890 break;
6891 case NEON_2RM_VUZP:
6892 if (gen_neon_unzip(rd, rm, size, q)) {
6893 return 1;
6895 break;
6896 case NEON_2RM_VZIP:
6897 if (gen_neon_zip(rd, rm, size, q)) {
6898 return 1;
6900 break;
6901 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6902 /* also VQMOVUN; op field and mnemonics don't line up */
6903 if (rm & 1) {
6904 return 1;
6906 TCGV_UNUSED_I32(tmp2);
6907 for (pass = 0; pass < 2; pass++) {
6908 neon_load_reg64(cpu_V0, rm + pass);
6909 tmp = tcg_temp_new_i32();
6910 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6911 tmp, cpu_V0);
6912 if (pass == 0) {
6913 tmp2 = tmp;
6914 } else {
6915 neon_store_reg(rd, 0, tmp2);
6916 neon_store_reg(rd, 1, tmp);
6919 break;
6920 case NEON_2RM_VSHLL:
6921 if (q || (rd & 1)) {
6922 return 1;
6924 tmp = neon_load_reg(rm, 0);
6925 tmp2 = neon_load_reg(rm, 1);
6926 for (pass = 0; pass < 2; pass++) {
6927 if (pass == 1)
6928 tmp = tmp2;
6929 gen_neon_widen(cpu_V0, tmp, size, 1);
6930 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6931 neon_store_reg64(cpu_V0, rd + pass);
6933 break;
6934 case NEON_2RM_VCVT_F16_F32:
6935 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6936 q || (rm & 1)) {
6937 return 1;
6939 tmp = tcg_temp_new_i32();
6940 tmp2 = tcg_temp_new_i32();
6941 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6942 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6943 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6944 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6945 tcg_gen_shli_i32(tmp2, tmp2, 16);
6946 tcg_gen_or_i32(tmp2, tmp2, tmp);
6947 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6948 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6949 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6950 neon_store_reg(rd, 0, tmp2);
6951 tmp2 = tcg_temp_new_i32();
6952 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6953 tcg_gen_shli_i32(tmp2, tmp2, 16);
6954 tcg_gen_or_i32(tmp2, tmp2, tmp);
6955 neon_store_reg(rd, 1, tmp2);
6956 tcg_temp_free_i32(tmp);
6957 break;
6958 case NEON_2RM_VCVT_F32_F16:
6959 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6960 q || (rd & 1)) {
6961 return 1;
6963 tmp3 = tcg_temp_new_i32();
6964 tmp = neon_load_reg(rm, 0);
6965 tmp2 = neon_load_reg(rm, 1);
6966 tcg_gen_ext16u_i32(tmp3, tmp);
6967 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6968 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6969 tcg_gen_shri_i32(tmp3, tmp, 16);
6970 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6971 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6972 tcg_temp_free_i32(tmp);
6973 tcg_gen_ext16u_i32(tmp3, tmp2);
6974 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6975 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6976 tcg_gen_shri_i32(tmp3, tmp2, 16);
6977 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6978 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6979 tcg_temp_free_i32(tmp2);
6980 tcg_temp_free_i32(tmp3);
6981 break;
6982 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6983 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6984 || ((rm | rd) & 1)) {
6985 return 1;
6987 tmp = tcg_const_i32(rd);
6988 tmp2 = tcg_const_i32(rm);
6990 /* Bit 6 is the lowest opcode bit; it distinguishes between
6991 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6993 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6995 if (op == NEON_2RM_AESE) {
6996 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6997 } else {
6998 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
7000 tcg_temp_free_i32(tmp);
7001 tcg_temp_free_i32(tmp2);
7002 tcg_temp_free_i32(tmp3);
7003 break;
7004 case NEON_2RM_SHA1H:
7005 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7006 || ((rm | rd) & 1)) {
7007 return 1;
7009 tmp = tcg_const_i32(rd);
7010 tmp2 = tcg_const_i32(rm);
7012 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
7014 tcg_temp_free_i32(tmp);
7015 tcg_temp_free_i32(tmp2);
7016 break;
7017 case NEON_2RM_SHA1SU1:
7018 if ((rm | rd) & 1) {
7019 return 1;
7021 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7022 if (q) {
7023 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7024 return 1;
7026 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7027 return 1;
7029 tmp = tcg_const_i32(rd);
7030 tmp2 = tcg_const_i32(rm);
7031 if (q) {
7032 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7033 } else {
7034 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7036 tcg_temp_free_i32(tmp);
7037 tcg_temp_free_i32(tmp2);
7038 break;
7039 default:
7040 elementwise:
7041 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7042 if (neon_2rm_is_float_op(op)) {
7043 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7044 neon_reg_offset(rm, pass));
7045 TCGV_UNUSED_I32(tmp);
7046 } else {
7047 tmp = neon_load_reg(rm, pass);
7049 switch (op) {
7050 case NEON_2RM_VREV32:
7051 switch (size) {
7052 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7053 case 1: gen_swap_half(tmp); break;
7054 default: abort();
7056 break;
7057 case NEON_2RM_VREV16:
7058 gen_rev16(tmp);
7059 break;
7060 case NEON_2RM_VCLS:
7061 switch (size) {
7062 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7063 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7064 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7065 default: abort();
7067 break;
7068 case NEON_2RM_VCLZ:
7069 switch (size) {
7070 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7071 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7072 case 2: gen_helper_clz(tmp, tmp); break;
7073 default: abort();
7075 break;
7076 case NEON_2RM_VCNT:
7077 gen_helper_neon_cnt_u8(tmp, tmp);
7078 break;
7079 case NEON_2RM_VMVN:
7080 tcg_gen_not_i32(tmp, tmp);
7081 break;
7082 case NEON_2RM_VQABS:
7083 switch (size) {
7084 case 0:
7085 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7086 break;
7087 case 1:
7088 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7089 break;
7090 case 2:
7091 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7092 break;
7093 default: abort();
7095 break;
7096 case NEON_2RM_VQNEG:
7097 switch (size) {
7098 case 0:
7099 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7100 break;
7101 case 1:
7102 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7103 break;
7104 case 2:
7105 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7106 break;
7107 default: abort();
7109 break;
7110 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7111 tmp2 = tcg_const_i32(0);
7112 switch(size) {
7113 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7114 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7115 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7116 default: abort();
7118 tcg_temp_free_i32(tmp2);
7119 if (op == NEON_2RM_VCLE0) {
7120 tcg_gen_not_i32(tmp, tmp);
7122 break;
7123 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7124 tmp2 = tcg_const_i32(0);
7125 switch(size) {
7126 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7127 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7128 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7129 default: abort();
7131 tcg_temp_free_i32(tmp2);
7132 if (op == NEON_2RM_VCLT0) {
7133 tcg_gen_not_i32(tmp, tmp);
7135 break;
7136 case NEON_2RM_VCEQ0:
7137 tmp2 = tcg_const_i32(0);
7138 switch(size) {
7139 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7140 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7141 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7142 default: abort();
7144 tcg_temp_free_i32(tmp2);
7145 break;
7146 case NEON_2RM_VABS:
7147 switch(size) {
7148 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7149 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7150 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7151 default: abort();
7153 break;
7154 case NEON_2RM_VNEG:
7155 tmp2 = tcg_const_i32(0);
7156 gen_neon_rsb(size, tmp, tmp2);
7157 tcg_temp_free_i32(tmp2);
7158 break;
7159 case NEON_2RM_VCGT0_F:
7161 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7162 tmp2 = tcg_const_i32(0);
7163 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7164 tcg_temp_free_i32(tmp2);
7165 tcg_temp_free_ptr(fpstatus);
7166 break;
7168 case NEON_2RM_VCGE0_F:
7170 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7171 tmp2 = tcg_const_i32(0);
7172 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7173 tcg_temp_free_i32(tmp2);
7174 tcg_temp_free_ptr(fpstatus);
7175 break;
7177 case NEON_2RM_VCEQ0_F:
7179 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7180 tmp2 = tcg_const_i32(0);
7181 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7182 tcg_temp_free_i32(tmp2);
7183 tcg_temp_free_ptr(fpstatus);
7184 break;
7186 case NEON_2RM_VCLE0_F:
7188 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7189 tmp2 = tcg_const_i32(0);
7190 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7191 tcg_temp_free_i32(tmp2);
7192 tcg_temp_free_ptr(fpstatus);
7193 break;
7195 case NEON_2RM_VCLT0_F:
7197 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7198 tmp2 = tcg_const_i32(0);
7199 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7200 tcg_temp_free_i32(tmp2);
7201 tcg_temp_free_ptr(fpstatus);
7202 break;
7204 case NEON_2RM_VABS_F:
7205 gen_vfp_abs(0);
7206 break;
7207 case NEON_2RM_VNEG_F:
7208 gen_vfp_neg(0);
7209 break;
7210 case NEON_2RM_VSWP:
7211 tmp2 = neon_load_reg(rd, pass);
7212 neon_store_reg(rm, pass, tmp2);
7213 break;
7214 case NEON_2RM_VTRN:
7215 tmp2 = neon_load_reg(rd, pass);
7216 switch (size) {
7217 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7218 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7219 default: abort();
7221 neon_store_reg(rm, pass, tmp2);
7222 break;
7223 case NEON_2RM_VRINTN:
7224 case NEON_2RM_VRINTA:
7225 case NEON_2RM_VRINTM:
7226 case NEON_2RM_VRINTP:
7227 case NEON_2RM_VRINTZ:
7229 TCGv_i32 tcg_rmode;
7230 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7231 int rmode;
7233 if (op == NEON_2RM_VRINTZ) {
7234 rmode = FPROUNDING_ZERO;
7235 } else {
7236 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7239 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7240 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7241 cpu_env);
7242 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7243 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7244 cpu_env);
7245 tcg_temp_free_ptr(fpstatus);
7246 tcg_temp_free_i32(tcg_rmode);
7247 break;
7249 case NEON_2RM_VRINTX:
7251 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7252 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7253 tcg_temp_free_ptr(fpstatus);
7254 break;
7256 case NEON_2RM_VCVTAU:
7257 case NEON_2RM_VCVTAS:
7258 case NEON_2RM_VCVTNU:
7259 case NEON_2RM_VCVTNS:
7260 case NEON_2RM_VCVTPU:
7261 case NEON_2RM_VCVTPS:
7262 case NEON_2RM_VCVTMU:
7263 case NEON_2RM_VCVTMS:
7265 bool is_signed = !extract32(insn, 7, 1);
7266 TCGv_ptr fpst = get_fpstatus_ptr(1);
7267 TCGv_i32 tcg_rmode, tcg_shift;
7268 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7270 tcg_shift = tcg_const_i32(0);
7271 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7272 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7273 cpu_env);
7275 if (is_signed) {
7276 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7277 tcg_shift, fpst);
7278 } else {
7279 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7280 tcg_shift, fpst);
7283 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7284 cpu_env);
7285 tcg_temp_free_i32(tcg_rmode);
7286 tcg_temp_free_i32(tcg_shift);
7287 tcg_temp_free_ptr(fpst);
7288 break;
7290 case NEON_2RM_VRECPE:
7292 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7293 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7294 tcg_temp_free_ptr(fpstatus);
7295 break;
7297 case NEON_2RM_VRSQRTE:
7299 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7300 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7301 tcg_temp_free_ptr(fpstatus);
7302 break;
7304 case NEON_2RM_VRECPE_F:
7306 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7307 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7308 tcg_temp_free_ptr(fpstatus);
7309 break;
7311 case NEON_2RM_VRSQRTE_F:
7313 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7314 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7315 tcg_temp_free_ptr(fpstatus);
7316 break;
7318 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7319 gen_vfp_sito(0, 1);
7320 break;
7321 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7322 gen_vfp_uito(0, 1);
7323 break;
7324 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7325 gen_vfp_tosiz(0, 1);
7326 break;
7327 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7328 gen_vfp_touiz(0, 1);
7329 break;
7330 default:
7331 /* Reserved op values were caught by the
7332 * neon_2rm_sizes[] check earlier.
7334 abort();
7336 if (neon_2rm_is_float_op(op)) {
7337 tcg_gen_st_f32(cpu_F0s, cpu_env,
7338 neon_reg_offset(rd, pass));
7339 } else {
7340 neon_store_reg(rd, pass, tmp);
7343 break;
7345 } else if ((insn & (1 << 10)) == 0) {
7346 /* VTBL, VTBX. */
7347 int n = ((insn >> 8) & 3) + 1;
7348 if ((rn + n) > 32) {
7349 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7350 * helper function running off the end of the register file.
7352 return 1;
7354 n <<= 3;
7355 if (insn & (1 << 6)) {
7356 tmp = neon_load_reg(rd, 0);
7357 } else {
7358 tmp = tcg_temp_new_i32();
7359 tcg_gen_movi_i32(tmp, 0);
7361 tmp2 = neon_load_reg(rm, 0);
7362 tmp4 = tcg_const_i32(rn);
7363 tmp5 = tcg_const_i32(n);
7364 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7365 tcg_temp_free_i32(tmp);
7366 if (insn & (1 << 6)) {
7367 tmp = neon_load_reg(rd, 1);
7368 } else {
7369 tmp = tcg_temp_new_i32();
7370 tcg_gen_movi_i32(tmp, 0);
7372 tmp3 = neon_load_reg(rm, 1);
7373 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7374 tcg_temp_free_i32(tmp5);
7375 tcg_temp_free_i32(tmp4);
7376 neon_store_reg(rd, 0, tmp2);
7377 neon_store_reg(rd, 1, tmp3);
7378 tcg_temp_free_i32(tmp);
7379 } else if ((insn & 0x380) == 0) {
7380 /* VDUP */
7381 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7382 return 1;
7384 if (insn & (1 << 19)) {
7385 tmp = neon_load_reg(rm, 1);
7386 } else {
7387 tmp = neon_load_reg(rm, 0);
7389 if (insn & (1 << 16)) {
7390 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7391 } else if (insn & (1 << 17)) {
7392 if ((insn >> 18) & 1)
7393 gen_neon_dup_high16(tmp);
7394 else
7395 gen_neon_dup_low16(tmp);
7397 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7398 tmp2 = tcg_temp_new_i32();
7399 tcg_gen_mov_i32(tmp2, tmp);
7400 neon_store_reg(rd, pass, tmp2);
7402 tcg_temp_free_i32(tmp);
7403 } else {
7404 return 1;
7408 return 0;
7411 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7413 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7414 const ARMCPRegInfo *ri;
7416 cpnum = (insn >> 8) & 0xf;
7418 /* First check for coprocessor space used for XScale/iwMMXt insns */
7419 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7420 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7421 return 1;
7423 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7424 return disas_iwmmxt_insn(s, insn);
7425 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7426 return disas_dsp_insn(s, insn);
7428 return 1;
7431 /* Otherwise treat as a generic register access */
7432 is64 = (insn & (1 << 25)) == 0;
7433 if (!is64 && ((insn & (1 << 4)) == 0)) {
7434 /* cdp */
7435 return 1;
7438 crm = insn & 0xf;
7439 if (is64) {
7440 crn = 0;
7441 opc1 = (insn >> 4) & 0xf;
7442 opc2 = 0;
7443 rt2 = (insn >> 16) & 0xf;
7444 } else {
7445 crn = (insn >> 16) & 0xf;
7446 opc1 = (insn >> 21) & 7;
7447 opc2 = (insn >> 5) & 7;
7448 rt2 = 0;
7450 isread = (insn >> 20) & 1;
7451 rt = (insn >> 12) & 0xf;
7453 ri = get_arm_cp_reginfo(s->cp_regs,
7454 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7455 if (ri) {
7456 /* Check access permissions */
7457 if (!cp_access_ok(s->current_el, ri, isread)) {
7458 return 1;
7461 if (ri->accessfn ||
7462 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7463 /* Emit code to perform further access permissions checks at
7464 * runtime; this may result in an exception.
7465 * Note that on XScale all cp0..c13 registers do an access check
7466 * call in order to handle c15_cpar.
7468 TCGv_ptr tmpptr;
7469 TCGv_i32 tcg_syn, tcg_isread;
7470 uint32_t syndrome;
7472 /* Note that since we are an implementation which takes an
7473 * exception on a trapped conditional instruction only if the
7474 * instruction passes its condition code check, we can take
7475 * advantage of the clause in the ARM ARM that allows us to set
7476 * the COND field in the instruction to 0xE in all cases.
7477 * We could fish the actual condition out of the insn (ARM)
7478 * or the condexec bits (Thumb) but it isn't necessary.
7480 switch (cpnum) {
7481 case 14:
7482 if (is64) {
7483 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7484 isread, false);
7485 } else {
7486 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7487 rt, isread, false);
7489 break;
7490 case 15:
7491 if (is64) {
7492 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7493 isread, false);
7494 } else {
7495 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7496 rt, isread, false);
7498 break;
7499 default:
7500 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7501 * so this can only happen if this is an ARMv7 or earlier CPU,
7502 * in which case the syndrome information won't actually be
7503 * guest visible.
7505 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7506 syndrome = syn_uncategorized();
7507 break;
7510 gen_set_condexec(s);
7511 gen_set_pc_im(s, s->pc - 4);
7512 tmpptr = tcg_const_ptr(ri);
7513 tcg_syn = tcg_const_i32(syndrome);
7514 tcg_isread = tcg_const_i32(isread);
7515 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7516 tcg_isread);
7517 tcg_temp_free_ptr(tmpptr);
7518 tcg_temp_free_i32(tcg_syn);
7519 tcg_temp_free_i32(tcg_isread);
7522 /* Handle special cases first */
7523 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7524 case ARM_CP_NOP:
7525 return 0;
7526 case ARM_CP_WFI:
7527 if (isread) {
7528 return 1;
7530 gen_set_pc_im(s, s->pc);
7531 s->is_jmp = DISAS_WFI;
7532 return 0;
7533 default:
7534 break;
7537 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7538 gen_io_start();
7541 if (isread) {
7542 /* Read */
7543 if (is64) {
7544 TCGv_i64 tmp64;
7545 TCGv_i32 tmp;
7546 if (ri->type & ARM_CP_CONST) {
7547 tmp64 = tcg_const_i64(ri->resetvalue);
7548 } else if (ri->readfn) {
7549 TCGv_ptr tmpptr;
7550 tmp64 = tcg_temp_new_i64();
7551 tmpptr = tcg_const_ptr(ri);
7552 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7553 tcg_temp_free_ptr(tmpptr);
7554 } else {
7555 tmp64 = tcg_temp_new_i64();
7556 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7558 tmp = tcg_temp_new_i32();
7559 tcg_gen_extrl_i64_i32(tmp, tmp64);
7560 store_reg(s, rt, tmp);
7561 tcg_gen_shri_i64(tmp64, tmp64, 32);
7562 tmp = tcg_temp_new_i32();
7563 tcg_gen_extrl_i64_i32(tmp, tmp64);
7564 tcg_temp_free_i64(tmp64);
7565 store_reg(s, rt2, tmp);
7566 } else {
7567 TCGv_i32 tmp;
7568 if (ri->type & ARM_CP_CONST) {
7569 tmp = tcg_const_i32(ri->resetvalue);
7570 } else if (ri->readfn) {
7571 TCGv_ptr tmpptr;
7572 tmp = tcg_temp_new_i32();
7573 tmpptr = tcg_const_ptr(ri);
7574 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7575 tcg_temp_free_ptr(tmpptr);
7576 } else {
7577 tmp = load_cpu_offset(ri->fieldoffset);
7579 if (rt == 15) {
7580 /* Destination register of r15 for 32 bit loads sets
7581 * the condition codes from the high 4 bits of the value
7583 gen_set_nzcv(tmp);
7584 tcg_temp_free_i32(tmp);
7585 } else {
7586 store_reg(s, rt, tmp);
7589 } else {
7590 /* Write */
7591 if (ri->type & ARM_CP_CONST) {
7592 /* If not forbidden by access permissions, treat as WI */
7593 return 0;
7596 if (is64) {
7597 TCGv_i32 tmplo, tmphi;
7598 TCGv_i64 tmp64 = tcg_temp_new_i64();
7599 tmplo = load_reg(s, rt);
7600 tmphi = load_reg(s, rt2);
7601 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7602 tcg_temp_free_i32(tmplo);
7603 tcg_temp_free_i32(tmphi);
7604 if (ri->writefn) {
7605 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7606 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7607 tcg_temp_free_ptr(tmpptr);
7608 } else {
7609 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7611 tcg_temp_free_i64(tmp64);
7612 } else {
7613 if (ri->writefn) {
7614 TCGv_i32 tmp;
7615 TCGv_ptr tmpptr;
7616 tmp = load_reg(s, rt);
7617 tmpptr = tcg_const_ptr(ri);
7618 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7619 tcg_temp_free_ptr(tmpptr);
7620 tcg_temp_free_i32(tmp);
7621 } else {
7622 TCGv_i32 tmp = load_reg(s, rt);
7623 store_cpu_offset(tmp, ri->fieldoffset);
7628 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7629 /* I/O operations must end the TB here (whether read or write) */
7630 gen_io_end();
7631 gen_lookup_tb(s);
7632 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7633 /* We default to ending the TB on a coprocessor register write,
7634 * but allow this to be suppressed by the register definition
7635 * (usually only necessary to work around guest bugs).
7637 gen_lookup_tb(s);
7640 return 0;
7643 /* Unknown register; this might be a guest error or a QEMU
7644 * unimplemented feature.
7646 if (is64) {
7647 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7648 "64 bit system register cp:%d opc1: %d crm:%d "
7649 "(%s)\n",
7650 isread ? "read" : "write", cpnum, opc1, crm,
7651 s->ns ? "non-secure" : "secure");
7652 } else {
7653 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7654 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7655 "(%s)\n",
7656 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7657 s->ns ? "non-secure" : "secure");
7660 return 1;
7664 /* Store a 64-bit value to a register pair. Clobbers val. */
7665 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7667 TCGv_i32 tmp;
7668 tmp = tcg_temp_new_i32();
7669 tcg_gen_extrl_i64_i32(tmp, val);
7670 store_reg(s, rlow, tmp);
7671 tmp = tcg_temp_new_i32();
7672 tcg_gen_shri_i64(val, val, 32);
7673 tcg_gen_extrl_i64_i32(tmp, val);
7674 store_reg(s, rhigh, tmp);
7677 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7678 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7680 TCGv_i64 tmp;
7681 TCGv_i32 tmp2;
7683 /* Load value and extend to 64 bits. */
7684 tmp = tcg_temp_new_i64();
7685 tmp2 = load_reg(s, rlow);
7686 tcg_gen_extu_i32_i64(tmp, tmp2);
7687 tcg_temp_free_i32(tmp2);
7688 tcg_gen_add_i64(val, val, tmp);
7689 tcg_temp_free_i64(tmp);
7692 /* load and add a 64-bit value from a register pair. */
7693 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7695 TCGv_i64 tmp;
7696 TCGv_i32 tmpl;
7697 TCGv_i32 tmph;
7699 /* Load 64-bit value rd:rn. */
7700 tmpl = load_reg(s, rlow);
7701 tmph = load_reg(s, rhigh);
7702 tmp = tcg_temp_new_i64();
7703 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7704 tcg_temp_free_i32(tmpl);
7705 tcg_temp_free_i32(tmph);
7706 tcg_gen_add_i64(val, val, tmp);
7707 tcg_temp_free_i64(tmp);
7710 /* Set N and Z flags from hi|lo. */
7711 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7713 tcg_gen_mov_i32(cpu_NF, hi);
7714 tcg_gen_or_i32(cpu_ZF, lo, hi);
7717 /* Load/Store exclusive instructions are implemented by remembering
7718 the value/address loaded, and seeing if these are the same
7719 when the store is performed. This should be sufficient to implement
7720 the architecturally mandated semantics, and avoids having to monitor
7721 regular stores.
7723 In system emulation mode only one CPU will be running at once, so
7724 this sequence is effectively atomic. In user emulation mode we
7725 throw an exception and handle the atomic operation elsewhere. */
7726 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7727 TCGv_i32 addr, int size)
7729 TCGv_i32 tmp = tcg_temp_new_i32();
7731 s->is_ldex = true;
7733 switch (size) {
7734 case 0:
7735 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7736 break;
7737 case 1:
7738 gen_aa32_ld16ua(s, tmp, addr, get_mem_index(s));
7739 break;
7740 case 2:
7741 case 3:
7742 gen_aa32_ld32ua(s, tmp, addr, get_mem_index(s));
7743 break;
7744 default:
7745 abort();
7748 if (size == 3) {
7749 TCGv_i32 tmp2 = tcg_temp_new_i32();
7750 TCGv_i32 tmp3 = tcg_temp_new_i32();
7752 tcg_gen_addi_i32(tmp2, addr, 4);
7753 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7754 tcg_temp_free_i32(tmp2);
7755 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7756 store_reg(s, rt2, tmp3);
7757 } else {
7758 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7761 store_reg(s, rt, tmp);
7762 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7765 static void gen_clrex(DisasContext *s)
7767 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7770 #ifdef CONFIG_USER_ONLY
7771 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7772 TCGv_i32 addr, int size)
7774 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7775 tcg_gen_movi_i32(cpu_exclusive_info,
7776 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7777 gen_exception_internal_insn(s, 4, EXCP_STREX);
7779 #else
7780 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7781 TCGv_i32 addr, int size)
7783 TCGv_i32 tmp;
7784 TCGv_i64 val64, extaddr;
7785 TCGLabel *done_label;
7786 TCGLabel *fail_label;
7788 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7789 [addr] = {Rt};
7790 {Rd} = 0;
7791 } else {
7792 {Rd} = 1;
7793 } */
7794 fail_label = gen_new_label();
7795 done_label = gen_new_label();
7796 extaddr = tcg_temp_new_i64();
7797 tcg_gen_extu_i32_i64(extaddr, addr);
7798 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7799 tcg_temp_free_i64(extaddr);
7801 tmp = tcg_temp_new_i32();
7802 switch (size) {
7803 case 0:
7804 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7805 break;
7806 case 1:
7807 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7808 break;
7809 case 2:
7810 case 3:
7811 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7812 break;
7813 default:
7814 abort();
7817 val64 = tcg_temp_new_i64();
7818 if (size == 3) {
7819 TCGv_i32 tmp2 = tcg_temp_new_i32();
7820 TCGv_i32 tmp3 = tcg_temp_new_i32();
7821 tcg_gen_addi_i32(tmp2, addr, 4);
7822 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7823 tcg_temp_free_i32(tmp2);
7824 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7825 tcg_temp_free_i32(tmp3);
7826 } else {
7827 tcg_gen_extu_i32_i64(val64, tmp);
7829 tcg_temp_free_i32(tmp);
7831 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7832 tcg_temp_free_i64(val64);
7834 tmp = load_reg(s, rt);
7835 switch (size) {
7836 case 0:
7837 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
7838 break;
7839 case 1:
7840 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
7841 break;
7842 case 2:
7843 case 3:
7844 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7845 break;
7846 default:
7847 abort();
7849 tcg_temp_free_i32(tmp);
7850 if (size == 3) {
7851 tcg_gen_addi_i32(addr, addr, 4);
7852 tmp = load_reg(s, rt2);
7853 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7854 tcg_temp_free_i32(tmp);
7856 tcg_gen_movi_i32(cpu_R[rd], 0);
7857 tcg_gen_br(done_label);
7858 gen_set_label(fail_label);
7859 tcg_gen_movi_i32(cpu_R[rd], 1);
7860 gen_set_label(done_label);
7861 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7863 #endif
7865 /* gen_srs:
7866 * @env: CPUARMState
7867 * @s: DisasContext
7868 * @mode: mode field from insn (which stack to store to)
7869 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7870 * @writeback: true if writeback bit set
7872 * Generate code for the SRS (Store Return State) insn.
7874 static void gen_srs(DisasContext *s,
7875 uint32_t mode, uint32_t amode, bool writeback)
7877 int32_t offset;
7878 TCGv_i32 addr, tmp;
7879 bool undef = false;
7881 /* SRS is:
7882 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7883 * and specified mode is monitor mode
7884 * - UNDEFINED in Hyp mode
7885 * - UNPREDICTABLE in User or System mode
7886 * - UNPREDICTABLE if the specified mode is:
7887 * -- not implemented
7888 * -- not a valid mode number
7889 * -- a mode that's at a higher exception level
7890 * -- Monitor, if we are Non-secure
7891 * For the UNPREDICTABLE cases we choose to UNDEF.
7893 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7894 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7895 return;
7898 if (s->current_el == 0 || s->current_el == 2) {
7899 undef = true;
7902 switch (mode) {
7903 case ARM_CPU_MODE_USR:
7904 case ARM_CPU_MODE_FIQ:
7905 case ARM_CPU_MODE_IRQ:
7906 case ARM_CPU_MODE_SVC:
7907 case ARM_CPU_MODE_ABT:
7908 case ARM_CPU_MODE_UND:
7909 case ARM_CPU_MODE_SYS:
7910 break;
7911 case ARM_CPU_MODE_HYP:
7912 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7913 undef = true;
7915 break;
7916 case ARM_CPU_MODE_MON:
7917 /* No need to check specifically for "are we non-secure" because
7918 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7919 * so if this isn't EL3 then we must be non-secure.
7921 if (s->current_el != 3) {
7922 undef = true;
7924 break;
7925 default:
7926 undef = true;
7929 if (undef) {
7930 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
7931 default_exception_el(s));
7932 return;
7935 addr = tcg_temp_new_i32();
7936 tmp = tcg_const_i32(mode);
7937 /* get_r13_banked() will raise an exception if called from System mode */
7938 gen_set_condexec(s);
7939 gen_set_pc_im(s, s->pc - 4);
7940 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7941 tcg_temp_free_i32(tmp);
7942 switch (amode) {
7943 case 0: /* DA */
7944 offset = -4;
7945 break;
7946 case 1: /* IA */
7947 offset = 0;
7948 break;
7949 case 2: /* DB */
7950 offset = -8;
7951 break;
7952 case 3: /* IB */
7953 offset = 4;
7954 break;
7955 default:
7956 abort();
7958 tcg_gen_addi_i32(addr, addr, offset);
7959 tmp = load_reg(s, 14);
7960 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7961 tcg_temp_free_i32(tmp);
7962 tmp = load_cpu_field(spsr);
7963 tcg_gen_addi_i32(addr, addr, 4);
7964 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7965 tcg_temp_free_i32(tmp);
7966 if (writeback) {
7967 switch (amode) {
7968 case 0:
7969 offset = -8;
7970 break;
7971 case 1:
7972 offset = 4;
7973 break;
7974 case 2:
7975 offset = -4;
7976 break;
7977 case 3:
7978 offset = 0;
7979 break;
7980 default:
7981 abort();
7983 tcg_gen_addi_i32(addr, addr, offset);
7984 tmp = tcg_const_i32(mode);
7985 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7986 tcg_temp_free_i32(tmp);
7988 tcg_temp_free_i32(addr);
7989 s->is_jmp = DISAS_UPDATE;
7992 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7994 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7995 TCGv_i32 tmp;
7996 TCGv_i32 tmp2;
7997 TCGv_i32 tmp3;
7998 TCGv_i32 addr;
7999 TCGv_i64 tmp64;
8001 /* M variants do not implement ARM mode. */
8002 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8003 goto illegal_op;
8005 cond = insn >> 28;
8006 if (cond == 0xf){
8007 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8008 * choose to UNDEF. In ARMv5 and above the space is used
8009 * for miscellaneous unconditional instructions.
8011 ARCH(5);
8013 /* Unconditional instructions. */
8014 if (((insn >> 25) & 7) == 1) {
8015 /* NEON Data processing. */
8016 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8017 goto illegal_op;
8020 if (disas_neon_data_insn(s, insn)) {
8021 goto illegal_op;
8023 return;
8025 if ((insn & 0x0f100000) == 0x04000000) {
8026 /* NEON load/store. */
8027 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8028 goto illegal_op;
8031 if (disas_neon_ls_insn(s, insn)) {
8032 goto illegal_op;
8034 return;
8036 if ((insn & 0x0f000e10) == 0x0e000a00) {
8037 /* VFP. */
8038 if (disas_vfp_insn(s, insn)) {
8039 goto illegal_op;
8041 return;
8043 if (((insn & 0x0f30f000) == 0x0510f000) ||
8044 ((insn & 0x0f30f010) == 0x0710f000)) {
8045 if ((insn & (1 << 22)) == 0) {
8046 /* PLDW; v7MP */
8047 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8048 goto illegal_op;
8051 /* Otherwise PLD; v5TE+ */
8052 ARCH(5TE);
8053 return;
8055 if (((insn & 0x0f70f000) == 0x0450f000) ||
8056 ((insn & 0x0f70f010) == 0x0650f000)) {
8057 ARCH(7);
8058 return; /* PLI; V7 */
8060 if (((insn & 0x0f700000) == 0x04100000) ||
8061 ((insn & 0x0f700010) == 0x06100000)) {
8062 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8063 goto illegal_op;
8065 return; /* v7MP: Unallocated memory hint: must NOP */
8068 if ((insn & 0x0ffffdff) == 0x01010000) {
8069 ARCH(6);
8070 /* setend */
8071 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8072 gen_helper_setend(cpu_env);
8073 s->is_jmp = DISAS_UPDATE;
8075 return;
8076 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8077 switch ((insn >> 4) & 0xf) {
8078 case 1: /* clrex */
8079 ARCH(6K);
8080 gen_clrex(s);
8081 return;
8082 case 4: /* dsb */
8083 case 5: /* dmb */
8084 ARCH(7);
8085 /* We don't emulate caches so these are a no-op. */
8086 return;
8087 case 6: /* isb */
8088 /* We need to break the TB after this insn to execute
8089 * self-modifying code correctly and also to take
8090 * any pending interrupts immediately.
8092 gen_lookup_tb(s);
8093 return;
8094 default:
8095 goto illegal_op;
8097 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8098 /* srs */
8099 ARCH(6);
8100 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8101 return;
8102 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8103 /* rfe */
8104 int32_t offset;
8105 if (IS_USER(s))
8106 goto illegal_op;
8107 ARCH(6);
8108 rn = (insn >> 16) & 0xf;
8109 addr = load_reg(s, rn);
8110 i = (insn >> 23) & 3;
8111 switch (i) {
8112 case 0: offset = -4; break; /* DA */
8113 case 1: offset = 0; break; /* IA */
8114 case 2: offset = -8; break; /* DB */
8115 case 3: offset = 4; break; /* IB */
8116 default: abort();
8118 if (offset)
8119 tcg_gen_addi_i32(addr, addr, offset);
8120 /* Load PC into tmp and CPSR into tmp2. */
8121 tmp = tcg_temp_new_i32();
8122 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8123 tcg_gen_addi_i32(addr, addr, 4);
8124 tmp2 = tcg_temp_new_i32();
8125 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8126 if (insn & (1 << 21)) {
8127 /* Base writeback. */
8128 switch (i) {
8129 case 0: offset = -8; break;
8130 case 1: offset = 4; break;
8131 case 2: offset = -4; break;
8132 case 3: offset = 0; break;
8133 default: abort();
8135 if (offset)
8136 tcg_gen_addi_i32(addr, addr, offset);
8137 store_reg(s, rn, addr);
8138 } else {
8139 tcg_temp_free_i32(addr);
8141 gen_rfe(s, tmp, tmp2);
8142 return;
8143 } else if ((insn & 0x0e000000) == 0x0a000000) {
8144 /* branch link and change to thumb (blx <offset>) */
8145 int32_t offset;
8147 val = (uint32_t)s->pc;
8148 tmp = tcg_temp_new_i32();
8149 tcg_gen_movi_i32(tmp, val);
8150 store_reg(s, 14, tmp);
8151 /* Sign-extend the 24-bit offset */
8152 offset = (((int32_t)insn) << 8) >> 8;
8153 /* offset * 4 + bit24 * 2 + (thumb bit) */
8154 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8155 /* pipeline offset */
8156 val += 4;
8157 /* protected by ARCH(5); above, near the start of uncond block */
8158 gen_bx_im(s, val);
8159 return;
8160 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8161 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8162 /* iWMMXt register transfer. */
8163 if (extract32(s->c15_cpar, 1, 1)) {
8164 if (!disas_iwmmxt_insn(s, insn)) {
8165 return;
8169 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8170 /* Coprocessor double register transfer. */
8171 ARCH(5TE);
8172 } else if ((insn & 0x0f000010) == 0x0e000010) {
8173 /* Additional coprocessor register transfer. */
8174 } else if ((insn & 0x0ff10020) == 0x01000000) {
8175 uint32_t mask;
8176 uint32_t val;
8177 /* cps (privileged) */
8178 if (IS_USER(s))
8179 return;
8180 mask = val = 0;
8181 if (insn & (1 << 19)) {
8182 if (insn & (1 << 8))
8183 mask |= CPSR_A;
8184 if (insn & (1 << 7))
8185 mask |= CPSR_I;
8186 if (insn & (1 << 6))
8187 mask |= CPSR_F;
8188 if (insn & (1 << 18))
8189 val |= mask;
8191 if (insn & (1 << 17)) {
8192 mask |= CPSR_M;
8193 val |= (insn & 0x1f);
8195 if (mask) {
8196 gen_set_psr_im(s, mask, 0, val);
8198 return;
8200 goto illegal_op;
8202 if (cond != 0xe) {
8203 /* if not always execute, we generate a conditional jump to
8204 next instruction */
8205 s->condlabel = gen_new_label();
8206 arm_gen_test_cc(cond ^ 1, s->condlabel);
8207 s->condjmp = 1;
8209 if ((insn & 0x0f900000) == 0x03000000) {
8210 if ((insn & (1 << 21)) == 0) {
8211 ARCH(6T2);
8212 rd = (insn >> 12) & 0xf;
8213 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8214 if ((insn & (1 << 22)) == 0) {
8215 /* MOVW */
8216 tmp = tcg_temp_new_i32();
8217 tcg_gen_movi_i32(tmp, val);
8218 } else {
8219 /* MOVT */
8220 tmp = load_reg(s, rd);
8221 tcg_gen_ext16u_i32(tmp, tmp);
8222 tcg_gen_ori_i32(tmp, tmp, val << 16);
8224 store_reg(s, rd, tmp);
8225 } else {
8226 if (((insn >> 12) & 0xf) != 0xf)
8227 goto illegal_op;
8228 if (((insn >> 16) & 0xf) == 0) {
8229 gen_nop_hint(s, insn & 0xff);
8230 } else {
8231 /* CPSR = immediate */
8232 val = insn & 0xff;
8233 shift = ((insn >> 8) & 0xf) * 2;
8234 if (shift)
8235 val = (val >> shift) | (val << (32 - shift));
8236 i = ((insn & (1 << 22)) != 0);
8237 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8238 i, val)) {
8239 goto illegal_op;
8243 } else if ((insn & 0x0f900000) == 0x01000000
8244 && (insn & 0x00000090) != 0x00000090) {
8245 /* miscellaneous instructions */
8246 op1 = (insn >> 21) & 3;
8247 sh = (insn >> 4) & 0xf;
8248 rm = insn & 0xf;
8249 switch (sh) {
8250 case 0x0: /* MSR, MRS */
8251 if (insn & (1 << 9)) {
8252 /* MSR (banked) and MRS (banked) */
8253 int sysm = extract32(insn, 16, 4) |
8254 (extract32(insn, 8, 1) << 4);
8255 int r = extract32(insn, 22, 1);
8257 if (op1 & 1) {
8258 /* MSR (banked) */
8259 gen_msr_banked(s, r, sysm, rm);
8260 } else {
8261 /* MRS (banked) */
8262 int rd = extract32(insn, 12, 4);
8264 gen_mrs_banked(s, r, sysm, rd);
8266 break;
8269 /* MSR, MRS (for PSRs) */
8270 if (op1 & 1) {
8271 /* PSR = reg */
8272 tmp = load_reg(s, rm);
8273 i = ((op1 & 2) != 0);
8274 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8275 goto illegal_op;
8276 } else {
8277 /* reg = PSR */
8278 rd = (insn >> 12) & 0xf;
8279 if (op1 & 2) {
8280 if (IS_USER(s))
8281 goto illegal_op;
8282 tmp = load_cpu_field(spsr);
8283 } else {
8284 tmp = tcg_temp_new_i32();
8285 gen_helper_cpsr_read(tmp, cpu_env);
8287 store_reg(s, rd, tmp);
8289 break;
8290 case 0x1:
8291 if (op1 == 1) {
8292 /* branch/exchange thumb (bx). */
8293 ARCH(4T);
8294 tmp = load_reg(s, rm);
8295 gen_bx(s, tmp);
8296 } else if (op1 == 3) {
8297 /* clz */
8298 ARCH(5);
8299 rd = (insn >> 12) & 0xf;
8300 tmp = load_reg(s, rm);
8301 gen_helper_clz(tmp, tmp);
8302 store_reg(s, rd, tmp);
8303 } else {
8304 goto illegal_op;
8306 break;
8307 case 0x2:
8308 if (op1 == 1) {
8309 ARCH(5J); /* bxj */
8310 /* Trivial implementation equivalent to bx. */
8311 tmp = load_reg(s, rm);
8312 gen_bx(s, tmp);
8313 } else {
8314 goto illegal_op;
8316 break;
8317 case 0x3:
8318 if (op1 != 1)
8319 goto illegal_op;
8321 ARCH(5);
8322 /* branch link/exchange thumb (blx) */
8323 tmp = load_reg(s, rm);
8324 tmp2 = tcg_temp_new_i32();
8325 tcg_gen_movi_i32(tmp2, s->pc);
8326 store_reg(s, 14, tmp2);
8327 gen_bx(s, tmp);
8328 break;
8329 case 0x4:
8331 /* crc32/crc32c */
8332 uint32_t c = extract32(insn, 8, 4);
8334 /* Check this CPU supports ARMv8 CRC instructions.
8335 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8336 * Bits 8, 10 and 11 should be zero.
8338 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8339 (c & 0xd) != 0) {
8340 goto illegal_op;
8343 rn = extract32(insn, 16, 4);
8344 rd = extract32(insn, 12, 4);
8346 tmp = load_reg(s, rn);
8347 tmp2 = load_reg(s, rm);
8348 if (op1 == 0) {
8349 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8350 } else if (op1 == 1) {
8351 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8353 tmp3 = tcg_const_i32(1 << op1);
8354 if (c & 0x2) {
8355 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8356 } else {
8357 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8359 tcg_temp_free_i32(tmp2);
8360 tcg_temp_free_i32(tmp3);
8361 store_reg(s, rd, tmp);
8362 break;
8364 case 0x5: /* saturating add/subtract */
8365 ARCH(5TE);
8366 rd = (insn >> 12) & 0xf;
8367 rn = (insn >> 16) & 0xf;
8368 tmp = load_reg(s, rm);
8369 tmp2 = load_reg(s, rn);
8370 if (op1 & 2)
8371 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8372 if (op1 & 1)
8373 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8374 else
8375 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8376 tcg_temp_free_i32(tmp2);
8377 store_reg(s, rd, tmp);
8378 break;
8379 case 7:
8381 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8382 switch (op1) {
8383 case 1:
8384 /* bkpt */
8385 ARCH(5);
8386 gen_exception_insn(s, 4, EXCP_BKPT,
8387 syn_aa32_bkpt(imm16, false),
8388 default_exception_el(s));
8389 break;
8390 case 2:
8391 /* Hypervisor call (v7) */
8392 ARCH(7);
8393 if (IS_USER(s)) {
8394 goto illegal_op;
8396 gen_hvc(s, imm16);
8397 break;
8398 case 3:
8399 /* Secure monitor call (v6+) */
8400 ARCH(6K);
8401 if (IS_USER(s)) {
8402 goto illegal_op;
8404 gen_smc(s);
8405 break;
8406 default:
8407 goto illegal_op;
8409 break;
8411 case 0x8: /* signed multiply */
8412 case 0xa:
8413 case 0xc:
8414 case 0xe:
8415 ARCH(5TE);
8416 rs = (insn >> 8) & 0xf;
8417 rn = (insn >> 12) & 0xf;
8418 rd = (insn >> 16) & 0xf;
8419 if (op1 == 1) {
8420 /* (32 * 16) >> 16 */
8421 tmp = load_reg(s, rm);
8422 tmp2 = load_reg(s, rs);
8423 if (sh & 4)
8424 tcg_gen_sari_i32(tmp2, tmp2, 16);
8425 else
8426 gen_sxth(tmp2);
8427 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8428 tcg_gen_shri_i64(tmp64, tmp64, 16);
8429 tmp = tcg_temp_new_i32();
8430 tcg_gen_extrl_i64_i32(tmp, tmp64);
8431 tcg_temp_free_i64(tmp64);
8432 if ((sh & 2) == 0) {
8433 tmp2 = load_reg(s, rn);
8434 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8435 tcg_temp_free_i32(tmp2);
8437 store_reg(s, rd, tmp);
8438 } else {
8439 /* 16 * 16 */
8440 tmp = load_reg(s, rm);
8441 tmp2 = load_reg(s, rs);
8442 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8443 tcg_temp_free_i32(tmp2);
8444 if (op1 == 2) {
8445 tmp64 = tcg_temp_new_i64();
8446 tcg_gen_ext_i32_i64(tmp64, tmp);
8447 tcg_temp_free_i32(tmp);
8448 gen_addq(s, tmp64, rn, rd);
8449 gen_storeq_reg(s, rn, rd, tmp64);
8450 tcg_temp_free_i64(tmp64);
8451 } else {
8452 if (op1 == 0) {
8453 tmp2 = load_reg(s, rn);
8454 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8455 tcg_temp_free_i32(tmp2);
8457 store_reg(s, rd, tmp);
8460 break;
8461 default:
8462 goto illegal_op;
8464 } else if (((insn & 0x0e000000) == 0 &&
8465 (insn & 0x00000090) != 0x90) ||
8466 ((insn & 0x0e000000) == (1 << 25))) {
8467 int set_cc, logic_cc, shiftop;
8469 op1 = (insn >> 21) & 0xf;
8470 set_cc = (insn >> 20) & 1;
8471 logic_cc = table_logic_cc[op1] & set_cc;
8473 /* data processing instruction */
8474 if (insn & (1 << 25)) {
8475 /* immediate operand */
8476 val = insn & 0xff;
8477 shift = ((insn >> 8) & 0xf) * 2;
8478 if (shift) {
8479 val = (val >> shift) | (val << (32 - shift));
8481 tmp2 = tcg_temp_new_i32();
8482 tcg_gen_movi_i32(tmp2, val);
8483 if (logic_cc && shift) {
8484 gen_set_CF_bit31(tmp2);
8486 } else {
8487 /* register */
8488 rm = (insn) & 0xf;
8489 tmp2 = load_reg(s, rm);
8490 shiftop = (insn >> 5) & 3;
8491 if (!(insn & (1 << 4))) {
8492 shift = (insn >> 7) & 0x1f;
8493 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8494 } else {
8495 rs = (insn >> 8) & 0xf;
8496 tmp = load_reg(s, rs);
8497 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8500 if (op1 != 0x0f && op1 != 0x0d) {
8501 rn = (insn >> 16) & 0xf;
8502 tmp = load_reg(s, rn);
8503 } else {
8504 TCGV_UNUSED_I32(tmp);
8506 rd = (insn >> 12) & 0xf;
8507 switch(op1) {
8508 case 0x00:
8509 tcg_gen_and_i32(tmp, tmp, tmp2);
8510 if (logic_cc) {
8511 gen_logic_CC(tmp);
8513 store_reg_bx(s, rd, tmp);
8514 break;
8515 case 0x01:
8516 tcg_gen_xor_i32(tmp, tmp, tmp2);
8517 if (logic_cc) {
8518 gen_logic_CC(tmp);
8520 store_reg_bx(s, rd, tmp);
8521 break;
8522 case 0x02:
8523 if (set_cc && rd == 15) {
8524 /* SUBS r15, ... is used for exception return. */
8525 if (IS_USER(s)) {
8526 goto illegal_op;
8528 gen_sub_CC(tmp, tmp, tmp2);
8529 gen_exception_return(s, tmp);
8530 } else {
8531 if (set_cc) {
8532 gen_sub_CC(tmp, tmp, tmp2);
8533 } else {
8534 tcg_gen_sub_i32(tmp, tmp, tmp2);
8536 store_reg_bx(s, rd, tmp);
8538 break;
8539 case 0x03:
8540 if (set_cc) {
8541 gen_sub_CC(tmp, tmp2, tmp);
8542 } else {
8543 tcg_gen_sub_i32(tmp, tmp2, tmp);
8545 store_reg_bx(s, rd, tmp);
8546 break;
8547 case 0x04:
8548 if (set_cc) {
8549 gen_add_CC(tmp, tmp, tmp2);
8550 } else {
8551 tcg_gen_add_i32(tmp, tmp, tmp2);
8553 store_reg_bx(s, rd, tmp);
8554 break;
8555 case 0x05:
8556 if (set_cc) {
8557 gen_adc_CC(tmp, tmp, tmp2);
8558 } else {
8559 gen_add_carry(tmp, tmp, tmp2);
8561 store_reg_bx(s, rd, tmp);
8562 break;
8563 case 0x06:
8564 if (set_cc) {
8565 gen_sbc_CC(tmp, tmp, tmp2);
8566 } else {
8567 gen_sub_carry(tmp, tmp, tmp2);
8569 store_reg_bx(s, rd, tmp);
8570 break;
8571 case 0x07:
8572 if (set_cc) {
8573 gen_sbc_CC(tmp, tmp2, tmp);
8574 } else {
8575 gen_sub_carry(tmp, tmp2, tmp);
8577 store_reg_bx(s, rd, tmp);
8578 break;
8579 case 0x08:
8580 if (set_cc) {
8581 tcg_gen_and_i32(tmp, tmp, tmp2);
8582 gen_logic_CC(tmp);
8584 tcg_temp_free_i32(tmp);
8585 break;
8586 case 0x09:
8587 if (set_cc) {
8588 tcg_gen_xor_i32(tmp, tmp, tmp2);
8589 gen_logic_CC(tmp);
8591 tcg_temp_free_i32(tmp);
8592 break;
8593 case 0x0a:
8594 if (set_cc) {
8595 gen_sub_CC(tmp, tmp, tmp2);
8597 tcg_temp_free_i32(tmp);
8598 break;
8599 case 0x0b:
8600 if (set_cc) {
8601 gen_add_CC(tmp, tmp, tmp2);
8603 tcg_temp_free_i32(tmp);
8604 break;
8605 case 0x0c:
8606 tcg_gen_or_i32(tmp, tmp, tmp2);
8607 if (logic_cc) {
8608 gen_logic_CC(tmp);
8610 store_reg_bx(s, rd, tmp);
8611 break;
8612 case 0x0d:
8613 if (logic_cc && rd == 15) {
8614 /* MOVS r15, ... is used for exception return. */
8615 if (IS_USER(s)) {
8616 goto illegal_op;
8618 gen_exception_return(s, tmp2);
8619 } else {
8620 if (logic_cc) {
8621 gen_logic_CC(tmp2);
8623 store_reg_bx(s, rd, tmp2);
8625 break;
8626 case 0x0e:
8627 tcg_gen_andc_i32(tmp, tmp, tmp2);
8628 if (logic_cc) {
8629 gen_logic_CC(tmp);
8631 store_reg_bx(s, rd, tmp);
8632 break;
8633 default:
8634 case 0x0f:
8635 tcg_gen_not_i32(tmp2, tmp2);
8636 if (logic_cc) {
8637 gen_logic_CC(tmp2);
8639 store_reg_bx(s, rd, tmp2);
8640 break;
8642 if (op1 != 0x0f && op1 != 0x0d) {
8643 tcg_temp_free_i32(tmp2);
8645 } else {
8646 /* other instructions */
8647 op1 = (insn >> 24) & 0xf;
8648 switch(op1) {
8649 case 0x0:
8650 case 0x1:
8651 /* multiplies, extra load/stores */
8652 sh = (insn >> 5) & 3;
8653 if (sh == 0) {
8654 if (op1 == 0x0) {
8655 rd = (insn >> 16) & 0xf;
8656 rn = (insn >> 12) & 0xf;
8657 rs = (insn >> 8) & 0xf;
8658 rm = (insn) & 0xf;
8659 op1 = (insn >> 20) & 0xf;
8660 switch (op1) {
8661 case 0: case 1: case 2: case 3: case 6:
8662 /* 32 bit mul */
8663 tmp = load_reg(s, rs);
8664 tmp2 = load_reg(s, rm);
8665 tcg_gen_mul_i32(tmp, tmp, tmp2);
8666 tcg_temp_free_i32(tmp2);
8667 if (insn & (1 << 22)) {
8668 /* Subtract (mls) */
8669 ARCH(6T2);
8670 tmp2 = load_reg(s, rn);
8671 tcg_gen_sub_i32(tmp, tmp2, tmp);
8672 tcg_temp_free_i32(tmp2);
8673 } else if (insn & (1 << 21)) {
8674 /* Add */
8675 tmp2 = load_reg(s, rn);
8676 tcg_gen_add_i32(tmp, tmp, tmp2);
8677 tcg_temp_free_i32(tmp2);
8679 if (insn & (1 << 20))
8680 gen_logic_CC(tmp);
8681 store_reg(s, rd, tmp);
8682 break;
8683 case 4:
8684 /* 64 bit mul double accumulate (UMAAL) */
8685 ARCH(6);
8686 tmp = load_reg(s, rs);
8687 tmp2 = load_reg(s, rm);
8688 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8689 gen_addq_lo(s, tmp64, rn);
8690 gen_addq_lo(s, tmp64, rd);
8691 gen_storeq_reg(s, rn, rd, tmp64);
8692 tcg_temp_free_i64(tmp64);
8693 break;
8694 case 8: case 9: case 10: case 11:
8695 case 12: case 13: case 14: case 15:
8696 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8697 tmp = load_reg(s, rs);
8698 tmp2 = load_reg(s, rm);
8699 if (insn & (1 << 22)) {
8700 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8701 } else {
8702 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8704 if (insn & (1 << 21)) { /* mult accumulate */
8705 TCGv_i32 al = load_reg(s, rn);
8706 TCGv_i32 ah = load_reg(s, rd);
8707 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8708 tcg_temp_free_i32(al);
8709 tcg_temp_free_i32(ah);
8711 if (insn & (1 << 20)) {
8712 gen_logicq_cc(tmp, tmp2);
8714 store_reg(s, rn, tmp);
8715 store_reg(s, rd, tmp2);
8716 break;
8717 default:
8718 goto illegal_op;
8720 } else {
8721 rn = (insn >> 16) & 0xf;
8722 rd = (insn >> 12) & 0xf;
8723 if (insn & (1 << 23)) {
8724 /* load/store exclusive */
8725 int op2 = (insn >> 8) & 3;
8726 op1 = (insn >> 21) & 0x3;
8728 switch (op2) {
8729 case 0: /* lda/stl */
8730 if (op1 == 1) {
8731 goto illegal_op;
8733 ARCH(8);
8734 break;
8735 case 1: /* reserved */
8736 goto illegal_op;
8737 case 2: /* ldaex/stlex */
8738 ARCH(8);
8739 break;
8740 case 3: /* ldrex/strex */
8741 if (op1) {
8742 ARCH(6K);
8743 } else {
8744 ARCH(6);
8746 break;
8749 addr = tcg_temp_local_new_i32();
8750 load_reg_var(s, addr, rn);
8752 /* Since the emulation does not have barriers,
8753 the acquire/release semantics need no special
8754 handling */
8755 if (op2 == 0) {
8756 if (insn & (1 << 20)) {
8757 tmp = tcg_temp_new_i32();
8758 switch (op1) {
8759 case 0: /* lda */
8760 gen_aa32_ld32u(s, tmp, addr,
8761 get_mem_index(s));
8762 break;
8763 case 2: /* ldab */
8764 gen_aa32_ld8u(s, tmp, addr,
8765 get_mem_index(s));
8766 break;
8767 case 3: /* ldah */
8768 gen_aa32_ld16u(s, tmp, addr,
8769 get_mem_index(s));
8770 break;
8771 default:
8772 abort();
8774 store_reg(s, rd, tmp);
8775 } else {
8776 rm = insn & 0xf;
8777 tmp = load_reg(s, rm);
8778 switch (op1) {
8779 case 0: /* stl */
8780 gen_aa32_st32(s, tmp, addr,
8781 get_mem_index(s));
8782 break;
8783 case 2: /* stlb */
8784 gen_aa32_st8(s, tmp, addr,
8785 get_mem_index(s));
8786 break;
8787 case 3: /* stlh */
8788 gen_aa32_st16(s, tmp, addr,
8789 get_mem_index(s));
8790 break;
8791 default:
8792 abort();
8794 tcg_temp_free_i32(tmp);
8796 } else if (insn & (1 << 20)) {
8797 switch (op1) {
8798 case 0: /* ldrex */
8799 gen_load_exclusive(s, rd, 15, addr, 2);
8800 break;
8801 case 1: /* ldrexd */
8802 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8803 break;
8804 case 2: /* ldrexb */
8805 gen_load_exclusive(s, rd, 15, addr, 0);
8806 break;
8807 case 3: /* ldrexh */
8808 gen_load_exclusive(s, rd, 15, addr, 1);
8809 break;
8810 default:
8811 abort();
8813 } else {
8814 rm = insn & 0xf;
8815 switch (op1) {
8816 case 0: /* strex */
8817 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8818 break;
8819 case 1: /* strexd */
8820 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8821 break;
8822 case 2: /* strexb */
8823 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8824 break;
8825 case 3: /* strexh */
8826 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8827 break;
8828 default:
8829 abort();
8832 tcg_temp_free_i32(addr);
8833 } else {
8834 /* SWP instruction */
8835 rm = (insn) & 0xf;
8837 /* ??? This is not really atomic. However we know
8838 we never have multiple CPUs running in parallel,
8839 so it is good enough. */
8840 addr = load_reg(s, rn);
8841 tmp = load_reg(s, rm);
8842 tmp2 = tcg_temp_new_i32();
8843 if (insn & (1 << 22)) {
8844 gen_aa32_ld8u(s, tmp2, addr, get_mem_index(s));
8845 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8846 } else {
8847 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8848 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8850 tcg_temp_free_i32(tmp);
8851 tcg_temp_free_i32(addr);
8852 store_reg(s, rd, tmp2);
8855 } else {
8856 int address_offset;
8857 bool load = insn & (1 << 20);
8858 bool doubleword = false;
8859 /* Misc load/store */
8860 rn = (insn >> 16) & 0xf;
8861 rd = (insn >> 12) & 0xf;
8863 if (!load && (sh & 2)) {
8864 /* doubleword */
8865 ARCH(5TE);
8866 if (rd & 1) {
8867 /* UNPREDICTABLE; we choose to UNDEF */
8868 goto illegal_op;
8870 load = (sh & 1) == 0;
8871 doubleword = true;
8874 addr = load_reg(s, rn);
8875 if (insn & (1 << 24))
8876 gen_add_datah_offset(s, insn, 0, addr);
8877 address_offset = 0;
8879 if (doubleword) {
8880 if (!load) {
8881 /* store */
8882 tmp = load_reg(s, rd);
8883 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8884 tcg_temp_free_i32(tmp);
8885 tcg_gen_addi_i32(addr, addr, 4);
8886 tmp = load_reg(s, rd + 1);
8887 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8888 tcg_temp_free_i32(tmp);
8889 } else {
8890 /* load */
8891 tmp = tcg_temp_new_i32();
8892 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8893 store_reg(s, rd, tmp);
8894 tcg_gen_addi_i32(addr, addr, 4);
8895 tmp = tcg_temp_new_i32();
8896 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8897 rd++;
8899 address_offset = -4;
8900 } else if (load) {
8901 /* load */
8902 tmp = tcg_temp_new_i32();
8903 switch (sh) {
8904 case 1:
8905 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8906 break;
8907 case 2:
8908 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
8909 break;
8910 default:
8911 case 3:
8912 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
8913 break;
8915 } else {
8916 /* store */
8917 tmp = load_reg(s, rd);
8918 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8919 tcg_temp_free_i32(tmp);
8921 /* Perform base writeback before the loaded value to
8922 ensure correct behavior with overlapping index registers.
8923 ldrd with base writeback is undefined if the
8924 destination and index registers overlap. */
8925 if (!(insn & (1 << 24))) {
8926 gen_add_datah_offset(s, insn, address_offset, addr);
8927 store_reg(s, rn, addr);
8928 } else if (insn & (1 << 21)) {
8929 if (address_offset)
8930 tcg_gen_addi_i32(addr, addr, address_offset);
8931 store_reg(s, rn, addr);
8932 } else {
8933 tcg_temp_free_i32(addr);
8935 if (load) {
8936 /* Complete the load. */
8937 store_reg(s, rd, tmp);
8940 break;
8941 case 0x4:
8942 case 0x5:
8943 goto do_ldst;
8944 case 0x6:
8945 case 0x7:
8946 if (insn & (1 << 4)) {
8947 ARCH(6);
8948 /* Armv6 Media instructions. */
8949 rm = insn & 0xf;
8950 rn = (insn >> 16) & 0xf;
8951 rd = (insn >> 12) & 0xf;
8952 rs = (insn >> 8) & 0xf;
8953 switch ((insn >> 23) & 3) {
8954 case 0: /* Parallel add/subtract. */
8955 op1 = (insn >> 20) & 7;
8956 tmp = load_reg(s, rn);
8957 tmp2 = load_reg(s, rm);
8958 sh = (insn >> 5) & 7;
8959 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8960 goto illegal_op;
8961 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8962 tcg_temp_free_i32(tmp2);
8963 store_reg(s, rd, tmp);
8964 break;
8965 case 1:
8966 if ((insn & 0x00700020) == 0) {
8967 /* Halfword pack. */
8968 tmp = load_reg(s, rn);
8969 tmp2 = load_reg(s, rm);
8970 shift = (insn >> 7) & 0x1f;
8971 if (insn & (1 << 6)) {
8972 /* pkhtb */
8973 if (shift == 0)
8974 shift = 31;
8975 tcg_gen_sari_i32(tmp2, tmp2, shift);
8976 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8977 tcg_gen_ext16u_i32(tmp2, tmp2);
8978 } else {
8979 /* pkhbt */
8980 if (shift)
8981 tcg_gen_shli_i32(tmp2, tmp2, shift);
8982 tcg_gen_ext16u_i32(tmp, tmp);
8983 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8985 tcg_gen_or_i32(tmp, tmp, tmp2);
8986 tcg_temp_free_i32(tmp2);
8987 store_reg(s, rd, tmp);
8988 } else if ((insn & 0x00200020) == 0x00200000) {
8989 /* [us]sat */
8990 tmp = load_reg(s, rm);
8991 shift = (insn >> 7) & 0x1f;
8992 if (insn & (1 << 6)) {
8993 if (shift == 0)
8994 shift = 31;
8995 tcg_gen_sari_i32(tmp, tmp, shift);
8996 } else {
8997 tcg_gen_shli_i32(tmp, tmp, shift);
8999 sh = (insn >> 16) & 0x1f;
9000 tmp2 = tcg_const_i32(sh);
9001 if (insn & (1 << 22))
9002 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9003 else
9004 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9005 tcg_temp_free_i32(tmp2);
9006 store_reg(s, rd, tmp);
9007 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9008 /* [us]sat16 */
9009 tmp = load_reg(s, rm);
9010 sh = (insn >> 16) & 0x1f;
9011 tmp2 = tcg_const_i32(sh);
9012 if (insn & (1 << 22))
9013 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9014 else
9015 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9016 tcg_temp_free_i32(tmp2);
9017 store_reg(s, rd, tmp);
9018 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9019 /* Select bytes. */
9020 tmp = load_reg(s, rn);
9021 tmp2 = load_reg(s, rm);
9022 tmp3 = tcg_temp_new_i32();
9023 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9024 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9025 tcg_temp_free_i32(tmp3);
9026 tcg_temp_free_i32(tmp2);
9027 store_reg(s, rd, tmp);
9028 } else if ((insn & 0x000003e0) == 0x00000060) {
9029 tmp = load_reg(s, rm);
9030 shift = (insn >> 10) & 3;
9031 /* ??? In many cases it's not necessary to do a
9032 rotate, a shift is sufficient. */
9033 if (shift != 0)
9034 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9035 op1 = (insn >> 20) & 7;
9036 switch (op1) {
9037 case 0: gen_sxtb16(tmp); break;
9038 case 2: gen_sxtb(tmp); break;
9039 case 3: gen_sxth(tmp); break;
9040 case 4: gen_uxtb16(tmp); break;
9041 case 6: gen_uxtb(tmp); break;
9042 case 7: gen_uxth(tmp); break;
9043 default: goto illegal_op;
9045 if (rn != 15) {
9046 tmp2 = load_reg(s, rn);
9047 if ((op1 & 3) == 0) {
9048 gen_add16(tmp, tmp2);
9049 } else {
9050 tcg_gen_add_i32(tmp, tmp, tmp2);
9051 tcg_temp_free_i32(tmp2);
9054 store_reg(s, rd, tmp);
9055 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9056 /* rev */
9057 tmp = load_reg(s, rm);
9058 if (insn & (1 << 22)) {
9059 if (insn & (1 << 7)) {
9060 gen_revsh(tmp);
9061 } else {
9062 ARCH(6T2);
9063 gen_helper_rbit(tmp, tmp);
9065 } else {
9066 if (insn & (1 << 7))
9067 gen_rev16(tmp);
9068 else
9069 tcg_gen_bswap32_i32(tmp, tmp);
9071 store_reg(s, rd, tmp);
9072 } else {
9073 goto illegal_op;
9075 break;
9076 case 2: /* Multiplies (Type 3). */
9077 switch ((insn >> 20) & 0x7) {
9078 case 5:
9079 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9080 /* op2 not 00x or 11x : UNDEF */
9081 goto illegal_op;
9083 /* Signed multiply most significant [accumulate].
9084 (SMMUL, SMMLA, SMMLS) */
9085 tmp = load_reg(s, rm);
9086 tmp2 = load_reg(s, rs);
9087 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9089 if (rd != 15) {
9090 tmp = load_reg(s, rd);
9091 if (insn & (1 << 6)) {
9092 tmp64 = gen_subq_msw(tmp64, tmp);
9093 } else {
9094 tmp64 = gen_addq_msw(tmp64, tmp);
9097 if (insn & (1 << 5)) {
9098 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9100 tcg_gen_shri_i64(tmp64, tmp64, 32);
9101 tmp = tcg_temp_new_i32();
9102 tcg_gen_extrl_i64_i32(tmp, tmp64);
9103 tcg_temp_free_i64(tmp64);
9104 store_reg(s, rn, tmp);
9105 break;
9106 case 0:
9107 case 4:
9108 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9109 if (insn & (1 << 7)) {
9110 goto illegal_op;
9112 tmp = load_reg(s, rm);
9113 tmp2 = load_reg(s, rs);
9114 if (insn & (1 << 5))
9115 gen_swap_half(tmp2);
9116 gen_smul_dual(tmp, tmp2);
9117 if (insn & (1 << 22)) {
9118 /* smlald, smlsld */
9119 TCGv_i64 tmp64_2;
9121 tmp64 = tcg_temp_new_i64();
9122 tmp64_2 = tcg_temp_new_i64();
9123 tcg_gen_ext_i32_i64(tmp64, tmp);
9124 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9125 tcg_temp_free_i32(tmp);
9126 tcg_temp_free_i32(tmp2);
9127 if (insn & (1 << 6)) {
9128 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9129 } else {
9130 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9132 tcg_temp_free_i64(tmp64_2);
9133 gen_addq(s, tmp64, rd, rn);
9134 gen_storeq_reg(s, rd, rn, tmp64);
9135 tcg_temp_free_i64(tmp64);
9136 } else {
9137 /* smuad, smusd, smlad, smlsd */
9138 if (insn & (1 << 6)) {
9139 /* This subtraction cannot overflow. */
9140 tcg_gen_sub_i32(tmp, tmp, tmp2);
9141 } else {
9142 /* This addition cannot overflow 32 bits;
9143 * however it may overflow considered as a
9144 * signed operation, in which case we must set
9145 * the Q flag.
9147 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9149 tcg_temp_free_i32(tmp2);
9150 if (rd != 15)
9152 tmp2 = load_reg(s, rd);
9153 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9154 tcg_temp_free_i32(tmp2);
9156 store_reg(s, rn, tmp);
9158 break;
9159 case 1:
9160 case 3:
9161 /* SDIV, UDIV */
9162 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9163 goto illegal_op;
9165 if (((insn >> 5) & 7) || (rd != 15)) {
9166 goto illegal_op;
9168 tmp = load_reg(s, rm);
9169 tmp2 = load_reg(s, rs);
9170 if (insn & (1 << 21)) {
9171 gen_helper_udiv(tmp, tmp, tmp2);
9172 } else {
9173 gen_helper_sdiv(tmp, tmp, tmp2);
9175 tcg_temp_free_i32(tmp2);
9176 store_reg(s, rn, tmp);
9177 break;
9178 default:
9179 goto illegal_op;
9181 break;
9182 case 3:
9183 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9184 switch (op1) {
9185 case 0: /* Unsigned sum of absolute differences. */
9186 ARCH(6);
9187 tmp = load_reg(s, rm);
9188 tmp2 = load_reg(s, rs);
9189 gen_helper_usad8(tmp, tmp, tmp2);
9190 tcg_temp_free_i32(tmp2);
9191 if (rd != 15) {
9192 tmp2 = load_reg(s, rd);
9193 tcg_gen_add_i32(tmp, tmp, tmp2);
9194 tcg_temp_free_i32(tmp2);
9196 store_reg(s, rn, tmp);
9197 break;
9198 case 0x20: case 0x24: case 0x28: case 0x2c:
9199 /* Bitfield insert/clear. */
9200 ARCH(6T2);
9201 shift = (insn >> 7) & 0x1f;
9202 i = (insn >> 16) & 0x1f;
9203 if (i < shift) {
9204 /* UNPREDICTABLE; we choose to UNDEF */
9205 goto illegal_op;
9207 i = i + 1 - shift;
9208 if (rm == 15) {
9209 tmp = tcg_temp_new_i32();
9210 tcg_gen_movi_i32(tmp, 0);
9211 } else {
9212 tmp = load_reg(s, rm);
9214 if (i != 32) {
9215 tmp2 = load_reg(s, rd);
9216 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9217 tcg_temp_free_i32(tmp2);
9219 store_reg(s, rd, tmp);
9220 break;
9221 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9222 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9223 ARCH(6T2);
9224 tmp = load_reg(s, rm);
9225 shift = (insn >> 7) & 0x1f;
9226 i = ((insn >> 16) & 0x1f) + 1;
9227 if (shift + i > 32)
9228 goto illegal_op;
9229 if (i < 32) {
9230 if (op1 & 0x20) {
9231 gen_ubfx(tmp, shift, (1u << i) - 1);
9232 } else {
9233 gen_sbfx(tmp, shift, i);
9236 store_reg(s, rd, tmp);
9237 break;
9238 default:
9239 goto illegal_op;
9241 break;
9243 break;
9245 do_ldst:
9246 /* Check for undefined extension instructions
9247 * per the ARM Bible IE:
9248 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9250 sh = (0xf << 20) | (0xf << 4);
9251 if (op1 == 0x7 && ((insn & sh) == sh))
9253 goto illegal_op;
9255 /* load/store byte/word */
9256 rn = (insn >> 16) & 0xf;
9257 rd = (insn >> 12) & 0xf;
9258 tmp2 = load_reg(s, rn);
9259 if ((insn & 0x01200000) == 0x00200000) {
9260 /* ldrt/strt */
9261 i = get_a32_user_mem_index(s);
9262 } else {
9263 i = get_mem_index(s);
9265 if (insn & (1 << 24))
9266 gen_add_data_offset(s, insn, tmp2);
9267 if (insn & (1 << 20)) {
9268 /* load */
9269 tmp = tcg_temp_new_i32();
9270 if (insn & (1 << 22)) {
9271 gen_aa32_ld8u(s, tmp, tmp2, i);
9272 } else {
9273 gen_aa32_ld32u(s, tmp, tmp2, i);
9275 } else {
9276 /* store */
9277 tmp = load_reg(s, rd);
9278 if (insn & (1 << 22)) {
9279 gen_aa32_st8(s, tmp, tmp2, i);
9280 } else {
9281 gen_aa32_st32(s, tmp, tmp2, i);
9283 tcg_temp_free_i32(tmp);
9285 if (!(insn & (1 << 24))) {
9286 gen_add_data_offset(s, insn, tmp2);
9287 store_reg(s, rn, tmp2);
9288 } else if (insn & (1 << 21)) {
9289 store_reg(s, rn, tmp2);
9290 } else {
9291 tcg_temp_free_i32(tmp2);
9293 if (insn & (1 << 20)) {
9294 /* Complete the load. */
9295 store_reg_from_load(s, rd, tmp);
9297 break;
9298 case 0x08:
9299 case 0x09:
9301 int j, n, loaded_base;
9302 bool exc_return = false;
9303 bool is_load = extract32(insn, 20, 1);
9304 bool user = false;
9305 TCGv_i32 loaded_var;
9306 /* load/store multiple words */
9307 /* XXX: store correct base if write back */
9308 if (insn & (1 << 22)) {
9309 /* LDM (user), LDM (exception return) and STM (user) */
9310 if (IS_USER(s))
9311 goto illegal_op; /* only usable in supervisor mode */
9313 if (is_load && extract32(insn, 15, 1)) {
9314 exc_return = true;
9315 } else {
9316 user = true;
9319 rn = (insn >> 16) & 0xf;
9320 addr = load_reg(s, rn);
9322 /* compute total size */
9323 loaded_base = 0;
9324 TCGV_UNUSED_I32(loaded_var);
9325 n = 0;
9326 for(i=0;i<16;i++) {
9327 if (insn & (1 << i))
9328 n++;
9330 /* XXX: test invalid n == 0 case ? */
9331 if (insn & (1 << 23)) {
9332 if (insn & (1 << 24)) {
9333 /* pre increment */
9334 tcg_gen_addi_i32(addr, addr, 4);
9335 } else {
9336 /* post increment */
9338 } else {
9339 if (insn & (1 << 24)) {
9340 /* pre decrement */
9341 tcg_gen_addi_i32(addr, addr, -(n * 4));
9342 } else {
9343 /* post decrement */
9344 if (n != 1)
9345 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9348 j = 0;
9349 for(i=0;i<16;i++) {
9350 if (insn & (1 << i)) {
9351 if (is_load) {
9352 /* load */
9353 tmp = tcg_temp_new_i32();
9354 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9355 if (user) {
9356 tmp2 = tcg_const_i32(i);
9357 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9358 tcg_temp_free_i32(tmp2);
9359 tcg_temp_free_i32(tmp);
9360 } else if (i == rn) {
9361 loaded_var = tmp;
9362 loaded_base = 1;
9363 } else {
9364 store_reg_from_load(s, i, tmp);
9366 } else {
9367 /* store */
9368 if (i == 15) {
9369 /* special case: r15 = PC + 8 */
9370 val = (long)s->pc + 4;
9371 tmp = tcg_temp_new_i32();
9372 tcg_gen_movi_i32(tmp, val);
9373 } else if (user) {
9374 tmp = tcg_temp_new_i32();
9375 tmp2 = tcg_const_i32(i);
9376 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9377 tcg_temp_free_i32(tmp2);
9378 } else {
9379 tmp = load_reg(s, i);
9381 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9382 tcg_temp_free_i32(tmp);
9384 j++;
9385 /* no need to add after the last transfer */
9386 if (j != n)
9387 tcg_gen_addi_i32(addr, addr, 4);
9390 if (insn & (1 << 21)) {
9391 /* write back */
9392 if (insn & (1 << 23)) {
9393 if (insn & (1 << 24)) {
9394 /* pre increment */
9395 } else {
9396 /* post increment */
9397 tcg_gen_addi_i32(addr, addr, 4);
9399 } else {
9400 if (insn & (1 << 24)) {
9401 /* pre decrement */
9402 if (n != 1)
9403 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9404 } else {
9405 /* post decrement */
9406 tcg_gen_addi_i32(addr, addr, -(n * 4));
9409 store_reg(s, rn, addr);
9410 } else {
9411 tcg_temp_free_i32(addr);
9413 if (loaded_base) {
9414 store_reg(s, rn, loaded_var);
9416 if (exc_return) {
9417 /* Restore CPSR from SPSR. */
9418 tmp = load_cpu_field(spsr);
9419 gen_helper_cpsr_write_eret(cpu_env, tmp);
9420 tcg_temp_free_i32(tmp);
9421 s->is_jmp = DISAS_JUMP;
9424 break;
9425 case 0xa:
9426 case 0xb:
9428 int32_t offset;
9430 /* branch (and link) */
9431 val = (int32_t)s->pc;
9432 if (insn & (1 << 24)) {
9433 tmp = tcg_temp_new_i32();
9434 tcg_gen_movi_i32(tmp, val);
9435 store_reg(s, 14, tmp);
9437 offset = sextract32(insn << 2, 0, 26);
9438 val += offset + 4;
9439 gen_jmp(s, val);
9441 break;
9442 case 0xc:
9443 case 0xd:
9444 case 0xe:
9445 if (((insn >> 8) & 0xe) == 10) {
9446 /* VFP. */
9447 if (disas_vfp_insn(s, insn)) {
9448 goto illegal_op;
9450 } else if (disas_coproc_insn(s, insn)) {
9451 /* Coprocessor. */
9452 goto illegal_op;
9454 break;
9455 case 0xf:
9456 /* swi */
9457 gen_set_pc_im(s, s->pc);
9458 s->svc_imm = extract32(insn, 0, 24);
9459 s->is_jmp = DISAS_SWI;
9460 break;
9461 default:
9462 illegal_op:
9463 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9464 default_exception_el(s));
9465 break;
9470 /* Return true if this is a Thumb-2 logical op. */
9471 static int
9472 thumb2_logic_op(int op)
9474 return (op < 8);
9477 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9478 then set condition code flags based on the result of the operation.
9479 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9480 to the high bit of T1.
9481 Returns zero if the opcode is valid. */
9483 static int
9484 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9485 TCGv_i32 t0, TCGv_i32 t1)
9487 int logic_cc;
9489 logic_cc = 0;
9490 switch (op) {
9491 case 0: /* and */
9492 tcg_gen_and_i32(t0, t0, t1);
9493 logic_cc = conds;
9494 break;
9495 case 1: /* bic */
9496 tcg_gen_andc_i32(t0, t0, t1);
9497 logic_cc = conds;
9498 break;
9499 case 2: /* orr */
9500 tcg_gen_or_i32(t0, t0, t1);
9501 logic_cc = conds;
9502 break;
9503 case 3: /* orn */
9504 tcg_gen_orc_i32(t0, t0, t1);
9505 logic_cc = conds;
9506 break;
9507 case 4: /* eor */
9508 tcg_gen_xor_i32(t0, t0, t1);
9509 logic_cc = conds;
9510 break;
9511 case 8: /* add */
9512 if (conds)
9513 gen_add_CC(t0, t0, t1);
9514 else
9515 tcg_gen_add_i32(t0, t0, t1);
9516 break;
9517 case 10: /* adc */
9518 if (conds)
9519 gen_adc_CC(t0, t0, t1);
9520 else
9521 gen_adc(t0, t1);
9522 break;
9523 case 11: /* sbc */
9524 if (conds) {
9525 gen_sbc_CC(t0, t0, t1);
9526 } else {
9527 gen_sub_carry(t0, t0, t1);
9529 break;
9530 case 13: /* sub */
9531 if (conds)
9532 gen_sub_CC(t0, t0, t1);
9533 else
9534 tcg_gen_sub_i32(t0, t0, t1);
9535 break;
9536 case 14: /* rsb */
9537 if (conds)
9538 gen_sub_CC(t0, t1, t0);
9539 else
9540 tcg_gen_sub_i32(t0, t1, t0);
9541 break;
9542 default: /* 5, 6, 7, 9, 12, 15. */
9543 return 1;
9545 if (logic_cc) {
9546 gen_logic_CC(t0);
9547 if (shifter_out)
9548 gen_set_CF_bit31(t1);
9550 return 0;
9553 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9554 is not legal. */
9555 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9557 uint32_t insn, imm, shift, offset;
9558 uint32_t rd, rn, rm, rs;
9559 TCGv_i32 tmp;
9560 TCGv_i32 tmp2;
9561 TCGv_i32 tmp3;
9562 TCGv_i32 addr;
9563 TCGv_i64 tmp64;
9564 int op;
9565 int shiftop;
9566 int conds;
9567 int logic_cc;
9569 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9570 || arm_dc_feature(s, ARM_FEATURE_M))) {
9571 /* Thumb-1 cores may need to treat bl and blx as a pair of
9572 16-bit instructions to get correct prefetch abort behavior. */
9573 insn = insn_hw1;
9574 if ((insn & (1 << 12)) == 0) {
9575 ARCH(5);
9576 /* Second half of blx. */
9577 offset = ((insn & 0x7ff) << 1);
9578 tmp = load_reg(s, 14);
9579 tcg_gen_addi_i32(tmp, tmp, offset);
9580 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9582 tmp2 = tcg_temp_new_i32();
9583 tcg_gen_movi_i32(tmp2, s->pc | 1);
9584 store_reg(s, 14, tmp2);
9585 gen_bx(s, tmp);
9586 return 0;
9588 if (insn & (1 << 11)) {
9589 /* Second half of bl. */
9590 offset = ((insn & 0x7ff) << 1) | 1;
9591 tmp = load_reg(s, 14);
9592 tcg_gen_addi_i32(tmp, tmp, offset);
9594 tmp2 = tcg_temp_new_i32();
9595 tcg_gen_movi_i32(tmp2, s->pc | 1);
9596 store_reg(s, 14, tmp2);
9597 gen_bx(s, tmp);
9598 return 0;
9600 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9601 /* Instruction spans a page boundary. Implement it as two
9602 16-bit instructions in case the second half causes an
9603 prefetch abort. */
9604 offset = ((int32_t)insn << 21) >> 9;
9605 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9606 return 0;
9608 /* Fall through to 32-bit decode. */
9611 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9612 s->pc += 2;
9613 insn |= (uint32_t)insn_hw1 << 16;
9615 if ((insn & 0xf800e800) != 0xf000e800) {
9616 ARCH(6T2);
9619 rn = (insn >> 16) & 0xf;
9620 rs = (insn >> 12) & 0xf;
9621 rd = (insn >> 8) & 0xf;
9622 rm = insn & 0xf;
9623 switch ((insn >> 25) & 0xf) {
9624 case 0: case 1: case 2: case 3:
9625 /* 16-bit instructions. Should never happen. */
9626 abort();
9627 case 4:
9628 if (insn & (1 << 22)) {
9629 /* Other load/store, table branch. */
9630 if (insn & 0x01200000) {
9631 /* Load/store doubleword. */
9632 if (rn == 15) {
9633 addr = tcg_temp_new_i32();
9634 tcg_gen_movi_i32(addr, s->pc & ~3);
9635 } else {
9636 addr = load_reg(s, rn);
9638 offset = (insn & 0xff) * 4;
9639 if ((insn & (1 << 23)) == 0)
9640 offset = -offset;
9641 if (insn & (1 << 24)) {
9642 tcg_gen_addi_i32(addr, addr, offset);
9643 offset = 0;
9645 if (insn & (1 << 20)) {
9646 /* ldrd */
9647 tmp = tcg_temp_new_i32();
9648 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9649 store_reg(s, rs, tmp);
9650 tcg_gen_addi_i32(addr, addr, 4);
9651 tmp = tcg_temp_new_i32();
9652 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9653 store_reg(s, rd, tmp);
9654 } else {
9655 /* strd */
9656 tmp = load_reg(s, rs);
9657 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9658 tcg_temp_free_i32(tmp);
9659 tcg_gen_addi_i32(addr, addr, 4);
9660 tmp = load_reg(s, rd);
9661 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9662 tcg_temp_free_i32(tmp);
9664 if (insn & (1 << 21)) {
9665 /* Base writeback. */
9666 if (rn == 15)
9667 goto illegal_op;
9668 tcg_gen_addi_i32(addr, addr, offset - 4);
9669 store_reg(s, rn, addr);
9670 } else {
9671 tcg_temp_free_i32(addr);
9673 } else if ((insn & (1 << 23)) == 0) {
9674 /* Load/store exclusive word. */
9675 addr = tcg_temp_local_new_i32();
9676 load_reg_var(s, addr, rn);
9677 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9678 if (insn & (1 << 20)) {
9679 gen_load_exclusive(s, rs, 15, addr, 2);
9680 } else {
9681 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9683 tcg_temp_free_i32(addr);
9684 } else if ((insn & (7 << 5)) == 0) {
9685 /* Table Branch. */
9686 if (rn == 15) {
9687 addr = tcg_temp_new_i32();
9688 tcg_gen_movi_i32(addr, s->pc);
9689 } else {
9690 addr = load_reg(s, rn);
9692 tmp = load_reg(s, rm);
9693 tcg_gen_add_i32(addr, addr, tmp);
9694 if (insn & (1 << 4)) {
9695 /* tbh */
9696 tcg_gen_add_i32(addr, addr, tmp);
9697 tcg_temp_free_i32(tmp);
9698 tmp = tcg_temp_new_i32();
9699 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9700 } else { /* tbb */
9701 tcg_temp_free_i32(tmp);
9702 tmp = tcg_temp_new_i32();
9703 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9705 tcg_temp_free_i32(addr);
9706 tcg_gen_shli_i32(tmp, tmp, 1);
9707 tcg_gen_addi_i32(tmp, tmp, s->pc);
9708 store_reg(s, 15, tmp);
9709 } else {
9710 int op2 = (insn >> 6) & 0x3;
9711 op = (insn >> 4) & 0x3;
9712 switch (op2) {
9713 case 0:
9714 goto illegal_op;
9715 case 1:
9716 /* Load/store exclusive byte/halfword/doubleword */
9717 if (op == 2) {
9718 goto illegal_op;
9720 ARCH(7);
9721 break;
9722 case 2:
9723 /* Load-acquire/store-release */
9724 if (op == 3) {
9725 goto illegal_op;
9727 /* Fall through */
9728 case 3:
9729 /* Load-acquire/store-release exclusive */
9730 ARCH(8);
9731 break;
9733 addr = tcg_temp_local_new_i32();
9734 load_reg_var(s, addr, rn);
9735 if (!(op2 & 1)) {
9736 if (insn & (1 << 20)) {
9737 tmp = tcg_temp_new_i32();
9738 switch (op) {
9739 case 0: /* ldab */
9740 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9741 break;
9742 case 1: /* ldah */
9743 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9744 break;
9745 case 2: /* lda */
9746 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9747 break;
9748 default:
9749 abort();
9751 store_reg(s, rs, tmp);
9752 } else {
9753 tmp = load_reg(s, rs);
9754 switch (op) {
9755 case 0: /* stlb */
9756 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
9757 break;
9758 case 1: /* stlh */
9759 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
9760 break;
9761 case 2: /* stl */
9762 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9763 break;
9764 default:
9765 abort();
9767 tcg_temp_free_i32(tmp);
9769 } else if (insn & (1 << 20)) {
9770 gen_load_exclusive(s, rs, rd, addr, op);
9771 } else {
9772 gen_store_exclusive(s, rm, rs, rd, addr, op);
9774 tcg_temp_free_i32(addr);
9776 } else {
9777 /* Load/store multiple, RFE, SRS. */
9778 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9779 /* RFE, SRS: not available in user mode or on M profile */
9780 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9781 goto illegal_op;
9783 if (insn & (1 << 20)) {
9784 /* rfe */
9785 addr = load_reg(s, rn);
9786 if ((insn & (1 << 24)) == 0)
9787 tcg_gen_addi_i32(addr, addr, -8);
9788 /* Load PC into tmp and CPSR into tmp2. */
9789 tmp = tcg_temp_new_i32();
9790 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9791 tcg_gen_addi_i32(addr, addr, 4);
9792 tmp2 = tcg_temp_new_i32();
9793 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9794 if (insn & (1 << 21)) {
9795 /* Base writeback. */
9796 if (insn & (1 << 24)) {
9797 tcg_gen_addi_i32(addr, addr, 4);
9798 } else {
9799 tcg_gen_addi_i32(addr, addr, -4);
9801 store_reg(s, rn, addr);
9802 } else {
9803 tcg_temp_free_i32(addr);
9805 gen_rfe(s, tmp, tmp2);
9806 } else {
9807 /* srs */
9808 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9809 insn & (1 << 21));
9811 } else {
9812 int i, loaded_base = 0;
9813 TCGv_i32 loaded_var;
9814 /* Load/store multiple. */
9815 addr = load_reg(s, rn);
9816 offset = 0;
9817 for (i = 0; i < 16; i++) {
9818 if (insn & (1 << i))
9819 offset += 4;
9821 if (insn & (1 << 24)) {
9822 tcg_gen_addi_i32(addr, addr, -offset);
9825 TCGV_UNUSED_I32(loaded_var);
9826 for (i = 0; i < 16; i++) {
9827 if ((insn & (1 << i)) == 0)
9828 continue;
9829 if (insn & (1 << 20)) {
9830 /* Load. */
9831 tmp = tcg_temp_new_i32();
9832 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9833 if (i == 15) {
9834 gen_bx(s, tmp);
9835 } else if (i == rn) {
9836 loaded_var = tmp;
9837 loaded_base = 1;
9838 } else {
9839 store_reg(s, i, tmp);
9841 } else {
9842 /* Store. */
9843 tmp = load_reg(s, i);
9844 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9845 tcg_temp_free_i32(tmp);
9847 tcg_gen_addi_i32(addr, addr, 4);
9849 if (loaded_base) {
9850 store_reg(s, rn, loaded_var);
9852 if (insn & (1 << 21)) {
9853 /* Base register writeback. */
9854 if (insn & (1 << 24)) {
9855 tcg_gen_addi_i32(addr, addr, -offset);
9857 /* Fault if writeback register is in register list. */
9858 if (insn & (1 << rn))
9859 goto illegal_op;
9860 store_reg(s, rn, addr);
9861 } else {
9862 tcg_temp_free_i32(addr);
9866 break;
9867 case 5:
9869 op = (insn >> 21) & 0xf;
9870 if (op == 6) {
9871 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9872 goto illegal_op;
9874 /* Halfword pack. */
9875 tmp = load_reg(s, rn);
9876 tmp2 = load_reg(s, rm);
9877 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9878 if (insn & (1 << 5)) {
9879 /* pkhtb */
9880 if (shift == 0)
9881 shift = 31;
9882 tcg_gen_sari_i32(tmp2, tmp2, shift);
9883 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9884 tcg_gen_ext16u_i32(tmp2, tmp2);
9885 } else {
9886 /* pkhbt */
9887 if (shift)
9888 tcg_gen_shli_i32(tmp2, tmp2, shift);
9889 tcg_gen_ext16u_i32(tmp, tmp);
9890 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9892 tcg_gen_or_i32(tmp, tmp, tmp2);
9893 tcg_temp_free_i32(tmp2);
9894 store_reg(s, rd, tmp);
9895 } else {
9896 /* Data processing register constant shift. */
9897 if (rn == 15) {
9898 tmp = tcg_temp_new_i32();
9899 tcg_gen_movi_i32(tmp, 0);
9900 } else {
9901 tmp = load_reg(s, rn);
9903 tmp2 = load_reg(s, rm);
9905 shiftop = (insn >> 4) & 3;
9906 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9907 conds = (insn & (1 << 20)) != 0;
9908 logic_cc = (conds && thumb2_logic_op(op));
9909 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9910 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9911 goto illegal_op;
9912 tcg_temp_free_i32(tmp2);
9913 if (rd != 15) {
9914 store_reg(s, rd, tmp);
9915 } else {
9916 tcg_temp_free_i32(tmp);
9919 break;
9920 case 13: /* Misc data processing. */
9921 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9922 if (op < 4 && (insn & 0xf000) != 0xf000)
9923 goto illegal_op;
9924 switch (op) {
9925 case 0: /* Register controlled shift. */
9926 tmp = load_reg(s, rn);
9927 tmp2 = load_reg(s, rm);
9928 if ((insn & 0x70) != 0)
9929 goto illegal_op;
9930 op = (insn >> 21) & 3;
9931 logic_cc = (insn & (1 << 20)) != 0;
9932 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9933 if (logic_cc)
9934 gen_logic_CC(tmp);
9935 store_reg_bx(s, rd, tmp);
9936 break;
9937 case 1: /* Sign/zero extend. */
9938 op = (insn >> 20) & 7;
9939 switch (op) {
9940 case 0: /* SXTAH, SXTH */
9941 case 1: /* UXTAH, UXTH */
9942 case 4: /* SXTAB, SXTB */
9943 case 5: /* UXTAB, UXTB */
9944 break;
9945 case 2: /* SXTAB16, SXTB16 */
9946 case 3: /* UXTAB16, UXTB16 */
9947 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9948 goto illegal_op;
9950 break;
9951 default:
9952 goto illegal_op;
9954 if (rn != 15) {
9955 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9956 goto illegal_op;
9959 tmp = load_reg(s, rm);
9960 shift = (insn >> 4) & 3;
9961 /* ??? In many cases it's not necessary to do a
9962 rotate, a shift is sufficient. */
9963 if (shift != 0)
9964 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9965 op = (insn >> 20) & 7;
9966 switch (op) {
9967 case 0: gen_sxth(tmp); break;
9968 case 1: gen_uxth(tmp); break;
9969 case 2: gen_sxtb16(tmp); break;
9970 case 3: gen_uxtb16(tmp); break;
9971 case 4: gen_sxtb(tmp); break;
9972 case 5: gen_uxtb(tmp); break;
9973 default:
9974 g_assert_not_reached();
9976 if (rn != 15) {
9977 tmp2 = load_reg(s, rn);
9978 if ((op >> 1) == 1) {
9979 gen_add16(tmp, tmp2);
9980 } else {
9981 tcg_gen_add_i32(tmp, tmp, tmp2);
9982 tcg_temp_free_i32(tmp2);
9985 store_reg(s, rd, tmp);
9986 break;
9987 case 2: /* SIMD add/subtract. */
9988 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9989 goto illegal_op;
9991 op = (insn >> 20) & 7;
9992 shift = (insn >> 4) & 7;
9993 if ((op & 3) == 3 || (shift & 3) == 3)
9994 goto illegal_op;
9995 tmp = load_reg(s, rn);
9996 tmp2 = load_reg(s, rm);
9997 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9998 tcg_temp_free_i32(tmp2);
9999 store_reg(s, rd, tmp);
10000 break;
10001 case 3: /* Other data processing. */
10002 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10003 if (op < 4) {
10004 /* Saturating add/subtract. */
10005 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10006 goto illegal_op;
10008 tmp = load_reg(s, rn);
10009 tmp2 = load_reg(s, rm);
10010 if (op & 1)
10011 gen_helper_double_saturate(tmp, cpu_env, tmp);
10012 if (op & 2)
10013 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10014 else
10015 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10016 tcg_temp_free_i32(tmp2);
10017 } else {
10018 switch (op) {
10019 case 0x0a: /* rbit */
10020 case 0x08: /* rev */
10021 case 0x09: /* rev16 */
10022 case 0x0b: /* revsh */
10023 case 0x18: /* clz */
10024 break;
10025 case 0x10: /* sel */
10026 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10027 goto illegal_op;
10029 break;
10030 case 0x20: /* crc32/crc32c */
10031 case 0x21:
10032 case 0x22:
10033 case 0x28:
10034 case 0x29:
10035 case 0x2a:
10036 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10037 goto illegal_op;
10039 break;
10040 default:
10041 goto illegal_op;
10043 tmp = load_reg(s, rn);
10044 switch (op) {
10045 case 0x0a: /* rbit */
10046 gen_helper_rbit(tmp, tmp);
10047 break;
10048 case 0x08: /* rev */
10049 tcg_gen_bswap32_i32(tmp, tmp);
10050 break;
10051 case 0x09: /* rev16 */
10052 gen_rev16(tmp);
10053 break;
10054 case 0x0b: /* revsh */
10055 gen_revsh(tmp);
10056 break;
10057 case 0x10: /* sel */
10058 tmp2 = load_reg(s, rm);
10059 tmp3 = tcg_temp_new_i32();
10060 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10061 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10062 tcg_temp_free_i32(tmp3);
10063 tcg_temp_free_i32(tmp2);
10064 break;
10065 case 0x18: /* clz */
10066 gen_helper_clz(tmp, tmp);
10067 break;
10068 case 0x20:
10069 case 0x21:
10070 case 0x22:
10071 case 0x28:
10072 case 0x29:
10073 case 0x2a:
10075 /* crc32/crc32c */
10076 uint32_t sz = op & 0x3;
10077 uint32_t c = op & 0x8;
10079 tmp2 = load_reg(s, rm);
10080 if (sz == 0) {
10081 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10082 } else if (sz == 1) {
10083 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10085 tmp3 = tcg_const_i32(1 << sz);
10086 if (c) {
10087 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10088 } else {
10089 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10091 tcg_temp_free_i32(tmp2);
10092 tcg_temp_free_i32(tmp3);
10093 break;
10095 default:
10096 g_assert_not_reached();
10099 store_reg(s, rd, tmp);
10100 break;
10101 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10102 switch ((insn >> 20) & 7) {
10103 case 0: /* 32 x 32 -> 32 */
10104 case 7: /* Unsigned sum of absolute differences. */
10105 break;
10106 case 1: /* 16 x 16 -> 32 */
10107 case 2: /* Dual multiply add. */
10108 case 3: /* 32 * 16 -> 32msb */
10109 case 4: /* Dual multiply subtract. */
10110 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10111 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10112 goto illegal_op;
10114 break;
10116 op = (insn >> 4) & 0xf;
10117 tmp = load_reg(s, rn);
10118 tmp2 = load_reg(s, rm);
10119 switch ((insn >> 20) & 7) {
10120 case 0: /* 32 x 32 -> 32 */
10121 tcg_gen_mul_i32(tmp, tmp, tmp2);
10122 tcg_temp_free_i32(tmp2);
10123 if (rs != 15) {
10124 tmp2 = load_reg(s, rs);
10125 if (op)
10126 tcg_gen_sub_i32(tmp, tmp2, tmp);
10127 else
10128 tcg_gen_add_i32(tmp, tmp, tmp2);
10129 tcg_temp_free_i32(tmp2);
10131 break;
10132 case 1: /* 16 x 16 -> 32 */
10133 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10134 tcg_temp_free_i32(tmp2);
10135 if (rs != 15) {
10136 tmp2 = load_reg(s, rs);
10137 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10138 tcg_temp_free_i32(tmp2);
10140 break;
10141 case 2: /* Dual multiply add. */
10142 case 4: /* Dual multiply subtract. */
10143 if (op)
10144 gen_swap_half(tmp2);
10145 gen_smul_dual(tmp, tmp2);
10146 if (insn & (1 << 22)) {
10147 /* This subtraction cannot overflow. */
10148 tcg_gen_sub_i32(tmp, tmp, tmp2);
10149 } else {
10150 /* This addition cannot overflow 32 bits;
10151 * however it may overflow considered as a signed
10152 * operation, in which case we must set the Q flag.
10154 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10156 tcg_temp_free_i32(tmp2);
10157 if (rs != 15)
10159 tmp2 = load_reg(s, rs);
10160 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10161 tcg_temp_free_i32(tmp2);
10163 break;
10164 case 3: /* 32 * 16 -> 32msb */
10165 if (op)
10166 tcg_gen_sari_i32(tmp2, tmp2, 16);
10167 else
10168 gen_sxth(tmp2);
10169 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10170 tcg_gen_shri_i64(tmp64, tmp64, 16);
10171 tmp = tcg_temp_new_i32();
10172 tcg_gen_extrl_i64_i32(tmp, tmp64);
10173 tcg_temp_free_i64(tmp64);
10174 if (rs != 15)
10176 tmp2 = load_reg(s, rs);
10177 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10178 tcg_temp_free_i32(tmp2);
10180 break;
10181 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10182 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10183 if (rs != 15) {
10184 tmp = load_reg(s, rs);
10185 if (insn & (1 << 20)) {
10186 tmp64 = gen_addq_msw(tmp64, tmp);
10187 } else {
10188 tmp64 = gen_subq_msw(tmp64, tmp);
10191 if (insn & (1 << 4)) {
10192 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10194 tcg_gen_shri_i64(tmp64, tmp64, 32);
10195 tmp = tcg_temp_new_i32();
10196 tcg_gen_extrl_i64_i32(tmp, tmp64);
10197 tcg_temp_free_i64(tmp64);
10198 break;
10199 case 7: /* Unsigned sum of absolute differences. */
10200 gen_helper_usad8(tmp, tmp, tmp2);
10201 tcg_temp_free_i32(tmp2);
10202 if (rs != 15) {
10203 tmp2 = load_reg(s, rs);
10204 tcg_gen_add_i32(tmp, tmp, tmp2);
10205 tcg_temp_free_i32(tmp2);
10207 break;
10209 store_reg(s, rd, tmp);
10210 break;
10211 case 6: case 7: /* 64-bit multiply, Divide. */
10212 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10213 tmp = load_reg(s, rn);
10214 tmp2 = load_reg(s, rm);
10215 if ((op & 0x50) == 0x10) {
10216 /* sdiv, udiv */
10217 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10218 goto illegal_op;
10220 if (op & 0x20)
10221 gen_helper_udiv(tmp, tmp, tmp2);
10222 else
10223 gen_helper_sdiv(tmp, tmp, tmp2);
10224 tcg_temp_free_i32(tmp2);
10225 store_reg(s, rd, tmp);
10226 } else if ((op & 0xe) == 0xc) {
10227 /* Dual multiply accumulate long. */
10228 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10229 tcg_temp_free_i32(tmp);
10230 tcg_temp_free_i32(tmp2);
10231 goto illegal_op;
10233 if (op & 1)
10234 gen_swap_half(tmp2);
10235 gen_smul_dual(tmp, tmp2);
10236 if (op & 0x10) {
10237 tcg_gen_sub_i32(tmp, tmp, tmp2);
10238 } else {
10239 tcg_gen_add_i32(tmp, tmp, tmp2);
10241 tcg_temp_free_i32(tmp2);
10242 /* BUGFIX */
10243 tmp64 = tcg_temp_new_i64();
10244 tcg_gen_ext_i32_i64(tmp64, tmp);
10245 tcg_temp_free_i32(tmp);
10246 gen_addq(s, tmp64, rs, rd);
10247 gen_storeq_reg(s, rs, rd, tmp64);
10248 tcg_temp_free_i64(tmp64);
10249 } else {
10250 if (op & 0x20) {
10251 /* Unsigned 64-bit multiply */
10252 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10253 } else {
10254 if (op & 8) {
10255 /* smlalxy */
10256 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10257 tcg_temp_free_i32(tmp2);
10258 tcg_temp_free_i32(tmp);
10259 goto illegal_op;
10261 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10262 tcg_temp_free_i32(tmp2);
10263 tmp64 = tcg_temp_new_i64();
10264 tcg_gen_ext_i32_i64(tmp64, tmp);
10265 tcg_temp_free_i32(tmp);
10266 } else {
10267 /* Signed 64-bit multiply */
10268 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10271 if (op & 4) {
10272 /* umaal */
10273 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10274 tcg_temp_free_i64(tmp64);
10275 goto illegal_op;
10277 gen_addq_lo(s, tmp64, rs);
10278 gen_addq_lo(s, tmp64, rd);
10279 } else if (op & 0x40) {
10280 /* 64-bit accumulate. */
10281 gen_addq(s, tmp64, rs, rd);
10283 gen_storeq_reg(s, rs, rd, tmp64);
10284 tcg_temp_free_i64(tmp64);
10286 break;
10288 break;
10289 case 6: case 7: case 14: case 15:
10290 /* Coprocessor. */
10291 if (((insn >> 24) & 3) == 3) {
10292 /* Translate into the equivalent ARM encoding. */
10293 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10294 if (disas_neon_data_insn(s, insn)) {
10295 goto illegal_op;
10297 } else if (((insn >> 8) & 0xe) == 10) {
10298 if (disas_vfp_insn(s, insn)) {
10299 goto illegal_op;
10301 } else {
10302 if (insn & (1 << 28))
10303 goto illegal_op;
10304 if (disas_coproc_insn(s, insn)) {
10305 goto illegal_op;
10308 break;
10309 case 8: case 9: case 10: case 11:
10310 if (insn & (1 << 15)) {
10311 /* Branches, misc control. */
10312 if (insn & 0x5000) {
10313 /* Unconditional branch. */
10314 /* signextend(hw1[10:0]) -> offset[:12]. */
10315 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10316 /* hw1[10:0] -> offset[11:1]. */
10317 offset |= (insn & 0x7ff) << 1;
10318 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10319 offset[24:22] already have the same value because of the
10320 sign extension above. */
10321 offset ^= ((~insn) & (1 << 13)) << 10;
10322 offset ^= ((~insn) & (1 << 11)) << 11;
10324 if (insn & (1 << 14)) {
10325 /* Branch and link. */
10326 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10329 offset += s->pc;
10330 if (insn & (1 << 12)) {
10331 /* b/bl */
10332 gen_jmp(s, offset);
10333 } else {
10334 /* blx */
10335 offset &= ~(uint32_t)2;
10336 /* thumb2 bx, no need to check */
10337 gen_bx_im(s, offset);
10339 } else if (((insn >> 23) & 7) == 7) {
10340 /* Misc control */
10341 if (insn & (1 << 13))
10342 goto illegal_op;
10344 if (insn & (1 << 26)) {
10345 if (!(insn & (1 << 20))) {
10346 /* Hypervisor call (v7) */
10347 int imm16 = extract32(insn, 16, 4) << 12
10348 | extract32(insn, 0, 12);
10349 ARCH(7);
10350 if (IS_USER(s)) {
10351 goto illegal_op;
10353 gen_hvc(s, imm16);
10354 } else {
10355 /* Secure monitor call (v6+) */
10356 ARCH(6K);
10357 if (IS_USER(s)) {
10358 goto illegal_op;
10360 gen_smc(s);
10362 } else {
10363 op = (insn >> 20) & 7;
10364 switch (op) {
10365 case 0: /* msr cpsr. */
10366 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10367 tmp = load_reg(s, rn);
10368 addr = tcg_const_i32(insn & 0xff);
10369 gen_helper_v7m_msr(cpu_env, addr, tmp);
10370 tcg_temp_free_i32(addr);
10371 tcg_temp_free_i32(tmp);
10372 gen_lookup_tb(s);
10373 break;
10375 /* fall through */
10376 case 1: /* msr spsr. */
10377 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10378 goto illegal_op;
10381 if (extract32(insn, 5, 1)) {
10382 /* MSR (banked) */
10383 int sysm = extract32(insn, 8, 4) |
10384 (extract32(insn, 4, 1) << 4);
10385 int r = op & 1;
10387 gen_msr_banked(s, r, sysm, rm);
10388 break;
10391 /* MSR (for PSRs) */
10392 tmp = load_reg(s, rn);
10393 if (gen_set_psr(s,
10394 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10395 op == 1, tmp))
10396 goto illegal_op;
10397 break;
10398 case 2: /* cps, nop-hint. */
10399 if (((insn >> 8) & 7) == 0) {
10400 gen_nop_hint(s, insn & 0xff);
10402 /* Implemented as NOP in user mode. */
10403 if (IS_USER(s))
10404 break;
10405 offset = 0;
10406 imm = 0;
10407 if (insn & (1 << 10)) {
10408 if (insn & (1 << 7))
10409 offset |= CPSR_A;
10410 if (insn & (1 << 6))
10411 offset |= CPSR_I;
10412 if (insn & (1 << 5))
10413 offset |= CPSR_F;
10414 if (insn & (1 << 9))
10415 imm = CPSR_A | CPSR_I | CPSR_F;
10417 if (insn & (1 << 8)) {
10418 offset |= 0x1f;
10419 imm |= (insn & 0x1f);
10421 if (offset) {
10422 gen_set_psr_im(s, offset, 0, imm);
10424 break;
10425 case 3: /* Special control operations. */
10426 ARCH(7);
10427 op = (insn >> 4) & 0xf;
10428 switch (op) {
10429 case 2: /* clrex */
10430 gen_clrex(s);
10431 break;
10432 case 4: /* dsb */
10433 case 5: /* dmb */
10434 /* These execute as NOPs. */
10435 break;
10436 case 6: /* isb */
10437 /* We need to break the TB after this insn
10438 * to execute self-modifying code correctly
10439 * and also to take any pending interrupts
10440 * immediately.
10442 gen_lookup_tb(s);
10443 break;
10444 default:
10445 goto illegal_op;
10447 break;
10448 case 4: /* bxj */
10449 /* Trivial implementation equivalent to bx. */
10450 tmp = load_reg(s, rn);
10451 gen_bx(s, tmp);
10452 break;
10453 case 5: /* Exception return. */
10454 if (IS_USER(s)) {
10455 goto illegal_op;
10457 if (rn != 14 || rd != 15) {
10458 goto illegal_op;
10460 tmp = load_reg(s, rn);
10461 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10462 gen_exception_return(s, tmp);
10463 break;
10464 case 6: /* MRS */
10465 if (extract32(insn, 5, 1)) {
10466 /* MRS (banked) */
10467 int sysm = extract32(insn, 16, 4) |
10468 (extract32(insn, 4, 1) << 4);
10470 gen_mrs_banked(s, 0, sysm, rd);
10471 break;
10474 /* mrs cpsr */
10475 tmp = tcg_temp_new_i32();
10476 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10477 addr = tcg_const_i32(insn & 0xff);
10478 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10479 tcg_temp_free_i32(addr);
10480 } else {
10481 gen_helper_cpsr_read(tmp, cpu_env);
10483 store_reg(s, rd, tmp);
10484 break;
10485 case 7: /* MRS */
10486 if (extract32(insn, 5, 1)) {
10487 /* MRS (banked) */
10488 int sysm = extract32(insn, 16, 4) |
10489 (extract32(insn, 4, 1) << 4);
10491 gen_mrs_banked(s, 1, sysm, rd);
10492 break;
10495 /* mrs spsr. */
10496 /* Not accessible in user mode. */
10497 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10498 goto illegal_op;
10500 tmp = load_cpu_field(spsr);
10501 store_reg(s, rd, tmp);
10502 break;
10505 } else {
10506 /* Conditional branch. */
10507 op = (insn >> 22) & 0xf;
10508 /* Generate a conditional jump to next instruction. */
10509 s->condlabel = gen_new_label();
10510 arm_gen_test_cc(op ^ 1, s->condlabel);
10511 s->condjmp = 1;
10513 /* offset[11:1] = insn[10:0] */
10514 offset = (insn & 0x7ff) << 1;
10515 /* offset[17:12] = insn[21:16]. */
10516 offset |= (insn & 0x003f0000) >> 4;
10517 /* offset[31:20] = insn[26]. */
10518 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10519 /* offset[18] = insn[13]. */
10520 offset |= (insn & (1 << 13)) << 5;
10521 /* offset[19] = insn[11]. */
10522 offset |= (insn & (1 << 11)) << 8;
10524 /* jump to the offset */
10525 gen_jmp(s, s->pc + offset);
10527 } else {
10528 /* Data processing immediate. */
10529 if (insn & (1 << 25)) {
10530 if (insn & (1 << 24)) {
10531 if (insn & (1 << 20))
10532 goto illegal_op;
10533 /* Bitfield/Saturate. */
10534 op = (insn >> 21) & 7;
10535 imm = insn & 0x1f;
10536 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10537 if (rn == 15) {
10538 tmp = tcg_temp_new_i32();
10539 tcg_gen_movi_i32(tmp, 0);
10540 } else {
10541 tmp = load_reg(s, rn);
10543 switch (op) {
10544 case 2: /* Signed bitfield extract. */
10545 imm++;
10546 if (shift + imm > 32)
10547 goto illegal_op;
10548 if (imm < 32)
10549 gen_sbfx(tmp, shift, imm);
10550 break;
10551 case 6: /* Unsigned bitfield extract. */
10552 imm++;
10553 if (shift + imm > 32)
10554 goto illegal_op;
10555 if (imm < 32)
10556 gen_ubfx(tmp, shift, (1u << imm) - 1);
10557 break;
10558 case 3: /* Bitfield insert/clear. */
10559 if (imm < shift)
10560 goto illegal_op;
10561 imm = imm + 1 - shift;
10562 if (imm != 32) {
10563 tmp2 = load_reg(s, rd);
10564 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10565 tcg_temp_free_i32(tmp2);
10567 break;
10568 case 7:
10569 goto illegal_op;
10570 default: /* Saturate. */
10571 if (shift) {
10572 if (op & 1)
10573 tcg_gen_sari_i32(tmp, tmp, shift);
10574 else
10575 tcg_gen_shli_i32(tmp, tmp, shift);
10577 tmp2 = tcg_const_i32(imm);
10578 if (op & 4) {
10579 /* Unsigned. */
10580 if ((op & 1) && shift == 0) {
10581 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10582 tcg_temp_free_i32(tmp);
10583 tcg_temp_free_i32(tmp2);
10584 goto illegal_op;
10586 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10587 } else {
10588 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10590 } else {
10591 /* Signed. */
10592 if ((op & 1) && shift == 0) {
10593 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10594 tcg_temp_free_i32(tmp);
10595 tcg_temp_free_i32(tmp2);
10596 goto illegal_op;
10598 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10599 } else {
10600 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10603 tcg_temp_free_i32(tmp2);
10604 break;
10606 store_reg(s, rd, tmp);
10607 } else {
10608 imm = ((insn & 0x04000000) >> 15)
10609 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10610 if (insn & (1 << 22)) {
10611 /* 16-bit immediate. */
10612 imm |= (insn >> 4) & 0xf000;
10613 if (insn & (1 << 23)) {
10614 /* movt */
10615 tmp = load_reg(s, rd);
10616 tcg_gen_ext16u_i32(tmp, tmp);
10617 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10618 } else {
10619 /* movw */
10620 tmp = tcg_temp_new_i32();
10621 tcg_gen_movi_i32(tmp, imm);
10623 } else {
10624 /* Add/sub 12-bit immediate. */
10625 if (rn == 15) {
10626 offset = s->pc & ~(uint32_t)3;
10627 if (insn & (1 << 23))
10628 offset -= imm;
10629 else
10630 offset += imm;
10631 tmp = tcg_temp_new_i32();
10632 tcg_gen_movi_i32(tmp, offset);
10633 } else {
10634 tmp = load_reg(s, rn);
10635 if (insn & (1 << 23))
10636 tcg_gen_subi_i32(tmp, tmp, imm);
10637 else
10638 tcg_gen_addi_i32(tmp, tmp, imm);
10641 store_reg(s, rd, tmp);
10643 } else {
10644 int shifter_out = 0;
10645 /* modified 12-bit immediate. */
10646 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10647 imm = (insn & 0xff);
10648 switch (shift) {
10649 case 0: /* XY */
10650 /* Nothing to do. */
10651 break;
10652 case 1: /* 00XY00XY */
10653 imm |= imm << 16;
10654 break;
10655 case 2: /* XY00XY00 */
10656 imm |= imm << 16;
10657 imm <<= 8;
10658 break;
10659 case 3: /* XYXYXYXY */
10660 imm |= imm << 16;
10661 imm |= imm << 8;
10662 break;
10663 default: /* Rotated constant. */
10664 shift = (shift << 1) | (imm >> 7);
10665 imm |= 0x80;
10666 imm = imm << (32 - shift);
10667 shifter_out = 1;
10668 break;
10670 tmp2 = tcg_temp_new_i32();
10671 tcg_gen_movi_i32(tmp2, imm);
10672 rn = (insn >> 16) & 0xf;
10673 if (rn == 15) {
10674 tmp = tcg_temp_new_i32();
10675 tcg_gen_movi_i32(tmp, 0);
10676 } else {
10677 tmp = load_reg(s, rn);
10679 op = (insn >> 21) & 0xf;
10680 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10681 shifter_out, tmp, tmp2))
10682 goto illegal_op;
10683 tcg_temp_free_i32(tmp2);
10684 rd = (insn >> 8) & 0xf;
10685 if (rd != 15) {
10686 store_reg(s, rd, tmp);
10687 } else {
10688 tcg_temp_free_i32(tmp);
10692 break;
10693 case 12: /* Load/store single data item. */
10695 int postinc = 0;
10696 int writeback = 0;
10697 int memidx;
10698 if ((insn & 0x01100000) == 0x01000000) {
10699 if (disas_neon_ls_insn(s, insn)) {
10700 goto illegal_op;
10702 break;
10704 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10705 if (rs == 15) {
10706 if (!(insn & (1 << 20))) {
10707 goto illegal_op;
10709 if (op != 2) {
10710 /* Byte or halfword load space with dest == r15 : memory hints.
10711 * Catch them early so we don't emit pointless addressing code.
10712 * This space is a mix of:
10713 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10714 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10715 * cores)
10716 * unallocated hints, which must be treated as NOPs
10717 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10718 * which is easiest for the decoding logic
10719 * Some space which must UNDEF
10721 int op1 = (insn >> 23) & 3;
10722 int op2 = (insn >> 6) & 0x3f;
10723 if (op & 2) {
10724 goto illegal_op;
10726 if (rn == 15) {
10727 /* UNPREDICTABLE, unallocated hint or
10728 * PLD/PLDW/PLI (literal)
10730 return 0;
10732 if (op1 & 1) {
10733 return 0; /* PLD/PLDW/PLI or unallocated hint */
10735 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10736 return 0; /* PLD/PLDW/PLI or unallocated hint */
10738 /* UNDEF space, or an UNPREDICTABLE */
10739 return 1;
10742 memidx = get_mem_index(s);
10743 if (rn == 15) {
10744 addr = tcg_temp_new_i32();
10745 /* PC relative. */
10746 /* s->pc has already been incremented by 4. */
10747 imm = s->pc & 0xfffffffc;
10748 if (insn & (1 << 23))
10749 imm += insn & 0xfff;
10750 else
10751 imm -= insn & 0xfff;
10752 tcg_gen_movi_i32(addr, imm);
10753 } else {
10754 addr = load_reg(s, rn);
10755 if (insn & (1 << 23)) {
10756 /* Positive offset. */
10757 imm = insn & 0xfff;
10758 tcg_gen_addi_i32(addr, addr, imm);
10759 } else {
10760 imm = insn & 0xff;
10761 switch ((insn >> 8) & 0xf) {
10762 case 0x0: /* Shifted Register. */
10763 shift = (insn >> 4) & 0xf;
10764 if (shift > 3) {
10765 tcg_temp_free_i32(addr);
10766 goto illegal_op;
10768 tmp = load_reg(s, rm);
10769 if (shift)
10770 tcg_gen_shli_i32(tmp, tmp, shift);
10771 tcg_gen_add_i32(addr, addr, tmp);
10772 tcg_temp_free_i32(tmp);
10773 break;
10774 case 0xc: /* Negative offset. */
10775 tcg_gen_addi_i32(addr, addr, -imm);
10776 break;
10777 case 0xe: /* User privilege. */
10778 tcg_gen_addi_i32(addr, addr, imm);
10779 memidx = get_a32_user_mem_index(s);
10780 break;
10781 case 0x9: /* Post-decrement. */
10782 imm = -imm;
10783 /* Fall through. */
10784 case 0xb: /* Post-increment. */
10785 postinc = 1;
10786 writeback = 1;
10787 break;
10788 case 0xd: /* Pre-decrement. */
10789 imm = -imm;
10790 /* Fall through. */
10791 case 0xf: /* Pre-increment. */
10792 tcg_gen_addi_i32(addr, addr, imm);
10793 writeback = 1;
10794 break;
10795 default:
10796 tcg_temp_free_i32(addr);
10797 goto illegal_op;
10801 if (insn & (1 << 20)) {
10802 /* Load. */
10803 tmp = tcg_temp_new_i32();
10804 switch (op) {
10805 case 0:
10806 gen_aa32_ld8u(s, tmp, addr, memidx);
10807 break;
10808 case 4:
10809 gen_aa32_ld8s(s, tmp, addr, memidx);
10810 break;
10811 case 1:
10812 gen_aa32_ld16u(s, tmp, addr, memidx);
10813 break;
10814 case 5:
10815 gen_aa32_ld16s(s, tmp, addr, memidx);
10816 break;
10817 case 2:
10818 gen_aa32_ld32u(s, tmp, addr, memidx);
10819 break;
10820 default:
10821 tcg_temp_free_i32(tmp);
10822 tcg_temp_free_i32(addr);
10823 goto illegal_op;
10825 if (rs == 15) {
10826 gen_bx(s, tmp);
10827 } else {
10828 store_reg(s, rs, tmp);
10830 } else {
10831 /* Store. */
10832 tmp = load_reg(s, rs);
10833 switch (op) {
10834 case 0:
10835 gen_aa32_st8(s, tmp, addr, memidx);
10836 break;
10837 case 1:
10838 gen_aa32_st16(s, tmp, addr, memidx);
10839 break;
10840 case 2:
10841 gen_aa32_st32(s, tmp, addr, memidx);
10842 break;
10843 default:
10844 tcg_temp_free_i32(tmp);
10845 tcg_temp_free_i32(addr);
10846 goto illegal_op;
10848 tcg_temp_free_i32(tmp);
10850 if (postinc)
10851 tcg_gen_addi_i32(addr, addr, imm);
10852 if (writeback) {
10853 store_reg(s, rn, addr);
10854 } else {
10855 tcg_temp_free_i32(addr);
10858 break;
10859 default:
10860 goto illegal_op;
10862 return 0;
10863 illegal_op:
10864 return 1;
10867 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10869 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10870 int32_t offset;
10871 int i;
10872 TCGv_i32 tmp;
10873 TCGv_i32 tmp2;
10874 TCGv_i32 addr;
10876 if (s->condexec_mask) {
10877 cond = s->condexec_cond;
10878 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10879 s->condlabel = gen_new_label();
10880 arm_gen_test_cc(cond ^ 1, s->condlabel);
10881 s->condjmp = 1;
10885 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
10886 s->pc += 2;
10888 switch (insn >> 12) {
10889 case 0: case 1:
10891 rd = insn & 7;
10892 op = (insn >> 11) & 3;
10893 if (op == 3) {
10894 /* add/subtract */
10895 rn = (insn >> 3) & 7;
10896 tmp = load_reg(s, rn);
10897 if (insn & (1 << 10)) {
10898 /* immediate */
10899 tmp2 = tcg_temp_new_i32();
10900 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10901 } else {
10902 /* reg */
10903 rm = (insn >> 6) & 7;
10904 tmp2 = load_reg(s, rm);
10906 if (insn & (1 << 9)) {
10907 if (s->condexec_mask)
10908 tcg_gen_sub_i32(tmp, tmp, tmp2);
10909 else
10910 gen_sub_CC(tmp, tmp, tmp2);
10911 } else {
10912 if (s->condexec_mask)
10913 tcg_gen_add_i32(tmp, tmp, tmp2);
10914 else
10915 gen_add_CC(tmp, tmp, tmp2);
10917 tcg_temp_free_i32(tmp2);
10918 store_reg(s, rd, tmp);
10919 } else {
10920 /* shift immediate */
10921 rm = (insn >> 3) & 7;
10922 shift = (insn >> 6) & 0x1f;
10923 tmp = load_reg(s, rm);
10924 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10925 if (!s->condexec_mask)
10926 gen_logic_CC(tmp);
10927 store_reg(s, rd, tmp);
10929 break;
10930 case 2: case 3:
10931 /* arithmetic large immediate */
10932 op = (insn >> 11) & 3;
10933 rd = (insn >> 8) & 0x7;
10934 if (op == 0) { /* mov */
10935 tmp = tcg_temp_new_i32();
10936 tcg_gen_movi_i32(tmp, insn & 0xff);
10937 if (!s->condexec_mask)
10938 gen_logic_CC(tmp);
10939 store_reg(s, rd, tmp);
10940 } else {
10941 tmp = load_reg(s, rd);
10942 tmp2 = tcg_temp_new_i32();
10943 tcg_gen_movi_i32(tmp2, insn & 0xff);
10944 switch (op) {
10945 case 1: /* cmp */
10946 gen_sub_CC(tmp, tmp, tmp2);
10947 tcg_temp_free_i32(tmp);
10948 tcg_temp_free_i32(tmp2);
10949 break;
10950 case 2: /* add */
10951 if (s->condexec_mask)
10952 tcg_gen_add_i32(tmp, tmp, tmp2);
10953 else
10954 gen_add_CC(tmp, tmp, tmp2);
10955 tcg_temp_free_i32(tmp2);
10956 store_reg(s, rd, tmp);
10957 break;
10958 case 3: /* sub */
10959 if (s->condexec_mask)
10960 tcg_gen_sub_i32(tmp, tmp, tmp2);
10961 else
10962 gen_sub_CC(tmp, tmp, tmp2);
10963 tcg_temp_free_i32(tmp2);
10964 store_reg(s, rd, tmp);
10965 break;
10968 break;
10969 case 4:
10970 if (insn & (1 << 11)) {
10971 rd = (insn >> 8) & 7;
10972 /* load pc-relative. Bit 1 of PC is ignored. */
10973 val = s->pc + 2 + ((insn & 0xff) * 4);
10974 val &= ~(uint32_t)2;
10975 addr = tcg_temp_new_i32();
10976 tcg_gen_movi_i32(addr, val);
10977 tmp = tcg_temp_new_i32();
10978 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10979 tcg_temp_free_i32(addr);
10980 store_reg(s, rd, tmp);
10981 break;
10983 if (insn & (1 << 10)) {
10984 /* data processing extended or blx */
10985 rd = (insn & 7) | ((insn >> 4) & 8);
10986 rm = (insn >> 3) & 0xf;
10987 op = (insn >> 8) & 3;
10988 switch (op) {
10989 case 0: /* add */
10990 tmp = load_reg(s, rd);
10991 tmp2 = load_reg(s, rm);
10992 tcg_gen_add_i32(tmp, tmp, tmp2);
10993 tcg_temp_free_i32(tmp2);
10994 store_reg(s, rd, tmp);
10995 break;
10996 case 1: /* cmp */
10997 tmp = load_reg(s, rd);
10998 tmp2 = load_reg(s, rm);
10999 gen_sub_CC(tmp, tmp, tmp2);
11000 tcg_temp_free_i32(tmp2);
11001 tcg_temp_free_i32(tmp);
11002 break;
11003 case 2: /* mov/cpy */
11004 tmp = load_reg(s, rm);
11005 store_reg(s, rd, tmp);
11006 break;
11007 case 3:/* branch [and link] exchange thumb register */
11008 tmp = load_reg(s, rm);
11009 if (insn & (1 << 7)) {
11010 ARCH(5);
11011 val = (uint32_t)s->pc | 1;
11012 tmp2 = tcg_temp_new_i32();
11013 tcg_gen_movi_i32(tmp2, val);
11014 store_reg(s, 14, tmp2);
11016 /* already thumb, no need to check */
11017 gen_bx(s, tmp);
11018 break;
11020 break;
11023 /* data processing register */
11024 rd = insn & 7;
11025 rm = (insn >> 3) & 7;
11026 op = (insn >> 6) & 0xf;
11027 if (op == 2 || op == 3 || op == 4 || op == 7) {
11028 /* the shift/rotate ops want the operands backwards */
11029 val = rm;
11030 rm = rd;
11031 rd = val;
11032 val = 1;
11033 } else {
11034 val = 0;
11037 if (op == 9) { /* neg */
11038 tmp = tcg_temp_new_i32();
11039 tcg_gen_movi_i32(tmp, 0);
11040 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11041 tmp = load_reg(s, rd);
11042 } else {
11043 TCGV_UNUSED_I32(tmp);
11046 tmp2 = load_reg(s, rm);
11047 switch (op) {
11048 case 0x0: /* and */
11049 tcg_gen_and_i32(tmp, tmp, tmp2);
11050 if (!s->condexec_mask)
11051 gen_logic_CC(tmp);
11052 break;
11053 case 0x1: /* eor */
11054 tcg_gen_xor_i32(tmp, tmp, tmp2);
11055 if (!s->condexec_mask)
11056 gen_logic_CC(tmp);
11057 break;
11058 case 0x2: /* lsl */
11059 if (s->condexec_mask) {
11060 gen_shl(tmp2, tmp2, tmp);
11061 } else {
11062 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11063 gen_logic_CC(tmp2);
11065 break;
11066 case 0x3: /* lsr */
11067 if (s->condexec_mask) {
11068 gen_shr(tmp2, tmp2, tmp);
11069 } else {
11070 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11071 gen_logic_CC(tmp2);
11073 break;
11074 case 0x4: /* asr */
11075 if (s->condexec_mask) {
11076 gen_sar(tmp2, tmp2, tmp);
11077 } else {
11078 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11079 gen_logic_CC(tmp2);
11081 break;
11082 case 0x5: /* adc */
11083 if (s->condexec_mask) {
11084 gen_adc(tmp, tmp2);
11085 } else {
11086 gen_adc_CC(tmp, tmp, tmp2);
11088 break;
11089 case 0x6: /* sbc */
11090 if (s->condexec_mask) {
11091 gen_sub_carry(tmp, tmp, tmp2);
11092 } else {
11093 gen_sbc_CC(tmp, tmp, tmp2);
11095 break;
11096 case 0x7: /* ror */
11097 if (s->condexec_mask) {
11098 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11099 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11100 } else {
11101 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11102 gen_logic_CC(tmp2);
11104 break;
11105 case 0x8: /* tst */
11106 tcg_gen_and_i32(tmp, tmp, tmp2);
11107 gen_logic_CC(tmp);
11108 rd = 16;
11109 break;
11110 case 0x9: /* neg */
11111 if (s->condexec_mask)
11112 tcg_gen_neg_i32(tmp, tmp2);
11113 else
11114 gen_sub_CC(tmp, tmp, tmp2);
11115 break;
11116 case 0xa: /* cmp */
11117 gen_sub_CC(tmp, tmp, tmp2);
11118 rd = 16;
11119 break;
11120 case 0xb: /* cmn */
11121 gen_add_CC(tmp, tmp, tmp2);
11122 rd = 16;
11123 break;
11124 case 0xc: /* orr */
11125 tcg_gen_or_i32(tmp, tmp, tmp2);
11126 if (!s->condexec_mask)
11127 gen_logic_CC(tmp);
11128 break;
11129 case 0xd: /* mul */
11130 tcg_gen_mul_i32(tmp, tmp, tmp2);
11131 if (!s->condexec_mask)
11132 gen_logic_CC(tmp);
11133 break;
11134 case 0xe: /* bic */
11135 tcg_gen_andc_i32(tmp, tmp, tmp2);
11136 if (!s->condexec_mask)
11137 gen_logic_CC(tmp);
11138 break;
11139 case 0xf: /* mvn */
11140 tcg_gen_not_i32(tmp2, tmp2);
11141 if (!s->condexec_mask)
11142 gen_logic_CC(tmp2);
11143 val = 1;
11144 rm = rd;
11145 break;
11147 if (rd != 16) {
11148 if (val) {
11149 store_reg(s, rm, tmp2);
11150 if (op != 0xf)
11151 tcg_temp_free_i32(tmp);
11152 } else {
11153 store_reg(s, rd, tmp);
11154 tcg_temp_free_i32(tmp2);
11156 } else {
11157 tcg_temp_free_i32(tmp);
11158 tcg_temp_free_i32(tmp2);
11160 break;
11162 case 5:
11163 /* load/store register offset. */
11164 rd = insn & 7;
11165 rn = (insn >> 3) & 7;
11166 rm = (insn >> 6) & 7;
11167 op = (insn >> 9) & 7;
11168 addr = load_reg(s, rn);
11169 tmp = load_reg(s, rm);
11170 tcg_gen_add_i32(addr, addr, tmp);
11171 tcg_temp_free_i32(tmp);
11173 if (op < 3) { /* store */
11174 tmp = load_reg(s, rd);
11175 } else {
11176 tmp = tcg_temp_new_i32();
11179 switch (op) {
11180 case 0: /* str */
11181 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11182 break;
11183 case 1: /* strh */
11184 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
11185 break;
11186 case 2: /* strb */
11187 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
11188 break;
11189 case 3: /* ldrsb */
11190 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
11191 break;
11192 case 4: /* ldr */
11193 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11194 break;
11195 case 5: /* ldrh */
11196 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
11197 break;
11198 case 6: /* ldrb */
11199 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
11200 break;
11201 case 7: /* ldrsh */
11202 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
11203 break;
11205 if (op >= 3) { /* load */
11206 store_reg(s, rd, tmp);
11207 } else {
11208 tcg_temp_free_i32(tmp);
11210 tcg_temp_free_i32(addr);
11211 break;
11213 case 6:
11214 /* load/store word immediate offset */
11215 rd = insn & 7;
11216 rn = (insn >> 3) & 7;
11217 addr = load_reg(s, rn);
11218 val = (insn >> 4) & 0x7c;
11219 tcg_gen_addi_i32(addr, addr, val);
11221 if (insn & (1 << 11)) {
11222 /* load */
11223 tmp = tcg_temp_new_i32();
11224 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11225 store_reg(s, rd, tmp);
11226 } else {
11227 /* store */
11228 tmp = load_reg(s, rd);
11229 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11230 tcg_temp_free_i32(tmp);
11232 tcg_temp_free_i32(addr);
11233 break;
11235 case 7:
11236 /* load/store byte immediate offset */
11237 rd = insn & 7;
11238 rn = (insn >> 3) & 7;
11239 addr = load_reg(s, rn);
11240 val = (insn >> 6) & 0x1f;
11241 tcg_gen_addi_i32(addr, addr, val);
11243 if (insn & (1 << 11)) {
11244 /* load */
11245 tmp = tcg_temp_new_i32();
11246 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
11247 store_reg(s, rd, tmp);
11248 } else {
11249 /* store */
11250 tmp = load_reg(s, rd);
11251 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
11252 tcg_temp_free_i32(tmp);
11254 tcg_temp_free_i32(addr);
11255 break;
11257 case 8:
11258 /* load/store halfword immediate offset */
11259 rd = insn & 7;
11260 rn = (insn >> 3) & 7;
11261 addr = load_reg(s, rn);
11262 val = (insn >> 5) & 0x3e;
11263 tcg_gen_addi_i32(addr, addr, val);
11265 if (insn & (1 << 11)) {
11266 /* load */
11267 tmp = tcg_temp_new_i32();
11268 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
11269 store_reg(s, rd, tmp);
11270 } else {
11271 /* store */
11272 tmp = load_reg(s, rd);
11273 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
11274 tcg_temp_free_i32(tmp);
11276 tcg_temp_free_i32(addr);
11277 break;
11279 case 9:
11280 /* load/store from stack */
11281 rd = (insn >> 8) & 7;
11282 addr = load_reg(s, 13);
11283 val = (insn & 0xff) * 4;
11284 tcg_gen_addi_i32(addr, addr, val);
11286 if (insn & (1 << 11)) {
11287 /* load */
11288 tmp = tcg_temp_new_i32();
11289 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11290 store_reg(s, rd, tmp);
11291 } else {
11292 /* store */
11293 tmp = load_reg(s, rd);
11294 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11295 tcg_temp_free_i32(tmp);
11297 tcg_temp_free_i32(addr);
11298 break;
11300 case 10:
11301 /* add to high reg */
11302 rd = (insn >> 8) & 7;
11303 if (insn & (1 << 11)) {
11304 /* SP */
11305 tmp = load_reg(s, 13);
11306 } else {
11307 /* PC. bit 1 is ignored. */
11308 tmp = tcg_temp_new_i32();
11309 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11311 val = (insn & 0xff) * 4;
11312 tcg_gen_addi_i32(tmp, tmp, val);
11313 store_reg(s, rd, tmp);
11314 break;
11316 case 11:
11317 /* misc */
11318 op = (insn >> 8) & 0xf;
11319 switch (op) {
11320 case 0:
11321 /* adjust stack pointer */
11322 tmp = load_reg(s, 13);
11323 val = (insn & 0x7f) * 4;
11324 if (insn & (1 << 7))
11325 val = -(int32_t)val;
11326 tcg_gen_addi_i32(tmp, tmp, val);
11327 store_reg(s, 13, tmp);
11328 break;
11330 case 2: /* sign/zero extend. */
11331 ARCH(6);
11332 rd = insn & 7;
11333 rm = (insn >> 3) & 7;
11334 tmp = load_reg(s, rm);
11335 switch ((insn >> 6) & 3) {
11336 case 0: gen_sxth(tmp); break;
11337 case 1: gen_sxtb(tmp); break;
11338 case 2: gen_uxth(tmp); break;
11339 case 3: gen_uxtb(tmp); break;
11341 store_reg(s, rd, tmp);
11342 break;
11343 case 4: case 5: case 0xc: case 0xd:
11344 /* push/pop */
11345 addr = load_reg(s, 13);
11346 if (insn & (1 << 8))
11347 offset = 4;
11348 else
11349 offset = 0;
11350 for (i = 0; i < 8; i++) {
11351 if (insn & (1 << i))
11352 offset += 4;
11354 if ((insn & (1 << 11)) == 0) {
11355 tcg_gen_addi_i32(addr, addr, -offset);
11357 for (i = 0; i < 8; i++) {
11358 if (insn & (1 << i)) {
11359 if (insn & (1 << 11)) {
11360 /* pop */
11361 tmp = tcg_temp_new_i32();
11362 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11363 store_reg(s, i, tmp);
11364 } else {
11365 /* push */
11366 tmp = load_reg(s, i);
11367 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11368 tcg_temp_free_i32(tmp);
11370 /* advance to the next address. */
11371 tcg_gen_addi_i32(addr, addr, 4);
11374 TCGV_UNUSED_I32(tmp);
11375 if (insn & (1 << 8)) {
11376 if (insn & (1 << 11)) {
11377 /* pop pc */
11378 tmp = tcg_temp_new_i32();
11379 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11380 /* don't set the pc until the rest of the instruction
11381 has completed */
11382 } else {
11383 /* push lr */
11384 tmp = load_reg(s, 14);
11385 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11386 tcg_temp_free_i32(tmp);
11388 tcg_gen_addi_i32(addr, addr, 4);
11390 if ((insn & (1 << 11)) == 0) {
11391 tcg_gen_addi_i32(addr, addr, -offset);
11393 /* write back the new stack pointer */
11394 store_reg(s, 13, addr);
11395 /* set the new PC value */
11396 if ((insn & 0x0900) == 0x0900) {
11397 store_reg_from_load(s, 15, tmp);
11399 break;
11401 case 1: case 3: case 9: case 11: /* czb */
11402 rm = insn & 7;
11403 tmp = load_reg(s, rm);
11404 s->condlabel = gen_new_label();
11405 s->condjmp = 1;
11406 if (insn & (1 << 11))
11407 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11408 else
11409 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11410 tcg_temp_free_i32(tmp);
11411 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11412 val = (uint32_t)s->pc + 2;
11413 val += offset;
11414 gen_jmp(s, val);
11415 break;
11417 case 15: /* IT, nop-hint. */
11418 if ((insn & 0xf) == 0) {
11419 gen_nop_hint(s, (insn >> 4) & 0xf);
11420 break;
11422 /* If Then. */
11423 s->condexec_cond = (insn >> 4) & 0xe;
11424 s->condexec_mask = insn & 0x1f;
11425 /* No actual code generated for this insn, just setup state. */
11426 break;
11428 case 0xe: /* bkpt */
11430 int imm8 = extract32(insn, 0, 8);
11431 ARCH(5);
11432 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11433 default_exception_el(s));
11434 break;
11437 case 0xa: /* rev */
11438 ARCH(6);
11439 rn = (insn >> 3) & 0x7;
11440 rd = insn & 0x7;
11441 tmp = load_reg(s, rn);
11442 switch ((insn >> 6) & 3) {
11443 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11444 case 1: gen_rev16(tmp); break;
11445 case 3: gen_revsh(tmp); break;
11446 default: goto illegal_op;
11448 store_reg(s, rd, tmp);
11449 break;
11451 case 6:
11452 switch ((insn >> 5) & 7) {
11453 case 2:
11454 /* setend */
11455 ARCH(6);
11456 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11457 gen_helper_setend(cpu_env);
11458 s->is_jmp = DISAS_UPDATE;
11460 break;
11461 case 3:
11462 /* cps */
11463 ARCH(6);
11464 if (IS_USER(s)) {
11465 break;
11467 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11468 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11469 /* FAULTMASK */
11470 if (insn & 1) {
11471 addr = tcg_const_i32(19);
11472 gen_helper_v7m_msr(cpu_env, addr, tmp);
11473 tcg_temp_free_i32(addr);
11475 /* PRIMASK */
11476 if (insn & 2) {
11477 addr = tcg_const_i32(16);
11478 gen_helper_v7m_msr(cpu_env, addr, tmp);
11479 tcg_temp_free_i32(addr);
11481 tcg_temp_free_i32(tmp);
11482 gen_lookup_tb(s);
11483 } else {
11484 if (insn & (1 << 4)) {
11485 shift = CPSR_A | CPSR_I | CPSR_F;
11486 } else {
11487 shift = 0;
11489 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11491 break;
11492 default:
11493 goto undef;
11495 break;
11497 default:
11498 goto undef;
11500 break;
11502 case 12:
11504 /* load/store multiple */
11505 TCGv_i32 loaded_var;
11506 TCGV_UNUSED_I32(loaded_var);
11507 rn = (insn >> 8) & 0x7;
11508 addr = load_reg(s, rn);
11509 for (i = 0; i < 8; i++) {
11510 if (insn & (1 << i)) {
11511 if (insn & (1 << 11)) {
11512 /* load */
11513 tmp = tcg_temp_new_i32();
11514 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11515 if (i == rn) {
11516 loaded_var = tmp;
11517 } else {
11518 store_reg(s, i, tmp);
11520 } else {
11521 /* store */
11522 tmp = load_reg(s, i);
11523 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11524 tcg_temp_free_i32(tmp);
11526 /* advance to the next address */
11527 tcg_gen_addi_i32(addr, addr, 4);
11530 if ((insn & (1 << rn)) == 0) {
11531 /* base reg not in list: base register writeback */
11532 store_reg(s, rn, addr);
11533 } else {
11534 /* base reg in list: if load, complete it now */
11535 if (insn & (1 << 11)) {
11536 store_reg(s, rn, loaded_var);
11538 tcg_temp_free_i32(addr);
11540 break;
11542 case 13:
11543 /* conditional branch or swi */
11544 cond = (insn >> 8) & 0xf;
11545 if (cond == 0xe)
11546 goto undef;
11548 if (cond == 0xf) {
11549 /* swi */
11550 gen_set_pc_im(s, s->pc);
11551 s->svc_imm = extract32(insn, 0, 8);
11552 s->is_jmp = DISAS_SWI;
11553 break;
11555 /* generate a conditional jump to next instruction */
11556 s->condlabel = gen_new_label();
11557 arm_gen_test_cc(cond ^ 1, s->condlabel);
11558 s->condjmp = 1;
11560 /* jump to the offset */
11561 val = (uint32_t)s->pc + 2;
11562 offset = ((int32_t)insn << 24) >> 24;
11563 val += offset << 1;
11564 gen_jmp(s, val);
11565 break;
11567 case 14:
11568 if (insn & (1 << 11)) {
11569 if (disas_thumb2_insn(env, s, insn))
11570 goto undef32;
11571 break;
11573 /* unconditional branch */
11574 val = (uint32_t)s->pc;
11575 offset = ((int32_t)insn << 21) >> 21;
11576 val += (offset << 1) + 2;
11577 gen_jmp(s, val);
11578 break;
11580 case 15:
11581 if (disas_thumb2_insn(env, s, insn))
11582 goto undef32;
11583 break;
11585 return;
11586 undef32:
11587 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11588 default_exception_el(s));
11589 return;
11590 illegal_op:
11591 undef:
11592 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11593 default_exception_el(s));
11596 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11598 /* Return true if the insn at dc->pc might cross a page boundary.
11599 * (False positives are OK, false negatives are not.)
11601 uint16_t insn;
11603 if ((s->pc & 3) == 0) {
11604 /* At a 4-aligned address we can't be crossing a page */
11605 return false;
11608 /* This must be a Thumb insn */
11609 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11611 if ((insn >> 11) >= 0x1d) {
11612 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11613 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11614 * end up actually treating this as two 16-bit insns (see the
11615 * code at the start of disas_thumb2_insn()) but we don't bother
11616 * to check for that as it is unlikely, and false positives here
11617 * are harmless.
11619 return true;
11621 /* Definitely a 16-bit insn, can't be crossing a page. */
11622 return false;
11625 /* generate intermediate code for basic block 'tb'. */
11626 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11628 ARMCPU *cpu = arm_env_get_cpu(env);
11629 CPUState *cs = CPU(cpu);
11630 DisasContext dc1, *dc = &dc1;
11631 target_ulong pc_start;
11632 target_ulong next_page_start;
11633 int num_insns;
11634 int max_insns;
11635 bool end_of_page;
11637 /* generate intermediate code */
11639 /* The A64 decoder has its own top level loop, because it doesn't need
11640 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11642 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11643 gen_intermediate_code_a64(cpu, tb);
11644 return;
11647 pc_start = tb->pc;
11649 dc->tb = tb;
11651 dc->is_jmp = DISAS_NEXT;
11652 dc->pc = pc_start;
11653 dc->singlestep_enabled = cs->singlestep_enabled;
11654 dc->condjmp = 0;
11656 dc->aarch64 = 0;
11657 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11658 * there is no secure EL1, so we route exceptions to EL3.
11660 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11661 !arm_el_is_aa64(env, 3);
11662 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11663 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11664 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11665 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11666 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11667 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11668 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11669 #if !defined(CONFIG_USER_ONLY)
11670 dc->user = (dc->current_el == 0);
11671 #endif
11672 dc->ns = ARM_TBFLAG_NS(tb->flags);
11673 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11674 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11675 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11676 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11677 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11678 dc->cp_regs = cpu->cp_regs;
11679 dc->features = env->features;
11681 /* Single step state. The code-generation logic here is:
11682 * SS_ACTIVE == 0:
11683 * generate code with no special handling for single-stepping (except
11684 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11685 * this happens anyway because those changes are all system register or
11686 * PSTATE writes).
11687 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11688 * emit code for one insn
11689 * emit code to clear PSTATE.SS
11690 * emit code to generate software step exception for completed step
11691 * end TB (as usual for having generated an exception)
11692 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11693 * emit code to generate a software step exception
11694 * end the TB
11696 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11697 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11698 dc->is_ldex = false;
11699 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11701 cpu_F0s = tcg_temp_new_i32();
11702 cpu_F1s = tcg_temp_new_i32();
11703 cpu_F0d = tcg_temp_new_i64();
11704 cpu_F1d = tcg_temp_new_i64();
11705 cpu_V0 = cpu_F0d;
11706 cpu_V1 = cpu_F1d;
11707 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11708 cpu_M0 = tcg_temp_new_i64();
11709 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11710 num_insns = 0;
11711 max_insns = tb->cflags & CF_COUNT_MASK;
11712 if (max_insns == 0) {
11713 max_insns = CF_COUNT_MASK;
11715 if (max_insns > TCG_MAX_INSNS) {
11716 max_insns = TCG_MAX_INSNS;
11719 gen_tb_start(tb);
11721 tcg_clear_temp_count();
11723 /* A note on handling of the condexec (IT) bits:
11725 * We want to avoid the overhead of having to write the updated condexec
11726 * bits back to the CPUARMState for every instruction in an IT block. So:
11727 * (1) if the condexec bits are not already zero then we write
11728 * zero back into the CPUARMState now. This avoids complications trying
11729 * to do it at the end of the block. (For example if we don't do this
11730 * it's hard to identify whether we can safely skip writing condexec
11731 * at the end of the TB, which we definitely want to do for the case
11732 * where a TB doesn't do anything with the IT state at all.)
11733 * (2) if we are going to leave the TB then we call gen_set_condexec()
11734 * which will write the correct value into CPUARMState if zero is wrong.
11735 * This is done both for leaving the TB at the end, and for leaving
11736 * it because of an exception we know will happen, which is done in
11737 * gen_exception_insn(). The latter is necessary because we need to
11738 * leave the TB with the PC/IT state just prior to execution of the
11739 * instruction which caused the exception.
11740 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11741 * then the CPUARMState will be wrong and we need to reset it.
11742 * This is handled in the same way as restoration of the
11743 * PC in these situations; we save the value of the condexec bits
11744 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11745 * then uses this to restore them after an exception.
11747 * Note that there are no instructions which can read the condexec
11748 * bits, and none which can write non-static values to them, so
11749 * we don't need to care about whether CPUARMState is correct in the
11750 * middle of a TB.
11753 /* Reset the conditional execution bits immediately. This avoids
11754 complications trying to do it at the end of the block. */
11755 if (dc->condexec_mask || dc->condexec_cond)
11757 TCGv_i32 tmp = tcg_temp_new_i32();
11758 tcg_gen_movi_i32(tmp, 0);
11759 store_cpu_field(tmp, condexec_bits);
11761 do {
11762 tcg_gen_insn_start(dc->pc,
11763 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11765 num_insns++;
11767 #ifdef CONFIG_USER_ONLY
11768 /* Intercept jump to the magic kernel page. */
11769 if (dc->pc >= 0xffff0000) {
11770 /* We always get here via a jump, so know we are not in a
11771 conditional execution block. */
11772 gen_exception_internal(EXCP_KERNEL_TRAP);
11773 dc->is_jmp = DISAS_EXC;
11774 break;
11776 #else
11777 if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
11778 /* We always get here via a jump, so know we are not in a
11779 conditional execution block. */
11780 gen_exception_internal(EXCP_EXCEPTION_EXIT);
11781 dc->is_jmp = DISAS_EXC;
11782 break;
11784 #endif
11786 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11787 CPUBreakpoint *bp;
11788 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11789 if (bp->pc == dc->pc) {
11790 if (bp->flags & BP_CPU) {
11791 gen_set_condexec(dc);
11792 gen_set_pc_im(dc, dc->pc);
11793 gen_helper_check_breakpoints(cpu_env);
11794 /* End the TB early; it's likely not going to be executed */
11795 dc->is_jmp = DISAS_UPDATE;
11796 } else {
11797 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11798 /* The address covered by the breakpoint must be
11799 included in [tb->pc, tb->pc + tb->size) in order
11800 to for it to be properly cleared -- thus we
11801 increment the PC here so that the logic setting
11802 tb->size below does the right thing. */
11803 /* TODO: Advance PC by correct instruction length to
11804 * avoid disassembler error messages */
11805 dc->pc += 2;
11806 goto done_generating;
11808 break;
11813 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11814 gen_io_start();
11817 if (dc->ss_active && !dc->pstate_ss) {
11818 /* Singlestep state is Active-pending.
11819 * If we're in this state at the start of a TB then either
11820 * a) we just took an exception to an EL which is being debugged
11821 * and this is the first insn in the exception handler
11822 * b) debug exceptions were masked and we just unmasked them
11823 * without changing EL (eg by clearing PSTATE.D)
11824 * In either case we're going to take a swstep exception in the
11825 * "did not step an insn" case, and so the syndrome ISV and EX
11826 * bits should be zero.
11828 assert(num_insns == 1);
11829 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11830 default_exception_el(dc));
11831 goto done_generating;
11834 if (dc->thumb) {
11835 disas_thumb_insn(env, dc);
11836 if (dc->condexec_mask) {
11837 dc->condexec_cond = (dc->condexec_cond & 0xe)
11838 | ((dc->condexec_mask >> 4) & 1);
11839 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11840 if (dc->condexec_mask == 0) {
11841 dc->condexec_cond = 0;
11844 } else {
11845 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
11846 dc->pc += 4;
11847 disas_arm_insn(dc, insn);
11850 if (dc->condjmp && !dc->is_jmp) {
11851 gen_set_label(dc->condlabel);
11852 dc->condjmp = 0;
11855 if (tcg_check_temp_count()) {
11856 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11857 dc->pc);
11860 /* Translation stops when a conditional branch is encountered.
11861 * Otherwise the subsequent code could get translated several times.
11862 * Also stop translation when a page boundary is reached. This
11863 * ensures prefetch aborts occur at the right place. */
11865 /* We want to stop the TB if the next insn starts in a new page,
11866 * or if it spans between this page and the next. This means that
11867 * if we're looking at the last halfword in the page we need to
11868 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11869 * or a 32-bit Thumb insn (which won't).
11870 * This is to avoid generating a silly TB with a single 16-bit insn
11871 * in it at the end of this page (which would execute correctly
11872 * but isn't very efficient).
11874 end_of_page = (dc->pc >= next_page_start) ||
11875 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
11877 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11878 !cs->singlestep_enabled &&
11879 !singlestep &&
11880 !dc->ss_active &&
11881 !end_of_page &&
11882 num_insns < max_insns);
11884 if (tb->cflags & CF_LAST_IO) {
11885 if (dc->condjmp) {
11886 /* FIXME: This can theoretically happen with self-modifying
11887 code. */
11888 cpu_abort(cs, "IO on conditional branch instruction");
11890 gen_io_end();
11893 /* At this stage dc->condjmp will only be set when the skipped
11894 instruction was a conditional branch or trap, and the PC has
11895 already been written. */
11896 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11897 /* Unconditional and "condition passed" instruction codepath. */
11898 gen_set_condexec(dc);
11899 switch (dc->is_jmp) {
11900 case DISAS_SWI:
11901 gen_ss_advance(dc);
11902 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11903 default_exception_el(dc));
11904 break;
11905 case DISAS_HVC:
11906 gen_ss_advance(dc);
11907 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11908 break;
11909 case DISAS_SMC:
11910 gen_ss_advance(dc);
11911 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11912 break;
11913 case DISAS_NEXT:
11914 case DISAS_UPDATE:
11915 gen_set_pc_im(dc, dc->pc);
11916 /* fall through */
11917 default:
11918 if (dc->ss_active) {
11919 gen_step_complete_exception(dc);
11920 } else {
11921 /* FIXME: Single stepping a WFI insn will not halt
11922 the CPU. */
11923 gen_exception_internal(EXCP_DEBUG);
11926 if (dc->condjmp) {
11927 /* "Condition failed" instruction codepath. */
11928 gen_set_label(dc->condlabel);
11929 gen_set_condexec(dc);
11930 gen_set_pc_im(dc, dc->pc);
11931 if (dc->ss_active) {
11932 gen_step_complete_exception(dc);
11933 } else {
11934 gen_exception_internal(EXCP_DEBUG);
11937 } else {
11938 /* While branches must always occur at the end of an IT block,
11939 there are a few other things that can cause us to terminate
11940 the TB in the middle of an IT block:
11941 - Exception generating instructions (bkpt, swi, undefined).
11942 - Page boundaries.
11943 - Hardware watchpoints.
11944 Hardware breakpoints have already been handled and skip this code.
11946 gen_set_condexec(dc);
11947 switch(dc->is_jmp) {
11948 case DISAS_NEXT:
11949 gen_goto_tb(dc, 1, dc->pc);
11950 break;
11951 case DISAS_UPDATE:
11952 gen_set_pc_im(dc, dc->pc);
11953 /* fall through */
11954 case DISAS_JUMP:
11955 default:
11956 /* indicate that the hash table must be used to find the next TB */
11957 tcg_gen_exit_tb(0);
11958 break;
11959 case DISAS_TB_JUMP:
11960 /* nothing more to generate */
11961 break;
11962 case DISAS_WFI:
11963 gen_helper_wfi(cpu_env);
11964 /* The helper doesn't necessarily throw an exception, but we
11965 * must go back to the main loop to check for interrupts anyway.
11967 tcg_gen_exit_tb(0);
11968 break;
11969 case DISAS_WFE:
11970 gen_helper_wfe(cpu_env);
11971 break;
11972 case DISAS_YIELD:
11973 gen_helper_yield(cpu_env);
11974 break;
11975 case DISAS_SWI:
11976 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11977 default_exception_el(dc));
11978 break;
11979 case DISAS_HVC:
11980 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11981 break;
11982 case DISAS_SMC:
11983 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11984 break;
11986 if (dc->condjmp) {
11987 gen_set_label(dc->condlabel);
11988 gen_set_condexec(dc);
11989 gen_goto_tb(dc, 1, dc->pc);
11990 dc->condjmp = 0;
11994 done_generating:
11995 gen_tb_end(tb, num_insns);
11997 #ifdef DEBUG_DISAS
11998 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
11999 qemu_log_in_addr_range(pc_start)) {
12000 qemu_log("----------------\n");
12001 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12002 log_target_disas(cs, pc_start, dc->pc - pc_start,
12003 dc->thumb | (dc->sctlr_b << 1));
12004 qemu_log("\n");
12006 #endif
12007 tb->size = dc->pc - pc_start;
12008 tb->icount = num_insns;
12011 static const char *cpu_mode_names[16] = {
12012 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12013 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12016 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12017 int flags)
12019 ARMCPU *cpu = ARM_CPU(cs);
12020 CPUARMState *env = &cpu->env;
12021 int i;
12022 uint32_t psr;
12023 const char *ns_status;
12025 if (is_a64(env)) {
12026 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12027 return;
12030 for(i=0;i<16;i++) {
12031 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12032 if ((i % 4) == 3)
12033 cpu_fprintf(f, "\n");
12034 else
12035 cpu_fprintf(f, " ");
12037 psr = cpsr_read(env);
12039 if (arm_feature(env, ARM_FEATURE_EL3) &&
12040 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12041 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12042 } else {
12043 ns_status = "";
12046 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12047 psr,
12048 psr & (1 << 31) ? 'N' : '-',
12049 psr & (1 << 30) ? 'Z' : '-',
12050 psr & (1 << 29) ? 'C' : '-',
12051 psr & (1 << 28) ? 'V' : '-',
12052 psr & CPSR_T ? 'T' : 'A',
12053 ns_status,
12054 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12056 if (flags & CPU_DUMP_FPU) {
12057 int numvfpregs = 0;
12058 if (arm_feature(env, ARM_FEATURE_VFP)) {
12059 numvfpregs += 16;
12061 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12062 numvfpregs += 16;
12064 for (i = 0; i < numvfpregs; i++) {
12065 uint64_t v = float64_val(env->vfp.regs[i]);
12066 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12067 i * 2, (uint32_t)v,
12068 i * 2 + 1, (uint32_t)(v >> 32),
12069 i, v);
12071 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12075 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12076 target_ulong *data)
12078 if (is_a64(env)) {
12079 env->pc = data[0];
12080 env->condexec_bits = 0;
12081 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12082 } else {
12083 env->regs[15] = data[0];
12084 env->condexec_bits = data[1];
12085 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;