msix: implement pba write (but read-only)
[qemu/ar7.git] / target-arm / translate.c
blob9f1d740b4e13d5d27d1eef8e08b904cf6159756e
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 <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
27 #include "cpu.h"
28 #include "internals.h"
29 #include "disas/disas.h"
30 #include "tcg-op.h"
31 #include "qemu/log.h"
32 #include "qemu/bitops.h"
33 #include "arm_ldst.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J 0
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
62 TCGv_ptr cpu_env;
63 /* We reuse the same 64-bit temporaries for efficiency. */
64 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
65 static TCGv_i32 cpu_R[16];
66 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
67 TCGv_i64 cpu_exclusive_addr;
68 TCGv_i64 cpu_exclusive_val;
69 #ifdef CONFIG_USER_ONLY
70 TCGv_i64 cpu_exclusive_test;
71 TCGv_i32 cpu_exclusive_info;
72 #endif
74 /* FIXME: These should be removed. */
75 static TCGv_i32 cpu_F0s, cpu_F1s;
76 static TCGv_i64 cpu_F0d, cpu_F1d;
78 #include "exec/gen-icount.h"
80 static const char *regnames[] =
81 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
82 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
84 /* initialize TCG globals. */
85 void arm_translate_init(void)
87 int i;
89 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
91 for (i = 0; i < 16; i++) {
92 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
93 offsetof(CPUARMState, regs[i]),
94 regnames[i]);
96 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
97 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
98 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
99 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
101 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
102 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
103 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
104 offsetof(CPUARMState, exclusive_val), "exclusive_val");
105 #ifdef CONFIG_USER_ONLY
106 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
107 offsetof(CPUARMState, exclusive_test), "exclusive_test");
108 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
109 offsetof(CPUARMState, exclusive_info), "exclusive_info");
110 #endif
112 a64_translate_init();
115 static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
117 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
118 * insns:
119 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
120 * otherwise, access as if at PL0.
122 switch (s->mmu_idx) {
123 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
124 case ARMMMUIdx_S12NSE0:
125 case ARMMMUIdx_S12NSE1:
126 return ARMMMUIdx_S12NSE0;
127 case ARMMMUIdx_S1E3:
128 case ARMMMUIdx_S1SE0:
129 case ARMMMUIdx_S1SE1:
130 return ARMMMUIdx_S1SE0;
131 case ARMMMUIdx_S2NS:
132 default:
133 g_assert_not_reached();
137 static inline TCGv_i32 load_cpu_offset(int offset)
139 TCGv_i32 tmp = tcg_temp_new_i32();
140 tcg_gen_ld_i32(tmp, cpu_env, offset);
141 return tmp;
144 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
146 static inline void store_cpu_offset(TCGv_i32 var, int offset)
148 tcg_gen_st_i32(var, cpu_env, offset);
149 tcg_temp_free_i32(var);
152 #define store_cpu_field(var, name) \
153 store_cpu_offset(var, offsetof(CPUARMState, name))
155 /* Set a variable to the value of a CPU register. */
156 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
158 if (reg == 15) {
159 uint32_t addr;
160 /* normally, since we updated PC, we need only to add one insn */
161 if (s->thumb)
162 addr = (long)s->pc + 2;
163 else
164 addr = (long)s->pc + 4;
165 tcg_gen_movi_i32(var, addr);
166 } else {
167 tcg_gen_mov_i32(var, cpu_R[reg]);
171 /* Create a new temporary and set it to the value of a CPU register. */
172 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
174 TCGv_i32 tmp = tcg_temp_new_i32();
175 load_reg_var(s, tmp, reg);
176 return tmp;
179 /* Set a CPU register. The source must be a temporary and will be
180 marked as dead. */
181 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
183 if (reg == 15) {
184 tcg_gen_andi_i32(var, var, ~1);
185 s->is_jmp = DISAS_JUMP;
187 tcg_gen_mov_i32(cpu_R[reg], var);
188 tcg_temp_free_i32(var);
191 /* Value extensions. */
192 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
193 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
194 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
195 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
197 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
198 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
201 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
203 TCGv_i32 tmp_mask = tcg_const_i32(mask);
204 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
205 tcg_temp_free_i32(tmp_mask);
207 /* Set NZCV flags from the high 4 bits of var. */
208 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
210 static void gen_exception_internal(int excp)
212 TCGv_i32 tcg_excp = tcg_const_i32(excp);
214 assert(excp_is_internal(excp));
215 gen_helper_exception_internal(cpu_env, tcg_excp);
216 tcg_temp_free_i32(tcg_excp);
219 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
221 TCGv_i32 tcg_excp = tcg_const_i32(excp);
222 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
223 TCGv_i32 tcg_el = tcg_const_i32(target_el);
225 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
226 tcg_syn, tcg_el);
228 tcg_temp_free_i32(tcg_el);
229 tcg_temp_free_i32(tcg_syn);
230 tcg_temp_free_i32(tcg_excp);
233 static void gen_ss_advance(DisasContext *s)
235 /* If the singlestep state is Active-not-pending, advance to
236 * Active-pending.
238 if (s->ss_active) {
239 s->pstate_ss = 0;
240 gen_helper_clear_pstate_ss(cpu_env);
244 static void gen_step_complete_exception(DisasContext *s)
246 /* We just completed step of an insn. Move from Active-not-pending
247 * to Active-pending, and then also take the swstep exception.
248 * This corresponds to making the (IMPDEF) choice to prioritize
249 * swstep exceptions over asynchronous exceptions taken to an exception
250 * level where debug is disabled. This choice has the advantage that
251 * we do not need to maintain internal state corresponding to the
252 * ISV/EX syndrome bits between completion of the step and generation
253 * of the exception, and our syndrome information is always correct.
255 gen_ss_advance(s);
256 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
257 default_exception_el(s));
258 s->is_jmp = DISAS_EXC;
261 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
263 TCGv_i32 tmp1 = tcg_temp_new_i32();
264 TCGv_i32 tmp2 = tcg_temp_new_i32();
265 tcg_gen_ext16s_i32(tmp1, a);
266 tcg_gen_ext16s_i32(tmp2, b);
267 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
268 tcg_temp_free_i32(tmp2);
269 tcg_gen_sari_i32(a, a, 16);
270 tcg_gen_sari_i32(b, b, 16);
271 tcg_gen_mul_i32(b, b, a);
272 tcg_gen_mov_i32(a, tmp1);
273 tcg_temp_free_i32(tmp1);
276 /* Byteswap each halfword. */
277 static void gen_rev16(TCGv_i32 var)
279 TCGv_i32 tmp = tcg_temp_new_i32();
280 tcg_gen_shri_i32(tmp, var, 8);
281 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
282 tcg_gen_shli_i32(var, var, 8);
283 tcg_gen_andi_i32(var, var, 0xff00ff00);
284 tcg_gen_or_i32(var, var, tmp);
285 tcg_temp_free_i32(tmp);
288 /* Byteswap low halfword and sign extend. */
289 static void gen_revsh(TCGv_i32 var)
291 tcg_gen_ext16u_i32(var, var);
292 tcg_gen_bswap16_i32(var, var);
293 tcg_gen_ext16s_i32(var, var);
296 /* Unsigned bitfield extract. */
297 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
299 if (shift)
300 tcg_gen_shri_i32(var, var, shift);
301 tcg_gen_andi_i32(var, var, mask);
304 /* Signed bitfield extract. */
305 static void gen_sbfx(TCGv_i32 var, int shift, int width)
307 uint32_t signbit;
309 if (shift)
310 tcg_gen_sari_i32(var, var, shift);
311 if (shift + width < 32) {
312 signbit = 1u << (width - 1);
313 tcg_gen_andi_i32(var, var, (1u << width) - 1);
314 tcg_gen_xori_i32(var, var, signbit);
315 tcg_gen_subi_i32(var, var, signbit);
319 /* Return (b << 32) + a. Mark inputs as dead */
320 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
322 TCGv_i64 tmp64 = tcg_temp_new_i64();
324 tcg_gen_extu_i32_i64(tmp64, b);
325 tcg_temp_free_i32(b);
326 tcg_gen_shli_i64(tmp64, tmp64, 32);
327 tcg_gen_add_i64(a, tmp64, a);
329 tcg_temp_free_i64(tmp64);
330 return a;
333 /* Return (b << 32) - a. Mark inputs as dead. */
334 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
336 TCGv_i64 tmp64 = tcg_temp_new_i64();
338 tcg_gen_extu_i32_i64(tmp64, b);
339 tcg_temp_free_i32(b);
340 tcg_gen_shli_i64(tmp64, tmp64, 32);
341 tcg_gen_sub_i64(a, tmp64, a);
343 tcg_temp_free_i64(tmp64);
344 return a;
347 /* 32x32->64 multiply. Marks inputs as dead. */
348 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
350 TCGv_i32 lo = tcg_temp_new_i32();
351 TCGv_i32 hi = tcg_temp_new_i32();
352 TCGv_i64 ret;
354 tcg_gen_mulu2_i32(lo, hi, a, b);
355 tcg_temp_free_i32(a);
356 tcg_temp_free_i32(b);
358 ret = tcg_temp_new_i64();
359 tcg_gen_concat_i32_i64(ret, lo, hi);
360 tcg_temp_free_i32(lo);
361 tcg_temp_free_i32(hi);
363 return ret;
366 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
368 TCGv_i32 lo = tcg_temp_new_i32();
369 TCGv_i32 hi = tcg_temp_new_i32();
370 TCGv_i64 ret;
372 tcg_gen_muls2_i32(lo, hi, a, b);
373 tcg_temp_free_i32(a);
374 tcg_temp_free_i32(b);
376 ret = tcg_temp_new_i64();
377 tcg_gen_concat_i32_i64(ret, lo, hi);
378 tcg_temp_free_i32(lo);
379 tcg_temp_free_i32(hi);
381 return ret;
384 /* Swap low and high halfwords. */
385 static void gen_swap_half(TCGv_i32 var)
387 TCGv_i32 tmp = tcg_temp_new_i32();
388 tcg_gen_shri_i32(tmp, var, 16);
389 tcg_gen_shli_i32(var, var, 16);
390 tcg_gen_or_i32(var, var, tmp);
391 tcg_temp_free_i32(tmp);
394 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
395 tmp = (t0 ^ t1) & 0x8000;
396 t0 &= ~0x8000;
397 t1 &= ~0x8000;
398 t0 = (t0 + t1) ^ tmp;
401 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
403 TCGv_i32 tmp = tcg_temp_new_i32();
404 tcg_gen_xor_i32(tmp, t0, t1);
405 tcg_gen_andi_i32(tmp, tmp, 0x8000);
406 tcg_gen_andi_i32(t0, t0, ~0x8000);
407 tcg_gen_andi_i32(t1, t1, ~0x8000);
408 tcg_gen_add_i32(t0, t0, t1);
409 tcg_gen_xor_i32(t0, t0, tmp);
410 tcg_temp_free_i32(tmp);
411 tcg_temp_free_i32(t1);
414 /* Set CF to the top bit of var. */
415 static void gen_set_CF_bit31(TCGv_i32 var)
417 tcg_gen_shri_i32(cpu_CF, var, 31);
420 /* Set N and Z flags from var. */
421 static inline void gen_logic_CC(TCGv_i32 var)
423 tcg_gen_mov_i32(cpu_NF, var);
424 tcg_gen_mov_i32(cpu_ZF, var);
427 /* T0 += T1 + CF. */
428 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
430 tcg_gen_add_i32(t0, t0, t1);
431 tcg_gen_add_i32(t0, t0, cpu_CF);
434 /* dest = T0 + T1 + CF. */
435 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
437 tcg_gen_add_i32(dest, t0, t1);
438 tcg_gen_add_i32(dest, dest, cpu_CF);
441 /* dest = T0 - T1 + CF - 1. */
442 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
444 tcg_gen_sub_i32(dest, t0, t1);
445 tcg_gen_add_i32(dest, dest, cpu_CF);
446 tcg_gen_subi_i32(dest, dest, 1);
449 /* dest = T0 + T1. Compute C, N, V and Z flags */
450 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
452 TCGv_i32 tmp = tcg_temp_new_i32();
453 tcg_gen_movi_i32(tmp, 0);
454 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
455 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
456 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
457 tcg_gen_xor_i32(tmp, t0, t1);
458 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
459 tcg_temp_free_i32(tmp);
460 tcg_gen_mov_i32(dest, cpu_NF);
463 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
464 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
466 TCGv_i32 tmp = tcg_temp_new_i32();
467 if (TCG_TARGET_HAS_add2_i32) {
468 tcg_gen_movi_i32(tmp, 0);
469 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
470 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
471 } else {
472 TCGv_i64 q0 = tcg_temp_new_i64();
473 TCGv_i64 q1 = tcg_temp_new_i64();
474 tcg_gen_extu_i32_i64(q0, t0);
475 tcg_gen_extu_i32_i64(q1, t1);
476 tcg_gen_add_i64(q0, q0, q1);
477 tcg_gen_extu_i32_i64(q1, cpu_CF);
478 tcg_gen_add_i64(q0, q0, q1);
479 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
480 tcg_temp_free_i64(q0);
481 tcg_temp_free_i64(q1);
483 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
484 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
485 tcg_gen_xor_i32(tmp, t0, t1);
486 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
487 tcg_temp_free_i32(tmp);
488 tcg_gen_mov_i32(dest, cpu_NF);
491 /* dest = T0 - T1. Compute C, N, V and Z flags */
492 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
494 TCGv_i32 tmp;
495 tcg_gen_sub_i32(cpu_NF, t0, t1);
496 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
497 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
498 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
499 tmp = tcg_temp_new_i32();
500 tcg_gen_xor_i32(tmp, t0, t1);
501 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
502 tcg_temp_free_i32(tmp);
503 tcg_gen_mov_i32(dest, cpu_NF);
506 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
507 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
509 TCGv_i32 tmp = tcg_temp_new_i32();
510 tcg_gen_not_i32(tmp, t1);
511 gen_adc_CC(dest, t0, tmp);
512 tcg_temp_free_i32(tmp);
515 #define GEN_SHIFT(name) \
516 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
518 TCGv_i32 tmp1, tmp2, tmp3; \
519 tmp1 = tcg_temp_new_i32(); \
520 tcg_gen_andi_i32(tmp1, t1, 0xff); \
521 tmp2 = tcg_const_i32(0); \
522 tmp3 = tcg_const_i32(0x1f); \
523 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
524 tcg_temp_free_i32(tmp3); \
525 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
526 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
527 tcg_temp_free_i32(tmp2); \
528 tcg_temp_free_i32(tmp1); \
530 GEN_SHIFT(shl)
531 GEN_SHIFT(shr)
532 #undef GEN_SHIFT
534 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
536 TCGv_i32 tmp1, tmp2;
537 tmp1 = tcg_temp_new_i32();
538 tcg_gen_andi_i32(tmp1, t1, 0xff);
539 tmp2 = tcg_const_i32(0x1f);
540 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
541 tcg_temp_free_i32(tmp2);
542 tcg_gen_sar_i32(dest, t0, tmp1);
543 tcg_temp_free_i32(tmp1);
546 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
548 TCGv_i32 c0 = tcg_const_i32(0);
549 TCGv_i32 tmp = tcg_temp_new_i32();
550 tcg_gen_neg_i32(tmp, src);
551 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
552 tcg_temp_free_i32(c0);
553 tcg_temp_free_i32(tmp);
556 static void shifter_out_im(TCGv_i32 var, int shift)
558 if (shift == 0) {
559 tcg_gen_andi_i32(cpu_CF, var, 1);
560 } else {
561 tcg_gen_shri_i32(cpu_CF, var, shift);
562 if (shift != 31) {
563 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
568 /* Shift by immediate. Includes special handling for shift == 0. */
569 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
570 int shift, int flags)
572 switch (shiftop) {
573 case 0: /* LSL */
574 if (shift != 0) {
575 if (flags)
576 shifter_out_im(var, 32 - shift);
577 tcg_gen_shli_i32(var, var, shift);
579 break;
580 case 1: /* LSR */
581 if (shift == 0) {
582 if (flags) {
583 tcg_gen_shri_i32(cpu_CF, var, 31);
585 tcg_gen_movi_i32(var, 0);
586 } else {
587 if (flags)
588 shifter_out_im(var, shift - 1);
589 tcg_gen_shri_i32(var, var, shift);
591 break;
592 case 2: /* ASR */
593 if (shift == 0)
594 shift = 32;
595 if (flags)
596 shifter_out_im(var, shift - 1);
597 if (shift == 32)
598 shift = 31;
599 tcg_gen_sari_i32(var, var, shift);
600 break;
601 case 3: /* ROR/RRX */
602 if (shift != 0) {
603 if (flags)
604 shifter_out_im(var, shift - 1);
605 tcg_gen_rotri_i32(var, var, shift); break;
606 } else {
607 TCGv_i32 tmp = tcg_temp_new_i32();
608 tcg_gen_shli_i32(tmp, cpu_CF, 31);
609 if (flags)
610 shifter_out_im(var, 0);
611 tcg_gen_shri_i32(var, var, 1);
612 tcg_gen_or_i32(var, var, tmp);
613 tcg_temp_free_i32(tmp);
618 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
619 TCGv_i32 shift, int flags)
621 if (flags) {
622 switch (shiftop) {
623 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
624 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
625 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
626 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
628 } else {
629 switch (shiftop) {
630 case 0:
631 gen_shl(var, var, shift);
632 break;
633 case 1:
634 gen_shr(var, var, shift);
635 break;
636 case 2:
637 gen_sar(var, var, shift);
638 break;
639 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
640 tcg_gen_rotr_i32(var, var, shift); break;
643 tcg_temp_free_i32(shift);
646 #define PAS_OP(pfx) \
647 switch (op2) { \
648 case 0: gen_pas_helper(glue(pfx,add16)); break; \
649 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
650 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
651 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
652 case 4: gen_pas_helper(glue(pfx,add8)); break; \
653 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
655 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
657 TCGv_ptr tmp;
659 switch (op1) {
660 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
661 case 1:
662 tmp = tcg_temp_new_ptr();
663 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
664 PAS_OP(s)
665 tcg_temp_free_ptr(tmp);
666 break;
667 case 5:
668 tmp = tcg_temp_new_ptr();
669 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
670 PAS_OP(u)
671 tcg_temp_free_ptr(tmp);
672 break;
673 #undef gen_pas_helper
674 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
675 case 2:
676 PAS_OP(q);
677 break;
678 case 3:
679 PAS_OP(sh);
680 break;
681 case 6:
682 PAS_OP(uq);
683 break;
684 case 7:
685 PAS_OP(uh);
686 break;
687 #undef gen_pas_helper
690 #undef PAS_OP
692 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
693 #define PAS_OP(pfx) \
694 switch (op1) { \
695 case 0: gen_pas_helper(glue(pfx,add8)); break; \
696 case 1: gen_pas_helper(glue(pfx,add16)); break; \
697 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
698 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
699 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
700 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
702 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
704 TCGv_ptr tmp;
706 switch (op2) {
707 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
708 case 0:
709 tmp = tcg_temp_new_ptr();
710 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
711 PAS_OP(s)
712 tcg_temp_free_ptr(tmp);
713 break;
714 case 4:
715 tmp = tcg_temp_new_ptr();
716 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
717 PAS_OP(u)
718 tcg_temp_free_ptr(tmp);
719 break;
720 #undef gen_pas_helper
721 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
722 case 1:
723 PAS_OP(q);
724 break;
725 case 2:
726 PAS_OP(sh);
727 break;
728 case 5:
729 PAS_OP(uq);
730 break;
731 case 6:
732 PAS_OP(uh);
733 break;
734 #undef gen_pas_helper
737 #undef PAS_OP
740 * Generate a conditional based on ARM condition code cc.
741 * This is common between ARM and Aarch64 targets.
743 void arm_test_cc(DisasCompare *cmp, int cc)
745 TCGv_i32 value;
746 TCGCond cond;
747 bool global = true;
749 switch (cc) {
750 case 0: /* eq: Z */
751 case 1: /* ne: !Z */
752 cond = TCG_COND_EQ;
753 value = cpu_ZF;
754 break;
756 case 2: /* cs: C */
757 case 3: /* cc: !C */
758 cond = TCG_COND_NE;
759 value = cpu_CF;
760 break;
762 case 4: /* mi: N */
763 case 5: /* pl: !N */
764 cond = TCG_COND_LT;
765 value = cpu_NF;
766 break;
768 case 6: /* vs: V */
769 case 7: /* vc: !V */
770 cond = TCG_COND_LT;
771 value = cpu_VF;
772 break;
774 case 8: /* hi: C && !Z */
775 case 9: /* ls: !C || Z -> !(C && !Z) */
776 cond = TCG_COND_NE;
777 value = tcg_temp_new_i32();
778 global = false;
779 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
780 ZF is non-zero for !Z; so AND the two subexpressions. */
781 tcg_gen_neg_i32(value, cpu_CF);
782 tcg_gen_and_i32(value, value, cpu_ZF);
783 break;
785 case 10: /* ge: N == V -> N ^ V == 0 */
786 case 11: /* lt: N != V -> N ^ V != 0 */
787 /* Since we're only interested in the sign bit, == 0 is >= 0. */
788 cond = TCG_COND_GE;
789 value = tcg_temp_new_i32();
790 global = false;
791 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
792 break;
794 case 12: /* gt: !Z && N == V */
795 case 13: /* le: Z || N != V */
796 cond = TCG_COND_NE;
797 value = tcg_temp_new_i32();
798 global = false;
799 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
800 * the sign bit then AND with ZF to yield the result. */
801 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
802 tcg_gen_sari_i32(value, value, 31);
803 tcg_gen_andc_i32(value, cpu_ZF, value);
804 break;
806 case 14: /* always */
807 case 15: /* always */
808 /* Use the ALWAYS condition, which will fold early.
809 * It doesn't matter what we use for the value. */
810 cond = TCG_COND_ALWAYS;
811 value = cpu_ZF;
812 goto no_invert;
814 default:
815 fprintf(stderr, "Bad condition code 0x%x\n", cc);
816 abort();
819 if (cc & 1) {
820 cond = tcg_invert_cond(cond);
823 no_invert:
824 cmp->cond = cond;
825 cmp->value = value;
826 cmp->value_global = global;
829 void arm_free_cc(DisasCompare *cmp)
831 if (!cmp->value_global) {
832 tcg_temp_free_i32(cmp->value);
836 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
838 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
841 void arm_gen_test_cc(int cc, TCGLabel *label)
843 DisasCompare cmp;
844 arm_test_cc(&cmp, cc);
845 arm_jump_cc(&cmp, label);
846 arm_free_cc(&cmp);
849 static const uint8_t table_logic_cc[16] = {
850 1, /* and */
851 1, /* xor */
852 0, /* sub */
853 0, /* rsb */
854 0, /* add */
855 0, /* adc */
856 0, /* sbc */
857 0, /* rsc */
858 1, /* andl */
859 1, /* xorl */
860 0, /* cmp */
861 0, /* cmn */
862 1, /* orr */
863 1, /* mov */
864 1, /* bic */
865 1, /* mvn */
868 /* Set PC and Thumb state from an immediate address. */
869 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
871 TCGv_i32 tmp;
873 s->is_jmp = DISAS_UPDATE;
874 if (s->thumb != (addr & 1)) {
875 tmp = tcg_temp_new_i32();
876 tcg_gen_movi_i32(tmp, addr & 1);
877 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
878 tcg_temp_free_i32(tmp);
880 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
883 /* Set PC and Thumb state from var. var is marked as dead. */
884 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
886 s->is_jmp = DISAS_UPDATE;
887 tcg_gen_andi_i32(cpu_R[15], var, ~1);
888 tcg_gen_andi_i32(var, var, 1);
889 store_cpu_field(var, thumb);
892 /* Variant of store_reg which uses branch&exchange logic when storing
893 to r15 in ARM architecture v7 and above. The source must be a temporary
894 and will be marked as dead. */
895 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
897 if (reg == 15 && ENABLE_ARCH_7) {
898 gen_bx(s, var);
899 } else {
900 store_reg(s, reg, var);
904 /* Variant of store_reg which uses branch&exchange logic when storing
905 * to r15 in ARM architecture v5T and above. This is used for storing
906 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
907 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
908 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
910 if (reg == 15 && ENABLE_ARCH_5) {
911 gen_bx(s, var);
912 } else {
913 store_reg(s, reg, var);
917 /* Abstractions of "generate code to do a guest load/store for
918 * AArch32", where a vaddr is always 32 bits (and is zero
919 * extended if we're a 64 bit core) and data is also
920 * 32 bits unless specifically doing a 64 bit access.
921 * These functions work like tcg_gen_qemu_{ld,st}* except
922 * that the address argument is TCGv_i32 rather than TCGv.
924 #if TARGET_LONG_BITS == 32
926 #define DO_GEN_LD(SUFF, OPC) \
927 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
929 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
932 #define DO_GEN_ST(SUFF, OPC) \
933 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
935 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
938 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
940 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
943 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
945 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
948 #else
950 #define DO_GEN_LD(SUFF, OPC) \
951 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
953 TCGv addr64 = tcg_temp_new(); \
954 tcg_gen_extu_i32_i64(addr64, addr); \
955 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
956 tcg_temp_free(addr64); \
959 #define DO_GEN_ST(SUFF, OPC) \
960 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
962 TCGv addr64 = tcg_temp_new(); \
963 tcg_gen_extu_i32_i64(addr64, addr); \
964 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
965 tcg_temp_free(addr64); \
968 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
970 TCGv addr64 = tcg_temp_new();
971 tcg_gen_extu_i32_i64(addr64, addr);
972 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
973 tcg_temp_free(addr64);
976 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
978 TCGv addr64 = tcg_temp_new();
979 tcg_gen_extu_i32_i64(addr64, addr);
980 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
981 tcg_temp_free(addr64);
984 #endif
986 DO_GEN_LD(8s, MO_SB)
987 DO_GEN_LD(8u, MO_UB)
988 DO_GEN_LD(16s, MO_TESW)
989 DO_GEN_LD(16u, MO_TEUW)
990 DO_GEN_LD(32u, MO_TEUL)
991 DO_GEN_ST(8, MO_UB)
992 DO_GEN_ST(16, MO_TEUW)
993 DO_GEN_ST(32, MO_TEUL)
995 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
997 tcg_gen_movi_i32(cpu_R[15], val);
1000 static inline void gen_hvc(DisasContext *s, int imm16)
1002 /* The pre HVC helper handles cases when HVC gets trapped
1003 * as an undefined insn by runtime configuration (ie before
1004 * the insn really executes).
1006 gen_set_pc_im(s, s->pc - 4);
1007 gen_helper_pre_hvc(cpu_env);
1008 /* Otherwise we will treat this as a real exception which
1009 * happens after execution of the insn. (The distinction matters
1010 * for the PC value reported to the exception handler and also
1011 * for single stepping.)
1013 s->svc_imm = imm16;
1014 gen_set_pc_im(s, s->pc);
1015 s->is_jmp = DISAS_HVC;
1018 static inline void gen_smc(DisasContext *s)
1020 /* As with HVC, we may take an exception either before or after
1021 * the insn executes.
1023 TCGv_i32 tmp;
1025 gen_set_pc_im(s, s->pc - 4);
1026 tmp = tcg_const_i32(syn_aa32_smc());
1027 gen_helper_pre_smc(cpu_env, tmp);
1028 tcg_temp_free_i32(tmp);
1029 gen_set_pc_im(s, s->pc);
1030 s->is_jmp = DISAS_SMC;
1033 static inline void
1034 gen_set_condexec (DisasContext *s)
1036 if (s->condexec_mask) {
1037 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1038 TCGv_i32 tmp = tcg_temp_new_i32();
1039 tcg_gen_movi_i32(tmp, val);
1040 store_cpu_field(tmp, condexec_bits);
1044 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1046 gen_set_condexec(s);
1047 gen_set_pc_im(s, s->pc - offset);
1048 gen_exception_internal(excp);
1049 s->is_jmp = DISAS_JUMP;
1052 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1053 int syn, uint32_t target_el)
1055 gen_set_condexec(s);
1056 gen_set_pc_im(s, s->pc - offset);
1057 gen_exception(excp, syn, target_el);
1058 s->is_jmp = DISAS_JUMP;
1061 /* Force a TB lookup after an instruction that changes the CPU state. */
1062 static inline void gen_lookup_tb(DisasContext *s)
1064 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1065 s->is_jmp = DISAS_UPDATE;
1068 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1069 TCGv_i32 var)
1071 int val, rm, shift, shiftop;
1072 TCGv_i32 offset;
1074 if (!(insn & (1 << 25))) {
1075 /* immediate */
1076 val = insn & 0xfff;
1077 if (!(insn & (1 << 23)))
1078 val = -val;
1079 if (val != 0)
1080 tcg_gen_addi_i32(var, var, val);
1081 } else {
1082 /* shift/register */
1083 rm = (insn) & 0xf;
1084 shift = (insn >> 7) & 0x1f;
1085 shiftop = (insn >> 5) & 3;
1086 offset = load_reg(s, rm);
1087 gen_arm_shift_im(offset, shiftop, shift, 0);
1088 if (!(insn & (1 << 23)))
1089 tcg_gen_sub_i32(var, var, offset);
1090 else
1091 tcg_gen_add_i32(var, var, offset);
1092 tcg_temp_free_i32(offset);
1096 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1097 int extra, TCGv_i32 var)
1099 int val, rm;
1100 TCGv_i32 offset;
1102 if (insn & (1 << 22)) {
1103 /* immediate */
1104 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1105 if (!(insn & (1 << 23)))
1106 val = -val;
1107 val += extra;
1108 if (val != 0)
1109 tcg_gen_addi_i32(var, var, val);
1110 } else {
1111 /* register */
1112 if (extra)
1113 tcg_gen_addi_i32(var, var, extra);
1114 rm = (insn) & 0xf;
1115 offset = load_reg(s, rm);
1116 if (!(insn & (1 << 23)))
1117 tcg_gen_sub_i32(var, var, offset);
1118 else
1119 tcg_gen_add_i32(var, var, offset);
1120 tcg_temp_free_i32(offset);
1124 static TCGv_ptr get_fpstatus_ptr(int neon)
1126 TCGv_ptr statusptr = tcg_temp_new_ptr();
1127 int offset;
1128 if (neon) {
1129 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1130 } else {
1131 offset = offsetof(CPUARMState, vfp.fp_status);
1133 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1134 return statusptr;
1137 #define VFP_OP2(name) \
1138 static inline void gen_vfp_##name(int dp) \
1140 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1141 if (dp) { \
1142 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1143 } else { \
1144 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1146 tcg_temp_free_ptr(fpst); \
1149 VFP_OP2(add)
1150 VFP_OP2(sub)
1151 VFP_OP2(mul)
1152 VFP_OP2(div)
1154 #undef VFP_OP2
1156 static inline void gen_vfp_F1_mul(int dp)
1158 /* Like gen_vfp_mul() but put result in F1 */
1159 TCGv_ptr fpst = get_fpstatus_ptr(0);
1160 if (dp) {
1161 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1162 } else {
1163 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1165 tcg_temp_free_ptr(fpst);
1168 static inline void gen_vfp_F1_neg(int dp)
1170 /* Like gen_vfp_neg() but put result in F1 */
1171 if (dp) {
1172 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1173 } else {
1174 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1178 static inline void gen_vfp_abs(int dp)
1180 if (dp)
1181 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1182 else
1183 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1186 static inline void gen_vfp_neg(int dp)
1188 if (dp)
1189 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1190 else
1191 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1194 static inline void gen_vfp_sqrt(int dp)
1196 if (dp)
1197 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1198 else
1199 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1202 static inline void gen_vfp_cmp(int dp)
1204 if (dp)
1205 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1206 else
1207 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1210 static inline void gen_vfp_cmpe(int dp)
1212 if (dp)
1213 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1214 else
1215 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1218 static inline void gen_vfp_F1_ld0(int dp)
1220 if (dp)
1221 tcg_gen_movi_i64(cpu_F1d, 0);
1222 else
1223 tcg_gen_movi_i32(cpu_F1s, 0);
1226 #define VFP_GEN_ITOF(name) \
1227 static inline void gen_vfp_##name(int dp, int neon) \
1229 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1230 if (dp) { \
1231 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1232 } else { \
1233 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1235 tcg_temp_free_ptr(statusptr); \
1238 VFP_GEN_ITOF(uito)
1239 VFP_GEN_ITOF(sito)
1240 #undef VFP_GEN_ITOF
1242 #define VFP_GEN_FTOI(name) \
1243 static inline void gen_vfp_##name(int dp, int neon) \
1245 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1246 if (dp) { \
1247 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1248 } else { \
1249 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1251 tcg_temp_free_ptr(statusptr); \
1254 VFP_GEN_FTOI(toui)
1255 VFP_GEN_FTOI(touiz)
1256 VFP_GEN_FTOI(tosi)
1257 VFP_GEN_FTOI(tosiz)
1258 #undef VFP_GEN_FTOI
1260 #define VFP_GEN_FIX(name, round) \
1261 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1263 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1264 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1265 if (dp) { \
1266 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1267 statusptr); \
1268 } else { \
1269 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1270 statusptr); \
1272 tcg_temp_free_i32(tmp_shift); \
1273 tcg_temp_free_ptr(statusptr); \
1275 VFP_GEN_FIX(tosh, _round_to_zero)
1276 VFP_GEN_FIX(tosl, _round_to_zero)
1277 VFP_GEN_FIX(touh, _round_to_zero)
1278 VFP_GEN_FIX(toul, _round_to_zero)
1279 VFP_GEN_FIX(shto, )
1280 VFP_GEN_FIX(slto, )
1281 VFP_GEN_FIX(uhto, )
1282 VFP_GEN_FIX(ulto, )
1283 #undef VFP_GEN_FIX
1285 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1287 if (dp) {
1288 gen_aa32_ld64(cpu_F0d, addr, get_mem_index(s));
1289 } else {
1290 gen_aa32_ld32u(cpu_F0s, addr, get_mem_index(s));
1294 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1296 if (dp) {
1297 gen_aa32_st64(cpu_F0d, addr, get_mem_index(s));
1298 } else {
1299 gen_aa32_st32(cpu_F0s, addr, get_mem_index(s));
1303 static inline long
1304 vfp_reg_offset (int dp, int reg)
1306 if (dp)
1307 return offsetof(CPUARMState, vfp.regs[reg]);
1308 else if (reg & 1) {
1309 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1310 + offsetof(CPU_DoubleU, l.upper);
1311 } else {
1312 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1313 + offsetof(CPU_DoubleU, l.lower);
1317 /* Return the offset of a 32-bit piece of a NEON register.
1318 zero is the least significant end of the register. */
1319 static inline long
1320 neon_reg_offset (int reg, int n)
1322 int sreg;
1323 sreg = reg * 2 + n;
1324 return vfp_reg_offset(0, sreg);
1327 static TCGv_i32 neon_load_reg(int reg, int pass)
1329 TCGv_i32 tmp = tcg_temp_new_i32();
1330 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1331 return tmp;
1334 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1336 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1337 tcg_temp_free_i32(var);
1340 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1342 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1345 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1347 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1350 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1351 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1352 #define tcg_gen_st_f32 tcg_gen_st_i32
1353 #define tcg_gen_st_f64 tcg_gen_st_i64
1355 static inline void gen_mov_F0_vreg(int dp, int reg)
1357 if (dp)
1358 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1359 else
1360 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1363 static inline void gen_mov_F1_vreg(int dp, int reg)
1365 if (dp)
1366 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1367 else
1368 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1371 static inline void gen_mov_vreg_F0(int dp, int reg)
1373 if (dp)
1374 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1375 else
1376 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1379 #define ARM_CP_RW_BIT (1 << 20)
1381 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1383 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1386 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1388 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1391 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1393 TCGv_i32 var = tcg_temp_new_i32();
1394 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1395 return var;
1398 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1400 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1401 tcg_temp_free_i32(var);
1404 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1406 iwmmxt_store_reg(cpu_M0, rn);
1409 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1411 iwmmxt_load_reg(cpu_M0, rn);
1414 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1416 iwmmxt_load_reg(cpu_V1, rn);
1417 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1420 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1422 iwmmxt_load_reg(cpu_V1, rn);
1423 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1426 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1428 iwmmxt_load_reg(cpu_V1, rn);
1429 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1432 #define IWMMXT_OP(name) \
1433 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1435 iwmmxt_load_reg(cpu_V1, rn); \
1436 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1439 #define IWMMXT_OP_ENV(name) \
1440 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1442 iwmmxt_load_reg(cpu_V1, rn); \
1443 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1446 #define IWMMXT_OP_ENV_SIZE(name) \
1447 IWMMXT_OP_ENV(name##b) \
1448 IWMMXT_OP_ENV(name##w) \
1449 IWMMXT_OP_ENV(name##l)
1451 #define IWMMXT_OP_ENV1(name) \
1452 static inline void gen_op_iwmmxt_##name##_M0(void) \
1454 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1457 IWMMXT_OP(maddsq)
1458 IWMMXT_OP(madduq)
1459 IWMMXT_OP(sadb)
1460 IWMMXT_OP(sadw)
1461 IWMMXT_OP(mulslw)
1462 IWMMXT_OP(mulshw)
1463 IWMMXT_OP(mululw)
1464 IWMMXT_OP(muluhw)
1465 IWMMXT_OP(macsw)
1466 IWMMXT_OP(macuw)
1468 IWMMXT_OP_ENV_SIZE(unpackl)
1469 IWMMXT_OP_ENV_SIZE(unpackh)
1471 IWMMXT_OP_ENV1(unpacklub)
1472 IWMMXT_OP_ENV1(unpackluw)
1473 IWMMXT_OP_ENV1(unpacklul)
1474 IWMMXT_OP_ENV1(unpackhub)
1475 IWMMXT_OP_ENV1(unpackhuw)
1476 IWMMXT_OP_ENV1(unpackhul)
1477 IWMMXT_OP_ENV1(unpacklsb)
1478 IWMMXT_OP_ENV1(unpacklsw)
1479 IWMMXT_OP_ENV1(unpacklsl)
1480 IWMMXT_OP_ENV1(unpackhsb)
1481 IWMMXT_OP_ENV1(unpackhsw)
1482 IWMMXT_OP_ENV1(unpackhsl)
1484 IWMMXT_OP_ENV_SIZE(cmpeq)
1485 IWMMXT_OP_ENV_SIZE(cmpgtu)
1486 IWMMXT_OP_ENV_SIZE(cmpgts)
1488 IWMMXT_OP_ENV_SIZE(mins)
1489 IWMMXT_OP_ENV_SIZE(minu)
1490 IWMMXT_OP_ENV_SIZE(maxs)
1491 IWMMXT_OP_ENV_SIZE(maxu)
1493 IWMMXT_OP_ENV_SIZE(subn)
1494 IWMMXT_OP_ENV_SIZE(addn)
1495 IWMMXT_OP_ENV_SIZE(subu)
1496 IWMMXT_OP_ENV_SIZE(addu)
1497 IWMMXT_OP_ENV_SIZE(subs)
1498 IWMMXT_OP_ENV_SIZE(adds)
1500 IWMMXT_OP_ENV(avgb0)
1501 IWMMXT_OP_ENV(avgb1)
1502 IWMMXT_OP_ENV(avgw0)
1503 IWMMXT_OP_ENV(avgw1)
1505 IWMMXT_OP_ENV(packuw)
1506 IWMMXT_OP_ENV(packul)
1507 IWMMXT_OP_ENV(packuq)
1508 IWMMXT_OP_ENV(packsw)
1509 IWMMXT_OP_ENV(packsl)
1510 IWMMXT_OP_ENV(packsq)
1512 static void gen_op_iwmmxt_set_mup(void)
1514 TCGv_i32 tmp;
1515 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1516 tcg_gen_ori_i32(tmp, tmp, 2);
1517 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1520 static void gen_op_iwmmxt_set_cup(void)
1522 TCGv_i32 tmp;
1523 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1524 tcg_gen_ori_i32(tmp, tmp, 1);
1525 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1528 static void gen_op_iwmmxt_setpsr_nz(void)
1530 TCGv_i32 tmp = tcg_temp_new_i32();
1531 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1532 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1535 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1537 iwmmxt_load_reg(cpu_V1, rn);
1538 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1539 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1542 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1543 TCGv_i32 dest)
1545 int rd;
1546 uint32_t offset;
1547 TCGv_i32 tmp;
1549 rd = (insn >> 16) & 0xf;
1550 tmp = load_reg(s, rd);
1552 offset = (insn & 0xff) << ((insn >> 7) & 2);
1553 if (insn & (1 << 24)) {
1554 /* Pre indexed */
1555 if (insn & (1 << 23))
1556 tcg_gen_addi_i32(tmp, tmp, offset);
1557 else
1558 tcg_gen_addi_i32(tmp, tmp, -offset);
1559 tcg_gen_mov_i32(dest, tmp);
1560 if (insn & (1 << 21))
1561 store_reg(s, rd, tmp);
1562 else
1563 tcg_temp_free_i32(tmp);
1564 } else if (insn & (1 << 21)) {
1565 /* Post indexed */
1566 tcg_gen_mov_i32(dest, tmp);
1567 if (insn & (1 << 23))
1568 tcg_gen_addi_i32(tmp, tmp, offset);
1569 else
1570 tcg_gen_addi_i32(tmp, tmp, -offset);
1571 store_reg(s, rd, tmp);
1572 } else if (!(insn & (1 << 23)))
1573 return 1;
1574 return 0;
1577 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1579 int rd = (insn >> 0) & 0xf;
1580 TCGv_i32 tmp;
1582 if (insn & (1 << 8)) {
1583 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1584 return 1;
1585 } else {
1586 tmp = iwmmxt_load_creg(rd);
1588 } else {
1589 tmp = tcg_temp_new_i32();
1590 iwmmxt_load_reg(cpu_V0, rd);
1591 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1593 tcg_gen_andi_i32(tmp, tmp, mask);
1594 tcg_gen_mov_i32(dest, tmp);
1595 tcg_temp_free_i32(tmp);
1596 return 0;
1599 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1600 (ie. an undefined instruction). */
1601 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1603 int rd, wrd;
1604 int rdhi, rdlo, rd0, rd1, i;
1605 TCGv_i32 addr;
1606 TCGv_i32 tmp, tmp2, tmp3;
1608 if ((insn & 0x0e000e00) == 0x0c000000) {
1609 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1610 wrd = insn & 0xf;
1611 rdlo = (insn >> 12) & 0xf;
1612 rdhi = (insn >> 16) & 0xf;
1613 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1614 iwmmxt_load_reg(cpu_V0, wrd);
1615 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1616 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1617 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1618 } else { /* TMCRR */
1619 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1620 iwmmxt_store_reg(cpu_V0, wrd);
1621 gen_op_iwmmxt_set_mup();
1623 return 0;
1626 wrd = (insn >> 12) & 0xf;
1627 addr = tcg_temp_new_i32();
1628 if (gen_iwmmxt_address(s, insn, addr)) {
1629 tcg_temp_free_i32(addr);
1630 return 1;
1632 if (insn & ARM_CP_RW_BIT) {
1633 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1634 tmp = tcg_temp_new_i32();
1635 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1636 iwmmxt_store_creg(wrd, tmp);
1637 } else {
1638 i = 1;
1639 if (insn & (1 << 8)) {
1640 if (insn & (1 << 22)) { /* WLDRD */
1641 gen_aa32_ld64(cpu_M0, addr, get_mem_index(s));
1642 i = 0;
1643 } else { /* WLDRW wRd */
1644 tmp = tcg_temp_new_i32();
1645 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1647 } else {
1648 tmp = tcg_temp_new_i32();
1649 if (insn & (1 << 22)) { /* WLDRH */
1650 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
1651 } else { /* WLDRB */
1652 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
1655 if (i) {
1656 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1657 tcg_temp_free_i32(tmp);
1659 gen_op_iwmmxt_movq_wRn_M0(wrd);
1661 } else {
1662 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1663 tmp = iwmmxt_load_creg(wrd);
1664 gen_aa32_st32(tmp, addr, get_mem_index(s));
1665 } else {
1666 gen_op_iwmmxt_movq_M0_wRn(wrd);
1667 tmp = tcg_temp_new_i32();
1668 if (insn & (1 << 8)) {
1669 if (insn & (1 << 22)) { /* WSTRD */
1670 gen_aa32_st64(cpu_M0, addr, get_mem_index(s));
1671 } else { /* WSTRW wRd */
1672 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1673 gen_aa32_st32(tmp, addr, get_mem_index(s));
1675 } else {
1676 if (insn & (1 << 22)) { /* WSTRH */
1677 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1678 gen_aa32_st16(tmp, addr, get_mem_index(s));
1679 } else { /* WSTRB */
1680 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1681 gen_aa32_st8(tmp, addr, get_mem_index(s));
1685 tcg_temp_free_i32(tmp);
1687 tcg_temp_free_i32(addr);
1688 return 0;
1691 if ((insn & 0x0f000000) != 0x0e000000)
1692 return 1;
1694 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1695 case 0x000: /* WOR */
1696 wrd = (insn >> 12) & 0xf;
1697 rd0 = (insn >> 0) & 0xf;
1698 rd1 = (insn >> 16) & 0xf;
1699 gen_op_iwmmxt_movq_M0_wRn(rd0);
1700 gen_op_iwmmxt_orq_M0_wRn(rd1);
1701 gen_op_iwmmxt_setpsr_nz();
1702 gen_op_iwmmxt_movq_wRn_M0(wrd);
1703 gen_op_iwmmxt_set_mup();
1704 gen_op_iwmmxt_set_cup();
1705 break;
1706 case 0x011: /* TMCR */
1707 if (insn & 0xf)
1708 return 1;
1709 rd = (insn >> 12) & 0xf;
1710 wrd = (insn >> 16) & 0xf;
1711 switch (wrd) {
1712 case ARM_IWMMXT_wCID:
1713 case ARM_IWMMXT_wCASF:
1714 break;
1715 case ARM_IWMMXT_wCon:
1716 gen_op_iwmmxt_set_cup();
1717 /* Fall through. */
1718 case ARM_IWMMXT_wCSSF:
1719 tmp = iwmmxt_load_creg(wrd);
1720 tmp2 = load_reg(s, rd);
1721 tcg_gen_andc_i32(tmp, tmp, tmp2);
1722 tcg_temp_free_i32(tmp2);
1723 iwmmxt_store_creg(wrd, tmp);
1724 break;
1725 case ARM_IWMMXT_wCGR0:
1726 case ARM_IWMMXT_wCGR1:
1727 case ARM_IWMMXT_wCGR2:
1728 case ARM_IWMMXT_wCGR3:
1729 gen_op_iwmmxt_set_cup();
1730 tmp = load_reg(s, rd);
1731 iwmmxt_store_creg(wrd, tmp);
1732 break;
1733 default:
1734 return 1;
1736 break;
1737 case 0x100: /* WXOR */
1738 wrd = (insn >> 12) & 0xf;
1739 rd0 = (insn >> 0) & 0xf;
1740 rd1 = (insn >> 16) & 0xf;
1741 gen_op_iwmmxt_movq_M0_wRn(rd0);
1742 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1743 gen_op_iwmmxt_setpsr_nz();
1744 gen_op_iwmmxt_movq_wRn_M0(wrd);
1745 gen_op_iwmmxt_set_mup();
1746 gen_op_iwmmxt_set_cup();
1747 break;
1748 case 0x111: /* TMRC */
1749 if (insn & 0xf)
1750 return 1;
1751 rd = (insn >> 12) & 0xf;
1752 wrd = (insn >> 16) & 0xf;
1753 tmp = iwmmxt_load_creg(wrd);
1754 store_reg(s, rd, tmp);
1755 break;
1756 case 0x300: /* WANDN */
1757 wrd = (insn >> 12) & 0xf;
1758 rd0 = (insn >> 0) & 0xf;
1759 rd1 = (insn >> 16) & 0xf;
1760 gen_op_iwmmxt_movq_M0_wRn(rd0);
1761 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1762 gen_op_iwmmxt_andq_M0_wRn(rd1);
1763 gen_op_iwmmxt_setpsr_nz();
1764 gen_op_iwmmxt_movq_wRn_M0(wrd);
1765 gen_op_iwmmxt_set_mup();
1766 gen_op_iwmmxt_set_cup();
1767 break;
1768 case 0x200: /* WAND */
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_andq_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 0x810: case 0xa10: /* WMADD */
1780 wrd = (insn >> 12) & 0xf;
1781 rd0 = (insn >> 0) & 0xf;
1782 rd1 = (insn >> 16) & 0xf;
1783 gen_op_iwmmxt_movq_M0_wRn(rd0);
1784 if (insn & (1 << 21))
1785 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1786 else
1787 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1788 gen_op_iwmmxt_movq_wRn_M0(wrd);
1789 gen_op_iwmmxt_set_mup();
1790 break;
1791 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1792 wrd = (insn >> 12) & 0xf;
1793 rd0 = (insn >> 16) & 0xf;
1794 rd1 = (insn >> 0) & 0xf;
1795 gen_op_iwmmxt_movq_M0_wRn(rd0);
1796 switch ((insn >> 22) & 3) {
1797 case 0:
1798 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1799 break;
1800 case 1:
1801 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1802 break;
1803 case 2:
1804 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1805 break;
1806 case 3:
1807 return 1;
1809 gen_op_iwmmxt_movq_wRn_M0(wrd);
1810 gen_op_iwmmxt_set_mup();
1811 gen_op_iwmmxt_set_cup();
1812 break;
1813 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1814 wrd = (insn >> 12) & 0xf;
1815 rd0 = (insn >> 16) & 0xf;
1816 rd1 = (insn >> 0) & 0xf;
1817 gen_op_iwmmxt_movq_M0_wRn(rd0);
1818 switch ((insn >> 22) & 3) {
1819 case 0:
1820 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1821 break;
1822 case 1:
1823 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1824 break;
1825 case 2:
1826 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1827 break;
1828 case 3:
1829 return 1;
1831 gen_op_iwmmxt_movq_wRn_M0(wrd);
1832 gen_op_iwmmxt_set_mup();
1833 gen_op_iwmmxt_set_cup();
1834 break;
1835 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1836 wrd = (insn >> 12) & 0xf;
1837 rd0 = (insn >> 16) & 0xf;
1838 rd1 = (insn >> 0) & 0xf;
1839 gen_op_iwmmxt_movq_M0_wRn(rd0);
1840 if (insn & (1 << 22))
1841 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1842 else
1843 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1844 if (!(insn & (1 << 20)))
1845 gen_op_iwmmxt_addl_M0_wRn(wrd);
1846 gen_op_iwmmxt_movq_wRn_M0(wrd);
1847 gen_op_iwmmxt_set_mup();
1848 break;
1849 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1850 wrd = (insn >> 12) & 0xf;
1851 rd0 = (insn >> 16) & 0xf;
1852 rd1 = (insn >> 0) & 0xf;
1853 gen_op_iwmmxt_movq_M0_wRn(rd0);
1854 if (insn & (1 << 21)) {
1855 if (insn & (1 << 20))
1856 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1857 else
1858 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1859 } else {
1860 if (insn & (1 << 20))
1861 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1862 else
1863 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1865 gen_op_iwmmxt_movq_wRn_M0(wrd);
1866 gen_op_iwmmxt_set_mup();
1867 break;
1868 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1869 wrd = (insn >> 12) & 0xf;
1870 rd0 = (insn >> 16) & 0xf;
1871 rd1 = (insn >> 0) & 0xf;
1872 gen_op_iwmmxt_movq_M0_wRn(rd0);
1873 if (insn & (1 << 21))
1874 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1875 else
1876 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1877 if (!(insn & (1 << 20))) {
1878 iwmmxt_load_reg(cpu_V1, wrd);
1879 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1881 gen_op_iwmmxt_movq_wRn_M0(wrd);
1882 gen_op_iwmmxt_set_mup();
1883 break;
1884 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1885 wrd = (insn >> 12) & 0xf;
1886 rd0 = (insn >> 16) & 0xf;
1887 rd1 = (insn >> 0) & 0xf;
1888 gen_op_iwmmxt_movq_M0_wRn(rd0);
1889 switch ((insn >> 22) & 3) {
1890 case 0:
1891 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1892 break;
1893 case 1:
1894 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1895 break;
1896 case 2:
1897 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1898 break;
1899 case 3:
1900 return 1;
1902 gen_op_iwmmxt_movq_wRn_M0(wrd);
1903 gen_op_iwmmxt_set_mup();
1904 gen_op_iwmmxt_set_cup();
1905 break;
1906 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1907 wrd = (insn >> 12) & 0xf;
1908 rd0 = (insn >> 16) & 0xf;
1909 rd1 = (insn >> 0) & 0xf;
1910 gen_op_iwmmxt_movq_M0_wRn(rd0);
1911 if (insn & (1 << 22)) {
1912 if (insn & (1 << 20))
1913 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1914 else
1915 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1916 } else {
1917 if (insn & (1 << 20))
1918 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1919 else
1920 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1922 gen_op_iwmmxt_movq_wRn_M0(wrd);
1923 gen_op_iwmmxt_set_mup();
1924 gen_op_iwmmxt_set_cup();
1925 break;
1926 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1927 wrd = (insn >> 12) & 0xf;
1928 rd0 = (insn >> 16) & 0xf;
1929 rd1 = (insn >> 0) & 0xf;
1930 gen_op_iwmmxt_movq_M0_wRn(rd0);
1931 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1932 tcg_gen_andi_i32(tmp, tmp, 7);
1933 iwmmxt_load_reg(cpu_V1, rd1);
1934 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1935 tcg_temp_free_i32(tmp);
1936 gen_op_iwmmxt_movq_wRn_M0(wrd);
1937 gen_op_iwmmxt_set_mup();
1938 break;
1939 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1940 if (((insn >> 6) & 3) == 3)
1941 return 1;
1942 rd = (insn >> 12) & 0xf;
1943 wrd = (insn >> 16) & 0xf;
1944 tmp = load_reg(s, rd);
1945 gen_op_iwmmxt_movq_M0_wRn(wrd);
1946 switch ((insn >> 6) & 3) {
1947 case 0:
1948 tmp2 = tcg_const_i32(0xff);
1949 tmp3 = tcg_const_i32((insn & 7) << 3);
1950 break;
1951 case 1:
1952 tmp2 = tcg_const_i32(0xffff);
1953 tmp3 = tcg_const_i32((insn & 3) << 4);
1954 break;
1955 case 2:
1956 tmp2 = tcg_const_i32(0xffffffff);
1957 tmp3 = tcg_const_i32((insn & 1) << 5);
1958 break;
1959 default:
1960 TCGV_UNUSED_I32(tmp2);
1961 TCGV_UNUSED_I32(tmp3);
1963 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1964 tcg_temp_free_i32(tmp3);
1965 tcg_temp_free_i32(tmp2);
1966 tcg_temp_free_i32(tmp);
1967 gen_op_iwmmxt_movq_wRn_M0(wrd);
1968 gen_op_iwmmxt_set_mup();
1969 break;
1970 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1971 rd = (insn >> 12) & 0xf;
1972 wrd = (insn >> 16) & 0xf;
1973 if (rd == 15 || ((insn >> 22) & 3) == 3)
1974 return 1;
1975 gen_op_iwmmxt_movq_M0_wRn(wrd);
1976 tmp = tcg_temp_new_i32();
1977 switch ((insn >> 22) & 3) {
1978 case 0:
1979 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1980 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1981 if (insn & 8) {
1982 tcg_gen_ext8s_i32(tmp, tmp);
1983 } else {
1984 tcg_gen_andi_i32(tmp, tmp, 0xff);
1986 break;
1987 case 1:
1988 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1989 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1990 if (insn & 8) {
1991 tcg_gen_ext16s_i32(tmp, tmp);
1992 } else {
1993 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1995 break;
1996 case 2:
1997 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1998 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1999 break;
2001 store_reg(s, rd, tmp);
2002 break;
2003 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2004 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2005 return 1;
2006 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2007 switch ((insn >> 22) & 3) {
2008 case 0:
2009 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2010 break;
2011 case 1:
2012 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2013 break;
2014 case 2:
2015 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2016 break;
2018 tcg_gen_shli_i32(tmp, tmp, 28);
2019 gen_set_nzcv(tmp);
2020 tcg_temp_free_i32(tmp);
2021 break;
2022 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2023 if (((insn >> 6) & 3) == 3)
2024 return 1;
2025 rd = (insn >> 12) & 0xf;
2026 wrd = (insn >> 16) & 0xf;
2027 tmp = load_reg(s, rd);
2028 switch ((insn >> 6) & 3) {
2029 case 0:
2030 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2031 break;
2032 case 1:
2033 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2034 break;
2035 case 2:
2036 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2037 break;
2039 tcg_temp_free_i32(tmp);
2040 gen_op_iwmmxt_movq_wRn_M0(wrd);
2041 gen_op_iwmmxt_set_mup();
2042 break;
2043 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2044 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2045 return 1;
2046 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2047 tmp2 = tcg_temp_new_i32();
2048 tcg_gen_mov_i32(tmp2, tmp);
2049 switch ((insn >> 22) & 3) {
2050 case 0:
2051 for (i = 0; i < 7; i ++) {
2052 tcg_gen_shli_i32(tmp2, tmp2, 4);
2053 tcg_gen_and_i32(tmp, tmp, tmp2);
2055 break;
2056 case 1:
2057 for (i = 0; i < 3; i ++) {
2058 tcg_gen_shli_i32(tmp2, tmp2, 8);
2059 tcg_gen_and_i32(tmp, tmp, tmp2);
2061 break;
2062 case 2:
2063 tcg_gen_shli_i32(tmp2, tmp2, 16);
2064 tcg_gen_and_i32(tmp, tmp, tmp2);
2065 break;
2067 gen_set_nzcv(tmp);
2068 tcg_temp_free_i32(tmp2);
2069 tcg_temp_free_i32(tmp);
2070 break;
2071 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2072 wrd = (insn >> 12) & 0xf;
2073 rd0 = (insn >> 16) & 0xf;
2074 gen_op_iwmmxt_movq_M0_wRn(rd0);
2075 switch ((insn >> 22) & 3) {
2076 case 0:
2077 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2078 break;
2079 case 1:
2080 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2081 break;
2082 case 2:
2083 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2084 break;
2085 case 3:
2086 return 1;
2088 gen_op_iwmmxt_movq_wRn_M0(wrd);
2089 gen_op_iwmmxt_set_mup();
2090 break;
2091 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2092 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2093 return 1;
2094 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2095 tmp2 = tcg_temp_new_i32();
2096 tcg_gen_mov_i32(tmp2, tmp);
2097 switch ((insn >> 22) & 3) {
2098 case 0:
2099 for (i = 0; i < 7; i ++) {
2100 tcg_gen_shli_i32(tmp2, tmp2, 4);
2101 tcg_gen_or_i32(tmp, tmp, tmp2);
2103 break;
2104 case 1:
2105 for (i = 0; i < 3; i ++) {
2106 tcg_gen_shli_i32(tmp2, tmp2, 8);
2107 tcg_gen_or_i32(tmp, tmp, tmp2);
2109 break;
2110 case 2:
2111 tcg_gen_shli_i32(tmp2, tmp2, 16);
2112 tcg_gen_or_i32(tmp, tmp, tmp2);
2113 break;
2115 gen_set_nzcv(tmp);
2116 tcg_temp_free_i32(tmp2);
2117 tcg_temp_free_i32(tmp);
2118 break;
2119 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2120 rd = (insn >> 12) & 0xf;
2121 rd0 = (insn >> 16) & 0xf;
2122 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2123 return 1;
2124 gen_op_iwmmxt_movq_M0_wRn(rd0);
2125 tmp = tcg_temp_new_i32();
2126 switch ((insn >> 22) & 3) {
2127 case 0:
2128 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2129 break;
2130 case 1:
2131 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2132 break;
2133 case 2:
2134 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2135 break;
2137 store_reg(s, rd, tmp);
2138 break;
2139 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2140 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2141 wrd = (insn >> 12) & 0xf;
2142 rd0 = (insn >> 16) & 0xf;
2143 rd1 = (insn >> 0) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0);
2145 switch ((insn >> 22) & 3) {
2146 case 0:
2147 if (insn & (1 << 21))
2148 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2149 else
2150 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2151 break;
2152 case 1:
2153 if (insn & (1 << 21))
2154 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2155 else
2156 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2157 break;
2158 case 2:
2159 if (insn & (1 << 21))
2160 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2161 else
2162 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2163 break;
2164 case 3:
2165 return 1;
2167 gen_op_iwmmxt_movq_wRn_M0(wrd);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2170 break;
2171 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2172 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2173 wrd = (insn >> 12) & 0xf;
2174 rd0 = (insn >> 16) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0);
2176 switch ((insn >> 22) & 3) {
2177 case 0:
2178 if (insn & (1 << 21))
2179 gen_op_iwmmxt_unpacklsb_M0();
2180 else
2181 gen_op_iwmmxt_unpacklub_M0();
2182 break;
2183 case 1:
2184 if (insn & (1 << 21))
2185 gen_op_iwmmxt_unpacklsw_M0();
2186 else
2187 gen_op_iwmmxt_unpackluw_M0();
2188 break;
2189 case 2:
2190 if (insn & (1 << 21))
2191 gen_op_iwmmxt_unpacklsl_M0();
2192 else
2193 gen_op_iwmmxt_unpacklul_M0();
2194 break;
2195 case 3:
2196 return 1;
2198 gen_op_iwmmxt_movq_wRn_M0(wrd);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2201 break;
2202 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2203 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2204 wrd = (insn >> 12) & 0xf;
2205 rd0 = (insn >> 16) & 0xf;
2206 gen_op_iwmmxt_movq_M0_wRn(rd0);
2207 switch ((insn >> 22) & 3) {
2208 case 0:
2209 if (insn & (1 << 21))
2210 gen_op_iwmmxt_unpackhsb_M0();
2211 else
2212 gen_op_iwmmxt_unpackhub_M0();
2213 break;
2214 case 1:
2215 if (insn & (1 << 21))
2216 gen_op_iwmmxt_unpackhsw_M0();
2217 else
2218 gen_op_iwmmxt_unpackhuw_M0();
2219 break;
2220 case 2:
2221 if (insn & (1 << 21))
2222 gen_op_iwmmxt_unpackhsl_M0();
2223 else
2224 gen_op_iwmmxt_unpackhul_M0();
2225 break;
2226 case 3:
2227 return 1;
2229 gen_op_iwmmxt_movq_wRn_M0(wrd);
2230 gen_op_iwmmxt_set_mup();
2231 gen_op_iwmmxt_set_cup();
2232 break;
2233 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2234 case 0x214: case 0x614: case 0xa14: case 0xe14:
2235 if (((insn >> 22) & 3) == 0)
2236 return 1;
2237 wrd = (insn >> 12) & 0xf;
2238 rd0 = (insn >> 16) & 0xf;
2239 gen_op_iwmmxt_movq_M0_wRn(rd0);
2240 tmp = tcg_temp_new_i32();
2241 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2242 tcg_temp_free_i32(tmp);
2243 return 1;
2245 switch ((insn >> 22) & 3) {
2246 case 1:
2247 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2248 break;
2249 case 2:
2250 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2251 break;
2252 case 3:
2253 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2254 break;
2256 tcg_temp_free_i32(tmp);
2257 gen_op_iwmmxt_movq_wRn_M0(wrd);
2258 gen_op_iwmmxt_set_mup();
2259 gen_op_iwmmxt_set_cup();
2260 break;
2261 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2262 case 0x014: case 0x414: case 0x814: case 0xc14:
2263 if (((insn >> 22) & 3) == 0)
2264 return 1;
2265 wrd = (insn >> 12) & 0xf;
2266 rd0 = (insn >> 16) & 0xf;
2267 gen_op_iwmmxt_movq_M0_wRn(rd0);
2268 tmp = tcg_temp_new_i32();
2269 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2270 tcg_temp_free_i32(tmp);
2271 return 1;
2273 switch ((insn >> 22) & 3) {
2274 case 1:
2275 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2276 break;
2277 case 2:
2278 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2279 break;
2280 case 3:
2281 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2282 break;
2284 tcg_temp_free_i32(tmp);
2285 gen_op_iwmmxt_movq_wRn_M0(wrd);
2286 gen_op_iwmmxt_set_mup();
2287 gen_op_iwmmxt_set_cup();
2288 break;
2289 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2290 case 0x114: case 0x514: case 0x914: case 0xd14:
2291 if (((insn >> 22) & 3) == 0)
2292 return 1;
2293 wrd = (insn >> 12) & 0xf;
2294 rd0 = (insn >> 16) & 0xf;
2295 gen_op_iwmmxt_movq_M0_wRn(rd0);
2296 tmp = tcg_temp_new_i32();
2297 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2298 tcg_temp_free_i32(tmp);
2299 return 1;
2301 switch ((insn >> 22) & 3) {
2302 case 1:
2303 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2304 break;
2305 case 2:
2306 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2307 break;
2308 case 3:
2309 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2310 break;
2312 tcg_temp_free_i32(tmp);
2313 gen_op_iwmmxt_movq_wRn_M0(wrd);
2314 gen_op_iwmmxt_set_mup();
2315 gen_op_iwmmxt_set_cup();
2316 break;
2317 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2318 case 0x314: case 0x714: case 0xb14: case 0xf14:
2319 if (((insn >> 22) & 3) == 0)
2320 return 1;
2321 wrd = (insn >> 12) & 0xf;
2322 rd0 = (insn >> 16) & 0xf;
2323 gen_op_iwmmxt_movq_M0_wRn(rd0);
2324 tmp = tcg_temp_new_i32();
2325 switch ((insn >> 22) & 3) {
2326 case 1:
2327 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2328 tcg_temp_free_i32(tmp);
2329 return 1;
2331 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2332 break;
2333 case 2:
2334 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2335 tcg_temp_free_i32(tmp);
2336 return 1;
2338 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2339 break;
2340 case 3:
2341 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2342 tcg_temp_free_i32(tmp);
2343 return 1;
2345 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2346 break;
2348 tcg_temp_free_i32(tmp);
2349 gen_op_iwmmxt_movq_wRn_M0(wrd);
2350 gen_op_iwmmxt_set_mup();
2351 gen_op_iwmmxt_set_cup();
2352 break;
2353 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2354 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2355 wrd = (insn >> 12) & 0xf;
2356 rd0 = (insn >> 16) & 0xf;
2357 rd1 = (insn >> 0) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0);
2359 switch ((insn >> 22) & 3) {
2360 case 0:
2361 if (insn & (1 << 21))
2362 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2363 else
2364 gen_op_iwmmxt_minub_M0_wRn(rd1);
2365 break;
2366 case 1:
2367 if (insn & (1 << 21))
2368 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2369 else
2370 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2371 break;
2372 case 2:
2373 if (insn & (1 << 21))
2374 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2375 else
2376 gen_op_iwmmxt_minul_M0_wRn(rd1);
2377 break;
2378 case 3:
2379 return 1;
2381 gen_op_iwmmxt_movq_wRn_M0(wrd);
2382 gen_op_iwmmxt_set_mup();
2383 break;
2384 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2385 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2386 wrd = (insn >> 12) & 0xf;
2387 rd0 = (insn >> 16) & 0xf;
2388 rd1 = (insn >> 0) & 0xf;
2389 gen_op_iwmmxt_movq_M0_wRn(rd0);
2390 switch ((insn >> 22) & 3) {
2391 case 0:
2392 if (insn & (1 << 21))
2393 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2394 else
2395 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2396 break;
2397 case 1:
2398 if (insn & (1 << 21))
2399 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2400 else
2401 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2402 break;
2403 case 2:
2404 if (insn & (1 << 21))
2405 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2406 else
2407 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2408 break;
2409 case 3:
2410 return 1;
2412 gen_op_iwmmxt_movq_wRn_M0(wrd);
2413 gen_op_iwmmxt_set_mup();
2414 break;
2415 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2416 case 0x402: case 0x502: case 0x602: case 0x702:
2417 wrd = (insn >> 12) & 0xf;
2418 rd0 = (insn >> 16) & 0xf;
2419 rd1 = (insn >> 0) & 0xf;
2420 gen_op_iwmmxt_movq_M0_wRn(rd0);
2421 tmp = tcg_const_i32((insn >> 20) & 3);
2422 iwmmxt_load_reg(cpu_V1, rd1);
2423 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2424 tcg_temp_free_i32(tmp);
2425 gen_op_iwmmxt_movq_wRn_M0(wrd);
2426 gen_op_iwmmxt_set_mup();
2427 break;
2428 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2429 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2430 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2431 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2432 wrd = (insn >> 12) & 0xf;
2433 rd0 = (insn >> 16) & 0xf;
2434 rd1 = (insn >> 0) & 0xf;
2435 gen_op_iwmmxt_movq_M0_wRn(rd0);
2436 switch ((insn >> 20) & 0xf) {
2437 case 0x0:
2438 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2439 break;
2440 case 0x1:
2441 gen_op_iwmmxt_subub_M0_wRn(rd1);
2442 break;
2443 case 0x3:
2444 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2445 break;
2446 case 0x4:
2447 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2448 break;
2449 case 0x5:
2450 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2451 break;
2452 case 0x7:
2453 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2454 break;
2455 case 0x8:
2456 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2457 break;
2458 case 0x9:
2459 gen_op_iwmmxt_subul_M0_wRn(rd1);
2460 break;
2461 case 0xb:
2462 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2463 break;
2464 default:
2465 return 1;
2467 gen_op_iwmmxt_movq_wRn_M0(wrd);
2468 gen_op_iwmmxt_set_mup();
2469 gen_op_iwmmxt_set_cup();
2470 break;
2471 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2472 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2473 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2474 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2475 wrd = (insn >> 12) & 0xf;
2476 rd0 = (insn >> 16) & 0xf;
2477 gen_op_iwmmxt_movq_M0_wRn(rd0);
2478 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2479 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2480 tcg_temp_free_i32(tmp);
2481 gen_op_iwmmxt_movq_wRn_M0(wrd);
2482 gen_op_iwmmxt_set_mup();
2483 gen_op_iwmmxt_set_cup();
2484 break;
2485 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2486 case 0x418: case 0x518: case 0x618: case 0x718:
2487 case 0x818: case 0x918: case 0xa18: case 0xb18:
2488 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2489 wrd = (insn >> 12) & 0xf;
2490 rd0 = (insn >> 16) & 0xf;
2491 rd1 = (insn >> 0) & 0xf;
2492 gen_op_iwmmxt_movq_M0_wRn(rd0);
2493 switch ((insn >> 20) & 0xf) {
2494 case 0x0:
2495 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2496 break;
2497 case 0x1:
2498 gen_op_iwmmxt_addub_M0_wRn(rd1);
2499 break;
2500 case 0x3:
2501 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2502 break;
2503 case 0x4:
2504 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2505 break;
2506 case 0x5:
2507 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2508 break;
2509 case 0x7:
2510 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2511 break;
2512 case 0x8:
2513 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2514 break;
2515 case 0x9:
2516 gen_op_iwmmxt_addul_M0_wRn(rd1);
2517 break;
2518 case 0xb:
2519 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2520 break;
2521 default:
2522 return 1;
2524 gen_op_iwmmxt_movq_wRn_M0(wrd);
2525 gen_op_iwmmxt_set_mup();
2526 gen_op_iwmmxt_set_cup();
2527 break;
2528 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2529 case 0x408: case 0x508: case 0x608: case 0x708:
2530 case 0x808: case 0x908: case 0xa08: case 0xb08:
2531 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2532 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2533 return 1;
2534 wrd = (insn >> 12) & 0xf;
2535 rd0 = (insn >> 16) & 0xf;
2536 rd1 = (insn >> 0) & 0xf;
2537 gen_op_iwmmxt_movq_M0_wRn(rd0);
2538 switch ((insn >> 22) & 3) {
2539 case 1:
2540 if (insn & (1 << 21))
2541 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2542 else
2543 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2544 break;
2545 case 2:
2546 if (insn & (1 << 21))
2547 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2548 else
2549 gen_op_iwmmxt_packul_M0_wRn(rd1);
2550 break;
2551 case 3:
2552 if (insn & (1 << 21))
2553 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2554 else
2555 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2556 break;
2558 gen_op_iwmmxt_movq_wRn_M0(wrd);
2559 gen_op_iwmmxt_set_mup();
2560 gen_op_iwmmxt_set_cup();
2561 break;
2562 case 0x201: case 0x203: case 0x205: case 0x207:
2563 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2564 case 0x211: case 0x213: case 0x215: case 0x217:
2565 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2566 wrd = (insn >> 5) & 0xf;
2567 rd0 = (insn >> 12) & 0xf;
2568 rd1 = (insn >> 0) & 0xf;
2569 if (rd0 == 0xf || rd1 == 0xf)
2570 return 1;
2571 gen_op_iwmmxt_movq_M0_wRn(wrd);
2572 tmp = load_reg(s, rd0);
2573 tmp2 = load_reg(s, rd1);
2574 switch ((insn >> 16) & 0xf) {
2575 case 0x0: /* TMIA */
2576 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2577 break;
2578 case 0x8: /* TMIAPH */
2579 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2580 break;
2581 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2582 if (insn & (1 << 16))
2583 tcg_gen_shri_i32(tmp, tmp, 16);
2584 if (insn & (1 << 17))
2585 tcg_gen_shri_i32(tmp2, tmp2, 16);
2586 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2587 break;
2588 default:
2589 tcg_temp_free_i32(tmp2);
2590 tcg_temp_free_i32(tmp);
2591 return 1;
2593 tcg_temp_free_i32(tmp2);
2594 tcg_temp_free_i32(tmp);
2595 gen_op_iwmmxt_movq_wRn_M0(wrd);
2596 gen_op_iwmmxt_set_mup();
2597 break;
2598 default:
2599 return 1;
2602 return 0;
2605 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2606 (ie. an undefined instruction). */
2607 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2609 int acc, rd0, rd1, rdhi, rdlo;
2610 TCGv_i32 tmp, tmp2;
2612 if ((insn & 0x0ff00f10) == 0x0e200010) {
2613 /* Multiply with Internal Accumulate Format */
2614 rd0 = (insn >> 12) & 0xf;
2615 rd1 = insn & 0xf;
2616 acc = (insn >> 5) & 7;
2618 if (acc != 0)
2619 return 1;
2621 tmp = load_reg(s, rd0);
2622 tmp2 = load_reg(s, rd1);
2623 switch ((insn >> 16) & 0xf) {
2624 case 0x0: /* MIA */
2625 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2626 break;
2627 case 0x8: /* MIAPH */
2628 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2629 break;
2630 case 0xc: /* MIABB */
2631 case 0xd: /* MIABT */
2632 case 0xe: /* MIATB */
2633 case 0xf: /* MIATT */
2634 if (insn & (1 << 16))
2635 tcg_gen_shri_i32(tmp, tmp, 16);
2636 if (insn & (1 << 17))
2637 tcg_gen_shri_i32(tmp2, tmp2, 16);
2638 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2639 break;
2640 default:
2641 return 1;
2643 tcg_temp_free_i32(tmp2);
2644 tcg_temp_free_i32(tmp);
2646 gen_op_iwmmxt_movq_wRn_M0(acc);
2647 return 0;
2650 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2651 /* Internal Accumulator Access Format */
2652 rdhi = (insn >> 16) & 0xf;
2653 rdlo = (insn >> 12) & 0xf;
2654 acc = insn & 7;
2656 if (acc != 0)
2657 return 1;
2659 if (insn & ARM_CP_RW_BIT) { /* MRA */
2660 iwmmxt_load_reg(cpu_V0, acc);
2661 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2662 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2663 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2664 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2665 } else { /* MAR */
2666 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2667 iwmmxt_store_reg(cpu_V0, acc);
2669 return 0;
2672 return 1;
2675 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2676 #define VFP_SREG(insn, bigbit, smallbit) \
2677 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2678 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2679 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2680 reg = (((insn) >> (bigbit)) & 0x0f) \
2681 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2682 } else { \
2683 if (insn & (1 << (smallbit))) \
2684 return 1; \
2685 reg = ((insn) >> (bigbit)) & 0x0f; \
2686 }} while (0)
2688 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2689 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2690 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2691 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2692 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2693 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2695 /* Move between integer and VFP cores. */
2696 static TCGv_i32 gen_vfp_mrs(void)
2698 TCGv_i32 tmp = tcg_temp_new_i32();
2699 tcg_gen_mov_i32(tmp, cpu_F0s);
2700 return tmp;
2703 static void gen_vfp_msr(TCGv_i32 tmp)
2705 tcg_gen_mov_i32(cpu_F0s, tmp);
2706 tcg_temp_free_i32(tmp);
2709 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2711 TCGv_i32 tmp = tcg_temp_new_i32();
2712 if (shift)
2713 tcg_gen_shri_i32(var, var, shift);
2714 tcg_gen_ext8u_i32(var, var);
2715 tcg_gen_shli_i32(tmp, var, 8);
2716 tcg_gen_or_i32(var, var, tmp);
2717 tcg_gen_shli_i32(tmp, var, 16);
2718 tcg_gen_or_i32(var, var, tmp);
2719 tcg_temp_free_i32(tmp);
2722 static void gen_neon_dup_low16(TCGv_i32 var)
2724 TCGv_i32 tmp = tcg_temp_new_i32();
2725 tcg_gen_ext16u_i32(var, var);
2726 tcg_gen_shli_i32(tmp, var, 16);
2727 tcg_gen_or_i32(var, var, tmp);
2728 tcg_temp_free_i32(tmp);
2731 static void gen_neon_dup_high16(TCGv_i32 var)
2733 TCGv_i32 tmp = tcg_temp_new_i32();
2734 tcg_gen_andi_i32(var, var, 0xffff0000);
2735 tcg_gen_shri_i32(tmp, var, 16);
2736 tcg_gen_or_i32(var, var, tmp);
2737 tcg_temp_free_i32(tmp);
2740 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2742 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2743 TCGv_i32 tmp = tcg_temp_new_i32();
2744 switch (size) {
2745 case 0:
2746 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
2747 gen_neon_dup_u8(tmp, 0);
2748 break;
2749 case 1:
2750 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
2751 gen_neon_dup_low16(tmp);
2752 break;
2753 case 2:
2754 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
2755 break;
2756 default: /* Avoid compiler warnings. */
2757 abort();
2759 return tmp;
2762 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2763 uint32_t dp)
2765 uint32_t cc = extract32(insn, 20, 2);
2767 if (dp) {
2768 TCGv_i64 frn, frm, dest;
2769 TCGv_i64 tmp, zero, zf, nf, vf;
2771 zero = tcg_const_i64(0);
2773 frn = tcg_temp_new_i64();
2774 frm = tcg_temp_new_i64();
2775 dest = tcg_temp_new_i64();
2777 zf = tcg_temp_new_i64();
2778 nf = tcg_temp_new_i64();
2779 vf = tcg_temp_new_i64();
2781 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2782 tcg_gen_ext_i32_i64(nf, cpu_NF);
2783 tcg_gen_ext_i32_i64(vf, cpu_VF);
2785 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2786 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2787 switch (cc) {
2788 case 0: /* eq: Z */
2789 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2790 frn, frm);
2791 break;
2792 case 1: /* vs: V */
2793 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2794 frn, frm);
2795 break;
2796 case 2: /* ge: N == V -> N ^ V == 0 */
2797 tmp = tcg_temp_new_i64();
2798 tcg_gen_xor_i64(tmp, vf, nf);
2799 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2800 frn, frm);
2801 tcg_temp_free_i64(tmp);
2802 break;
2803 case 3: /* gt: !Z && N == V */
2804 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2805 frn, frm);
2806 tmp = tcg_temp_new_i64();
2807 tcg_gen_xor_i64(tmp, vf, nf);
2808 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2809 dest, frm);
2810 tcg_temp_free_i64(tmp);
2811 break;
2813 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2814 tcg_temp_free_i64(frn);
2815 tcg_temp_free_i64(frm);
2816 tcg_temp_free_i64(dest);
2818 tcg_temp_free_i64(zf);
2819 tcg_temp_free_i64(nf);
2820 tcg_temp_free_i64(vf);
2822 tcg_temp_free_i64(zero);
2823 } else {
2824 TCGv_i32 frn, frm, dest;
2825 TCGv_i32 tmp, zero;
2827 zero = tcg_const_i32(0);
2829 frn = tcg_temp_new_i32();
2830 frm = tcg_temp_new_i32();
2831 dest = tcg_temp_new_i32();
2832 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2833 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2834 switch (cc) {
2835 case 0: /* eq: Z */
2836 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2837 frn, frm);
2838 break;
2839 case 1: /* vs: V */
2840 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2841 frn, frm);
2842 break;
2843 case 2: /* ge: N == V -> N ^ V == 0 */
2844 tmp = tcg_temp_new_i32();
2845 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2846 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2847 frn, frm);
2848 tcg_temp_free_i32(tmp);
2849 break;
2850 case 3: /* gt: !Z && N == V */
2851 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2852 frn, frm);
2853 tmp = tcg_temp_new_i32();
2854 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2855 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2856 dest, frm);
2857 tcg_temp_free_i32(tmp);
2858 break;
2860 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2861 tcg_temp_free_i32(frn);
2862 tcg_temp_free_i32(frm);
2863 tcg_temp_free_i32(dest);
2865 tcg_temp_free_i32(zero);
2868 return 0;
2871 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2872 uint32_t rm, uint32_t dp)
2874 uint32_t vmin = extract32(insn, 6, 1);
2875 TCGv_ptr fpst = get_fpstatus_ptr(0);
2877 if (dp) {
2878 TCGv_i64 frn, frm, dest;
2880 frn = tcg_temp_new_i64();
2881 frm = tcg_temp_new_i64();
2882 dest = tcg_temp_new_i64();
2884 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2885 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2886 if (vmin) {
2887 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2888 } else {
2889 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2891 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2892 tcg_temp_free_i64(frn);
2893 tcg_temp_free_i64(frm);
2894 tcg_temp_free_i64(dest);
2895 } else {
2896 TCGv_i32 frn, frm, dest;
2898 frn = tcg_temp_new_i32();
2899 frm = tcg_temp_new_i32();
2900 dest = tcg_temp_new_i32();
2902 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2903 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2904 if (vmin) {
2905 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2906 } else {
2907 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2909 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2910 tcg_temp_free_i32(frn);
2911 tcg_temp_free_i32(frm);
2912 tcg_temp_free_i32(dest);
2915 tcg_temp_free_ptr(fpst);
2916 return 0;
2919 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2920 int rounding)
2922 TCGv_ptr fpst = get_fpstatus_ptr(0);
2923 TCGv_i32 tcg_rmode;
2925 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2926 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2928 if (dp) {
2929 TCGv_i64 tcg_op;
2930 TCGv_i64 tcg_res;
2931 tcg_op = tcg_temp_new_i64();
2932 tcg_res = tcg_temp_new_i64();
2933 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2934 gen_helper_rintd(tcg_res, tcg_op, fpst);
2935 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2936 tcg_temp_free_i64(tcg_op);
2937 tcg_temp_free_i64(tcg_res);
2938 } else {
2939 TCGv_i32 tcg_op;
2940 TCGv_i32 tcg_res;
2941 tcg_op = tcg_temp_new_i32();
2942 tcg_res = tcg_temp_new_i32();
2943 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2944 gen_helper_rints(tcg_res, tcg_op, fpst);
2945 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2946 tcg_temp_free_i32(tcg_op);
2947 tcg_temp_free_i32(tcg_res);
2950 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2951 tcg_temp_free_i32(tcg_rmode);
2953 tcg_temp_free_ptr(fpst);
2954 return 0;
2957 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2958 int rounding)
2960 bool is_signed = extract32(insn, 7, 1);
2961 TCGv_ptr fpst = get_fpstatus_ptr(0);
2962 TCGv_i32 tcg_rmode, tcg_shift;
2964 tcg_shift = tcg_const_i32(0);
2966 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2967 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2969 if (dp) {
2970 TCGv_i64 tcg_double, tcg_res;
2971 TCGv_i32 tcg_tmp;
2972 /* Rd is encoded as a single precision register even when the source
2973 * is double precision.
2975 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2976 tcg_double = tcg_temp_new_i64();
2977 tcg_res = tcg_temp_new_i64();
2978 tcg_tmp = tcg_temp_new_i32();
2979 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2980 if (is_signed) {
2981 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2982 } else {
2983 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2985 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
2986 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2987 tcg_temp_free_i32(tcg_tmp);
2988 tcg_temp_free_i64(tcg_res);
2989 tcg_temp_free_i64(tcg_double);
2990 } else {
2991 TCGv_i32 tcg_single, tcg_res;
2992 tcg_single = tcg_temp_new_i32();
2993 tcg_res = tcg_temp_new_i32();
2994 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2995 if (is_signed) {
2996 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2997 } else {
2998 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3000 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3001 tcg_temp_free_i32(tcg_res);
3002 tcg_temp_free_i32(tcg_single);
3005 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3006 tcg_temp_free_i32(tcg_rmode);
3008 tcg_temp_free_i32(tcg_shift);
3010 tcg_temp_free_ptr(fpst);
3012 return 0;
3015 /* Table for converting the most common AArch32 encoding of
3016 * rounding mode to arm_fprounding order (which matches the
3017 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3019 static const uint8_t fp_decode_rm[] = {
3020 FPROUNDING_TIEAWAY,
3021 FPROUNDING_TIEEVEN,
3022 FPROUNDING_POSINF,
3023 FPROUNDING_NEGINF,
3026 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3028 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3030 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3031 return 1;
3034 if (dp) {
3035 VFP_DREG_D(rd, insn);
3036 VFP_DREG_N(rn, insn);
3037 VFP_DREG_M(rm, insn);
3038 } else {
3039 rd = VFP_SREG_D(insn);
3040 rn = VFP_SREG_N(insn);
3041 rm = VFP_SREG_M(insn);
3044 if ((insn & 0x0f800e50) == 0x0e000a00) {
3045 return handle_vsel(insn, rd, rn, rm, dp);
3046 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3047 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3048 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3049 /* VRINTA, VRINTN, VRINTP, VRINTM */
3050 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3051 return handle_vrint(insn, rd, rm, dp, rounding);
3052 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3053 /* VCVTA, VCVTN, VCVTP, VCVTM */
3054 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3055 return handle_vcvt(insn, rd, rm, dp, rounding);
3057 return 1;
3060 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3061 (ie. an undefined instruction). */
3062 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3064 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3065 int dp, veclen;
3066 TCGv_i32 addr;
3067 TCGv_i32 tmp;
3068 TCGv_i32 tmp2;
3070 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3071 return 1;
3074 /* FIXME: this access check should not take precedence over UNDEF
3075 * for invalid encodings; we will generate incorrect syndrome information
3076 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3078 if (s->fp_excp_el) {
3079 gen_exception_insn(s, 4, EXCP_UDEF,
3080 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
3081 return 0;
3084 if (!s->vfp_enabled) {
3085 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3086 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3087 return 1;
3088 rn = (insn >> 16) & 0xf;
3089 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3090 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3091 return 1;
3095 if (extract32(insn, 28, 4) == 0xf) {
3096 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3097 * only used in v8 and above.
3099 return disas_vfp_v8_insn(s, insn);
3102 dp = ((insn & 0xf00) == 0xb00);
3103 switch ((insn >> 24) & 0xf) {
3104 case 0xe:
3105 if (insn & (1 << 4)) {
3106 /* single register transfer */
3107 rd = (insn >> 12) & 0xf;
3108 if (dp) {
3109 int size;
3110 int pass;
3112 VFP_DREG_N(rn, insn);
3113 if (insn & 0xf)
3114 return 1;
3115 if (insn & 0x00c00060
3116 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3117 return 1;
3120 pass = (insn >> 21) & 1;
3121 if (insn & (1 << 22)) {
3122 size = 0;
3123 offset = ((insn >> 5) & 3) * 8;
3124 } else if (insn & (1 << 5)) {
3125 size = 1;
3126 offset = (insn & (1 << 6)) ? 16 : 0;
3127 } else {
3128 size = 2;
3129 offset = 0;
3131 if (insn & ARM_CP_RW_BIT) {
3132 /* vfp->arm */
3133 tmp = neon_load_reg(rn, pass);
3134 switch (size) {
3135 case 0:
3136 if (offset)
3137 tcg_gen_shri_i32(tmp, tmp, offset);
3138 if (insn & (1 << 23))
3139 gen_uxtb(tmp);
3140 else
3141 gen_sxtb(tmp);
3142 break;
3143 case 1:
3144 if (insn & (1 << 23)) {
3145 if (offset) {
3146 tcg_gen_shri_i32(tmp, tmp, 16);
3147 } else {
3148 gen_uxth(tmp);
3150 } else {
3151 if (offset) {
3152 tcg_gen_sari_i32(tmp, tmp, 16);
3153 } else {
3154 gen_sxth(tmp);
3157 break;
3158 case 2:
3159 break;
3161 store_reg(s, rd, tmp);
3162 } else {
3163 /* arm->vfp */
3164 tmp = load_reg(s, rd);
3165 if (insn & (1 << 23)) {
3166 /* VDUP */
3167 if (size == 0) {
3168 gen_neon_dup_u8(tmp, 0);
3169 } else if (size == 1) {
3170 gen_neon_dup_low16(tmp);
3172 for (n = 0; n <= pass * 2; n++) {
3173 tmp2 = tcg_temp_new_i32();
3174 tcg_gen_mov_i32(tmp2, tmp);
3175 neon_store_reg(rn, n, tmp2);
3177 neon_store_reg(rn, n, tmp);
3178 } else {
3179 /* VMOV */
3180 switch (size) {
3181 case 0:
3182 tmp2 = neon_load_reg(rn, pass);
3183 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3184 tcg_temp_free_i32(tmp2);
3185 break;
3186 case 1:
3187 tmp2 = neon_load_reg(rn, pass);
3188 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3189 tcg_temp_free_i32(tmp2);
3190 break;
3191 case 2:
3192 break;
3194 neon_store_reg(rn, pass, tmp);
3197 } else { /* !dp */
3198 if ((insn & 0x6f) != 0x00)
3199 return 1;
3200 rn = VFP_SREG_N(insn);
3201 if (insn & ARM_CP_RW_BIT) {
3202 /* vfp->arm */
3203 if (insn & (1 << 21)) {
3204 /* system register */
3205 rn >>= 1;
3207 switch (rn) {
3208 case ARM_VFP_FPSID:
3209 /* VFP2 allows access to FSID from userspace.
3210 VFP3 restricts all id registers to privileged
3211 accesses. */
3212 if (IS_USER(s)
3213 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3214 return 1;
3216 tmp = load_cpu_field(vfp.xregs[rn]);
3217 break;
3218 case ARM_VFP_FPEXC:
3219 if (IS_USER(s))
3220 return 1;
3221 tmp = load_cpu_field(vfp.xregs[rn]);
3222 break;
3223 case ARM_VFP_FPINST:
3224 case ARM_VFP_FPINST2:
3225 /* Not present in VFP3. */
3226 if (IS_USER(s)
3227 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3228 return 1;
3230 tmp = load_cpu_field(vfp.xregs[rn]);
3231 break;
3232 case ARM_VFP_FPSCR:
3233 if (rd == 15) {
3234 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3235 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3236 } else {
3237 tmp = tcg_temp_new_i32();
3238 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3240 break;
3241 case ARM_VFP_MVFR2:
3242 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3243 return 1;
3245 /* fall through */
3246 case ARM_VFP_MVFR0:
3247 case ARM_VFP_MVFR1:
3248 if (IS_USER(s)
3249 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3250 return 1;
3252 tmp = load_cpu_field(vfp.xregs[rn]);
3253 break;
3254 default:
3255 return 1;
3257 } else {
3258 gen_mov_F0_vreg(0, rn);
3259 tmp = gen_vfp_mrs();
3261 if (rd == 15) {
3262 /* Set the 4 flag bits in the CPSR. */
3263 gen_set_nzcv(tmp);
3264 tcg_temp_free_i32(tmp);
3265 } else {
3266 store_reg(s, rd, tmp);
3268 } else {
3269 /* arm->vfp */
3270 if (insn & (1 << 21)) {
3271 rn >>= 1;
3272 /* system register */
3273 switch (rn) {
3274 case ARM_VFP_FPSID:
3275 case ARM_VFP_MVFR0:
3276 case ARM_VFP_MVFR1:
3277 /* Writes are ignored. */
3278 break;
3279 case ARM_VFP_FPSCR:
3280 tmp = load_reg(s, rd);
3281 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3282 tcg_temp_free_i32(tmp);
3283 gen_lookup_tb(s);
3284 break;
3285 case ARM_VFP_FPEXC:
3286 if (IS_USER(s))
3287 return 1;
3288 /* TODO: VFP subarchitecture support.
3289 * For now, keep the EN bit only */
3290 tmp = load_reg(s, rd);
3291 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3292 store_cpu_field(tmp, vfp.xregs[rn]);
3293 gen_lookup_tb(s);
3294 break;
3295 case ARM_VFP_FPINST:
3296 case ARM_VFP_FPINST2:
3297 if (IS_USER(s)) {
3298 return 1;
3300 tmp = load_reg(s, rd);
3301 store_cpu_field(tmp, vfp.xregs[rn]);
3302 break;
3303 default:
3304 return 1;
3306 } else {
3307 tmp = load_reg(s, rd);
3308 gen_vfp_msr(tmp);
3309 gen_mov_vreg_F0(0, rn);
3313 } else {
3314 /* data processing */
3315 /* The opcode is in bits 23, 21, 20 and 6. */
3316 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3317 if (dp) {
3318 if (op == 15) {
3319 /* rn is opcode */
3320 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3321 } else {
3322 /* rn is register number */
3323 VFP_DREG_N(rn, insn);
3326 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3327 ((rn & 0x1e) == 0x6))) {
3328 /* Integer or single/half precision destination. */
3329 rd = VFP_SREG_D(insn);
3330 } else {
3331 VFP_DREG_D(rd, insn);
3333 if (op == 15 &&
3334 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3335 ((rn & 0x1e) == 0x4))) {
3336 /* VCVT from int or half precision is always from S reg
3337 * regardless of dp bit. VCVT with immediate frac_bits
3338 * has same format as SREG_M.
3340 rm = VFP_SREG_M(insn);
3341 } else {
3342 VFP_DREG_M(rm, insn);
3344 } else {
3345 rn = VFP_SREG_N(insn);
3346 if (op == 15 && rn == 15) {
3347 /* Double precision destination. */
3348 VFP_DREG_D(rd, insn);
3349 } else {
3350 rd = VFP_SREG_D(insn);
3352 /* NB that we implicitly rely on the encoding for the frac_bits
3353 * in VCVT of fixed to float being the same as that of an SREG_M
3355 rm = VFP_SREG_M(insn);
3358 veclen = s->vec_len;
3359 if (op == 15 && rn > 3)
3360 veclen = 0;
3362 /* Shut up compiler warnings. */
3363 delta_m = 0;
3364 delta_d = 0;
3365 bank_mask = 0;
3367 if (veclen > 0) {
3368 if (dp)
3369 bank_mask = 0xc;
3370 else
3371 bank_mask = 0x18;
3373 /* Figure out what type of vector operation this is. */
3374 if ((rd & bank_mask) == 0) {
3375 /* scalar */
3376 veclen = 0;
3377 } else {
3378 if (dp)
3379 delta_d = (s->vec_stride >> 1) + 1;
3380 else
3381 delta_d = s->vec_stride + 1;
3383 if ((rm & bank_mask) == 0) {
3384 /* mixed scalar/vector */
3385 delta_m = 0;
3386 } else {
3387 /* vector */
3388 delta_m = delta_d;
3393 /* Load the initial operands. */
3394 if (op == 15) {
3395 switch (rn) {
3396 case 16:
3397 case 17:
3398 /* Integer source */
3399 gen_mov_F0_vreg(0, rm);
3400 break;
3401 case 8:
3402 case 9:
3403 /* Compare */
3404 gen_mov_F0_vreg(dp, rd);
3405 gen_mov_F1_vreg(dp, rm);
3406 break;
3407 case 10:
3408 case 11:
3409 /* Compare with zero */
3410 gen_mov_F0_vreg(dp, rd);
3411 gen_vfp_F1_ld0(dp);
3412 break;
3413 case 20:
3414 case 21:
3415 case 22:
3416 case 23:
3417 case 28:
3418 case 29:
3419 case 30:
3420 case 31:
3421 /* Source and destination the same. */
3422 gen_mov_F0_vreg(dp, rd);
3423 break;
3424 case 4:
3425 case 5:
3426 case 6:
3427 case 7:
3428 /* VCVTB, VCVTT: only present with the halfprec extension
3429 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3430 * (we choose to UNDEF)
3432 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3433 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3434 return 1;
3436 if (!extract32(rn, 1, 1)) {
3437 /* Half precision source. */
3438 gen_mov_F0_vreg(0, rm);
3439 break;
3441 /* Otherwise fall through */
3442 default:
3443 /* One source operand. */
3444 gen_mov_F0_vreg(dp, rm);
3445 break;
3447 } else {
3448 /* Two source operands. */
3449 gen_mov_F0_vreg(dp, rn);
3450 gen_mov_F1_vreg(dp, rm);
3453 for (;;) {
3454 /* Perform the calculation. */
3455 switch (op) {
3456 case 0: /* VMLA: fd + (fn * fm) */
3457 /* Note that order of inputs to the add matters for NaNs */
3458 gen_vfp_F1_mul(dp);
3459 gen_mov_F0_vreg(dp, rd);
3460 gen_vfp_add(dp);
3461 break;
3462 case 1: /* VMLS: fd + -(fn * fm) */
3463 gen_vfp_mul(dp);
3464 gen_vfp_F1_neg(dp);
3465 gen_mov_F0_vreg(dp, rd);
3466 gen_vfp_add(dp);
3467 break;
3468 case 2: /* VNMLS: -fd + (fn * fm) */
3469 /* Note that it isn't valid to replace (-A + B) with (B - A)
3470 * or similar plausible looking simplifications
3471 * because this will give wrong results for NaNs.
3473 gen_vfp_F1_mul(dp);
3474 gen_mov_F0_vreg(dp, rd);
3475 gen_vfp_neg(dp);
3476 gen_vfp_add(dp);
3477 break;
3478 case 3: /* VNMLA: -fd + -(fn * fm) */
3479 gen_vfp_mul(dp);
3480 gen_vfp_F1_neg(dp);
3481 gen_mov_F0_vreg(dp, rd);
3482 gen_vfp_neg(dp);
3483 gen_vfp_add(dp);
3484 break;
3485 case 4: /* mul: fn * fm */
3486 gen_vfp_mul(dp);
3487 break;
3488 case 5: /* nmul: -(fn * fm) */
3489 gen_vfp_mul(dp);
3490 gen_vfp_neg(dp);
3491 break;
3492 case 6: /* add: fn + fm */
3493 gen_vfp_add(dp);
3494 break;
3495 case 7: /* sub: fn - fm */
3496 gen_vfp_sub(dp);
3497 break;
3498 case 8: /* div: fn / fm */
3499 gen_vfp_div(dp);
3500 break;
3501 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3502 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3503 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3504 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3505 /* These are fused multiply-add, and must be done as one
3506 * floating point operation with no rounding between the
3507 * multiplication and addition steps.
3508 * NB that doing the negations here as separate steps is
3509 * correct : an input NaN should come out with its sign bit
3510 * flipped if it is a negated-input.
3512 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3513 return 1;
3515 if (dp) {
3516 TCGv_ptr fpst;
3517 TCGv_i64 frd;
3518 if (op & 1) {
3519 /* VFNMS, VFMS */
3520 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3522 frd = tcg_temp_new_i64();
3523 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3524 if (op & 2) {
3525 /* VFNMA, VFNMS */
3526 gen_helper_vfp_negd(frd, frd);
3528 fpst = get_fpstatus_ptr(0);
3529 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3530 cpu_F1d, frd, fpst);
3531 tcg_temp_free_ptr(fpst);
3532 tcg_temp_free_i64(frd);
3533 } else {
3534 TCGv_ptr fpst;
3535 TCGv_i32 frd;
3536 if (op & 1) {
3537 /* VFNMS, VFMS */
3538 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3540 frd = tcg_temp_new_i32();
3541 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3542 if (op & 2) {
3543 gen_helper_vfp_negs(frd, frd);
3545 fpst = get_fpstatus_ptr(0);
3546 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3547 cpu_F1s, frd, fpst);
3548 tcg_temp_free_ptr(fpst);
3549 tcg_temp_free_i32(frd);
3551 break;
3552 case 14: /* fconst */
3553 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3554 return 1;
3557 n = (insn << 12) & 0x80000000;
3558 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3559 if (dp) {
3560 if (i & 0x40)
3561 i |= 0x3f80;
3562 else
3563 i |= 0x4000;
3564 n |= i << 16;
3565 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3566 } else {
3567 if (i & 0x40)
3568 i |= 0x780;
3569 else
3570 i |= 0x800;
3571 n |= i << 19;
3572 tcg_gen_movi_i32(cpu_F0s, n);
3574 break;
3575 case 15: /* extension space */
3576 switch (rn) {
3577 case 0: /* cpy */
3578 /* no-op */
3579 break;
3580 case 1: /* abs */
3581 gen_vfp_abs(dp);
3582 break;
3583 case 2: /* neg */
3584 gen_vfp_neg(dp);
3585 break;
3586 case 3: /* sqrt */
3587 gen_vfp_sqrt(dp);
3588 break;
3589 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3590 tmp = gen_vfp_mrs();
3591 tcg_gen_ext16u_i32(tmp, tmp);
3592 if (dp) {
3593 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3594 cpu_env);
3595 } else {
3596 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3597 cpu_env);
3599 tcg_temp_free_i32(tmp);
3600 break;
3601 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3602 tmp = gen_vfp_mrs();
3603 tcg_gen_shri_i32(tmp, tmp, 16);
3604 if (dp) {
3605 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3606 cpu_env);
3607 } else {
3608 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3609 cpu_env);
3611 tcg_temp_free_i32(tmp);
3612 break;
3613 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3614 tmp = tcg_temp_new_i32();
3615 if (dp) {
3616 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3617 cpu_env);
3618 } else {
3619 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3620 cpu_env);
3622 gen_mov_F0_vreg(0, rd);
3623 tmp2 = gen_vfp_mrs();
3624 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3625 tcg_gen_or_i32(tmp, tmp, tmp2);
3626 tcg_temp_free_i32(tmp2);
3627 gen_vfp_msr(tmp);
3628 break;
3629 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3630 tmp = tcg_temp_new_i32();
3631 if (dp) {
3632 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3633 cpu_env);
3634 } else {
3635 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3636 cpu_env);
3638 tcg_gen_shli_i32(tmp, tmp, 16);
3639 gen_mov_F0_vreg(0, rd);
3640 tmp2 = gen_vfp_mrs();
3641 tcg_gen_ext16u_i32(tmp2, tmp2);
3642 tcg_gen_or_i32(tmp, tmp, tmp2);
3643 tcg_temp_free_i32(tmp2);
3644 gen_vfp_msr(tmp);
3645 break;
3646 case 8: /* cmp */
3647 gen_vfp_cmp(dp);
3648 break;
3649 case 9: /* cmpe */
3650 gen_vfp_cmpe(dp);
3651 break;
3652 case 10: /* cmpz */
3653 gen_vfp_cmp(dp);
3654 break;
3655 case 11: /* cmpez */
3656 gen_vfp_F1_ld0(dp);
3657 gen_vfp_cmpe(dp);
3658 break;
3659 case 12: /* vrintr */
3661 TCGv_ptr fpst = get_fpstatus_ptr(0);
3662 if (dp) {
3663 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3664 } else {
3665 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3667 tcg_temp_free_ptr(fpst);
3668 break;
3670 case 13: /* vrintz */
3672 TCGv_ptr fpst = get_fpstatus_ptr(0);
3673 TCGv_i32 tcg_rmode;
3674 tcg_rmode = tcg_const_i32(float_round_to_zero);
3675 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3676 if (dp) {
3677 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3678 } else {
3679 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3681 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3682 tcg_temp_free_i32(tcg_rmode);
3683 tcg_temp_free_ptr(fpst);
3684 break;
3686 case 14: /* vrintx */
3688 TCGv_ptr fpst = get_fpstatus_ptr(0);
3689 if (dp) {
3690 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3691 } else {
3692 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3694 tcg_temp_free_ptr(fpst);
3695 break;
3697 case 15: /* single<->double conversion */
3698 if (dp)
3699 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3700 else
3701 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3702 break;
3703 case 16: /* fuito */
3704 gen_vfp_uito(dp, 0);
3705 break;
3706 case 17: /* fsito */
3707 gen_vfp_sito(dp, 0);
3708 break;
3709 case 20: /* fshto */
3710 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3711 return 1;
3713 gen_vfp_shto(dp, 16 - rm, 0);
3714 break;
3715 case 21: /* fslto */
3716 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3717 return 1;
3719 gen_vfp_slto(dp, 32 - rm, 0);
3720 break;
3721 case 22: /* fuhto */
3722 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3723 return 1;
3725 gen_vfp_uhto(dp, 16 - rm, 0);
3726 break;
3727 case 23: /* fulto */
3728 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3729 return 1;
3731 gen_vfp_ulto(dp, 32 - rm, 0);
3732 break;
3733 case 24: /* ftoui */
3734 gen_vfp_toui(dp, 0);
3735 break;
3736 case 25: /* ftouiz */
3737 gen_vfp_touiz(dp, 0);
3738 break;
3739 case 26: /* ftosi */
3740 gen_vfp_tosi(dp, 0);
3741 break;
3742 case 27: /* ftosiz */
3743 gen_vfp_tosiz(dp, 0);
3744 break;
3745 case 28: /* ftosh */
3746 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3747 return 1;
3749 gen_vfp_tosh(dp, 16 - rm, 0);
3750 break;
3751 case 29: /* ftosl */
3752 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3753 return 1;
3755 gen_vfp_tosl(dp, 32 - rm, 0);
3756 break;
3757 case 30: /* ftouh */
3758 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3759 return 1;
3761 gen_vfp_touh(dp, 16 - rm, 0);
3762 break;
3763 case 31: /* ftoul */
3764 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3765 return 1;
3767 gen_vfp_toul(dp, 32 - rm, 0);
3768 break;
3769 default: /* undefined */
3770 return 1;
3772 break;
3773 default: /* undefined */
3774 return 1;
3777 /* Write back the result. */
3778 if (op == 15 && (rn >= 8 && rn <= 11)) {
3779 /* Comparison, do nothing. */
3780 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3781 (rn & 0x1e) == 0x6)) {
3782 /* VCVT double to int: always integer result.
3783 * VCVT double to half precision is always a single
3784 * precision result.
3786 gen_mov_vreg_F0(0, rd);
3787 } else if (op == 15 && rn == 15) {
3788 /* conversion */
3789 gen_mov_vreg_F0(!dp, rd);
3790 } else {
3791 gen_mov_vreg_F0(dp, rd);
3794 /* break out of the loop if we have finished */
3795 if (veclen == 0)
3796 break;
3798 if (op == 15 && delta_m == 0) {
3799 /* single source one-many */
3800 while (veclen--) {
3801 rd = ((rd + delta_d) & (bank_mask - 1))
3802 | (rd & bank_mask);
3803 gen_mov_vreg_F0(dp, rd);
3805 break;
3807 /* Setup the next operands. */
3808 veclen--;
3809 rd = ((rd + delta_d) & (bank_mask - 1))
3810 | (rd & bank_mask);
3812 if (op == 15) {
3813 /* One source operand. */
3814 rm = ((rm + delta_m) & (bank_mask - 1))
3815 | (rm & bank_mask);
3816 gen_mov_F0_vreg(dp, rm);
3817 } else {
3818 /* Two source operands. */
3819 rn = ((rn + delta_d) & (bank_mask - 1))
3820 | (rn & bank_mask);
3821 gen_mov_F0_vreg(dp, rn);
3822 if (delta_m) {
3823 rm = ((rm + delta_m) & (bank_mask - 1))
3824 | (rm & bank_mask);
3825 gen_mov_F1_vreg(dp, rm);
3830 break;
3831 case 0xc:
3832 case 0xd:
3833 if ((insn & 0x03e00000) == 0x00400000) {
3834 /* two-register transfer */
3835 rn = (insn >> 16) & 0xf;
3836 rd = (insn >> 12) & 0xf;
3837 if (dp) {
3838 VFP_DREG_M(rm, insn);
3839 } else {
3840 rm = VFP_SREG_M(insn);
3843 if (insn & ARM_CP_RW_BIT) {
3844 /* vfp->arm */
3845 if (dp) {
3846 gen_mov_F0_vreg(0, rm * 2);
3847 tmp = gen_vfp_mrs();
3848 store_reg(s, rd, tmp);
3849 gen_mov_F0_vreg(0, rm * 2 + 1);
3850 tmp = gen_vfp_mrs();
3851 store_reg(s, rn, tmp);
3852 } else {
3853 gen_mov_F0_vreg(0, rm);
3854 tmp = gen_vfp_mrs();
3855 store_reg(s, rd, tmp);
3856 gen_mov_F0_vreg(0, rm + 1);
3857 tmp = gen_vfp_mrs();
3858 store_reg(s, rn, tmp);
3860 } else {
3861 /* arm->vfp */
3862 if (dp) {
3863 tmp = load_reg(s, rd);
3864 gen_vfp_msr(tmp);
3865 gen_mov_vreg_F0(0, rm * 2);
3866 tmp = load_reg(s, rn);
3867 gen_vfp_msr(tmp);
3868 gen_mov_vreg_F0(0, rm * 2 + 1);
3869 } else {
3870 tmp = load_reg(s, rd);
3871 gen_vfp_msr(tmp);
3872 gen_mov_vreg_F0(0, rm);
3873 tmp = load_reg(s, rn);
3874 gen_vfp_msr(tmp);
3875 gen_mov_vreg_F0(0, rm + 1);
3878 } else {
3879 /* Load/store */
3880 rn = (insn >> 16) & 0xf;
3881 if (dp)
3882 VFP_DREG_D(rd, insn);
3883 else
3884 rd = VFP_SREG_D(insn);
3885 if ((insn & 0x01200000) == 0x01000000) {
3886 /* Single load/store */
3887 offset = (insn & 0xff) << 2;
3888 if ((insn & (1 << 23)) == 0)
3889 offset = -offset;
3890 if (s->thumb && rn == 15) {
3891 /* This is actually UNPREDICTABLE */
3892 addr = tcg_temp_new_i32();
3893 tcg_gen_movi_i32(addr, s->pc & ~2);
3894 } else {
3895 addr = load_reg(s, rn);
3897 tcg_gen_addi_i32(addr, addr, offset);
3898 if (insn & (1 << 20)) {
3899 gen_vfp_ld(s, dp, addr);
3900 gen_mov_vreg_F0(dp, rd);
3901 } else {
3902 gen_mov_F0_vreg(dp, rd);
3903 gen_vfp_st(s, dp, addr);
3905 tcg_temp_free_i32(addr);
3906 } else {
3907 /* load/store multiple */
3908 int w = insn & (1 << 21);
3909 if (dp)
3910 n = (insn >> 1) & 0x7f;
3911 else
3912 n = insn & 0xff;
3914 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3915 /* P == U , W == 1 => UNDEF */
3916 return 1;
3918 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3919 /* UNPREDICTABLE cases for bad immediates: we choose to
3920 * UNDEF to avoid generating huge numbers of TCG ops
3922 return 1;
3924 if (rn == 15 && w) {
3925 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3926 return 1;
3929 if (s->thumb && rn == 15) {
3930 /* This is actually UNPREDICTABLE */
3931 addr = tcg_temp_new_i32();
3932 tcg_gen_movi_i32(addr, s->pc & ~2);
3933 } else {
3934 addr = load_reg(s, rn);
3936 if (insn & (1 << 24)) /* pre-decrement */
3937 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3939 if (dp)
3940 offset = 8;
3941 else
3942 offset = 4;
3943 for (i = 0; i < n; i++) {
3944 if (insn & ARM_CP_RW_BIT) {
3945 /* load */
3946 gen_vfp_ld(s, dp, addr);
3947 gen_mov_vreg_F0(dp, rd + i);
3948 } else {
3949 /* store */
3950 gen_mov_F0_vreg(dp, rd + i);
3951 gen_vfp_st(s, dp, addr);
3953 tcg_gen_addi_i32(addr, addr, offset);
3955 if (w) {
3956 /* writeback */
3957 if (insn & (1 << 24))
3958 offset = -offset * n;
3959 else if (dp && (insn & 1))
3960 offset = 4;
3961 else
3962 offset = 0;
3964 if (offset != 0)
3965 tcg_gen_addi_i32(addr, addr, offset);
3966 store_reg(s, rn, addr);
3967 } else {
3968 tcg_temp_free_i32(addr);
3972 break;
3973 default:
3974 /* Should never happen. */
3975 return 1;
3977 return 0;
3980 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3982 TranslationBlock *tb;
3984 tb = s->tb;
3985 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3986 tcg_gen_goto_tb(n);
3987 gen_set_pc_im(s, dest);
3988 tcg_gen_exit_tb((uintptr_t)tb + n);
3989 } else {
3990 gen_set_pc_im(s, dest);
3991 tcg_gen_exit_tb(0);
3995 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3997 if (unlikely(s->singlestep_enabled || s->ss_active)) {
3998 /* An indirect jump so that we still trigger the debug exception. */
3999 if (s->thumb)
4000 dest |= 1;
4001 gen_bx_im(s, dest);
4002 } else {
4003 gen_goto_tb(s, 0, dest);
4004 s->is_jmp = DISAS_TB_JUMP;
4008 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4010 if (x)
4011 tcg_gen_sari_i32(t0, t0, 16);
4012 else
4013 gen_sxth(t0);
4014 if (y)
4015 tcg_gen_sari_i32(t1, t1, 16);
4016 else
4017 gen_sxth(t1);
4018 tcg_gen_mul_i32(t0, t0, t1);
4021 /* Return the mask of PSR bits set by a MSR instruction. */
4022 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4024 uint32_t mask;
4026 mask = 0;
4027 if (flags & (1 << 0))
4028 mask |= 0xff;
4029 if (flags & (1 << 1))
4030 mask |= 0xff00;
4031 if (flags & (1 << 2))
4032 mask |= 0xff0000;
4033 if (flags & (1 << 3))
4034 mask |= 0xff000000;
4036 /* Mask out undefined bits. */
4037 mask &= ~CPSR_RESERVED;
4038 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4039 mask &= ~CPSR_T;
4041 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4042 mask &= ~CPSR_Q; /* V5TE in reality*/
4044 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4045 mask &= ~(CPSR_E | CPSR_GE);
4047 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4048 mask &= ~CPSR_IT;
4050 /* Mask out execution state and reserved bits. */
4051 if (!spsr) {
4052 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4054 /* Mask out privileged bits. */
4055 if (IS_USER(s))
4056 mask &= CPSR_USER;
4057 return mask;
4060 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4061 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4063 TCGv_i32 tmp;
4064 if (spsr) {
4065 /* ??? This is also undefined in system mode. */
4066 if (IS_USER(s))
4067 return 1;
4069 tmp = load_cpu_field(spsr);
4070 tcg_gen_andi_i32(tmp, tmp, ~mask);
4071 tcg_gen_andi_i32(t0, t0, mask);
4072 tcg_gen_or_i32(tmp, tmp, t0);
4073 store_cpu_field(tmp, spsr);
4074 } else {
4075 gen_set_cpsr(t0, mask);
4077 tcg_temp_free_i32(t0);
4078 gen_lookup_tb(s);
4079 return 0;
4082 /* Returns nonzero if access to the PSR is not permitted. */
4083 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4085 TCGv_i32 tmp;
4086 tmp = tcg_temp_new_i32();
4087 tcg_gen_movi_i32(tmp, val);
4088 return gen_set_psr(s, mask, spsr, tmp);
4091 /* Generate an old-style exception return. Marks pc as dead. */
4092 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4094 TCGv_i32 tmp;
4095 store_reg(s, 15, pc);
4096 tmp = load_cpu_field(spsr);
4097 gen_set_cpsr(tmp, CPSR_ERET_MASK);
4098 tcg_temp_free_i32(tmp);
4099 s->is_jmp = DISAS_UPDATE;
4102 /* Generate a v6 exception return. Marks both values as dead. */
4103 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4105 gen_set_cpsr(cpsr, CPSR_ERET_MASK);
4106 tcg_temp_free_i32(cpsr);
4107 store_reg(s, 15, pc);
4108 s->is_jmp = DISAS_UPDATE;
4111 static void gen_nop_hint(DisasContext *s, int val)
4113 switch (val) {
4114 case 1: /* yield */
4115 gen_set_pc_im(s, s->pc);
4116 s->is_jmp = DISAS_YIELD;
4117 break;
4118 case 3: /* wfi */
4119 gen_set_pc_im(s, s->pc);
4120 s->is_jmp = DISAS_WFI;
4121 break;
4122 case 2: /* wfe */
4123 gen_set_pc_im(s, s->pc);
4124 s->is_jmp = DISAS_WFE;
4125 break;
4126 case 4: /* sev */
4127 case 5: /* sevl */
4128 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4129 default: /* nop */
4130 break;
4134 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4136 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4138 switch (size) {
4139 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4140 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4141 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4142 default: abort();
4146 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4148 switch (size) {
4149 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4150 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4151 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4152 default: return;
4156 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4157 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4158 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4159 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4160 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4162 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4163 switch ((size << 1) | u) { \
4164 case 0: \
4165 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4166 break; \
4167 case 1: \
4168 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4169 break; \
4170 case 2: \
4171 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4172 break; \
4173 case 3: \
4174 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4175 break; \
4176 case 4: \
4177 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4178 break; \
4179 case 5: \
4180 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4181 break; \
4182 default: return 1; \
4183 }} while (0)
4185 #define GEN_NEON_INTEGER_OP(name) do { \
4186 switch ((size << 1) | u) { \
4187 case 0: \
4188 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4189 break; \
4190 case 1: \
4191 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4192 break; \
4193 case 2: \
4194 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4195 break; \
4196 case 3: \
4197 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4198 break; \
4199 case 4: \
4200 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4201 break; \
4202 case 5: \
4203 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4204 break; \
4205 default: return 1; \
4206 }} while (0)
4208 static TCGv_i32 neon_load_scratch(int scratch)
4210 TCGv_i32 tmp = tcg_temp_new_i32();
4211 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4212 return tmp;
4215 static void neon_store_scratch(int scratch, TCGv_i32 var)
4217 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4218 tcg_temp_free_i32(var);
4221 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4223 TCGv_i32 tmp;
4224 if (size == 1) {
4225 tmp = neon_load_reg(reg & 7, reg >> 4);
4226 if (reg & 8) {
4227 gen_neon_dup_high16(tmp);
4228 } else {
4229 gen_neon_dup_low16(tmp);
4231 } else {
4232 tmp = neon_load_reg(reg & 15, reg >> 4);
4234 return tmp;
4237 static int gen_neon_unzip(int rd, int rm, int size, int q)
4239 TCGv_i32 tmp, tmp2;
4240 if (!q && size == 2) {
4241 return 1;
4243 tmp = tcg_const_i32(rd);
4244 tmp2 = tcg_const_i32(rm);
4245 if (q) {
4246 switch (size) {
4247 case 0:
4248 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4249 break;
4250 case 1:
4251 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4252 break;
4253 case 2:
4254 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4255 break;
4256 default:
4257 abort();
4259 } else {
4260 switch (size) {
4261 case 0:
4262 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4263 break;
4264 case 1:
4265 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4266 break;
4267 default:
4268 abort();
4271 tcg_temp_free_i32(tmp);
4272 tcg_temp_free_i32(tmp2);
4273 return 0;
4276 static int gen_neon_zip(int rd, int rm, int size, int q)
4278 TCGv_i32 tmp, tmp2;
4279 if (!q && size == 2) {
4280 return 1;
4282 tmp = tcg_const_i32(rd);
4283 tmp2 = tcg_const_i32(rm);
4284 if (q) {
4285 switch (size) {
4286 case 0:
4287 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4288 break;
4289 case 1:
4290 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4291 break;
4292 case 2:
4293 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4294 break;
4295 default:
4296 abort();
4298 } else {
4299 switch (size) {
4300 case 0:
4301 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4302 break;
4303 case 1:
4304 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4305 break;
4306 default:
4307 abort();
4310 tcg_temp_free_i32(tmp);
4311 tcg_temp_free_i32(tmp2);
4312 return 0;
4315 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4317 TCGv_i32 rd, tmp;
4319 rd = tcg_temp_new_i32();
4320 tmp = tcg_temp_new_i32();
4322 tcg_gen_shli_i32(rd, t0, 8);
4323 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4324 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4325 tcg_gen_or_i32(rd, rd, tmp);
4327 tcg_gen_shri_i32(t1, t1, 8);
4328 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4329 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4330 tcg_gen_or_i32(t1, t1, tmp);
4331 tcg_gen_mov_i32(t0, rd);
4333 tcg_temp_free_i32(tmp);
4334 tcg_temp_free_i32(rd);
4337 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4339 TCGv_i32 rd, tmp;
4341 rd = tcg_temp_new_i32();
4342 tmp = tcg_temp_new_i32();
4344 tcg_gen_shli_i32(rd, t0, 16);
4345 tcg_gen_andi_i32(tmp, t1, 0xffff);
4346 tcg_gen_or_i32(rd, rd, tmp);
4347 tcg_gen_shri_i32(t1, t1, 16);
4348 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4349 tcg_gen_or_i32(t1, t1, tmp);
4350 tcg_gen_mov_i32(t0, rd);
4352 tcg_temp_free_i32(tmp);
4353 tcg_temp_free_i32(rd);
4357 static struct {
4358 int nregs;
4359 int interleave;
4360 int spacing;
4361 } neon_ls_element_type[11] = {
4362 {4, 4, 1},
4363 {4, 4, 2},
4364 {4, 1, 1},
4365 {4, 2, 1},
4366 {3, 3, 1},
4367 {3, 3, 2},
4368 {3, 1, 1},
4369 {1, 1, 1},
4370 {2, 2, 1},
4371 {2, 2, 2},
4372 {2, 1, 1}
4375 /* Translate a NEON load/store element instruction. Return nonzero if the
4376 instruction is invalid. */
4377 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4379 int rd, rn, rm;
4380 int op;
4381 int nregs;
4382 int interleave;
4383 int spacing;
4384 int stride;
4385 int size;
4386 int reg;
4387 int pass;
4388 int load;
4389 int shift;
4390 int n;
4391 TCGv_i32 addr;
4392 TCGv_i32 tmp;
4393 TCGv_i32 tmp2;
4394 TCGv_i64 tmp64;
4396 /* FIXME: this access check should not take precedence over UNDEF
4397 * for invalid encodings; we will generate incorrect syndrome information
4398 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4400 if (s->fp_excp_el) {
4401 gen_exception_insn(s, 4, EXCP_UDEF,
4402 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
4403 return 0;
4406 if (!s->vfp_enabled)
4407 return 1;
4408 VFP_DREG_D(rd, insn);
4409 rn = (insn >> 16) & 0xf;
4410 rm = insn & 0xf;
4411 load = (insn & (1 << 21)) != 0;
4412 if ((insn & (1 << 23)) == 0) {
4413 /* Load store all elements. */
4414 op = (insn >> 8) & 0xf;
4415 size = (insn >> 6) & 3;
4416 if (op > 10)
4417 return 1;
4418 /* Catch UNDEF cases for bad values of align field */
4419 switch (op & 0xc) {
4420 case 4:
4421 if (((insn >> 5) & 1) == 1) {
4422 return 1;
4424 break;
4425 case 8:
4426 if (((insn >> 4) & 3) == 3) {
4427 return 1;
4429 break;
4430 default:
4431 break;
4433 nregs = neon_ls_element_type[op].nregs;
4434 interleave = neon_ls_element_type[op].interleave;
4435 spacing = neon_ls_element_type[op].spacing;
4436 if (size == 3 && (interleave | spacing) != 1)
4437 return 1;
4438 addr = tcg_temp_new_i32();
4439 load_reg_var(s, addr, rn);
4440 stride = (1 << size) * interleave;
4441 for (reg = 0; reg < nregs; reg++) {
4442 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4443 load_reg_var(s, addr, rn);
4444 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4445 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4446 load_reg_var(s, addr, rn);
4447 tcg_gen_addi_i32(addr, addr, 1 << size);
4449 if (size == 3) {
4450 tmp64 = tcg_temp_new_i64();
4451 if (load) {
4452 gen_aa32_ld64(tmp64, addr, get_mem_index(s));
4453 neon_store_reg64(tmp64, rd);
4454 } else {
4455 neon_load_reg64(tmp64, rd);
4456 gen_aa32_st64(tmp64, addr, get_mem_index(s));
4458 tcg_temp_free_i64(tmp64);
4459 tcg_gen_addi_i32(addr, addr, stride);
4460 } else {
4461 for (pass = 0; pass < 2; pass++) {
4462 if (size == 2) {
4463 if (load) {
4464 tmp = tcg_temp_new_i32();
4465 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4466 neon_store_reg(rd, pass, tmp);
4467 } else {
4468 tmp = neon_load_reg(rd, pass);
4469 gen_aa32_st32(tmp, addr, get_mem_index(s));
4470 tcg_temp_free_i32(tmp);
4472 tcg_gen_addi_i32(addr, addr, stride);
4473 } else if (size == 1) {
4474 if (load) {
4475 tmp = tcg_temp_new_i32();
4476 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4477 tcg_gen_addi_i32(addr, addr, stride);
4478 tmp2 = tcg_temp_new_i32();
4479 gen_aa32_ld16u(tmp2, addr, get_mem_index(s));
4480 tcg_gen_addi_i32(addr, addr, stride);
4481 tcg_gen_shli_i32(tmp2, tmp2, 16);
4482 tcg_gen_or_i32(tmp, tmp, tmp2);
4483 tcg_temp_free_i32(tmp2);
4484 neon_store_reg(rd, pass, tmp);
4485 } else {
4486 tmp = neon_load_reg(rd, pass);
4487 tmp2 = tcg_temp_new_i32();
4488 tcg_gen_shri_i32(tmp2, tmp, 16);
4489 gen_aa32_st16(tmp, addr, get_mem_index(s));
4490 tcg_temp_free_i32(tmp);
4491 tcg_gen_addi_i32(addr, addr, stride);
4492 gen_aa32_st16(tmp2, addr, get_mem_index(s));
4493 tcg_temp_free_i32(tmp2);
4494 tcg_gen_addi_i32(addr, addr, stride);
4496 } else /* size == 0 */ {
4497 if (load) {
4498 TCGV_UNUSED_I32(tmp2);
4499 for (n = 0; n < 4; n++) {
4500 tmp = tcg_temp_new_i32();
4501 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4502 tcg_gen_addi_i32(addr, addr, stride);
4503 if (n == 0) {
4504 tmp2 = tmp;
4505 } else {
4506 tcg_gen_shli_i32(tmp, tmp, n * 8);
4507 tcg_gen_or_i32(tmp2, tmp2, tmp);
4508 tcg_temp_free_i32(tmp);
4511 neon_store_reg(rd, pass, tmp2);
4512 } else {
4513 tmp2 = neon_load_reg(rd, pass);
4514 for (n = 0; n < 4; n++) {
4515 tmp = tcg_temp_new_i32();
4516 if (n == 0) {
4517 tcg_gen_mov_i32(tmp, tmp2);
4518 } else {
4519 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4521 gen_aa32_st8(tmp, addr, get_mem_index(s));
4522 tcg_temp_free_i32(tmp);
4523 tcg_gen_addi_i32(addr, addr, stride);
4525 tcg_temp_free_i32(tmp2);
4530 rd += spacing;
4532 tcg_temp_free_i32(addr);
4533 stride = nregs * 8;
4534 } else {
4535 size = (insn >> 10) & 3;
4536 if (size == 3) {
4537 /* Load single element to all lanes. */
4538 int a = (insn >> 4) & 1;
4539 if (!load) {
4540 return 1;
4542 size = (insn >> 6) & 3;
4543 nregs = ((insn >> 8) & 3) + 1;
4545 if (size == 3) {
4546 if (nregs != 4 || a == 0) {
4547 return 1;
4549 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4550 size = 2;
4552 if (nregs == 1 && a == 1 && size == 0) {
4553 return 1;
4555 if (nregs == 3 && a == 1) {
4556 return 1;
4558 addr = tcg_temp_new_i32();
4559 load_reg_var(s, addr, rn);
4560 if (nregs == 1) {
4561 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4562 tmp = gen_load_and_replicate(s, addr, size);
4563 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4564 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4565 if (insn & (1 << 5)) {
4566 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4567 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4569 tcg_temp_free_i32(tmp);
4570 } else {
4571 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4572 stride = (insn & (1 << 5)) ? 2 : 1;
4573 for (reg = 0; reg < nregs; reg++) {
4574 tmp = gen_load_and_replicate(s, addr, size);
4575 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4576 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4577 tcg_temp_free_i32(tmp);
4578 tcg_gen_addi_i32(addr, addr, 1 << size);
4579 rd += stride;
4582 tcg_temp_free_i32(addr);
4583 stride = (1 << size) * nregs;
4584 } else {
4585 /* Single element. */
4586 int idx = (insn >> 4) & 0xf;
4587 pass = (insn >> 7) & 1;
4588 switch (size) {
4589 case 0:
4590 shift = ((insn >> 5) & 3) * 8;
4591 stride = 1;
4592 break;
4593 case 1:
4594 shift = ((insn >> 6) & 1) * 16;
4595 stride = (insn & (1 << 5)) ? 2 : 1;
4596 break;
4597 case 2:
4598 shift = 0;
4599 stride = (insn & (1 << 6)) ? 2 : 1;
4600 break;
4601 default:
4602 abort();
4604 nregs = ((insn >> 8) & 3) + 1;
4605 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4606 switch (nregs) {
4607 case 1:
4608 if (((idx & (1 << size)) != 0) ||
4609 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4610 return 1;
4612 break;
4613 case 3:
4614 if ((idx & 1) != 0) {
4615 return 1;
4617 /* fall through */
4618 case 2:
4619 if (size == 2 && (idx & 2) != 0) {
4620 return 1;
4622 break;
4623 case 4:
4624 if ((size == 2) && ((idx & 3) == 3)) {
4625 return 1;
4627 break;
4628 default:
4629 abort();
4631 if ((rd + stride * (nregs - 1)) > 31) {
4632 /* Attempts to write off the end of the register file
4633 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4634 * the neon_load_reg() would write off the end of the array.
4636 return 1;
4638 addr = tcg_temp_new_i32();
4639 load_reg_var(s, addr, rn);
4640 for (reg = 0; reg < nregs; reg++) {
4641 if (load) {
4642 tmp = tcg_temp_new_i32();
4643 switch (size) {
4644 case 0:
4645 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4646 break;
4647 case 1:
4648 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4649 break;
4650 case 2:
4651 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4652 break;
4653 default: /* Avoid compiler warnings. */
4654 abort();
4656 if (size != 2) {
4657 tmp2 = neon_load_reg(rd, pass);
4658 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4659 shift, size ? 16 : 8);
4660 tcg_temp_free_i32(tmp2);
4662 neon_store_reg(rd, pass, tmp);
4663 } else { /* Store */
4664 tmp = neon_load_reg(rd, pass);
4665 if (shift)
4666 tcg_gen_shri_i32(tmp, tmp, shift);
4667 switch (size) {
4668 case 0:
4669 gen_aa32_st8(tmp, addr, get_mem_index(s));
4670 break;
4671 case 1:
4672 gen_aa32_st16(tmp, addr, get_mem_index(s));
4673 break;
4674 case 2:
4675 gen_aa32_st32(tmp, addr, get_mem_index(s));
4676 break;
4678 tcg_temp_free_i32(tmp);
4680 rd += stride;
4681 tcg_gen_addi_i32(addr, addr, 1 << size);
4683 tcg_temp_free_i32(addr);
4684 stride = nregs * (1 << size);
4687 if (rm != 15) {
4688 TCGv_i32 base;
4690 base = load_reg(s, rn);
4691 if (rm == 13) {
4692 tcg_gen_addi_i32(base, base, stride);
4693 } else {
4694 TCGv_i32 index;
4695 index = load_reg(s, rm);
4696 tcg_gen_add_i32(base, base, index);
4697 tcg_temp_free_i32(index);
4699 store_reg(s, rn, base);
4701 return 0;
4704 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4705 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4707 tcg_gen_and_i32(t, t, c);
4708 tcg_gen_andc_i32(f, f, c);
4709 tcg_gen_or_i32(dest, t, f);
4712 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4714 switch (size) {
4715 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4716 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4717 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4718 default: abort();
4722 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4724 switch (size) {
4725 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4726 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4727 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4728 default: abort();
4732 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4734 switch (size) {
4735 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4736 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4737 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4738 default: abort();
4742 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4744 switch (size) {
4745 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4746 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4747 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4748 default: abort();
4752 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4753 int q, int u)
4755 if (q) {
4756 if (u) {
4757 switch (size) {
4758 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4759 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4760 default: abort();
4762 } else {
4763 switch (size) {
4764 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4765 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4766 default: abort();
4769 } else {
4770 if (u) {
4771 switch (size) {
4772 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4773 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4774 default: abort();
4776 } else {
4777 switch (size) {
4778 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4779 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4780 default: abort();
4786 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4788 if (u) {
4789 switch (size) {
4790 case 0: gen_helper_neon_widen_u8(dest, src); break;
4791 case 1: gen_helper_neon_widen_u16(dest, src); break;
4792 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4793 default: abort();
4795 } else {
4796 switch (size) {
4797 case 0: gen_helper_neon_widen_s8(dest, src); break;
4798 case 1: gen_helper_neon_widen_s16(dest, src); break;
4799 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4800 default: abort();
4803 tcg_temp_free_i32(src);
4806 static inline void gen_neon_addl(int size)
4808 switch (size) {
4809 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4810 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4811 case 2: tcg_gen_add_i64(CPU_V001); break;
4812 default: abort();
4816 static inline void gen_neon_subl(int size)
4818 switch (size) {
4819 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4820 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4821 case 2: tcg_gen_sub_i64(CPU_V001); break;
4822 default: abort();
4826 static inline void gen_neon_negl(TCGv_i64 var, int size)
4828 switch (size) {
4829 case 0: gen_helper_neon_negl_u16(var, var); break;
4830 case 1: gen_helper_neon_negl_u32(var, var); break;
4831 case 2:
4832 tcg_gen_neg_i64(var, var);
4833 break;
4834 default: abort();
4838 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4840 switch (size) {
4841 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4842 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4843 default: abort();
4847 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4848 int size, int u)
4850 TCGv_i64 tmp;
4852 switch ((size << 1) | u) {
4853 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4854 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4855 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4856 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4857 case 4:
4858 tmp = gen_muls_i64_i32(a, b);
4859 tcg_gen_mov_i64(dest, tmp);
4860 tcg_temp_free_i64(tmp);
4861 break;
4862 case 5:
4863 tmp = gen_mulu_i64_i32(a, b);
4864 tcg_gen_mov_i64(dest, tmp);
4865 tcg_temp_free_i64(tmp);
4866 break;
4867 default: abort();
4870 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4871 Don't forget to clean them now. */
4872 if (size < 2) {
4873 tcg_temp_free_i32(a);
4874 tcg_temp_free_i32(b);
4878 static void gen_neon_narrow_op(int op, int u, int size,
4879 TCGv_i32 dest, TCGv_i64 src)
4881 if (op) {
4882 if (u) {
4883 gen_neon_unarrow_sats(size, dest, src);
4884 } else {
4885 gen_neon_narrow(size, dest, src);
4887 } else {
4888 if (u) {
4889 gen_neon_narrow_satu(size, dest, src);
4890 } else {
4891 gen_neon_narrow_sats(size, dest, src);
4896 /* Symbolic constants for op fields for Neon 3-register same-length.
4897 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4898 * table A7-9.
4900 #define NEON_3R_VHADD 0
4901 #define NEON_3R_VQADD 1
4902 #define NEON_3R_VRHADD 2
4903 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4904 #define NEON_3R_VHSUB 4
4905 #define NEON_3R_VQSUB 5
4906 #define NEON_3R_VCGT 6
4907 #define NEON_3R_VCGE 7
4908 #define NEON_3R_VSHL 8
4909 #define NEON_3R_VQSHL 9
4910 #define NEON_3R_VRSHL 10
4911 #define NEON_3R_VQRSHL 11
4912 #define NEON_3R_VMAX 12
4913 #define NEON_3R_VMIN 13
4914 #define NEON_3R_VABD 14
4915 #define NEON_3R_VABA 15
4916 #define NEON_3R_VADD_VSUB 16
4917 #define NEON_3R_VTST_VCEQ 17
4918 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4919 #define NEON_3R_VMUL 19
4920 #define NEON_3R_VPMAX 20
4921 #define NEON_3R_VPMIN 21
4922 #define NEON_3R_VQDMULH_VQRDMULH 22
4923 #define NEON_3R_VPADD 23
4924 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4925 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4926 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4927 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4928 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4929 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4930 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4931 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4933 static const uint8_t neon_3r_sizes[] = {
4934 [NEON_3R_VHADD] = 0x7,
4935 [NEON_3R_VQADD] = 0xf,
4936 [NEON_3R_VRHADD] = 0x7,
4937 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4938 [NEON_3R_VHSUB] = 0x7,
4939 [NEON_3R_VQSUB] = 0xf,
4940 [NEON_3R_VCGT] = 0x7,
4941 [NEON_3R_VCGE] = 0x7,
4942 [NEON_3R_VSHL] = 0xf,
4943 [NEON_3R_VQSHL] = 0xf,
4944 [NEON_3R_VRSHL] = 0xf,
4945 [NEON_3R_VQRSHL] = 0xf,
4946 [NEON_3R_VMAX] = 0x7,
4947 [NEON_3R_VMIN] = 0x7,
4948 [NEON_3R_VABD] = 0x7,
4949 [NEON_3R_VABA] = 0x7,
4950 [NEON_3R_VADD_VSUB] = 0xf,
4951 [NEON_3R_VTST_VCEQ] = 0x7,
4952 [NEON_3R_VML] = 0x7,
4953 [NEON_3R_VMUL] = 0x7,
4954 [NEON_3R_VPMAX] = 0x7,
4955 [NEON_3R_VPMIN] = 0x7,
4956 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4957 [NEON_3R_VPADD] = 0x7,
4958 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4959 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4960 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4961 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4962 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4963 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4964 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4965 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4968 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4969 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4970 * table A7-13.
4972 #define NEON_2RM_VREV64 0
4973 #define NEON_2RM_VREV32 1
4974 #define NEON_2RM_VREV16 2
4975 #define NEON_2RM_VPADDL 4
4976 #define NEON_2RM_VPADDL_U 5
4977 #define NEON_2RM_AESE 6 /* Includes AESD */
4978 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4979 #define NEON_2RM_VCLS 8
4980 #define NEON_2RM_VCLZ 9
4981 #define NEON_2RM_VCNT 10
4982 #define NEON_2RM_VMVN 11
4983 #define NEON_2RM_VPADAL 12
4984 #define NEON_2RM_VPADAL_U 13
4985 #define NEON_2RM_VQABS 14
4986 #define NEON_2RM_VQNEG 15
4987 #define NEON_2RM_VCGT0 16
4988 #define NEON_2RM_VCGE0 17
4989 #define NEON_2RM_VCEQ0 18
4990 #define NEON_2RM_VCLE0 19
4991 #define NEON_2RM_VCLT0 20
4992 #define NEON_2RM_SHA1H 21
4993 #define NEON_2RM_VABS 22
4994 #define NEON_2RM_VNEG 23
4995 #define NEON_2RM_VCGT0_F 24
4996 #define NEON_2RM_VCGE0_F 25
4997 #define NEON_2RM_VCEQ0_F 26
4998 #define NEON_2RM_VCLE0_F 27
4999 #define NEON_2RM_VCLT0_F 28
5000 #define NEON_2RM_VABS_F 30
5001 #define NEON_2RM_VNEG_F 31
5002 #define NEON_2RM_VSWP 32
5003 #define NEON_2RM_VTRN 33
5004 #define NEON_2RM_VUZP 34
5005 #define NEON_2RM_VZIP 35
5006 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5007 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5008 #define NEON_2RM_VSHLL 38
5009 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5010 #define NEON_2RM_VRINTN 40
5011 #define NEON_2RM_VRINTX 41
5012 #define NEON_2RM_VRINTA 42
5013 #define NEON_2RM_VRINTZ 43
5014 #define NEON_2RM_VCVT_F16_F32 44
5015 #define NEON_2RM_VRINTM 45
5016 #define NEON_2RM_VCVT_F32_F16 46
5017 #define NEON_2RM_VRINTP 47
5018 #define NEON_2RM_VCVTAU 48
5019 #define NEON_2RM_VCVTAS 49
5020 #define NEON_2RM_VCVTNU 50
5021 #define NEON_2RM_VCVTNS 51
5022 #define NEON_2RM_VCVTPU 52
5023 #define NEON_2RM_VCVTPS 53
5024 #define NEON_2RM_VCVTMU 54
5025 #define NEON_2RM_VCVTMS 55
5026 #define NEON_2RM_VRECPE 56
5027 #define NEON_2RM_VRSQRTE 57
5028 #define NEON_2RM_VRECPE_F 58
5029 #define NEON_2RM_VRSQRTE_F 59
5030 #define NEON_2RM_VCVT_FS 60
5031 #define NEON_2RM_VCVT_FU 61
5032 #define NEON_2RM_VCVT_SF 62
5033 #define NEON_2RM_VCVT_UF 63
5035 static int neon_2rm_is_float_op(int op)
5037 /* Return true if this neon 2reg-misc op is float-to-float */
5038 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5039 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5040 op == NEON_2RM_VRINTM ||
5041 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5042 op >= NEON_2RM_VRECPE_F);
5045 /* Each entry in this array has bit n set if the insn allows
5046 * size value n (otherwise it will UNDEF). Since unallocated
5047 * op values will have no bits set they always UNDEF.
5049 static const uint8_t neon_2rm_sizes[] = {
5050 [NEON_2RM_VREV64] = 0x7,
5051 [NEON_2RM_VREV32] = 0x3,
5052 [NEON_2RM_VREV16] = 0x1,
5053 [NEON_2RM_VPADDL] = 0x7,
5054 [NEON_2RM_VPADDL_U] = 0x7,
5055 [NEON_2RM_AESE] = 0x1,
5056 [NEON_2RM_AESMC] = 0x1,
5057 [NEON_2RM_VCLS] = 0x7,
5058 [NEON_2RM_VCLZ] = 0x7,
5059 [NEON_2RM_VCNT] = 0x1,
5060 [NEON_2RM_VMVN] = 0x1,
5061 [NEON_2RM_VPADAL] = 0x7,
5062 [NEON_2RM_VPADAL_U] = 0x7,
5063 [NEON_2RM_VQABS] = 0x7,
5064 [NEON_2RM_VQNEG] = 0x7,
5065 [NEON_2RM_VCGT0] = 0x7,
5066 [NEON_2RM_VCGE0] = 0x7,
5067 [NEON_2RM_VCEQ0] = 0x7,
5068 [NEON_2RM_VCLE0] = 0x7,
5069 [NEON_2RM_VCLT0] = 0x7,
5070 [NEON_2RM_SHA1H] = 0x4,
5071 [NEON_2RM_VABS] = 0x7,
5072 [NEON_2RM_VNEG] = 0x7,
5073 [NEON_2RM_VCGT0_F] = 0x4,
5074 [NEON_2RM_VCGE0_F] = 0x4,
5075 [NEON_2RM_VCEQ0_F] = 0x4,
5076 [NEON_2RM_VCLE0_F] = 0x4,
5077 [NEON_2RM_VCLT0_F] = 0x4,
5078 [NEON_2RM_VABS_F] = 0x4,
5079 [NEON_2RM_VNEG_F] = 0x4,
5080 [NEON_2RM_VSWP] = 0x1,
5081 [NEON_2RM_VTRN] = 0x7,
5082 [NEON_2RM_VUZP] = 0x7,
5083 [NEON_2RM_VZIP] = 0x7,
5084 [NEON_2RM_VMOVN] = 0x7,
5085 [NEON_2RM_VQMOVN] = 0x7,
5086 [NEON_2RM_VSHLL] = 0x7,
5087 [NEON_2RM_SHA1SU1] = 0x4,
5088 [NEON_2RM_VRINTN] = 0x4,
5089 [NEON_2RM_VRINTX] = 0x4,
5090 [NEON_2RM_VRINTA] = 0x4,
5091 [NEON_2RM_VRINTZ] = 0x4,
5092 [NEON_2RM_VCVT_F16_F32] = 0x2,
5093 [NEON_2RM_VRINTM] = 0x4,
5094 [NEON_2RM_VCVT_F32_F16] = 0x2,
5095 [NEON_2RM_VRINTP] = 0x4,
5096 [NEON_2RM_VCVTAU] = 0x4,
5097 [NEON_2RM_VCVTAS] = 0x4,
5098 [NEON_2RM_VCVTNU] = 0x4,
5099 [NEON_2RM_VCVTNS] = 0x4,
5100 [NEON_2RM_VCVTPU] = 0x4,
5101 [NEON_2RM_VCVTPS] = 0x4,
5102 [NEON_2RM_VCVTMU] = 0x4,
5103 [NEON_2RM_VCVTMS] = 0x4,
5104 [NEON_2RM_VRECPE] = 0x4,
5105 [NEON_2RM_VRSQRTE] = 0x4,
5106 [NEON_2RM_VRECPE_F] = 0x4,
5107 [NEON_2RM_VRSQRTE_F] = 0x4,
5108 [NEON_2RM_VCVT_FS] = 0x4,
5109 [NEON_2RM_VCVT_FU] = 0x4,
5110 [NEON_2RM_VCVT_SF] = 0x4,
5111 [NEON_2RM_VCVT_UF] = 0x4,
5114 /* Translate a NEON data processing instruction. Return nonzero if the
5115 instruction is invalid.
5116 We process data in a mixture of 32-bit and 64-bit chunks.
5117 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5119 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5121 int op;
5122 int q;
5123 int rd, rn, rm;
5124 int size;
5125 int shift;
5126 int pass;
5127 int count;
5128 int pairwise;
5129 int u;
5130 uint32_t imm, mask;
5131 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5132 TCGv_i64 tmp64;
5134 /* FIXME: this access check should not take precedence over UNDEF
5135 * for invalid encodings; we will generate incorrect syndrome information
5136 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5138 if (s->fp_excp_el) {
5139 gen_exception_insn(s, 4, EXCP_UDEF,
5140 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
5141 return 0;
5144 if (!s->vfp_enabled)
5145 return 1;
5146 q = (insn & (1 << 6)) != 0;
5147 u = (insn >> 24) & 1;
5148 VFP_DREG_D(rd, insn);
5149 VFP_DREG_N(rn, insn);
5150 VFP_DREG_M(rm, insn);
5151 size = (insn >> 20) & 3;
5152 if ((insn & (1 << 23)) == 0) {
5153 /* Three register same length. */
5154 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5155 /* Catch invalid op and bad size combinations: UNDEF */
5156 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5157 return 1;
5159 /* All insns of this form UNDEF for either this condition or the
5160 * superset of cases "Q==1"; we catch the latter later.
5162 if (q && ((rd | rn | rm) & 1)) {
5163 return 1;
5166 * The SHA-1/SHA-256 3-register instructions require special treatment
5167 * here, as their size field is overloaded as an op type selector, and
5168 * they all consume their input in a single pass.
5170 if (op == NEON_3R_SHA) {
5171 if (!q) {
5172 return 1;
5174 if (!u) { /* SHA-1 */
5175 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5176 return 1;
5178 tmp = tcg_const_i32(rd);
5179 tmp2 = tcg_const_i32(rn);
5180 tmp3 = tcg_const_i32(rm);
5181 tmp4 = tcg_const_i32(size);
5182 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5183 tcg_temp_free_i32(tmp4);
5184 } else { /* SHA-256 */
5185 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5186 return 1;
5188 tmp = tcg_const_i32(rd);
5189 tmp2 = tcg_const_i32(rn);
5190 tmp3 = tcg_const_i32(rm);
5191 switch (size) {
5192 case 0:
5193 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5194 break;
5195 case 1:
5196 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5197 break;
5198 case 2:
5199 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5200 break;
5203 tcg_temp_free_i32(tmp);
5204 tcg_temp_free_i32(tmp2);
5205 tcg_temp_free_i32(tmp3);
5206 return 0;
5208 if (size == 3 && op != NEON_3R_LOGIC) {
5209 /* 64-bit element instructions. */
5210 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5211 neon_load_reg64(cpu_V0, rn + pass);
5212 neon_load_reg64(cpu_V1, rm + pass);
5213 switch (op) {
5214 case NEON_3R_VQADD:
5215 if (u) {
5216 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5217 cpu_V0, cpu_V1);
5218 } else {
5219 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5220 cpu_V0, cpu_V1);
5222 break;
5223 case NEON_3R_VQSUB:
5224 if (u) {
5225 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5226 cpu_V0, cpu_V1);
5227 } else {
5228 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5229 cpu_V0, cpu_V1);
5231 break;
5232 case NEON_3R_VSHL:
5233 if (u) {
5234 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5235 } else {
5236 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5238 break;
5239 case NEON_3R_VQSHL:
5240 if (u) {
5241 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5242 cpu_V1, cpu_V0);
5243 } else {
5244 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5245 cpu_V1, cpu_V0);
5247 break;
5248 case NEON_3R_VRSHL:
5249 if (u) {
5250 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5251 } else {
5252 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5254 break;
5255 case NEON_3R_VQRSHL:
5256 if (u) {
5257 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5258 cpu_V1, cpu_V0);
5259 } else {
5260 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5261 cpu_V1, cpu_V0);
5263 break;
5264 case NEON_3R_VADD_VSUB:
5265 if (u) {
5266 tcg_gen_sub_i64(CPU_V001);
5267 } else {
5268 tcg_gen_add_i64(CPU_V001);
5270 break;
5271 default:
5272 abort();
5274 neon_store_reg64(cpu_V0, rd + pass);
5276 return 0;
5278 pairwise = 0;
5279 switch (op) {
5280 case NEON_3R_VSHL:
5281 case NEON_3R_VQSHL:
5282 case NEON_3R_VRSHL:
5283 case NEON_3R_VQRSHL:
5285 int rtmp;
5286 /* Shift instruction operands are reversed. */
5287 rtmp = rn;
5288 rn = rm;
5289 rm = rtmp;
5291 break;
5292 case NEON_3R_VPADD:
5293 if (u) {
5294 return 1;
5296 /* Fall through */
5297 case NEON_3R_VPMAX:
5298 case NEON_3R_VPMIN:
5299 pairwise = 1;
5300 break;
5301 case NEON_3R_FLOAT_ARITH:
5302 pairwise = (u && size < 2); /* if VPADD (float) */
5303 break;
5304 case NEON_3R_FLOAT_MINMAX:
5305 pairwise = u; /* if VPMIN/VPMAX (float) */
5306 break;
5307 case NEON_3R_FLOAT_CMP:
5308 if (!u && size) {
5309 /* no encoding for U=0 C=1x */
5310 return 1;
5312 break;
5313 case NEON_3R_FLOAT_ACMP:
5314 if (!u) {
5315 return 1;
5317 break;
5318 case NEON_3R_FLOAT_MISC:
5319 /* VMAXNM/VMINNM in ARMv8 */
5320 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5321 return 1;
5323 break;
5324 case NEON_3R_VMUL:
5325 if (u && (size != 0)) {
5326 /* UNDEF on invalid size for polynomial subcase */
5327 return 1;
5329 break;
5330 case NEON_3R_VFM:
5331 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5332 return 1;
5334 break;
5335 default:
5336 break;
5339 if (pairwise && q) {
5340 /* All the pairwise insns UNDEF if Q is set */
5341 return 1;
5344 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5346 if (pairwise) {
5347 /* Pairwise. */
5348 if (pass < 1) {
5349 tmp = neon_load_reg(rn, 0);
5350 tmp2 = neon_load_reg(rn, 1);
5351 } else {
5352 tmp = neon_load_reg(rm, 0);
5353 tmp2 = neon_load_reg(rm, 1);
5355 } else {
5356 /* Elementwise. */
5357 tmp = neon_load_reg(rn, pass);
5358 tmp2 = neon_load_reg(rm, pass);
5360 switch (op) {
5361 case NEON_3R_VHADD:
5362 GEN_NEON_INTEGER_OP(hadd);
5363 break;
5364 case NEON_3R_VQADD:
5365 GEN_NEON_INTEGER_OP_ENV(qadd);
5366 break;
5367 case NEON_3R_VRHADD:
5368 GEN_NEON_INTEGER_OP(rhadd);
5369 break;
5370 case NEON_3R_LOGIC: /* Logic ops. */
5371 switch ((u << 2) | size) {
5372 case 0: /* VAND */
5373 tcg_gen_and_i32(tmp, tmp, tmp2);
5374 break;
5375 case 1: /* BIC */
5376 tcg_gen_andc_i32(tmp, tmp, tmp2);
5377 break;
5378 case 2: /* VORR */
5379 tcg_gen_or_i32(tmp, tmp, tmp2);
5380 break;
5381 case 3: /* VORN */
5382 tcg_gen_orc_i32(tmp, tmp, tmp2);
5383 break;
5384 case 4: /* VEOR */
5385 tcg_gen_xor_i32(tmp, tmp, tmp2);
5386 break;
5387 case 5: /* VBSL */
5388 tmp3 = neon_load_reg(rd, pass);
5389 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5390 tcg_temp_free_i32(tmp3);
5391 break;
5392 case 6: /* VBIT */
5393 tmp3 = neon_load_reg(rd, pass);
5394 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5395 tcg_temp_free_i32(tmp3);
5396 break;
5397 case 7: /* VBIF */
5398 tmp3 = neon_load_reg(rd, pass);
5399 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5400 tcg_temp_free_i32(tmp3);
5401 break;
5403 break;
5404 case NEON_3R_VHSUB:
5405 GEN_NEON_INTEGER_OP(hsub);
5406 break;
5407 case NEON_3R_VQSUB:
5408 GEN_NEON_INTEGER_OP_ENV(qsub);
5409 break;
5410 case NEON_3R_VCGT:
5411 GEN_NEON_INTEGER_OP(cgt);
5412 break;
5413 case NEON_3R_VCGE:
5414 GEN_NEON_INTEGER_OP(cge);
5415 break;
5416 case NEON_3R_VSHL:
5417 GEN_NEON_INTEGER_OP(shl);
5418 break;
5419 case NEON_3R_VQSHL:
5420 GEN_NEON_INTEGER_OP_ENV(qshl);
5421 break;
5422 case NEON_3R_VRSHL:
5423 GEN_NEON_INTEGER_OP(rshl);
5424 break;
5425 case NEON_3R_VQRSHL:
5426 GEN_NEON_INTEGER_OP_ENV(qrshl);
5427 break;
5428 case NEON_3R_VMAX:
5429 GEN_NEON_INTEGER_OP(max);
5430 break;
5431 case NEON_3R_VMIN:
5432 GEN_NEON_INTEGER_OP(min);
5433 break;
5434 case NEON_3R_VABD:
5435 GEN_NEON_INTEGER_OP(abd);
5436 break;
5437 case NEON_3R_VABA:
5438 GEN_NEON_INTEGER_OP(abd);
5439 tcg_temp_free_i32(tmp2);
5440 tmp2 = neon_load_reg(rd, pass);
5441 gen_neon_add(size, tmp, tmp2);
5442 break;
5443 case NEON_3R_VADD_VSUB:
5444 if (!u) { /* VADD */
5445 gen_neon_add(size, tmp, tmp2);
5446 } else { /* VSUB */
5447 switch (size) {
5448 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5449 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5450 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5451 default: abort();
5454 break;
5455 case NEON_3R_VTST_VCEQ:
5456 if (!u) { /* VTST */
5457 switch (size) {
5458 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5459 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5460 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5461 default: abort();
5463 } else { /* VCEQ */
5464 switch (size) {
5465 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5466 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5467 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5468 default: abort();
5471 break;
5472 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5473 switch (size) {
5474 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5475 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5476 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5477 default: abort();
5479 tcg_temp_free_i32(tmp2);
5480 tmp2 = neon_load_reg(rd, pass);
5481 if (u) { /* VMLS */
5482 gen_neon_rsb(size, tmp, tmp2);
5483 } else { /* VMLA */
5484 gen_neon_add(size, tmp, tmp2);
5486 break;
5487 case NEON_3R_VMUL:
5488 if (u) { /* polynomial */
5489 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5490 } else { /* Integer */
5491 switch (size) {
5492 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5493 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5494 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5495 default: abort();
5498 break;
5499 case NEON_3R_VPMAX:
5500 GEN_NEON_INTEGER_OP(pmax);
5501 break;
5502 case NEON_3R_VPMIN:
5503 GEN_NEON_INTEGER_OP(pmin);
5504 break;
5505 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5506 if (!u) { /* VQDMULH */
5507 switch (size) {
5508 case 1:
5509 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5510 break;
5511 case 2:
5512 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5513 break;
5514 default: abort();
5516 } else { /* VQRDMULH */
5517 switch (size) {
5518 case 1:
5519 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5520 break;
5521 case 2:
5522 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5523 break;
5524 default: abort();
5527 break;
5528 case NEON_3R_VPADD:
5529 switch (size) {
5530 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5531 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5532 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5533 default: abort();
5535 break;
5536 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5538 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5539 switch ((u << 2) | size) {
5540 case 0: /* VADD */
5541 case 4: /* VPADD */
5542 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5543 break;
5544 case 2: /* VSUB */
5545 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5546 break;
5547 case 6: /* VABD */
5548 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5549 break;
5550 default:
5551 abort();
5553 tcg_temp_free_ptr(fpstatus);
5554 break;
5556 case NEON_3R_FLOAT_MULTIPLY:
5558 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5559 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5560 if (!u) {
5561 tcg_temp_free_i32(tmp2);
5562 tmp2 = neon_load_reg(rd, pass);
5563 if (size == 0) {
5564 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5565 } else {
5566 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5569 tcg_temp_free_ptr(fpstatus);
5570 break;
5572 case NEON_3R_FLOAT_CMP:
5574 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5575 if (!u) {
5576 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5577 } else {
5578 if (size == 0) {
5579 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5580 } else {
5581 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5584 tcg_temp_free_ptr(fpstatus);
5585 break;
5587 case NEON_3R_FLOAT_ACMP:
5589 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5590 if (size == 0) {
5591 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5592 } else {
5593 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5595 tcg_temp_free_ptr(fpstatus);
5596 break;
5598 case NEON_3R_FLOAT_MINMAX:
5600 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5601 if (size == 0) {
5602 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5603 } else {
5604 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5606 tcg_temp_free_ptr(fpstatus);
5607 break;
5609 case NEON_3R_FLOAT_MISC:
5610 if (u) {
5611 /* VMAXNM/VMINNM */
5612 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5613 if (size == 0) {
5614 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5615 } else {
5616 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5618 tcg_temp_free_ptr(fpstatus);
5619 } else {
5620 if (size == 0) {
5621 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5622 } else {
5623 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5626 break;
5627 case NEON_3R_VFM:
5629 /* VFMA, VFMS: fused multiply-add */
5630 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5631 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5632 if (size) {
5633 /* VFMS */
5634 gen_helper_vfp_negs(tmp, tmp);
5636 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5637 tcg_temp_free_i32(tmp3);
5638 tcg_temp_free_ptr(fpstatus);
5639 break;
5641 default:
5642 abort();
5644 tcg_temp_free_i32(tmp2);
5646 /* Save the result. For elementwise operations we can put it
5647 straight into the destination register. For pairwise operations
5648 we have to be careful to avoid clobbering the source operands. */
5649 if (pairwise && rd == rm) {
5650 neon_store_scratch(pass, tmp);
5651 } else {
5652 neon_store_reg(rd, pass, tmp);
5655 } /* for pass */
5656 if (pairwise && rd == rm) {
5657 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5658 tmp = neon_load_scratch(pass);
5659 neon_store_reg(rd, pass, tmp);
5662 /* End of 3 register same size operations. */
5663 } else if (insn & (1 << 4)) {
5664 if ((insn & 0x00380080) != 0) {
5665 /* Two registers and shift. */
5666 op = (insn >> 8) & 0xf;
5667 if (insn & (1 << 7)) {
5668 /* 64-bit shift. */
5669 if (op > 7) {
5670 return 1;
5672 size = 3;
5673 } else {
5674 size = 2;
5675 while ((insn & (1 << (size + 19))) == 0)
5676 size--;
5678 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5679 /* To avoid excessive duplication of ops we implement shift
5680 by immediate using the variable shift operations. */
5681 if (op < 8) {
5682 /* Shift by immediate:
5683 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5684 if (q && ((rd | rm) & 1)) {
5685 return 1;
5687 if (!u && (op == 4 || op == 6)) {
5688 return 1;
5690 /* Right shifts are encoded as N - shift, where N is the
5691 element size in bits. */
5692 if (op <= 4)
5693 shift = shift - (1 << (size + 3));
5694 if (size == 3) {
5695 count = q + 1;
5696 } else {
5697 count = q ? 4: 2;
5699 switch (size) {
5700 case 0:
5701 imm = (uint8_t) shift;
5702 imm |= imm << 8;
5703 imm |= imm << 16;
5704 break;
5705 case 1:
5706 imm = (uint16_t) shift;
5707 imm |= imm << 16;
5708 break;
5709 case 2:
5710 case 3:
5711 imm = shift;
5712 break;
5713 default:
5714 abort();
5717 for (pass = 0; pass < count; pass++) {
5718 if (size == 3) {
5719 neon_load_reg64(cpu_V0, rm + pass);
5720 tcg_gen_movi_i64(cpu_V1, imm);
5721 switch (op) {
5722 case 0: /* VSHR */
5723 case 1: /* VSRA */
5724 if (u)
5725 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5726 else
5727 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5728 break;
5729 case 2: /* VRSHR */
5730 case 3: /* VRSRA */
5731 if (u)
5732 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5733 else
5734 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5735 break;
5736 case 4: /* VSRI */
5737 case 5: /* VSHL, VSLI */
5738 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5739 break;
5740 case 6: /* VQSHLU */
5741 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5742 cpu_V0, cpu_V1);
5743 break;
5744 case 7: /* VQSHL */
5745 if (u) {
5746 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5747 cpu_V0, cpu_V1);
5748 } else {
5749 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5750 cpu_V0, cpu_V1);
5752 break;
5754 if (op == 1 || op == 3) {
5755 /* Accumulate. */
5756 neon_load_reg64(cpu_V1, rd + pass);
5757 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5758 } else if (op == 4 || (op == 5 && u)) {
5759 /* Insert */
5760 neon_load_reg64(cpu_V1, rd + pass);
5761 uint64_t mask;
5762 if (shift < -63 || shift > 63) {
5763 mask = 0;
5764 } else {
5765 if (op == 4) {
5766 mask = 0xffffffffffffffffull >> -shift;
5767 } else {
5768 mask = 0xffffffffffffffffull << shift;
5771 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5772 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5774 neon_store_reg64(cpu_V0, rd + pass);
5775 } else { /* size < 3 */
5776 /* Operands in T0 and T1. */
5777 tmp = neon_load_reg(rm, pass);
5778 tmp2 = tcg_temp_new_i32();
5779 tcg_gen_movi_i32(tmp2, imm);
5780 switch (op) {
5781 case 0: /* VSHR */
5782 case 1: /* VSRA */
5783 GEN_NEON_INTEGER_OP(shl);
5784 break;
5785 case 2: /* VRSHR */
5786 case 3: /* VRSRA */
5787 GEN_NEON_INTEGER_OP(rshl);
5788 break;
5789 case 4: /* VSRI */
5790 case 5: /* VSHL, VSLI */
5791 switch (size) {
5792 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5793 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5794 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5795 default: abort();
5797 break;
5798 case 6: /* VQSHLU */
5799 switch (size) {
5800 case 0:
5801 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5802 tmp, tmp2);
5803 break;
5804 case 1:
5805 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5806 tmp, tmp2);
5807 break;
5808 case 2:
5809 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5810 tmp, tmp2);
5811 break;
5812 default:
5813 abort();
5815 break;
5816 case 7: /* VQSHL */
5817 GEN_NEON_INTEGER_OP_ENV(qshl);
5818 break;
5820 tcg_temp_free_i32(tmp2);
5822 if (op == 1 || op == 3) {
5823 /* Accumulate. */
5824 tmp2 = neon_load_reg(rd, pass);
5825 gen_neon_add(size, tmp, tmp2);
5826 tcg_temp_free_i32(tmp2);
5827 } else if (op == 4 || (op == 5 && u)) {
5828 /* Insert */
5829 switch (size) {
5830 case 0:
5831 if (op == 4)
5832 mask = 0xff >> -shift;
5833 else
5834 mask = (uint8_t)(0xff << shift);
5835 mask |= mask << 8;
5836 mask |= mask << 16;
5837 break;
5838 case 1:
5839 if (op == 4)
5840 mask = 0xffff >> -shift;
5841 else
5842 mask = (uint16_t)(0xffff << shift);
5843 mask |= mask << 16;
5844 break;
5845 case 2:
5846 if (shift < -31 || shift > 31) {
5847 mask = 0;
5848 } else {
5849 if (op == 4)
5850 mask = 0xffffffffu >> -shift;
5851 else
5852 mask = 0xffffffffu << shift;
5854 break;
5855 default:
5856 abort();
5858 tmp2 = neon_load_reg(rd, pass);
5859 tcg_gen_andi_i32(tmp, tmp, mask);
5860 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5861 tcg_gen_or_i32(tmp, tmp, tmp2);
5862 tcg_temp_free_i32(tmp2);
5864 neon_store_reg(rd, pass, tmp);
5866 } /* for pass */
5867 } else if (op < 10) {
5868 /* Shift by immediate and narrow:
5869 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5870 int input_unsigned = (op == 8) ? !u : u;
5871 if (rm & 1) {
5872 return 1;
5874 shift = shift - (1 << (size + 3));
5875 size++;
5876 if (size == 3) {
5877 tmp64 = tcg_const_i64(shift);
5878 neon_load_reg64(cpu_V0, rm);
5879 neon_load_reg64(cpu_V1, rm + 1);
5880 for (pass = 0; pass < 2; pass++) {
5881 TCGv_i64 in;
5882 if (pass == 0) {
5883 in = cpu_V0;
5884 } else {
5885 in = cpu_V1;
5887 if (q) {
5888 if (input_unsigned) {
5889 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5890 } else {
5891 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5893 } else {
5894 if (input_unsigned) {
5895 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5896 } else {
5897 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5900 tmp = tcg_temp_new_i32();
5901 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5902 neon_store_reg(rd, pass, tmp);
5903 } /* for pass */
5904 tcg_temp_free_i64(tmp64);
5905 } else {
5906 if (size == 1) {
5907 imm = (uint16_t)shift;
5908 imm |= imm << 16;
5909 } else {
5910 /* size == 2 */
5911 imm = (uint32_t)shift;
5913 tmp2 = tcg_const_i32(imm);
5914 tmp4 = neon_load_reg(rm + 1, 0);
5915 tmp5 = neon_load_reg(rm + 1, 1);
5916 for (pass = 0; pass < 2; pass++) {
5917 if (pass == 0) {
5918 tmp = neon_load_reg(rm, 0);
5919 } else {
5920 tmp = tmp4;
5922 gen_neon_shift_narrow(size, tmp, tmp2, q,
5923 input_unsigned);
5924 if (pass == 0) {
5925 tmp3 = neon_load_reg(rm, 1);
5926 } else {
5927 tmp3 = tmp5;
5929 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5930 input_unsigned);
5931 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5932 tcg_temp_free_i32(tmp);
5933 tcg_temp_free_i32(tmp3);
5934 tmp = tcg_temp_new_i32();
5935 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5936 neon_store_reg(rd, pass, tmp);
5937 } /* for pass */
5938 tcg_temp_free_i32(tmp2);
5940 } else if (op == 10) {
5941 /* VSHLL, VMOVL */
5942 if (q || (rd & 1)) {
5943 return 1;
5945 tmp = neon_load_reg(rm, 0);
5946 tmp2 = neon_load_reg(rm, 1);
5947 for (pass = 0; pass < 2; pass++) {
5948 if (pass == 1)
5949 tmp = tmp2;
5951 gen_neon_widen(cpu_V0, tmp, size, u);
5953 if (shift != 0) {
5954 /* The shift is less than the width of the source
5955 type, so we can just shift the whole register. */
5956 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5957 /* Widen the result of shift: we need to clear
5958 * the potential overflow bits resulting from
5959 * left bits of the narrow input appearing as
5960 * right bits of left the neighbour narrow
5961 * input. */
5962 if (size < 2 || !u) {
5963 uint64_t imm64;
5964 if (size == 0) {
5965 imm = (0xffu >> (8 - shift));
5966 imm |= imm << 16;
5967 } else if (size == 1) {
5968 imm = 0xffff >> (16 - shift);
5969 } else {
5970 /* size == 2 */
5971 imm = 0xffffffff >> (32 - shift);
5973 if (size < 2) {
5974 imm64 = imm | (((uint64_t)imm) << 32);
5975 } else {
5976 imm64 = imm;
5978 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5981 neon_store_reg64(cpu_V0, rd + pass);
5983 } else if (op >= 14) {
5984 /* VCVT fixed-point. */
5985 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5986 return 1;
5988 /* We have already masked out the must-be-1 top bit of imm6,
5989 * hence this 32-shift where the ARM ARM has 64-imm6.
5991 shift = 32 - shift;
5992 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5993 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5994 if (!(op & 1)) {
5995 if (u)
5996 gen_vfp_ulto(0, shift, 1);
5997 else
5998 gen_vfp_slto(0, shift, 1);
5999 } else {
6000 if (u)
6001 gen_vfp_toul(0, shift, 1);
6002 else
6003 gen_vfp_tosl(0, shift, 1);
6005 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6007 } else {
6008 return 1;
6010 } else { /* (insn & 0x00380080) == 0 */
6011 int invert;
6012 if (q && (rd & 1)) {
6013 return 1;
6016 op = (insn >> 8) & 0xf;
6017 /* One register and immediate. */
6018 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6019 invert = (insn & (1 << 5)) != 0;
6020 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6021 * We choose to not special-case this and will behave as if a
6022 * valid constant encoding of 0 had been given.
6024 switch (op) {
6025 case 0: case 1:
6026 /* no-op */
6027 break;
6028 case 2: case 3:
6029 imm <<= 8;
6030 break;
6031 case 4: case 5:
6032 imm <<= 16;
6033 break;
6034 case 6: case 7:
6035 imm <<= 24;
6036 break;
6037 case 8: case 9:
6038 imm |= imm << 16;
6039 break;
6040 case 10: case 11:
6041 imm = (imm << 8) | (imm << 24);
6042 break;
6043 case 12:
6044 imm = (imm << 8) | 0xff;
6045 break;
6046 case 13:
6047 imm = (imm << 16) | 0xffff;
6048 break;
6049 case 14:
6050 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6051 if (invert)
6052 imm = ~imm;
6053 break;
6054 case 15:
6055 if (invert) {
6056 return 1;
6058 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6059 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6060 break;
6062 if (invert)
6063 imm = ~imm;
6065 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6066 if (op & 1 && op < 12) {
6067 tmp = neon_load_reg(rd, pass);
6068 if (invert) {
6069 /* The immediate value has already been inverted, so
6070 BIC becomes AND. */
6071 tcg_gen_andi_i32(tmp, tmp, imm);
6072 } else {
6073 tcg_gen_ori_i32(tmp, tmp, imm);
6075 } else {
6076 /* VMOV, VMVN. */
6077 tmp = tcg_temp_new_i32();
6078 if (op == 14 && invert) {
6079 int n;
6080 uint32_t val;
6081 val = 0;
6082 for (n = 0; n < 4; n++) {
6083 if (imm & (1 << (n + (pass & 1) * 4)))
6084 val |= 0xff << (n * 8);
6086 tcg_gen_movi_i32(tmp, val);
6087 } else {
6088 tcg_gen_movi_i32(tmp, imm);
6091 neon_store_reg(rd, pass, tmp);
6094 } else { /* (insn & 0x00800010 == 0x00800000) */
6095 if (size != 3) {
6096 op = (insn >> 8) & 0xf;
6097 if ((insn & (1 << 6)) == 0) {
6098 /* Three registers of different lengths. */
6099 int src1_wide;
6100 int src2_wide;
6101 int prewiden;
6102 /* undefreq: bit 0 : UNDEF if size == 0
6103 * bit 1 : UNDEF if size == 1
6104 * bit 2 : UNDEF if size == 2
6105 * bit 3 : UNDEF if U == 1
6106 * Note that [2:0] set implies 'always UNDEF'
6108 int undefreq;
6109 /* prewiden, src1_wide, src2_wide, undefreq */
6110 static const int neon_3reg_wide[16][4] = {
6111 {1, 0, 0, 0}, /* VADDL */
6112 {1, 1, 0, 0}, /* VADDW */
6113 {1, 0, 0, 0}, /* VSUBL */
6114 {1, 1, 0, 0}, /* VSUBW */
6115 {0, 1, 1, 0}, /* VADDHN */
6116 {0, 0, 0, 0}, /* VABAL */
6117 {0, 1, 1, 0}, /* VSUBHN */
6118 {0, 0, 0, 0}, /* VABDL */
6119 {0, 0, 0, 0}, /* VMLAL */
6120 {0, 0, 0, 9}, /* VQDMLAL */
6121 {0, 0, 0, 0}, /* VMLSL */
6122 {0, 0, 0, 9}, /* VQDMLSL */
6123 {0, 0, 0, 0}, /* Integer VMULL */
6124 {0, 0, 0, 1}, /* VQDMULL */
6125 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6126 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6129 prewiden = neon_3reg_wide[op][0];
6130 src1_wide = neon_3reg_wide[op][1];
6131 src2_wide = neon_3reg_wide[op][2];
6132 undefreq = neon_3reg_wide[op][3];
6134 if ((undefreq & (1 << size)) ||
6135 ((undefreq & 8) && u)) {
6136 return 1;
6138 if ((src1_wide && (rn & 1)) ||
6139 (src2_wide && (rm & 1)) ||
6140 (!src2_wide && (rd & 1))) {
6141 return 1;
6144 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6145 * outside the loop below as it only performs a single pass.
6147 if (op == 14 && size == 2) {
6148 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6150 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6151 return 1;
6153 tcg_rn = tcg_temp_new_i64();
6154 tcg_rm = tcg_temp_new_i64();
6155 tcg_rd = tcg_temp_new_i64();
6156 neon_load_reg64(tcg_rn, rn);
6157 neon_load_reg64(tcg_rm, rm);
6158 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6159 neon_store_reg64(tcg_rd, rd);
6160 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6161 neon_store_reg64(tcg_rd, rd + 1);
6162 tcg_temp_free_i64(tcg_rn);
6163 tcg_temp_free_i64(tcg_rm);
6164 tcg_temp_free_i64(tcg_rd);
6165 return 0;
6168 /* Avoid overlapping operands. Wide source operands are
6169 always aligned so will never overlap with wide
6170 destinations in problematic ways. */
6171 if (rd == rm && !src2_wide) {
6172 tmp = neon_load_reg(rm, 1);
6173 neon_store_scratch(2, tmp);
6174 } else if (rd == rn && !src1_wide) {
6175 tmp = neon_load_reg(rn, 1);
6176 neon_store_scratch(2, tmp);
6178 TCGV_UNUSED_I32(tmp3);
6179 for (pass = 0; pass < 2; pass++) {
6180 if (src1_wide) {
6181 neon_load_reg64(cpu_V0, rn + pass);
6182 TCGV_UNUSED_I32(tmp);
6183 } else {
6184 if (pass == 1 && rd == rn) {
6185 tmp = neon_load_scratch(2);
6186 } else {
6187 tmp = neon_load_reg(rn, pass);
6189 if (prewiden) {
6190 gen_neon_widen(cpu_V0, tmp, size, u);
6193 if (src2_wide) {
6194 neon_load_reg64(cpu_V1, rm + pass);
6195 TCGV_UNUSED_I32(tmp2);
6196 } else {
6197 if (pass == 1 && rd == rm) {
6198 tmp2 = neon_load_scratch(2);
6199 } else {
6200 tmp2 = neon_load_reg(rm, pass);
6202 if (prewiden) {
6203 gen_neon_widen(cpu_V1, tmp2, size, u);
6206 switch (op) {
6207 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6208 gen_neon_addl(size);
6209 break;
6210 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6211 gen_neon_subl(size);
6212 break;
6213 case 5: case 7: /* VABAL, VABDL */
6214 switch ((size << 1) | u) {
6215 case 0:
6216 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6217 break;
6218 case 1:
6219 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6220 break;
6221 case 2:
6222 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6223 break;
6224 case 3:
6225 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6226 break;
6227 case 4:
6228 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6229 break;
6230 case 5:
6231 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6232 break;
6233 default: abort();
6235 tcg_temp_free_i32(tmp2);
6236 tcg_temp_free_i32(tmp);
6237 break;
6238 case 8: case 9: case 10: case 11: case 12: case 13:
6239 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6240 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6241 break;
6242 case 14: /* Polynomial VMULL */
6243 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6244 tcg_temp_free_i32(tmp2);
6245 tcg_temp_free_i32(tmp);
6246 break;
6247 default: /* 15 is RESERVED: caught earlier */
6248 abort();
6250 if (op == 13) {
6251 /* VQDMULL */
6252 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6253 neon_store_reg64(cpu_V0, rd + pass);
6254 } else if (op == 5 || (op >= 8 && op <= 11)) {
6255 /* Accumulate. */
6256 neon_load_reg64(cpu_V1, rd + pass);
6257 switch (op) {
6258 case 10: /* VMLSL */
6259 gen_neon_negl(cpu_V0, size);
6260 /* Fall through */
6261 case 5: case 8: /* VABAL, VMLAL */
6262 gen_neon_addl(size);
6263 break;
6264 case 9: case 11: /* VQDMLAL, VQDMLSL */
6265 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6266 if (op == 11) {
6267 gen_neon_negl(cpu_V0, size);
6269 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6270 break;
6271 default:
6272 abort();
6274 neon_store_reg64(cpu_V0, rd + pass);
6275 } else if (op == 4 || op == 6) {
6276 /* Narrowing operation. */
6277 tmp = tcg_temp_new_i32();
6278 if (!u) {
6279 switch (size) {
6280 case 0:
6281 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6282 break;
6283 case 1:
6284 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6285 break;
6286 case 2:
6287 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6288 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6289 break;
6290 default: abort();
6292 } else {
6293 switch (size) {
6294 case 0:
6295 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6296 break;
6297 case 1:
6298 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6299 break;
6300 case 2:
6301 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6302 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6303 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6304 break;
6305 default: abort();
6308 if (pass == 0) {
6309 tmp3 = tmp;
6310 } else {
6311 neon_store_reg(rd, 0, tmp3);
6312 neon_store_reg(rd, 1, tmp);
6314 } else {
6315 /* Write back the result. */
6316 neon_store_reg64(cpu_V0, rd + pass);
6319 } else {
6320 /* Two registers and a scalar. NB that for ops of this form
6321 * the ARM ARM labels bit 24 as Q, but it is in our variable
6322 * 'u', not 'q'.
6324 if (size == 0) {
6325 return 1;
6327 switch (op) {
6328 case 1: /* Float VMLA scalar */
6329 case 5: /* Floating point VMLS scalar */
6330 case 9: /* Floating point VMUL scalar */
6331 if (size == 1) {
6332 return 1;
6334 /* fall through */
6335 case 0: /* Integer VMLA scalar */
6336 case 4: /* Integer VMLS scalar */
6337 case 8: /* Integer VMUL scalar */
6338 case 12: /* VQDMULH scalar */
6339 case 13: /* VQRDMULH scalar */
6340 if (u && ((rd | rn) & 1)) {
6341 return 1;
6343 tmp = neon_get_scalar(size, rm);
6344 neon_store_scratch(0, tmp);
6345 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6346 tmp = neon_load_scratch(0);
6347 tmp2 = neon_load_reg(rn, pass);
6348 if (op == 12) {
6349 if (size == 1) {
6350 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6351 } else {
6352 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6354 } else if (op == 13) {
6355 if (size == 1) {
6356 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6357 } else {
6358 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6360 } else if (op & 1) {
6361 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6362 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6363 tcg_temp_free_ptr(fpstatus);
6364 } else {
6365 switch (size) {
6366 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6367 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6368 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6369 default: abort();
6372 tcg_temp_free_i32(tmp2);
6373 if (op < 8) {
6374 /* Accumulate. */
6375 tmp2 = neon_load_reg(rd, pass);
6376 switch (op) {
6377 case 0:
6378 gen_neon_add(size, tmp, tmp2);
6379 break;
6380 case 1:
6382 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6383 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6384 tcg_temp_free_ptr(fpstatus);
6385 break;
6387 case 4:
6388 gen_neon_rsb(size, tmp, tmp2);
6389 break;
6390 case 5:
6392 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6393 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6394 tcg_temp_free_ptr(fpstatus);
6395 break;
6397 default:
6398 abort();
6400 tcg_temp_free_i32(tmp2);
6402 neon_store_reg(rd, pass, tmp);
6404 break;
6405 case 3: /* VQDMLAL scalar */
6406 case 7: /* VQDMLSL scalar */
6407 case 11: /* VQDMULL scalar */
6408 if (u == 1) {
6409 return 1;
6411 /* fall through */
6412 case 2: /* VMLAL sclar */
6413 case 6: /* VMLSL scalar */
6414 case 10: /* VMULL scalar */
6415 if (rd & 1) {
6416 return 1;
6418 tmp2 = neon_get_scalar(size, rm);
6419 /* We need a copy of tmp2 because gen_neon_mull
6420 * deletes it during pass 0. */
6421 tmp4 = tcg_temp_new_i32();
6422 tcg_gen_mov_i32(tmp4, tmp2);
6423 tmp3 = neon_load_reg(rn, 1);
6425 for (pass = 0; pass < 2; pass++) {
6426 if (pass == 0) {
6427 tmp = neon_load_reg(rn, 0);
6428 } else {
6429 tmp = tmp3;
6430 tmp2 = tmp4;
6432 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6433 if (op != 11) {
6434 neon_load_reg64(cpu_V1, rd + pass);
6436 switch (op) {
6437 case 6:
6438 gen_neon_negl(cpu_V0, size);
6439 /* Fall through */
6440 case 2:
6441 gen_neon_addl(size);
6442 break;
6443 case 3: case 7:
6444 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6445 if (op == 7) {
6446 gen_neon_negl(cpu_V0, size);
6448 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6449 break;
6450 case 10:
6451 /* no-op */
6452 break;
6453 case 11:
6454 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6455 break;
6456 default:
6457 abort();
6459 neon_store_reg64(cpu_V0, rd + pass);
6463 break;
6464 default: /* 14 and 15 are RESERVED */
6465 return 1;
6468 } else { /* size == 3 */
6469 if (!u) {
6470 /* Extract. */
6471 imm = (insn >> 8) & 0xf;
6473 if (imm > 7 && !q)
6474 return 1;
6476 if (q && ((rd | rn | rm) & 1)) {
6477 return 1;
6480 if (imm == 0) {
6481 neon_load_reg64(cpu_V0, rn);
6482 if (q) {
6483 neon_load_reg64(cpu_V1, rn + 1);
6485 } else if (imm == 8) {
6486 neon_load_reg64(cpu_V0, rn + 1);
6487 if (q) {
6488 neon_load_reg64(cpu_V1, rm);
6490 } else if (q) {
6491 tmp64 = tcg_temp_new_i64();
6492 if (imm < 8) {
6493 neon_load_reg64(cpu_V0, rn);
6494 neon_load_reg64(tmp64, rn + 1);
6495 } else {
6496 neon_load_reg64(cpu_V0, rn + 1);
6497 neon_load_reg64(tmp64, rm);
6499 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6500 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6501 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6502 if (imm < 8) {
6503 neon_load_reg64(cpu_V1, rm);
6504 } else {
6505 neon_load_reg64(cpu_V1, rm + 1);
6506 imm -= 8;
6508 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6509 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6510 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6511 tcg_temp_free_i64(tmp64);
6512 } else {
6513 /* BUGFIX */
6514 neon_load_reg64(cpu_V0, rn);
6515 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6516 neon_load_reg64(cpu_V1, rm);
6517 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6518 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6520 neon_store_reg64(cpu_V0, rd);
6521 if (q) {
6522 neon_store_reg64(cpu_V1, rd + 1);
6524 } else if ((insn & (1 << 11)) == 0) {
6525 /* Two register misc. */
6526 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6527 size = (insn >> 18) & 3;
6528 /* UNDEF for unknown op values and bad op-size combinations */
6529 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6530 return 1;
6532 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6533 q && ((rm | rd) & 1)) {
6534 return 1;
6536 switch (op) {
6537 case NEON_2RM_VREV64:
6538 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6539 tmp = neon_load_reg(rm, pass * 2);
6540 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6541 switch (size) {
6542 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6543 case 1: gen_swap_half(tmp); break;
6544 case 2: /* no-op */ break;
6545 default: abort();
6547 neon_store_reg(rd, pass * 2 + 1, tmp);
6548 if (size == 2) {
6549 neon_store_reg(rd, pass * 2, tmp2);
6550 } else {
6551 switch (size) {
6552 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6553 case 1: gen_swap_half(tmp2); break;
6554 default: abort();
6556 neon_store_reg(rd, pass * 2, tmp2);
6559 break;
6560 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6561 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6562 for (pass = 0; pass < q + 1; pass++) {
6563 tmp = neon_load_reg(rm, pass * 2);
6564 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6565 tmp = neon_load_reg(rm, pass * 2 + 1);
6566 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6567 switch (size) {
6568 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6569 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6570 case 2: tcg_gen_add_i64(CPU_V001); break;
6571 default: abort();
6573 if (op >= NEON_2RM_VPADAL) {
6574 /* Accumulate. */
6575 neon_load_reg64(cpu_V1, rd + pass);
6576 gen_neon_addl(size);
6578 neon_store_reg64(cpu_V0, rd + pass);
6580 break;
6581 case NEON_2RM_VTRN:
6582 if (size == 2) {
6583 int n;
6584 for (n = 0; n < (q ? 4 : 2); n += 2) {
6585 tmp = neon_load_reg(rm, n);
6586 tmp2 = neon_load_reg(rd, n + 1);
6587 neon_store_reg(rm, n, tmp2);
6588 neon_store_reg(rd, n + 1, tmp);
6590 } else {
6591 goto elementwise;
6593 break;
6594 case NEON_2RM_VUZP:
6595 if (gen_neon_unzip(rd, rm, size, q)) {
6596 return 1;
6598 break;
6599 case NEON_2RM_VZIP:
6600 if (gen_neon_zip(rd, rm, size, q)) {
6601 return 1;
6603 break;
6604 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6605 /* also VQMOVUN; op field and mnemonics don't line up */
6606 if (rm & 1) {
6607 return 1;
6609 TCGV_UNUSED_I32(tmp2);
6610 for (pass = 0; pass < 2; pass++) {
6611 neon_load_reg64(cpu_V0, rm + pass);
6612 tmp = tcg_temp_new_i32();
6613 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6614 tmp, cpu_V0);
6615 if (pass == 0) {
6616 tmp2 = tmp;
6617 } else {
6618 neon_store_reg(rd, 0, tmp2);
6619 neon_store_reg(rd, 1, tmp);
6622 break;
6623 case NEON_2RM_VSHLL:
6624 if (q || (rd & 1)) {
6625 return 1;
6627 tmp = neon_load_reg(rm, 0);
6628 tmp2 = neon_load_reg(rm, 1);
6629 for (pass = 0; pass < 2; pass++) {
6630 if (pass == 1)
6631 tmp = tmp2;
6632 gen_neon_widen(cpu_V0, tmp, size, 1);
6633 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6634 neon_store_reg64(cpu_V0, rd + pass);
6636 break;
6637 case NEON_2RM_VCVT_F16_F32:
6638 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6639 q || (rm & 1)) {
6640 return 1;
6642 tmp = tcg_temp_new_i32();
6643 tmp2 = tcg_temp_new_i32();
6644 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6645 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6646 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6647 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6648 tcg_gen_shli_i32(tmp2, tmp2, 16);
6649 tcg_gen_or_i32(tmp2, tmp2, tmp);
6650 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6651 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6652 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6653 neon_store_reg(rd, 0, tmp2);
6654 tmp2 = tcg_temp_new_i32();
6655 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6656 tcg_gen_shli_i32(tmp2, tmp2, 16);
6657 tcg_gen_or_i32(tmp2, tmp2, tmp);
6658 neon_store_reg(rd, 1, tmp2);
6659 tcg_temp_free_i32(tmp);
6660 break;
6661 case NEON_2RM_VCVT_F32_F16:
6662 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6663 q || (rd & 1)) {
6664 return 1;
6666 tmp3 = tcg_temp_new_i32();
6667 tmp = neon_load_reg(rm, 0);
6668 tmp2 = neon_load_reg(rm, 1);
6669 tcg_gen_ext16u_i32(tmp3, tmp);
6670 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6671 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6672 tcg_gen_shri_i32(tmp3, tmp, 16);
6673 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6674 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6675 tcg_temp_free_i32(tmp);
6676 tcg_gen_ext16u_i32(tmp3, tmp2);
6677 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6678 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6679 tcg_gen_shri_i32(tmp3, tmp2, 16);
6680 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6681 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6682 tcg_temp_free_i32(tmp2);
6683 tcg_temp_free_i32(tmp3);
6684 break;
6685 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6686 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6687 || ((rm | rd) & 1)) {
6688 return 1;
6690 tmp = tcg_const_i32(rd);
6691 tmp2 = tcg_const_i32(rm);
6693 /* Bit 6 is the lowest opcode bit; it distinguishes between
6694 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6696 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6698 if (op == NEON_2RM_AESE) {
6699 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6700 } else {
6701 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6703 tcg_temp_free_i32(tmp);
6704 tcg_temp_free_i32(tmp2);
6705 tcg_temp_free_i32(tmp3);
6706 break;
6707 case NEON_2RM_SHA1H:
6708 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
6709 || ((rm | rd) & 1)) {
6710 return 1;
6712 tmp = tcg_const_i32(rd);
6713 tmp2 = tcg_const_i32(rm);
6715 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
6717 tcg_temp_free_i32(tmp);
6718 tcg_temp_free_i32(tmp2);
6719 break;
6720 case NEON_2RM_SHA1SU1:
6721 if ((rm | rd) & 1) {
6722 return 1;
6724 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6725 if (q) {
6726 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
6727 return 1;
6729 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
6730 return 1;
6732 tmp = tcg_const_i32(rd);
6733 tmp2 = tcg_const_i32(rm);
6734 if (q) {
6735 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
6736 } else {
6737 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
6739 tcg_temp_free_i32(tmp);
6740 tcg_temp_free_i32(tmp2);
6741 break;
6742 default:
6743 elementwise:
6744 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6745 if (neon_2rm_is_float_op(op)) {
6746 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6747 neon_reg_offset(rm, pass));
6748 TCGV_UNUSED_I32(tmp);
6749 } else {
6750 tmp = neon_load_reg(rm, pass);
6752 switch (op) {
6753 case NEON_2RM_VREV32:
6754 switch (size) {
6755 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6756 case 1: gen_swap_half(tmp); break;
6757 default: abort();
6759 break;
6760 case NEON_2RM_VREV16:
6761 gen_rev16(tmp);
6762 break;
6763 case NEON_2RM_VCLS:
6764 switch (size) {
6765 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6766 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6767 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6768 default: abort();
6770 break;
6771 case NEON_2RM_VCLZ:
6772 switch (size) {
6773 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6774 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6775 case 2: gen_helper_clz(tmp, tmp); break;
6776 default: abort();
6778 break;
6779 case NEON_2RM_VCNT:
6780 gen_helper_neon_cnt_u8(tmp, tmp);
6781 break;
6782 case NEON_2RM_VMVN:
6783 tcg_gen_not_i32(tmp, tmp);
6784 break;
6785 case NEON_2RM_VQABS:
6786 switch (size) {
6787 case 0:
6788 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6789 break;
6790 case 1:
6791 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6792 break;
6793 case 2:
6794 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6795 break;
6796 default: abort();
6798 break;
6799 case NEON_2RM_VQNEG:
6800 switch (size) {
6801 case 0:
6802 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6803 break;
6804 case 1:
6805 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6806 break;
6807 case 2:
6808 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6809 break;
6810 default: abort();
6812 break;
6813 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6814 tmp2 = tcg_const_i32(0);
6815 switch(size) {
6816 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6817 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6818 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6819 default: abort();
6821 tcg_temp_free_i32(tmp2);
6822 if (op == NEON_2RM_VCLE0) {
6823 tcg_gen_not_i32(tmp, tmp);
6825 break;
6826 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6827 tmp2 = tcg_const_i32(0);
6828 switch(size) {
6829 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6830 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6831 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6832 default: abort();
6834 tcg_temp_free_i32(tmp2);
6835 if (op == NEON_2RM_VCLT0) {
6836 tcg_gen_not_i32(tmp, tmp);
6838 break;
6839 case NEON_2RM_VCEQ0:
6840 tmp2 = tcg_const_i32(0);
6841 switch(size) {
6842 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6843 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6844 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6845 default: abort();
6847 tcg_temp_free_i32(tmp2);
6848 break;
6849 case NEON_2RM_VABS:
6850 switch(size) {
6851 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6852 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6853 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6854 default: abort();
6856 break;
6857 case NEON_2RM_VNEG:
6858 tmp2 = tcg_const_i32(0);
6859 gen_neon_rsb(size, tmp, tmp2);
6860 tcg_temp_free_i32(tmp2);
6861 break;
6862 case NEON_2RM_VCGT0_F:
6864 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6865 tmp2 = tcg_const_i32(0);
6866 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6867 tcg_temp_free_i32(tmp2);
6868 tcg_temp_free_ptr(fpstatus);
6869 break;
6871 case NEON_2RM_VCGE0_F:
6873 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6874 tmp2 = tcg_const_i32(0);
6875 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6876 tcg_temp_free_i32(tmp2);
6877 tcg_temp_free_ptr(fpstatus);
6878 break;
6880 case NEON_2RM_VCEQ0_F:
6882 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6883 tmp2 = tcg_const_i32(0);
6884 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6885 tcg_temp_free_i32(tmp2);
6886 tcg_temp_free_ptr(fpstatus);
6887 break;
6889 case NEON_2RM_VCLE0_F:
6891 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6892 tmp2 = tcg_const_i32(0);
6893 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6894 tcg_temp_free_i32(tmp2);
6895 tcg_temp_free_ptr(fpstatus);
6896 break;
6898 case NEON_2RM_VCLT0_F:
6900 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6901 tmp2 = tcg_const_i32(0);
6902 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6903 tcg_temp_free_i32(tmp2);
6904 tcg_temp_free_ptr(fpstatus);
6905 break;
6907 case NEON_2RM_VABS_F:
6908 gen_vfp_abs(0);
6909 break;
6910 case NEON_2RM_VNEG_F:
6911 gen_vfp_neg(0);
6912 break;
6913 case NEON_2RM_VSWP:
6914 tmp2 = neon_load_reg(rd, pass);
6915 neon_store_reg(rm, pass, tmp2);
6916 break;
6917 case NEON_2RM_VTRN:
6918 tmp2 = neon_load_reg(rd, pass);
6919 switch (size) {
6920 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6921 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6922 default: abort();
6924 neon_store_reg(rm, pass, tmp2);
6925 break;
6926 case NEON_2RM_VRINTN:
6927 case NEON_2RM_VRINTA:
6928 case NEON_2RM_VRINTM:
6929 case NEON_2RM_VRINTP:
6930 case NEON_2RM_VRINTZ:
6932 TCGv_i32 tcg_rmode;
6933 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6934 int rmode;
6936 if (op == NEON_2RM_VRINTZ) {
6937 rmode = FPROUNDING_ZERO;
6938 } else {
6939 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6942 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6943 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6944 cpu_env);
6945 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6946 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6947 cpu_env);
6948 tcg_temp_free_ptr(fpstatus);
6949 tcg_temp_free_i32(tcg_rmode);
6950 break;
6952 case NEON_2RM_VRINTX:
6954 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6955 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6956 tcg_temp_free_ptr(fpstatus);
6957 break;
6959 case NEON_2RM_VCVTAU:
6960 case NEON_2RM_VCVTAS:
6961 case NEON_2RM_VCVTNU:
6962 case NEON_2RM_VCVTNS:
6963 case NEON_2RM_VCVTPU:
6964 case NEON_2RM_VCVTPS:
6965 case NEON_2RM_VCVTMU:
6966 case NEON_2RM_VCVTMS:
6968 bool is_signed = !extract32(insn, 7, 1);
6969 TCGv_ptr fpst = get_fpstatus_ptr(1);
6970 TCGv_i32 tcg_rmode, tcg_shift;
6971 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6973 tcg_shift = tcg_const_i32(0);
6974 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6975 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6976 cpu_env);
6978 if (is_signed) {
6979 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6980 tcg_shift, fpst);
6981 } else {
6982 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6983 tcg_shift, fpst);
6986 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6987 cpu_env);
6988 tcg_temp_free_i32(tcg_rmode);
6989 tcg_temp_free_i32(tcg_shift);
6990 tcg_temp_free_ptr(fpst);
6991 break;
6993 case NEON_2RM_VRECPE:
6995 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6996 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6997 tcg_temp_free_ptr(fpstatus);
6998 break;
7000 case NEON_2RM_VRSQRTE:
7002 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7003 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7004 tcg_temp_free_ptr(fpstatus);
7005 break;
7007 case NEON_2RM_VRECPE_F:
7009 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7010 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7011 tcg_temp_free_ptr(fpstatus);
7012 break;
7014 case NEON_2RM_VRSQRTE_F:
7016 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7017 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7018 tcg_temp_free_ptr(fpstatus);
7019 break;
7021 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7022 gen_vfp_sito(0, 1);
7023 break;
7024 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7025 gen_vfp_uito(0, 1);
7026 break;
7027 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7028 gen_vfp_tosiz(0, 1);
7029 break;
7030 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7031 gen_vfp_touiz(0, 1);
7032 break;
7033 default:
7034 /* Reserved op values were caught by the
7035 * neon_2rm_sizes[] check earlier.
7037 abort();
7039 if (neon_2rm_is_float_op(op)) {
7040 tcg_gen_st_f32(cpu_F0s, cpu_env,
7041 neon_reg_offset(rd, pass));
7042 } else {
7043 neon_store_reg(rd, pass, tmp);
7046 break;
7048 } else if ((insn & (1 << 10)) == 0) {
7049 /* VTBL, VTBX. */
7050 int n = ((insn >> 8) & 3) + 1;
7051 if ((rn + n) > 32) {
7052 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7053 * helper function running off the end of the register file.
7055 return 1;
7057 n <<= 3;
7058 if (insn & (1 << 6)) {
7059 tmp = neon_load_reg(rd, 0);
7060 } else {
7061 tmp = tcg_temp_new_i32();
7062 tcg_gen_movi_i32(tmp, 0);
7064 tmp2 = neon_load_reg(rm, 0);
7065 tmp4 = tcg_const_i32(rn);
7066 tmp5 = tcg_const_i32(n);
7067 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7068 tcg_temp_free_i32(tmp);
7069 if (insn & (1 << 6)) {
7070 tmp = neon_load_reg(rd, 1);
7071 } else {
7072 tmp = tcg_temp_new_i32();
7073 tcg_gen_movi_i32(tmp, 0);
7075 tmp3 = neon_load_reg(rm, 1);
7076 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7077 tcg_temp_free_i32(tmp5);
7078 tcg_temp_free_i32(tmp4);
7079 neon_store_reg(rd, 0, tmp2);
7080 neon_store_reg(rd, 1, tmp3);
7081 tcg_temp_free_i32(tmp);
7082 } else if ((insn & 0x380) == 0) {
7083 /* VDUP */
7084 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7085 return 1;
7087 if (insn & (1 << 19)) {
7088 tmp = neon_load_reg(rm, 1);
7089 } else {
7090 tmp = neon_load_reg(rm, 0);
7092 if (insn & (1 << 16)) {
7093 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7094 } else if (insn & (1 << 17)) {
7095 if ((insn >> 18) & 1)
7096 gen_neon_dup_high16(tmp);
7097 else
7098 gen_neon_dup_low16(tmp);
7100 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7101 tmp2 = tcg_temp_new_i32();
7102 tcg_gen_mov_i32(tmp2, tmp);
7103 neon_store_reg(rd, pass, tmp2);
7105 tcg_temp_free_i32(tmp);
7106 } else {
7107 return 1;
7111 return 0;
7114 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7116 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7117 const ARMCPRegInfo *ri;
7119 cpnum = (insn >> 8) & 0xf;
7121 /* First check for coprocessor space used for XScale/iwMMXt insns */
7122 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7123 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7124 return 1;
7126 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7127 return disas_iwmmxt_insn(s, insn);
7128 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7129 return disas_dsp_insn(s, insn);
7131 return 1;
7134 /* Otherwise treat as a generic register access */
7135 is64 = (insn & (1 << 25)) == 0;
7136 if (!is64 && ((insn & (1 << 4)) == 0)) {
7137 /* cdp */
7138 return 1;
7141 crm = insn & 0xf;
7142 if (is64) {
7143 crn = 0;
7144 opc1 = (insn >> 4) & 0xf;
7145 opc2 = 0;
7146 rt2 = (insn >> 16) & 0xf;
7147 } else {
7148 crn = (insn >> 16) & 0xf;
7149 opc1 = (insn >> 21) & 7;
7150 opc2 = (insn >> 5) & 7;
7151 rt2 = 0;
7153 isread = (insn >> 20) & 1;
7154 rt = (insn >> 12) & 0xf;
7156 ri = get_arm_cp_reginfo(s->cp_regs,
7157 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7158 if (ri) {
7159 /* Check access permissions */
7160 if (!cp_access_ok(s->current_el, ri, isread)) {
7161 return 1;
7164 if (ri->accessfn ||
7165 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7166 /* Emit code to perform further access permissions checks at
7167 * runtime; this may result in an exception.
7168 * Note that on XScale all cp0..c13 registers do an access check
7169 * call in order to handle c15_cpar.
7171 TCGv_ptr tmpptr;
7172 TCGv_i32 tcg_syn;
7173 uint32_t syndrome;
7175 /* Note that since we are an implementation which takes an
7176 * exception on a trapped conditional instruction only if the
7177 * instruction passes its condition code check, we can take
7178 * advantage of the clause in the ARM ARM that allows us to set
7179 * the COND field in the instruction to 0xE in all cases.
7180 * We could fish the actual condition out of the insn (ARM)
7181 * or the condexec bits (Thumb) but it isn't necessary.
7183 switch (cpnum) {
7184 case 14:
7185 if (is64) {
7186 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7187 isread, s->thumb);
7188 } else {
7189 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7190 rt, isread, s->thumb);
7192 break;
7193 case 15:
7194 if (is64) {
7195 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7196 isread, s->thumb);
7197 } else {
7198 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7199 rt, isread, s->thumb);
7201 break;
7202 default:
7203 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7204 * so this can only happen if this is an ARMv7 or earlier CPU,
7205 * in which case the syndrome information won't actually be
7206 * guest visible.
7208 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7209 syndrome = syn_uncategorized();
7210 break;
7213 gen_set_pc_im(s, s->pc - 4);
7214 tmpptr = tcg_const_ptr(ri);
7215 tcg_syn = tcg_const_i32(syndrome);
7216 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
7217 tcg_temp_free_ptr(tmpptr);
7218 tcg_temp_free_i32(tcg_syn);
7221 /* Handle special cases first */
7222 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7223 case ARM_CP_NOP:
7224 return 0;
7225 case ARM_CP_WFI:
7226 if (isread) {
7227 return 1;
7229 gen_set_pc_im(s, s->pc);
7230 s->is_jmp = DISAS_WFI;
7231 return 0;
7232 default:
7233 break;
7236 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7237 gen_io_start();
7240 if (isread) {
7241 /* Read */
7242 if (is64) {
7243 TCGv_i64 tmp64;
7244 TCGv_i32 tmp;
7245 if (ri->type & ARM_CP_CONST) {
7246 tmp64 = tcg_const_i64(ri->resetvalue);
7247 } else if (ri->readfn) {
7248 TCGv_ptr tmpptr;
7249 tmp64 = tcg_temp_new_i64();
7250 tmpptr = tcg_const_ptr(ri);
7251 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7252 tcg_temp_free_ptr(tmpptr);
7253 } else {
7254 tmp64 = tcg_temp_new_i64();
7255 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7257 tmp = tcg_temp_new_i32();
7258 tcg_gen_extrl_i64_i32(tmp, tmp64);
7259 store_reg(s, rt, tmp);
7260 tcg_gen_shri_i64(tmp64, tmp64, 32);
7261 tmp = tcg_temp_new_i32();
7262 tcg_gen_extrl_i64_i32(tmp, tmp64);
7263 tcg_temp_free_i64(tmp64);
7264 store_reg(s, rt2, tmp);
7265 } else {
7266 TCGv_i32 tmp;
7267 if (ri->type & ARM_CP_CONST) {
7268 tmp = tcg_const_i32(ri->resetvalue);
7269 } else if (ri->readfn) {
7270 TCGv_ptr tmpptr;
7271 tmp = tcg_temp_new_i32();
7272 tmpptr = tcg_const_ptr(ri);
7273 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7274 tcg_temp_free_ptr(tmpptr);
7275 } else {
7276 tmp = load_cpu_offset(ri->fieldoffset);
7278 if (rt == 15) {
7279 /* Destination register of r15 for 32 bit loads sets
7280 * the condition codes from the high 4 bits of the value
7282 gen_set_nzcv(tmp);
7283 tcg_temp_free_i32(tmp);
7284 } else {
7285 store_reg(s, rt, tmp);
7288 } else {
7289 /* Write */
7290 if (ri->type & ARM_CP_CONST) {
7291 /* If not forbidden by access permissions, treat as WI */
7292 return 0;
7295 if (is64) {
7296 TCGv_i32 tmplo, tmphi;
7297 TCGv_i64 tmp64 = tcg_temp_new_i64();
7298 tmplo = load_reg(s, rt);
7299 tmphi = load_reg(s, rt2);
7300 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7301 tcg_temp_free_i32(tmplo);
7302 tcg_temp_free_i32(tmphi);
7303 if (ri->writefn) {
7304 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7305 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7306 tcg_temp_free_ptr(tmpptr);
7307 } else {
7308 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7310 tcg_temp_free_i64(tmp64);
7311 } else {
7312 if (ri->writefn) {
7313 TCGv_i32 tmp;
7314 TCGv_ptr tmpptr;
7315 tmp = load_reg(s, rt);
7316 tmpptr = tcg_const_ptr(ri);
7317 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7318 tcg_temp_free_ptr(tmpptr);
7319 tcg_temp_free_i32(tmp);
7320 } else {
7321 TCGv_i32 tmp = load_reg(s, rt);
7322 store_cpu_offset(tmp, ri->fieldoffset);
7327 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7328 /* I/O operations must end the TB here (whether read or write) */
7329 gen_io_end();
7330 gen_lookup_tb(s);
7331 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7332 /* We default to ending the TB on a coprocessor register write,
7333 * but allow this to be suppressed by the register definition
7334 * (usually only necessary to work around guest bugs).
7336 gen_lookup_tb(s);
7339 return 0;
7342 /* Unknown register; this might be a guest error or a QEMU
7343 * unimplemented feature.
7345 if (is64) {
7346 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7347 "64 bit system register cp:%d opc1: %d crm:%d "
7348 "(%s)\n",
7349 isread ? "read" : "write", cpnum, opc1, crm,
7350 s->ns ? "non-secure" : "secure");
7351 } else {
7352 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7353 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7354 "(%s)\n",
7355 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7356 s->ns ? "non-secure" : "secure");
7359 return 1;
7363 /* Store a 64-bit value to a register pair. Clobbers val. */
7364 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7366 TCGv_i32 tmp;
7367 tmp = tcg_temp_new_i32();
7368 tcg_gen_extrl_i64_i32(tmp, val);
7369 store_reg(s, rlow, tmp);
7370 tmp = tcg_temp_new_i32();
7371 tcg_gen_shri_i64(val, val, 32);
7372 tcg_gen_extrl_i64_i32(tmp, val);
7373 store_reg(s, rhigh, tmp);
7376 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7377 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7379 TCGv_i64 tmp;
7380 TCGv_i32 tmp2;
7382 /* Load value and extend to 64 bits. */
7383 tmp = tcg_temp_new_i64();
7384 tmp2 = load_reg(s, rlow);
7385 tcg_gen_extu_i32_i64(tmp, tmp2);
7386 tcg_temp_free_i32(tmp2);
7387 tcg_gen_add_i64(val, val, tmp);
7388 tcg_temp_free_i64(tmp);
7391 /* load and add a 64-bit value from a register pair. */
7392 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7394 TCGv_i64 tmp;
7395 TCGv_i32 tmpl;
7396 TCGv_i32 tmph;
7398 /* Load 64-bit value rd:rn. */
7399 tmpl = load_reg(s, rlow);
7400 tmph = load_reg(s, rhigh);
7401 tmp = tcg_temp_new_i64();
7402 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7403 tcg_temp_free_i32(tmpl);
7404 tcg_temp_free_i32(tmph);
7405 tcg_gen_add_i64(val, val, tmp);
7406 tcg_temp_free_i64(tmp);
7409 /* Set N and Z flags from hi|lo. */
7410 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7412 tcg_gen_mov_i32(cpu_NF, hi);
7413 tcg_gen_or_i32(cpu_ZF, lo, hi);
7416 /* Load/Store exclusive instructions are implemented by remembering
7417 the value/address loaded, and seeing if these are the same
7418 when the store is performed. This should be sufficient to implement
7419 the architecturally mandated semantics, and avoids having to monitor
7420 regular stores.
7422 In system emulation mode only one CPU will be running at once, so
7423 this sequence is effectively atomic. In user emulation mode we
7424 throw an exception and handle the atomic operation elsewhere. */
7425 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7426 TCGv_i32 addr, int size)
7428 TCGv_i32 tmp = tcg_temp_new_i32();
7430 s->is_ldex = true;
7432 switch (size) {
7433 case 0:
7434 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7435 break;
7436 case 1:
7437 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7438 break;
7439 case 2:
7440 case 3:
7441 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7442 break;
7443 default:
7444 abort();
7447 if (size == 3) {
7448 TCGv_i32 tmp2 = tcg_temp_new_i32();
7449 TCGv_i32 tmp3 = tcg_temp_new_i32();
7451 tcg_gen_addi_i32(tmp2, addr, 4);
7452 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7453 tcg_temp_free_i32(tmp2);
7454 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7455 store_reg(s, rt2, tmp3);
7456 } else {
7457 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7460 store_reg(s, rt, tmp);
7461 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7464 static void gen_clrex(DisasContext *s)
7466 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7469 #ifdef CONFIG_USER_ONLY
7470 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7471 TCGv_i32 addr, int size)
7473 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7474 tcg_gen_movi_i32(cpu_exclusive_info,
7475 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7476 gen_exception_internal_insn(s, 4, EXCP_STREX);
7478 #else
7479 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7480 TCGv_i32 addr, int size)
7482 TCGv_i32 tmp;
7483 TCGv_i64 val64, extaddr;
7484 TCGLabel *done_label;
7485 TCGLabel *fail_label;
7487 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7488 [addr] = {Rt};
7489 {Rd} = 0;
7490 } else {
7491 {Rd} = 1;
7492 } */
7493 fail_label = gen_new_label();
7494 done_label = gen_new_label();
7495 extaddr = tcg_temp_new_i64();
7496 tcg_gen_extu_i32_i64(extaddr, addr);
7497 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7498 tcg_temp_free_i64(extaddr);
7500 tmp = tcg_temp_new_i32();
7501 switch (size) {
7502 case 0:
7503 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7504 break;
7505 case 1:
7506 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7507 break;
7508 case 2:
7509 case 3:
7510 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7511 break;
7512 default:
7513 abort();
7516 val64 = tcg_temp_new_i64();
7517 if (size == 3) {
7518 TCGv_i32 tmp2 = tcg_temp_new_i32();
7519 TCGv_i32 tmp3 = tcg_temp_new_i32();
7520 tcg_gen_addi_i32(tmp2, addr, 4);
7521 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7522 tcg_temp_free_i32(tmp2);
7523 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7524 tcg_temp_free_i32(tmp3);
7525 } else {
7526 tcg_gen_extu_i32_i64(val64, tmp);
7528 tcg_temp_free_i32(tmp);
7530 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7531 tcg_temp_free_i64(val64);
7533 tmp = load_reg(s, rt);
7534 switch (size) {
7535 case 0:
7536 gen_aa32_st8(tmp, addr, get_mem_index(s));
7537 break;
7538 case 1:
7539 gen_aa32_st16(tmp, addr, get_mem_index(s));
7540 break;
7541 case 2:
7542 case 3:
7543 gen_aa32_st32(tmp, addr, get_mem_index(s));
7544 break;
7545 default:
7546 abort();
7548 tcg_temp_free_i32(tmp);
7549 if (size == 3) {
7550 tcg_gen_addi_i32(addr, addr, 4);
7551 tmp = load_reg(s, rt2);
7552 gen_aa32_st32(tmp, addr, get_mem_index(s));
7553 tcg_temp_free_i32(tmp);
7555 tcg_gen_movi_i32(cpu_R[rd], 0);
7556 tcg_gen_br(done_label);
7557 gen_set_label(fail_label);
7558 tcg_gen_movi_i32(cpu_R[rd], 1);
7559 gen_set_label(done_label);
7560 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7562 #endif
7564 /* gen_srs:
7565 * @env: CPUARMState
7566 * @s: DisasContext
7567 * @mode: mode field from insn (which stack to store to)
7568 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7569 * @writeback: true if writeback bit set
7571 * Generate code for the SRS (Store Return State) insn.
7573 static void gen_srs(DisasContext *s,
7574 uint32_t mode, uint32_t amode, bool writeback)
7576 int32_t offset;
7577 TCGv_i32 addr = tcg_temp_new_i32();
7578 TCGv_i32 tmp = tcg_const_i32(mode);
7579 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7580 tcg_temp_free_i32(tmp);
7581 switch (amode) {
7582 case 0: /* DA */
7583 offset = -4;
7584 break;
7585 case 1: /* IA */
7586 offset = 0;
7587 break;
7588 case 2: /* DB */
7589 offset = -8;
7590 break;
7591 case 3: /* IB */
7592 offset = 4;
7593 break;
7594 default:
7595 abort();
7597 tcg_gen_addi_i32(addr, addr, offset);
7598 tmp = load_reg(s, 14);
7599 gen_aa32_st32(tmp, addr, get_mem_index(s));
7600 tcg_temp_free_i32(tmp);
7601 tmp = load_cpu_field(spsr);
7602 tcg_gen_addi_i32(addr, addr, 4);
7603 gen_aa32_st32(tmp, addr, get_mem_index(s));
7604 tcg_temp_free_i32(tmp);
7605 if (writeback) {
7606 switch (amode) {
7607 case 0:
7608 offset = -8;
7609 break;
7610 case 1:
7611 offset = 4;
7612 break;
7613 case 2:
7614 offset = -4;
7615 break;
7616 case 3:
7617 offset = 0;
7618 break;
7619 default:
7620 abort();
7622 tcg_gen_addi_i32(addr, addr, offset);
7623 tmp = tcg_const_i32(mode);
7624 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7625 tcg_temp_free_i32(tmp);
7627 tcg_temp_free_i32(addr);
7630 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7632 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7633 TCGv_i32 tmp;
7634 TCGv_i32 tmp2;
7635 TCGv_i32 tmp3;
7636 TCGv_i32 addr;
7637 TCGv_i64 tmp64;
7639 /* M variants do not implement ARM mode. */
7640 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7641 goto illegal_op;
7643 cond = insn >> 28;
7644 if (cond == 0xf){
7645 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7646 * choose to UNDEF. In ARMv5 and above the space is used
7647 * for miscellaneous unconditional instructions.
7649 ARCH(5);
7651 /* Unconditional instructions. */
7652 if (((insn >> 25) & 7) == 1) {
7653 /* NEON Data processing. */
7654 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7655 goto illegal_op;
7658 if (disas_neon_data_insn(s, insn)) {
7659 goto illegal_op;
7661 return;
7663 if ((insn & 0x0f100000) == 0x04000000) {
7664 /* NEON load/store. */
7665 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7666 goto illegal_op;
7669 if (disas_neon_ls_insn(s, insn)) {
7670 goto illegal_op;
7672 return;
7674 if ((insn & 0x0f000e10) == 0x0e000a00) {
7675 /* VFP. */
7676 if (disas_vfp_insn(s, insn)) {
7677 goto illegal_op;
7679 return;
7681 if (((insn & 0x0f30f000) == 0x0510f000) ||
7682 ((insn & 0x0f30f010) == 0x0710f000)) {
7683 if ((insn & (1 << 22)) == 0) {
7684 /* PLDW; v7MP */
7685 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7686 goto illegal_op;
7689 /* Otherwise PLD; v5TE+ */
7690 ARCH(5TE);
7691 return;
7693 if (((insn & 0x0f70f000) == 0x0450f000) ||
7694 ((insn & 0x0f70f010) == 0x0650f000)) {
7695 ARCH(7);
7696 return; /* PLI; V7 */
7698 if (((insn & 0x0f700000) == 0x04100000) ||
7699 ((insn & 0x0f700010) == 0x06100000)) {
7700 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7701 goto illegal_op;
7703 return; /* v7MP: Unallocated memory hint: must NOP */
7706 if ((insn & 0x0ffffdff) == 0x01010000) {
7707 ARCH(6);
7708 /* setend */
7709 if (((insn >> 9) & 1) != s->bswap_code) {
7710 /* Dynamic endianness switching not implemented. */
7711 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7712 goto illegal_op;
7714 return;
7715 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7716 switch ((insn >> 4) & 0xf) {
7717 case 1: /* clrex */
7718 ARCH(6K);
7719 gen_clrex(s);
7720 return;
7721 case 4: /* dsb */
7722 case 5: /* dmb */
7723 ARCH(7);
7724 /* We don't emulate caches so these are a no-op. */
7725 return;
7726 case 6: /* isb */
7727 /* We need to break the TB after this insn to execute
7728 * self-modifying code correctly and also to take
7729 * any pending interrupts immediately.
7731 gen_lookup_tb(s);
7732 return;
7733 default:
7734 goto illegal_op;
7736 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7737 /* srs */
7738 if (IS_USER(s)) {
7739 goto illegal_op;
7741 ARCH(6);
7742 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7743 return;
7744 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7745 /* rfe */
7746 int32_t offset;
7747 if (IS_USER(s))
7748 goto illegal_op;
7749 ARCH(6);
7750 rn = (insn >> 16) & 0xf;
7751 addr = load_reg(s, rn);
7752 i = (insn >> 23) & 3;
7753 switch (i) {
7754 case 0: offset = -4; break; /* DA */
7755 case 1: offset = 0; break; /* IA */
7756 case 2: offset = -8; break; /* DB */
7757 case 3: offset = 4; break; /* IB */
7758 default: abort();
7760 if (offset)
7761 tcg_gen_addi_i32(addr, addr, offset);
7762 /* Load PC into tmp and CPSR into tmp2. */
7763 tmp = tcg_temp_new_i32();
7764 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7765 tcg_gen_addi_i32(addr, addr, 4);
7766 tmp2 = tcg_temp_new_i32();
7767 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
7768 if (insn & (1 << 21)) {
7769 /* Base writeback. */
7770 switch (i) {
7771 case 0: offset = -8; break;
7772 case 1: offset = 4; break;
7773 case 2: offset = -4; break;
7774 case 3: offset = 0; break;
7775 default: abort();
7777 if (offset)
7778 tcg_gen_addi_i32(addr, addr, offset);
7779 store_reg(s, rn, addr);
7780 } else {
7781 tcg_temp_free_i32(addr);
7783 gen_rfe(s, tmp, tmp2);
7784 return;
7785 } else if ((insn & 0x0e000000) == 0x0a000000) {
7786 /* branch link and change to thumb (blx <offset>) */
7787 int32_t offset;
7789 val = (uint32_t)s->pc;
7790 tmp = tcg_temp_new_i32();
7791 tcg_gen_movi_i32(tmp, val);
7792 store_reg(s, 14, tmp);
7793 /* Sign-extend the 24-bit offset */
7794 offset = (((int32_t)insn) << 8) >> 8;
7795 /* offset * 4 + bit24 * 2 + (thumb bit) */
7796 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7797 /* pipeline offset */
7798 val += 4;
7799 /* protected by ARCH(5); above, near the start of uncond block */
7800 gen_bx_im(s, val);
7801 return;
7802 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7803 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7804 /* iWMMXt register transfer. */
7805 if (extract32(s->c15_cpar, 1, 1)) {
7806 if (!disas_iwmmxt_insn(s, insn)) {
7807 return;
7811 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7812 /* Coprocessor double register transfer. */
7813 ARCH(5TE);
7814 } else if ((insn & 0x0f000010) == 0x0e000010) {
7815 /* Additional coprocessor register transfer. */
7816 } else if ((insn & 0x0ff10020) == 0x01000000) {
7817 uint32_t mask;
7818 uint32_t val;
7819 /* cps (privileged) */
7820 if (IS_USER(s))
7821 return;
7822 mask = val = 0;
7823 if (insn & (1 << 19)) {
7824 if (insn & (1 << 8))
7825 mask |= CPSR_A;
7826 if (insn & (1 << 7))
7827 mask |= CPSR_I;
7828 if (insn & (1 << 6))
7829 mask |= CPSR_F;
7830 if (insn & (1 << 18))
7831 val |= mask;
7833 if (insn & (1 << 17)) {
7834 mask |= CPSR_M;
7835 val |= (insn & 0x1f);
7837 if (mask) {
7838 gen_set_psr_im(s, mask, 0, val);
7840 return;
7842 goto illegal_op;
7844 if (cond != 0xe) {
7845 /* if not always execute, we generate a conditional jump to
7846 next instruction */
7847 s->condlabel = gen_new_label();
7848 arm_gen_test_cc(cond ^ 1, s->condlabel);
7849 s->condjmp = 1;
7851 if ((insn & 0x0f900000) == 0x03000000) {
7852 if ((insn & (1 << 21)) == 0) {
7853 ARCH(6T2);
7854 rd = (insn >> 12) & 0xf;
7855 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7856 if ((insn & (1 << 22)) == 0) {
7857 /* MOVW */
7858 tmp = tcg_temp_new_i32();
7859 tcg_gen_movi_i32(tmp, val);
7860 } else {
7861 /* MOVT */
7862 tmp = load_reg(s, rd);
7863 tcg_gen_ext16u_i32(tmp, tmp);
7864 tcg_gen_ori_i32(tmp, tmp, val << 16);
7866 store_reg(s, rd, tmp);
7867 } else {
7868 if (((insn >> 12) & 0xf) != 0xf)
7869 goto illegal_op;
7870 if (((insn >> 16) & 0xf) == 0) {
7871 gen_nop_hint(s, insn & 0xff);
7872 } else {
7873 /* CPSR = immediate */
7874 val = insn & 0xff;
7875 shift = ((insn >> 8) & 0xf) * 2;
7876 if (shift)
7877 val = (val >> shift) | (val << (32 - shift));
7878 i = ((insn & (1 << 22)) != 0);
7879 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7880 i, val)) {
7881 goto illegal_op;
7885 } else if ((insn & 0x0f900000) == 0x01000000
7886 && (insn & 0x00000090) != 0x00000090) {
7887 /* miscellaneous instructions */
7888 op1 = (insn >> 21) & 3;
7889 sh = (insn >> 4) & 0xf;
7890 rm = insn & 0xf;
7891 switch (sh) {
7892 case 0x0: /* move program status register */
7893 if (op1 & 1) {
7894 /* PSR = reg */
7895 tmp = load_reg(s, rm);
7896 i = ((op1 & 2) != 0);
7897 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7898 goto illegal_op;
7899 } else {
7900 /* reg = PSR */
7901 rd = (insn >> 12) & 0xf;
7902 if (op1 & 2) {
7903 if (IS_USER(s))
7904 goto illegal_op;
7905 tmp = load_cpu_field(spsr);
7906 } else {
7907 tmp = tcg_temp_new_i32();
7908 gen_helper_cpsr_read(tmp, cpu_env);
7910 store_reg(s, rd, tmp);
7912 break;
7913 case 0x1:
7914 if (op1 == 1) {
7915 /* branch/exchange thumb (bx). */
7916 ARCH(4T);
7917 tmp = load_reg(s, rm);
7918 gen_bx(s, tmp);
7919 } else if (op1 == 3) {
7920 /* clz */
7921 ARCH(5);
7922 rd = (insn >> 12) & 0xf;
7923 tmp = load_reg(s, rm);
7924 gen_helper_clz(tmp, tmp);
7925 store_reg(s, rd, tmp);
7926 } else {
7927 goto illegal_op;
7929 break;
7930 case 0x2:
7931 if (op1 == 1) {
7932 ARCH(5J); /* bxj */
7933 /* Trivial implementation equivalent to bx. */
7934 tmp = load_reg(s, rm);
7935 gen_bx(s, tmp);
7936 } else {
7937 goto illegal_op;
7939 break;
7940 case 0x3:
7941 if (op1 != 1)
7942 goto illegal_op;
7944 ARCH(5);
7945 /* branch link/exchange thumb (blx) */
7946 tmp = load_reg(s, rm);
7947 tmp2 = tcg_temp_new_i32();
7948 tcg_gen_movi_i32(tmp2, s->pc);
7949 store_reg(s, 14, tmp2);
7950 gen_bx(s, tmp);
7951 break;
7952 case 0x4:
7954 /* crc32/crc32c */
7955 uint32_t c = extract32(insn, 8, 4);
7957 /* Check this CPU supports ARMv8 CRC instructions.
7958 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7959 * Bits 8, 10 and 11 should be zero.
7961 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
7962 (c & 0xd) != 0) {
7963 goto illegal_op;
7966 rn = extract32(insn, 16, 4);
7967 rd = extract32(insn, 12, 4);
7969 tmp = load_reg(s, rn);
7970 tmp2 = load_reg(s, rm);
7971 if (op1 == 0) {
7972 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
7973 } else if (op1 == 1) {
7974 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
7976 tmp3 = tcg_const_i32(1 << op1);
7977 if (c & 0x2) {
7978 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7979 } else {
7980 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7982 tcg_temp_free_i32(tmp2);
7983 tcg_temp_free_i32(tmp3);
7984 store_reg(s, rd, tmp);
7985 break;
7987 case 0x5: /* saturating add/subtract */
7988 ARCH(5TE);
7989 rd = (insn >> 12) & 0xf;
7990 rn = (insn >> 16) & 0xf;
7991 tmp = load_reg(s, rm);
7992 tmp2 = load_reg(s, rn);
7993 if (op1 & 2)
7994 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7995 if (op1 & 1)
7996 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7997 else
7998 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7999 tcg_temp_free_i32(tmp2);
8000 store_reg(s, rd, tmp);
8001 break;
8002 case 7:
8004 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8005 switch (op1) {
8006 case 1:
8007 /* bkpt */
8008 ARCH(5);
8009 gen_exception_insn(s, 4, EXCP_BKPT,
8010 syn_aa32_bkpt(imm16, false),
8011 default_exception_el(s));
8012 break;
8013 case 2:
8014 /* Hypervisor call (v7) */
8015 ARCH(7);
8016 if (IS_USER(s)) {
8017 goto illegal_op;
8019 gen_hvc(s, imm16);
8020 break;
8021 case 3:
8022 /* Secure monitor call (v6+) */
8023 ARCH(6K);
8024 if (IS_USER(s)) {
8025 goto illegal_op;
8027 gen_smc(s);
8028 break;
8029 default:
8030 goto illegal_op;
8032 break;
8034 case 0x8: /* signed multiply */
8035 case 0xa:
8036 case 0xc:
8037 case 0xe:
8038 ARCH(5TE);
8039 rs = (insn >> 8) & 0xf;
8040 rn = (insn >> 12) & 0xf;
8041 rd = (insn >> 16) & 0xf;
8042 if (op1 == 1) {
8043 /* (32 * 16) >> 16 */
8044 tmp = load_reg(s, rm);
8045 tmp2 = load_reg(s, rs);
8046 if (sh & 4)
8047 tcg_gen_sari_i32(tmp2, tmp2, 16);
8048 else
8049 gen_sxth(tmp2);
8050 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8051 tcg_gen_shri_i64(tmp64, tmp64, 16);
8052 tmp = tcg_temp_new_i32();
8053 tcg_gen_extrl_i64_i32(tmp, tmp64);
8054 tcg_temp_free_i64(tmp64);
8055 if ((sh & 2) == 0) {
8056 tmp2 = load_reg(s, rn);
8057 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8058 tcg_temp_free_i32(tmp2);
8060 store_reg(s, rd, tmp);
8061 } else {
8062 /* 16 * 16 */
8063 tmp = load_reg(s, rm);
8064 tmp2 = load_reg(s, rs);
8065 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8066 tcg_temp_free_i32(tmp2);
8067 if (op1 == 2) {
8068 tmp64 = tcg_temp_new_i64();
8069 tcg_gen_ext_i32_i64(tmp64, tmp);
8070 tcg_temp_free_i32(tmp);
8071 gen_addq(s, tmp64, rn, rd);
8072 gen_storeq_reg(s, rn, rd, tmp64);
8073 tcg_temp_free_i64(tmp64);
8074 } else {
8075 if (op1 == 0) {
8076 tmp2 = load_reg(s, rn);
8077 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8078 tcg_temp_free_i32(tmp2);
8080 store_reg(s, rd, tmp);
8083 break;
8084 default:
8085 goto illegal_op;
8087 } else if (((insn & 0x0e000000) == 0 &&
8088 (insn & 0x00000090) != 0x90) ||
8089 ((insn & 0x0e000000) == (1 << 25))) {
8090 int set_cc, logic_cc, shiftop;
8092 op1 = (insn >> 21) & 0xf;
8093 set_cc = (insn >> 20) & 1;
8094 logic_cc = table_logic_cc[op1] & set_cc;
8096 /* data processing instruction */
8097 if (insn & (1 << 25)) {
8098 /* immediate operand */
8099 val = insn & 0xff;
8100 shift = ((insn >> 8) & 0xf) * 2;
8101 if (shift) {
8102 val = (val >> shift) | (val << (32 - shift));
8104 tmp2 = tcg_temp_new_i32();
8105 tcg_gen_movi_i32(tmp2, val);
8106 if (logic_cc && shift) {
8107 gen_set_CF_bit31(tmp2);
8109 } else {
8110 /* register */
8111 rm = (insn) & 0xf;
8112 tmp2 = load_reg(s, rm);
8113 shiftop = (insn >> 5) & 3;
8114 if (!(insn & (1 << 4))) {
8115 shift = (insn >> 7) & 0x1f;
8116 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8117 } else {
8118 rs = (insn >> 8) & 0xf;
8119 tmp = load_reg(s, rs);
8120 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8123 if (op1 != 0x0f && op1 != 0x0d) {
8124 rn = (insn >> 16) & 0xf;
8125 tmp = load_reg(s, rn);
8126 } else {
8127 TCGV_UNUSED_I32(tmp);
8129 rd = (insn >> 12) & 0xf;
8130 switch(op1) {
8131 case 0x00:
8132 tcg_gen_and_i32(tmp, tmp, tmp2);
8133 if (logic_cc) {
8134 gen_logic_CC(tmp);
8136 store_reg_bx(s, rd, tmp);
8137 break;
8138 case 0x01:
8139 tcg_gen_xor_i32(tmp, tmp, tmp2);
8140 if (logic_cc) {
8141 gen_logic_CC(tmp);
8143 store_reg_bx(s, rd, tmp);
8144 break;
8145 case 0x02:
8146 if (set_cc && rd == 15) {
8147 /* SUBS r15, ... is used for exception return. */
8148 if (IS_USER(s)) {
8149 goto illegal_op;
8151 gen_sub_CC(tmp, tmp, tmp2);
8152 gen_exception_return(s, tmp);
8153 } else {
8154 if (set_cc) {
8155 gen_sub_CC(tmp, tmp, tmp2);
8156 } else {
8157 tcg_gen_sub_i32(tmp, tmp, tmp2);
8159 store_reg_bx(s, rd, tmp);
8161 break;
8162 case 0x03:
8163 if (set_cc) {
8164 gen_sub_CC(tmp, tmp2, tmp);
8165 } else {
8166 tcg_gen_sub_i32(tmp, tmp2, tmp);
8168 store_reg_bx(s, rd, tmp);
8169 break;
8170 case 0x04:
8171 if (set_cc) {
8172 gen_add_CC(tmp, tmp, tmp2);
8173 } else {
8174 tcg_gen_add_i32(tmp, tmp, tmp2);
8176 store_reg_bx(s, rd, tmp);
8177 break;
8178 case 0x05:
8179 if (set_cc) {
8180 gen_adc_CC(tmp, tmp, tmp2);
8181 } else {
8182 gen_add_carry(tmp, tmp, tmp2);
8184 store_reg_bx(s, rd, tmp);
8185 break;
8186 case 0x06:
8187 if (set_cc) {
8188 gen_sbc_CC(tmp, tmp, tmp2);
8189 } else {
8190 gen_sub_carry(tmp, tmp, tmp2);
8192 store_reg_bx(s, rd, tmp);
8193 break;
8194 case 0x07:
8195 if (set_cc) {
8196 gen_sbc_CC(tmp, tmp2, tmp);
8197 } else {
8198 gen_sub_carry(tmp, tmp2, tmp);
8200 store_reg_bx(s, rd, tmp);
8201 break;
8202 case 0x08:
8203 if (set_cc) {
8204 tcg_gen_and_i32(tmp, tmp, tmp2);
8205 gen_logic_CC(tmp);
8207 tcg_temp_free_i32(tmp);
8208 break;
8209 case 0x09:
8210 if (set_cc) {
8211 tcg_gen_xor_i32(tmp, tmp, tmp2);
8212 gen_logic_CC(tmp);
8214 tcg_temp_free_i32(tmp);
8215 break;
8216 case 0x0a:
8217 if (set_cc) {
8218 gen_sub_CC(tmp, tmp, tmp2);
8220 tcg_temp_free_i32(tmp);
8221 break;
8222 case 0x0b:
8223 if (set_cc) {
8224 gen_add_CC(tmp, tmp, tmp2);
8226 tcg_temp_free_i32(tmp);
8227 break;
8228 case 0x0c:
8229 tcg_gen_or_i32(tmp, tmp, tmp2);
8230 if (logic_cc) {
8231 gen_logic_CC(tmp);
8233 store_reg_bx(s, rd, tmp);
8234 break;
8235 case 0x0d:
8236 if (logic_cc && rd == 15) {
8237 /* MOVS r15, ... is used for exception return. */
8238 if (IS_USER(s)) {
8239 goto illegal_op;
8241 gen_exception_return(s, tmp2);
8242 } else {
8243 if (logic_cc) {
8244 gen_logic_CC(tmp2);
8246 store_reg_bx(s, rd, tmp2);
8248 break;
8249 case 0x0e:
8250 tcg_gen_andc_i32(tmp, tmp, tmp2);
8251 if (logic_cc) {
8252 gen_logic_CC(tmp);
8254 store_reg_bx(s, rd, tmp);
8255 break;
8256 default:
8257 case 0x0f:
8258 tcg_gen_not_i32(tmp2, tmp2);
8259 if (logic_cc) {
8260 gen_logic_CC(tmp2);
8262 store_reg_bx(s, rd, tmp2);
8263 break;
8265 if (op1 != 0x0f && op1 != 0x0d) {
8266 tcg_temp_free_i32(tmp2);
8268 } else {
8269 /* other instructions */
8270 op1 = (insn >> 24) & 0xf;
8271 switch(op1) {
8272 case 0x0:
8273 case 0x1:
8274 /* multiplies, extra load/stores */
8275 sh = (insn >> 5) & 3;
8276 if (sh == 0) {
8277 if (op1 == 0x0) {
8278 rd = (insn >> 16) & 0xf;
8279 rn = (insn >> 12) & 0xf;
8280 rs = (insn >> 8) & 0xf;
8281 rm = (insn) & 0xf;
8282 op1 = (insn >> 20) & 0xf;
8283 switch (op1) {
8284 case 0: case 1: case 2: case 3: case 6:
8285 /* 32 bit mul */
8286 tmp = load_reg(s, rs);
8287 tmp2 = load_reg(s, rm);
8288 tcg_gen_mul_i32(tmp, tmp, tmp2);
8289 tcg_temp_free_i32(tmp2);
8290 if (insn & (1 << 22)) {
8291 /* Subtract (mls) */
8292 ARCH(6T2);
8293 tmp2 = load_reg(s, rn);
8294 tcg_gen_sub_i32(tmp, tmp2, tmp);
8295 tcg_temp_free_i32(tmp2);
8296 } else if (insn & (1 << 21)) {
8297 /* Add */
8298 tmp2 = load_reg(s, rn);
8299 tcg_gen_add_i32(tmp, tmp, tmp2);
8300 tcg_temp_free_i32(tmp2);
8302 if (insn & (1 << 20))
8303 gen_logic_CC(tmp);
8304 store_reg(s, rd, tmp);
8305 break;
8306 case 4:
8307 /* 64 bit mul double accumulate (UMAAL) */
8308 ARCH(6);
8309 tmp = load_reg(s, rs);
8310 tmp2 = load_reg(s, rm);
8311 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8312 gen_addq_lo(s, tmp64, rn);
8313 gen_addq_lo(s, tmp64, rd);
8314 gen_storeq_reg(s, rn, rd, tmp64);
8315 tcg_temp_free_i64(tmp64);
8316 break;
8317 case 8: case 9: case 10: case 11:
8318 case 12: case 13: case 14: case 15:
8319 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8320 tmp = load_reg(s, rs);
8321 tmp2 = load_reg(s, rm);
8322 if (insn & (1 << 22)) {
8323 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8324 } else {
8325 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8327 if (insn & (1 << 21)) { /* mult accumulate */
8328 TCGv_i32 al = load_reg(s, rn);
8329 TCGv_i32 ah = load_reg(s, rd);
8330 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8331 tcg_temp_free_i32(al);
8332 tcg_temp_free_i32(ah);
8334 if (insn & (1 << 20)) {
8335 gen_logicq_cc(tmp, tmp2);
8337 store_reg(s, rn, tmp);
8338 store_reg(s, rd, tmp2);
8339 break;
8340 default:
8341 goto illegal_op;
8343 } else {
8344 rn = (insn >> 16) & 0xf;
8345 rd = (insn >> 12) & 0xf;
8346 if (insn & (1 << 23)) {
8347 /* load/store exclusive */
8348 int op2 = (insn >> 8) & 3;
8349 op1 = (insn >> 21) & 0x3;
8351 switch (op2) {
8352 case 0: /* lda/stl */
8353 if (op1 == 1) {
8354 goto illegal_op;
8356 ARCH(8);
8357 break;
8358 case 1: /* reserved */
8359 goto illegal_op;
8360 case 2: /* ldaex/stlex */
8361 ARCH(8);
8362 break;
8363 case 3: /* ldrex/strex */
8364 if (op1) {
8365 ARCH(6K);
8366 } else {
8367 ARCH(6);
8369 break;
8372 addr = tcg_temp_local_new_i32();
8373 load_reg_var(s, addr, rn);
8375 /* Since the emulation does not have barriers,
8376 the acquire/release semantics need no special
8377 handling */
8378 if (op2 == 0) {
8379 if (insn & (1 << 20)) {
8380 tmp = tcg_temp_new_i32();
8381 switch (op1) {
8382 case 0: /* lda */
8383 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8384 break;
8385 case 2: /* ldab */
8386 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
8387 break;
8388 case 3: /* ldah */
8389 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8390 break;
8391 default:
8392 abort();
8394 store_reg(s, rd, tmp);
8395 } else {
8396 rm = insn & 0xf;
8397 tmp = load_reg(s, rm);
8398 switch (op1) {
8399 case 0: /* stl */
8400 gen_aa32_st32(tmp, addr, get_mem_index(s));
8401 break;
8402 case 2: /* stlb */
8403 gen_aa32_st8(tmp, addr, get_mem_index(s));
8404 break;
8405 case 3: /* stlh */
8406 gen_aa32_st16(tmp, addr, get_mem_index(s));
8407 break;
8408 default:
8409 abort();
8411 tcg_temp_free_i32(tmp);
8413 } else if (insn & (1 << 20)) {
8414 switch (op1) {
8415 case 0: /* ldrex */
8416 gen_load_exclusive(s, rd, 15, addr, 2);
8417 break;
8418 case 1: /* ldrexd */
8419 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8420 break;
8421 case 2: /* ldrexb */
8422 gen_load_exclusive(s, rd, 15, addr, 0);
8423 break;
8424 case 3: /* ldrexh */
8425 gen_load_exclusive(s, rd, 15, addr, 1);
8426 break;
8427 default:
8428 abort();
8430 } else {
8431 rm = insn & 0xf;
8432 switch (op1) {
8433 case 0: /* strex */
8434 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8435 break;
8436 case 1: /* strexd */
8437 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8438 break;
8439 case 2: /* strexb */
8440 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8441 break;
8442 case 3: /* strexh */
8443 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8444 break;
8445 default:
8446 abort();
8449 tcg_temp_free_i32(addr);
8450 } else {
8451 /* SWP instruction */
8452 rm = (insn) & 0xf;
8454 /* ??? This is not really atomic. However we know
8455 we never have multiple CPUs running in parallel,
8456 so it is good enough. */
8457 addr = load_reg(s, rn);
8458 tmp = load_reg(s, rm);
8459 tmp2 = tcg_temp_new_i32();
8460 if (insn & (1 << 22)) {
8461 gen_aa32_ld8u(tmp2, addr, get_mem_index(s));
8462 gen_aa32_st8(tmp, addr, get_mem_index(s));
8463 } else {
8464 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
8465 gen_aa32_st32(tmp, addr, get_mem_index(s));
8467 tcg_temp_free_i32(tmp);
8468 tcg_temp_free_i32(addr);
8469 store_reg(s, rd, tmp2);
8472 } else {
8473 int address_offset;
8474 bool load = insn & (1 << 20);
8475 bool doubleword = false;
8476 /* Misc load/store */
8477 rn = (insn >> 16) & 0xf;
8478 rd = (insn >> 12) & 0xf;
8480 if (!load && (sh & 2)) {
8481 /* doubleword */
8482 ARCH(5TE);
8483 if (rd & 1) {
8484 /* UNPREDICTABLE; we choose to UNDEF */
8485 goto illegal_op;
8487 load = (sh & 1) == 0;
8488 doubleword = true;
8491 addr = load_reg(s, rn);
8492 if (insn & (1 << 24))
8493 gen_add_datah_offset(s, insn, 0, addr);
8494 address_offset = 0;
8496 if (doubleword) {
8497 if (!load) {
8498 /* store */
8499 tmp = load_reg(s, rd);
8500 gen_aa32_st32(tmp, addr, get_mem_index(s));
8501 tcg_temp_free_i32(tmp);
8502 tcg_gen_addi_i32(addr, addr, 4);
8503 tmp = load_reg(s, rd + 1);
8504 gen_aa32_st32(tmp, addr, get_mem_index(s));
8505 tcg_temp_free_i32(tmp);
8506 } else {
8507 /* load */
8508 tmp = tcg_temp_new_i32();
8509 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8510 store_reg(s, rd, tmp);
8511 tcg_gen_addi_i32(addr, addr, 4);
8512 tmp = tcg_temp_new_i32();
8513 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8514 rd++;
8516 address_offset = -4;
8517 } else if (load) {
8518 /* load */
8519 tmp = tcg_temp_new_i32();
8520 switch (sh) {
8521 case 1:
8522 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8523 break;
8524 case 2:
8525 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
8526 break;
8527 default:
8528 case 3:
8529 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
8530 break;
8532 } else {
8533 /* store */
8534 tmp = load_reg(s, rd);
8535 gen_aa32_st16(tmp, addr, get_mem_index(s));
8536 tcg_temp_free_i32(tmp);
8538 /* Perform base writeback before the loaded value to
8539 ensure correct behavior with overlapping index registers.
8540 ldrd with base writeback is undefined if the
8541 destination and index registers overlap. */
8542 if (!(insn & (1 << 24))) {
8543 gen_add_datah_offset(s, insn, address_offset, addr);
8544 store_reg(s, rn, addr);
8545 } else if (insn & (1 << 21)) {
8546 if (address_offset)
8547 tcg_gen_addi_i32(addr, addr, address_offset);
8548 store_reg(s, rn, addr);
8549 } else {
8550 tcg_temp_free_i32(addr);
8552 if (load) {
8553 /* Complete the load. */
8554 store_reg(s, rd, tmp);
8557 break;
8558 case 0x4:
8559 case 0x5:
8560 goto do_ldst;
8561 case 0x6:
8562 case 0x7:
8563 if (insn & (1 << 4)) {
8564 ARCH(6);
8565 /* Armv6 Media instructions. */
8566 rm = insn & 0xf;
8567 rn = (insn >> 16) & 0xf;
8568 rd = (insn >> 12) & 0xf;
8569 rs = (insn >> 8) & 0xf;
8570 switch ((insn >> 23) & 3) {
8571 case 0: /* Parallel add/subtract. */
8572 op1 = (insn >> 20) & 7;
8573 tmp = load_reg(s, rn);
8574 tmp2 = load_reg(s, rm);
8575 sh = (insn >> 5) & 7;
8576 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8577 goto illegal_op;
8578 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8579 tcg_temp_free_i32(tmp2);
8580 store_reg(s, rd, tmp);
8581 break;
8582 case 1:
8583 if ((insn & 0x00700020) == 0) {
8584 /* Halfword pack. */
8585 tmp = load_reg(s, rn);
8586 tmp2 = load_reg(s, rm);
8587 shift = (insn >> 7) & 0x1f;
8588 if (insn & (1 << 6)) {
8589 /* pkhtb */
8590 if (shift == 0)
8591 shift = 31;
8592 tcg_gen_sari_i32(tmp2, tmp2, shift);
8593 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8594 tcg_gen_ext16u_i32(tmp2, tmp2);
8595 } else {
8596 /* pkhbt */
8597 if (shift)
8598 tcg_gen_shli_i32(tmp2, tmp2, shift);
8599 tcg_gen_ext16u_i32(tmp, tmp);
8600 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8602 tcg_gen_or_i32(tmp, tmp, tmp2);
8603 tcg_temp_free_i32(tmp2);
8604 store_reg(s, rd, tmp);
8605 } else if ((insn & 0x00200020) == 0x00200000) {
8606 /* [us]sat */
8607 tmp = load_reg(s, rm);
8608 shift = (insn >> 7) & 0x1f;
8609 if (insn & (1 << 6)) {
8610 if (shift == 0)
8611 shift = 31;
8612 tcg_gen_sari_i32(tmp, tmp, shift);
8613 } else {
8614 tcg_gen_shli_i32(tmp, tmp, shift);
8616 sh = (insn >> 16) & 0x1f;
8617 tmp2 = tcg_const_i32(sh);
8618 if (insn & (1 << 22))
8619 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8620 else
8621 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8622 tcg_temp_free_i32(tmp2);
8623 store_reg(s, rd, tmp);
8624 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8625 /* [us]sat16 */
8626 tmp = load_reg(s, rm);
8627 sh = (insn >> 16) & 0x1f;
8628 tmp2 = tcg_const_i32(sh);
8629 if (insn & (1 << 22))
8630 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8631 else
8632 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8633 tcg_temp_free_i32(tmp2);
8634 store_reg(s, rd, tmp);
8635 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8636 /* Select bytes. */
8637 tmp = load_reg(s, rn);
8638 tmp2 = load_reg(s, rm);
8639 tmp3 = tcg_temp_new_i32();
8640 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8641 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8642 tcg_temp_free_i32(tmp3);
8643 tcg_temp_free_i32(tmp2);
8644 store_reg(s, rd, tmp);
8645 } else if ((insn & 0x000003e0) == 0x00000060) {
8646 tmp = load_reg(s, rm);
8647 shift = (insn >> 10) & 3;
8648 /* ??? In many cases it's not necessary to do a
8649 rotate, a shift is sufficient. */
8650 if (shift != 0)
8651 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8652 op1 = (insn >> 20) & 7;
8653 switch (op1) {
8654 case 0: gen_sxtb16(tmp); break;
8655 case 2: gen_sxtb(tmp); break;
8656 case 3: gen_sxth(tmp); break;
8657 case 4: gen_uxtb16(tmp); break;
8658 case 6: gen_uxtb(tmp); break;
8659 case 7: gen_uxth(tmp); break;
8660 default: goto illegal_op;
8662 if (rn != 15) {
8663 tmp2 = load_reg(s, rn);
8664 if ((op1 & 3) == 0) {
8665 gen_add16(tmp, tmp2);
8666 } else {
8667 tcg_gen_add_i32(tmp, tmp, tmp2);
8668 tcg_temp_free_i32(tmp2);
8671 store_reg(s, rd, tmp);
8672 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8673 /* rev */
8674 tmp = load_reg(s, rm);
8675 if (insn & (1 << 22)) {
8676 if (insn & (1 << 7)) {
8677 gen_revsh(tmp);
8678 } else {
8679 ARCH(6T2);
8680 gen_helper_rbit(tmp, tmp);
8682 } else {
8683 if (insn & (1 << 7))
8684 gen_rev16(tmp);
8685 else
8686 tcg_gen_bswap32_i32(tmp, tmp);
8688 store_reg(s, rd, tmp);
8689 } else {
8690 goto illegal_op;
8692 break;
8693 case 2: /* Multiplies (Type 3). */
8694 switch ((insn >> 20) & 0x7) {
8695 case 5:
8696 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8697 /* op2 not 00x or 11x : UNDEF */
8698 goto illegal_op;
8700 /* Signed multiply most significant [accumulate].
8701 (SMMUL, SMMLA, SMMLS) */
8702 tmp = load_reg(s, rm);
8703 tmp2 = load_reg(s, rs);
8704 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8706 if (rd != 15) {
8707 tmp = load_reg(s, rd);
8708 if (insn & (1 << 6)) {
8709 tmp64 = gen_subq_msw(tmp64, tmp);
8710 } else {
8711 tmp64 = gen_addq_msw(tmp64, tmp);
8714 if (insn & (1 << 5)) {
8715 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8717 tcg_gen_shri_i64(tmp64, tmp64, 32);
8718 tmp = tcg_temp_new_i32();
8719 tcg_gen_extrl_i64_i32(tmp, tmp64);
8720 tcg_temp_free_i64(tmp64);
8721 store_reg(s, rn, tmp);
8722 break;
8723 case 0:
8724 case 4:
8725 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8726 if (insn & (1 << 7)) {
8727 goto illegal_op;
8729 tmp = load_reg(s, rm);
8730 tmp2 = load_reg(s, rs);
8731 if (insn & (1 << 5))
8732 gen_swap_half(tmp2);
8733 gen_smul_dual(tmp, tmp2);
8734 if (insn & (1 << 22)) {
8735 /* smlald, smlsld */
8736 TCGv_i64 tmp64_2;
8738 tmp64 = tcg_temp_new_i64();
8739 tmp64_2 = tcg_temp_new_i64();
8740 tcg_gen_ext_i32_i64(tmp64, tmp);
8741 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8742 tcg_temp_free_i32(tmp);
8743 tcg_temp_free_i32(tmp2);
8744 if (insn & (1 << 6)) {
8745 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8746 } else {
8747 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8749 tcg_temp_free_i64(tmp64_2);
8750 gen_addq(s, tmp64, rd, rn);
8751 gen_storeq_reg(s, rd, rn, tmp64);
8752 tcg_temp_free_i64(tmp64);
8753 } else {
8754 /* smuad, smusd, smlad, smlsd */
8755 if (insn & (1 << 6)) {
8756 /* This subtraction cannot overflow. */
8757 tcg_gen_sub_i32(tmp, tmp, tmp2);
8758 } else {
8759 /* This addition cannot overflow 32 bits;
8760 * however it may overflow considered as a
8761 * signed operation, in which case we must set
8762 * the Q flag.
8764 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8766 tcg_temp_free_i32(tmp2);
8767 if (rd != 15)
8769 tmp2 = load_reg(s, rd);
8770 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8771 tcg_temp_free_i32(tmp2);
8773 store_reg(s, rn, tmp);
8775 break;
8776 case 1:
8777 case 3:
8778 /* SDIV, UDIV */
8779 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
8780 goto illegal_op;
8782 if (((insn >> 5) & 7) || (rd != 15)) {
8783 goto illegal_op;
8785 tmp = load_reg(s, rm);
8786 tmp2 = load_reg(s, rs);
8787 if (insn & (1 << 21)) {
8788 gen_helper_udiv(tmp, tmp, tmp2);
8789 } else {
8790 gen_helper_sdiv(tmp, tmp, tmp2);
8792 tcg_temp_free_i32(tmp2);
8793 store_reg(s, rn, tmp);
8794 break;
8795 default:
8796 goto illegal_op;
8798 break;
8799 case 3:
8800 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8801 switch (op1) {
8802 case 0: /* Unsigned sum of absolute differences. */
8803 ARCH(6);
8804 tmp = load_reg(s, rm);
8805 tmp2 = load_reg(s, rs);
8806 gen_helper_usad8(tmp, tmp, tmp2);
8807 tcg_temp_free_i32(tmp2);
8808 if (rd != 15) {
8809 tmp2 = load_reg(s, rd);
8810 tcg_gen_add_i32(tmp, tmp, tmp2);
8811 tcg_temp_free_i32(tmp2);
8813 store_reg(s, rn, tmp);
8814 break;
8815 case 0x20: case 0x24: case 0x28: case 0x2c:
8816 /* Bitfield insert/clear. */
8817 ARCH(6T2);
8818 shift = (insn >> 7) & 0x1f;
8819 i = (insn >> 16) & 0x1f;
8820 if (i < shift) {
8821 /* UNPREDICTABLE; we choose to UNDEF */
8822 goto illegal_op;
8824 i = i + 1 - shift;
8825 if (rm == 15) {
8826 tmp = tcg_temp_new_i32();
8827 tcg_gen_movi_i32(tmp, 0);
8828 } else {
8829 tmp = load_reg(s, rm);
8831 if (i != 32) {
8832 tmp2 = load_reg(s, rd);
8833 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8834 tcg_temp_free_i32(tmp2);
8836 store_reg(s, rd, tmp);
8837 break;
8838 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8839 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8840 ARCH(6T2);
8841 tmp = load_reg(s, rm);
8842 shift = (insn >> 7) & 0x1f;
8843 i = ((insn >> 16) & 0x1f) + 1;
8844 if (shift + i > 32)
8845 goto illegal_op;
8846 if (i < 32) {
8847 if (op1 & 0x20) {
8848 gen_ubfx(tmp, shift, (1u << i) - 1);
8849 } else {
8850 gen_sbfx(tmp, shift, i);
8853 store_reg(s, rd, tmp);
8854 break;
8855 default:
8856 goto illegal_op;
8858 break;
8860 break;
8862 do_ldst:
8863 /* Check for undefined extension instructions
8864 * per the ARM Bible IE:
8865 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8867 sh = (0xf << 20) | (0xf << 4);
8868 if (op1 == 0x7 && ((insn & sh) == sh))
8870 goto illegal_op;
8872 /* load/store byte/word */
8873 rn = (insn >> 16) & 0xf;
8874 rd = (insn >> 12) & 0xf;
8875 tmp2 = load_reg(s, rn);
8876 if ((insn & 0x01200000) == 0x00200000) {
8877 /* ldrt/strt */
8878 i = get_a32_user_mem_index(s);
8879 } else {
8880 i = get_mem_index(s);
8882 if (insn & (1 << 24))
8883 gen_add_data_offset(s, insn, tmp2);
8884 if (insn & (1 << 20)) {
8885 /* load */
8886 tmp = tcg_temp_new_i32();
8887 if (insn & (1 << 22)) {
8888 gen_aa32_ld8u(tmp, tmp2, i);
8889 } else {
8890 gen_aa32_ld32u(tmp, tmp2, i);
8892 } else {
8893 /* store */
8894 tmp = load_reg(s, rd);
8895 if (insn & (1 << 22)) {
8896 gen_aa32_st8(tmp, tmp2, i);
8897 } else {
8898 gen_aa32_st32(tmp, tmp2, i);
8900 tcg_temp_free_i32(tmp);
8902 if (!(insn & (1 << 24))) {
8903 gen_add_data_offset(s, insn, tmp2);
8904 store_reg(s, rn, tmp2);
8905 } else if (insn & (1 << 21)) {
8906 store_reg(s, rn, tmp2);
8907 } else {
8908 tcg_temp_free_i32(tmp2);
8910 if (insn & (1 << 20)) {
8911 /* Complete the load. */
8912 store_reg_from_load(s, rd, tmp);
8914 break;
8915 case 0x08:
8916 case 0x09:
8918 int j, n, loaded_base;
8919 bool exc_return = false;
8920 bool is_load = extract32(insn, 20, 1);
8921 bool user = false;
8922 TCGv_i32 loaded_var;
8923 /* load/store multiple words */
8924 /* XXX: store correct base if write back */
8925 if (insn & (1 << 22)) {
8926 /* LDM (user), LDM (exception return) and STM (user) */
8927 if (IS_USER(s))
8928 goto illegal_op; /* only usable in supervisor mode */
8930 if (is_load && extract32(insn, 15, 1)) {
8931 exc_return = true;
8932 } else {
8933 user = true;
8936 rn = (insn >> 16) & 0xf;
8937 addr = load_reg(s, rn);
8939 /* compute total size */
8940 loaded_base = 0;
8941 TCGV_UNUSED_I32(loaded_var);
8942 n = 0;
8943 for(i=0;i<16;i++) {
8944 if (insn & (1 << i))
8945 n++;
8947 /* XXX: test invalid n == 0 case ? */
8948 if (insn & (1 << 23)) {
8949 if (insn & (1 << 24)) {
8950 /* pre increment */
8951 tcg_gen_addi_i32(addr, addr, 4);
8952 } else {
8953 /* post increment */
8955 } else {
8956 if (insn & (1 << 24)) {
8957 /* pre decrement */
8958 tcg_gen_addi_i32(addr, addr, -(n * 4));
8959 } else {
8960 /* post decrement */
8961 if (n != 1)
8962 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8965 j = 0;
8966 for(i=0;i<16;i++) {
8967 if (insn & (1 << i)) {
8968 if (is_load) {
8969 /* load */
8970 tmp = tcg_temp_new_i32();
8971 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8972 if (user) {
8973 tmp2 = tcg_const_i32(i);
8974 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8975 tcg_temp_free_i32(tmp2);
8976 tcg_temp_free_i32(tmp);
8977 } else if (i == rn) {
8978 loaded_var = tmp;
8979 loaded_base = 1;
8980 } else {
8981 store_reg_from_load(s, i, tmp);
8983 } else {
8984 /* store */
8985 if (i == 15) {
8986 /* special case: r15 = PC + 8 */
8987 val = (long)s->pc + 4;
8988 tmp = tcg_temp_new_i32();
8989 tcg_gen_movi_i32(tmp, val);
8990 } else if (user) {
8991 tmp = tcg_temp_new_i32();
8992 tmp2 = tcg_const_i32(i);
8993 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8994 tcg_temp_free_i32(tmp2);
8995 } else {
8996 tmp = load_reg(s, i);
8998 gen_aa32_st32(tmp, addr, get_mem_index(s));
8999 tcg_temp_free_i32(tmp);
9001 j++;
9002 /* no need to add after the last transfer */
9003 if (j != n)
9004 tcg_gen_addi_i32(addr, addr, 4);
9007 if (insn & (1 << 21)) {
9008 /* write back */
9009 if (insn & (1 << 23)) {
9010 if (insn & (1 << 24)) {
9011 /* pre increment */
9012 } else {
9013 /* post increment */
9014 tcg_gen_addi_i32(addr, addr, 4);
9016 } else {
9017 if (insn & (1 << 24)) {
9018 /* pre decrement */
9019 if (n != 1)
9020 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9021 } else {
9022 /* post decrement */
9023 tcg_gen_addi_i32(addr, addr, -(n * 4));
9026 store_reg(s, rn, addr);
9027 } else {
9028 tcg_temp_free_i32(addr);
9030 if (loaded_base) {
9031 store_reg(s, rn, loaded_var);
9033 if (exc_return) {
9034 /* Restore CPSR from SPSR. */
9035 tmp = load_cpu_field(spsr);
9036 gen_set_cpsr(tmp, CPSR_ERET_MASK);
9037 tcg_temp_free_i32(tmp);
9038 s->is_jmp = DISAS_UPDATE;
9041 break;
9042 case 0xa:
9043 case 0xb:
9045 int32_t offset;
9047 /* branch (and link) */
9048 val = (int32_t)s->pc;
9049 if (insn & (1 << 24)) {
9050 tmp = tcg_temp_new_i32();
9051 tcg_gen_movi_i32(tmp, val);
9052 store_reg(s, 14, tmp);
9054 offset = sextract32(insn << 2, 0, 26);
9055 val += offset + 4;
9056 gen_jmp(s, val);
9058 break;
9059 case 0xc:
9060 case 0xd:
9061 case 0xe:
9062 if (((insn >> 8) & 0xe) == 10) {
9063 /* VFP. */
9064 if (disas_vfp_insn(s, insn)) {
9065 goto illegal_op;
9067 } else if (disas_coproc_insn(s, insn)) {
9068 /* Coprocessor. */
9069 goto illegal_op;
9071 break;
9072 case 0xf:
9073 /* swi */
9074 gen_set_pc_im(s, s->pc);
9075 s->svc_imm = extract32(insn, 0, 24);
9076 s->is_jmp = DISAS_SWI;
9077 break;
9078 default:
9079 illegal_op:
9080 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9081 default_exception_el(s));
9082 break;
9087 /* Return true if this is a Thumb-2 logical op. */
9088 static int
9089 thumb2_logic_op(int op)
9091 return (op < 8);
9094 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9095 then set condition code flags based on the result of the operation.
9096 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9097 to the high bit of T1.
9098 Returns zero if the opcode is valid. */
9100 static int
9101 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9102 TCGv_i32 t0, TCGv_i32 t1)
9104 int logic_cc;
9106 logic_cc = 0;
9107 switch (op) {
9108 case 0: /* and */
9109 tcg_gen_and_i32(t0, t0, t1);
9110 logic_cc = conds;
9111 break;
9112 case 1: /* bic */
9113 tcg_gen_andc_i32(t0, t0, t1);
9114 logic_cc = conds;
9115 break;
9116 case 2: /* orr */
9117 tcg_gen_or_i32(t0, t0, t1);
9118 logic_cc = conds;
9119 break;
9120 case 3: /* orn */
9121 tcg_gen_orc_i32(t0, t0, t1);
9122 logic_cc = conds;
9123 break;
9124 case 4: /* eor */
9125 tcg_gen_xor_i32(t0, t0, t1);
9126 logic_cc = conds;
9127 break;
9128 case 8: /* add */
9129 if (conds)
9130 gen_add_CC(t0, t0, t1);
9131 else
9132 tcg_gen_add_i32(t0, t0, t1);
9133 break;
9134 case 10: /* adc */
9135 if (conds)
9136 gen_adc_CC(t0, t0, t1);
9137 else
9138 gen_adc(t0, t1);
9139 break;
9140 case 11: /* sbc */
9141 if (conds) {
9142 gen_sbc_CC(t0, t0, t1);
9143 } else {
9144 gen_sub_carry(t0, t0, t1);
9146 break;
9147 case 13: /* sub */
9148 if (conds)
9149 gen_sub_CC(t0, t0, t1);
9150 else
9151 tcg_gen_sub_i32(t0, t0, t1);
9152 break;
9153 case 14: /* rsb */
9154 if (conds)
9155 gen_sub_CC(t0, t1, t0);
9156 else
9157 tcg_gen_sub_i32(t0, t1, t0);
9158 break;
9159 default: /* 5, 6, 7, 9, 12, 15. */
9160 return 1;
9162 if (logic_cc) {
9163 gen_logic_CC(t0);
9164 if (shifter_out)
9165 gen_set_CF_bit31(t1);
9167 return 0;
9170 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9171 is not legal. */
9172 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9174 uint32_t insn, imm, shift, offset;
9175 uint32_t rd, rn, rm, rs;
9176 TCGv_i32 tmp;
9177 TCGv_i32 tmp2;
9178 TCGv_i32 tmp3;
9179 TCGv_i32 addr;
9180 TCGv_i64 tmp64;
9181 int op;
9182 int shiftop;
9183 int conds;
9184 int logic_cc;
9186 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9187 || arm_dc_feature(s, ARM_FEATURE_M))) {
9188 /* Thumb-1 cores may need to treat bl and blx as a pair of
9189 16-bit instructions to get correct prefetch abort behavior. */
9190 insn = insn_hw1;
9191 if ((insn & (1 << 12)) == 0) {
9192 ARCH(5);
9193 /* Second half of blx. */
9194 offset = ((insn & 0x7ff) << 1);
9195 tmp = load_reg(s, 14);
9196 tcg_gen_addi_i32(tmp, tmp, offset);
9197 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9199 tmp2 = tcg_temp_new_i32();
9200 tcg_gen_movi_i32(tmp2, s->pc | 1);
9201 store_reg(s, 14, tmp2);
9202 gen_bx(s, tmp);
9203 return 0;
9205 if (insn & (1 << 11)) {
9206 /* Second half of bl. */
9207 offset = ((insn & 0x7ff) << 1) | 1;
9208 tmp = load_reg(s, 14);
9209 tcg_gen_addi_i32(tmp, tmp, offset);
9211 tmp2 = tcg_temp_new_i32();
9212 tcg_gen_movi_i32(tmp2, s->pc | 1);
9213 store_reg(s, 14, tmp2);
9214 gen_bx(s, tmp);
9215 return 0;
9217 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9218 /* Instruction spans a page boundary. Implement it as two
9219 16-bit instructions in case the second half causes an
9220 prefetch abort. */
9221 offset = ((int32_t)insn << 21) >> 9;
9222 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9223 return 0;
9225 /* Fall through to 32-bit decode. */
9228 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9229 s->pc += 2;
9230 insn |= (uint32_t)insn_hw1 << 16;
9232 if ((insn & 0xf800e800) != 0xf000e800) {
9233 ARCH(6T2);
9236 rn = (insn >> 16) & 0xf;
9237 rs = (insn >> 12) & 0xf;
9238 rd = (insn >> 8) & 0xf;
9239 rm = insn & 0xf;
9240 switch ((insn >> 25) & 0xf) {
9241 case 0: case 1: case 2: case 3:
9242 /* 16-bit instructions. Should never happen. */
9243 abort();
9244 case 4:
9245 if (insn & (1 << 22)) {
9246 /* Other load/store, table branch. */
9247 if (insn & 0x01200000) {
9248 /* Load/store doubleword. */
9249 if (rn == 15) {
9250 addr = tcg_temp_new_i32();
9251 tcg_gen_movi_i32(addr, s->pc & ~3);
9252 } else {
9253 addr = load_reg(s, rn);
9255 offset = (insn & 0xff) * 4;
9256 if ((insn & (1 << 23)) == 0)
9257 offset = -offset;
9258 if (insn & (1 << 24)) {
9259 tcg_gen_addi_i32(addr, addr, offset);
9260 offset = 0;
9262 if (insn & (1 << 20)) {
9263 /* ldrd */
9264 tmp = tcg_temp_new_i32();
9265 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9266 store_reg(s, rs, tmp);
9267 tcg_gen_addi_i32(addr, addr, 4);
9268 tmp = tcg_temp_new_i32();
9269 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9270 store_reg(s, rd, tmp);
9271 } else {
9272 /* strd */
9273 tmp = load_reg(s, rs);
9274 gen_aa32_st32(tmp, addr, get_mem_index(s));
9275 tcg_temp_free_i32(tmp);
9276 tcg_gen_addi_i32(addr, addr, 4);
9277 tmp = load_reg(s, rd);
9278 gen_aa32_st32(tmp, addr, get_mem_index(s));
9279 tcg_temp_free_i32(tmp);
9281 if (insn & (1 << 21)) {
9282 /* Base writeback. */
9283 if (rn == 15)
9284 goto illegal_op;
9285 tcg_gen_addi_i32(addr, addr, offset - 4);
9286 store_reg(s, rn, addr);
9287 } else {
9288 tcg_temp_free_i32(addr);
9290 } else if ((insn & (1 << 23)) == 0) {
9291 /* Load/store exclusive word. */
9292 addr = tcg_temp_local_new_i32();
9293 load_reg_var(s, addr, rn);
9294 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9295 if (insn & (1 << 20)) {
9296 gen_load_exclusive(s, rs, 15, addr, 2);
9297 } else {
9298 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9300 tcg_temp_free_i32(addr);
9301 } else if ((insn & (7 << 5)) == 0) {
9302 /* Table Branch. */
9303 if (rn == 15) {
9304 addr = tcg_temp_new_i32();
9305 tcg_gen_movi_i32(addr, s->pc);
9306 } else {
9307 addr = load_reg(s, rn);
9309 tmp = load_reg(s, rm);
9310 tcg_gen_add_i32(addr, addr, tmp);
9311 if (insn & (1 << 4)) {
9312 /* tbh */
9313 tcg_gen_add_i32(addr, addr, tmp);
9314 tcg_temp_free_i32(tmp);
9315 tmp = tcg_temp_new_i32();
9316 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9317 } else { /* tbb */
9318 tcg_temp_free_i32(tmp);
9319 tmp = tcg_temp_new_i32();
9320 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9322 tcg_temp_free_i32(addr);
9323 tcg_gen_shli_i32(tmp, tmp, 1);
9324 tcg_gen_addi_i32(tmp, tmp, s->pc);
9325 store_reg(s, 15, tmp);
9326 } else {
9327 int op2 = (insn >> 6) & 0x3;
9328 op = (insn >> 4) & 0x3;
9329 switch (op2) {
9330 case 0:
9331 goto illegal_op;
9332 case 1:
9333 /* Load/store exclusive byte/halfword/doubleword */
9334 if (op == 2) {
9335 goto illegal_op;
9337 ARCH(7);
9338 break;
9339 case 2:
9340 /* Load-acquire/store-release */
9341 if (op == 3) {
9342 goto illegal_op;
9344 /* Fall through */
9345 case 3:
9346 /* Load-acquire/store-release exclusive */
9347 ARCH(8);
9348 break;
9350 addr = tcg_temp_local_new_i32();
9351 load_reg_var(s, addr, rn);
9352 if (!(op2 & 1)) {
9353 if (insn & (1 << 20)) {
9354 tmp = tcg_temp_new_i32();
9355 switch (op) {
9356 case 0: /* ldab */
9357 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9358 break;
9359 case 1: /* ldah */
9360 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9361 break;
9362 case 2: /* lda */
9363 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9364 break;
9365 default:
9366 abort();
9368 store_reg(s, rs, tmp);
9369 } else {
9370 tmp = load_reg(s, rs);
9371 switch (op) {
9372 case 0: /* stlb */
9373 gen_aa32_st8(tmp, addr, get_mem_index(s));
9374 break;
9375 case 1: /* stlh */
9376 gen_aa32_st16(tmp, addr, get_mem_index(s));
9377 break;
9378 case 2: /* stl */
9379 gen_aa32_st32(tmp, addr, get_mem_index(s));
9380 break;
9381 default:
9382 abort();
9384 tcg_temp_free_i32(tmp);
9386 } else if (insn & (1 << 20)) {
9387 gen_load_exclusive(s, rs, rd, addr, op);
9388 } else {
9389 gen_store_exclusive(s, rm, rs, rd, addr, op);
9391 tcg_temp_free_i32(addr);
9393 } else {
9394 /* Load/store multiple, RFE, SRS. */
9395 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9396 /* RFE, SRS: not available in user mode or on M profile */
9397 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9398 goto illegal_op;
9400 if (insn & (1 << 20)) {
9401 /* rfe */
9402 addr = load_reg(s, rn);
9403 if ((insn & (1 << 24)) == 0)
9404 tcg_gen_addi_i32(addr, addr, -8);
9405 /* Load PC into tmp and CPSR into tmp2. */
9406 tmp = tcg_temp_new_i32();
9407 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9408 tcg_gen_addi_i32(addr, addr, 4);
9409 tmp2 = tcg_temp_new_i32();
9410 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
9411 if (insn & (1 << 21)) {
9412 /* Base writeback. */
9413 if (insn & (1 << 24)) {
9414 tcg_gen_addi_i32(addr, addr, 4);
9415 } else {
9416 tcg_gen_addi_i32(addr, addr, -4);
9418 store_reg(s, rn, addr);
9419 } else {
9420 tcg_temp_free_i32(addr);
9422 gen_rfe(s, tmp, tmp2);
9423 } else {
9424 /* srs */
9425 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9426 insn & (1 << 21));
9428 } else {
9429 int i, loaded_base = 0;
9430 TCGv_i32 loaded_var;
9431 /* Load/store multiple. */
9432 addr = load_reg(s, rn);
9433 offset = 0;
9434 for (i = 0; i < 16; i++) {
9435 if (insn & (1 << i))
9436 offset += 4;
9438 if (insn & (1 << 24)) {
9439 tcg_gen_addi_i32(addr, addr, -offset);
9442 TCGV_UNUSED_I32(loaded_var);
9443 for (i = 0; i < 16; i++) {
9444 if ((insn & (1 << i)) == 0)
9445 continue;
9446 if (insn & (1 << 20)) {
9447 /* Load. */
9448 tmp = tcg_temp_new_i32();
9449 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9450 if (i == 15) {
9451 gen_bx(s, tmp);
9452 } else if (i == rn) {
9453 loaded_var = tmp;
9454 loaded_base = 1;
9455 } else {
9456 store_reg(s, i, tmp);
9458 } else {
9459 /* Store. */
9460 tmp = load_reg(s, i);
9461 gen_aa32_st32(tmp, addr, get_mem_index(s));
9462 tcg_temp_free_i32(tmp);
9464 tcg_gen_addi_i32(addr, addr, 4);
9466 if (loaded_base) {
9467 store_reg(s, rn, loaded_var);
9469 if (insn & (1 << 21)) {
9470 /* Base register writeback. */
9471 if (insn & (1 << 24)) {
9472 tcg_gen_addi_i32(addr, addr, -offset);
9474 /* Fault if writeback register is in register list. */
9475 if (insn & (1 << rn))
9476 goto illegal_op;
9477 store_reg(s, rn, addr);
9478 } else {
9479 tcg_temp_free_i32(addr);
9483 break;
9484 case 5:
9486 op = (insn >> 21) & 0xf;
9487 if (op == 6) {
9488 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9489 goto illegal_op;
9491 /* Halfword pack. */
9492 tmp = load_reg(s, rn);
9493 tmp2 = load_reg(s, rm);
9494 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9495 if (insn & (1 << 5)) {
9496 /* pkhtb */
9497 if (shift == 0)
9498 shift = 31;
9499 tcg_gen_sari_i32(tmp2, tmp2, shift);
9500 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9501 tcg_gen_ext16u_i32(tmp2, tmp2);
9502 } else {
9503 /* pkhbt */
9504 if (shift)
9505 tcg_gen_shli_i32(tmp2, tmp2, shift);
9506 tcg_gen_ext16u_i32(tmp, tmp);
9507 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9509 tcg_gen_or_i32(tmp, tmp, tmp2);
9510 tcg_temp_free_i32(tmp2);
9511 store_reg(s, rd, tmp);
9512 } else {
9513 /* Data processing register constant shift. */
9514 if (rn == 15) {
9515 tmp = tcg_temp_new_i32();
9516 tcg_gen_movi_i32(tmp, 0);
9517 } else {
9518 tmp = load_reg(s, rn);
9520 tmp2 = load_reg(s, rm);
9522 shiftop = (insn >> 4) & 3;
9523 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9524 conds = (insn & (1 << 20)) != 0;
9525 logic_cc = (conds && thumb2_logic_op(op));
9526 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9527 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9528 goto illegal_op;
9529 tcg_temp_free_i32(tmp2);
9530 if (rd != 15) {
9531 store_reg(s, rd, tmp);
9532 } else {
9533 tcg_temp_free_i32(tmp);
9536 break;
9537 case 13: /* Misc data processing. */
9538 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9539 if (op < 4 && (insn & 0xf000) != 0xf000)
9540 goto illegal_op;
9541 switch (op) {
9542 case 0: /* Register controlled shift. */
9543 tmp = load_reg(s, rn);
9544 tmp2 = load_reg(s, rm);
9545 if ((insn & 0x70) != 0)
9546 goto illegal_op;
9547 op = (insn >> 21) & 3;
9548 logic_cc = (insn & (1 << 20)) != 0;
9549 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9550 if (logic_cc)
9551 gen_logic_CC(tmp);
9552 store_reg_bx(s, rd, tmp);
9553 break;
9554 case 1: /* Sign/zero extend. */
9555 op = (insn >> 20) & 7;
9556 switch (op) {
9557 case 0: /* SXTAH, SXTH */
9558 case 1: /* UXTAH, UXTH */
9559 case 4: /* SXTAB, SXTB */
9560 case 5: /* UXTAB, UXTB */
9561 break;
9562 case 2: /* SXTAB16, SXTB16 */
9563 case 3: /* UXTAB16, UXTB16 */
9564 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9565 goto illegal_op;
9567 break;
9568 default:
9569 goto illegal_op;
9571 if (rn != 15) {
9572 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9573 goto illegal_op;
9576 tmp = load_reg(s, rm);
9577 shift = (insn >> 4) & 3;
9578 /* ??? In many cases it's not necessary to do a
9579 rotate, a shift is sufficient. */
9580 if (shift != 0)
9581 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9582 op = (insn >> 20) & 7;
9583 switch (op) {
9584 case 0: gen_sxth(tmp); break;
9585 case 1: gen_uxth(tmp); break;
9586 case 2: gen_sxtb16(tmp); break;
9587 case 3: gen_uxtb16(tmp); break;
9588 case 4: gen_sxtb(tmp); break;
9589 case 5: gen_uxtb(tmp); break;
9590 default:
9591 g_assert_not_reached();
9593 if (rn != 15) {
9594 tmp2 = load_reg(s, rn);
9595 if ((op >> 1) == 1) {
9596 gen_add16(tmp, tmp2);
9597 } else {
9598 tcg_gen_add_i32(tmp, tmp, tmp2);
9599 tcg_temp_free_i32(tmp2);
9602 store_reg(s, rd, tmp);
9603 break;
9604 case 2: /* SIMD add/subtract. */
9605 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9606 goto illegal_op;
9608 op = (insn >> 20) & 7;
9609 shift = (insn >> 4) & 7;
9610 if ((op & 3) == 3 || (shift & 3) == 3)
9611 goto illegal_op;
9612 tmp = load_reg(s, rn);
9613 tmp2 = load_reg(s, rm);
9614 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9615 tcg_temp_free_i32(tmp2);
9616 store_reg(s, rd, tmp);
9617 break;
9618 case 3: /* Other data processing. */
9619 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9620 if (op < 4) {
9621 /* Saturating add/subtract. */
9622 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9623 goto illegal_op;
9625 tmp = load_reg(s, rn);
9626 tmp2 = load_reg(s, rm);
9627 if (op & 1)
9628 gen_helper_double_saturate(tmp, cpu_env, tmp);
9629 if (op & 2)
9630 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9631 else
9632 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9633 tcg_temp_free_i32(tmp2);
9634 } else {
9635 switch (op) {
9636 case 0x0a: /* rbit */
9637 case 0x08: /* rev */
9638 case 0x09: /* rev16 */
9639 case 0x0b: /* revsh */
9640 case 0x18: /* clz */
9641 break;
9642 case 0x10: /* sel */
9643 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9644 goto illegal_op;
9646 break;
9647 case 0x20: /* crc32/crc32c */
9648 case 0x21:
9649 case 0x22:
9650 case 0x28:
9651 case 0x29:
9652 case 0x2a:
9653 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
9654 goto illegal_op;
9656 break;
9657 default:
9658 goto illegal_op;
9660 tmp = load_reg(s, rn);
9661 switch (op) {
9662 case 0x0a: /* rbit */
9663 gen_helper_rbit(tmp, tmp);
9664 break;
9665 case 0x08: /* rev */
9666 tcg_gen_bswap32_i32(tmp, tmp);
9667 break;
9668 case 0x09: /* rev16 */
9669 gen_rev16(tmp);
9670 break;
9671 case 0x0b: /* revsh */
9672 gen_revsh(tmp);
9673 break;
9674 case 0x10: /* sel */
9675 tmp2 = load_reg(s, rm);
9676 tmp3 = tcg_temp_new_i32();
9677 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9678 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9679 tcg_temp_free_i32(tmp3);
9680 tcg_temp_free_i32(tmp2);
9681 break;
9682 case 0x18: /* clz */
9683 gen_helper_clz(tmp, tmp);
9684 break;
9685 case 0x20:
9686 case 0x21:
9687 case 0x22:
9688 case 0x28:
9689 case 0x29:
9690 case 0x2a:
9692 /* crc32/crc32c */
9693 uint32_t sz = op & 0x3;
9694 uint32_t c = op & 0x8;
9696 tmp2 = load_reg(s, rm);
9697 if (sz == 0) {
9698 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9699 } else if (sz == 1) {
9700 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9702 tmp3 = tcg_const_i32(1 << sz);
9703 if (c) {
9704 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9705 } else {
9706 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9708 tcg_temp_free_i32(tmp2);
9709 tcg_temp_free_i32(tmp3);
9710 break;
9712 default:
9713 g_assert_not_reached();
9716 store_reg(s, rd, tmp);
9717 break;
9718 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9719 switch ((insn >> 20) & 7) {
9720 case 0: /* 32 x 32 -> 32 */
9721 case 7: /* Unsigned sum of absolute differences. */
9722 break;
9723 case 1: /* 16 x 16 -> 32 */
9724 case 2: /* Dual multiply add. */
9725 case 3: /* 32 * 16 -> 32msb */
9726 case 4: /* Dual multiply subtract. */
9727 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9728 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9729 goto illegal_op;
9731 break;
9733 op = (insn >> 4) & 0xf;
9734 tmp = load_reg(s, rn);
9735 tmp2 = load_reg(s, rm);
9736 switch ((insn >> 20) & 7) {
9737 case 0: /* 32 x 32 -> 32 */
9738 tcg_gen_mul_i32(tmp, tmp, tmp2);
9739 tcg_temp_free_i32(tmp2);
9740 if (rs != 15) {
9741 tmp2 = load_reg(s, rs);
9742 if (op)
9743 tcg_gen_sub_i32(tmp, tmp2, tmp);
9744 else
9745 tcg_gen_add_i32(tmp, tmp, tmp2);
9746 tcg_temp_free_i32(tmp2);
9748 break;
9749 case 1: /* 16 x 16 -> 32 */
9750 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9751 tcg_temp_free_i32(tmp2);
9752 if (rs != 15) {
9753 tmp2 = load_reg(s, rs);
9754 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9755 tcg_temp_free_i32(tmp2);
9757 break;
9758 case 2: /* Dual multiply add. */
9759 case 4: /* Dual multiply subtract. */
9760 if (op)
9761 gen_swap_half(tmp2);
9762 gen_smul_dual(tmp, tmp2);
9763 if (insn & (1 << 22)) {
9764 /* This subtraction cannot overflow. */
9765 tcg_gen_sub_i32(tmp, tmp, tmp2);
9766 } else {
9767 /* This addition cannot overflow 32 bits;
9768 * however it may overflow considered as a signed
9769 * operation, in which case we must set the Q flag.
9771 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9773 tcg_temp_free_i32(tmp2);
9774 if (rs != 15)
9776 tmp2 = load_reg(s, rs);
9777 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9778 tcg_temp_free_i32(tmp2);
9780 break;
9781 case 3: /* 32 * 16 -> 32msb */
9782 if (op)
9783 tcg_gen_sari_i32(tmp2, tmp2, 16);
9784 else
9785 gen_sxth(tmp2);
9786 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9787 tcg_gen_shri_i64(tmp64, tmp64, 16);
9788 tmp = tcg_temp_new_i32();
9789 tcg_gen_extrl_i64_i32(tmp, tmp64);
9790 tcg_temp_free_i64(tmp64);
9791 if (rs != 15)
9793 tmp2 = load_reg(s, rs);
9794 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9795 tcg_temp_free_i32(tmp2);
9797 break;
9798 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9799 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9800 if (rs != 15) {
9801 tmp = load_reg(s, rs);
9802 if (insn & (1 << 20)) {
9803 tmp64 = gen_addq_msw(tmp64, tmp);
9804 } else {
9805 tmp64 = gen_subq_msw(tmp64, tmp);
9808 if (insn & (1 << 4)) {
9809 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9811 tcg_gen_shri_i64(tmp64, tmp64, 32);
9812 tmp = tcg_temp_new_i32();
9813 tcg_gen_extrl_i64_i32(tmp, tmp64);
9814 tcg_temp_free_i64(tmp64);
9815 break;
9816 case 7: /* Unsigned sum of absolute differences. */
9817 gen_helper_usad8(tmp, tmp, tmp2);
9818 tcg_temp_free_i32(tmp2);
9819 if (rs != 15) {
9820 tmp2 = load_reg(s, rs);
9821 tcg_gen_add_i32(tmp, tmp, tmp2);
9822 tcg_temp_free_i32(tmp2);
9824 break;
9826 store_reg(s, rd, tmp);
9827 break;
9828 case 6: case 7: /* 64-bit multiply, Divide. */
9829 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9830 tmp = load_reg(s, rn);
9831 tmp2 = load_reg(s, rm);
9832 if ((op & 0x50) == 0x10) {
9833 /* sdiv, udiv */
9834 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
9835 goto illegal_op;
9837 if (op & 0x20)
9838 gen_helper_udiv(tmp, tmp, tmp2);
9839 else
9840 gen_helper_sdiv(tmp, tmp, tmp2);
9841 tcg_temp_free_i32(tmp2);
9842 store_reg(s, rd, tmp);
9843 } else if ((op & 0xe) == 0xc) {
9844 /* Dual multiply accumulate long. */
9845 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9846 tcg_temp_free_i32(tmp);
9847 tcg_temp_free_i32(tmp2);
9848 goto illegal_op;
9850 if (op & 1)
9851 gen_swap_half(tmp2);
9852 gen_smul_dual(tmp, tmp2);
9853 if (op & 0x10) {
9854 tcg_gen_sub_i32(tmp, tmp, tmp2);
9855 } else {
9856 tcg_gen_add_i32(tmp, tmp, tmp2);
9858 tcg_temp_free_i32(tmp2);
9859 /* BUGFIX */
9860 tmp64 = tcg_temp_new_i64();
9861 tcg_gen_ext_i32_i64(tmp64, tmp);
9862 tcg_temp_free_i32(tmp);
9863 gen_addq(s, tmp64, rs, rd);
9864 gen_storeq_reg(s, rs, rd, tmp64);
9865 tcg_temp_free_i64(tmp64);
9866 } else {
9867 if (op & 0x20) {
9868 /* Unsigned 64-bit multiply */
9869 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9870 } else {
9871 if (op & 8) {
9872 /* smlalxy */
9873 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9874 tcg_temp_free_i32(tmp2);
9875 tcg_temp_free_i32(tmp);
9876 goto illegal_op;
9878 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9879 tcg_temp_free_i32(tmp2);
9880 tmp64 = tcg_temp_new_i64();
9881 tcg_gen_ext_i32_i64(tmp64, tmp);
9882 tcg_temp_free_i32(tmp);
9883 } else {
9884 /* Signed 64-bit multiply */
9885 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9888 if (op & 4) {
9889 /* umaal */
9890 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9891 tcg_temp_free_i64(tmp64);
9892 goto illegal_op;
9894 gen_addq_lo(s, tmp64, rs);
9895 gen_addq_lo(s, tmp64, rd);
9896 } else if (op & 0x40) {
9897 /* 64-bit accumulate. */
9898 gen_addq(s, tmp64, rs, rd);
9900 gen_storeq_reg(s, rs, rd, tmp64);
9901 tcg_temp_free_i64(tmp64);
9903 break;
9905 break;
9906 case 6: case 7: case 14: case 15:
9907 /* Coprocessor. */
9908 if (((insn >> 24) & 3) == 3) {
9909 /* Translate into the equivalent ARM encoding. */
9910 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9911 if (disas_neon_data_insn(s, insn)) {
9912 goto illegal_op;
9914 } else if (((insn >> 8) & 0xe) == 10) {
9915 if (disas_vfp_insn(s, insn)) {
9916 goto illegal_op;
9918 } else {
9919 if (insn & (1 << 28))
9920 goto illegal_op;
9921 if (disas_coproc_insn(s, insn)) {
9922 goto illegal_op;
9925 break;
9926 case 8: case 9: case 10: case 11:
9927 if (insn & (1 << 15)) {
9928 /* Branches, misc control. */
9929 if (insn & 0x5000) {
9930 /* Unconditional branch. */
9931 /* signextend(hw1[10:0]) -> offset[:12]. */
9932 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9933 /* hw1[10:0] -> offset[11:1]. */
9934 offset |= (insn & 0x7ff) << 1;
9935 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9936 offset[24:22] already have the same value because of the
9937 sign extension above. */
9938 offset ^= ((~insn) & (1 << 13)) << 10;
9939 offset ^= ((~insn) & (1 << 11)) << 11;
9941 if (insn & (1 << 14)) {
9942 /* Branch and link. */
9943 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9946 offset += s->pc;
9947 if (insn & (1 << 12)) {
9948 /* b/bl */
9949 gen_jmp(s, offset);
9950 } else {
9951 /* blx */
9952 offset &= ~(uint32_t)2;
9953 /* thumb2 bx, no need to check */
9954 gen_bx_im(s, offset);
9956 } else if (((insn >> 23) & 7) == 7) {
9957 /* Misc control */
9958 if (insn & (1 << 13))
9959 goto illegal_op;
9961 if (insn & (1 << 26)) {
9962 if (!(insn & (1 << 20))) {
9963 /* Hypervisor call (v7) */
9964 int imm16 = extract32(insn, 16, 4) << 12
9965 | extract32(insn, 0, 12);
9966 ARCH(7);
9967 if (IS_USER(s)) {
9968 goto illegal_op;
9970 gen_hvc(s, imm16);
9971 } else {
9972 /* Secure monitor call (v6+) */
9973 ARCH(6K);
9974 if (IS_USER(s)) {
9975 goto illegal_op;
9977 gen_smc(s);
9979 } else {
9980 op = (insn >> 20) & 7;
9981 switch (op) {
9982 case 0: /* msr cpsr. */
9983 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9984 tmp = load_reg(s, rn);
9985 addr = tcg_const_i32(insn & 0xff);
9986 gen_helper_v7m_msr(cpu_env, addr, tmp);
9987 tcg_temp_free_i32(addr);
9988 tcg_temp_free_i32(tmp);
9989 gen_lookup_tb(s);
9990 break;
9992 /* fall through */
9993 case 1: /* msr spsr. */
9994 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9995 goto illegal_op;
9997 tmp = load_reg(s, rn);
9998 if (gen_set_psr(s,
9999 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10000 op == 1, tmp))
10001 goto illegal_op;
10002 break;
10003 case 2: /* cps, nop-hint. */
10004 if (((insn >> 8) & 7) == 0) {
10005 gen_nop_hint(s, insn & 0xff);
10007 /* Implemented as NOP in user mode. */
10008 if (IS_USER(s))
10009 break;
10010 offset = 0;
10011 imm = 0;
10012 if (insn & (1 << 10)) {
10013 if (insn & (1 << 7))
10014 offset |= CPSR_A;
10015 if (insn & (1 << 6))
10016 offset |= CPSR_I;
10017 if (insn & (1 << 5))
10018 offset |= CPSR_F;
10019 if (insn & (1 << 9))
10020 imm = CPSR_A | CPSR_I | CPSR_F;
10022 if (insn & (1 << 8)) {
10023 offset |= 0x1f;
10024 imm |= (insn & 0x1f);
10026 if (offset) {
10027 gen_set_psr_im(s, offset, 0, imm);
10029 break;
10030 case 3: /* Special control operations. */
10031 ARCH(7);
10032 op = (insn >> 4) & 0xf;
10033 switch (op) {
10034 case 2: /* clrex */
10035 gen_clrex(s);
10036 break;
10037 case 4: /* dsb */
10038 case 5: /* dmb */
10039 /* These execute as NOPs. */
10040 break;
10041 case 6: /* isb */
10042 /* We need to break the TB after this insn
10043 * to execute self-modifying code correctly
10044 * and also to take any pending interrupts
10045 * immediately.
10047 gen_lookup_tb(s);
10048 break;
10049 default:
10050 goto illegal_op;
10052 break;
10053 case 4: /* bxj */
10054 /* Trivial implementation equivalent to bx. */
10055 tmp = load_reg(s, rn);
10056 gen_bx(s, tmp);
10057 break;
10058 case 5: /* Exception return. */
10059 if (IS_USER(s)) {
10060 goto illegal_op;
10062 if (rn != 14 || rd != 15) {
10063 goto illegal_op;
10065 tmp = load_reg(s, rn);
10066 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10067 gen_exception_return(s, tmp);
10068 break;
10069 case 6: /* mrs cpsr. */
10070 tmp = tcg_temp_new_i32();
10071 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10072 addr = tcg_const_i32(insn & 0xff);
10073 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10074 tcg_temp_free_i32(addr);
10075 } else {
10076 gen_helper_cpsr_read(tmp, cpu_env);
10078 store_reg(s, rd, tmp);
10079 break;
10080 case 7: /* mrs spsr. */
10081 /* Not accessible in user mode. */
10082 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10083 goto illegal_op;
10085 tmp = load_cpu_field(spsr);
10086 store_reg(s, rd, tmp);
10087 break;
10090 } else {
10091 /* Conditional branch. */
10092 op = (insn >> 22) & 0xf;
10093 /* Generate a conditional jump to next instruction. */
10094 s->condlabel = gen_new_label();
10095 arm_gen_test_cc(op ^ 1, s->condlabel);
10096 s->condjmp = 1;
10098 /* offset[11:1] = insn[10:0] */
10099 offset = (insn & 0x7ff) << 1;
10100 /* offset[17:12] = insn[21:16]. */
10101 offset |= (insn & 0x003f0000) >> 4;
10102 /* offset[31:20] = insn[26]. */
10103 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10104 /* offset[18] = insn[13]. */
10105 offset |= (insn & (1 << 13)) << 5;
10106 /* offset[19] = insn[11]. */
10107 offset |= (insn & (1 << 11)) << 8;
10109 /* jump to the offset */
10110 gen_jmp(s, s->pc + offset);
10112 } else {
10113 /* Data processing immediate. */
10114 if (insn & (1 << 25)) {
10115 if (insn & (1 << 24)) {
10116 if (insn & (1 << 20))
10117 goto illegal_op;
10118 /* Bitfield/Saturate. */
10119 op = (insn >> 21) & 7;
10120 imm = insn & 0x1f;
10121 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10122 if (rn == 15) {
10123 tmp = tcg_temp_new_i32();
10124 tcg_gen_movi_i32(tmp, 0);
10125 } else {
10126 tmp = load_reg(s, rn);
10128 switch (op) {
10129 case 2: /* Signed bitfield extract. */
10130 imm++;
10131 if (shift + imm > 32)
10132 goto illegal_op;
10133 if (imm < 32)
10134 gen_sbfx(tmp, shift, imm);
10135 break;
10136 case 6: /* Unsigned bitfield extract. */
10137 imm++;
10138 if (shift + imm > 32)
10139 goto illegal_op;
10140 if (imm < 32)
10141 gen_ubfx(tmp, shift, (1u << imm) - 1);
10142 break;
10143 case 3: /* Bitfield insert/clear. */
10144 if (imm < shift)
10145 goto illegal_op;
10146 imm = imm + 1 - shift;
10147 if (imm != 32) {
10148 tmp2 = load_reg(s, rd);
10149 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10150 tcg_temp_free_i32(tmp2);
10152 break;
10153 case 7:
10154 goto illegal_op;
10155 default: /* Saturate. */
10156 if (shift) {
10157 if (op & 1)
10158 tcg_gen_sari_i32(tmp, tmp, shift);
10159 else
10160 tcg_gen_shli_i32(tmp, tmp, shift);
10162 tmp2 = tcg_const_i32(imm);
10163 if (op & 4) {
10164 /* Unsigned. */
10165 if ((op & 1) && shift == 0) {
10166 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10167 tcg_temp_free_i32(tmp);
10168 tcg_temp_free_i32(tmp2);
10169 goto illegal_op;
10171 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10172 } else {
10173 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10175 } else {
10176 /* Signed. */
10177 if ((op & 1) && shift == 0) {
10178 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10179 tcg_temp_free_i32(tmp);
10180 tcg_temp_free_i32(tmp2);
10181 goto illegal_op;
10183 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10184 } else {
10185 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10188 tcg_temp_free_i32(tmp2);
10189 break;
10191 store_reg(s, rd, tmp);
10192 } else {
10193 imm = ((insn & 0x04000000) >> 15)
10194 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10195 if (insn & (1 << 22)) {
10196 /* 16-bit immediate. */
10197 imm |= (insn >> 4) & 0xf000;
10198 if (insn & (1 << 23)) {
10199 /* movt */
10200 tmp = load_reg(s, rd);
10201 tcg_gen_ext16u_i32(tmp, tmp);
10202 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10203 } else {
10204 /* movw */
10205 tmp = tcg_temp_new_i32();
10206 tcg_gen_movi_i32(tmp, imm);
10208 } else {
10209 /* Add/sub 12-bit immediate. */
10210 if (rn == 15) {
10211 offset = s->pc & ~(uint32_t)3;
10212 if (insn & (1 << 23))
10213 offset -= imm;
10214 else
10215 offset += imm;
10216 tmp = tcg_temp_new_i32();
10217 tcg_gen_movi_i32(tmp, offset);
10218 } else {
10219 tmp = load_reg(s, rn);
10220 if (insn & (1 << 23))
10221 tcg_gen_subi_i32(tmp, tmp, imm);
10222 else
10223 tcg_gen_addi_i32(tmp, tmp, imm);
10226 store_reg(s, rd, tmp);
10228 } else {
10229 int shifter_out = 0;
10230 /* modified 12-bit immediate. */
10231 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10232 imm = (insn & 0xff);
10233 switch (shift) {
10234 case 0: /* XY */
10235 /* Nothing to do. */
10236 break;
10237 case 1: /* 00XY00XY */
10238 imm |= imm << 16;
10239 break;
10240 case 2: /* XY00XY00 */
10241 imm |= imm << 16;
10242 imm <<= 8;
10243 break;
10244 case 3: /* XYXYXYXY */
10245 imm |= imm << 16;
10246 imm |= imm << 8;
10247 break;
10248 default: /* Rotated constant. */
10249 shift = (shift << 1) | (imm >> 7);
10250 imm |= 0x80;
10251 imm = imm << (32 - shift);
10252 shifter_out = 1;
10253 break;
10255 tmp2 = tcg_temp_new_i32();
10256 tcg_gen_movi_i32(tmp2, imm);
10257 rn = (insn >> 16) & 0xf;
10258 if (rn == 15) {
10259 tmp = tcg_temp_new_i32();
10260 tcg_gen_movi_i32(tmp, 0);
10261 } else {
10262 tmp = load_reg(s, rn);
10264 op = (insn >> 21) & 0xf;
10265 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10266 shifter_out, tmp, tmp2))
10267 goto illegal_op;
10268 tcg_temp_free_i32(tmp2);
10269 rd = (insn >> 8) & 0xf;
10270 if (rd != 15) {
10271 store_reg(s, rd, tmp);
10272 } else {
10273 tcg_temp_free_i32(tmp);
10277 break;
10278 case 12: /* Load/store single data item. */
10280 int postinc = 0;
10281 int writeback = 0;
10282 int memidx;
10283 if ((insn & 0x01100000) == 0x01000000) {
10284 if (disas_neon_ls_insn(s, insn)) {
10285 goto illegal_op;
10287 break;
10289 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10290 if (rs == 15) {
10291 if (!(insn & (1 << 20))) {
10292 goto illegal_op;
10294 if (op != 2) {
10295 /* Byte or halfword load space with dest == r15 : memory hints.
10296 * Catch them early so we don't emit pointless addressing code.
10297 * This space is a mix of:
10298 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10299 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10300 * cores)
10301 * unallocated hints, which must be treated as NOPs
10302 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10303 * which is easiest for the decoding logic
10304 * Some space which must UNDEF
10306 int op1 = (insn >> 23) & 3;
10307 int op2 = (insn >> 6) & 0x3f;
10308 if (op & 2) {
10309 goto illegal_op;
10311 if (rn == 15) {
10312 /* UNPREDICTABLE, unallocated hint or
10313 * PLD/PLDW/PLI (literal)
10315 return 0;
10317 if (op1 & 1) {
10318 return 0; /* PLD/PLDW/PLI or unallocated hint */
10320 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10321 return 0; /* PLD/PLDW/PLI or unallocated hint */
10323 /* UNDEF space, or an UNPREDICTABLE */
10324 return 1;
10327 memidx = get_mem_index(s);
10328 if (rn == 15) {
10329 addr = tcg_temp_new_i32();
10330 /* PC relative. */
10331 /* s->pc has already been incremented by 4. */
10332 imm = s->pc & 0xfffffffc;
10333 if (insn & (1 << 23))
10334 imm += insn & 0xfff;
10335 else
10336 imm -= insn & 0xfff;
10337 tcg_gen_movi_i32(addr, imm);
10338 } else {
10339 addr = load_reg(s, rn);
10340 if (insn & (1 << 23)) {
10341 /* Positive offset. */
10342 imm = insn & 0xfff;
10343 tcg_gen_addi_i32(addr, addr, imm);
10344 } else {
10345 imm = insn & 0xff;
10346 switch ((insn >> 8) & 0xf) {
10347 case 0x0: /* Shifted Register. */
10348 shift = (insn >> 4) & 0xf;
10349 if (shift > 3) {
10350 tcg_temp_free_i32(addr);
10351 goto illegal_op;
10353 tmp = load_reg(s, rm);
10354 if (shift)
10355 tcg_gen_shli_i32(tmp, tmp, shift);
10356 tcg_gen_add_i32(addr, addr, tmp);
10357 tcg_temp_free_i32(tmp);
10358 break;
10359 case 0xc: /* Negative offset. */
10360 tcg_gen_addi_i32(addr, addr, -imm);
10361 break;
10362 case 0xe: /* User privilege. */
10363 tcg_gen_addi_i32(addr, addr, imm);
10364 memidx = get_a32_user_mem_index(s);
10365 break;
10366 case 0x9: /* Post-decrement. */
10367 imm = -imm;
10368 /* Fall through. */
10369 case 0xb: /* Post-increment. */
10370 postinc = 1;
10371 writeback = 1;
10372 break;
10373 case 0xd: /* Pre-decrement. */
10374 imm = -imm;
10375 /* Fall through. */
10376 case 0xf: /* Pre-increment. */
10377 tcg_gen_addi_i32(addr, addr, imm);
10378 writeback = 1;
10379 break;
10380 default:
10381 tcg_temp_free_i32(addr);
10382 goto illegal_op;
10386 if (insn & (1 << 20)) {
10387 /* Load. */
10388 tmp = tcg_temp_new_i32();
10389 switch (op) {
10390 case 0:
10391 gen_aa32_ld8u(tmp, addr, memidx);
10392 break;
10393 case 4:
10394 gen_aa32_ld8s(tmp, addr, memidx);
10395 break;
10396 case 1:
10397 gen_aa32_ld16u(tmp, addr, memidx);
10398 break;
10399 case 5:
10400 gen_aa32_ld16s(tmp, addr, memidx);
10401 break;
10402 case 2:
10403 gen_aa32_ld32u(tmp, addr, memidx);
10404 break;
10405 default:
10406 tcg_temp_free_i32(tmp);
10407 tcg_temp_free_i32(addr);
10408 goto illegal_op;
10410 if (rs == 15) {
10411 gen_bx(s, tmp);
10412 } else {
10413 store_reg(s, rs, tmp);
10415 } else {
10416 /* Store. */
10417 tmp = load_reg(s, rs);
10418 switch (op) {
10419 case 0:
10420 gen_aa32_st8(tmp, addr, memidx);
10421 break;
10422 case 1:
10423 gen_aa32_st16(tmp, addr, memidx);
10424 break;
10425 case 2:
10426 gen_aa32_st32(tmp, addr, memidx);
10427 break;
10428 default:
10429 tcg_temp_free_i32(tmp);
10430 tcg_temp_free_i32(addr);
10431 goto illegal_op;
10433 tcg_temp_free_i32(tmp);
10435 if (postinc)
10436 tcg_gen_addi_i32(addr, addr, imm);
10437 if (writeback) {
10438 store_reg(s, rn, addr);
10439 } else {
10440 tcg_temp_free_i32(addr);
10443 break;
10444 default:
10445 goto illegal_op;
10447 return 0;
10448 illegal_op:
10449 return 1;
10452 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10454 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10455 int32_t offset;
10456 int i;
10457 TCGv_i32 tmp;
10458 TCGv_i32 tmp2;
10459 TCGv_i32 addr;
10461 if (s->condexec_mask) {
10462 cond = s->condexec_cond;
10463 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10464 s->condlabel = gen_new_label();
10465 arm_gen_test_cc(cond ^ 1, s->condlabel);
10466 s->condjmp = 1;
10470 insn = arm_lduw_code(env, s->pc, s->bswap_code);
10471 s->pc += 2;
10473 switch (insn >> 12) {
10474 case 0: case 1:
10476 rd = insn & 7;
10477 op = (insn >> 11) & 3;
10478 if (op == 3) {
10479 /* add/subtract */
10480 rn = (insn >> 3) & 7;
10481 tmp = load_reg(s, rn);
10482 if (insn & (1 << 10)) {
10483 /* immediate */
10484 tmp2 = tcg_temp_new_i32();
10485 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10486 } else {
10487 /* reg */
10488 rm = (insn >> 6) & 7;
10489 tmp2 = load_reg(s, rm);
10491 if (insn & (1 << 9)) {
10492 if (s->condexec_mask)
10493 tcg_gen_sub_i32(tmp, tmp, tmp2);
10494 else
10495 gen_sub_CC(tmp, tmp, tmp2);
10496 } else {
10497 if (s->condexec_mask)
10498 tcg_gen_add_i32(tmp, tmp, tmp2);
10499 else
10500 gen_add_CC(tmp, tmp, tmp2);
10502 tcg_temp_free_i32(tmp2);
10503 store_reg(s, rd, tmp);
10504 } else {
10505 /* shift immediate */
10506 rm = (insn >> 3) & 7;
10507 shift = (insn >> 6) & 0x1f;
10508 tmp = load_reg(s, rm);
10509 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10510 if (!s->condexec_mask)
10511 gen_logic_CC(tmp);
10512 store_reg(s, rd, tmp);
10514 break;
10515 case 2: case 3:
10516 /* arithmetic large immediate */
10517 op = (insn >> 11) & 3;
10518 rd = (insn >> 8) & 0x7;
10519 if (op == 0) { /* mov */
10520 tmp = tcg_temp_new_i32();
10521 tcg_gen_movi_i32(tmp, insn & 0xff);
10522 if (!s->condexec_mask)
10523 gen_logic_CC(tmp);
10524 store_reg(s, rd, tmp);
10525 } else {
10526 tmp = load_reg(s, rd);
10527 tmp2 = tcg_temp_new_i32();
10528 tcg_gen_movi_i32(tmp2, insn & 0xff);
10529 switch (op) {
10530 case 1: /* cmp */
10531 gen_sub_CC(tmp, tmp, tmp2);
10532 tcg_temp_free_i32(tmp);
10533 tcg_temp_free_i32(tmp2);
10534 break;
10535 case 2: /* add */
10536 if (s->condexec_mask)
10537 tcg_gen_add_i32(tmp, tmp, tmp2);
10538 else
10539 gen_add_CC(tmp, tmp, tmp2);
10540 tcg_temp_free_i32(tmp2);
10541 store_reg(s, rd, tmp);
10542 break;
10543 case 3: /* sub */
10544 if (s->condexec_mask)
10545 tcg_gen_sub_i32(tmp, tmp, tmp2);
10546 else
10547 gen_sub_CC(tmp, tmp, tmp2);
10548 tcg_temp_free_i32(tmp2);
10549 store_reg(s, rd, tmp);
10550 break;
10553 break;
10554 case 4:
10555 if (insn & (1 << 11)) {
10556 rd = (insn >> 8) & 7;
10557 /* load pc-relative. Bit 1 of PC is ignored. */
10558 val = s->pc + 2 + ((insn & 0xff) * 4);
10559 val &= ~(uint32_t)2;
10560 addr = tcg_temp_new_i32();
10561 tcg_gen_movi_i32(addr, val);
10562 tmp = tcg_temp_new_i32();
10563 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10564 tcg_temp_free_i32(addr);
10565 store_reg(s, rd, tmp);
10566 break;
10568 if (insn & (1 << 10)) {
10569 /* data processing extended or blx */
10570 rd = (insn & 7) | ((insn >> 4) & 8);
10571 rm = (insn >> 3) & 0xf;
10572 op = (insn >> 8) & 3;
10573 switch (op) {
10574 case 0: /* add */
10575 tmp = load_reg(s, rd);
10576 tmp2 = load_reg(s, rm);
10577 tcg_gen_add_i32(tmp, tmp, tmp2);
10578 tcg_temp_free_i32(tmp2);
10579 store_reg(s, rd, tmp);
10580 break;
10581 case 1: /* cmp */
10582 tmp = load_reg(s, rd);
10583 tmp2 = load_reg(s, rm);
10584 gen_sub_CC(tmp, tmp, tmp2);
10585 tcg_temp_free_i32(tmp2);
10586 tcg_temp_free_i32(tmp);
10587 break;
10588 case 2: /* mov/cpy */
10589 tmp = load_reg(s, rm);
10590 store_reg(s, rd, tmp);
10591 break;
10592 case 3:/* branch [and link] exchange thumb register */
10593 tmp = load_reg(s, rm);
10594 if (insn & (1 << 7)) {
10595 ARCH(5);
10596 val = (uint32_t)s->pc | 1;
10597 tmp2 = tcg_temp_new_i32();
10598 tcg_gen_movi_i32(tmp2, val);
10599 store_reg(s, 14, tmp2);
10601 /* already thumb, no need to check */
10602 gen_bx(s, tmp);
10603 break;
10605 break;
10608 /* data processing register */
10609 rd = insn & 7;
10610 rm = (insn >> 3) & 7;
10611 op = (insn >> 6) & 0xf;
10612 if (op == 2 || op == 3 || op == 4 || op == 7) {
10613 /* the shift/rotate ops want the operands backwards */
10614 val = rm;
10615 rm = rd;
10616 rd = val;
10617 val = 1;
10618 } else {
10619 val = 0;
10622 if (op == 9) { /* neg */
10623 tmp = tcg_temp_new_i32();
10624 tcg_gen_movi_i32(tmp, 0);
10625 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10626 tmp = load_reg(s, rd);
10627 } else {
10628 TCGV_UNUSED_I32(tmp);
10631 tmp2 = load_reg(s, rm);
10632 switch (op) {
10633 case 0x0: /* and */
10634 tcg_gen_and_i32(tmp, tmp, tmp2);
10635 if (!s->condexec_mask)
10636 gen_logic_CC(tmp);
10637 break;
10638 case 0x1: /* eor */
10639 tcg_gen_xor_i32(tmp, tmp, tmp2);
10640 if (!s->condexec_mask)
10641 gen_logic_CC(tmp);
10642 break;
10643 case 0x2: /* lsl */
10644 if (s->condexec_mask) {
10645 gen_shl(tmp2, tmp2, tmp);
10646 } else {
10647 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10648 gen_logic_CC(tmp2);
10650 break;
10651 case 0x3: /* lsr */
10652 if (s->condexec_mask) {
10653 gen_shr(tmp2, tmp2, tmp);
10654 } else {
10655 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10656 gen_logic_CC(tmp2);
10658 break;
10659 case 0x4: /* asr */
10660 if (s->condexec_mask) {
10661 gen_sar(tmp2, tmp2, tmp);
10662 } else {
10663 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10664 gen_logic_CC(tmp2);
10666 break;
10667 case 0x5: /* adc */
10668 if (s->condexec_mask) {
10669 gen_adc(tmp, tmp2);
10670 } else {
10671 gen_adc_CC(tmp, tmp, tmp2);
10673 break;
10674 case 0x6: /* sbc */
10675 if (s->condexec_mask) {
10676 gen_sub_carry(tmp, tmp, tmp2);
10677 } else {
10678 gen_sbc_CC(tmp, tmp, tmp2);
10680 break;
10681 case 0x7: /* ror */
10682 if (s->condexec_mask) {
10683 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10684 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10685 } else {
10686 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10687 gen_logic_CC(tmp2);
10689 break;
10690 case 0x8: /* tst */
10691 tcg_gen_and_i32(tmp, tmp, tmp2);
10692 gen_logic_CC(tmp);
10693 rd = 16;
10694 break;
10695 case 0x9: /* neg */
10696 if (s->condexec_mask)
10697 tcg_gen_neg_i32(tmp, tmp2);
10698 else
10699 gen_sub_CC(tmp, tmp, tmp2);
10700 break;
10701 case 0xa: /* cmp */
10702 gen_sub_CC(tmp, tmp, tmp2);
10703 rd = 16;
10704 break;
10705 case 0xb: /* cmn */
10706 gen_add_CC(tmp, tmp, tmp2);
10707 rd = 16;
10708 break;
10709 case 0xc: /* orr */
10710 tcg_gen_or_i32(tmp, tmp, tmp2);
10711 if (!s->condexec_mask)
10712 gen_logic_CC(tmp);
10713 break;
10714 case 0xd: /* mul */
10715 tcg_gen_mul_i32(tmp, tmp, tmp2);
10716 if (!s->condexec_mask)
10717 gen_logic_CC(tmp);
10718 break;
10719 case 0xe: /* bic */
10720 tcg_gen_andc_i32(tmp, tmp, tmp2);
10721 if (!s->condexec_mask)
10722 gen_logic_CC(tmp);
10723 break;
10724 case 0xf: /* mvn */
10725 tcg_gen_not_i32(tmp2, tmp2);
10726 if (!s->condexec_mask)
10727 gen_logic_CC(tmp2);
10728 val = 1;
10729 rm = rd;
10730 break;
10732 if (rd != 16) {
10733 if (val) {
10734 store_reg(s, rm, tmp2);
10735 if (op != 0xf)
10736 tcg_temp_free_i32(tmp);
10737 } else {
10738 store_reg(s, rd, tmp);
10739 tcg_temp_free_i32(tmp2);
10741 } else {
10742 tcg_temp_free_i32(tmp);
10743 tcg_temp_free_i32(tmp2);
10745 break;
10747 case 5:
10748 /* load/store register offset. */
10749 rd = insn & 7;
10750 rn = (insn >> 3) & 7;
10751 rm = (insn >> 6) & 7;
10752 op = (insn >> 9) & 7;
10753 addr = load_reg(s, rn);
10754 tmp = load_reg(s, rm);
10755 tcg_gen_add_i32(addr, addr, tmp);
10756 tcg_temp_free_i32(tmp);
10758 if (op < 3) { /* store */
10759 tmp = load_reg(s, rd);
10760 } else {
10761 tmp = tcg_temp_new_i32();
10764 switch (op) {
10765 case 0: /* str */
10766 gen_aa32_st32(tmp, addr, get_mem_index(s));
10767 break;
10768 case 1: /* strh */
10769 gen_aa32_st16(tmp, addr, get_mem_index(s));
10770 break;
10771 case 2: /* strb */
10772 gen_aa32_st8(tmp, addr, get_mem_index(s));
10773 break;
10774 case 3: /* ldrsb */
10775 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
10776 break;
10777 case 4: /* ldr */
10778 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10779 break;
10780 case 5: /* ldrh */
10781 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10782 break;
10783 case 6: /* ldrb */
10784 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10785 break;
10786 case 7: /* ldrsh */
10787 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
10788 break;
10790 if (op >= 3) { /* load */
10791 store_reg(s, rd, tmp);
10792 } else {
10793 tcg_temp_free_i32(tmp);
10795 tcg_temp_free_i32(addr);
10796 break;
10798 case 6:
10799 /* load/store word immediate offset */
10800 rd = insn & 7;
10801 rn = (insn >> 3) & 7;
10802 addr = load_reg(s, rn);
10803 val = (insn >> 4) & 0x7c;
10804 tcg_gen_addi_i32(addr, addr, val);
10806 if (insn & (1 << 11)) {
10807 /* load */
10808 tmp = tcg_temp_new_i32();
10809 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10810 store_reg(s, rd, tmp);
10811 } else {
10812 /* store */
10813 tmp = load_reg(s, rd);
10814 gen_aa32_st32(tmp, addr, get_mem_index(s));
10815 tcg_temp_free_i32(tmp);
10817 tcg_temp_free_i32(addr);
10818 break;
10820 case 7:
10821 /* load/store byte immediate offset */
10822 rd = insn & 7;
10823 rn = (insn >> 3) & 7;
10824 addr = load_reg(s, rn);
10825 val = (insn >> 6) & 0x1f;
10826 tcg_gen_addi_i32(addr, addr, val);
10828 if (insn & (1 << 11)) {
10829 /* load */
10830 tmp = tcg_temp_new_i32();
10831 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10832 store_reg(s, rd, tmp);
10833 } else {
10834 /* store */
10835 tmp = load_reg(s, rd);
10836 gen_aa32_st8(tmp, addr, get_mem_index(s));
10837 tcg_temp_free_i32(tmp);
10839 tcg_temp_free_i32(addr);
10840 break;
10842 case 8:
10843 /* load/store halfword immediate offset */
10844 rd = insn & 7;
10845 rn = (insn >> 3) & 7;
10846 addr = load_reg(s, rn);
10847 val = (insn >> 5) & 0x3e;
10848 tcg_gen_addi_i32(addr, addr, val);
10850 if (insn & (1 << 11)) {
10851 /* load */
10852 tmp = tcg_temp_new_i32();
10853 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10854 store_reg(s, rd, tmp);
10855 } else {
10856 /* store */
10857 tmp = load_reg(s, rd);
10858 gen_aa32_st16(tmp, addr, get_mem_index(s));
10859 tcg_temp_free_i32(tmp);
10861 tcg_temp_free_i32(addr);
10862 break;
10864 case 9:
10865 /* load/store from stack */
10866 rd = (insn >> 8) & 7;
10867 addr = load_reg(s, 13);
10868 val = (insn & 0xff) * 4;
10869 tcg_gen_addi_i32(addr, addr, val);
10871 if (insn & (1 << 11)) {
10872 /* load */
10873 tmp = tcg_temp_new_i32();
10874 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10875 store_reg(s, rd, tmp);
10876 } else {
10877 /* store */
10878 tmp = load_reg(s, rd);
10879 gen_aa32_st32(tmp, addr, get_mem_index(s));
10880 tcg_temp_free_i32(tmp);
10882 tcg_temp_free_i32(addr);
10883 break;
10885 case 10:
10886 /* add to high reg */
10887 rd = (insn >> 8) & 7;
10888 if (insn & (1 << 11)) {
10889 /* SP */
10890 tmp = load_reg(s, 13);
10891 } else {
10892 /* PC. bit 1 is ignored. */
10893 tmp = tcg_temp_new_i32();
10894 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10896 val = (insn & 0xff) * 4;
10897 tcg_gen_addi_i32(tmp, tmp, val);
10898 store_reg(s, rd, tmp);
10899 break;
10901 case 11:
10902 /* misc */
10903 op = (insn >> 8) & 0xf;
10904 switch (op) {
10905 case 0:
10906 /* adjust stack pointer */
10907 tmp = load_reg(s, 13);
10908 val = (insn & 0x7f) * 4;
10909 if (insn & (1 << 7))
10910 val = -(int32_t)val;
10911 tcg_gen_addi_i32(tmp, tmp, val);
10912 store_reg(s, 13, tmp);
10913 break;
10915 case 2: /* sign/zero extend. */
10916 ARCH(6);
10917 rd = insn & 7;
10918 rm = (insn >> 3) & 7;
10919 tmp = load_reg(s, rm);
10920 switch ((insn >> 6) & 3) {
10921 case 0: gen_sxth(tmp); break;
10922 case 1: gen_sxtb(tmp); break;
10923 case 2: gen_uxth(tmp); break;
10924 case 3: gen_uxtb(tmp); break;
10926 store_reg(s, rd, tmp);
10927 break;
10928 case 4: case 5: case 0xc: case 0xd:
10929 /* push/pop */
10930 addr = load_reg(s, 13);
10931 if (insn & (1 << 8))
10932 offset = 4;
10933 else
10934 offset = 0;
10935 for (i = 0; i < 8; i++) {
10936 if (insn & (1 << i))
10937 offset += 4;
10939 if ((insn & (1 << 11)) == 0) {
10940 tcg_gen_addi_i32(addr, addr, -offset);
10942 for (i = 0; i < 8; i++) {
10943 if (insn & (1 << i)) {
10944 if (insn & (1 << 11)) {
10945 /* pop */
10946 tmp = tcg_temp_new_i32();
10947 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10948 store_reg(s, i, tmp);
10949 } else {
10950 /* push */
10951 tmp = load_reg(s, i);
10952 gen_aa32_st32(tmp, addr, get_mem_index(s));
10953 tcg_temp_free_i32(tmp);
10955 /* advance to the next address. */
10956 tcg_gen_addi_i32(addr, addr, 4);
10959 TCGV_UNUSED_I32(tmp);
10960 if (insn & (1 << 8)) {
10961 if (insn & (1 << 11)) {
10962 /* pop pc */
10963 tmp = tcg_temp_new_i32();
10964 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10965 /* don't set the pc until the rest of the instruction
10966 has completed */
10967 } else {
10968 /* push lr */
10969 tmp = load_reg(s, 14);
10970 gen_aa32_st32(tmp, addr, get_mem_index(s));
10971 tcg_temp_free_i32(tmp);
10973 tcg_gen_addi_i32(addr, addr, 4);
10975 if ((insn & (1 << 11)) == 0) {
10976 tcg_gen_addi_i32(addr, addr, -offset);
10978 /* write back the new stack pointer */
10979 store_reg(s, 13, addr);
10980 /* set the new PC value */
10981 if ((insn & 0x0900) == 0x0900) {
10982 store_reg_from_load(s, 15, tmp);
10984 break;
10986 case 1: case 3: case 9: case 11: /* czb */
10987 rm = insn & 7;
10988 tmp = load_reg(s, rm);
10989 s->condlabel = gen_new_label();
10990 s->condjmp = 1;
10991 if (insn & (1 << 11))
10992 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10993 else
10994 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10995 tcg_temp_free_i32(tmp);
10996 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10997 val = (uint32_t)s->pc + 2;
10998 val += offset;
10999 gen_jmp(s, val);
11000 break;
11002 case 15: /* IT, nop-hint. */
11003 if ((insn & 0xf) == 0) {
11004 gen_nop_hint(s, (insn >> 4) & 0xf);
11005 break;
11007 /* If Then. */
11008 s->condexec_cond = (insn >> 4) & 0xe;
11009 s->condexec_mask = insn & 0x1f;
11010 /* No actual code generated for this insn, just setup state. */
11011 break;
11013 case 0xe: /* bkpt */
11015 int imm8 = extract32(insn, 0, 8);
11016 ARCH(5);
11017 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11018 default_exception_el(s));
11019 break;
11022 case 0xa: /* rev */
11023 ARCH(6);
11024 rn = (insn >> 3) & 0x7;
11025 rd = insn & 0x7;
11026 tmp = load_reg(s, rn);
11027 switch ((insn >> 6) & 3) {
11028 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11029 case 1: gen_rev16(tmp); break;
11030 case 3: gen_revsh(tmp); break;
11031 default: goto illegal_op;
11033 store_reg(s, rd, tmp);
11034 break;
11036 case 6:
11037 switch ((insn >> 5) & 7) {
11038 case 2:
11039 /* setend */
11040 ARCH(6);
11041 if (((insn >> 3) & 1) != s->bswap_code) {
11042 /* Dynamic endianness switching not implemented. */
11043 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
11044 goto illegal_op;
11046 break;
11047 case 3:
11048 /* cps */
11049 ARCH(6);
11050 if (IS_USER(s)) {
11051 break;
11053 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11054 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11055 /* FAULTMASK */
11056 if (insn & 1) {
11057 addr = tcg_const_i32(19);
11058 gen_helper_v7m_msr(cpu_env, addr, tmp);
11059 tcg_temp_free_i32(addr);
11061 /* PRIMASK */
11062 if (insn & 2) {
11063 addr = tcg_const_i32(16);
11064 gen_helper_v7m_msr(cpu_env, addr, tmp);
11065 tcg_temp_free_i32(addr);
11067 tcg_temp_free_i32(tmp);
11068 gen_lookup_tb(s);
11069 } else {
11070 if (insn & (1 << 4)) {
11071 shift = CPSR_A | CPSR_I | CPSR_F;
11072 } else {
11073 shift = 0;
11075 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11077 break;
11078 default:
11079 goto undef;
11081 break;
11083 default:
11084 goto undef;
11086 break;
11088 case 12:
11090 /* load/store multiple */
11091 TCGv_i32 loaded_var;
11092 TCGV_UNUSED_I32(loaded_var);
11093 rn = (insn >> 8) & 0x7;
11094 addr = load_reg(s, rn);
11095 for (i = 0; i < 8; i++) {
11096 if (insn & (1 << i)) {
11097 if (insn & (1 << 11)) {
11098 /* load */
11099 tmp = tcg_temp_new_i32();
11100 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
11101 if (i == rn) {
11102 loaded_var = tmp;
11103 } else {
11104 store_reg(s, i, tmp);
11106 } else {
11107 /* store */
11108 tmp = load_reg(s, i);
11109 gen_aa32_st32(tmp, addr, get_mem_index(s));
11110 tcg_temp_free_i32(tmp);
11112 /* advance to the next address */
11113 tcg_gen_addi_i32(addr, addr, 4);
11116 if ((insn & (1 << rn)) == 0) {
11117 /* base reg not in list: base register writeback */
11118 store_reg(s, rn, addr);
11119 } else {
11120 /* base reg in list: if load, complete it now */
11121 if (insn & (1 << 11)) {
11122 store_reg(s, rn, loaded_var);
11124 tcg_temp_free_i32(addr);
11126 break;
11128 case 13:
11129 /* conditional branch or swi */
11130 cond = (insn >> 8) & 0xf;
11131 if (cond == 0xe)
11132 goto undef;
11134 if (cond == 0xf) {
11135 /* swi */
11136 gen_set_pc_im(s, s->pc);
11137 s->svc_imm = extract32(insn, 0, 8);
11138 s->is_jmp = DISAS_SWI;
11139 break;
11141 /* generate a conditional jump to next instruction */
11142 s->condlabel = gen_new_label();
11143 arm_gen_test_cc(cond ^ 1, s->condlabel);
11144 s->condjmp = 1;
11146 /* jump to the offset */
11147 val = (uint32_t)s->pc + 2;
11148 offset = ((int32_t)insn << 24) >> 24;
11149 val += offset << 1;
11150 gen_jmp(s, val);
11151 break;
11153 case 14:
11154 if (insn & (1 << 11)) {
11155 if (disas_thumb2_insn(env, s, insn))
11156 goto undef32;
11157 break;
11159 /* unconditional branch */
11160 val = (uint32_t)s->pc;
11161 offset = ((int32_t)insn << 21) >> 21;
11162 val += (offset << 1) + 2;
11163 gen_jmp(s, val);
11164 break;
11166 case 15:
11167 if (disas_thumb2_insn(env, s, insn))
11168 goto undef32;
11169 break;
11171 return;
11172 undef32:
11173 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11174 default_exception_el(s));
11175 return;
11176 illegal_op:
11177 undef:
11178 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11179 default_exception_el(s));
11182 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11183 basic block 'tb'. */
11184 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11186 ARMCPU *cpu = arm_env_get_cpu(env);
11187 CPUState *cs = CPU(cpu);
11188 DisasContext dc1, *dc = &dc1;
11189 target_ulong pc_start;
11190 target_ulong next_page_start;
11191 int num_insns;
11192 int max_insns;
11194 /* generate intermediate code */
11196 /* The A64 decoder has its own top level loop, because it doesn't need
11197 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11199 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11200 gen_intermediate_code_a64(cpu, tb);
11201 return;
11204 pc_start = tb->pc;
11206 dc->tb = tb;
11208 dc->is_jmp = DISAS_NEXT;
11209 dc->pc = pc_start;
11210 dc->singlestep_enabled = cs->singlestep_enabled;
11211 dc->condjmp = 0;
11213 dc->aarch64 = 0;
11214 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11215 * there is no secure EL1, so we route exceptions to EL3.
11217 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11218 !arm_el_is_aa64(env, 3);
11219 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11220 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
11221 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11222 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11223 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11224 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11225 #if !defined(CONFIG_USER_ONLY)
11226 dc->user = (dc->current_el == 0);
11227 #endif
11228 dc->ns = ARM_TBFLAG_NS(tb->flags);
11229 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11230 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11231 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11232 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11233 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11234 dc->cp_regs = cpu->cp_regs;
11235 dc->features = env->features;
11237 /* Single step state. The code-generation logic here is:
11238 * SS_ACTIVE == 0:
11239 * generate code with no special handling for single-stepping (except
11240 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11241 * this happens anyway because those changes are all system register or
11242 * PSTATE writes).
11243 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11244 * emit code for one insn
11245 * emit code to clear PSTATE.SS
11246 * emit code to generate software step exception for completed step
11247 * end TB (as usual for having generated an exception)
11248 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11249 * emit code to generate a software step exception
11250 * end the TB
11252 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11253 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11254 dc->is_ldex = false;
11255 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11257 cpu_F0s = tcg_temp_new_i32();
11258 cpu_F1s = tcg_temp_new_i32();
11259 cpu_F0d = tcg_temp_new_i64();
11260 cpu_F1d = tcg_temp_new_i64();
11261 cpu_V0 = cpu_F0d;
11262 cpu_V1 = cpu_F1d;
11263 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11264 cpu_M0 = tcg_temp_new_i64();
11265 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11266 num_insns = 0;
11267 max_insns = tb->cflags & CF_COUNT_MASK;
11268 if (max_insns == 0) {
11269 max_insns = CF_COUNT_MASK;
11271 if (max_insns > TCG_MAX_INSNS) {
11272 max_insns = TCG_MAX_INSNS;
11275 gen_tb_start(tb);
11277 tcg_clear_temp_count();
11279 /* A note on handling of the condexec (IT) bits:
11281 * We want to avoid the overhead of having to write the updated condexec
11282 * bits back to the CPUARMState for every instruction in an IT block. So:
11283 * (1) if the condexec bits are not already zero then we write
11284 * zero back into the CPUARMState now. This avoids complications trying
11285 * to do it at the end of the block. (For example if we don't do this
11286 * it's hard to identify whether we can safely skip writing condexec
11287 * at the end of the TB, which we definitely want to do for the case
11288 * where a TB doesn't do anything with the IT state at all.)
11289 * (2) if we are going to leave the TB then we call gen_set_condexec()
11290 * which will write the correct value into CPUARMState if zero is wrong.
11291 * This is done both for leaving the TB at the end, and for leaving
11292 * it because of an exception we know will happen, which is done in
11293 * gen_exception_insn(). The latter is necessary because we need to
11294 * leave the TB with the PC/IT state just prior to execution of the
11295 * instruction which caused the exception.
11296 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11297 * then the CPUARMState will be wrong and we need to reset it.
11298 * This is handled in the same way as restoration of the
11299 * PC in these situations; we save the value of the condexec bits
11300 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11301 * then uses this to restore them after an exception.
11303 * Note that there are no instructions which can read the condexec
11304 * bits, and none which can write non-static values to them, so
11305 * we don't need to care about whether CPUARMState is correct in the
11306 * middle of a TB.
11309 /* Reset the conditional execution bits immediately. This avoids
11310 complications trying to do it at the end of the block. */
11311 if (dc->condexec_mask || dc->condexec_cond)
11313 TCGv_i32 tmp = tcg_temp_new_i32();
11314 tcg_gen_movi_i32(tmp, 0);
11315 store_cpu_field(tmp, condexec_bits);
11317 do {
11318 tcg_gen_insn_start(dc->pc,
11319 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1));
11320 num_insns++;
11322 #ifdef CONFIG_USER_ONLY
11323 /* Intercept jump to the magic kernel page. */
11324 if (dc->pc >= 0xffff0000) {
11325 /* We always get here via a jump, so know we are not in a
11326 conditional execution block. */
11327 gen_exception_internal(EXCP_KERNEL_TRAP);
11328 dc->is_jmp = DISAS_UPDATE;
11329 break;
11331 #else
11332 if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
11333 /* We always get here via a jump, so know we are not in a
11334 conditional execution block. */
11335 gen_exception_internal(EXCP_EXCEPTION_EXIT);
11336 dc->is_jmp = DISAS_UPDATE;
11337 break;
11339 #endif
11341 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11342 CPUBreakpoint *bp;
11343 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11344 if (bp->pc == dc->pc) {
11345 if (bp->flags & BP_CPU) {
11346 gen_helper_check_breakpoints(cpu_env);
11347 /* End the TB early; it's likely not going to be executed */
11348 dc->is_jmp = DISAS_UPDATE;
11349 } else {
11350 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11351 /* Advance PC so that clearing the breakpoint will
11352 invalidate this TB. */
11353 /* TODO: Advance PC by correct instruction length to
11354 * avoid disassembler error messages */
11355 dc->pc += 2;
11356 goto done_generating;
11358 break;
11363 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11364 gen_io_start();
11367 if (dc->ss_active && !dc->pstate_ss) {
11368 /* Singlestep state is Active-pending.
11369 * If we're in this state at the start of a TB then either
11370 * a) we just took an exception to an EL which is being debugged
11371 * and this is the first insn in the exception handler
11372 * b) debug exceptions were masked and we just unmasked them
11373 * without changing EL (eg by clearing PSTATE.D)
11374 * In either case we're going to take a swstep exception in the
11375 * "did not step an insn" case, and so the syndrome ISV and EX
11376 * bits should be zero.
11378 assert(num_insns == 1);
11379 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11380 default_exception_el(dc));
11381 goto done_generating;
11384 if (dc->thumb) {
11385 disas_thumb_insn(env, dc);
11386 if (dc->condexec_mask) {
11387 dc->condexec_cond = (dc->condexec_cond & 0xe)
11388 | ((dc->condexec_mask >> 4) & 1);
11389 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11390 if (dc->condexec_mask == 0) {
11391 dc->condexec_cond = 0;
11394 } else {
11395 unsigned int insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
11396 dc->pc += 4;
11397 disas_arm_insn(dc, insn);
11400 if (dc->condjmp && !dc->is_jmp) {
11401 gen_set_label(dc->condlabel);
11402 dc->condjmp = 0;
11405 if (tcg_check_temp_count()) {
11406 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11407 dc->pc);
11410 /* Translation stops when a conditional branch is encountered.
11411 * Otherwise the subsequent code could get translated several times.
11412 * Also stop translation when a page boundary is reached. This
11413 * ensures prefetch aborts occur at the right place. */
11414 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11415 !cs->singlestep_enabled &&
11416 !singlestep &&
11417 !dc->ss_active &&
11418 dc->pc < next_page_start &&
11419 num_insns < max_insns);
11421 if (tb->cflags & CF_LAST_IO) {
11422 if (dc->condjmp) {
11423 /* FIXME: This can theoretically happen with self-modifying
11424 code. */
11425 cpu_abort(cs, "IO on conditional branch instruction");
11427 gen_io_end();
11430 /* At this stage dc->condjmp will only be set when the skipped
11431 instruction was a conditional branch or trap, and the PC has
11432 already been written. */
11433 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11434 /* Make sure the pc is updated, and raise a debug exception. */
11435 if (dc->condjmp) {
11436 gen_set_condexec(dc);
11437 if (dc->is_jmp == DISAS_SWI) {
11438 gen_ss_advance(dc);
11439 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11440 default_exception_el(dc));
11441 } else if (dc->is_jmp == DISAS_HVC) {
11442 gen_ss_advance(dc);
11443 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11444 } else if (dc->is_jmp == DISAS_SMC) {
11445 gen_ss_advance(dc);
11446 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11447 } else if (dc->ss_active) {
11448 gen_step_complete_exception(dc);
11449 } else {
11450 gen_exception_internal(EXCP_DEBUG);
11452 gen_set_label(dc->condlabel);
11454 if (dc->condjmp || !dc->is_jmp) {
11455 gen_set_pc_im(dc, dc->pc);
11456 dc->condjmp = 0;
11458 gen_set_condexec(dc);
11459 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
11460 gen_ss_advance(dc);
11461 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11462 default_exception_el(dc));
11463 } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
11464 gen_ss_advance(dc);
11465 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11466 } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
11467 gen_ss_advance(dc);
11468 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11469 } else if (dc->ss_active) {
11470 gen_step_complete_exception(dc);
11471 } else {
11472 /* FIXME: Single stepping a WFI insn will not halt
11473 the CPU. */
11474 gen_exception_internal(EXCP_DEBUG);
11476 } else {
11477 /* While branches must always occur at the end of an IT block,
11478 there are a few other things that can cause us to terminate
11479 the TB in the middle of an IT block:
11480 - Exception generating instructions (bkpt, swi, undefined).
11481 - Page boundaries.
11482 - Hardware watchpoints.
11483 Hardware breakpoints have already been handled and skip this code.
11485 gen_set_condexec(dc);
11486 switch(dc->is_jmp) {
11487 case DISAS_NEXT:
11488 gen_goto_tb(dc, 1, dc->pc);
11489 break;
11490 default:
11491 case DISAS_JUMP:
11492 case DISAS_UPDATE:
11493 /* indicate that the hash table must be used to find the next TB */
11494 tcg_gen_exit_tb(0);
11495 break;
11496 case DISAS_TB_JUMP:
11497 /* nothing more to generate */
11498 break;
11499 case DISAS_WFI:
11500 gen_helper_wfi(cpu_env);
11501 /* The helper doesn't necessarily throw an exception, but we
11502 * must go back to the main loop to check for interrupts anyway.
11504 tcg_gen_exit_tb(0);
11505 break;
11506 case DISAS_WFE:
11507 gen_helper_wfe(cpu_env);
11508 break;
11509 case DISAS_YIELD:
11510 gen_helper_yield(cpu_env);
11511 break;
11512 case DISAS_SWI:
11513 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11514 default_exception_el(dc));
11515 break;
11516 case DISAS_HVC:
11517 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11518 break;
11519 case DISAS_SMC:
11520 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11521 break;
11523 if (dc->condjmp) {
11524 gen_set_label(dc->condlabel);
11525 gen_set_condexec(dc);
11526 gen_goto_tb(dc, 1, dc->pc);
11527 dc->condjmp = 0;
11531 done_generating:
11532 gen_tb_end(tb, num_insns);
11534 #ifdef DEBUG_DISAS
11535 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11536 qemu_log("----------------\n");
11537 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11538 log_target_disas(cs, pc_start, dc->pc - pc_start,
11539 dc->thumb | (dc->bswap_code << 1));
11540 qemu_log("\n");
11542 #endif
11543 tb->size = dc->pc - pc_start;
11544 tb->icount = num_insns;
11547 static const char *cpu_mode_names[16] = {
11548 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11549 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11552 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11553 int flags)
11555 ARMCPU *cpu = ARM_CPU(cs);
11556 CPUARMState *env = &cpu->env;
11557 int i;
11558 uint32_t psr;
11560 if (is_a64(env)) {
11561 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11562 return;
11565 for(i=0;i<16;i++) {
11566 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11567 if ((i % 4) == 3)
11568 cpu_fprintf(f, "\n");
11569 else
11570 cpu_fprintf(f, " ");
11572 psr = cpsr_read(env);
11573 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11574 psr,
11575 psr & (1 << 31) ? 'N' : '-',
11576 psr & (1 << 30) ? 'Z' : '-',
11577 psr & (1 << 29) ? 'C' : '-',
11578 psr & (1 << 28) ? 'V' : '-',
11579 psr & CPSR_T ? 'T' : 'A',
11580 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11582 if (flags & CPU_DUMP_FPU) {
11583 int numvfpregs = 0;
11584 if (arm_feature(env, ARM_FEATURE_VFP)) {
11585 numvfpregs += 16;
11587 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11588 numvfpregs += 16;
11590 for (i = 0; i < numvfpregs; i++) {
11591 uint64_t v = float64_val(env->vfp.regs[i]);
11592 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11593 i * 2, (uint32_t)v,
11594 i * 2 + 1, (uint32_t)(v >> 32),
11595 i, v);
11597 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11601 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
11602 target_ulong *data)
11604 if (is_a64(env)) {
11605 env->pc = data[0];
11606 env->condexec_bits = 0;
11607 } else {
11608 env->regs[15] = data[0];
11609 env->condexec_bits = data[1];