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