target-arm: Implement PMSAv7 MPU
[qemu/cris-port.git] / target-arm / translate.c
blobead08f4820a8341adccb166e899d571b91272ed7
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
27 #include "cpu.h"
28 #include "internals.h"
29 #include "disas/disas.h"
30 #include "tcg-op.h"
31 #include "qemu/log.h"
32 #include "qemu/bitops.h"
33 #include "arm_ldst.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J 0
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
55 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
57 #if defined(CONFIG_USER_ONLY)
58 #define IS_USER(s) 1
59 #else
60 #define IS_USER(s) (s->user)
61 #endif
63 TCGv_ptr cpu_env;
64 /* We reuse the same 64-bit temporaries for efficiency. */
65 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
66 static TCGv_i32 cpu_R[16];
67 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
68 static TCGv_i64 cpu_exclusive_addr;
69 static TCGv_i64 cpu_exclusive_val;
70 #ifdef CONFIG_USER_ONLY
71 static TCGv_i64 cpu_exclusive_test;
72 static TCGv_i32 cpu_exclusive_info;
73 #endif
75 /* FIXME: These should be removed. */
76 static TCGv_i32 cpu_F0s, cpu_F1s;
77 static TCGv_i64 cpu_F0d, cpu_F1d;
79 #include "exec/gen-icount.h"
81 static const char *regnames[] =
82 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
85 /* initialize TCG globals. */
86 void arm_translate_init(void)
88 int i;
90 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
92 for (i = 0; i < 16; i++) {
93 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
94 offsetof(CPUARMState, regs[i]),
95 regnames[i]);
97 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
98 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
99 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
100 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
102 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
103 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
104 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
105 offsetof(CPUARMState, exclusive_val), "exclusive_val");
106 #ifdef CONFIG_USER_ONLY
107 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
108 offsetof(CPUARMState, exclusive_test), "exclusive_test");
109 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
110 offsetof(CPUARMState, exclusive_info), "exclusive_info");
111 #endif
113 a64_translate_init();
116 static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
118 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
119 * insns:
120 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
121 * otherwise, access as if at PL0.
123 switch (s->mmu_idx) {
124 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
125 case ARMMMUIdx_S12NSE0:
126 case ARMMMUIdx_S12NSE1:
127 return ARMMMUIdx_S12NSE0;
128 case ARMMMUIdx_S1E3:
129 case ARMMMUIdx_S1SE0:
130 case ARMMMUIdx_S1SE1:
131 return ARMMMUIdx_S1SE0;
132 case ARMMMUIdx_S2NS:
133 default:
134 g_assert_not_reached();
138 static inline TCGv_i32 load_cpu_offset(int offset)
140 TCGv_i32 tmp = tcg_temp_new_i32();
141 tcg_gen_ld_i32(tmp, cpu_env, offset);
142 return tmp;
145 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
147 static inline void store_cpu_offset(TCGv_i32 var, int offset)
149 tcg_gen_st_i32(var, cpu_env, offset);
150 tcg_temp_free_i32(var);
153 #define store_cpu_field(var, name) \
154 store_cpu_offset(var, offsetof(CPUARMState, name))
156 /* Set a variable to the value of a CPU register. */
157 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
159 if (reg == 15) {
160 uint32_t addr;
161 /* normally, since we updated PC, we need only to add one insn */
162 if (s->thumb)
163 addr = (long)s->pc + 2;
164 else
165 addr = (long)s->pc + 4;
166 tcg_gen_movi_i32(var, addr);
167 } else {
168 tcg_gen_mov_i32(var, cpu_R[reg]);
172 /* Create a new temporary and set it to the value of a CPU register. */
173 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
175 TCGv_i32 tmp = tcg_temp_new_i32();
176 load_reg_var(s, tmp, reg);
177 return tmp;
180 /* Set a CPU register. The source must be a temporary and will be
181 marked as dead. */
182 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
184 if (reg == 15) {
185 tcg_gen_andi_i32(var, var, ~1);
186 s->is_jmp = DISAS_JUMP;
188 tcg_gen_mov_i32(cpu_R[reg], var);
189 tcg_temp_free_i32(var);
192 /* Value extensions. */
193 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
194 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
195 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
196 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
198 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
199 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
202 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
204 TCGv_i32 tmp_mask = tcg_const_i32(mask);
205 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
206 tcg_temp_free_i32(tmp_mask);
208 /* Set NZCV flags from the high 4 bits of var. */
209 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
211 static void gen_exception_internal(int excp)
213 TCGv_i32 tcg_excp = tcg_const_i32(excp);
215 assert(excp_is_internal(excp));
216 gen_helper_exception_internal(cpu_env, tcg_excp);
217 tcg_temp_free_i32(tcg_excp);
220 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
222 TCGv_i32 tcg_excp = tcg_const_i32(excp);
223 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
224 TCGv_i32 tcg_el = tcg_const_i32(target_el);
226 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
227 tcg_syn, tcg_el);
229 tcg_temp_free_i32(tcg_el);
230 tcg_temp_free_i32(tcg_syn);
231 tcg_temp_free_i32(tcg_excp);
234 static void gen_ss_advance(DisasContext *s)
236 /* If the singlestep state is Active-not-pending, advance to
237 * Active-pending.
239 if (s->ss_active) {
240 s->pstate_ss = 0;
241 gen_helper_clear_pstate_ss(cpu_env);
245 static void gen_step_complete_exception(DisasContext *s)
247 /* We just completed step of an insn. Move from Active-not-pending
248 * to Active-pending, and then also take the swstep exception.
249 * This corresponds to making the (IMPDEF) choice to prioritize
250 * swstep exceptions over asynchronous exceptions taken to an exception
251 * level where debug is disabled. This choice has the advantage that
252 * we do not need to maintain internal state corresponding to the
253 * ISV/EX syndrome bits between completion of the step and generation
254 * of the exception, and our syndrome information is always correct.
256 gen_ss_advance(s);
257 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
258 default_exception_el(s));
259 s->is_jmp = DISAS_EXC;
262 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
264 TCGv_i32 tmp1 = tcg_temp_new_i32();
265 TCGv_i32 tmp2 = tcg_temp_new_i32();
266 tcg_gen_ext16s_i32(tmp1, a);
267 tcg_gen_ext16s_i32(tmp2, b);
268 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
269 tcg_temp_free_i32(tmp2);
270 tcg_gen_sari_i32(a, a, 16);
271 tcg_gen_sari_i32(b, b, 16);
272 tcg_gen_mul_i32(b, b, a);
273 tcg_gen_mov_i32(a, tmp1);
274 tcg_temp_free_i32(tmp1);
277 /* Byteswap each halfword. */
278 static void gen_rev16(TCGv_i32 var)
280 TCGv_i32 tmp = tcg_temp_new_i32();
281 tcg_gen_shri_i32(tmp, var, 8);
282 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
283 tcg_gen_shli_i32(var, var, 8);
284 tcg_gen_andi_i32(var, var, 0xff00ff00);
285 tcg_gen_or_i32(var, var, tmp);
286 tcg_temp_free_i32(tmp);
289 /* Byteswap low halfword and sign extend. */
290 static void gen_revsh(TCGv_i32 var)
292 tcg_gen_ext16u_i32(var, var);
293 tcg_gen_bswap16_i32(var, var);
294 tcg_gen_ext16s_i32(var, var);
297 /* Unsigned bitfield extract. */
298 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
300 if (shift)
301 tcg_gen_shri_i32(var, var, shift);
302 tcg_gen_andi_i32(var, var, mask);
305 /* Signed bitfield extract. */
306 static void gen_sbfx(TCGv_i32 var, int shift, int width)
308 uint32_t signbit;
310 if (shift)
311 tcg_gen_sari_i32(var, var, shift);
312 if (shift + width < 32) {
313 signbit = 1u << (width - 1);
314 tcg_gen_andi_i32(var, var, (1u << width) - 1);
315 tcg_gen_xori_i32(var, var, signbit);
316 tcg_gen_subi_i32(var, var, signbit);
320 /* Return (b << 32) + a. Mark inputs as dead */
321 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
323 TCGv_i64 tmp64 = tcg_temp_new_i64();
325 tcg_gen_extu_i32_i64(tmp64, b);
326 tcg_temp_free_i32(b);
327 tcg_gen_shli_i64(tmp64, tmp64, 32);
328 tcg_gen_add_i64(a, tmp64, a);
330 tcg_temp_free_i64(tmp64);
331 return a;
334 /* Return (b << 32) - a. Mark inputs as dead. */
335 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
337 TCGv_i64 tmp64 = tcg_temp_new_i64();
339 tcg_gen_extu_i32_i64(tmp64, b);
340 tcg_temp_free_i32(b);
341 tcg_gen_shli_i64(tmp64, tmp64, 32);
342 tcg_gen_sub_i64(a, tmp64, a);
344 tcg_temp_free_i64(tmp64);
345 return a;
348 /* 32x32->64 multiply. Marks inputs as dead. */
349 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
351 TCGv_i32 lo = tcg_temp_new_i32();
352 TCGv_i32 hi = tcg_temp_new_i32();
353 TCGv_i64 ret;
355 tcg_gen_mulu2_i32(lo, hi, a, b);
356 tcg_temp_free_i32(a);
357 tcg_temp_free_i32(b);
359 ret = tcg_temp_new_i64();
360 tcg_gen_concat_i32_i64(ret, lo, hi);
361 tcg_temp_free_i32(lo);
362 tcg_temp_free_i32(hi);
364 return ret;
367 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
369 TCGv_i32 lo = tcg_temp_new_i32();
370 TCGv_i32 hi = tcg_temp_new_i32();
371 TCGv_i64 ret;
373 tcg_gen_muls2_i32(lo, hi, a, b);
374 tcg_temp_free_i32(a);
375 tcg_temp_free_i32(b);
377 ret = tcg_temp_new_i64();
378 tcg_gen_concat_i32_i64(ret, lo, hi);
379 tcg_temp_free_i32(lo);
380 tcg_temp_free_i32(hi);
382 return ret;
385 /* Swap low and high halfwords. */
386 static void gen_swap_half(TCGv_i32 var)
388 TCGv_i32 tmp = tcg_temp_new_i32();
389 tcg_gen_shri_i32(tmp, var, 16);
390 tcg_gen_shli_i32(var, var, 16);
391 tcg_gen_or_i32(var, var, tmp);
392 tcg_temp_free_i32(tmp);
395 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
396 tmp = (t0 ^ t1) & 0x8000;
397 t0 &= ~0x8000;
398 t1 &= ~0x8000;
399 t0 = (t0 + t1) ^ tmp;
402 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
404 TCGv_i32 tmp = tcg_temp_new_i32();
405 tcg_gen_xor_i32(tmp, t0, t1);
406 tcg_gen_andi_i32(tmp, tmp, 0x8000);
407 tcg_gen_andi_i32(t0, t0, ~0x8000);
408 tcg_gen_andi_i32(t1, t1, ~0x8000);
409 tcg_gen_add_i32(t0, t0, t1);
410 tcg_gen_xor_i32(t0, t0, tmp);
411 tcg_temp_free_i32(tmp);
412 tcg_temp_free_i32(t1);
415 /* Set CF to the top bit of var. */
416 static void gen_set_CF_bit31(TCGv_i32 var)
418 tcg_gen_shri_i32(cpu_CF, var, 31);
421 /* Set N and Z flags from var. */
422 static inline void gen_logic_CC(TCGv_i32 var)
424 tcg_gen_mov_i32(cpu_NF, var);
425 tcg_gen_mov_i32(cpu_ZF, var);
428 /* T0 += T1 + CF. */
429 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
431 tcg_gen_add_i32(t0, t0, t1);
432 tcg_gen_add_i32(t0, t0, cpu_CF);
435 /* dest = T0 + T1 + CF. */
436 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
438 tcg_gen_add_i32(dest, t0, t1);
439 tcg_gen_add_i32(dest, dest, cpu_CF);
442 /* dest = T0 - T1 + CF - 1. */
443 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
445 tcg_gen_sub_i32(dest, t0, t1);
446 tcg_gen_add_i32(dest, dest, cpu_CF);
447 tcg_gen_subi_i32(dest, dest, 1);
450 /* dest = T0 + T1. Compute C, N, V and Z flags */
451 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
453 TCGv_i32 tmp = tcg_temp_new_i32();
454 tcg_gen_movi_i32(tmp, 0);
455 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
456 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
457 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
458 tcg_gen_xor_i32(tmp, t0, t1);
459 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
460 tcg_temp_free_i32(tmp);
461 tcg_gen_mov_i32(dest, cpu_NF);
464 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
465 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
467 TCGv_i32 tmp = tcg_temp_new_i32();
468 if (TCG_TARGET_HAS_add2_i32) {
469 tcg_gen_movi_i32(tmp, 0);
470 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
471 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
472 } else {
473 TCGv_i64 q0 = tcg_temp_new_i64();
474 TCGv_i64 q1 = tcg_temp_new_i64();
475 tcg_gen_extu_i32_i64(q0, t0);
476 tcg_gen_extu_i32_i64(q1, t1);
477 tcg_gen_add_i64(q0, q0, q1);
478 tcg_gen_extu_i32_i64(q1, cpu_CF);
479 tcg_gen_add_i64(q0, q0, q1);
480 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
481 tcg_temp_free_i64(q0);
482 tcg_temp_free_i64(q1);
484 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
485 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
486 tcg_gen_xor_i32(tmp, t0, t1);
487 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
488 tcg_temp_free_i32(tmp);
489 tcg_gen_mov_i32(dest, cpu_NF);
492 /* dest = T0 - T1. Compute C, N, V and Z flags */
493 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
495 TCGv_i32 tmp;
496 tcg_gen_sub_i32(cpu_NF, t0, t1);
497 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
498 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
499 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
500 tmp = tcg_temp_new_i32();
501 tcg_gen_xor_i32(tmp, t0, t1);
502 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
503 tcg_temp_free_i32(tmp);
504 tcg_gen_mov_i32(dest, cpu_NF);
507 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
508 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
510 TCGv_i32 tmp = tcg_temp_new_i32();
511 tcg_gen_not_i32(tmp, t1);
512 gen_adc_CC(dest, t0, tmp);
513 tcg_temp_free_i32(tmp);
516 #define GEN_SHIFT(name) \
517 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
519 TCGv_i32 tmp1, tmp2, tmp3; \
520 tmp1 = tcg_temp_new_i32(); \
521 tcg_gen_andi_i32(tmp1, t1, 0xff); \
522 tmp2 = tcg_const_i32(0); \
523 tmp3 = tcg_const_i32(0x1f); \
524 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
525 tcg_temp_free_i32(tmp3); \
526 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
527 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
528 tcg_temp_free_i32(tmp2); \
529 tcg_temp_free_i32(tmp1); \
531 GEN_SHIFT(shl)
532 GEN_SHIFT(shr)
533 #undef GEN_SHIFT
535 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
537 TCGv_i32 tmp1, tmp2;
538 tmp1 = tcg_temp_new_i32();
539 tcg_gen_andi_i32(tmp1, t1, 0xff);
540 tmp2 = tcg_const_i32(0x1f);
541 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
542 tcg_temp_free_i32(tmp2);
543 tcg_gen_sar_i32(dest, t0, tmp1);
544 tcg_temp_free_i32(tmp1);
547 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
549 TCGv_i32 c0 = tcg_const_i32(0);
550 TCGv_i32 tmp = tcg_temp_new_i32();
551 tcg_gen_neg_i32(tmp, src);
552 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
553 tcg_temp_free_i32(c0);
554 tcg_temp_free_i32(tmp);
557 static void shifter_out_im(TCGv_i32 var, int shift)
559 if (shift == 0) {
560 tcg_gen_andi_i32(cpu_CF, var, 1);
561 } else {
562 tcg_gen_shri_i32(cpu_CF, var, shift);
563 if (shift != 31) {
564 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
569 /* Shift by immediate. Includes special handling for shift == 0. */
570 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
571 int shift, int flags)
573 switch (shiftop) {
574 case 0: /* LSL */
575 if (shift != 0) {
576 if (flags)
577 shifter_out_im(var, 32 - shift);
578 tcg_gen_shli_i32(var, var, shift);
580 break;
581 case 1: /* LSR */
582 if (shift == 0) {
583 if (flags) {
584 tcg_gen_shri_i32(cpu_CF, var, 31);
586 tcg_gen_movi_i32(var, 0);
587 } else {
588 if (flags)
589 shifter_out_im(var, shift - 1);
590 tcg_gen_shri_i32(var, var, shift);
592 break;
593 case 2: /* ASR */
594 if (shift == 0)
595 shift = 32;
596 if (flags)
597 shifter_out_im(var, shift - 1);
598 if (shift == 32)
599 shift = 31;
600 tcg_gen_sari_i32(var, var, shift);
601 break;
602 case 3: /* ROR/RRX */
603 if (shift != 0) {
604 if (flags)
605 shifter_out_im(var, shift - 1);
606 tcg_gen_rotri_i32(var, var, shift); break;
607 } else {
608 TCGv_i32 tmp = tcg_temp_new_i32();
609 tcg_gen_shli_i32(tmp, cpu_CF, 31);
610 if (flags)
611 shifter_out_im(var, 0);
612 tcg_gen_shri_i32(var, var, 1);
613 tcg_gen_or_i32(var, var, tmp);
614 tcg_temp_free_i32(tmp);
619 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
620 TCGv_i32 shift, int flags)
622 if (flags) {
623 switch (shiftop) {
624 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
625 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
626 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
627 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
629 } else {
630 switch (shiftop) {
631 case 0:
632 gen_shl(var, var, shift);
633 break;
634 case 1:
635 gen_shr(var, var, shift);
636 break;
637 case 2:
638 gen_sar(var, var, shift);
639 break;
640 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
641 tcg_gen_rotr_i32(var, var, shift); break;
644 tcg_temp_free_i32(shift);
647 #define PAS_OP(pfx) \
648 switch (op2) { \
649 case 0: gen_pas_helper(glue(pfx,add16)); break; \
650 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
651 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
652 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
653 case 4: gen_pas_helper(glue(pfx,add8)); break; \
654 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
656 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
658 TCGv_ptr tmp;
660 switch (op1) {
661 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
662 case 1:
663 tmp = tcg_temp_new_ptr();
664 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
665 PAS_OP(s)
666 tcg_temp_free_ptr(tmp);
667 break;
668 case 5:
669 tmp = tcg_temp_new_ptr();
670 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
671 PAS_OP(u)
672 tcg_temp_free_ptr(tmp);
673 break;
674 #undef gen_pas_helper
675 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
676 case 2:
677 PAS_OP(q);
678 break;
679 case 3:
680 PAS_OP(sh);
681 break;
682 case 6:
683 PAS_OP(uq);
684 break;
685 case 7:
686 PAS_OP(uh);
687 break;
688 #undef gen_pas_helper
691 #undef PAS_OP
693 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
694 #define PAS_OP(pfx) \
695 switch (op1) { \
696 case 0: gen_pas_helper(glue(pfx,add8)); break; \
697 case 1: gen_pas_helper(glue(pfx,add16)); break; \
698 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
699 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
700 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
701 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
703 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
705 TCGv_ptr tmp;
707 switch (op2) {
708 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
709 case 0:
710 tmp = tcg_temp_new_ptr();
711 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
712 PAS_OP(s)
713 tcg_temp_free_ptr(tmp);
714 break;
715 case 4:
716 tmp = tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
718 PAS_OP(u)
719 tcg_temp_free_ptr(tmp);
720 break;
721 #undef gen_pas_helper
722 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
723 case 1:
724 PAS_OP(q);
725 break;
726 case 2:
727 PAS_OP(sh);
728 break;
729 case 5:
730 PAS_OP(uq);
731 break;
732 case 6:
733 PAS_OP(uh);
734 break;
735 #undef gen_pas_helper
738 #undef PAS_OP
741 * generate a conditional branch based on ARM condition code cc.
742 * This is common between ARM and Aarch64 targets.
744 void arm_gen_test_cc(int cc, TCGLabel *label)
746 TCGv_i32 tmp;
747 TCGLabel *inv;
749 switch (cc) {
750 case 0: /* eq: Z */
751 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
752 break;
753 case 1: /* ne: !Z */
754 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
755 break;
756 case 2: /* cs: C */
757 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
758 break;
759 case 3: /* cc: !C */
760 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
761 break;
762 case 4: /* mi: N */
763 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
764 break;
765 case 5: /* pl: !N */
766 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
767 break;
768 case 6: /* vs: V */
769 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
770 break;
771 case 7: /* vc: !V */
772 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
773 break;
774 case 8: /* hi: C && !Z */
775 inv = gen_new_label();
776 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
777 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
778 gen_set_label(inv);
779 break;
780 case 9: /* ls: !C || Z */
781 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
782 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
783 break;
784 case 10: /* ge: N == V -> N ^ V == 0 */
785 tmp = tcg_temp_new_i32();
786 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
787 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
788 tcg_temp_free_i32(tmp);
789 break;
790 case 11: /* lt: N != V -> N ^ V != 0 */
791 tmp = tcg_temp_new_i32();
792 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
793 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
794 tcg_temp_free_i32(tmp);
795 break;
796 case 12: /* gt: !Z && N == V */
797 inv = gen_new_label();
798 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
799 tmp = tcg_temp_new_i32();
800 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
801 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
802 tcg_temp_free_i32(tmp);
803 gen_set_label(inv);
804 break;
805 case 13: /* le: Z || N != V */
806 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
807 tmp = tcg_temp_new_i32();
808 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
809 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
810 tcg_temp_free_i32(tmp);
811 break;
812 default:
813 fprintf(stderr, "Bad condition code 0x%x\n", cc);
814 abort();
818 static const uint8_t table_logic_cc[16] = {
819 1, /* and */
820 1, /* xor */
821 0, /* sub */
822 0, /* rsb */
823 0, /* add */
824 0, /* adc */
825 0, /* sbc */
826 0, /* rsc */
827 1, /* andl */
828 1, /* xorl */
829 0, /* cmp */
830 0, /* cmn */
831 1, /* orr */
832 1, /* mov */
833 1, /* bic */
834 1, /* mvn */
837 /* Set PC and Thumb state from an immediate address. */
838 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
840 TCGv_i32 tmp;
842 s->is_jmp = DISAS_UPDATE;
843 if (s->thumb != (addr & 1)) {
844 tmp = tcg_temp_new_i32();
845 tcg_gen_movi_i32(tmp, addr & 1);
846 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
847 tcg_temp_free_i32(tmp);
849 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
852 /* Set PC and Thumb state from var. var is marked as dead. */
853 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
855 s->is_jmp = DISAS_UPDATE;
856 tcg_gen_andi_i32(cpu_R[15], var, ~1);
857 tcg_gen_andi_i32(var, var, 1);
858 store_cpu_field(var, thumb);
861 /* Variant of store_reg which uses branch&exchange logic when storing
862 to r15 in ARM architecture v7 and above. The source must be a temporary
863 and will be marked as dead. */
864 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
866 if (reg == 15 && ENABLE_ARCH_7) {
867 gen_bx(s, var);
868 } else {
869 store_reg(s, reg, var);
873 /* Variant of store_reg which uses branch&exchange logic when storing
874 * to r15 in ARM architecture v5T and above. This is used for storing
875 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
876 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
877 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
879 if (reg == 15 && ENABLE_ARCH_5) {
880 gen_bx(s, var);
881 } else {
882 store_reg(s, reg, var);
886 /* Abstractions of "generate code to do a guest load/store for
887 * AArch32", where a vaddr is always 32 bits (and is zero
888 * extended if we're a 64 bit core) and data is also
889 * 32 bits unless specifically doing a 64 bit access.
890 * These functions work like tcg_gen_qemu_{ld,st}* except
891 * that the address argument is TCGv_i32 rather than TCGv.
893 #if TARGET_LONG_BITS == 32
895 #define DO_GEN_LD(SUFF, OPC) \
896 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
898 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
901 #define DO_GEN_ST(SUFF, OPC) \
902 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
904 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
907 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
909 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
912 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
914 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
917 #else
919 #define DO_GEN_LD(SUFF, OPC) \
920 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
922 TCGv addr64 = tcg_temp_new(); \
923 tcg_gen_extu_i32_i64(addr64, addr); \
924 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
925 tcg_temp_free(addr64); \
928 #define DO_GEN_ST(SUFF, OPC) \
929 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
931 TCGv addr64 = tcg_temp_new(); \
932 tcg_gen_extu_i32_i64(addr64, addr); \
933 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
934 tcg_temp_free(addr64); \
937 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
939 TCGv addr64 = tcg_temp_new();
940 tcg_gen_extu_i32_i64(addr64, addr);
941 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
942 tcg_temp_free(addr64);
945 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
947 TCGv addr64 = tcg_temp_new();
948 tcg_gen_extu_i32_i64(addr64, addr);
949 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
950 tcg_temp_free(addr64);
953 #endif
955 DO_GEN_LD(8s, MO_SB)
956 DO_GEN_LD(8u, MO_UB)
957 DO_GEN_LD(16s, MO_TESW)
958 DO_GEN_LD(16u, MO_TEUW)
959 DO_GEN_LD(32u, MO_TEUL)
960 DO_GEN_ST(8, MO_UB)
961 DO_GEN_ST(16, MO_TEUW)
962 DO_GEN_ST(32, MO_TEUL)
964 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
966 tcg_gen_movi_i32(cpu_R[15], val);
969 static inline void gen_hvc(DisasContext *s, int imm16)
971 /* The pre HVC helper handles cases when HVC gets trapped
972 * as an undefined insn by runtime configuration (ie before
973 * the insn really executes).
975 gen_set_pc_im(s, s->pc - 4);
976 gen_helper_pre_hvc(cpu_env);
977 /* Otherwise we will treat this as a real exception which
978 * happens after execution of the insn. (The distinction matters
979 * for the PC value reported to the exception handler and also
980 * for single stepping.)
982 s->svc_imm = imm16;
983 gen_set_pc_im(s, s->pc);
984 s->is_jmp = DISAS_HVC;
987 static inline void gen_smc(DisasContext *s)
989 /* As with HVC, we may take an exception either before or after
990 * the insn executes.
992 TCGv_i32 tmp;
994 gen_set_pc_im(s, s->pc - 4);
995 tmp = tcg_const_i32(syn_aa32_smc());
996 gen_helper_pre_smc(cpu_env, tmp);
997 tcg_temp_free_i32(tmp);
998 gen_set_pc_im(s, s->pc);
999 s->is_jmp = DISAS_SMC;
1002 static inline void
1003 gen_set_condexec (DisasContext *s)
1005 if (s->condexec_mask) {
1006 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1007 TCGv_i32 tmp = tcg_temp_new_i32();
1008 tcg_gen_movi_i32(tmp, val);
1009 store_cpu_field(tmp, condexec_bits);
1013 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1015 gen_set_condexec(s);
1016 gen_set_pc_im(s, s->pc - offset);
1017 gen_exception_internal(excp);
1018 s->is_jmp = DISAS_JUMP;
1021 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1022 int syn, uint32_t target_el)
1024 gen_set_condexec(s);
1025 gen_set_pc_im(s, s->pc - offset);
1026 gen_exception(excp, syn, target_el);
1027 s->is_jmp = DISAS_JUMP;
1030 /* Force a TB lookup after an instruction that changes the CPU state. */
1031 static inline void gen_lookup_tb(DisasContext *s)
1033 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1034 s->is_jmp = DISAS_UPDATE;
1037 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1038 TCGv_i32 var)
1040 int val, rm, shift, shiftop;
1041 TCGv_i32 offset;
1043 if (!(insn & (1 << 25))) {
1044 /* immediate */
1045 val = insn & 0xfff;
1046 if (!(insn & (1 << 23)))
1047 val = -val;
1048 if (val != 0)
1049 tcg_gen_addi_i32(var, var, val);
1050 } else {
1051 /* shift/register */
1052 rm = (insn) & 0xf;
1053 shift = (insn >> 7) & 0x1f;
1054 shiftop = (insn >> 5) & 3;
1055 offset = load_reg(s, rm);
1056 gen_arm_shift_im(offset, shiftop, shift, 0);
1057 if (!(insn & (1 << 23)))
1058 tcg_gen_sub_i32(var, var, offset);
1059 else
1060 tcg_gen_add_i32(var, var, offset);
1061 tcg_temp_free_i32(offset);
1065 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1066 int extra, TCGv_i32 var)
1068 int val, rm;
1069 TCGv_i32 offset;
1071 if (insn & (1 << 22)) {
1072 /* immediate */
1073 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1074 if (!(insn & (1 << 23)))
1075 val = -val;
1076 val += extra;
1077 if (val != 0)
1078 tcg_gen_addi_i32(var, var, val);
1079 } else {
1080 /* register */
1081 if (extra)
1082 tcg_gen_addi_i32(var, var, extra);
1083 rm = (insn) & 0xf;
1084 offset = load_reg(s, rm);
1085 if (!(insn & (1 << 23)))
1086 tcg_gen_sub_i32(var, var, offset);
1087 else
1088 tcg_gen_add_i32(var, var, offset);
1089 tcg_temp_free_i32(offset);
1093 static TCGv_ptr get_fpstatus_ptr(int neon)
1095 TCGv_ptr statusptr = tcg_temp_new_ptr();
1096 int offset;
1097 if (neon) {
1098 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1099 } else {
1100 offset = offsetof(CPUARMState, vfp.fp_status);
1102 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1103 return statusptr;
1106 #define VFP_OP2(name) \
1107 static inline void gen_vfp_##name(int dp) \
1109 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1110 if (dp) { \
1111 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1112 } else { \
1113 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1115 tcg_temp_free_ptr(fpst); \
1118 VFP_OP2(add)
1119 VFP_OP2(sub)
1120 VFP_OP2(mul)
1121 VFP_OP2(div)
1123 #undef VFP_OP2
1125 static inline void gen_vfp_F1_mul(int dp)
1127 /* Like gen_vfp_mul() but put result in F1 */
1128 TCGv_ptr fpst = get_fpstatus_ptr(0);
1129 if (dp) {
1130 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1131 } else {
1132 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1134 tcg_temp_free_ptr(fpst);
1137 static inline void gen_vfp_F1_neg(int dp)
1139 /* Like gen_vfp_neg() but put result in F1 */
1140 if (dp) {
1141 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1142 } else {
1143 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1147 static inline void gen_vfp_abs(int dp)
1149 if (dp)
1150 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1151 else
1152 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1155 static inline void gen_vfp_neg(int dp)
1157 if (dp)
1158 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1159 else
1160 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1163 static inline void gen_vfp_sqrt(int dp)
1165 if (dp)
1166 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1167 else
1168 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1171 static inline void gen_vfp_cmp(int dp)
1173 if (dp)
1174 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1175 else
1176 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1179 static inline void gen_vfp_cmpe(int dp)
1181 if (dp)
1182 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1183 else
1184 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1187 static inline void gen_vfp_F1_ld0(int dp)
1189 if (dp)
1190 tcg_gen_movi_i64(cpu_F1d, 0);
1191 else
1192 tcg_gen_movi_i32(cpu_F1s, 0);
1195 #define VFP_GEN_ITOF(name) \
1196 static inline void gen_vfp_##name(int dp, int neon) \
1198 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1199 if (dp) { \
1200 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1201 } else { \
1202 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1204 tcg_temp_free_ptr(statusptr); \
1207 VFP_GEN_ITOF(uito)
1208 VFP_GEN_ITOF(sito)
1209 #undef VFP_GEN_ITOF
1211 #define VFP_GEN_FTOI(name) \
1212 static inline void gen_vfp_##name(int dp, int neon) \
1214 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1215 if (dp) { \
1216 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1217 } else { \
1218 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1220 tcg_temp_free_ptr(statusptr); \
1223 VFP_GEN_FTOI(toui)
1224 VFP_GEN_FTOI(touiz)
1225 VFP_GEN_FTOI(tosi)
1226 VFP_GEN_FTOI(tosiz)
1227 #undef VFP_GEN_FTOI
1229 #define VFP_GEN_FIX(name, round) \
1230 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1232 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1233 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1234 if (dp) { \
1235 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1236 statusptr); \
1237 } else { \
1238 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1239 statusptr); \
1241 tcg_temp_free_i32(tmp_shift); \
1242 tcg_temp_free_ptr(statusptr); \
1244 VFP_GEN_FIX(tosh, _round_to_zero)
1245 VFP_GEN_FIX(tosl, _round_to_zero)
1246 VFP_GEN_FIX(touh, _round_to_zero)
1247 VFP_GEN_FIX(toul, _round_to_zero)
1248 VFP_GEN_FIX(shto, )
1249 VFP_GEN_FIX(slto, )
1250 VFP_GEN_FIX(uhto, )
1251 VFP_GEN_FIX(ulto, )
1252 #undef VFP_GEN_FIX
1254 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1256 if (dp) {
1257 gen_aa32_ld64(cpu_F0d, addr, get_mem_index(s));
1258 } else {
1259 gen_aa32_ld32u(cpu_F0s, addr, get_mem_index(s));
1263 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1265 if (dp) {
1266 gen_aa32_st64(cpu_F0d, addr, get_mem_index(s));
1267 } else {
1268 gen_aa32_st32(cpu_F0s, addr, get_mem_index(s));
1272 static inline long
1273 vfp_reg_offset (int dp, int reg)
1275 if (dp)
1276 return offsetof(CPUARMState, vfp.regs[reg]);
1277 else if (reg & 1) {
1278 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1279 + offsetof(CPU_DoubleU, l.upper);
1280 } else {
1281 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1282 + offsetof(CPU_DoubleU, l.lower);
1286 /* Return the offset of a 32-bit piece of a NEON register.
1287 zero is the least significant end of the register. */
1288 static inline long
1289 neon_reg_offset (int reg, int n)
1291 int sreg;
1292 sreg = reg * 2 + n;
1293 return vfp_reg_offset(0, sreg);
1296 static TCGv_i32 neon_load_reg(int reg, int pass)
1298 TCGv_i32 tmp = tcg_temp_new_i32();
1299 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1300 return tmp;
1303 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1305 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1306 tcg_temp_free_i32(var);
1309 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1311 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1314 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1316 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1319 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1320 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1321 #define tcg_gen_st_f32 tcg_gen_st_i32
1322 #define tcg_gen_st_f64 tcg_gen_st_i64
1324 static inline void gen_mov_F0_vreg(int dp, int reg)
1326 if (dp)
1327 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1328 else
1329 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1332 static inline void gen_mov_F1_vreg(int dp, int reg)
1334 if (dp)
1335 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1336 else
1337 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1340 static inline void gen_mov_vreg_F0(int dp, int reg)
1342 if (dp)
1343 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1344 else
1345 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1348 #define ARM_CP_RW_BIT (1 << 20)
1350 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1352 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1355 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1357 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1360 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1362 TCGv_i32 var = tcg_temp_new_i32();
1363 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1364 return var;
1367 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1369 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1370 tcg_temp_free_i32(var);
1373 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1375 iwmmxt_store_reg(cpu_M0, rn);
1378 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1380 iwmmxt_load_reg(cpu_M0, rn);
1383 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1385 iwmmxt_load_reg(cpu_V1, rn);
1386 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1389 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1391 iwmmxt_load_reg(cpu_V1, rn);
1392 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1395 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1397 iwmmxt_load_reg(cpu_V1, rn);
1398 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1401 #define IWMMXT_OP(name) \
1402 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1404 iwmmxt_load_reg(cpu_V1, rn); \
1405 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1408 #define IWMMXT_OP_ENV(name) \
1409 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1411 iwmmxt_load_reg(cpu_V1, rn); \
1412 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1415 #define IWMMXT_OP_ENV_SIZE(name) \
1416 IWMMXT_OP_ENV(name##b) \
1417 IWMMXT_OP_ENV(name##w) \
1418 IWMMXT_OP_ENV(name##l)
1420 #define IWMMXT_OP_ENV1(name) \
1421 static inline void gen_op_iwmmxt_##name##_M0(void) \
1423 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1426 IWMMXT_OP(maddsq)
1427 IWMMXT_OP(madduq)
1428 IWMMXT_OP(sadb)
1429 IWMMXT_OP(sadw)
1430 IWMMXT_OP(mulslw)
1431 IWMMXT_OP(mulshw)
1432 IWMMXT_OP(mululw)
1433 IWMMXT_OP(muluhw)
1434 IWMMXT_OP(macsw)
1435 IWMMXT_OP(macuw)
1437 IWMMXT_OP_ENV_SIZE(unpackl)
1438 IWMMXT_OP_ENV_SIZE(unpackh)
1440 IWMMXT_OP_ENV1(unpacklub)
1441 IWMMXT_OP_ENV1(unpackluw)
1442 IWMMXT_OP_ENV1(unpacklul)
1443 IWMMXT_OP_ENV1(unpackhub)
1444 IWMMXT_OP_ENV1(unpackhuw)
1445 IWMMXT_OP_ENV1(unpackhul)
1446 IWMMXT_OP_ENV1(unpacklsb)
1447 IWMMXT_OP_ENV1(unpacklsw)
1448 IWMMXT_OP_ENV1(unpacklsl)
1449 IWMMXT_OP_ENV1(unpackhsb)
1450 IWMMXT_OP_ENV1(unpackhsw)
1451 IWMMXT_OP_ENV1(unpackhsl)
1453 IWMMXT_OP_ENV_SIZE(cmpeq)
1454 IWMMXT_OP_ENV_SIZE(cmpgtu)
1455 IWMMXT_OP_ENV_SIZE(cmpgts)
1457 IWMMXT_OP_ENV_SIZE(mins)
1458 IWMMXT_OP_ENV_SIZE(minu)
1459 IWMMXT_OP_ENV_SIZE(maxs)
1460 IWMMXT_OP_ENV_SIZE(maxu)
1462 IWMMXT_OP_ENV_SIZE(subn)
1463 IWMMXT_OP_ENV_SIZE(addn)
1464 IWMMXT_OP_ENV_SIZE(subu)
1465 IWMMXT_OP_ENV_SIZE(addu)
1466 IWMMXT_OP_ENV_SIZE(subs)
1467 IWMMXT_OP_ENV_SIZE(adds)
1469 IWMMXT_OP_ENV(avgb0)
1470 IWMMXT_OP_ENV(avgb1)
1471 IWMMXT_OP_ENV(avgw0)
1472 IWMMXT_OP_ENV(avgw1)
1474 IWMMXT_OP_ENV(packuw)
1475 IWMMXT_OP_ENV(packul)
1476 IWMMXT_OP_ENV(packuq)
1477 IWMMXT_OP_ENV(packsw)
1478 IWMMXT_OP_ENV(packsl)
1479 IWMMXT_OP_ENV(packsq)
1481 static void gen_op_iwmmxt_set_mup(void)
1483 TCGv_i32 tmp;
1484 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1485 tcg_gen_ori_i32(tmp, tmp, 2);
1486 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1489 static void gen_op_iwmmxt_set_cup(void)
1491 TCGv_i32 tmp;
1492 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1493 tcg_gen_ori_i32(tmp, tmp, 1);
1494 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1497 static void gen_op_iwmmxt_setpsr_nz(void)
1499 TCGv_i32 tmp = tcg_temp_new_i32();
1500 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1501 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1504 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1506 iwmmxt_load_reg(cpu_V1, rn);
1507 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1508 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1511 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1512 TCGv_i32 dest)
1514 int rd;
1515 uint32_t offset;
1516 TCGv_i32 tmp;
1518 rd = (insn >> 16) & 0xf;
1519 tmp = load_reg(s, rd);
1521 offset = (insn & 0xff) << ((insn >> 7) & 2);
1522 if (insn & (1 << 24)) {
1523 /* Pre indexed */
1524 if (insn & (1 << 23))
1525 tcg_gen_addi_i32(tmp, tmp, offset);
1526 else
1527 tcg_gen_addi_i32(tmp, tmp, -offset);
1528 tcg_gen_mov_i32(dest, tmp);
1529 if (insn & (1 << 21))
1530 store_reg(s, rd, tmp);
1531 else
1532 tcg_temp_free_i32(tmp);
1533 } else if (insn & (1 << 21)) {
1534 /* Post indexed */
1535 tcg_gen_mov_i32(dest, tmp);
1536 if (insn & (1 << 23))
1537 tcg_gen_addi_i32(tmp, tmp, offset);
1538 else
1539 tcg_gen_addi_i32(tmp, tmp, -offset);
1540 store_reg(s, rd, tmp);
1541 } else if (!(insn & (1 << 23)))
1542 return 1;
1543 return 0;
1546 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1548 int rd = (insn >> 0) & 0xf;
1549 TCGv_i32 tmp;
1551 if (insn & (1 << 8)) {
1552 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1553 return 1;
1554 } else {
1555 tmp = iwmmxt_load_creg(rd);
1557 } else {
1558 tmp = tcg_temp_new_i32();
1559 iwmmxt_load_reg(cpu_V0, rd);
1560 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1562 tcg_gen_andi_i32(tmp, tmp, mask);
1563 tcg_gen_mov_i32(dest, tmp);
1564 tcg_temp_free_i32(tmp);
1565 return 0;
1568 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1569 (ie. an undefined instruction). */
1570 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1572 int rd, wrd;
1573 int rdhi, rdlo, rd0, rd1, i;
1574 TCGv_i32 addr;
1575 TCGv_i32 tmp, tmp2, tmp3;
1577 if ((insn & 0x0e000e00) == 0x0c000000) {
1578 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1579 wrd = insn & 0xf;
1580 rdlo = (insn >> 12) & 0xf;
1581 rdhi = (insn >> 16) & 0xf;
1582 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1583 iwmmxt_load_reg(cpu_V0, wrd);
1584 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1585 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1586 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1587 } else { /* TMCRR */
1588 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1589 iwmmxt_store_reg(cpu_V0, wrd);
1590 gen_op_iwmmxt_set_mup();
1592 return 0;
1595 wrd = (insn >> 12) & 0xf;
1596 addr = tcg_temp_new_i32();
1597 if (gen_iwmmxt_address(s, insn, addr)) {
1598 tcg_temp_free_i32(addr);
1599 return 1;
1601 if (insn & ARM_CP_RW_BIT) {
1602 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1603 tmp = tcg_temp_new_i32();
1604 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1605 iwmmxt_store_creg(wrd, tmp);
1606 } else {
1607 i = 1;
1608 if (insn & (1 << 8)) {
1609 if (insn & (1 << 22)) { /* WLDRD */
1610 gen_aa32_ld64(cpu_M0, addr, get_mem_index(s));
1611 i = 0;
1612 } else { /* WLDRW wRd */
1613 tmp = tcg_temp_new_i32();
1614 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1616 } else {
1617 tmp = tcg_temp_new_i32();
1618 if (insn & (1 << 22)) { /* WLDRH */
1619 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
1620 } else { /* WLDRB */
1621 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
1624 if (i) {
1625 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1626 tcg_temp_free_i32(tmp);
1628 gen_op_iwmmxt_movq_wRn_M0(wrd);
1630 } else {
1631 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1632 tmp = iwmmxt_load_creg(wrd);
1633 gen_aa32_st32(tmp, addr, get_mem_index(s));
1634 } else {
1635 gen_op_iwmmxt_movq_M0_wRn(wrd);
1636 tmp = tcg_temp_new_i32();
1637 if (insn & (1 << 8)) {
1638 if (insn & (1 << 22)) { /* WSTRD */
1639 gen_aa32_st64(cpu_M0, addr, get_mem_index(s));
1640 } else { /* WSTRW wRd */
1641 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1642 gen_aa32_st32(tmp, addr, get_mem_index(s));
1644 } else {
1645 if (insn & (1 << 22)) { /* WSTRH */
1646 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1647 gen_aa32_st16(tmp, addr, get_mem_index(s));
1648 } else { /* WSTRB */
1649 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1650 gen_aa32_st8(tmp, addr, get_mem_index(s));
1654 tcg_temp_free_i32(tmp);
1656 tcg_temp_free_i32(addr);
1657 return 0;
1660 if ((insn & 0x0f000000) != 0x0e000000)
1661 return 1;
1663 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1664 case 0x000: /* WOR */
1665 wrd = (insn >> 12) & 0xf;
1666 rd0 = (insn >> 0) & 0xf;
1667 rd1 = (insn >> 16) & 0xf;
1668 gen_op_iwmmxt_movq_M0_wRn(rd0);
1669 gen_op_iwmmxt_orq_M0_wRn(rd1);
1670 gen_op_iwmmxt_setpsr_nz();
1671 gen_op_iwmmxt_movq_wRn_M0(wrd);
1672 gen_op_iwmmxt_set_mup();
1673 gen_op_iwmmxt_set_cup();
1674 break;
1675 case 0x011: /* TMCR */
1676 if (insn & 0xf)
1677 return 1;
1678 rd = (insn >> 12) & 0xf;
1679 wrd = (insn >> 16) & 0xf;
1680 switch (wrd) {
1681 case ARM_IWMMXT_wCID:
1682 case ARM_IWMMXT_wCASF:
1683 break;
1684 case ARM_IWMMXT_wCon:
1685 gen_op_iwmmxt_set_cup();
1686 /* Fall through. */
1687 case ARM_IWMMXT_wCSSF:
1688 tmp = iwmmxt_load_creg(wrd);
1689 tmp2 = load_reg(s, rd);
1690 tcg_gen_andc_i32(tmp, tmp, tmp2);
1691 tcg_temp_free_i32(tmp2);
1692 iwmmxt_store_creg(wrd, tmp);
1693 break;
1694 case ARM_IWMMXT_wCGR0:
1695 case ARM_IWMMXT_wCGR1:
1696 case ARM_IWMMXT_wCGR2:
1697 case ARM_IWMMXT_wCGR3:
1698 gen_op_iwmmxt_set_cup();
1699 tmp = load_reg(s, rd);
1700 iwmmxt_store_creg(wrd, tmp);
1701 break;
1702 default:
1703 return 1;
1705 break;
1706 case 0x100: /* WXOR */
1707 wrd = (insn >> 12) & 0xf;
1708 rd0 = (insn >> 0) & 0xf;
1709 rd1 = (insn >> 16) & 0xf;
1710 gen_op_iwmmxt_movq_M0_wRn(rd0);
1711 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1712 gen_op_iwmmxt_setpsr_nz();
1713 gen_op_iwmmxt_movq_wRn_M0(wrd);
1714 gen_op_iwmmxt_set_mup();
1715 gen_op_iwmmxt_set_cup();
1716 break;
1717 case 0x111: /* TMRC */
1718 if (insn & 0xf)
1719 return 1;
1720 rd = (insn >> 12) & 0xf;
1721 wrd = (insn >> 16) & 0xf;
1722 tmp = iwmmxt_load_creg(wrd);
1723 store_reg(s, rd, tmp);
1724 break;
1725 case 0x300: /* WANDN */
1726 wrd = (insn >> 12) & 0xf;
1727 rd0 = (insn >> 0) & 0xf;
1728 rd1 = (insn >> 16) & 0xf;
1729 gen_op_iwmmxt_movq_M0_wRn(rd0);
1730 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1731 gen_op_iwmmxt_andq_M0_wRn(rd1);
1732 gen_op_iwmmxt_setpsr_nz();
1733 gen_op_iwmmxt_movq_wRn_M0(wrd);
1734 gen_op_iwmmxt_set_mup();
1735 gen_op_iwmmxt_set_cup();
1736 break;
1737 case 0x200: /* WAND */
1738 wrd = (insn >> 12) & 0xf;
1739 rd0 = (insn >> 0) & 0xf;
1740 rd1 = (insn >> 16) & 0xf;
1741 gen_op_iwmmxt_movq_M0_wRn(rd0);
1742 gen_op_iwmmxt_andq_M0_wRn(rd1);
1743 gen_op_iwmmxt_setpsr_nz();
1744 gen_op_iwmmxt_movq_wRn_M0(wrd);
1745 gen_op_iwmmxt_set_mup();
1746 gen_op_iwmmxt_set_cup();
1747 break;
1748 case 0x810: case 0xa10: /* WMADD */
1749 wrd = (insn >> 12) & 0xf;
1750 rd0 = (insn >> 0) & 0xf;
1751 rd1 = (insn >> 16) & 0xf;
1752 gen_op_iwmmxt_movq_M0_wRn(rd0);
1753 if (insn & (1 << 21))
1754 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1755 else
1756 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1757 gen_op_iwmmxt_movq_wRn_M0(wrd);
1758 gen_op_iwmmxt_set_mup();
1759 break;
1760 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1761 wrd = (insn >> 12) & 0xf;
1762 rd0 = (insn >> 16) & 0xf;
1763 rd1 = (insn >> 0) & 0xf;
1764 gen_op_iwmmxt_movq_M0_wRn(rd0);
1765 switch ((insn >> 22) & 3) {
1766 case 0:
1767 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1768 break;
1769 case 1:
1770 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1771 break;
1772 case 2:
1773 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1774 break;
1775 case 3:
1776 return 1;
1778 gen_op_iwmmxt_movq_wRn_M0(wrd);
1779 gen_op_iwmmxt_set_mup();
1780 gen_op_iwmmxt_set_cup();
1781 break;
1782 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1783 wrd = (insn >> 12) & 0xf;
1784 rd0 = (insn >> 16) & 0xf;
1785 rd1 = (insn >> 0) & 0xf;
1786 gen_op_iwmmxt_movq_M0_wRn(rd0);
1787 switch ((insn >> 22) & 3) {
1788 case 0:
1789 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1790 break;
1791 case 1:
1792 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1793 break;
1794 case 2:
1795 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1796 break;
1797 case 3:
1798 return 1;
1800 gen_op_iwmmxt_movq_wRn_M0(wrd);
1801 gen_op_iwmmxt_set_mup();
1802 gen_op_iwmmxt_set_cup();
1803 break;
1804 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1805 wrd = (insn >> 12) & 0xf;
1806 rd0 = (insn >> 16) & 0xf;
1807 rd1 = (insn >> 0) & 0xf;
1808 gen_op_iwmmxt_movq_M0_wRn(rd0);
1809 if (insn & (1 << 22))
1810 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1811 else
1812 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1813 if (!(insn & (1 << 20)))
1814 gen_op_iwmmxt_addl_M0_wRn(wrd);
1815 gen_op_iwmmxt_movq_wRn_M0(wrd);
1816 gen_op_iwmmxt_set_mup();
1817 break;
1818 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1819 wrd = (insn >> 12) & 0xf;
1820 rd0 = (insn >> 16) & 0xf;
1821 rd1 = (insn >> 0) & 0xf;
1822 gen_op_iwmmxt_movq_M0_wRn(rd0);
1823 if (insn & (1 << 21)) {
1824 if (insn & (1 << 20))
1825 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1826 else
1827 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1828 } else {
1829 if (insn & (1 << 20))
1830 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1831 else
1832 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1834 gen_op_iwmmxt_movq_wRn_M0(wrd);
1835 gen_op_iwmmxt_set_mup();
1836 break;
1837 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1838 wrd = (insn >> 12) & 0xf;
1839 rd0 = (insn >> 16) & 0xf;
1840 rd1 = (insn >> 0) & 0xf;
1841 gen_op_iwmmxt_movq_M0_wRn(rd0);
1842 if (insn & (1 << 21))
1843 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1844 else
1845 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1846 if (!(insn & (1 << 20))) {
1847 iwmmxt_load_reg(cpu_V1, wrd);
1848 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd);
1851 gen_op_iwmmxt_set_mup();
1852 break;
1853 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1854 wrd = (insn >> 12) & 0xf;
1855 rd0 = (insn >> 16) & 0xf;
1856 rd1 = (insn >> 0) & 0xf;
1857 gen_op_iwmmxt_movq_M0_wRn(rd0);
1858 switch ((insn >> 22) & 3) {
1859 case 0:
1860 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1861 break;
1862 case 1:
1863 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1864 break;
1865 case 2:
1866 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1867 break;
1868 case 3:
1869 return 1;
1871 gen_op_iwmmxt_movq_wRn_M0(wrd);
1872 gen_op_iwmmxt_set_mup();
1873 gen_op_iwmmxt_set_cup();
1874 break;
1875 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1876 wrd = (insn >> 12) & 0xf;
1877 rd0 = (insn >> 16) & 0xf;
1878 rd1 = (insn >> 0) & 0xf;
1879 gen_op_iwmmxt_movq_M0_wRn(rd0);
1880 if (insn & (1 << 22)) {
1881 if (insn & (1 << 20))
1882 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1883 else
1884 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1885 } else {
1886 if (insn & (1 << 20))
1887 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1888 else
1889 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1891 gen_op_iwmmxt_movq_wRn_M0(wrd);
1892 gen_op_iwmmxt_set_mup();
1893 gen_op_iwmmxt_set_cup();
1894 break;
1895 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1896 wrd = (insn >> 12) & 0xf;
1897 rd0 = (insn >> 16) & 0xf;
1898 rd1 = (insn >> 0) & 0xf;
1899 gen_op_iwmmxt_movq_M0_wRn(rd0);
1900 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1901 tcg_gen_andi_i32(tmp, tmp, 7);
1902 iwmmxt_load_reg(cpu_V1, rd1);
1903 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1904 tcg_temp_free_i32(tmp);
1905 gen_op_iwmmxt_movq_wRn_M0(wrd);
1906 gen_op_iwmmxt_set_mup();
1907 break;
1908 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1909 if (((insn >> 6) & 3) == 3)
1910 return 1;
1911 rd = (insn >> 12) & 0xf;
1912 wrd = (insn >> 16) & 0xf;
1913 tmp = load_reg(s, rd);
1914 gen_op_iwmmxt_movq_M0_wRn(wrd);
1915 switch ((insn >> 6) & 3) {
1916 case 0:
1917 tmp2 = tcg_const_i32(0xff);
1918 tmp3 = tcg_const_i32((insn & 7) << 3);
1919 break;
1920 case 1:
1921 tmp2 = tcg_const_i32(0xffff);
1922 tmp3 = tcg_const_i32((insn & 3) << 4);
1923 break;
1924 case 2:
1925 tmp2 = tcg_const_i32(0xffffffff);
1926 tmp3 = tcg_const_i32((insn & 1) << 5);
1927 break;
1928 default:
1929 TCGV_UNUSED_I32(tmp2);
1930 TCGV_UNUSED_I32(tmp3);
1932 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1933 tcg_temp_free_i32(tmp3);
1934 tcg_temp_free_i32(tmp2);
1935 tcg_temp_free_i32(tmp);
1936 gen_op_iwmmxt_movq_wRn_M0(wrd);
1937 gen_op_iwmmxt_set_mup();
1938 break;
1939 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1940 rd = (insn >> 12) & 0xf;
1941 wrd = (insn >> 16) & 0xf;
1942 if (rd == 15 || ((insn >> 22) & 3) == 3)
1943 return 1;
1944 gen_op_iwmmxt_movq_M0_wRn(wrd);
1945 tmp = tcg_temp_new_i32();
1946 switch ((insn >> 22) & 3) {
1947 case 0:
1948 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1949 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1950 if (insn & 8) {
1951 tcg_gen_ext8s_i32(tmp, tmp);
1952 } else {
1953 tcg_gen_andi_i32(tmp, tmp, 0xff);
1955 break;
1956 case 1:
1957 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1958 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1959 if (insn & 8) {
1960 tcg_gen_ext16s_i32(tmp, tmp);
1961 } else {
1962 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1964 break;
1965 case 2:
1966 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1967 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1968 break;
1970 store_reg(s, rd, tmp);
1971 break;
1972 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1973 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1974 return 1;
1975 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1976 switch ((insn >> 22) & 3) {
1977 case 0:
1978 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1979 break;
1980 case 1:
1981 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1982 break;
1983 case 2:
1984 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1985 break;
1987 tcg_gen_shli_i32(tmp, tmp, 28);
1988 gen_set_nzcv(tmp);
1989 tcg_temp_free_i32(tmp);
1990 break;
1991 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1992 if (((insn >> 6) & 3) == 3)
1993 return 1;
1994 rd = (insn >> 12) & 0xf;
1995 wrd = (insn >> 16) & 0xf;
1996 tmp = load_reg(s, rd);
1997 switch ((insn >> 6) & 3) {
1998 case 0:
1999 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2000 break;
2001 case 1:
2002 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2003 break;
2004 case 2:
2005 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2006 break;
2008 tcg_temp_free_i32(tmp);
2009 gen_op_iwmmxt_movq_wRn_M0(wrd);
2010 gen_op_iwmmxt_set_mup();
2011 break;
2012 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2013 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2014 return 1;
2015 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2016 tmp2 = tcg_temp_new_i32();
2017 tcg_gen_mov_i32(tmp2, tmp);
2018 switch ((insn >> 22) & 3) {
2019 case 0:
2020 for (i = 0; i < 7; i ++) {
2021 tcg_gen_shli_i32(tmp2, tmp2, 4);
2022 tcg_gen_and_i32(tmp, tmp, tmp2);
2024 break;
2025 case 1:
2026 for (i = 0; i < 3; i ++) {
2027 tcg_gen_shli_i32(tmp2, tmp2, 8);
2028 tcg_gen_and_i32(tmp, tmp, tmp2);
2030 break;
2031 case 2:
2032 tcg_gen_shli_i32(tmp2, tmp2, 16);
2033 tcg_gen_and_i32(tmp, tmp, tmp2);
2034 break;
2036 gen_set_nzcv(tmp);
2037 tcg_temp_free_i32(tmp2);
2038 tcg_temp_free_i32(tmp);
2039 break;
2040 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2041 wrd = (insn >> 12) & 0xf;
2042 rd0 = (insn >> 16) & 0xf;
2043 gen_op_iwmmxt_movq_M0_wRn(rd0);
2044 switch ((insn >> 22) & 3) {
2045 case 0:
2046 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2047 break;
2048 case 1:
2049 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2050 break;
2051 case 2:
2052 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2053 break;
2054 case 3:
2055 return 1;
2057 gen_op_iwmmxt_movq_wRn_M0(wrd);
2058 gen_op_iwmmxt_set_mup();
2059 break;
2060 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2061 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2062 return 1;
2063 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2064 tmp2 = tcg_temp_new_i32();
2065 tcg_gen_mov_i32(tmp2, tmp);
2066 switch ((insn >> 22) & 3) {
2067 case 0:
2068 for (i = 0; i < 7; i ++) {
2069 tcg_gen_shli_i32(tmp2, tmp2, 4);
2070 tcg_gen_or_i32(tmp, tmp, tmp2);
2072 break;
2073 case 1:
2074 for (i = 0; i < 3; i ++) {
2075 tcg_gen_shli_i32(tmp2, tmp2, 8);
2076 tcg_gen_or_i32(tmp, tmp, tmp2);
2078 break;
2079 case 2:
2080 tcg_gen_shli_i32(tmp2, tmp2, 16);
2081 tcg_gen_or_i32(tmp, tmp, tmp2);
2082 break;
2084 gen_set_nzcv(tmp);
2085 tcg_temp_free_i32(tmp2);
2086 tcg_temp_free_i32(tmp);
2087 break;
2088 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2089 rd = (insn >> 12) & 0xf;
2090 rd0 = (insn >> 16) & 0xf;
2091 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2092 return 1;
2093 gen_op_iwmmxt_movq_M0_wRn(rd0);
2094 tmp = tcg_temp_new_i32();
2095 switch ((insn >> 22) & 3) {
2096 case 0:
2097 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2098 break;
2099 case 1:
2100 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2101 break;
2102 case 2:
2103 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2104 break;
2106 store_reg(s, rd, tmp);
2107 break;
2108 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2109 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2110 wrd = (insn >> 12) & 0xf;
2111 rd0 = (insn >> 16) & 0xf;
2112 rd1 = (insn >> 0) & 0xf;
2113 gen_op_iwmmxt_movq_M0_wRn(rd0);
2114 switch ((insn >> 22) & 3) {
2115 case 0:
2116 if (insn & (1 << 21))
2117 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2118 else
2119 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2120 break;
2121 case 1:
2122 if (insn & (1 << 21))
2123 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2124 else
2125 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2126 break;
2127 case 2:
2128 if (insn & (1 << 21))
2129 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2130 else
2131 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2132 break;
2133 case 3:
2134 return 1;
2136 gen_op_iwmmxt_movq_wRn_M0(wrd);
2137 gen_op_iwmmxt_set_mup();
2138 gen_op_iwmmxt_set_cup();
2139 break;
2140 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2141 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2142 wrd = (insn >> 12) & 0xf;
2143 rd0 = (insn >> 16) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0);
2145 switch ((insn >> 22) & 3) {
2146 case 0:
2147 if (insn & (1 << 21))
2148 gen_op_iwmmxt_unpacklsb_M0();
2149 else
2150 gen_op_iwmmxt_unpacklub_M0();
2151 break;
2152 case 1:
2153 if (insn & (1 << 21))
2154 gen_op_iwmmxt_unpacklsw_M0();
2155 else
2156 gen_op_iwmmxt_unpackluw_M0();
2157 break;
2158 case 2:
2159 if (insn & (1 << 21))
2160 gen_op_iwmmxt_unpacklsl_M0();
2161 else
2162 gen_op_iwmmxt_unpacklul_M0();
2163 break;
2164 case 3:
2165 return 1;
2167 gen_op_iwmmxt_movq_wRn_M0(wrd);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2170 break;
2171 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2172 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2173 wrd = (insn >> 12) & 0xf;
2174 rd0 = (insn >> 16) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0);
2176 switch ((insn >> 22) & 3) {
2177 case 0:
2178 if (insn & (1 << 21))
2179 gen_op_iwmmxt_unpackhsb_M0();
2180 else
2181 gen_op_iwmmxt_unpackhub_M0();
2182 break;
2183 case 1:
2184 if (insn & (1 << 21))
2185 gen_op_iwmmxt_unpackhsw_M0();
2186 else
2187 gen_op_iwmmxt_unpackhuw_M0();
2188 break;
2189 case 2:
2190 if (insn & (1 << 21))
2191 gen_op_iwmmxt_unpackhsl_M0();
2192 else
2193 gen_op_iwmmxt_unpackhul_M0();
2194 break;
2195 case 3:
2196 return 1;
2198 gen_op_iwmmxt_movq_wRn_M0(wrd);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2201 break;
2202 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2203 case 0x214: case 0x614: case 0xa14: case 0xe14:
2204 if (((insn >> 22) & 3) == 0)
2205 return 1;
2206 wrd = (insn >> 12) & 0xf;
2207 rd0 = (insn >> 16) & 0xf;
2208 gen_op_iwmmxt_movq_M0_wRn(rd0);
2209 tmp = tcg_temp_new_i32();
2210 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2211 tcg_temp_free_i32(tmp);
2212 return 1;
2214 switch ((insn >> 22) & 3) {
2215 case 1:
2216 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2217 break;
2218 case 2:
2219 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2220 break;
2221 case 3:
2222 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2223 break;
2225 tcg_temp_free_i32(tmp);
2226 gen_op_iwmmxt_movq_wRn_M0(wrd);
2227 gen_op_iwmmxt_set_mup();
2228 gen_op_iwmmxt_set_cup();
2229 break;
2230 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2231 case 0x014: case 0x414: case 0x814: case 0xc14:
2232 if (((insn >> 22) & 3) == 0)
2233 return 1;
2234 wrd = (insn >> 12) & 0xf;
2235 rd0 = (insn >> 16) & 0xf;
2236 gen_op_iwmmxt_movq_M0_wRn(rd0);
2237 tmp = tcg_temp_new_i32();
2238 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2239 tcg_temp_free_i32(tmp);
2240 return 1;
2242 switch ((insn >> 22) & 3) {
2243 case 1:
2244 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2245 break;
2246 case 2:
2247 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2248 break;
2249 case 3:
2250 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2251 break;
2253 tcg_temp_free_i32(tmp);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2257 break;
2258 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2259 case 0x114: case 0x514: case 0x914: case 0xd14:
2260 if (((insn >> 22) & 3) == 0)
2261 return 1;
2262 wrd = (insn >> 12) & 0xf;
2263 rd0 = (insn >> 16) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0);
2265 tmp = tcg_temp_new_i32();
2266 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2267 tcg_temp_free_i32(tmp);
2268 return 1;
2270 switch ((insn >> 22) & 3) {
2271 case 1:
2272 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2273 break;
2274 case 2:
2275 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2276 break;
2277 case 3:
2278 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2279 break;
2281 tcg_temp_free_i32(tmp);
2282 gen_op_iwmmxt_movq_wRn_M0(wrd);
2283 gen_op_iwmmxt_set_mup();
2284 gen_op_iwmmxt_set_cup();
2285 break;
2286 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2287 case 0x314: case 0x714: case 0xb14: case 0xf14:
2288 if (((insn >> 22) & 3) == 0)
2289 return 1;
2290 wrd = (insn >> 12) & 0xf;
2291 rd0 = (insn >> 16) & 0xf;
2292 gen_op_iwmmxt_movq_M0_wRn(rd0);
2293 tmp = tcg_temp_new_i32();
2294 switch ((insn >> 22) & 3) {
2295 case 1:
2296 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2297 tcg_temp_free_i32(tmp);
2298 return 1;
2300 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2301 break;
2302 case 2:
2303 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2304 tcg_temp_free_i32(tmp);
2305 return 1;
2307 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2308 break;
2309 case 3:
2310 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2311 tcg_temp_free_i32(tmp);
2312 return 1;
2314 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2315 break;
2317 tcg_temp_free_i32(tmp);
2318 gen_op_iwmmxt_movq_wRn_M0(wrd);
2319 gen_op_iwmmxt_set_mup();
2320 gen_op_iwmmxt_set_cup();
2321 break;
2322 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2323 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2324 wrd = (insn >> 12) & 0xf;
2325 rd0 = (insn >> 16) & 0xf;
2326 rd1 = (insn >> 0) & 0xf;
2327 gen_op_iwmmxt_movq_M0_wRn(rd0);
2328 switch ((insn >> 22) & 3) {
2329 case 0:
2330 if (insn & (1 << 21))
2331 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2332 else
2333 gen_op_iwmmxt_minub_M0_wRn(rd1);
2334 break;
2335 case 1:
2336 if (insn & (1 << 21))
2337 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2338 else
2339 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2340 break;
2341 case 2:
2342 if (insn & (1 << 21))
2343 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2344 else
2345 gen_op_iwmmxt_minul_M0_wRn(rd1);
2346 break;
2347 case 3:
2348 return 1;
2350 gen_op_iwmmxt_movq_wRn_M0(wrd);
2351 gen_op_iwmmxt_set_mup();
2352 break;
2353 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2354 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2355 wrd = (insn >> 12) & 0xf;
2356 rd0 = (insn >> 16) & 0xf;
2357 rd1 = (insn >> 0) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0);
2359 switch ((insn >> 22) & 3) {
2360 case 0:
2361 if (insn & (1 << 21))
2362 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2363 else
2364 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2365 break;
2366 case 1:
2367 if (insn & (1 << 21))
2368 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2369 else
2370 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2371 break;
2372 case 2:
2373 if (insn & (1 << 21))
2374 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2375 else
2376 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2377 break;
2378 case 3:
2379 return 1;
2381 gen_op_iwmmxt_movq_wRn_M0(wrd);
2382 gen_op_iwmmxt_set_mup();
2383 break;
2384 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2385 case 0x402: case 0x502: case 0x602: case 0x702:
2386 wrd = (insn >> 12) & 0xf;
2387 rd0 = (insn >> 16) & 0xf;
2388 rd1 = (insn >> 0) & 0xf;
2389 gen_op_iwmmxt_movq_M0_wRn(rd0);
2390 tmp = tcg_const_i32((insn >> 20) & 3);
2391 iwmmxt_load_reg(cpu_V1, rd1);
2392 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2393 tcg_temp_free_i32(tmp);
2394 gen_op_iwmmxt_movq_wRn_M0(wrd);
2395 gen_op_iwmmxt_set_mup();
2396 break;
2397 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2398 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2399 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2400 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2401 wrd = (insn >> 12) & 0xf;
2402 rd0 = (insn >> 16) & 0xf;
2403 rd1 = (insn >> 0) & 0xf;
2404 gen_op_iwmmxt_movq_M0_wRn(rd0);
2405 switch ((insn >> 20) & 0xf) {
2406 case 0x0:
2407 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2408 break;
2409 case 0x1:
2410 gen_op_iwmmxt_subub_M0_wRn(rd1);
2411 break;
2412 case 0x3:
2413 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2414 break;
2415 case 0x4:
2416 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2417 break;
2418 case 0x5:
2419 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2420 break;
2421 case 0x7:
2422 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2423 break;
2424 case 0x8:
2425 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2426 break;
2427 case 0x9:
2428 gen_op_iwmmxt_subul_M0_wRn(rd1);
2429 break;
2430 case 0xb:
2431 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2432 break;
2433 default:
2434 return 1;
2436 gen_op_iwmmxt_movq_wRn_M0(wrd);
2437 gen_op_iwmmxt_set_mup();
2438 gen_op_iwmmxt_set_cup();
2439 break;
2440 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2441 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2442 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2443 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2444 wrd = (insn >> 12) & 0xf;
2445 rd0 = (insn >> 16) & 0xf;
2446 gen_op_iwmmxt_movq_M0_wRn(rd0);
2447 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2448 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2449 tcg_temp_free_i32(tmp);
2450 gen_op_iwmmxt_movq_wRn_M0(wrd);
2451 gen_op_iwmmxt_set_mup();
2452 gen_op_iwmmxt_set_cup();
2453 break;
2454 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2455 case 0x418: case 0x518: case 0x618: case 0x718:
2456 case 0x818: case 0x918: case 0xa18: case 0xb18:
2457 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2458 wrd = (insn >> 12) & 0xf;
2459 rd0 = (insn >> 16) & 0xf;
2460 rd1 = (insn >> 0) & 0xf;
2461 gen_op_iwmmxt_movq_M0_wRn(rd0);
2462 switch ((insn >> 20) & 0xf) {
2463 case 0x0:
2464 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2465 break;
2466 case 0x1:
2467 gen_op_iwmmxt_addub_M0_wRn(rd1);
2468 break;
2469 case 0x3:
2470 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2471 break;
2472 case 0x4:
2473 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2474 break;
2475 case 0x5:
2476 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2477 break;
2478 case 0x7:
2479 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2480 break;
2481 case 0x8:
2482 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2483 break;
2484 case 0x9:
2485 gen_op_iwmmxt_addul_M0_wRn(rd1);
2486 break;
2487 case 0xb:
2488 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2489 break;
2490 default:
2491 return 1;
2493 gen_op_iwmmxt_movq_wRn_M0(wrd);
2494 gen_op_iwmmxt_set_mup();
2495 gen_op_iwmmxt_set_cup();
2496 break;
2497 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2498 case 0x408: case 0x508: case 0x608: case 0x708:
2499 case 0x808: case 0x908: case 0xa08: case 0xb08:
2500 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2501 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2502 return 1;
2503 wrd = (insn >> 12) & 0xf;
2504 rd0 = (insn >> 16) & 0xf;
2505 rd1 = (insn >> 0) & 0xf;
2506 gen_op_iwmmxt_movq_M0_wRn(rd0);
2507 switch ((insn >> 22) & 3) {
2508 case 1:
2509 if (insn & (1 << 21))
2510 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2511 else
2512 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2513 break;
2514 case 2:
2515 if (insn & (1 << 21))
2516 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2517 else
2518 gen_op_iwmmxt_packul_M0_wRn(rd1);
2519 break;
2520 case 3:
2521 if (insn & (1 << 21))
2522 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2523 else
2524 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2525 break;
2527 gen_op_iwmmxt_movq_wRn_M0(wrd);
2528 gen_op_iwmmxt_set_mup();
2529 gen_op_iwmmxt_set_cup();
2530 break;
2531 case 0x201: case 0x203: case 0x205: case 0x207:
2532 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2533 case 0x211: case 0x213: case 0x215: case 0x217:
2534 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2535 wrd = (insn >> 5) & 0xf;
2536 rd0 = (insn >> 12) & 0xf;
2537 rd1 = (insn >> 0) & 0xf;
2538 if (rd0 == 0xf || rd1 == 0xf)
2539 return 1;
2540 gen_op_iwmmxt_movq_M0_wRn(wrd);
2541 tmp = load_reg(s, rd0);
2542 tmp2 = load_reg(s, rd1);
2543 switch ((insn >> 16) & 0xf) {
2544 case 0x0: /* TMIA */
2545 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2546 break;
2547 case 0x8: /* TMIAPH */
2548 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2549 break;
2550 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2551 if (insn & (1 << 16))
2552 tcg_gen_shri_i32(tmp, tmp, 16);
2553 if (insn & (1 << 17))
2554 tcg_gen_shri_i32(tmp2, tmp2, 16);
2555 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2556 break;
2557 default:
2558 tcg_temp_free_i32(tmp2);
2559 tcg_temp_free_i32(tmp);
2560 return 1;
2562 tcg_temp_free_i32(tmp2);
2563 tcg_temp_free_i32(tmp);
2564 gen_op_iwmmxt_movq_wRn_M0(wrd);
2565 gen_op_iwmmxt_set_mup();
2566 break;
2567 default:
2568 return 1;
2571 return 0;
2574 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2575 (ie. an undefined instruction). */
2576 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2578 int acc, rd0, rd1, rdhi, rdlo;
2579 TCGv_i32 tmp, tmp2;
2581 if ((insn & 0x0ff00f10) == 0x0e200010) {
2582 /* Multiply with Internal Accumulate Format */
2583 rd0 = (insn >> 12) & 0xf;
2584 rd1 = insn & 0xf;
2585 acc = (insn >> 5) & 7;
2587 if (acc != 0)
2588 return 1;
2590 tmp = load_reg(s, rd0);
2591 tmp2 = load_reg(s, rd1);
2592 switch ((insn >> 16) & 0xf) {
2593 case 0x0: /* MIA */
2594 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2595 break;
2596 case 0x8: /* MIAPH */
2597 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2598 break;
2599 case 0xc: /* MIABB */
2600 case 0xd: /* MIABT */
2601 case 0xe: /* MIATB */
2602 case 0xf: /* MIATT */
2603 if (insn & (1 << 16))
2604 tcg_gen_shri_i32(tmp, tmp, 16);
2605 if (insn & (1 << 17))
2606 tcg_gen_shri_i32(tmp2, tmp2, 16);
2607 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2608 break;
2609 default:
2610 return 1;
2612 tcg_temp_free_i32(tmp2);
2613 tcg_temp_free_i32(tmp);
2615 gen_op_iwmmxt_movq_wRn_M0(acc);
2616 return 0;
2619 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2620 /* Internal Accumulator Access Format */
2621 rdhi = (insn >> 16) & 0xf;
2622 rdlo = (insn >> 12) & 0xf;
2623 acc = insn & 7;
2625 if (acc != 0)
2626 return 1;
2628 if (insn & ARM_CP_RW_BIT) { /* MRA */
2629 iwmmxt_load_reg(cpu_V0, acc);
2630 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2631 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2632 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2633 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2634 } else { /* MAR */
2635 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2636 iwmmxt_store_reg(cpu_V0, acc);
2638 return 0;
2641 return 1;
2644 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2645 #define VFP_SREG(insn, bigbit, smallbit) \
2646 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2647 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2648 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2649 reg = (((insn) >> (bigbit)) & 0x0f) \
2650 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2651 } else { \
2652 if (insn & (1 << (smallbit))) \
2653 return 1; \
2654 reg = ((insn) >> (bigbit)) & 0x0f; \
2655 }} while (0)
2657 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2658 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2659 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2660 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2661 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2662 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2664 /* Move between integer and VFP cores. */
2665 static TCGv_i32 gen_vfp_mrs(void)
2667 TCGv_i32 tmp = tcg_temp_new_i32();
2668 tcg_gen_mov_i32(tmp, cpu_F0s);
2669 return tmp;
2672 static void gen_vfp_msr(TCGv_i32 tmp)
2674 tcg_gen_mov_i32(cpu_F0s, tmp);
2675 tcg_temp_free_i32(tmp);
2678 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2680 TCGv_i32 tmp = tcg_temp_new_i32();
2681 if (shift)
2682 tcg_gen_shri_i32(var, var, shift);
2683 tcg_gen_ext8u_i32(var, var);
2684 tcg_gen_shli_i32(tmp, var, 8);
2685 tcg_gen_or_i32(var, var, tmp);
2686 tcg_gen_shli_i32(tmp, var, 16);
2687 tcg_gen_or_i32(var, var, tmp);
2688 tcg_temp_free_i32(tmp);
2691 static void gen_neon_dup_low16(TCGv_i32 var)
2693 TCGv_i32 tmp = tcg_temp_new_i32();
2694 tcg_gen_ext16u_i32(var, var);
2695 tcg_gen_shli_i32(tmp, var, 16);
2696 tcg_gen_or_i32(var, var, tmp);
2697 tcg_temp_free_i32(tmp);
2700 static void gen_neon_dup_high16(TCGv_i32 var)
2702 TCGv_i32 tmp = tcg_temp_new_i32();
2703 tcg_gen_andi_i32(var, var, 0xffff0000);
2704 tcg_gen_shri_i32(tmp, var, 16);
2705 tcg_gen_or_i32(var, var, tmp);
2706 tcg_temp_free_i32(tmp);
2709 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2711 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2712 TCGv_i32 tmp = tcg_temp_new_i32();
2713 switch (size) {
2714 case 0:
2715 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
2716 gen_neon_dup_u8(tmp, 0);
2717 break;
2718 case 1:
2719 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
2720 gen_neon_dup_low16(tmp);
2721 break;
2722 case 2:
2723 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
2724 break;
2725 default: /* Avoid compiler warnings. */
2726 abort();
2728 return tmp;
2731 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2732 uint32_t dp)
2734 uint32_t cc = extract32(insn, 20, 2);
2736 if (dp) {
2737 TCGv_i64 frn, frm, dest;
2738 TCGv_i64 tmp, zero, zf, nf, vf;
2740 zero = tcg_const_i64(0);
2742 frn = tcg_temp_new_i64();
2743 frm = tcg_temp_new_i64();
2744 dest = tcg_temp_new_i64();
2746 zf = tcg_temp_new_i64();
2747 nf = tcg_temp_new_i64();
2748 vf = tcg_temp_new_i64();
2750 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2751 tcg_gen_ext_i32_i64(nf, cpu_NF);
2752 tcg_gen_ext_i32_i64(vf, cpu_VF);
2754 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2755 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2756 switch (cc) {
2757 case 0: /* eq: Z */
2758 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2759 frn, frm);
2760 break;
2761 case 1: /* vs: V */
2762 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2763 frn, frm);
2764 break;
2765 case 2: /* ge: N == V -> N ^ V == 0 */
2766 tmp = tcg_temp_new_i64();
2767 tcg_gen_xor_i64(tmp, vf, nf);
2768 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2769 frn, frm);
2770 tcg_temp_free_i64(tmp);
2771 break;
2772 case 3: /* gt: !Z && N == V */
2773 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2774 frn, frm);
2775 tmp = tcg_temp_new_i64();
2776 tcg_gen_xor_i64(tmp, vf, nf);
2777 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2778 dest, frm);
2779 tcg_temp_free_i64(tmp);
2780 break;
2782 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2783 tcg_temp_free_i64(frn);
2784 tcg_temp_free_i64(frm);
2785 tcg_temp_free_i64(dest);
2787 tcg_temp_free_i64(zf);
2788 tcg_temp_free_i64(nf);
2789 tcg_temp_free_i64(vf);
2791 tcg_temp_free_i64(zero);
2792 } else {
2793 TCGv_i32 frn, frm, dest;
2794 TCGv_i32 tmp, zero;
2796 zero = tcg_const_i32(0);
2798 frn = tcg_temp_new_i32();
2799 frm = tcg_temp_new_i32();
2800 dest = tcg_temp_new_i32();
2801 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2802 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2803 switch (cc) {
2804 case 0: /* eq: Z */
2805 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2806 frn, frm);
2807 break;
2808 case 1: /* vs: V */
2809 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2810 frn, frm);
2811 break;
2812 case 2: /* ge: N == V -> N ^ V == 0 */
2813 tmp = tcg_temp_new_i32();
2814 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2815 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2816 frn, frm);
2817 tcg_temp_free_i32(tmp);
2818 break;
2819 case 3: /* gt: !Z && N == V */
2820 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2821 frn, frm);
2822 tmp = tcg_temp_new_i32();
2823 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2824 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2825 dest, frm);
2826 tcg_temp_free_i32(tmp);
2827 break;
2829 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2830 tcg_temp_free_i32(frn);
2831 tcg_temp_free_i32(frm);
2832 tcg_temp_free_i32(dest);
2834 tcg_temp_free_i32(zero);
2837 return 0;
2840 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2841 uint32_t rm, uint32_t dp)
2843 uint32_t vmin = extract32(insn, 6, 1);
2844 TCGv_ptr fpst = get_fpstatus_ptr(0);
2846 if (dp) {
2847 TCGv_i64 frn, frm, dest;
2849 frn = tcg_temp_new_i64();
2850 frm = tcg_temp_new_i64();
2851 dest = tcg_temp_new_i64();
2853 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2854 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2855 if (vmin) {
2856 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2857 } else {
2858 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2860 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2861 tcg_temp_free_i64(frn);
2862 tcg_temp_free_i64(frm);
2863 tcg_temp_free_i64(dest);
2864 } else {
2865 TCGv_i32 frn, frm, dest;
2867 frn = tcg_temp_new_i32();
2868 frm = tcg_temp_new_i32();
2869 dest = tcg_temp_new_i32();
2871 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2872 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2873 if (vmin) {
2874 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2875 } else {
2876 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2878 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2879 tcg_temp_free_i32(frn);
2880 tcg_temp_free_i32(frm);
2881 tcg_temp_free_i32(dest);
2884 tcg_temp_free_ptr(fpst);
2885 return 0;
2888 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2889 int rounding)
2891 TCGv_ptr fpst = get_fpstatus_ptr(0);
2892 TCGv_i32 tcg_rmode;
2894 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2895 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2897 if (dp) {
2898 TCGv_i64 tcg_op;
2899 TCGv_i64 tcg_res;
2900 tcg_op = tcg_temp_new_i64();
2901 tcg_res = tcg_temp_new_i64();
2902 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2903 gen_helper_rintd(tcg_res, tcg_op, fpst);
2904 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2905 tcg_temp_free_i64(tcg_op);
2906 tcg_temp_free_i64(tcg_res);
2907 } else {
2908 TCGv_i32 tcg_op;
2909 TCGv_i32 tcg_res;
2910 tcg_op = tcg_temp_new_i32();
2911 tcg_res = tcg_temp_new_i32();
2912 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2913 gen_helper_rints(tcg_res, tcg_op, fpst);
2914 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2915 tcg_temp_free_i32(tcg_op);
2916 tcg_temp_free_i32(tcg_res);
2919 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2920 tcg_temp_free_i32(tcg_rmode);
2922 tcg_temp_free_ptr(fpst);
2923 return 0;
2926 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2927 int rounding)
2929 bool is_signed = extract32(insn, 7, 1);
2930 TCGv_ptr fpst = get_fpstatus_ptr(0);
2931 TCGv_i32 tcg_rmode, tcg_shift;
2933 tcg_shift = tcg_const_i32(0);
2935 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2936 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2938 if (dp) {
2939 TCGv_i64 tcg_double, tcg_res;
2940 TCGv_i32 tcg_tmp;
2941 /* Rd is encoded as a single precision register even when the source
2942 * is double precision.
2944 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2945 tcg_double = tcg_temp_new_i64();
2946 tcg_res = tcg_temp_new_i64();
2947 tcg_tmp = tcg_temp_new_i32();
2948 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2949 if (is_signed) {
2950 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2951 } else {
2952 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2954 tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2955 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2956 tcg_temp_free_i32(tcg_tmp);
2957 tcg_temp_free_i64(tcg_res);
2958 tcg_temp_free_i64(tcg_double);
2959 } else {
2960 TCGv_i32 tcg_single, tcg_res;
2961 tcg_single = tcg_temp_new_i32();
2962 tcg_res = tcg_temp_new_i32();
2963 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2964 if (is_signed) {
2965 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2966 } else {
2967 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2969 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2970 tcg_temp_free_i32(tcg_res);
2971 tcg_temp_free_i32(tcg_single);
2974 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2975 tcg_temp_free_i32(tcg_rmode);
2977 tcg_temp_free_i32(tcg_shift);
2979 tcg_temp_free_ptr(fpst);
2981 return 0;
2984 /* Table for converting the most common AArch32 encoding of
2985 * rounding mode to arm_fprounding order (which matches the
2986 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2988 static const uint8_t fp_decode_rm[] = {
2989 FPROUNDING_TIEAWAY,
2990 FPROUNDING_TIEEVEN,
2991 FPROUNDING_POSINF,
2992 FPROUNDING_NEGINF,
2995 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
2997 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2999 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3000 return 1;
3003 if (dp) {
3004 VFP_DREG_D(rd, insn);
3005 VFP_DREG_N(rn, insn);
3006 VFP_DREG_M(rm, insn);
3007 } else {
3008 rd = VFP_SREG_D(insn);
3009 rn = VFP_SREG_N(insn);
3010 rm = VFP_SREG_M(insn);
3013 if ((insn & 0x0f800e50) == 0x0e000a00) {
3014 return handle_vsel(insn, rd, rn, rm, dp);
3015 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3016 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3017 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3018 /* VRINTA, VRINTN, VRINTP, VRINTM */
3019 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3020 return handle_vrint(insn, rd, rm, dp, rounding);
3021 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3022 /* VCVTA, VCVTN, VCVTP, VCVTM */
3023 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3024 return handle_vcvt(insn, rd, rm, dp, rounding);
3026 return 1;
3029 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3030 (ie. an undefined instruction). */
3031 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3033 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3034 int dp, veclen;
3035 TCGv_i32 addr;
3036 TCGv_i32 tmp;
3037 TCGv_i32 tmp2;
3039 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3040 return 1;
3043 /* FIXME: this access check should not take precedence over UNDEF
3044 * for invalid encodings; we will generate incorrect syndrome information
3045 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3047 if (s->fp_excp_el) {
3048 gen_exception_insn(s, 4, EXCP_UDEF,
3049 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
3050 return 0;
3053 if (!s->vfp_enabled) {
3054 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3055 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3056 return 1;
3057 rn = (insn >> 16) & 0xf;
3058 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3059 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3060 return 1;
3064 if (extract32(insn, 28, 4) == 0xf) {
3065 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3066 * only used in v8 and above.
3068 return disas_vfp_v8_insn(s, insn);
3071 dp = ((insn & 0xf00) == 0xb00);
3072 switch ((insn >> 24) & 0xf) {
3073 case 0xe:
3074 if (insn & (1 << 4)) {
3075 /* single register transfer */
3076 rd = (insn >> 12) & 0xf;
3077 if (dp) {
3078 int size;
3079 int pass;
3081 VFP_DREG_N(rn, insn);
3082 if (insn & 0xf)
3083 return 1;
3084 if (insn & 0x00c00060
3085 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3086 return 1;
3089 pass = (insn >> 21) & 1;
3090 if (insn & (1 << 22)) {
3091 size = 0;
3092 offset = ((insn >> 5) & 3) * 8;
3093 } else if (insn & (1 << 5)) {
3094 size = 1;
3095 offset = (insn & (1 << 6)) ? 16 : 0;
3096 } else {
3097 size = 2;
3098 offset = 0;
3100 if (insn & ARM_CP_RW_BIT) {
3101 /* vfp->arm */
3102 tmp = neon_load_reg(rn, pass);
3103 switch (size) {
3104 case 0:
3105 if (offset)
3106 tcg_gen_shri_i32(tmp, tmp, offset);
3107 if (insn & (1 << 23))
3108 gen_uxtb(tmp);
3109 else
3110 gen_sxtb(tmp);
3111 break;
3112 case 1:
3113 if (insn & (1 << 23)) {
3114 if (offset) {
3115 tcg_gen_shri_i32(tmp, tmp, 16);
3116 } else {
3117 gen_uxth(tmp);
3119 } else {
3120 if (offset) {
3121 tcg_gen_sari_i32(tmp, tmp, 16);
3122 } else {
3123 gen_sxth(tmp);
3126 break;
3127 case 2:
3128 break;
3130 store_reg(s, rd, tmp);
3131 } else {
3132 /* arm->vfp */
3133 tmp = load_reg(s, rd);
3134 if (insn & (1 << 23)) {
3135 /* VDUP */
3136 if (size == 0) {
3137 gen_neon_dup_u8(tmp, 0);
3138 } else if (size == 1) {
3139 gen_neon_dup_low16(tmp);
3141 for (n = 0; n <= pass * 2; n++) {
3142 tmp2 = tcg_temp_new_i32();
3143 tcg_gen_mov_i32(tmp2, tmp);
3144 neon_store_reg(rn, n, tmp2);
3146 neon_store_reg(rn, n, tmp);
3147 } else {
3148 /* VMOV */
3149 switch (size) {
3150 case 0:
3151 tmp2 = neon_load_reg(rn, pass);
3152 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3153 tcg_temp_free_i32(tmp2);
3154 break;
3155 case 1:
3156 tmp2 = neon_load_reg(rn, pass);
3157 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3158 tcg_temp_free_i32(tmp2);
3159 break;
3160 case 2:
3161 break;
3163 neon_store_reg(rn, pass, tmp);
3166 } else { /* !dp */
3167 if ((insn & 0x6f) != 0x00)
3168 return 1;
3169 rn = VFP_SREG_N(insn);
3170 if (insn & ARM_CP_RW_BIT) {
3171 /* vfp->arm */
3172 if (insn & (1 << 21)) {
3173 /* system register */
3174 rn >>= 1;
3176 switch (rn) {
3177 case ARM_VFP_FPSID:
3178 /* VFP2 allows access to FSID from userspace.
3179 VFP3 restricts all id registers to privileged
3180 accesses. */
3181 if (IS_USER(s)
3182 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3183 return 1;
3185 tmp = load_cpu_field(vfp.xregs[rn]);
3186 break;
3187 case ARM_VFP_FPEXC:
3188 if (IS_USER(s))
3189 return 1;
3190 tmp = load_cpu_field(vfp.xregs[rn]);
3191 break;
3192 case ARM_VFP_FPINST:
3193 case ARM_VFP_FPINST2:
3194 /* Not present in VFP3. */
3195 if (IS_USER(s)
3196 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3197 return 1;
3199 tmp = load_cpu_field(vfp.xregs[rn]);
3200 break;
3201 case ARM_VFP_FPSCR:
3202 if (rd == 15) {
3203 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3204 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3205 } else {
3206 tmp = tcg_temp_new_i32();
3207 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3209 break;
3210 case ARM_VFP_MVFR2:
3211 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3212 return 1;
3214 /* fall through */
3215 case ARM_VFP_MVFR0:
3216 case ARM_VFP_MVFR1:
3217 if (IS_USER(s)
3218 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3219 return 1;
3221 tmp = load_cpu_field(vfp.xregs[rn]);
3222 break;
3223 default:
3224 return 1;
3226 } else {
3227 gen_mov_F0_vreg(0, rn);
3228 tmp = gen_vfp_mrs();
3230 if (rd == 15) {
3231 /* Set the 4 flag bits in the CPSR. */
3232 gen_set_nzcv(tmp);
3233 tcg_temp_free_i32(tmp);
3234 } else {
3235 store_reg(s, rd, tmp);
3237 } else {
3238 /* arm->vfp */
3239 if (insn & (1 << 21)) {
3240 rn >>= 1;
3241 /* system register */
3242 switch (rn) {
3243 case ARM_VFP_FPSID:
3244 case ARM_VFP_MVFR0:
3245 case ARM_VFP_MVFR1:
3246 /* Writes are ignored. */
3247 break;
3248 case ARM_VFP_FPSCR:
3249 tmp = load_reg(s, rd);
3250 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3251 tcg_temp_free_i32(tmp);
3252 gen_lookup_tb(s);
3253 break;
3254 case ARM_VFP_FPEXC:
3255 if (IS_USER(s))
3256 return 1;
3257 /* TODO: VFP subarchitecture support.
3258 * For now, keep the EN bit only */
3259 tmp = load_reg(s, rd);
3260 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3261 store_cpu_field(tmp, vfp.xregs[rn]);
3262 gen_lookup_tb(s);
3263 break;
3264 case ARM_VFP_FPINST:
3265 case ARM_VFP_FPINST2:
3266 if (IS_USER(s)) {
3267 return 1;
3269 tmp = load_reg(s, rd);
3270 store_cpu_field(tmp, vfp.xregs[rn]);
3271 break;
3272 default:
3273 return 1;
3275 } else {
3276 tmp = load_reg(s, rd);
3277 gen_vfp_msr(tmp);
3278 gen_mov_vreg_F0(0, rn);
3282 } else {
3283 /* data processing */
3284 /* The opcode is in bits 23, 21, 20 and 6. */
3285 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3286 if (dp) {
3287 if (op == 15) {
3288 /* rn is opcode */
3289 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3290 } else {
3291 /* rn is register number */
3292 VFP_DREG_N(rn, insn);
3295 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3296 ((rn & 0x1e) == 0x6))) {
3297 /* Integer or single/half precision destination. */
3298 rd = VFP_SREG_D(insn);
3299 } else {
3300 VFP_DREG_D(rd, insn);
3302 if (op == 15 &&
3303 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3304 ((rn & 0x1e) == 0x4))) {
3305 /* VCVT from int or half precision is always from S reg
3306 * regardless of dp bit. VCVT with immediate frac_bits
3307 * has same format as SREG_M.
3309 rm = VFP_SREG_M(insn);
3310 } else {
3311 VFP_DREG_M(rm, insn);
3313 } else {
3314 rn = VFP_SREG_N(insn);
3315 if (op == 15 && rn == 15) {
3316 /* Double precision destination. */
3317 VFP_DREG_D(rd, insn);
3318 } else {
3319 rd = VFP_SREG_D(insn);
3321 /* NB that we implicitly rely on the encoding for the frac_bits
3322 * in VCVT of fixed to float being the same as that of an SREG_M
3324 rm = VFP_SREG_M(insn);
3327 veclen = s->vec_len;
3328 if (op == 15 && rn > 3)
3329 veclen = 0;
3331 /* Shut up compiler warnings. */
3332 delta_m = 0;
3333 delta_d = 0;
3334 bank_mask = 0;
3336 if (veclen > 0) {
3337 if (dp)
3338 bank_mask = 0xc;
3339 else
3340 bank_mask = 0x18;
3342 /* Figure out what type of vector operation this is. */
3343 if ((rd & bank_mask) == 0) {
3344 /* scalar */
3345 veclen = 0;
3346 } else {
3347 if (dp)
3348 delta_d = (s->vec_stride >> 1) + 1;
3349 else
3350 delta_d = s->vec_stride + 1;
3352 if ((rm & bank_mask) == 0) {
3353 /* mixed scalar/vector */
3354 delta_m = 0;
3355 } else {
3356 /* vector */
3357 delta_m = delta_d;
3362 /* Load the initial operands. */
3363 if (op == 15) {
3364 switch (rn) {
3365 case 16:
3366 case 17:
3367 /* Integer source */
3368 gen_mov_F0_vreg(0, rm);
3369 break;
3370 case 8:
3371 case 9:
3372 /* Compare */
3373 gen_mov_F0_vreg(dp, rd);
3374 gen_mov_F1_vreg(dp, rm);
3375 break;
3376 case 10:
3377 case 11:
3378 /* Compare with zero */
3379 gen_mov_F0_vreg(dp, rd);
3380 gen_vfp_F1_ld0(dp);
3381 break;
3382 case 20:
3383 case 21:
3384 case 22:
3385 case 23:
3386 case 28:
3387 case 29:
3388 case 30:
3389 case 31:
3390 /* Source and destination the same. */
3391 gen_mov_F0_vreg(dp, rd);
3392 break;
3393 case 4:
3394 case 5:
3395 case 6:
3396 case 7:
3397 /* VCVTB, VCVTT: only present with the halfprec extension
3398 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3399 * (we choose to UNDEF)
3401 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3402 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3403 return 1;
3405 if (!extract32(rn, 1, 1)) {
3406 /* Half precision source. */
3407 gen_mov_F0_vreg(0, rm);
3408 break;
3410 /* Otherwise fall through */
3411 default:
3412 /* One source operand. */
3413 gen_mov_F0_vreg(dp, rm);
3414 break;
3416 } else {
3417 /* Two source operands. */
3418 gen_mov_F0_vreg(dp, rn);
3419 gen_mov_F1_vreg(dp, rm);
3422 for (;;) {
3423 /* Perform the calculation. */
3424 switch (op) {
3425 case 0: /* VMLA: fd + (fn * fm) */
3426 /* Note that order of inputs to the add matters for NaNs */
3427 gen_vfp_F1_mul(dp);
3428 gen_mov_F0_vreg(dp, rd);
3429 gen_vfp_add(dp);
3430 break;
3431 case 1: /* VMLS: fd + -(fn * fm) */
3432 gen_vfp_mul(dp);
3433 gen_vfp_F1_neg(dp);
3434 gen_mov_F0_vreg(dp, rd);
3435 gen_vfp_add(dp);
3436 break;
3437 case 2: /* VNMLS: -fd + (fn * fm) */
3438 /* Note that it isn't valid to replace (-A + B) with (B - A)
3439 * or similar plausible looking simplifications
3440 * because this will give wrong results for NaNs.
3442 gen_vfp_F1_mul(dp);
3443 gen_mov_F0_vreg(dp, rd);
3444 gen_vfp_neg(dp);
3445 gen_vfp_add(dp);
3446 break;
3447 case 3: /* VNMLA: -fd + -(fn * fm) */
3448 gen_vfp_mul(dp);
3449 gen_vfp_F1_neg(dp);
3450 gen_mov_F0_vreg(dp, rd);
3451 gen_vfp_neg(dp);
3452 gen_vfp_add(dp);
3453 break;
3454 case 4: /* mul: fn * fm */
3455 gen_vfp_mul(dp);
3456 break;
3457 case 5: /* nmul: -(fn * fm) */
3458 gen_vfp_mul(dp);
3459 gen_vfp_neg(dp);
3460 break;
3461 case 6: /* add: fn + fm */
3462 gen_vfp_add(dp);
3463 break;
3464 case 7: /* sub: fn - fm */
3465 gen_vfp_sub(dp);
3466 break;
3467 case 8: /* div: fn / fm */
3468 gen_vfp_div(dp);
3469 break;
3470 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3471 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3472 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3473 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3474 /* These are fused multiply-add, and must be done as one
3475 * floating point operation with no rounding between the
3476 * multiplication and addition steps.
3477 * NB that doing the negations here as separate steps is
3478 * correct : an input NaN should come out with its sign bit
3479 * flipped if it is a negated-input.
3481 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3482 return 1;
3484 if (dp) {
3485 TCGv_ptr fpst;
3486 TCGv_i64 frd;
3487 if (op & 1) {
3488 /* VFNMS, VFMS */
3489 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3491 frd = tcg_temp_new_i64();
3492 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3493 if (op & 2) {
3494 /* VFNMA, VFNMS */
3495 gen_helper_vfp_negd(frd, frd);
3497 fpst = get_fpstatus_ptr(0);
3498 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3499 cpu_F1d, frd, fpst);
3500 tcg_temp_free_ptr(fpst);
3501 tcg_temp_free_i64(frd);
3502 } else {
3503 TCGv_ptr fpst;
3504 TCGv_i32 frd;
3505 if (op & 1) {
3506 /* VFNMS, VFMS */
3507 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3509 frd = tcg_temp_new_i32();
3510 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3511 if (op & 2) {
3512 gen_helper_vfp_negs(frd, frd);
3514 fpst = get_fpstatus_ptr(0);
3515 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3516 cpu_F1s, frd, fpst);
3517 tcg_temp_free_ptr(fpst);
3518 tcg_temp_free_i32(frd);
3520 break;
3521 case 14: /* fconst */
3522 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3523 return 1;
3526 n = (insn << 12) & 0x80000000;
3527 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3528 if (dp) {
3529 if (i & 0x40)
3530 i |= 0x3f80;
3531 else
3532 i |= 0x4000;
3533 n |= i << 16;
3534 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3535 } else {
3536 if (i & 0x40)
3537 i |= 0x780;
3538 else
3539 i |= 0x800;
3540 n |= i << 19;
3541 tcg_gen_movi_i32(cpu_F0s, n);
3543 break;
3544 case 15: /* extension space */
3545 switch (rn) {
3546 case 0: /* cpy */
3547 /* no-op */
3548 break;
3549 case 1: /* abs */
3550 gen_vfp_abs(dp);
3551 break;
3552 case 2: /* neg */
3553 gen_vfp_neg(dp);
3554 break;
3555 case 3: /* sqrt */
3556 gen_vfp_sqrt(dp);
3557 break;
3558 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3559 tmp = gen_vfp_mrs();
3560 tcg_gen_ext16u_i32(tmp, tmp);
3561 if (dp) {
3562 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3563 cpu_env);
3564 } else {
3565 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3566 cpu_env);
3568 tcg_temp_free_i32(tmp);
3569 break;
3570 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3571 tmp = gen_vfp_mrs();
3572 tcg_gen_shri_i32(tmp, tmp, 16);
3573 if (dp) {
3574 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3575 cpu_env);
3576 } else {
3577 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3578 cpu_env);
3580 tcg_temp_free_i32(tmp);
3581 break;
3582 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3583 tmp = tcg_temp_new_i32();
3584 if (dp) {
3585 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3586 cpu_env);
3587 } else {
3588 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3589 cpu_env);
3591 gen_mov_F0_vreg(0, rd);
3592 tmp2 = gen_vfp_mrs();
3593 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3594 tcg_gen_or_i32(tmp, tmp, tmp2);
3595 tcg_temp_free_i32(tmp2);
3596 gen_vfp_msr(tmp);
3597 break;
3598 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3599 tmp = tcg_temp_new_i32();
3600 if (dp) {
3601 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3602 cpu_env);
3603 } else {
3604 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3605 cpu_env);
3607 tcg_gen_shli_i32(tmp, tmp, 16);
3608 gen_mov_F0_vreg(0, rd);
3609 tmp2 = gen_vfp_mrs();
3610 tcg_gen_ext16u_i32(tmp2, tmp2);
3611 tcg_gen_or_i32(tmp, tmp, tmp2);
3612 tcg_temp_free_i32(tmp2);
3613 gen_vfp_msr(tmp);
3614 break;
3615 case 8: /* cmp */
3616 gen_vfp_cmp(dp);
3617 break;
3618 case 9: /* cmpe */
3619 gen_vfp_cmpe(dp);
3620 break;
3621 case 10: /* cmpz */
3622 gen_vfp_cmp(dp);
3623 break;
3624 case 11: /* cmpez */
3625 gen_vfp_F1_ld0(dp);
3626 gen_vfp_cmpe(dp);
3627 break;
3628 case 12: /* vrintr */
3630 TCGv_ptr fpst = get_fpstatus_ptr(0);
3631 if (dp) {
3632 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3633 } else {
3634 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3636 tcg_temp_free_ptr(fpst);
3637 break;
3639 case 13: /* vrintz */
3641 TCGv_ptr fpst = get_fpstatus_ptr(0);
3642 TCGv_i32 tcg_rmode;
3643 tcg_rmode = tcg_const_i32(float_round_to_zero);
3644 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3645 if (dp) {
3646 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3647 } else {
3648 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3650 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3651 tcg_temp_free_i32(tcg_rmode);
3652 tcg_temp_free_ptr(fpst);
3653 break;
3655 case 14: /* vrintx */
3657 TCGv_ptr fpst = get_fpstatus_ptr(0);
3658 if (dp) {
3659 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3660 } else {
3661 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3663 tcg_temp_free_ptr(fpst);
3664 break;
3666 case 15: /* single<->double conversion */
3667 if (dp)
3668 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3669 else
3670 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3671 break;
3672 case 16: /* fuito */
3673 gen_vfp_uito(dp, 0);
3674 break;
3675 case 17: /* fsito */
3676 gen_vfp_sito(dp, 0);
3677 break;
3678 case 20: /* fshto */
3679 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3680 return 1;
3682 gen_vfp_shto(dp, 16 - rm, 0);
3683 break;
3684 case 21: /* fslto */
3685 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3686 return 1;
3688 gen_vfp_slto(dp, 32 - rm, 0);
3689 break;
3690 case 22: /* fuhto */
3691 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3692 return 1;
3694 gen_vfp_uhto(dp, 16 - rm, 0);
3695 break;
3696 case 23: /* fulto */
3697 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3698 return 1;
3700 gen_vfp_ulto(dp, 32 - rm, 0);
3701 break;
3702 case 24: /* ftoui */
3703 gen_vfp_toui(dp, 0);
3704 break;
3705 case 25: /* ftouiz */
3706 gen_vfp_touiz(dp, 0);
3707 break;
3708 case 26: /* ftosi */
3709 gen_vfp_tosi(dp, 0);
3710 break;
3711 case 27: /* ftosiz */
3712 gen_vfp_tosiz(dp, 0);
3713 break;
3714 case 28: /* ftosh */
3715 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3716 return 1;
3718 gen_vfp_tosh(dp, 16 - rm, 0);
3719 break;
3720 case 29: /* ftosl */
3721 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3722 return 1;
3724 gen_vfp_tosl(dp, 32 - rm, 0);
3725 break;
3726 case 30: /* ftouh */
3727 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3728 return 1;
3730 gen_vfp_touh(dp, 16 - rm, 0);
3731 break;
3732 case 31: /* ftoul */
3733 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3734 return 1;
3736 gen_vfp_toul(dp, 32 - rm, 0);
3737 break;
3738 default: /* undefined */
3739 return 1;
3741 break;
3742 default: /* undefined */
3743 return 1;
3746 /* Write back the result. */
3747 if (op == 15 && (rn >= 8 && rn <= 11)) {
3748 /* Comparison, do nothing. */
3749 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3750 (rn & 0x1e) == 0x6)) {
3751 /* VCVT double to int: always integer result.
3752 * VCVT double to half precision is always a single
3753 * precision result.
3755 gen_mov_vreg_F0(0, rd);
3756 } else if (op == 15 && rn == 15) {
3757 /* conversion */
3758 gen_mov_vreg_F0(!dp, rd);
3759 } else {
3760 gen_mov_vreg_F0(dp, rd);
3763 /* break out of the loop if we have finished */
3764 if (veclen == 0)
3765 break;
3767 if (op == 15 && delta_m == 0) {
3768 /* single source one-many */
3769 while (veclen--) {
3770 rd = ((rd + delta_d) & (bank_mask - 1))
3771 | (rd & bank_mask);
3772 gen_mov_vreg_F0(dp, rd);
3774 break;
3776 /* Setup the next operands. */
3777 veclen--;
3778 rd = ((rd + delta_d) & (bank_mask - 1))
3779 | (rd & bank_mask);
3781 if (op == 15) {
3782 /* One source operand. */
3783 rm = ((rm + delta_m) & (bank_mask - 1))
3784 | (rm & bank_mask);
3785 gen_mov_F0_vreg(dp, rm);
3786 } else {
3787 /* Two source operands. */
3788 rn = ((rn + delta_d) & (bank_mask - 1))
3789 | (rn & bank_mask);
3790 gen_mov_F0_vreg(dp, rn);
3791 if (delta_m) {
3792 rm = ((rm + delta_m) & (bank_mask - 1))
3793 | (rm & bank_mask);
3794 gen_mov_F1_vreg(dp, rm);
3799 break;
3800 case 0xc:
3801 case 0xd:
3802 if ((insn & 0x03e00000) == 0x00400000) {
3803 /* two-register transfer */
3804 rn = (insn >> 16) & 0xf;
3805 rd = (insn >> 12) & 0xf;
3806 if (dp) {
3807 VFP_DREG_M(rm, insn);
3808 } else {
3809 rm = VFP_SREG_M(insn);
3812 if (insn & ARM_CP_RW_BIT) {
3813 /* vfp->arm */
3814 if (dp) {
3815 gen_mov_F0_vreg(0, rm * 2);
3816 tmp = gen_vfp_mrs();
3817 store_reg(s, rd, tmp);
3818 gen_mov_F0_vreg(0, rm * 2 + 1);
3819 tmp = gen_vfp_mrs();
3820 store_reg(s, rn, tmp);
3821 } else {
3822 gen_mov_F0_vreg(0, rm);
3823 tmp = gen_vfp_mrs();
3824 store_reg(s, rd, tmp);
3825 gen_mov_F0_vreg(0, rm + 1);
3826 tmp = gen_vfp_mrs();
3827 store_reg(s, rn, tmp);
3829 } else {
3830 /* arm->vfp */
3831 if (dp) {
3832 tmp = load_reg(s, rd);
3833 gen_vfp_msr(tmp);
3834 gen_mov_vreg_F0(0, rm * 2);
3835 tmp = load_reg(s, rn);
3836 gen_vfp_msr(tmp);
3837 gen_mov_vreg_F0(0, rm * 2 + 1);
3838 } else {
3839 tmp = load_reg(s, rd);
3840 gen_vfp_msr(tmp);
3841 gen_mov_vreg_F0(0, rm);
3842 tmp = load_reg(s, rn);
3843 gen_vfp_msr(tmp);
3844 gen_mov_vreg_F0(0, rm + 1);
3847 } else {
3848 /* Load/store */
3849 rn = (insn >> 16) & 0xf;
3850 if (dp)
3851 VFP_DREG_D(rd, insn);
3852 else
3853 rd = VFP_SREG_D(insn);
3854 if ((insn & 0x01200000) == 0x01000000) {
3855 /* Single load/store */
3856 offset = (insn & 0xff) << 2;
3857 if ((insn & (1 << 23)) == 0)
3858 offset = -offset;
3859 if (s->thumb && rn == 15) {
3860 /* This is actually UNPREDICTABLE */
3861 addr = tcg_temp_new_i32();
3862 tcg_gen_movi_i32(addr, s->pc & ~2);
3863 } else {
3864 addr = load_reg(s, rn);
3866 tcg_gen_addi_i32(addr, addr, offset);
3867 if (insn & (1 << 20)) {
3868 gen_vfp_ld(s, dp, addr);
3869 gen_mov_vreg_F0(dp, rd);
3870 } else {
3871 gen_mov_F0_vreg(dp, rd);
3872 gen_vfp_st(s, dp, addr);
3874 tcg_temp_free_i32(addr);
3875 } else {
3876 /* load/store multiple */
3877 int w = insn & (1 << 21);
3878 if (dp)
3879 n = (insn >> 1) & 0x7f;
3880 else
3881 n = insn & 0xff;
3883 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3884 /* P == U , W == 1 => UNDEF */
3885 return 1;
3887 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3888 /* UNPREDICTABLE cases for bad immediates: we choose to
3889 * UNDEF to avoid generating huge numbers of TCG ops
3891 return 1;
3893 if (rn == 15 && w) {
3894 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3895 return 1;
3898 if (s->thumb && rn == 15) {
3899 /* This is actually UNPREDICTABLE */
3900 addr = tcg_temp_new_i32();
3901 tcg_gen_movi_i32(addr, s->pc & ~2);
3902 } else {
3903 addr = load_reg(s, rn);
3905 if (insn & (1 << 24)) /* pre-decrement */
3906 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3908 if (dp)
3909 offset = 8;
3910 else
3911 offset = 4;
3912 for (i = 0; i < n; i++) {
3913 if (insn & ARM_CP_RW_BIT) {
3914 /* load */
3915 gen_vfp_ld(s, dp, addr);
3916 gen_mov_vreg_F0(dp, rd + i);
3917 } else {
3918 /* store */
3919 gen_mov_F0_vreg(dp, rd + i);
3920 gen_vfp_st(s, dp, addr);
3922 tcg_gen_addi_i32(addr, addr, offset);
3924 if (w) {
3925 /* writeback */
3926 if (insn & (1 << 24))
3927 offset = -offset * n;
3928 else if (dp && (insn & 1))
3929 offset = 4;
3930 else
3931 offset = 0;
3933 if (offset != 0)
3934 tcg_gen_addi_i32(addr, addr, offset);
3935 store_reg(s, rn, addr);
3936 } else {
3937 tcg_temp_free_i32(addr);
3941 break;
3942 default:
3943 /* Should never happen. */
3944 return 1;
3946 return 0;
3949 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3951 TranslationBlock *tb;
3953 tb = s->tb;
3954 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3955 tcg_gen_goto_tb(n);
3956 gen_set_pc_im(s, dest);
3957 tcg_gen_exit_tb((uintptr_t)tb + n);
3958 } else {
3959 gen_set_pc_im(s, dest);
3960 tcg_gen_exit_tb(0);
3964 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3966 if (unlikely(s->singlestep_enabled || s->ss_active)) {
3967 /* An indirect jump so that we still trigger the debug exception. */
3968 if (s->thumb)
3969 dest |= 1;
3970 gen_bx_im(s, dest);
3971 } else {
3972 gen_goto_tb(s, 0, dest);
3973 s->is_jmp = DISAS_TB_JUMP;
3977 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3979 if (x)
3980 tcg_gen_sari_i32(t0, t0, 16);
3981 else
3982 gen_sxth(t0);
3983 if (y)
3984 tcg_gen_sari_i32(t1, t1, 16);
3985 else
3986 gen_sxth(t1);
3987 tcg_gen_mul_i32(t0, t0, t1);
3990 /* Return the mask of PSR bits set by a MSR instruction. */
3991 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
3993 uint32_t mask;
3995 mask = 0;
3996 if (flags & (1 << 0))
3997 mask |= 0xff;
3998 if (flags & (1 << 1))
3999 mask |= 0xff00;
4000 if (flags & (1 << 2))
4001 mask |= 0xff0000;
4002 if (flags & (1 << 3))
4003 mask |= 0xff000000;
4005 /* Mask out undefined bits. */
4006 mask &= ~CPSR_RESERVED;
4007 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4008 mask &= ~CPSR_T;
4010 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4011 mask &= ~CPSR_Q; /* V5TE in reality*/
4013 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4014 mask &= ~(CPSR_E | CPSR_GE);
4016 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4017 mask &= ~CPSR_IT;
4019 /* Mask out execution state and reserved bits. */
4020 if (!spsr) {
4021 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4023 /* Mask out privileged bits. */
4024 if (IS_USER(s))
4025 mask &= CPSR_USER;
4026 return mask;
4029 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4030 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4032 TCGv_i32 tmp;
4033 if (spsr) {
4034 /* ??? This is also undefined in system mode. */
4035 if (IS_USER(s))
4036 return 1;
4038 tmp = load_cpu_field(spsr);
4039 tcg_gen_andi_i32(tmp, tmp, ~mask);
4040 tcg_gen_andi_i32(t0, t0, mask);
4041 tcg_gen_or_i32(tmp, tmp, t0);
4042 store_cpu_field(tmp, spsr);
4043 } else {
4044 gen_set_cpsr(t0, mask);
4046 tcg_temp_free_i32(t0);
4047 gen_lookup_tb(s);
4048 return 0;
4051 /* Returns nonzero if access to the PSR is not permitted. */
4052 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4054 TCGv_i32 tmp;
4055 tmp = tcg_temp_new_i32();
4056 tcg_gen_movi_i32(tmp, val);
4057 return gen_set_psr(s, mask, spsr, tmp);
4060 /* Generate an old-style exception return. Marks pc as dead. */
4061 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4063 TCGv_i32 tmp;
4064 store_reg(s, 15, pc);
4065 tmp = load_cpu_field(spsr);
4066 gen_set_cpsr(tmp, CPSR_ERET_MASK);
4067 tcg_temp_free_i32(tmp);
4068 s->is_jmp = DISAS_UPDATE;
4071 /* Generate a v6 exception return. Marks both values as dead. */
4072 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4074 gen_set_cpsr(cpsr, CPSR_ERET_MASK);
4075 tcg_temp_free_i32(cpsr);
4076 store_reg(s, 15, pc);
4077 s->is_jmp = DISAS_UPDATE;
4080 static void gen_nop_hint(DisasContext *s, int val)
4082 switch (val) {
4083 case 3: /* wfi */
4084 gen_set_pc_im(s, s->pc);
4085 s->is_jmp = DISAS_WFI;
4086 break;
4087 case 2: /* wfe */
4088 gen_set_pc_im(s, s->pc);
4089 s->is_jmp = DISAS_WFE;
4090 break;
4091 case 4: /* sev */
4092 case 5: /* sevl */
4093 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4094 default: /* nop */
4095 break;
4099 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4101 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4103 switch (size) {
4104 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4105 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4106 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4107 default: abort();
4111 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4113 switch (size) {
4114 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4115 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4116 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4117 default: return;
4121 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4122 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4123 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4124 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4125 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4127 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4128 switch ((size << 1) | u) { \
4129 case 0: \
4130 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4131 break; \
4132 case 1: \
4133 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4134 break; \
4135 case 2: \
4136 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4137 break; \
4138 case 3: \
4139 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4140 break; \
4141 case 4: \
4142 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4143 break; \
4144 case 5: \
4145 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4146 break; \
4147 default: return 1; \
4148 }} while (0)
4150 #define GEN_NEON_INTEGER_OP(name) do { \
4151 switch ((size << 1) | u) { \
4152 case 0: \
4153 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4154 break; \
4155 case 1: \
4156 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4157 break; \
4158 case 2: \
4159 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4160 break; \
4161 case 3: \
4162 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4163 break; \
4164 case 4: \
4165 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4166 break; \
4167 case 5: \
4168 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4169 break; \
4170 default: return 1; \
4171 }} while (0)
4173 static TCGv_i32 neon_load_scratch(int scratch)
4175 TCGv_i32 tmp = tcg_temp_new_i32();
4176 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4177 return tmp;
4180 static void neon_store_scratch(int scratch, TCGv_i32 var)
4182 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4183 tcg_temp_free_i32(var);
4186 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4188 TCGv_i32 tmp;
4189 if (size == 1) {
4190 tmp = neon_load_reg(reg & 7, reg >> 4);
4191 if (reg & 8) {
4192 gen_neon_dup_high16(tmp);
4193 } else {
4194 gen_neon_dup_low16(tmp);
4196 } else {
4197 tmp = neon_load_reg(reg & 15, reg >> 4);
4199 return tmp;
4202 static int gen_neon_unzip(int rd, int rm, int size, int q)
4204 TCGv_i32 tmp, tmp2;
4205 if (!q && size == 2) {
4206 return 1;
4208 tmp = tcg_const_i32(rd);
4209 tmp2 = tcg_const_i32(rm);
4210 if (q) {
4211 switch (size) {
4212 case 0:
4213 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4214 break;
4215 case 1:
4216 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4217 break;
4218 case 2:
4219 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4220 break;
4221 default:
4222 abort();
4224 } else {
4225 switch (size) {
4226 case 0:
4227 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4228 break;
4229 case 1:
4230 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4231 break;
4232 default:
4233 abort();
4236 tcg_temp_free_i32(tmp);
4237 tcg_temp_free_i32(tmp2);
4238 return 0;
4241 static int gen_neon_zip(int rd, int rm, int size, int q)
4243 TCGv_i32 tmp, tmp2;
4244 if (!q && size == 2) {
4245 return 1;
4247 tmp = tcg_const_i32(rd);
4248 tmp2 = tcg_const_i32(rm);
4249 if (q) {
4250 switch (size) {
4251 case 0:
4252 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4253 break;
4254 case 1:
4255 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4256 break;
4257 case 2:
4258 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4259 break;
4260 default:
4261 abort();
4263 } else {
4264 switch (size) {
4265 case 0:
4266 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4267 break;
4268 case 1:
4269 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4270 break;
4271 default:
4272 abort();
4275 tcg_temp_free_i32(tmp);
4276 tcg_temp_free_i32(tmp2);
4277 return 0;
4280 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4282 TCGv_i32 rd, tmp;
4284 rd = tcg_temp_new_i32();
4285 tmp = tcg_temp_new_i32();
4287 tcg_gen_shli_i32(rd, t0, 8);
4288 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4289 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4290 tcg_gen_or_i32(rd, rd, tmp);
4292 tcg_gen_shri_i32(t1, t1, 8);
4293 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4294 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4295 tcg_gen_or_i32(t1, t1, tmp);
4296 tcg_gen_mov_i32(t0, rd);
4298 tcg_temp_free_i32(tmp);
4299 tcg_temp_free_i32(rd);
4302 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4304 TCGv_i32 rd, tmp;
4306 rd = tcg_temp_new_i32();
4307 tmp = tcg_temp_new_i32();
4309 tcg_gen_shli_i32(rd, t0, 16);
4310 tcg_gen_andi_i32(tmp, t1, 0xffff);
4311 tcg_gen_or_i32(rd, rd, tmp);
4312 tcg_gen_shri_i32(t1, t1, 16);
4313 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4314 tcg_gen_or_i32(t1, t1, tmp);
4315 tcg_gen_mov_i32(t0, rd);
4317 tcg_temp_free_i32(tmp);
4318 tcg_temp_free_i32(rd);
4322 static struct {
4323 int nregs;
4324 int interleave;
4325 int spacing;
4326 } neon_ls_element_type[11] = {
4327 {4, 4, 1},
4328 {4, 4, 2},
4329 {4, 1, 1},
4330 {4, 2, 1},
4331 {3, 3, 1},
4332 {3, 3, 2},
4333 {3, 1, 1},
4334 {1, 1, 1},
4335 {2, 2, 1},
4336 {2, 2, 2},
4337 {2, 1, 1}
4340 /* Translate a NEON load/store element instruction. Return nonzero if the
4341 instruction is invalid. */
4342 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4344 int rd, rn, rm;
4345 int op;
4346 int nregs;
4347 int interleave;
4348 int spacing;
4349 int stride;
4350 int size;
4351 int reg;
4352 int pass;
4353 int load;
4354 int shift;
4355 int n;
4356 TCGv_i32 addr;
4357 TCGv_i32 tmp;
4358 TCGv_i32 tmp2;
4359 TCGv_i64 tmp64;
4361 /* FIXME: this access check should not take precedence over UNDEF
4362 * for invalid encodings; we will generate incorrect syndrome information
4363 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4365 if (s->fp_excp_el) {
4366 gen_exception_insn(s, 4, EXCP_UDEF,
4367 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
4368 return 0;
4371 if (!s->vfp_enabled)
4372 return 1;
4373 VFP_DREG_D(rd, insn);
4374 rn = (insn >> 16) & 0xf;
4375 rm = insn & 0xf;
4376 load = (insn & (1 << 21)) != 0;
4377 if ((insn & (1 << 23)) == 0) {
4378 /* Load store all elements. */
4379 op = (insn >> 8) & 0xf;
4380 size = (insn >> 6) & 3;
4381 if (op > 10)
4382 return 1;
4383 /* Catch UNDEF cases for bad values of align field */
4384 switch (op & 0xc) {
4385 case 4:
4386 if (((insn >> 5) & 1) == 1) {
4387 return 1;
4389 break;
4390 case 8:
4391 if (((insn >> 4) & 3) == 3) {
4392 return 1;
4394 break;
4395 default:
4396 break;
4398 nregs = neon_ls_element_type[op].nregs;
4399 interleave = neon_ls_element_type[op].interleave;
4400 spacing = neon_ls_element_type[op].spacing;
4401 if (size == 3 && (interleave | spacing) != 1)
4402 return 1;
4403 addr = tcg_temp_new_i32();
4404 load_reg_var(s, addr, rn);
4405 stride = (1 << size) * interleave;
4406 for (reg = 0; reg < nregs; reg++) {
4407 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4408 load_reg_var(s, addr, rn);
4409 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4410 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4411 load_reg_var(s, addr, rn);
4412 tcg_gen_addi_i32(addr, addr, 1 << size);
4414 if (size == 3) {
4415 tmp64 = tcg_temp_new_i64();
4416 if (load) {
4417 gen_aa32_ld64(tmp64, addr, get_mem_index(s));
4418 neon_store_reg64(tmp64, rd);
4419 } else {
4420 neon_load_reg64(tmp64, rd);
4421 gen_aa32_st64(tmp64, addr, get_mem_index(s));
4423 tcg_temp_free_i64(tmp64);
4424 tcg_gen_addi_i32(addr, addr, stride);
4425 } else {
4426 for (pass = 0; pass < 2; pass++) {
4427 if (size == 2) {
4428 if (load) {
4429 tmp = tcg_temp_new_i32();
4430 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4431 neon_store_reg(rd, pass, tmp);
4432 } else {
4433 tmp = neon_load_reg(rd, pass);
4434 gen_aa32_st32(tmp, addr, get_mem_index(s));
4435 tcg_temp_free_i32(tmp);
4437 tcg_gen_addi_i32(addr, addr, stride);
4438 } else if (size == 1) {
4439 if (load) {
4440 tmp = tcg_temp_new_i32();
4441 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4442 tcg_gen_addi_i32(addr, addr, stride);
4443 tmp2 = tcg_temp_new_i32();
4444 gen_aa32_ld16u(tmp2, addr, get_mem_index(s));
4445 tcg_gen_addi_i32(addr, addr, stride);
4446 tcg_gen_shli_i32(tmp2, tmp2, 16);
4447 tcg_gen_or_i32(tmp, tmp, tmp2);
4448 tcg_temp_free_i32(tmp2);
4449 neon_store_reg(rd, pass, tmp);
4450 } else {
4451 tmp = neon_load_reg(rd, pass);
4452 tmp2 = tcg_temp_new_i32();
4453 tcg_gen_shri_i32(tmp2, tmp, 16);
4454 gen_aa32_st16(tmp, addr, get_mem_index(s));
4455 tcg_temp_free_i32(tmp);
4456 tcg_gen_addi_i32(addr, addr, stride);
4457 gen_aa32_st16(tmp2, addr, get_mem_index(s));
4458 tcg_temp_free_i32(tmp2);
4459 tcg_gen_addi_i32(addr, addr, stride);
4461 } else /* size == 0 */ {
4462 if (load) {
4463 TCGV_UNUSED_I32(tmp2);
4464 for (n = 0; n < 4; n++) {
4465 tmp = tcg_temp_new_i32();
4466 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4467 tcg_gen_addi_i32(addr, addr, stride);
4468 if (n == 0) {
4469 tmp2 = tmp;
4470 } else {
4471 tcg_gen_shli_i32(tmp, tmp, n * 8);
4472 tcg_gen_or_i32(tmp2, tmp2, tmp);
4473 tcg_temp_free_i32(tmp);
4476 neon_store_reg(rd, pass, tmp2);
4477 } else {
4478 tmp2 = neon_load_reg(rd, pass);
4479 for (n = 0; n < 4; n++) {
4480 tmp = tcg_temp_new_i32();
4481 if (n == 0) {
4482 tcg_gen_mov_i32(tmp, tmp2);
4483 } else {
4484 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4486 gen_aa32_st8(tmp, addr, get_mem_index(s));
4487 tcg_temp_free_i32(tmp);
4488 tcg_gen_addi_i32(addr, addr, stride);
4490 tcg_temp_free_i32(tmp2);
4495 rd += spacing;
4497 tcg_temp_free_i32(addr);
4498 stride = nregs * 8;
4499 } else {
4500 size = (insn >> 10) & 3;
4501 if (size == 3) {
4502 /* Load single element to all lanes. */
4503 int a = (insn >> 4) & 1;
4504 if (!load) {
4505 return 1;
4507 size = (insn >> 6) & 3;
4508 nregs = ((insn >> 8) & 3) + 1;
4510 if (size == 3) {
4511 if (nregs != 4 || a == 0) {
4512 return 1;
4514 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4515 size = 2;
4517 if (nregs == 1 && a == 1 && size == 0) {
4518 return 1;
4520 if (nregs == 3 && a == 1) {
4521 return 1;
4523 addr = tcg_temp_new_i32();
4524 load_reg_var(s, addr, rn);
4525 if (nregs == 1) {
4526 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4527 tmp = gen_load_and_replicate(s, addr, size);
4528 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4529 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4530 if (insn & (1 << 5)) {
4531 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4532 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4534 tcg_temp_free_i32(tmp);
4535 } else {
4536 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4537 stride = (insn & (1 << 5)) ? 2 : 1;
4538 for (reg = 0; reg < nregs; reg++) {
4539 tmp = gen_load_and_replicate(s, addr, size);
4540 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4541 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4542 tcg_temp_free_i32(tmp);
4543 tcg_gen_addi_i32(addr, addr, 1 << size);
4544 rd += stride;
4547 tcg_temp_free_i32(addr);
4548 stride = (1 << size) * nregs;
4549 } else {
4550 /* Single element. */
4551 int idx = (insn >> 4) & 0xf;
4552 pass = (insn >> 7) & 1;
4553 switch (size) {
4554 case 0:
4555 shift = ((insn >> 5) & 3) * 8;
4556 stride = 1;
4557 break;
4558 case 1:
4559 shift = ((insn >> 6) & 1) * 16;
4560 stride = (insn & (1 << 5)) ? 2 : 1;
4561 break;
4562 case 2:
4563 shift = 0;
4564 stride = (insn & (1 << 6)) ? 2 : 1;
4565 break;
4566 default:
4567 abort();
4569 nregs = ((insn >> 8) & 3) + 1;
4570 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4571 switch (nregs) {
4572 case 1:
4573 if (((idx & (1 << size)) != 0) ||
4574 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4575 return 1;
4577 break;
4578 case 3:
4579 if ((idx & 1) != 0) {
4580 return 1;
4582 /* fall through */
4583 case 2:
4584 if (size == 2 && (idx & 2) != 0) {
4585 return 1;
4587 break;
4588 case 4:
4589 if ((size == 2) && ((idx & 3) == 3)) {
4590 return 1;
4592 break;
4593 default:
4594 abort();
4596 if ((rd + stride * (nregs - 1)) > 31) {
4597 /* Attempts to write off the end of the register file
4598 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4599 * the neon_load_reg() would write off the end of the array.
4601 return 1;
4603 addr = tcg_temp_new_i32();
4604 load_reg_var(s, addr, rn);
4605 for (reg = 0; reg < nregs; reg++) {
4606 if (load) {
4607 tmp = tcg_temp_new_i32();
4608 switch (size) {
4609 case 0:
4610 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4611 break;
4612 case 1:
4613 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4614 break;
4615 case 2:
4616 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4617 break;
4618 default: /* Avoid compiler warnings. */
4619 abort();
4621 if (size != 2) {
4622 tmp2 = neon_load_reg(rd, pass);
4623 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4624 shift, size ? 16 : 8);
4625 tcg_temp_free_i32(tmp2);
4627 neon_store_reg(rd, pass, tmp);
4628 } else { /* Store */
4629 tmp = neon_load_reg(rd, pass);
4630 if (shift)
4631 tcg_gen_shri_i32(tmp, tmp, shift);
4632 switch (size) {
4633 case 0:
4634 gen_aa32_st8(tmp, addr, get_mem_index(s));
4635 break;
4636 case 1:
4637 gen_aa32_st16(tmp, addr, get_mem_index(s));
4638 break;
4639 case 2:
4640 gen_aa32_st32(tmp, addr, get_mem_index(s));
4641 break;
4643 tcg_temp_free_i32(tmp);
4645 rd += stride;
4646 tcg_gen_addi_i32(addr, addr, 1 << size);
4648 tcg_temp_free_i32(addr);
4649 stride = nregs * (1 << size);
4652 if (rm != 15) {
4653 TCGv_i32 base;
4655 base = load_reg(s, rn);
4656 if (rm == 13) {
4657 tcg_gen_addi_i32(base, base, stride);
4658 } else {
4659 TCGv_i32 index;
4660 index = load_reg(s, rm);
4661 tcg_gen_add_i32(base, base, index);
4662 tcg_temp_free_i32(index);
4664 store_reg(s, rn, base);
4666 return 0;
4669 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4670 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4672 tcg_gen_and_i32(t, t, c);
4673 tcg_gen_andc_i32(f, f, c);
4674 tcg_gen_or_i32(dest, t, f);
4677 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4679 switch (size) {
4680 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4681 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4682 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4683 default: abort();
4687 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4689 switch (size) {
4690 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4691 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4692 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4693 default: abort();
4697 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4699 switch (size) {
4700 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4701 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4702 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4703 default: abort();
4707 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4709 switch (size) {
4710 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4711 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4712 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4713 default: abort();
4717 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4718 int q, int u)
4720 if (q) {
4721 if (u) {
4722 switch (size) {
4723 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4724 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4725 default: abort();
4727 } else {
4728 switch (size) {
4729 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4730 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4731 default: abort();
4734 } else {
4735 if (u) {
4736 switch (size) {
4737 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4738 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4739 default: abort();
4741 } else {
4742 switch (size) {
4743 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4744 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4745 default: abort();
4751 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4753 if (u) {
4754 switch (size) {
4755 case 0: gen_helper_neon_widen_u8(dest, src); break;
4756 case 1: gen_helper_neon_widen_u16(dest, src); break;
4757 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4758 default: abort();
4760 } else {
4761 switch (size) {
4762 case 0: gen_helper_neon_widen_s8(dest, src); break;
4763 case 1: gen_helper_neon_widen_s16(dest, src); break;
4764 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4765 default: abort();
4768 tcg_temp_free_i32(src);
4771 static inline void gen_neon_addl(int size)
4773 switch (size) {
4774 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4775 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4776 case 2: tcg_gen_add_i64(CPU_V001); break;
4777 default: abort();
4781 static inline void gen_neon_subl(int size)
4783 switch (size) {
4784 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4785 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4786 case 2: tcg_gen_sub_i64(CPU_V001); break;
4787 default: abort();
4791 static inline void gen_neon_negl(TCGv_i64 var, int size)
4793 switch (size) {
4794 case 0: gen_helper_neon_negl_u16(var, var); break;
4795 case 1: gen_helper_neon_negl_u32(var, var); break;
4796 case 2:
4797 tcg_gen_neg_i64(var, var);
4798 break;
4799 default: abort();
4803 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4805 switch (size) {
4806 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4807 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4808 default: abort();
4812 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4813 int size, int u)
4815 TCGv_i64 tmp;
4817 switch ((size << 1) | u) {
4818 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4819 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4820 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4821 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4822 case 4:
4823 tmp = gen_muls_i64_i32(a, b);
4824 tcg_gen_mov_i64(dest, tmp);
4825 tcg_temp_free_i64(tmp);
4826 break;
4827 case 5:
4828 tmp = gen_mulu_i64_i32(a, b);
4829 tcg_gen_mov_i64(dest, tmp);
4830 tcg_temp_free_i64(tmp);
4831 break;
4832 default: abort();
4835 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4836 Don't forget to clean them now. */
4837 if (size < 2) {
4838 tcg_temp_free_i32(a);
4839 tcg_temp_free_i32(b);
4843 static void gen_neon_narrow_op(int op, int u, int size,
4844 TCGv_i32 dest, TCGv_i64 src)
4846 if (op) {
4847 if (u) {
4848 gen_neon_unarrow_sats(size, dest, src);
4849 } else {
4850 gen_neon_narrow(size, dest, src);
4852 } else {
4853 if (u) {
4854 gen_neon_narrow_satu(size, dest, src);
4855 } else {
4856 gen_neon_narrow_sats(size, dest, src);
4861 /* Symbolic constants for op fields for Neon 3-register same-length.
4862 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4863 * table A7-9.
4865 #define NEON_3R_VHADD 0
4866 #define NEON_3R_VQADD 1
4867 #define NEON_3R_VRHADD 2
4868 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4869 #define NEON_3R_VHSUB 4
4870 #define NEON_3R_VQSUB 5
4871 #define NEON_3R_VCGT 6
4872 #define NEON_3R_VCGE 7
4873 #define NEON_3R_VSHL 8
4874 #define NEON_3R_VQSHL 9
4875 #define NEON_3R_VRSHL 10
4876 #define NEON_3R_VQRSHL 11
4877 #define NEON_3R_VMAX 12
4878 #define NEON_3R_VMIN 13
4879 #define NEON_3R_VABD 14
4880 #define NEON_3R_VABA 15
4881 #define NEON_3R_VADD_VSUB 16
4882 #define NEON_3R_VTST_VCEQ 17
4883 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4884 #define NEON_3R_VMUL 19
4885 #define NEON_3R_VPMAX 20
4886 #define NEON_3R_VPMIN 21
4887 #define NEON_3R_VQDMULH_VQRDMULH 22
4888 #define NEON_3R_VPADD 23
4889 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4890 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4891 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4892 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4893 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4894 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4895 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4896 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4898 static const uint8_t neon_3r_sizes[] = {
4899 [NEON_3R_VHADD] = 0x7,
4900 [NEON_3R_VQADD] = 0xf,
4901 [NEON_3R_VRHADD] = 0x7,
4902 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4903 [NEON_3R_VHSUB] = 0x7,
4904 [NEON_3R_VQSUB] = 0xf,
4905 [NEON_3R_VCGT] = 0x7,
4906 [NEON_3R_VCGE] = 0x7,
4907 [NEON_3R_VSHL] = 0xf,
4908 [NEON_3R_VQSHL] = 0xf,
4909 [NEON_3R_VRSHL] = 0xf,
4910 [NEON_3R_VQRSHL] = 0xf,
4911 [NEON_3R_VMAX] = 0x7,
4912 [NEON_3R_VMIN] = 0x7,
4913 [NEON_3R_VABD] = 0x7,
4914 [NEON_3R_VABA] = 0x7,
4915 [NEON_3R_VADD_VSUB] = 0xf,
4916 [NEON_3R_VTST_VCEQ] = 0x7,
4917 [NEON_3R_VML] = 0x7,
4918 [NEON_3R_VMUL] = 0x7,
4919 [NEON_3R_VPMAX] = 0x7,
4920 [NEON_3R_VPMIN] = 0x7,
4921 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4922 [NEON_3R_VPADD] = 0x7,
4923 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4924 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4925 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4926 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4927 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4928 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4929 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4930 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4933 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4934 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4935 * table A7-13.
4937 #define NEON_2RM_VREV64 0
4938 #define NEON_2RM_VREV32 1
4939 #define NEON_2RM_VREV16 2
4940 #define NEON_2RM_VPADDL 4
4941 #define NEON_2RM_VPADDL_U 5
4942 #define NEON_2RM_AESE 6 /* Includes AESD */
4943 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4944 #define NEON_2RM_VCLS 8
4945 #define NEON_2RM_VCLZ 9
4946 #define NEON_2RM_VCNT 10
4947 #define NEON_2RM_VMVN 11
4948 #define NEON_2RM_VPADAL 12
4949 #define NEON_2RM_VPADAL_U 13
4950 #define NEON_2RM_VQABS 14
4951 #define NEON_2RM_VQNEG 15
4952 #define NEON_2RM_VCGT0 16
4953 #define NEON_2RM_VCGE0 17
4954 #define NEON_2RM_VCEQ0 18
4955 #define NEON_2RM_VCLE0 19
4956 #define NEON_2RM_VCLT0 20
4957 #define NEON_2RM_SHA1H 21
4958 #define NEON_2RM_VABS 22
4959 #define NEON_2RM_VNEG 23
4960 #define NEON_2RM_VCGT0_F 24
4961 #define NEON_2RM_VCGE0_F 25
4962 #define NEON_2RM_VCEQ0_F 26
4963 #define NEON_2RM_VCLE0_F 27
4964 #define NEON_2RM_VCLT0_F 28
4965 #define NEON_2RM_VABS_F 30
4966 #define NEON_2RM_VNEG_F 31
4967 #define NEON_2RM_VSWP 32
4968 #define NEON_2RM_VTRN 33
4969 #define NEON_2RM_VUZP 34
4970 #define NEON_2RM_VZIP 35
4971 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4972 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4973 #define NEON_2RM_VSHLL 38
4974 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4975 #define NEON_2RM_VRINTN 40
4976 #define NEON_2RM_VRINTX 41
4977 #define NEON_2RM_VRINTA 42
4978 #define NEON_2RM_VRINTZ 43
4979 #define NEON_2RM_VCVT_F16_F32 44
4980 #define NEON_2RM_VRINTM 45
4981 #define NEON_2RM_VCVT_F32_F16 46
4982 #define NEON_2RM_VRINTP 47
4983 #define NEON_2RM_VCVTAU 48
4984 #define NEON_2RM_VCVTAS 49
4985 #define NEON_2RM_VCVTNU 50
4986 #define NEON_2RM_VCVTNS 51
4987 #define NEON_2RM_VCVTPU 52
4988 #define NEON_2RM_VCVTPS 53
4989 #define NEON_2RM_VCVTMU 54
4990 #define NEON_2RM_VCVTMS 55
4991 #define NEON_2RM_VRECPE 56
4992 #define NEON_2RM_VRSQRTE 57
4993 #define NEON_2RM_VRECPE_F 58
4994 #define NEON_2RM_VRSQRTE_F 59
4995 #define NEON_2RM_VCVT_FS 60
4996 #define NEON_2RM_VCVT_FU 61
4997 #define NEON_2RM_VCVT_SF 62
4998 #define NEON_2RM_VCVT_UF 63
5000 static int neon_2rm_is_float_op(int op)
5002 /* Return true if this neon 2reg-misc op is float-to-float */
5003 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5004 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5005 op == NEON_2RM_VRINTM ||
5006 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5007 op >= NEON_2RM_VRECPE_F);
5010 /* Each entry in this array has bit n set if the insn allows
5011 * size value n (otherwise it will UNDEF). Since unallocated
5012 * op values will have no bits set they always UNDEF.
5014 static const uint8_t neon_2rm_sizes[] = {
5015 [NEON_2RM_VREV64] = 0x7,
5016 [NEON_2RM_VREV32] = 0x3,
5017 [NEON_2RM_VREV16] = 0x1,
5018 [NEON_2RM_VPADDL] = 0x7,
5019 [NEON_2RM_VPADDL_U] = 0x7,
5020 [NEON_2RM_AESE] = 0x1,
5021 [NEON_2RM_AESMC] = 0x1,
5022 [NEON_2RM_VCLS] = 0x7,
5023 [NEON_2RM_VCLZ] = 0x7,
5024 [NEON_2RM_VCNT] = 0x1,
5025 [NEON_2RM_VMVN] = 0x1,
5026 [NEON_2RM_VPADAL] = 0x7,
5027 [NEON_2RM_VPADAL_U] = 0x7,
5028 [NEON_2RM_VQABS] = 0x7,
5029 [NEON_2RM_VQNEG] = 0x7,
5030 [NEON_2RM_VCGT0] = 0x7,
5031 [NEON_2RM_VCGE0] = 0x7,
5032 [NEON_2RM_VCEQ0] = 0x7,
5033 [NEON_2RM_VCLE0] = 0x7,
5034 [NEON_2RM_VCLT0] = 0x7,
5035 [NEON_2RM_SHA1H] = 0x4,
5036 [NEON_2RM_VABS] = 0x7,
5037 [NEON_2RM_VNEG] = 0x7,
5038 [NEON_2RM_VCGT0_F] = 0x4,
5039 [NEON_2RM_VCGE0_F] = 0x4,
5040 [NEON_2RM_VCEQ0_F] = 0x4,
5041 [NEON_2RM_VCLE0_F] = 0x4,
5042 [NEON_2RM_VCLT0_F] = 0x4,
5043 [NEON_2RM_VABS_F] = 0x4,
5044 [NEON_2RM_VNEG_F] = 0x4,
5045 [NEON_2RM_VSWP] = 0x1,
5046 [NEON_2RM_VTRN] = 0x7,
5047 [NEON_2RM_VUZP] = 0x7,
5048 [NEON_2RM_VZIP] = 0x7,
5049 [NEON_2RM_VMOVN] = 0x7,
5050 [NEON_2RM_VQMOVN] = 0x7,
5051 [NEON_2RM_VSHLL] = 0x7,
5052 [NEON_2RM_SHA1SU1] = 0x4,
5053 [NEON_2RM_VRINTN] = 0x4,
5054 [NEON_2RM_VRINTX] = 0x4,
5055 [NEON_2RM_VRINTA] = 0x4,
5056 [NEON_2RM_VRINTZ] = 0x4,
5057 [NEON_2RM_VCVT_F16_F32] = 0x2,
5058 [NEON_2RM_VRINTM] = 0x4,
5059 [NEON_2RM_VCVT_F32_F16] = 0x2,
5060 [NEON_2RM_VRINTP] = 0x4,
5061 [NEON_2RM_VCVTAU] = 0x4,
5062 [NEON_2RM_VCVTAS] = 0x4,
5063 [NEON_2RM_VCVTNU] = 0x4,
5064 [NEON_2RM_VCVTNS] = 0x4,
5065 [NEON_2RM_VCVTPU] = 0x4,
5066 [NEON_2RM_VCVTPS] = 0x4,
5067 [NEON_2RM_VCVTMU] = 0x4,
5068 [NEON_2RM_VCVTMS] = 0x4,
5069 [NEON_2RM_VRECPE] = 0x4,
5070 [NEON_2RM_VRSQRTE] = 0x4,
5071 [NEON_2RM_VRECPE_F] = 0x4,
5072 [NEON_2RM_VRSQRTE_F] = 0x4,
5073 [NEON_2RM_VCVT_FS] = 0x4,
5074 [NEON_2RM_VCVT_FU] = 0x4,
5075 [NEON_2RM_VCVT_SF] = 0x4,
5076 [NEON_2RM_VCVT_UF] = 0x4,
5079 /* Translate a NEON data processing instruction. Return nonzero if the
5080 instruction is invalid.
5081 We process data in a mixture of 32-bit and 64-bit chunks.
5082 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5084 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5086 int op;
5087 int q;
5088 int rd, rn, rm;
5089 int size;
5090 int shift;
5091 int pass;
5092 int count;
5093 int pairwise;
5094 int u;
5095 uint32_t imm, mask;
5096 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5097 TCGv_i64 tmp64;
5099 /* FIXME: this access check should not take precedence over UNDEF
5100 * for invalid encodings; we will generate incorrect syndrome information
5101 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5103 if (s->fp_excp_el) {
5104 gen_exception_insn(s, 4, EXCP_UDEF,
5105 syn_fp_access_trap(1, 0xe, s->thumb), s->fp_excp_el);
5106 return 0;
5109 if (!s->vfp_enabled)
5110 return 1;
5111 q = (insn & (1 << 6)) != 0;
5112 u = (insn >> 24) & 1;
5113 VFP_DREG_D(rd, insn);
5114 VFP_DREG_N(rn, insn);
5115 VFP_DREG_M(rm, insn);
5116 size = (insn >> 20) & 3;
5117 if ((insn & (1 << 23)) == 0) {
5118 /* Three register same length. */
5119 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5120 /* Catch invalid op and bad size combinations: UNDEF */
5121 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5122 return 1;
5124 /* All insns of this form UNDEF for either this condition or the
5125 * superset of cases "Q==1"; we catch the latter later.
5127 if (q && ((rd | rn | rm) & 1)) {
5128 return 1;
5131 * The SHA-1/SHA-256 3-register instructions require special treatment
5132 * here, as their size field is overloaded as an op type selector, and
5133 * they all consume their input in a single pass.
5135 if (op == NEON_3R_SHA) {
5136 if (!q) {
5137 return 1;
5139 if (!u) { /* SHA-1 */
5140 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5141 return 1;
5143 tmp = tcg_const_i32(rd);
5144 tmp2 = tcg_const_i32(rn);
5145 tmp3 = tcg_const_i32(rm);
5146 tmp4 = tcg_const_i32(size);
5147 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5148 tcg_temp_free_i32(tmp4);
5149 } else { /* SHA-256 */
5150 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5151 return 1;
5153 tmp = tcg_const_i32(rd);
5154 tmp2 = tcg_const_i32(rn);
5155 tmp3 = tcg_const_i32(rm);
5156 switch (size) {
5157 case 0:
5158 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5159 break;
5160 case 1:
5161 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5162 break;
5163 case 2:
5164 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5165 break;
5168 tcg_temp_free_i32(tmp);
5169 tcg_temp_free_i32(tmp2);
5170 tcg_temp_free_i32(tmp3);
5171 return 0;
5173 if (size == 3 && op != NEON_3R_LOGIC) {
5174 /* 64-bit element instructions. */
5175 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5176 neon_load_reg64(cpu_V0, rn + pass);
5177 neon_load_reg64(cpu_V1, rm + pass);
5178 switch (op) {
5179 case NEON_3R_VQADD:
5180 if (u) {
5181 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5182 cpu_V0, cpu_V1);
5183 } else {
5184 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5185 cpu_V0, cpu_V1);
5187 break;
5188 case NEON_3R_VQSUB:
5189 if (u) {
5190 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5191 cpu_V0, cpu_V1);
5192 } else {
5193 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5194 cpu_V0, cpu_V1);
5196 break;
5197 case NEON_3R_VSHL:
5198 if (u) {
5199 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5200 } else {
5201 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5203 break;
5204 case NEON_3R_VQSHL:
5205 if (u) {
5206 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5207 cpu_V1, cpu_V0);
5208 } else {
5209 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5210 cpu_V1, cpu_V0);
5212 break;
5213 case NEON_3R_VRSHL:
5214 if (u) {
5215 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5216 } else {
5217 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5219 break;
5220 case NEON_3R_VQRSHL:
5221 if (u) {
5222 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5223 cpu_V1, cpu_V0);
5224 } else {
5225 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5226 cpu_V1, cpu_V0);
5228 break;
5229 case NEON_3R_VADD_VSUB:
5230 if (u) {
5231 tcg_gen_sub_i64(CPU_V001);
5232 } else {
5233 tcg_gen_add_i64(CPU_V001);
5235 break;
5236 default:
5237 abort();
5239 neon_store_reg64(cpu_V0, rd + pass);
5241 return 0;
5243 pairwise = 0;
5244 switch (op) {
5245 case NEON_3R_VSHL:
5246 case NEON_3R_VQSHL:
5247 case NEON_3R_VRSHL:
5248 case NEON_3R_VQRSHL:
5250 int rtmp;
5251 /* Shift instruction operands are reversed. */
5252 rtmp = rn;
5253 rn = rm;
5254 rm = rtmp;
5256 break;
5257 case NEON_3R_VPADD:
5258 if (u) {
5259 return 1;
5261 /* Fall through */
5262 case NEON_3R_VPMAX:
5263 case NEON_3R_VPMIN:
5264 pairwise = 1;
5265 break;
5266 case NEON_3R_FLOAT_ARITH:
5267 pairwise = (u && size < 2); /* if VPADD (float) */
5268 break;
5269 case NEON_3R_FLOAT_MINMAX:
5270 pairwise = u; /* if VPMIN/VPMAX (float) */
5271 break;
5272 case NEON_3R_FLOAT_CMP:
5273 if (!u && size) {
5274 /* no encoding for U=0 C=1x */
5275 return 1;
5277 break;
5278 case NEON_3R_FLOAT_ACMP:
5279 if (!u) {
5280 return 1;
5282 break;
5283 case NEON_3R_FLOAT_MISC:
5284 /* VMAXNM/VMINNM in ARMv8 */
5285 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5286 return 1;
5288 break;
5289 case NEON_3R_VMUL:
5290 if (u && (size != 0)) {
5291 /* UNDEF on invalid size for polynomial subcase */
5292 return 1;
5294 break;
5295 case NEON_3R_VFM:
5296 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5297 return 1;
5299 break;
5300 default:
5301 break;
5304 if (pairwise && q) {
5305 /* All the pairwise insns UNDEF if Q is set */
5306 return 1;
5309 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5311 if (pairwise) {
5312 /* Pairwise. */
5313 if (pass < 1) {
5314 tmp = neon_load_reg(rn, 0);
5315 tmp2 = neon_load_reg(rn, 1);
5316 } else {
5317 tmp = neon_load_reg(rm, 0);
5318 tmp2 = neon_load_reg(rm, 1);
5320 } else {
5321 /* Elementwise. */
5322 tmp = neon_load_reg(rn, pass);
5323 tmp2 = neon_load_reg(rm, pass);
5325 switch (op) {
5326 case NEON_3R_VHADD:
5327 GEN_NEON_INTEGER_OP(hadd);
5328 break;
5329 case NEON_3R_VQADD:
5330 GEN_NEON_INTEGER_OP_ENV(qadd);
5331 break;
5332 case NEON_3R_VRHADD:
5333 GEN_NEON_INTEGER_OP(rhadd);
5334 break;
5335 case NEON_3R_LOGIC: /* Logic ops. */
5336 switch ((u << 2) | size) {
5337 case 0: /* VAND */
5338 tcg_gen_and_i32(tmp, tmp, tmp2);
5339 break;
5340 case 1: /* BIC */
5341 tcg_gen_andc_i32(tmp, tmp, tmp2);
5342 break;
5343 case 2: /* VORR */
5344 tcg_gen_or_i32(tmp, tmp, tmp2);
5345 break;
5346 case 3: /* VORN */
5347 tcg_gen_orc_i32(tmp, tmp, tmp2);
5348 break;
5349 case 4: /* VEOR */
5350 tcg_gen_xor_i32(tmp, tmp, tmp2);
5351 break;
5352 case 5: /* VBSL */
5353 tmp3 = neon_load_reg(rd, pass);
5354 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5355 tcg_temp_free_i32(tmp3);
5356 break;
5357 case 6: /* VBIT */
5358 tmp3 = neon_load_reg(rd, pass);
5359 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5360 tcg_temp_free_i32(tmp3);
5361 break;
5362 case 7: /* VBIF */
5363 tmp3 = neon_load_reg(rd, pass);
5364 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5365 tcg_temp_free_i32(tmp3);
5366 break;
5368 break;
5369 case NEON_3R_VHSUB:
5370 GEN_NEON_INTEGER_OP(hsub);
5371 break;
5372 case NEON_3R_VQSUB:
5373 GEN_NEON_INTEGER_OP_ENV(qsub);
5374 break;
5375 case NEON_3R_VCGT:
5376 GEN_NEON_INTEGER_OP(cgt);
5377 break;
5378 case NEON_3R_VCGE:
5379 GEN_NEON_INTEGER_OP(cge);
5380 break;
5381 case NEON_3R_VSHL:
5382 GEN_NEON_INTEGER_OP(shl);
5383 break;
5384 case NEON_3R_VQSHL:
5385 GEN_NEON_INTEGER_OP_ENV(qshl);
5386 break;
5387 case NEON_3R_VRSHL:
5388 GEN_NEON_INTEGER_OP(rshl);
5389 break;
5390 case NEON_3R_VQRSHL:
5391 GEN_NEON_INTEGER_OP_ENV(qrshl);
5392 break;
5393 case NEON_3R_VMAX:
5394 GEN_NEON_INTEGER_OP(max);
5395 break;
5396 case NEON_3R_VMIN:
5397 GEN_NEON_INTEGER_OP(min);
5398 break;
5399 case NEON_3R_VABD:
5400 GEN_NEON_INTEGER_OP(abd);
5401 break;
5402 case NEON_3R_VABA:
5403 GEN_NEON_INTEGER_OP(abd);
5404 tcg_temp_free_i32(tmp2);
5405 tmp2 = neon_load_reg(rd, pass);
5406 gen_neon_add(size, tmp, tmp2);
5407 break;
5408 case NEON_3R_VADD_VSUB:
5409 if (!u) { /* VADD */
5410 gen_neon_add(size, tmp, tmp2);
5411 } else { /* VSUB */
5412 switch (size) {
5413 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5414 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5415 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5416 default: abort();
5419 break;
5420 case NEON_3R_VTST_VCEQ:
5421 if (!u) { /* VTST */
5422 switch (size) {
5423 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5424 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5425 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5426 default: abort();
5428 } else { /* VCEQ */
5429 switch (size) {
5430 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5431 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5432 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5433 default: abort();
5436 break;
5437 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5438 switch (size) {
5439 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5440 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5441 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5442 default: abort();
5444 tcg_temp_free_i32(tmp2);
5445 tmp2 = neon_load_reg(rd, pass);
5446 if (u) { /* VMLS */
5447 gen_neon_rsb(size, tmp, tmp2);
5448 } else { /* VMLA */
5449 gen_neon_add(size, tmp, tmp2);
5451 break;
5452 case NEON_3R_VMUL:
5453 if (u) { /* polynomial */
5454 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5455 } else { /* Integer */
5456 switch (size) {
5457 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5458 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5459 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5460 default: abort();
5463 break;
5464 case NEON_3R_VPMAX:
5465 GEN_NEON_INTEGER_OP(pmax);
5466 break;
5467 case NEON_3R_VPMIN:
5468 GEN_NEON_INTEGER_OP(pmin);
5469 break;
5470 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5471 if (!u) { /* VQDMULH */
5472 switch (size) {
5473 case 1:
5474 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5475 break;
5476 case 2:
5477 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5478 break;
5479 default: abort();
5481 } else { /* VQRDMULH */
5482 switch (size) {
5483 case 1:
5484 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5485 break;
5486 case 2:
5487 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5488 break;
5489 default: abort();
5492 break;
5493 case NEON_3R_VPADD:
5494 switch (size) {
5495 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5496 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5497 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5498 default: abort();
5500 break;
5501 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5503 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5504 switch ((u << 2) | size) {
5505 case 0: /* VADD */
5506 case 4: /* VPADD */
5507 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5508 break;
5509 case 2: /* VSUB */
5510 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5511 break;
5512 case 6: /* VABD */
5513 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5514 break;
5515 default:
5516 abort();
5518 tcg_temp_free_ptr(fpstatus);
5519 break;
5521 case NEON_3R_FLOAT_MULTIPLY:
5523 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5524 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5525 if (!u) {
5526 tcg_temp_free_i32(tmp2);
5527 tmp2 = neon_load_reg(rd, pass);
5528 if (size == 0) {
5529 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5530 } else {
5531 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5534 tcg_temp_free_ptr(fpstatus);
5535 break;
5537 case NEON_3R_FLOAT_CMP:
5539 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5540 if (!u) {
5541 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5542 } else {
5543 if (size == 0) {
5544 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5545 } else {
5546 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5549 tcg_temp_free_ptr(fpstatus);
5550 break;
5552 case NEON_3R_FLOAT_ACMP:
5554 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5555 if (size == 0) {
5556 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5557 } else {
5558 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5560 tcg_temp_free_ptr(fpstatus);
5561 break;
5563 case NEON_3R_FLOAT_MINMAX:
5565 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5566 if (size == 0) {
5567 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5568 } else {
5569 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5571 tcg_temp_free_ptr(fpstatus);
5572 break;
5574 case NEON_3R_FLOAT_MISC:
5575 if (u) {
5576 /* VMAXNM/VMINNM */
5577 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5578 if (size == 0) {
5579 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5580 } else {
5581 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5583 tcg_temp_free_ptr(fpstatus);
5584 } else {
5585 if (size == 0) {
5586 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5587 } else {
5588 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5591 break;
5592 case NEON_3R_VFM:
5594 /* VFMA, VFMS: fused multiply-add */
5595 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5596 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5597 if (size) {
5598 /* VFMS */
5599 gen_helper_vfp_negs(tmp, tmp);
5601 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5602 tcg_temp_free_i32(tmp3);
5603 tcg_temp_free_ptr(fpstatus);
5604 break;
5606 default:
5607 abort();
5609 tcg_temp_free_i32(tmp2);
5611 /* Save the result. For elementwise operations we can put it
5612 straight into the destination register. For pairwise operations
5613 we have to be careful to avoid clobbering the source operands. */
5614 if (pairwise && rd == rm) {
5615 neon_store_scratch(pass, tmp);
5616 } else {
5617 neon_store_reg(rd, pass, tmp);
5620 } /* for pass */
5621 if (pairwise && rd == rm) {
5622 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5623 tmp = neon_load_scratch(pass);
5624 neon_store_reg(rd, pass, tmp);
5627 /* End of 3 register same size operations. */
5628 } else if (insn & (1 << 4)) {
5629 if ((insn & 0x00380080) != 0) {
5630 /* Two registers and shift. */
5631 op = (insn >> 8) & 0xf;
5632 if (insn & (1 << 7)) {
5633 /* 64-bit shift. */
5634 if (op > 7) {
5635 return 1;
5637 size = 3;
5638 } else {
5639 size = 2;
5640 while ((insn & (1 << (size + 19))) == 0)
5641 size--;
5643 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5644 /* To avoid excessive duplication of ops we implement shift
5645 by immediate using the variable shift operations. */
5646 if (op < 8) {
5647 /* Shift by immediate:
5648 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5649 if (q && ((rd | rm) & 1)) {
5650 return 1;
5652 if (!u && (op == 4 || op == 6)) {
5653 return 1;
5655 /* Right shifts are encoded as N - shift, where N is the
5656 element size in bits. */
5657 if (op <= 4)
5658 shift = shift - (1 << (size + 3));
5659 if (size == 3) {
5660 count = q + 1;
5661 } else {
5662 count = q ? 4: 2;
5664 switch (size) {
5665 case 0:
5666 imm = (uint8_t) shift;
5667 imm |= imm << 8;
5668 imm |= imm << 16;
5669 break;
5670 case 1:
5671 imm = (uint16_t) shift;
5672 imm |= imm << 16;
5673 break;
5674 case 2:
5675 case 3:
5676 imm = shift;
5677 break;
5678 default:
5679 abort();
5682 for (pass = 0; pass < count; pass++) {
5683 if (size == 3) {
5684 neon_load_reg64(cpu_V0, rm + pass);
5685 tcg_gen_movi_i64(cpu_V1, imm);
5686 switch (op) {
5687 case 0: /* VSHR */
5688 case 1: /* VSRA */
5689 if (u)
5690 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5691 else
5692 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5693 break;
5694 case 2: /* VRSHR */
5695 case 3: /* VRSRA */
5696 if (u)
5697 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5698 else
5699 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5700 break;
5701 case 4: /* VSRI */
5702 case 5: /* VSHL, VSLI */
5703 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5704 break;
5705 case 6: /* VQSHLU */
5706 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5707 cpu_V0, cpu_V1);
5708 break;
5709 case 7: /* VQSHL */
5710 if (u) {
5711 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5712 cpu_V0, cpu_V1);
5713 } else {
5714 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5715 cpu_V0, cpu_V1);
5717 break;
5719 if (op == 1 || op == 3) {
5720 /* Accumulate. */
5721 neon_load_reg64(cpu_V1, rd + pass);
5722 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5723 } else if (op == 4 || (op == 5 && u)) {
5724 /* Insert */
5725 neon_load_reg64(cpu_V1, rd + pass);
5726 uint64_t mask;
5727 if (shift < -63 || shift > 63) {
5728 mask = 0;
5729 } else {
5730 if (op == 4) {
5731 mask = 0xffffffffffffffffull >> -shift;
5732 } else {
5733 mask = 0xffffffffffffffffull << shift;
5736 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5737 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5739 neon_store_reg64(cpu_V0, rd + pass);
5740 } else { /* size < 3 */
5741 /* Operands in T0 and T1. */
5742 tmp = neon_load_reg(rm, pass);
5743 tmp2 = tcg_temp_new_i32();
5744 tcg_gen_movi_i32(tmp2, imm);
5745 switch (op) {
5746 case 0: /* VSHR */
5747 case 1: /* VSRA */
5748 GEN_NEON_INTEGER_OP(shl);
5749 break;
5750 case 2: /* VRSHR */
5751 case 3: /* VRSRA */
5752 GEN_NEON_INTEGER_OP(rshl);
5753 break;
5754 case 4: /* VSRI */
5755 case 5: /* VSHL, VSLI */
5756 switch (size) {
5757 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5758 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5759 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5760 default: abort();
5762 break;
5763 case 6: /* VQSHLU */
5764 switch (size) {
5765 case 0:
5766 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5767 tmp, tmp2);
5768 break;
5769 case 1:
5770 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5771 tmp, tmp2);
5772 break;
5773 case 2:
5774 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5775 tmp, tmp2);
5776 break;
5777 default:
5778 abort();
5780 break;
5781 case 7: /* VQSHL */
5782 GEN_NEON_INTEGER_OP_ENV(qshl);
5783 break;
5785 tcg_temp_free_i32(tmp2);
5787 if (op == 1 || op == 3) {
5788 /* Accumulate. */
5789 tmp2 = neon_load_reg(rd, pass);
5790 gen_neon_add(size, tmp, tmp2);
5791 tcg_temp_free_i32(tmp2);
5792 } else if (op == 4 || (op == 5 && u)) {
5793 /* Insert */
5794 switch (size) {
5795 case 0:
5796 if (op == 4)
5797 mask = 0xff >> -shift;
5798 else
5799 mask = (uint8_t)(0xff << shift);
5800 mask |= mask << 8;
5801 mask |= mask << 16;
5802 break;
5803 case 1:
5804 if (op == 4)
5805 mask = 0xffff >> -shift;
5806 else
5807 mask = (uint16_t)(0xffff << shift);
5808 mask |= mask << 16;
5809 break;
5810 case 2:
5811 if (shift < -31 || shift > 31) {
5812 mask = 0;
5813 } else {
5814 if (op == 4)
5815 mask = 0xffffffffu >> -shift;
5816 else
5817 mask = 0xffffffffu << shift;
5819 break;
5820 default:
5821 abort();
5823 tmp2 = neon_load_reg(rd, pass);
5824 tcg_gen_andi_i32(tmp, tmp, mask);
5825 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5826 tcg_gen_or_i32(tmp, tmp, tmp2);
5827 tcg_temp_free_i32(tmp2);
5829 neon_store_reg(rd, pass, tmp);
5831 } /* for pass */
5832 } else if (op < 10) {
5833 /* Shift by immediate and narrow:
5834 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5835 int input_unsigned = (op == 8) ? !u : u;
5836 if (rm & 1) {
5837 return 1;
5839 shift = shift - (1 << (size + 3));
5840 size++;
5841 if (size == 3) {
5842 tmp64 = tcg_const_i64(shift);
5843 neon_load_reg64(cpu_V0, rm);
5844 neon_load_reg64(cpu_V1, rm + 1);
5845 for (pass = 0; pass < 2; pass++) {
5846 TCGv_i64 in;
5847 if (pass == 0) {
5848 in = cpu_V0;
5849 } else {
5850 in = cpu_V1;
5852 if (q) {
5853 if (input_unsigned) {
5854 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5855 } else {
5856 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5858 } else {
5859 if (input_unsigned) {
5860 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5861 } else {
5862 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5865 tmp = tcg_temp_new_i32();
5866 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5867 neon_store_reg(rd, pass, tmp);
5868 } /* for pass */
5869 tcg_temp_free_i64(tmp64);
5870 } else {
5871 if (size == 1) {
5872 imm = (uint16_t)shift;
5873 imm |= imm << 16;
5874 } else {
5875 /* size == 2 */
5876 imm = (uint32_t)shift;
5878 tmp2 = tcg_const_i32(imm);
5879 tmp4 = neon_load_reg(rm + 1, 0);
5880 tmp5 = neon_load_reg(rm + 1, 1);
5881 for (pass = 0; pass < 2; pass++) {
5882 if (pass == 0) {
5883 tmp = neon_load_reg(rm, 0);
5884 } else {
5885 tmp = tmp4;
5887 gen_neon_shift_narrow(size, tmp, tmp2, q,
5888 input_unsigned);
5889 if (pass == 0) {
5890 tmp3 = neon_load_reg(rm, 1);
5891 } else {
5892 tmp3 = tmp5;
5894 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5895 input_unsigned);
5896 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5897 tcg_temp_free_i32(tmp);
5898 tcg_temp_free_i32(tmp3);
5899 tmp = tcg_temp_new_i32();
5900 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5901 neon_store_reg(rd, pass, tmp);
5902 } /* for pass */
5903 tcg_temp_free_i32(tmp2);
5905 } else if (op == 10) {
5906 /* VSHLL, VMOVL */
5907 if (q || (rd & 1)) {
5908 return 1;
5910 tmp = neon_load_reg(rm, 0);
5911 tmp2 = neon_load_reg(rm, 1);
5912 for (pass = 0; pass < 2; pass++) {
5913 if (pass == 1)
5914 tmp = tmp2;
5916 gen_neon_widen(cpu_V0, tmp, size, u);
5918 if (shift != 0) {
5919 /* The shift is less than the width of the source
5920 type, so we can just shift the whole register. */
5921 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5922 /* Widen the result of shift: we need to clear
5923 * the potential overflow bits resulting from
5924 * left bits of the narrow input appearing as
5925 * right bits of left the neighbour narrow
5926 * input. */
5927 if (size < 2 || !u) {
5928 uint64_t imm64;
5929 if (size == 0) {
5930 imm = (0xffu >> (8 - shift));
5931 imm |= imm << 16;
5932 } else if (size == 1) {
5933 imm = 0xffff >> (16 - shift);
5934 } else {
5935 /* size == 2 */
5936 imm = 0xffffffff >> (32 - shift);
5938 if (size < 2) {
5939 imm64 = imm | (((uint64_t)imm) << 32);
5940 } else {
5941 imm64 = imm;
5943 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5946 neon_store_reg64(cpu_V0, rd + pass);
5948 } else if (op >= 14) {
5949 /* VCVT fixed-point. */
5950 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5951 return 1;
5953 /* We have already masked out the must-be-1 top bit of imm6,
5954 * hence this 32-shift where the ARM ARM has 64-imm6.
5956 shift = 32 - shift;
5957 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5958 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5959 if (!(op & 1)) {
5960 if (u)
5961 gen_vfp_ulto(0, shift, 1);
5962 else
5963 gen_vfp_slto(0, shift, 1);
5964 } else {
5965 if (u)
5966 gen_vfp_toul(0, shift, 1);
5967 else
5968 gen_vfp_tosl(0, shift, 1);
5970 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5972 } else {
5973 return 1;
5975 } else { /* (insn & 0x00380080) == 0 */
5976 int invert;
5977 if (q && (rd & 1)) {
5978 return 1;
5981 op = (insn >> 8) & 0xf;
5982 /* One register and immediate. */
5983 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5984 invert = (insn & (1 << 5)) != 0;
5985 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5986 * We choose to not special-case this and will behave as if a
5987 * valid constant encoding of 0 had been given.
5989 switch (op) {
5990 case 0: case 1:
5991 /* no-op */
5992 break;
5993 case 2: case 3:
5994 imm <<= 8;
5995 break;
5996 case 4: case 5:
5997 imm <<= 16;
5998 break;
5999 case 6: case 7:
6000 imm <<= 24;
6001 break;
6002 case 8: case 9:
6003 imm |= imm << 16;
6004 break;
6005 case 10: case 11:
6006 imm = (imm << 8) | (imm << 24);
6007 break;
6008 case 12:
6009 imm = (imm << 8) | 0xff;
6010 break;
6011 case 13:
6012 imm = (imm << 16) | 0xffff;
6013 break;
6014 case 14:
6015 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6016 if (invert)
6017 imm = ~imm;
6018 break;
6019 case 15:
6020 if (invert) {
6021 return 1;
6023 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6024 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6025 break;
6027 if (invert)
6028 imm = ~imm;
6030 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6031 if (op & 1 && op < 12) {
6032 tmp = neon_load_reg(rd, pass);
6033 if (invert) {
6034 /* The immediate value has already been inverted, so
6035 BIC becomes AND. */
6036 tcg_gen_andi_i32(tmp, tmp, imm);
6037 } else {
6038 tcg_gen_ori_i32(tmp, tmp, imm);
6040 } else {
6041 /* VMOV, VMVN. */
6042 tmp = tcg_temp_new_i32();
6043 if (op == 14 && invert) {
6044 int n;
6045 uint32_t val;
6046 val = 0;
6047 for (n = 0; n < 4; n++) {
6048 if (imm & (1 << (n + (pass & 1) * 4)))
6049 val |= 0xff << (n * 8);
6051 tcg_gen_movi_i32(tmp, val);
6052 } else {
6053 tcg_gen_movi_i32(tmp, imm);
6056 neon_store_reg(rd, pass, tmp);
6059 } else { /* (insn & 0x00800010 == 0x00800000) */
6060 if (size != 3) {
6061 op = (insn >> 8) & 0xf;
6062 if ((insn & (1 << 6)) == 0) {
6063 /* Three registers of different lengths. */
6064 int src1_wide;
6065 int src2_wide;
6066 int prewiden;
6067 /* undefreq: bit 0 : UNDEF if size == 0
6068 * bit 1 : UNDEF if size == 1
6069 * bit 2 : UNDEF if size == 2
6070 * bit 3 : UNDEF if U == 1
6071 * Note that [2:0] set implies 'always UNDEF'
6073 int undefreq;
6074 /* prewiden, src1_wide, src2_wide, undefreq */
6075 static const int neon_3reg_wide[16][4] = {
6076 {1, 0, 0, 0}, /* VADDL */
6077 {1, 1, 0, 0}, /* VADDW */
6078 {1, 0, 0, 0}, /* VSUBL */
6079 {1, 1, 0, 0}, /* VSUBW */
6080 {0, 1, 1, 0}, /* VADDHN */
6081 {0, 0, 0, 0}, /* VABAL */
6082 {0, 1, 1, 0}, /* VSUBHN */
6083 {0, 0, 0, 0}, /* VABDL */
6084 {0, 0, 0, 0}, /* VMLAL */
6085 {0, 0, 0, 9}, /* VQDMLAL */
6086 {0, 0, 0, 0}, /* VMLSL */
6087 {0, 0, 0, 9}, /* VQDMLSL */
6088 {0, 0, 0, 0}, /* Integer VMULL */
6089 {0, 0, 0, 1}, /* VQDMULL */
6090 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6091 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6094 prewiden = neon_3reg_wide[op][0];
6095 src1_wide = neon_3reg_wide[op][1];
6096 src2_wide = neon_3reg_wide[op][2];
6097 undefreq = neon_3reg_wide[op][3];
6099 if ((undefreq & (1 << size)) ||
6100 ((undefreq & 8) && u)) {
6101 return 1;
6103 if ((src1_wide && (rn & 1)) ||
6104 (src2_wide && (rm & 1)) ||
6105 (!src2_wide && (rd & 1))) {
6106 return 1;
6109 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6110 * outside the loop below as it only performs a single pass.
6112 if (op == 14 && size == 2) {
6113 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6115 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6116 return 1;
6118 tcg_rn = tcg_temp_new_i64();
6119 tcg_rm = tcg_temp_new_i64();
6120 tcg_rd = tcg_temp_new_i64();
6121 neon_load_reg64(tcg_rn, rn);
6122 neon_load_reg64(tcg_rm, rm);
6123 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6124 neon_store_reg64(tcg_rd, rd);
6125 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6126 neon_store_reg64(tcg_rd, rd + 1);
6127 tcg_temp_free_i64(tcg_rn);
6128 tcg_temp_free_i64(tcg_rm);
6129 tcg_temp_free_i64(tcg_rd);
6130 return 0;
6133 /* Avoid overlapping operands. Wide source operands are
6134 always aligned so will never overlap with wide
6135 destinations in problematic ways. */
6136 if (rd == rm && !src2_wide) {
6137 tmp = neon_load_reg(rm, 1);
6138 neon_store_scratch(2, tmp);
6139 } else if (rd == rn && !src1_wide) {
6140 tmp = neon_load_reg(rn, 1);
6141 neon_store_scratch(2, tmp);
6143 TCGV_UNUSED_I32(tmp3);
6144 for (pass = 0; pass < 2; pass++) {
6145 if (src1_wide) {
6146 neon_load_reg64(cpu_V0, rn + pass);
6147 TCGV_UNUSED_I32(tmp);
6148 } else {
6149 if (pass == 1 && rd == rn) {
6150 tmp = neon_load_scratch(2);
6151 } else {
6152 tmp = neon_load_reg(rn, pass);
6154 if (prewiden) {
6155 gen_neon_widen(cpu_V0, tmp, size, u);
6158 if (src2_wide) {
6159 neon_load_reg64(cpu_V1, rm + pass);
6160 TCGV_UNUSED_I32(tmp2);
6161 } else {
6162 if (pass == 1 && rd == rm) {
6163 tmp2 = neon_load_scratch(2);
6164 } else {
6165 tmp2 = neon_load_reg(rm, pass);
6167 if (prewiden) {
6168 gen_neon_widen(cpu_V1, tmp2, size, u);
6171 switch (op) {
6172 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6173 gen_neon_addl(size);
6174 break;
6175 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6176 gen_neon_subl(size);
6177 break;
6178 case 5: case 7: /* VABAL, VABDL */
6179 switch ((size << 1) | u) {
6180 case 0:
6181 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6182 break;
6183 case 1:
6184 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6185 break;
6186 case 2:
6187 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6188 break;
6189 case 3:
6190 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6191 break;
6192 case 4:
6193 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6194 break;
6195 case 5:
6196 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6197 break;
6198 default: abort();
6200 tcg_temp_free_i32(tmp2);
6201 tcg_temp_free_i32(tmp);
6202 break;
6203 case 8: case 9: case 10: case 11: case 12: case 13:
6204 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6205 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6206 break;
6207 case 14: /* Polynomial VMULL */
6208 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6209 tcg_temp_free_i32(tmp2);
6210 tcg_temp_free_i32(tmp);
6211 break;
6212 default: /* 15 is RESERVED: caught earlier */
6213 abort();
6215 if (op == 13) {
6216 /* VQDMULL */
6217 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6218 neon_store_reg64(cpu_V0, rd + pass);
6219 } else if (op == 5 || (op >= 8 && op <= 11)) {
6220 /* Accumulate. */
6221 neon_load_reg64(cpu_V1, rd + pass);
6222 switch (op) {
6223 case 10: /* VMLSL */
6224 gen_neon_negl(cpu_V0, size);
6225 /* Fall through */
6226 case 5: case 8: /* VABAL, VMLAL */
6227 gen_neon_addl(size);
6228 break;
6229 case 9: case 11: /* VQDMLAL, VQDMLSL */
6230 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6231 if (op == 11) {
6232 gen_neon_negl(cpu_V0, size);
6234 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6235 break;
6236 default:
6237 abort();
6239 neon_store_reg64(cpu_V0, rd + pass);
6240 } else if (op == 4 || op == 6) {
6241 /* Narrowing operation. */
6242 tmp = tcg_temp_new_i32();
6243 if (!u) {
6244 switch (size) {
6245 case 0:
6246 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6247 break;
6248 case 1:
6249 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6250 break;
6251 case 2:
6252 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6253 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6254 break;
6255 default: abort();
6257 } else {
6258 switch (size) {
6259 case 0:
6260 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6261 break;
6262 case 1:
6263 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6264 break;
6265 case 2:
6266 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6267 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6268 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6269 break;
6270 default: abort();
6273 if (pass == 0) {
6274 tmp3 = tmp;
6275 } else {
6276 neon_store_reg(rd, 0, tmp3);
6277 neon_store_reg(rd, 1, tmp);
6279 } else {
6280 /* Write back the result. */
6281 neon_store_reg64(cpu_V0, rd + pass);
6284 } else {
6285 /* Two registers and a scalar. NB that for ops of this form
6286 * the ARM ARM labels bit 24 as Q, but it is in our variable
6287 * 'u', not 'q'.
6289 if (size == 0) {
6290 return 1;
6292 switch (op) {
6293 case 1: /* Float VMLA scalar */
6294 case 5: /* Floating point VMLS scalar */
6295 case 9: /* Floating point VMUL scalar */
6296 if (size == 1) {
6297 return 1;
6299 /* fall through */
6300 case 0: /* Integer VMLA scalar */
6301 case 4: /* Integer VMLS scalar */
6302 case 8: /* Integer VMUL scalar */
6303 case 12: /* VQDMULH scalar */
6304 case 13: /* VQRDMULH scalar */
6305 if (u && ((rd | rn) & 1)) {
6306 return 1;
6308 tmp = neon_get_scalar(size, rm);
6309 neon_store_scratch(0, tmp);
6310 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6311 tmp = neon_load_scratch(0);
6312 tmp2 = neon_load_reg(rn, pass);
6313 if (op == 12) {
6314 if (size == 1) {
6315 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6316 } else {
6317 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6319 } else if (op == 13) {
6320 if (size == 1) {
6321 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6322 } else {
6323 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6325 } else if (op & 1) {
6326 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6327 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6328 tcg_temp_free_ptr(fpstatus);
6329 } else {
6330 switch (size) {
6331 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6332 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6333 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6334 default: abort();
6337 tcg_temp_free_i32(tmp2);
6338 if (op < 8) {
6339 /* Accumulate. */
6340 tmp2 = neon_load_reg(rd, pass);
6341 switch (op) {
6342 case 0:
6343 gen_neon_add(size, tmp, tmp2);
6344 break;
6345 case 1:
6347 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6348 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6349 tcg_temp_free_ptr(fpstatus);
6350 break;
6352 case 4:
6353 gen_neon_rsb(size, tmp, tmp2);
6354 break;
6355 case 5:
6357 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6358 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6359 tcg_temp_free_ptr(fpstatus);
6360 break;
6362 default:
6363 abort();
6365 tcg_temp_free_i32(tmp2);
6367 neon_store_reg(rd, pass, tmp);
6369 break;
6370 case 3: /* VQDMLAL scalar */
6371 case 7: /* VQDMLSL scalar */
6372 case 11: /* VQDMULL scalar */
6373 if (u == 1) {
6374 return 1;
6376 /* fall through */
6377 case 2: /* VMLAL sclar */
6378 case 6: /* VMLSL scalar */
6379 case 10: /* VMULL scalar */
6380 if (rd & 1) {
6381 return 1;
6383 tmp2 = neon_get_scalar(size, rm);
6384 /* We need a copy of tmp2 because gen_neon_mull
6385 * deletes it during pass 0. */
6386 tmp4 = tcg_temp_new_i32();
6387 tcg_gen_mov_i32(tmp4, tmp2);
6388 tmp3 = neon_load_reg(rn, 1);
6390 for (pass = 0; pass < 2; pass++) {
6391 if (pass == 0) {
6392 tmp = neon_load_reg(rn, 0);
6393 } else {
6394 tmp = tmp3;
6395 tmp2 = tmp4;
6397 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6398 if (op != 11) {
6399 neon_load_reg64(cpu_V1, rd + pass);
6401 switch (op) {
6402 case 6:
6403 gen_neon_negl(cpu_V0, size);
6404 /* Fall through */
6405 case 2:
6406 gen_neon_addl(size);
6407 break;
6408 case 3: case 7:
6409 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6410 if (op == 7) {
6411 gen_neon_negl(cpu_V0, size);
6413 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6414 break;
6415 case 10:
6416 /* no-op */
6417 break;
6418 case 11:
6419 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6420 break;
6421 default:
6422 abort();
6424 neon_store_reg64(cpu_V0, rd + pass);
6428 break;
6429 default: /* 14 and 15 are RESERVED */
6430 return 1;
6433 } else { /* size == 3 */
6434 if (!u) {
6435 /* Extract. */
6436 imm = (insn >> 8) & 0xf;
6438 if (imm > 7 && !q)
6439 return 1;
6441 if (q && ((rd | rn | rm) & 1)) {
6442 return 1;
6445 if (imm == 0) {
6446 neon_load_reg64(cpu_V0, rn);
6447 if (q) {
6448 neon_load_reg64(cpu_V1, rn + 1);
6450 } else if (imm == 8) {
6451 neon_load_reg64(cpu_V0, rn + 1);
6452 if (q) {
6453 neon_load_reg64(cpu_V1, rm);
6455 } else if (q) {
6456 tmp64 = tcg_temp_new_i64();
6457 if (imm < 8) {
6458 neon_load_reg64(cpu_V0, rn);
6459 neon_load_reg64(tmp64, rn + 1);
6460 } else {
6461 neon_load_reg64(cpu_V0, rn + 1);
6462 neon_load_reg64(tmp64, rm);
6464 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6465 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6466 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6467 if (imm < 8) {
6468 neon_load_reg64(cpu_V1, rm);
6469 } else {
6470 neon_load_reg64(cpu_V1, rm + 1);
6471 imm -= 8;
6473 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6474 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6475 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6476 tcg_temp_free_i64(tmp64);
6477 } else {
6478 /* BUGFIX */
6479 neon_load_reg64(cpu_V0, rn);
6480 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6481 neon_load_reg64(cpu_V1, rm);
6482 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6483 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6485 neon_store_reg64(cpu_V0, rd);
6486 if (q) {
6487 neon_store_reg64(cpu_V1, rd + 1);
6489 } else if ((insn & (1 << 11)) == 0) {
6490 /* Two register misc. */
6491 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6492 size = (insn >> 18) & 3;
6493 /* UNDEF for unknown op values and bad op-size combinations */
6494 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6495 return 1;
6497 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6498 q && ((rm | rd) & 1)) {
6499 return 1;
6501 switch (op) {
6502 case NEON_2RM_VREV64:
6503 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6504 tmp = neon_load_reg(rm, pass * 2);
6505 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6506 switch (size) {
6507 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6508 case 1: gen_swap_half(tmp); break;
6509 case 2: /* no-op */ break;
6510 default: abort();
6512 neon_store_reg(rd, pass * 2 + 1, tmp);
6513 if (size == 2) {
6514 neon_store_reg(rd, pass * 2, tmp2);
6515 } else {
6516 switch (size) {
6517 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6518 case 1: gen_swap_half(tmp2); break;
6519 default: abort();
6521 neon_store_reg(rd, pass * 2, tmp2);
6524 break;
6525 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6526 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6527 for (pass = 0; pass < q + 1; pass++) {
6528 tmp = neon_load_reg(rm, pass * 2);
6529 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6530 tmp = neon_load_reg(rm, pass * 2 + 1);
6531 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6532 switch (size) {
6533 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6534 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6535 case 2: tcg_gen_add_i64(CPU_V001); break;
6536 default: abort();
6538 if (op >= NEON_2RM_VPADAL) {
6539 /* Accumulate. */
6540 neon_load_reg64(cpu_V1, rd + pass);
6541 gen_neon_addl(size);
6543 neon_store_reg64(cpu_V0, rd + pass);
6545 break;
6546 case NEON_2RM_VTRN:
6547 if (size == 2) {
6548 int n;
6549 for (n = 0; n < (q ? 4 : 2); n += 2) {
6550 tmp = neon_load_reg(rm, n);
6551 tmp2 = neon_load_reg(rd, n + 1);
6552 neon_store_reg(rm, n, tmp2);
6553 neon_store_reg(rd, n + 1, tmp);
6555 } else {
6556 goto elementwise;
6558 break;
6559 case NEON_2RM_VUZP:
6560 if (gen_neon_unzip(rd, rm, size, q)) {
6561 return 1;
6563 break;
6564 case NEON_2RM_VZIP:
6565 if (gen_neon_zip(rd, rm, size, q)) {
6566 return 1;
6568 break;
6569 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6570 /* also VQMOVUN; op field and mnemonics don't line up */
6571 if (rm & 1) {
6572 return 1;
6574 TCGV_UNUSED_I32(tmp2);
6575 for (pass = 0; pass < 2; pass++) {
6576 neon_load_reg64(cpu_V0, rm + pass);
6577 tmp = tcg_temp_new_i32();
6578 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6579 tmp, cpu_V0);
6580 if (pass == 0) {
6581 tmp2 = tmp;
6582 } else {
6583 neon_store_reg(rd, 0, tmp2);
6584 neon_store_reg(rd, 1, tmp);
6587 break;
6588 case NEON_2RM_VSHLL:
6589 if (q || (rd & 1)) {
6590 return 1;
6592 tmp = neon_load_reg(rm, 0);
6593 tmp2 = neon_load_reg(rm, 1);
6594 for (pass = 0; pass < 2; pass++) {
6595 if (pass == 1)
6596 tmp = tmp2;
6597 gen_neon_widen(cpu_V0, tmp, size, 1);
6598 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6599 neon_store_reg64(cpu_V0, rd + pass);
6601 break;
6602 case NEON_2RM_VCVT_F16_F32:
6603 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6604 q || (rm & 1)) {
6605 return 1;
6607 tmp = tcg_temp_new_i32();
6608 tmp2 = tcg_temp_new_i32();
6609 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6610 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6611 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6612 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6613 tcg_gen_shli_i32(tmp2, tmp2, 16);
6614 tcg_gen_or_i32(tmp2, tmp2, tmp);
6615 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6616 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6617 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6618 neon_store_reg(rd, 0, tmp2);
6619 tmp2 = tcg_temp_new_i32();
6620 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6621 tcg_gen_shli_i32(tmp2, tmp2, 16);
6622 tcg_gen_or_i32(tmp2, tmp2, tmp);
6623 neon_store_reg(rd, 1, tmp2);
6624 tcg_temp_free_i32(tmp);
6625 break;
6626 case NEON_2RM_VCVT_F32_F16:
6627 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6628 q || (rd & 1)) {
6629 return 1;
6631 tmp3 = tcg_temp_new_i32();
6632 tmp = neon_load_reg(rm, 0);
6633 tmp2 = neon_load_reg(rm, 1);
6634 tcg_gen_ext16u_i32(tmp3, tmp);
6635 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6636 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6637 tcg_gen_shri_i32(tmp3, tmp, 16);
6638 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6639 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6640 tcg_temp_free_i32(tmp);
6641 tcg_gen_ext16u_i32(tmp3, tmp2);
6642 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6643 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6644 tcg_gen_shri_i32(tmp3, tmp2, 16);
6645 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6646 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6647 tcg_temp_free_i32(tmp2);
6648 tcg_temp_free_i32(tmp3);
6649 break;
6650 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6651 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6652 || ((rm | rd) & 1)) {
6653 return 1;
6655 tmp = tcg_const_i32(rd);
6656 tmp2 = tcg_const_i32(rm);
6658 /* Bit 6 is the lowest opcode bit; it distinguishes between
6659 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6661 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6663 if (op == NEON_2RM_AESE) {
6664 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6665 } else {
6666 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6668 tcg_temp_free_i32(tmp);
6669 tcg_temp_free_i32(tmp2);
6670 tcg_temp_free_i32(tmp3);
6671 break;
6672 case NEON_2RM_SHA1H:
6673 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
6674 || ((rm | rd) & 1)) {
6675 return 1;
6677 tmp = tcg_const_i32(rd);
6678 tmp2 = tcg_const_i32(rm);
6680 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
6682 tcg_temp_free_i32(tmp);
6683 tcg_temp_free_i32(tmp2);
6684 break;
6685 case NEON_2RM_SHA1SU1:
6686 if ((rm | rd) & 1) {
6687 return 1;
6689 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6690 if (q) {
6691 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
6692 return 1;
6694 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
6695 return 1;
6697 tmp = tcg_const_i32(rd);
6698 tmp2 = tcg_const_i32(rm);
6699 if (q) {
6700 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
6701 } else {
6702 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
6704 tcg_temp_free_i32(tmp);
6705 tcg_temp_free_i32(tmp2);
6706 break;
6707 default:
6708 elementwise:
6709 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6710 if (neon_2rm_is_float_op(op)) {
6711 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6712 neon_reg_offset(rm, pass));
6713 TCGV_UNUSED_I32(tmp);
6714 } else {
6715 tmp = neon_load_reg(rm, pass);
6717 switch (op) {
6718 case NEON_2RM_VREV32:
6719 switch (size) {
6720 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6721 case 1: gen_swap_half(tmp); break;
6722 default: abort();
6724 break;
6725 case NEON_2RM_VREV16:
6726 gen_rev16(tmp);
6727 break;
6728 case NEON_2RM_VCLS:
6729 switch (size) {
6730 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6731 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6732 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6733 default: abort();
6735 break;
6736 case NEON_2RM_VCLZ:
6737 switch (size) {
6738 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6739 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6740 case 2: gen_helper_clz(tmp, tmp); break;
6741 default: abort();
6743 break;
6744 case NEON_2RM_VCNT:
6745 gen_helper_neon_cnt_u8(tmp, tmp);
6746 break;
6747 case NEON_2RM_VMVN:
6748 tcg_gen_not_i32(tmp, tmp);
6749 break;
6750 case NEON_2RM_VQABS:
6751 switch (size) {
6752 case 0:
6753 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6754 break;
6755 case 1:
6756 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6757 break;
6758 case 2:
6759 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6760 break;
6761 default: abort();
6763 break;
6764 case NEON_2RM_VQNEG:
6765 switch (size) {
6766 case 0:
6767 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6768 break;
6769 case 1:
6770 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6771 break;
6772 case 2:
6773 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6774 break;
6775 default: abort();
6777 break;
6778 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6779 tmp2 = tcg_const_i32(0);
6780 switch(size) {
6781 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6782 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6783 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6784 default: abort();
6786 tcg_temp_free_i32(tmp2);
6787 if (op == NEON_2RM_VCLE0) {
6788 tcg_gen_not_i32(tmp, tmp);
6790 break;
6791 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6792 tmp2 = tcg_const_i32(0);
6793 switch(size) {
6794 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6795 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6796 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6797 default: abort();
6799 tcg_temp_free_i32(tmp2);
6800 if (op == NEON_2RM_VCLT0) {
6801 tcg_gen_not_i32(tmp, tmp);
6803 break;
6804 case NEON_2RM_VCEQ0:
6805 tmp2 = tcg_const_i32(0);
6806 switch(size) {
6807 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6808 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6809 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6810 default: abort();
6812 tcg_temp_free_i32(tmp2);
6813 break;
6814 case NEON_2RM_VABS:
6815 switch(size) {
6816 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6817 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6818 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6819 default: abort();
6821 break;
6822 case NEON_2RM_VNEG:
6823 tmp2 = tcg_const_i32(0);
6824 gen_neon_rsb(size, tmp, tmp2);
6825 tcg_temp_free_i32(tmp2);
6826 break;
6827 case NEON_2RM_VCGT0_F:
6829 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6830 tmp2 = tcg_const_i32(0);
6831 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6832 tcg_temp_free_i32(tmp2);
6833 tcg_temp_free_ptr(fpstatus);
6834 break;
6836 case NEON_2RM_VCGE0_F:
6838 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6839 tmp2 = tcg_const_i32(0);
6840 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6841 tcg_temp_free_i32(tmp2);
6842 tcg_temp_free_ptr(fpstatus);
6843 break;
6845 case NEON_2RM_VCEQ0_F:
6847 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6848 tmp2 = tcg_const_i32(0);
6849 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6850 tcg_temp_free_i32(tmp2);
6851 tcg_temp_free_ptr(fpstatus);
6852 break;
6854 case NEON_2RM_VCLE0_F:
6856 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6857 tmp2 = tcg_const_i32(0);
6858 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6859 tcg_temp_free_i32(tmp2);
6860 tcg_temp_free_ptr(fpstatus);
6861 break;
6863 case NEON_2RM_VCLT0_F:
6865 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6866 tmp2 = tcg_const_i32(0);
6867 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6868 tcg_temp_free_i32(tmp2);
6869 tcg_temp_free_ptr(fpstatus);
6870 break;
6872 case NEON_2RM_VABS_F:
6873 gen_vfp_abs(0);
6874 break;
6875 case NEON_2RM_VNEG_F:
6876 gen_vfp_neg(0);
6877 break;
6878 case NEON_2RM_VSWP:
6879 tmp2 = neon_load_reg(rd, pass);
6880 neon_store_reg(rm, pass, tmp2);
6881 break;
6882 case NEON_2RM_VTRN:
6883 tmp2 = neon_load_reg(rd, pass);
6884 switch (size) {
6885 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6886 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6887 default: abort();
6889 neon_store_reg(rm, pass, tmp2);
6890 break;
6891 case NEON_2RM_VRINTN:
6892 case NEON_2RM_VRINTA:
6893 case NEON_2RM_VRINTM:
6894 case NEON_2RM_VRINTP:
6895 case NEON_2RM_VRINTZ:
6897 TCGv_i32 tcg_rmode;
6898 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6899 int rmode;
6901 if (op == NEON_2RM_VRINTZ) {
6902 rmode = FPROUNDING_ZERO;
6903 } else {
6904 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6907 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6908 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6909 cpu_env);
6910 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6911 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6912 cpu_env);
6913 tcg_temp_free_ptr(fpstatus);
6914 tcg_temp_free_i32(tcg_rmode);
6915 break;
6917 case NEON_2RM_VRINTX:
6919 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6920 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6921 tcg_temp_free_ptr(fpstatus);
6922 break;
6924 case NEON_2RM_VCVTAU:
6925 case NEON_2RM_VCVTAS:
6926 case NEON_2RM_VCVTNU:
6927 case NEON_2RM_VCVTNS:
6928 case NEON_2RM_VCVTPU:
6929 case NEON_2RM_VCVTPS:
6930 case NEON_2RM_VCVTMU:
6931 case NEON_2RM_VCVTMS:
6933 bool is_signed = !extract32(insn, 7, 1);
6934 TCGv_ptr fpst = get_fpstatus_ptr(1);
6935 TCGv_i32 tcg_rmode, tcg_shift;
6936 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6938 tcg_shift = tcg_const_i32(0);
6939 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6940 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6941 cpu_env);
6943 if (is_signed) {
6944 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6945 tcg_shift, fpst);
6946 } else {
6947 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6948 tcg_shift, fpst);
6951 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6952 cpu_env);
6953 tcg_temp_free_i32(tcg_rmode);
6954 tcg_temp_free_i32(tcg_shift);
6955 tcg_temp_free_ptr(fpst);
6956 break;
6958 case NEON_2RM_VRECPE:
6960 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6961 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6962 tcg_temp_free_ptr(fpstatus);
6963 break;
6965 case NEON_2RM_VRSQRTE:
6967 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6968 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6969 tcg_temp_free_ptr(fpstatus);
6970 break;
6972 case NEON_2RM_VRECPE_F:
6974 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6975 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
6976 tcg_temp_free_ptr(fpstatus);
6977 break;
6979 case NEON_2RM_VRSQRTE_F:
6981 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6982 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
6983 tcg_temp_free_ptr(fpstatus);
6984 break;
6986 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6987 gen_vfp_sito(0, 1);
6988 break;
6989 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6990 gen_vfp_uito(0, 1);
6991 break;
6992 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6993 gen_vfp_tosiz(0, 1);
6994 break;
6995 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6996 gen_vfp_touiz(0, 1);
6997 break;
6998 default:
6999 /* Reserved op values were caught by the
7000 * neon_2rm_sizes[] check earlier.
7002 abort();
7004 if (neon_2rm_is_float_op(op)) {
7005 tcg_gen_st_f32(cpu_F0s, cpu_env,
7006 neon_reg_offset(rd, pass));
7007 } else {
7008 neon_store_reg(rd, pass, tmp);
7011 break;
7013 } else if ((insn & (1 << 10)) == 0) {
7014 /* VTBL, VTBX. */
7015 int n = ((insn >> 8) & 3) + 1;
7016 if ((rn + n) > 32) {
7017 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7018 * helper function running off the end of the register file.
7020 return 1;
7022 n <<= 3;
7023 if (insn & (1 << 6)) {
7024 tmp = neon_load_reg(rd, 0);
7025 } else {
7026 tmp = tcg_temp_new_i32();
7027 tcg_gen_movi_i32(tmp, 0);
7029 tmp2 = neon_load_reg(rm, 0);
7030 tmp4 = tcg_const_i32(rn);
7031 tmp5 = tcg_const_i32(n);
7032 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7033 tcg_temp_free_i32(tmp);
7034 if (insn & (1 << 6)) {
7035 tmp = neon_load_reg(rd, 1);
7036 } else {
7037 tmp = tcg_temp_new_i32();
7038 tcg_gen_movi_i32(tmp, 0);
7040 tmp3 = neon_load_reg(rm, 1);
7041 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7042 tcg_temp_free_i32(tmp5);
7043 tcg_temp_free_i32(tmp4);
7044 neon_store_reg(rd, 0, tmp2);
7045 neon_store_reg(rd, 1, tmp3);
7046 tcg_temp_free_i32(tmp);
7047 } else if ((insn & 0x380) == 0) {
7048 /* VDUP */
7049 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7050 return 1;
7052 if (insn & (1 << 19)) {
7053 tmp = neon_load_reg(rm, 1);
7054 } else {
7055 tmp = neon_load_reg(rm, 0);
7057 if (insn & (1 << 16)) {
7058 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7059 } else if (insn & (1 << 17)) {
7060 if ((insn >> 18) & 1)
7061 gen_neon_dup_high16(tmp);
7062 else
7063 gen_neon_dup_low16(tmp);
7065 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7066 tmp2 = tcg_temp_new_i32();
7067 tcg_gen_mov_i32(tmp2, tmp);
7068 neon_store_reg(rd, pass, tmp2);
7070 tcg_temp_free_i32(tmp);
7071 } else {
7072 return 1;
7076 return 0;
7079 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7081 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7082 const ARMCPRegInfo *ri;
7084 cpnum = (insn >> 8) & 0xf;
7086 /* First check for coprocessor space used for XScale/iwMMXt insns */
7087 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7088 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7089 return 1;
7091 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7092 return disas_iwmmxt_insn(s, insn);
7093 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7094 return disas_dsp_insn(s, insn);
7096 return 1;
7099 /* Otherwise treat as a generic register access */
7100 is64 = (insn & (1 << 25)) == 0;
7101 if (!is64 && ((insn & (1 << 4)) == 0)) {
7102 /* cdp */
7103 return 1;
7106 crm = insn & 0xf;
7107 if (is64) {
7108 crn = 0;
7109 opc1 = (insn >> 4) & 0xf;
7110 opc2 = 0;
7111 rt2 = (insn >> 16) & 0xf;
7112 } else {
7113 crn = (insn >> 16) & 0xf;
7114 opc1 = (insn >> 21) & 7;
7115 opc2 = (insn >> 5) & 7;
7116 rt2 = 0;
7118 isread = (insn >> 20) & 1;
7119 rt = (insn >> 12) & 0xf;
7121 ri = get_arm_cp_reginfo(s->cp_regs,
7122 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7123 if (ri) {
7124 /* Check access permissions */
7125 if (!cp_access_ok(s->current_el, ri, isread)) {
7126 return 1;
7129 if (ri->accessfn ||
7130 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7131 /* Emit code to perform further access permissions checks at
7132 * runtime; this may result in an exception.
7133 * Note that on XScale all cp0..c13 registers do an access check
7134 * call in order to handle c15_cpar.
7136 TCGv_ptr tmpptr;
7137 TCGv_i32 tcg_syn;
7138 uint32_t syndrome;
7140 /* Note that since we are an implementation which takes an
7141 * exception on a trapped conditional instruction only if the
7142 * instruction passes its condition code check, we can take
7143 * advantage of the clause in the ARM ARM that allows us to set
7144 * the COND field in the instruction to 0xE in all cases.
7145 * We could fish the actual condition out of the insn (ARM)
7146 * or the condexec bits (Thumb) but it isn't necessary.
7148 switch (cpnum) {
7149 case 14:
7150 if (is64) {
7151 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7152 isread, s->thumb);
7153 } else {
7154 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7155 rt, isread, s->thumb);
7157 break;
7158 case 15:
7159 if (is64) {
7160 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7161 isread, s->thumb);
7162 } else {
7163 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7164 rt, isread, s->thumb);
7166 break;
7167 default:
7168 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7169 * so this can only happen if this is an ARMv7 or earlier CPU,
7170 * in which case the syndrome information won't actually be
7171 * guest visible.
7173 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7174 syndrome = syn_uncategorized();
7175 break;
7178 gen_set_pc_im(s, s->pc - 4);
7179 tmpptr = tcg_const_ptr(ri);
7180 tcg_syn = tcg_const_i32(syndrome);
7181 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
7182 tcg_temp_free_ptr(tmpptr);
7183 tcg_temp_free_i32(tcg_syn);
7186 /* Handle special cases first */
7187 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7188 case ARM_CP_NOP:
7189 return 0;
7190 case ARM_CP_WFI:
7191 if (isread) {
7192 return 1;
7194 gen_set_pc_im(s, s->pc);
7195 s->is_jmp = DISAS_WFI;
7196 return 0;
7197 default:
7198 break;
7201 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7202 gen_io_start();
7205 if (isread) {
7206 /* Read */
7207 if (is64) {
7208 TCGv_i64 tmp64;
7209 TCGv_i32 tmp;
7210 if (ri->type & ARM_CP_CONST) {
7211 tmp64 = tcg_const_i64(ri->resetvalue);
7212 } else if (ri->readfn) {
7213 TCGv_ptr tmpptr;
7214 tmp64 = tcg_temp_new_i64();
7215 tmpptr = tcg_const_ptr(ri);
7216 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7217 tcg_temp_free_ptr(tmpptr);
7218 } else {
7219 tmp64 = tcg_temp_new_i64();
7220 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7222 tmp = tcg_temp_new_i32();
7223 tcg_gen_trunc_i64_i32(tmp, tmp64);
7224 store_reg(s, rt, tmp);
7225 tcg_gen_shri_i64(tmp64, tmp64, 32);
7226 tmp = tcg_temp_new_i32();
7227 tcg_gen_trunc_i64_i32(tmp, tmp64);
7228 tcg_temp_free_i64(tmp64);
7229 store_reg(s, rt2, tmp);
7230 } else {
7231 TCGv_i32 tmp;
7232 if (ri->type & ARM_CP_CONST) {
7233 tmp = tcg_const_i32(ri->resetvalue);
7234 } else if (ri->readfn) {
7235 TCGv_ptr tmpptr;
7236 tmp = tcg_temp_new_i32();
7237 tmpptr = tcg_const_ptr(ri);
7238 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7239 tcg_temp_free_ptr(tmpptr);
7240 } else {
7241 tmp = load_cpu_offset(ri->fieldoffset);
7243 if (rt == 15) {
7244 /* Destination register of r15 for 32 bit loads sets
7245 * the condition codes from the high 4 bits of the value
7247 gen_set_nzcv(tmp);
7248 tcg_temp_free_i32(tmp);
7249 } else {
7250 store_reg(s, rt, tmp);
7253 } else {
7254 /* Write */
7255 if (ri->type & ARM_CP_CONST) {
7256 /* If not forbidden by access permissions, treat as WI */
7257 return 0;
7260 if (is64) {
7261 TCGv_i32 tmplo, tmphi;
7262 TCGv_i64 tmp64 = tcg_temp_new_i64();
7263 tmplo = load_reg(s, rt);
7264 tmphi = load_reg(s, rt2);
7265 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7266 tcg_temp_free_i32(tmplo);
7267 tcg_temp_free_i32(tmphi);
7268 if (ri->writefn) {
7269 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7270 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7271 tcg_temp_free_ptr(tmpptr);
7272 } else {
7273 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7275 tcg_temp_free_i64(tmp64);
7276 } else {
7277 if (ri->writefn) {
7278 TCGv_i32 tmp;
7279 TCGv_ptr tmpptr;
7280 tmp = load_reg(s, rt);
7281 tmpptr = tcg_const_ptr(ri);
7282 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7283 tcg_temp_free_ptr(tmpptr);
7284 tcg_temp_free_i32(tmp);
7285 } else {
7286 TCGv_i32 tmp = load_reg(s, rt);
7287 store_cpu_offset(tmp, ri->fieldoffset);
7292 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7293 /* I/O operations must end the TB here (whether read or write) */
7294 gen_io_end();
7295 gen_lookup_tb(s);
7296 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7297 /* We default to ending the TB on a coprocessor register write,
7298 * but allow this to be suppressed by the register definition
7299 * (usually only necessary to work around guest bugs).
7301 gen_lookup_tb(s);
7304 return 0;
7307 /* Unknown register; this might be a guest error or a QEMU
7308 * unimplemented feature.
7310 if (is64) {
7311 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7312 "64 bit system register cp:%d opc1: %d crm:%d "
7313 "(%s)\n",
7314 isread ? "read" : "write", cpnum, opc1, crm,
7315 s->ns ? "non-secure" : "secure");
7316 } else {
7317 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7318 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7319 "(%s)\n",
7320 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7321 s->ns ? "non-secure" : "secure");
7324 return 1;
7328 /* Store a 64-bit value to a register pair. Clobbers val. */
7329 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7331 TCGv_i32 tmp;
7332 tmp = tcg_temp_new_i32();
7333 tcg_gen_trunc_i64_i32(tmp, val);
7334 store_reg(s, rlow, tmp);
7335 tmp = tcg_temp_new_i32();
7336 tcg_gen_shri_i64(val, val, 32);
7337 tcg_gen_trunc_i64_i32(tmp, val);
7338 store_reg(s, rhigh, tmp);
7341 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7342 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7344 TCGv_i64 tmp;
7345 TCGv_i32 tmp2;
7347 /* Load value and extend to 64 bits. */
7348 tmp = tcg_temp_new_i64();
7349 tmp2 = load_reg(s, rlow);
7350 tcg_gen_extu_i32_i64(tmp, tmp2);
7351 tcg_temp_free_i32(tmp2);
7352 tcg_gen_add_i64(val, val, tmp);
7353 tcg_temp_free_i64(tmp);
7356 /* load and add a 64-bit value from a register pair. */
7357 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7359 TCGv_i64 tmp;
7360 TCGv_i32 tmpl;
7361 TCGv_i32 tmph;
7363 /* Load 64-bit value rd:rn. */
7364 tmpl = load_reg(s, rlow);
7365 tmph = load_reg(s, rhigh);
7366 tmp = tcg_temp_new_i64();
7367 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7368 tcg_temp_free_i32(tmpl);
7369 tcg_temp_free_i32(tmph);
7370 tcg_gen_add_i64(val, val, tmp);
7371 tcg_temp_free_i64(tmp);
7374 /* Set N and Z flags from hi|lo. */
7375 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7377 tcg_gen_mov_i32(cpu_NF, hi);
7378 tcg_gen_or_i32(cpu_ZF, lo, hi);
7381 /* Load/Store exclusive instructions are implemented by remembering
7382 the value/address loaded, and seeing if these are the same
7383 when the store is performed. This should be sufficient to implement
7384 the architecturally mandated semantics, and avoids having to monitor
7385 regular stores.
7387 In system emulation mode only one CPU will be running at once, so
7388 this sequence is effectively atomic. In user emulation mode we
7389 throw an exception and handle the atomic operation elsewhere. */
7390 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7391 TCGv_i32 addr, int size)
7393 TCGv_i32 tmp = tcg_temp_new_i32();
7395 s->is_ldex = true;
7397 switch (size) {
7398 case 0:
7399 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7400 break;
7401 case 1:
7402 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7403 break;
7404 case 2:
7405 case 3:
7406 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7407 break;
7408 default:
7409 abort();
7412 if (size == 3) {
7413 TCGv_i32 tmp2 = tcg_temp_new_i32();
7414 TCGv_i32 tmp3 = tcg_temp_new_i32();
7416 tcg_gen_addi_i32(tmp2, addr, 4);
7417 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7418 tcg_temp_free_i32(tmp2);
7419 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7420 store_reg(s, rt2, tmp3);
7421 } else {
7422 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7425 store_reg(s, rt, tmp);
7426 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7429 static void gen_clrex(DisasContext *s)
7431 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7434 #ifdef CONFIG_USER_ONLY
7435 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7436 TCGv_i32 addr, int size)
7438 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7439 tcg_gen_movi_i32(cpu_exclusive_info,
7440 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7441 gen_exception_internal_insn(s, 4, EXCP_STREX);
7443 #else
7444 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7445 TCGv_i32 addr, int size)
7447 TCGv_i32 tmp;
7448 TCGv_i64 val64, extaddr;
7449 TCGLabel *done_label;
7450 TCGLabel *fail_label;
7452 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7453 [addr] = {Rt};
7454 {Rd} = 0;
7455 } else {
7456 {Rd} = 1;
7457 } */
7458 fail_label = gen_new_label();
7459 done_label = gen_new_label();
7460 extaddr = tcg_temp_new_i64();
7461 tcg_gen_extu_i32_i64(extaddr, addr);
7462 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7463 tcg_temp_free_i64(extaddr);
7465 tmp = tcg_temp_new_i32();
7466 switch (size) {
7467 case 0:
7468 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7469 break;
7470 case 1:
7471 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7472 break;
7473 case 2:
7474 case 3:
7475 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7476 break;
7477 default:
7478 abort();
7481 val64 = tcg_temp_new_i64();
7482 if (size == 3) {
7483 TCGv_i32 tmp2 = tcg_temp_new_i32();
7484 TCGv_i32 tmp3 = tcg_temp_new_i32();
7485 tcg_gen_addi_i32(tmp2, addr, 4);
7486 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7487 tcg_temp_free_i32(tmp2);
7488 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7489 tcg_temp_free_i32(tmp3);
7490 } else {
7491 tcg_gen_extu_i32_i64(val64, tmp);
7493 tcg_temp_free_i32(tmp);
7495 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7496 tcg_temp_free_i64(val64);
7498 tmp = load_reg(s, rt);
7499 switch (size) {
7500 case 0:
7501 gen_aa32_st8(tmp, addr, get_mem_index(s));
7502 break;
7503 case 1:
7504 gen_aa32_st16(tmp, addr, get_mem_index(s));
7505 break;
7506 case 2:
7507 case 3:
7508 gen_aa32_st32(tmp, addr, get_mem_index(s));
7509 break;
7510 default:
7511 abort();
7513 tcg_temp_free_i32(tmp);
7514 if (size == 3) {
7515 tcg_gen_addi_i32(addr, addr, 4);
7516 tmp = load_reg(s, rt2);
7517 gen_aa32_st32(tmp, addr, get_mem_index(s));
7518 tcg_temp_free_i32(tmp);
7520 tcg_gen_movi_i32(cpu_R[rd], 0);
7521 tcg_gen_br(done_label);
7522 gen_set_label(fail_label);
7523 tcg_gen_movi_i32(cpu_R[rd], 1);
7524 gen_set_label(done_label);
7525 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7527 #endif
7529 /* gen_srs:
7530 * @env: CPUARMState
7531 * @s: DisasContext
7532 * @mode: mode field from insn (which stack to store to)
7533 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7534 * @writeback: true if writeback bit set
7536 * Generate code for the SRS (Store Return State) insn.
7538 static void gen_srs(DisasContext *s,
7539 uint32_t mode, uint32_t amode, bool writeback)
7541 int32_t offset;
7542 TCGv_i32 addr = tcg_temp_new_i32();
7543 TCGv_i32 tmp = tcg_const_i32(mode);
7544 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7545 tcg_temp_free_i32(tmp);
7546 switch (amode) {
7547 case 0: /* DA */
7548 offset = -4;
7549 break;
7550 case 1: /* IA */
7551 offset = 0;
7552 break;
7553 case 2: /* DB */
7554 offset = -8;
7555 break;
7556 case 3: /* IB */
7557 offset = 4;
7558 break;
7559 default:
7560 abort();
7562 tcg_gen_addi_i32(addr, addr, offset);
7563 tmp = load_reg(s, 14);
7564 gen_aa32_st32(tmp, addr, get_mem_index(s));
7565 tcg_temp_free_i32(tmp);
7566 tmp = load_cpu_field(spsr);
7567 tcg_gen_addi_i32(addr, addr, 4);
7568 gen_aa32_st32(tmp, addr, get_mem_index(s));
7569 tcg_temp_free_i32(tmp);
7570 if (writeback) {
7571 switch (amode) {
7572 case 0:
7573 offset = -8;
7574 break;
7575 case 1:
7576 offset = 4;
7577 break;
7578 case 2:
7579 offset = -4;
7580 break;
7581 case 3:
7582 offset = 0;
7583 break;
7584 default:
7585 abort();
7587 tcg_gen_addi_i32(addr, addr, offset);
7588 tmp = tcg_const_i32(mode);
7589 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7590 tcg_temp_free_i32(tmp);
7592 tcg_temp_free_i32(addr);
7595 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7597 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7598 TCGv_i32 tmp;
7599 TCGv_i32 tmp2;
7600 TCGv_i32 tmp3;
7601 TCGv_i32 addr;
7602 TCGv_i64 tmp64;
7604 /* M variants do not implement ARM mode. */
7605 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7606 goto illegal_op;
7608 cond = insn >> 28;
7609 if (cond == 0xf){
7610 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7611 * choose to UNDEF. In ARMv5 and above the space is used
7612 * for miscellaneous unconditional instructions.
7614 ARCH(5);
7616 /* Unconditional instructions. */
7617 if (((insn >> 25) & 7) == 1) {
7618 /* NEON Data processing. */
7619 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7620 goto illegal_op;
7623 if (disas_neon_data_insn(s, insn)) {
7624 goto illegal_op;
7626 return;
7628 if ((insn & 0x0f100000) == 0x04000000) {
7629 /* NEON load/store. */
7630 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7631 goto illegal_op;
7634 if (disas_neon_ls_insn(s, insn)) {
7635 goto illegal_op;
7637 return;
7639 if ((insn & 0x0f000e10) == 0x0e000a00) {
7640 /* VFP. */
7641 if (disas_vfp_insn(s, insn)) {
7642 goto illegal_op;
7644 return;
7646 if (((insn & 0x0f30f000) == 0x0510f000) ||
7647 ((insn & 0x0f30f010) == 0x0710f000)) {
7648 if ((insn & (1 << 22)) == 0) {
7649 /* PLDW; v7MP */
7650 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7651 goto illegal_op;
7654 /* Otherwise PLD; v5TE+ */
7655 ARCH(5TE);
7656 return;
7658 if (((insn & 0x0f70f000) == 0x0450f000) ||
7659 ((insn & 0x0f70f010) == 0x0650f000)) {
7660 ARCH(7);
7661 return; /* PLI; V7 */
7663 if (((insn & 0x0f700000) == 0x04100000) ||
7664 ((insn & 0x0f700010) == 0x06100000)) {
7665 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7666 goto illegal_op;
7668 return; /* v7MP: Unallocated memory hint: must NOP */
7671 if ((insn & 0x0ffffdff) == 0x01010000) {
7672 ARCH(6);
7673 /* setend */
7674 if (((insn >> 9) & 1) != s->bswap_code) {
7675 /* Dynamic endianness switching not implemented. */
7676 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7677 goto illegal_op;
7679 return;
7680 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7681 switch ((insn >> 4) & 0xf) {
7682 case 1: /* clrex */
7683 ARCH(6K);
7684 gen_clrex(s);
7685 return;
7686 case 4: /* dsb */
7687 case 5: /* dmb */
7688 case 6: /* isb */
7689 ARCH(7);
7690 /* We don't emulate caches so these are a no-op. */
7691 return;
7692 default:
7693 goto illegal_op;
7695 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7696 /* srs */
7697 if (IS_USER(s)) {
7698 goto illegal_op;
7700 ARCH(6);
7701 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7702 return;
7703 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7704 /* rfe */
7705 int32_t offset;
7706 if (IS_USER(s))
7707 goto illegal_op;
7708 ARCH(6);
7709 rn = (insn >> 16) & 0xf;
7710 addr = load_reg(s, rn);
7711 i = (insn >> 23) & 3;
7712 switch (i) {
7713 case 0: offset = -4; break; /* DA */
7714 case 1: offset = 0; break; /* IA */
7715 case 2: offset = -8; break; /* DB */
7716 case 3: offset = 4; break; /* IB */
7717 default: abort();
7719 if (offset)
7720 tcg_gen_addi_i32(addr, addr, offset);
7721 /* Load PC into tmp and CPSR into tmp2. */
7722 tmp = tcg_temp_new_i32();
7723 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7724 tcg_gen_addi_i32(addr, addr, 4);
7725 tmp2 = tcg_temp_new_i32();
7726 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
7727 if (insn & (1 << 21)) {
7728 /* Base writeback. */
7729 switch (i) {
7730 case 0: offset = -8; break;
7731 case 1: offset = 4; break;
7732 case 2: offset = -4; break;
7733 case 3: offset = 0; break;
7734 default: abort();
7736 if (offset)
7737 tcg_gen_addi_i32(addr, addr, offset);
7738 store_reg(s, rn, addr);
7739 } else {
7740 tcg_temp_free_i32(addr);
7742 gen_rfe(s, tmp, tmp2);
7743 return;
7744 } else if ((insn & 0x0e000000) == 0x0a000000) {
7745 /* branch link and change to thumb (blx <offset>) */
7746 int32_t offset;
7748 val = (uint32_t)s->pc;
7749 tmp = tcg_temp_new_i32();
7750 tcg_gen_movi_i32(tmp, val);
7751 store_reg(s, 14, tmp);
7752 /* Sign-extend the 24-bit offset */
7753 offset = (((int32_t)insn) << 8) >> 8;
7754 /* offset * 4 + bit24 * 2 + (thumb bit) */
7755 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7756 /* pipeline offset */
7757 val += 4;
7758 /* protected by ARCH(5); above, near the start of uncond block */
7759 gen_bx_im(s, val);
7760 return;
7761 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7762 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7763 /* iWMMXt register transfer. */
7764 if (extract32(s->c15_cpar, 1, 1)) {
7765 if (!disas_iwmmxt_insn(s, insn)) {
7766 return;
7770 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7771 /* Coprocessor double register transfer. */
7772 ARCH(5TE);
7773 } else if ((insn & 0x0f000010) == 0x0e000010) {
7774 /* Additional coprocessor register transfer. */
7775 } else if ((insn & 0x0ff10020) == 0x01000000) {
7776 uint32_t mask;
7777 uint32_t val;
7778 /* cps (privileged) */
7779 if (IS_USER(s))
7780 return;
7781 mask = val = 0;
7782 if (insn & (1 << 19)) {
7783 if (insn & (1 << 8))
7784 mask |= CPSR_A;
7785 if (insn & (1 << 7))
7786 mask |= CPSR_I;
7787 if (insn & (1 << 6))
7788 mask |= CPSR_F;
7789 if (insn & (1 << 18))
7790 val |= mask;
7792 if (insn & (1 << 17)) {
7793 mask |= CPSR_M;
7794 val |= (insn & 0x1f);
7796 if (mask) {
7797 gen_set_psr_im(s, mask, 0, val);
7799 return;
7801 goto illegal_op;
7803 if (cond != 0xe) {
7804 /* if not always execute, we generate a conditional jump to
7805 next instruction */
7806 s->condlabel = gen_new_label();
7807 arm_gen_test_cc(cond ^ 1, s->condlabel);
7808 s->condjmp = 1;
7810 if ((insn & 0x0f900000) == 0x03000000) {
7811 if ((insn & (1 << 21)) == 0) {
7812 ARCH(6T2);
7813 rd = (insn >> 12) & 0xf;
7814 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7815 if ((insn & (1 << 22)) == 0) {
7816 /* MOVW */
7817 tmp = tcg_temp_new_i32();
7818 tcg_gen_movi_i32(tmp, val);
7819 } else {
7820 /* MOVT */
7821 tmp = load_reg(s, rd);
7822 tcg_gen_ext16u_i32(tmp, tmp);
7823 tcg_gen_ori_i32(tmp, tmp, val << 16);
7825 store_reg(s, rd, tmp);
7826 } else {
7827 if (((insn >> 12) & 0xf) != 0xf)
7828 goto illegal_op;
7829 if (((insn >> 16) & 0xf) == 0) {
7830 gen_nop_hint(s, insn & 0xff);
7831 } else {
7832 /* CPSR = immediate */
7833 val = insn & 0xff;
7834 shift = ((insn >> 8) & 0xf) * 2;
7835 if (shift)
7836 val = (val >> shift) | (val << (32 - shift));
7837 i = ((insn & (1 << 22)) != 0);
7838 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7839 i, val)) {
7840 goto illegal_op;
7844 } else if ((insn & 0x0f900000) == 0x01000000
7845 && (insn & 0x00000090) != 0x00000090) {
7846 /* miscellaneous instructions */
7847 op1 = (insn >> 21) & 3;
7848 sh = (insn >> 4) & 0xf;
7849 rm = insn & 0xf;
7850 switch (sh) {
7851 case 0x0: /* move program status register */
7852 if (op1 & 1) {
7853 /* PSR = reg */
7854 tmp = load_reg(s, rm);
7855 i = ((op1 & 2) != 0);
7856 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7857 goto illegal_op;
7858 } else {
7859 /* reg = PSR */
7860 rd = (insn >> 12) & 0xf;
7861 if (op1 & 2) {
7862 if (IS_USER(s))
7863 goto illegal_op;
7864 tmp = load_cpu_field(spsr);
7865 } else {
7866 tmp = tcg_temp_new_i32();
7867 gen_helper_cpsr_read(tmp, cpu_env);
7869 store_reg(s, rd, tmp);
7871 break;
7872 case 0x1:
7873 if (op1 == 1) {
7874 /* branch/exchange thumb (bx). */
7875 ARCH(4T);
7876 tmp = load_reg(s, rm);
7877 gen_bx(s, tmp);
7878 } else if (op1 == 3) {
7879 /* clz */
7880 ARCH(5);
7881 rd = (insn >> 12) & 0xf;
7882 tmp = load_reg(s, rm);
7883 gen_helper_clz(tmp, tmp);
7884 store_reg(s, rd, tmp);
7885 } else {
7886 goto illegal_op;
7888 break;
7889 case 0x2:
7890 if (op1 == 1) {
7891 ARCH(5J); /* bxj */
7892 /* Trivial implementation equivalent to bx. */
7893 tmp = load_reg(s, rm);
7894 gen_bx(s, tmp);
7895 } else {
7896 goto illegal_op;
7898 break;
7899 case 0x3:
7900 if (op1 != 1)
7901 goto illegal_op;
7903 ARCH(5);
7904 /* branch link/exchange thumb (blx) */
7905 tmp = load_reg(s, rm);
7906 tmp2 = tcg_temp_new_i32();
7907 tcg_gen_movi_i32(tmp2, s->pc);
7908 store_reg(s, 14, tmp2);
7909 gen_bx(s, tmp);
7910 break;
7911 case 0x4:
7913 /* crc32/crc32c */
7914 uint32_t c = extract32(insn, 8, 4);
7916 /* Check this CPU supports ARMv8 CRC instructions.
7917 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7918 * Bits 8, 10 and 11 should be zero.
7920 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
7921 (c & 0xd) != 0) {
7922 goto illegal_op;
7925 rn = extract32(insn, 16, 4);
7926 rd = extract32(insn, 12, 4);
7928 tmp = load_reg(s, rn);
7929 tmp2 = load_reg(s, rm);
7930 if (op1 == 0) {
7931 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
7932 } else if (op1 == 1) {
7933 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
7935 tmp3 = tcg_const_i32(1 << op1);
7936 if (c & 0x2) {
7937 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7938 } else {
7939 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7941 tcg_temp_free_i32(tmp2);
7942 tcg_temp_free_i32(tmp3);
7943 store_reg(s, rd, tmp);
7944 break;
7946 case 0x5: /* saturating add/subtract */
7947 ARCH(5TE);
7948 rd = (insn >> 12) & 0xf;
7949 rn = (insn >> 16) & 0xf;
7950 tmp = load_reg(s, rm);
7951 tmp2 = load_reg(s, rn);
7952 if (op1 & 2)
7953 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7954 if (op1 & 1)
7955 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7956 else
7957 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7958 tcg_temp_free_i32(tmp2);
7959 store_reg(s, rd, tmp);
7960 break;
7961 case 7:
7963 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
7964 switch (op1) {
7965 case 1:
7966 /* bkpt */
7967 ARCH(5);
7968 gen_exception_insn(s, 4, EXCP_BKPT,
7969 syn_aa32_bkpt(imm16, false),
7970 default_exception_el(s));
7971 break;
7972 case 2:
7973 /* Hypervisor call (v7) */
7974 ARCH(7);
7975 if (IS_USER(s)) {
7976 goto illegal_op;
7978 gen_hvc(s, imm16);
7979 break;
7980 case 3:
7981 /* Secure monitor call (v6+) */
7982 ARCH(6K);
7983 if (IS_USER(s)) {
7984 goto illegal_op;
7986 gen_smc(s);
7987 break;
7988 default:
7989 goto illegal_op;
7991 break;
7993 case 0x8: /* signed multiply */
7994 case 0xa:
7995 case 0xc:
7996 case 0xe:
7997 ARCH(5TE);
7998 rs = (insn >> 8) & 0xf;
7999 rn = (insn >> 12) & 0xf;
8000 rd = (insn >> 16) & 0xf;
8001 if (op1 == 1) {
8002 /* (32 * 16) >> 16 */
8003 tmp = load_reg(s, rm);
8004 tmp2 = load_reg(s, rs);
8005 if (sh & 4)
8006 tcg_gen_sari_i32(tmp2, tmp2, 16);
8007 else
8008 gen_sxth(tmp2);
8009 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8010 tcg_gen_shri_i64(tmp64, tmp64, 16);
8011 tmp = tcg_temp_new_i32();
8012 tcg_gen_trunc_i64_i32(tmp, tmp64);
8013 tcg_temp_free_i64(tmp64);
8014 if ((sh & 2) == 0) {
8015 tmp2 = load_reg(s, rn);
8016 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8017 tcg_temp_free_i32(tmp2);
8019 store_reg(s, rd, tmp);
8020 } else {
8021 /* 16 * 16 */
8022 tmp = load_reg(s, rm);
8023 tmp2 = load_reg(s, rs);
8024 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8025 tcg_temp_free_i32(tmp2);
8026 if (op1 == 2) {
8027 tmp64 = tcg_temp_new_i64();
8028 tcg_gen_ext_i32_i64(tmp64, tmp);
8029 tcg_temp_free_i32(tmp);
8030 gen_addq(s, tmp64, rn, rd);
8031 gen_storeq_reg(s, rn, rd, tmp64);
8032 tcg_temp_free_i64(tmp64);
8033 } else {
8034 if (op1 == 0) {
8035 tmp2 = load_reg(s, rn);
8036 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8037 tcg_temp_free_i32(tmp2);
8039 store_reg(s, rd, tmp);
8042 break;
8043 default:
8044 goto illegal_op;
8046 } else if (((insn & 0x0e000000) == 0 &&
8047 (insn & 0x00000090) != 0x90) ||
8048 ((insn & 0x0e000000) == (1 << 25))) {
8049 int set_cc, logic_cc, shiftop;
8051 op1 = (insn >> 21) & 0xf;
8052 set_cc = (insn >> 20) & 1;
8053 logic_cc = table_logic_cc[op1] & set_cc;
8055 /* data processing instruction */
8056 if (insn & (1 << 25)) {
8057 /* immediate operand */
8058 val = insn & 0xff;
8059 shift = ((insn >> 8) & 0xf) * 2;
8060 if (shift) {
8061 val = (val >> shift) | (val << (32 - shift));
8063 tmp2 = tcg_temp_new_i32();
8064 tcg_gen_movi_i32(tmp2, val);
8065 if (logic_cc && shift) {
8066 gen_set_CF_bit31(tmp2);
8068 } else {
8069 /* register */
8070 rm = (insn) & 0xf;
8071 tmp2 = load_reg(s, rm);
8072 shiftop = (insn >> 5) & 3;
8073 if (!(insn & (1 << 4))) {
8074 shift = (insn >> 7) & 0x1f;
8075 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8076 } else {
8077 rs = (insn >> 8) & 0xf;
8078 tmp = load_reg(s, rs);
8079 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8082 if (op1 != 0x0f && op1 != 0x0d) {
8083 rn = (insn >> 16) & 0xf;
8084 tmp = load_reg(s, rn);
8085 } else {
8086 TCGV_UNUSED_I32(tmp);
8088 rd = (insn >> 12) & 0xf;
8089 switch(op1) {
8090 case 0x00:
8091 tcg_gen_and_i32(tmp, tmp, tmp2);
8092 if (logic_cc) {
8093 gen_logic_CC(tmp);
8095 store_reg_bx(s, rd, tmp);
8096 break;
8097 case 0x01:
8098 tcg_gen_xor_i32(tmp, tmp, tmp2);
8099 if (logic_cc) {
8100 gen_logic_CC(tmp);
8102 store_reg_bx(s, rd, tmp);
8103 break;
8104 case 0x02:
8105 if (set_cc && rd == 15) {
8106 /* SUBS r15, ... is used for exception return. */
8107 if (IS_USER(s)) {
8108 goto illegal_op;
8110 gen_sub_CC(tmp, tmp, tmp2);
8111 gen_exception_return(s, tmp);
8112 } else {
8113 if (set_cc) {
8114 gen_sub_CC(tmp, tmp, tmp2);
8115 } else {
8116 tcg_gen_sub_i32(tmp, tmp, tmp2);
8118 store_reg_bx(s, rd, tmp);
8120 break;
8121 case 0x03:
8122 if (set_cc) {
8123 gen_sub_CC(tmp, tmp2, tmp);
8124 } else {
8125 tcg_gen_sub_i32(tmp, tmp2, tmp);
8127 store_reg_bx(s, rd, tmp);
8128 break;
8129 case 0x04:
8130 if (set_cc) {
8131 gen_add_CC(tmp, tmp, tmp2);
8132 } else {
8133 tcg_gen_add_i32(tmp, tmp, tmp2);
8135 store_reg_bx(s, rd, tmp);
8136 break;
8137 case 0x05:
8138 if (set_cc) {
8139 gen_adc_CC(tmp, tmp, tmp2);
8140 } else {
8141 gen_add_carry(tmp, tmp, tmp2);
8143 store_reg_bx(s, rd, tmp);
8144 break;
8145 case 0x06:
8146 if (set_cc) {
8147 gen_sbc_CC(tmp, tmp, tmp2);
8148 } else {
8149 gen_sub_carry(tmp, tmp, tmp2);
8151 store_reg_bx(s, rd, tmp);
8152 break;
8153 case 0x07:
8154 if (set_cc) {
8155 gen_sbc_CC(tmp, tmp2, tmp);
8156 } else {
8157 gen_sub_carry(tmp, tmp2, tmp);
8159 store_reg_bx(s, rd, tmp);
8160 break;
8161 case 0x08:
8162 if (set_cc) {
8163 tcg_gen_and_i32(tmp, tmp, tmp2);
8164 gen_logic_CC(tmp);
8166 tcg_temp_free_i32(tmp);
8167 break;
8168 case 0x09:
8169 if (set_cc) {
8170 tcg_gen_xor_i32(tmp, tmp, tmp2);
8171 gen_logic_CC(tmp);
8173 tcg_temp_free_i32(tmp);
8174 break;
8175 case 0x0a:
8176 if (set_cc) {
8177 gen_sub_CC(tmp, tmp, tmp2);
8179 tcg_temp_free_i32(tmp);
8180 break;
8181 case 0x0b:
8182 if (set_cc) {
8183 gen_add_CC(tmp, tmp, tmp2);
8185 tcg_temp_free_i32(tmp);
8186 break;
8187 case 0x0c:
8188 tcg_gen_or_i32(tmp, tmp, tmp2);
8189 if (logic_cc) {
8190 gen_logic_CC(tmp);
8192 store_reg_bx(s, rd, tmp);
8193 break;
8194 case 0x0d:
8195 if (logic_cc && rd == 15) {
8196 /* MOVS r15, ... is used for exception return. */
8197 if (IS_USER(s)) {
8198 goto illegal_op;
8200 gen_exception_return(s, tmp2);
8201 } else {
8202 if (logic_cc) {
8203 gen_logic_CC(tmp2);
8205 store_reg_bx(s, rd, tmp2);
8207 break;
8208 case 0x0e:
8209 tcg_gen_andc_i32(tmp, tmp, tmp2);
8210 if (logic_cc) {
8211 gen_logic_CC(tmp);
8213 store_reg_bx(s, rd, tmp);
8214 break;
8215 default:
8216 case 0x0f:
8217 tcg_gen_not_i32(tmp2, tmp2);
8218 if (logic_cc) {
8219 gen_logic_CC(tmp2);
8221 store_reg_bx(s, rd, tmp2);
8222 break;
8224 if (op1 != 0x0f && op1 != 0x0d) {
8225 tcg_temp_free_i32(tmp2);
8227 } else {
8228 /* other instructions */
8229 op1 = (insn >> 24) & 0xf;
8230 switch(op1) {
8231 case 0x0:
8232 case 0x1:
8233 /* multiplies, extra load/stores */
8234 sh = (insn >> 5) & 3;
8235 if (sh == 0) {
8236 if (op1 == 0x0) {
8237 rd = (insn >> 16) & 0xf;
8238 rn = (insn >> 12) & 0xf;
8239 rs = (insn >> 8) & 0xf;
8240 rm = (insn) & 0xf;
8241 op1 = (insn >> 20) & 0xf;
8242 switch (op1) {
8243 case 0: case 1: case 2: case 3: case 6:
8244 /* 32 bit mul */
8245 tmp = load_reg(s, rs);
8246 tmp2 = load_reg(s, rm);
8247 tcg_gen_mul_i32(tmp, tmp, tmp2);
8248 tcg_temp_free_i32(tmp2);
8249 if (insn & (1 << 22)) {
8250 /* Subtract (mls) */
8251 ARCH(6T2);
8252 tmp2 = load_reg(s, rn);
8253 tcg_gen_sub_i32(tmp, tmp2, tmp);
8254 tcg_temp_free_i32(tmp2);
8255 } else if (insn & (1 << 21)) {
8256 /* Add */
8257 tmp2 = load_reg(s, rn);
8258 tcg_gen_add_i32(tmp, tmp, tmp2);
8259 tcg_temp_free_i32(tmp2);
8261 if (insn & (1 << 20))
8262 gen_logic_CC(tmp);
8263 store_reg(s, rd, tmp);
8264 break;
8265 case 4:
8266 /* 64 bit mul double accumulate (UMAAL) */
8267 ARCH(6);
8268 tmp = load_reg(s, rs);
8269 tmp2 = load_reg(s, rm);
8270 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8271 gen_addq_lo(s, tmp64, rn);
8272 gen_addq_lo(s, tmp64, rd);
8273 gen_storeq_reg(s, rn, rd, tmp64);
8274 tcg_temp_free_i64(tmp64);
8275 break;
8276 case 8: case 9: case 10: case 11:
8277 case 12: case 13: case 14: case 15:
8278 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8279 tmp = load_reg(s, rs);
8280 tmp2 = load_reg(s, rm);
8281 if (insn & (1 << 22)) {
8282 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8283 } else {
8284 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8286 if (insn & (1 << 21)) { /* mult accumulate */
8287 TCGv_i32 al = load_reg(s, rn);
8288 TCGv_i32 ah = load_reg(s, rd);
8289 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8290 tcg_temp_free_i32(al);
8291 tcg_temp_free_i32(ah);
8293 if (insn & (1 << 20)) {
8294 gen_logicq_cc(tmp, tmp2);
8296 store_reg(s, rn, tmp);
8297 store_reg(s, rd, tmp2);
8298 break;
8299 default:
8300 goto illegal_op;
8302 } else {
8303 rn = (insn >> 16) & 0xf;
8304 rd = (insn >> 12) & 0xf;
8305 if (insn & (1 << 23)) {
8306 /* load/store exclusive */
8307 int op2 = (insn >> 8) & 3;
8308 op1 = (insn >> 21) & 0x3;
8310 switch (op2) {
8311 case 0: /* lda/stl */
8312 if (op1 == 1) {
8313 goto illegal_op;
8315 ARCH(8);
8316 break;
8317 case 1: /* reserved */
8318 goto illegal_op;
8319 case 2: /* ldaex/stlex */
8320 ARCH(8);
8321 break;
8322 case 3: /* ldrex/strex */
8323 if (op1) {
8324 ARCH(6K);
8325 } else {
8326 ARCH(6);
8328 break;
8331 addr = tcg_temp_local_new_i32();
8332 load_reg_var(s, addr, rn);
8334 /* Since the emulation does not have barriers,
8335 the acquire/release semantics need no special
8336 handling */
8337 if (op2 == 0) {
8338 if (insn & (1 << 20)) {
8339 tmp = tcg_temp_new_i32();
8340 switch (op1) {
8341 case 0: /* lda */
8342 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8343 break;
8344 case 2: /* ldab */
8345 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
8346 break;
8347 case 3: /* ldah */
8348 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8349 break;
8350 default:
8351 abort();
8353 store_reg(s, rd, tmp);
8354 } else {
8355 rm = insn & 0xf;
8356 tmp = load_reg(s, rm);
8357 switch (op1) {
8358 case 0: /* stl */
8359 gen_aa32_st32(tmp, addr, get_mem_index(s));
8360 break;
8361 case 2: /* stlb */
8362 gen_aa32_st8(tmp, addr, get_mem_index(s));
8363 break;
8364 case 3: /* stlh */
8365 gen_aa32_st16(tmp, addr, get_mem_index(s));
8366 break;
8367 default:
8368 abort();
8370 tcg_temp_free_i32(tmp);
8372 } else if (insn & (1 << 20)) {
8373 switch (op1) {
8374 case 0: /* ldrex */
8375 gen_load_exclusive(s, rd, 15, addr, 2);
8376 break;
8377 case 1: /* ldrexd */
8378 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8379 break;
8380 case 2: /* ldrexb */
8381 gen_load_exclusive(s, rd, 15, addr, 0);
8382 break;
8383 case 3: /* ldrexh */
8384 gen_load_exclusive(s, rd, 15, addr, 1);
8385 break;
8386 default:
8387 abort();
8389 } else {
8390 rm = insn & 0xf;
8391 switch (op1) {
8392 case 0: /* strex */
8393 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8394 break;
8395 case 1: /* strexd */
8396 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8397 break;
8398 case 2: /* strexb */
8399 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8400 break;
8401 case 3: /* strexh */
8402 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8403 break;
8404 default:
8405 abort();
8408 tcg_temp_free_i32(addr);
8409 } else {
8410 /* SWP instruction */
8411 rm = (insn) & 0xf;
8413 /* ??? This is not really atomic. However we know
8414 we never have multiple CPUs running in parallel,
8415 so it is good enough. */
8416 addr = load_reg(s, rn);
8417 tmp = load_reg(s, rm);
8418 tmp2 = tcg_temp_new_i32();
8419 if (insn & (1 << 22)) {
8420 gen_aa32_ld8u(tmp2, addr, get_mem_index(s));
8421 gen_aa32_st8(tmp, addr, get_mem_index(s));
8422 } else {
8423 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
8424 gen_aa32_st32(tmp, addr, get_mem_index(s));
8426 tcg_temp_free_i32(tmp);
8427 tcg_temp_free_i32(addr);
8428 store_reg(s, rd, tmp2);
8431 } else {
8432 int address_offset;
8433 bool load = insn & (1 << 20);
8434 bool doubleword = false;
8435 /* Misc load/store */
8436 rn = (insn >> 16) & 0xf;
8437 rd = (insn >> 12) & 0xf;
8439 if (!load && (sh & 2)) {
8440 /* doubleword */
8441 ARCH(5TE);
8442 if (rd & 1) {
8443 /* UNPREDICTABLE; we choose to UNDEF */
8444 goto illegal_op;
8446 load = (sh & 1) == 0;
8447 doubleword = true;
8450 addr = load_reg(s, rn);
8451 if (insn & (1 << 24))
8452 gen_add_datah_offset(s, insn, 0, addr);
8453 address_offset = 0;
8455 if (doubleword) {
8456 if (!load) {
8457 /* store */
8458 tmp = load_reg(s, rd);
8459 gen_aa32_st32(tmp, addr, get_mem_index(s));
8460 tcg_temp_free_i32(tmp);
8461 tcg_gen_addi_i32(addr, addr, 4);
8462 tmp = load_reg(s, rd + 1);
8463 gen_aa32_st32(tmp, addr, get_mem_index(s));
8464 tcg_temp_free_i32(tmp);
8465 } else {
8466 /* load */
8467 tmp = tcg_temp_new_i32();
8468 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8469 store_reg(s, rd, tmp);
8470 tcg_gen_addi_i32(addr, addr, 4);
8471 tmp = tcg_temp_new_i32();
8472 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8473 rd++;
8475 address_offset = -4;
8476 } else if (load) {
8477 /* load */
8478 tmp = tcg_temp_new_i32();
8479 switch (sh) {
8480 case 1:
8481 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8482 break;
8483 case 2:
8484 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
8485 break;
8486 default:
8487 case 3:
8488 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
8489 break;
8491 } else {
8492 /* store */
8493 tmp = load_reg(s, rd);
8494 gen_aa32_st16(tmp, addr, get_mem_index(s));
8495 tcg_temp_free_i32(tmp);
8497 /* Perform base writeback before the loaded value to
8498 ensure correct behavior with overlapping index registers.
8499 ldrd with base writeback is is undefined if the
8500 destination and index registers overlap. */
8501 if (!(insn & (1 << 24))) {
8502 gen_add_datah_offset(s, insn, address_offset, addr);
8503 store_reg(s, rn, addr);
8504 } else if (insn & (1 << 21)) {
8505 if (address_offset)
8506 tcg_gen_addi_i32(addr, addr, address_offset);
8507 store_reg(s, rn, addr);
8508 } else {
8509 tcg_temp_free_i32(addr);
8511 if (load) {
8512 /* Complete the load. */
8513 store_reg(s, rd, tmp);
8516 break;
8517 case 0x4:
8518 case 0x5:
8519 goto do_ldst;
8520 case 0x6:
8521 case 0x7:
8522 if (insn & (1 << 4)) {
8523 ARCH(6);
8524 /* Armv6 Media instructions. */
8525 rm = insn & 0xf;
8526 rn = (insn >> 16) & 0xf;
8527 rd = (insn >> 12) & 0xf;
8528 rs = (insn >> 8) & 0xf;
8529 switch ((insn >> 23) & 3) {
8530 case 0: /* Parallel add/subtract. */
8531 op1 = (insn >> 20) & 7;
8532 tmp = load_reg(s, rn);
8533 tmp2 = load_reg(s, rm);
8534 sh = (insn >> 5) & 7;
8535 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8536 goto illegal_op;
8537 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8538 tcg_temp_free_i32(tmp2);
8539 store_reg(s, rd, tmp);
8540 break;
8541 case 1:
8542 if ((insn & 0x00700020) == 0) {
8543 /* Halfword pack. */
8544 tmp = load_reg(s, rn);
8545 tmp2 = load_reg(s, rm);
8546 shift = (insn >> 7) & 0x1f;
8547 if (insn & (1 << 6)) {
8548 /* pkhtb */
8549 if (shift == 0)
8550 shift = 31;
8551 tcg_gen_sari_i32(tmp2, tmp2, shift);
8552 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8553 tcg_gen_ext16u_i32(tmp2, tmp2);
8554 } else {
8555 /* pkhbt */
8556 if (shift)
8557 tcg_gen_shli_i32(tmp2, tmp2, shift);
8558 tcg_gen_ext16u_i32(tmp, tmp);
8559 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8561 tcg_gen_or_i32(tmp, tmp, tmp2);
8562 tcg_temp_free_i32(tmp2);
8563 store_reg(s, rd, tmp);
8564 } else if ((insn & 0x00200020) == 0x00200000) {
8565 /* [us]sat */
8566 tmp = load_reg(s, rm);
8567 shift = (insn >> 7) & 0x1f;
8568 if (insn & (1 << 6)) {
8569 if (shift == 0)
8570 shift = 31;
8571 tcg_gen_sari_i32(tmp, tmp, shift);
8572 } else {
8573 tcg_gen_shli_i32(tmp, tmp, shift);
8575 sh = (insn >> 16) & 0x1f;
8576 tmp2 = tcg_const_i32(sh);
8577 if (insn & (1 << 22))
8578 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8579 else
8580 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8581 tcg_temp_free_i32(tmp2);
8582 store_reg(s, rd, tmp);
8583 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8584 /* [us]sat16 */
8585 tmp = load_reg(s, rm);
8586 sh = (insn >> 16) & 0x1f;
8587 tmp2 = tcg_const_i32(sh);
8588 if (insn & (1 << 22))
8589 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8590 else
8591 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8592 tcg_temp_free_i32(tmp2);
8593 store_reg(s, rd, tmp);
8594 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8595 /* Select bytes. */
8596 tmp = load_reg(s, rn);
8597 tmp2 = load_reg(s, rm);
8598 tmp3 = tcg_temp_new_i32();
8599 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8600 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8601 tcg_temp_free_i32(tmp3);
8602 tcg_temp_free_i32(tmp2);
8603 store_reg(s, rd, tmp);
8604 } else if ((insn & 0x000003e0) == 0x00000060) {
8605 tmp = load_reg(s, rm);
8606 shift = (insn >> 10) & 3;
8607 /* ??? In many cases it's not necessary to do a
8608 rotate, a shift is sufficient. */
8609 if (shift != 0)
8610 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8611 op1 = (insn >> 20) & 7;
8612 switch (op1) {
8613 case 0: gen_sxtb16(tmp); break;
8614 case 2: gen_sxtb(tmp); break;
8615 case 3: gen_sxth(tmp); break;
8616 case 4: gen_uxtb16(tmp); break;
8617 case 6: gen_uxtb(tmp); break;
8618 case 7: gen_uxth(tmp); break;
8619 default: goto illegal_op;
8621 if (rn != 15) {
8622 tmp2 = load_reg(s, rn);
8623 if ((op1 & 3) == 0) {
8624 gen_add16(tmp, tmp2);
8625 } else {
8626 tcg_gen_add_i32(tmp, tmp, tmp2);
8627 tcg_temp_free_i32(tmp2);
8630 store_reg(s, rd, tmp);
8631 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8632 /* rev */
8633 tmp = load_reg(s, rm);
8634 if (insn & (1 << 22)) {
8635 if (insn & (1 << 7)) {
8636 gen_revsh(tmp);
8637 } else {
8638 ARCH(6T2);
8639 gen_helper_rbit(tmp, tmp);
8641 } else {
8642 if (insn & (1 << 7))
8643 gen_rev16(tmp);
8644 else
8645 tcg_gen_bswap32_i32(tmp, tmp);
8647 store_reg(s, rd, tmp);
8648 } else {
8649 goto illegal_op;
8651 break;
8652 case 2: /* Multiplies (Type 3). */
8653 switch ((insn >> 20) & 0x7) {
8654 case 5:
8655 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8656 /* op2 not 00x or 11x : UNDEF */
8657 goto illegal_op;
8659 /* Signed multiply most significant [accumulate].
8660 (SMMUL, SMMLA, SMMLS) */
8661 tmp = load_reg(s, rm);
8662 tmp2 = load_reg(s, rs);
8663 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8665 if (rd != 15) {
8666 tmp = load_reg(s, rd);
8667 if (insn & (1 << 6)) {
8668 tmp64 = gen_subq_msw(tmp64, tmp);
8669 } else {
8670 tmp64 = gen_addq_msw(tmp64, tmp);
8673 if (insn & (1 << 5)) {
8674 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8676 tcg_gen_shri_i64(tmp64, tmp64, 32);
8677 tmp = tcg_temp_new_i32();
8678 tcg_gen_trunc_i64_i32(tmp, tmp64);
8679 tcg_temp_free_i64(tmp64);
8680 store_reg(s, rn, tmp);
8681 break;
8682 case 0:
8683 case 4:
8684 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8685 if (insn & (1 << 7)) {
8686 goto illegal_op;
8688 tmp = load_reg(s, rm);
8689 tmp2 = load_reg(s, rs);
8690 if (insn & (1 << 5))
8691 gen_swap_half(tmp2);
8692 gen_smul_dual(tmp, tmp2);
8693 if (insn & (1 << 22)) {
8694 /* smlald, smlsld */
8695 TCGv_i64 tmp64_2;
8697 tmp64 = tcg_temp_new_i64();
8698 tmp64_2 = tcg_temp_new_i64();
8699 tcg_gen_ext_i32_i64(tmp64, tmp);
8700 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8701 tcg_temp_free_i32(tmp);
8702 tcg_temp_free_i32(tmp2);
8703 if (insn & (1 << 6)) {
8704 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8705 } else {
8706 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8708 tcg_temp_free_i64(tmp64_2);
8709 gen_addq(s, tmp64, rd, rn);
8710 gen_storeq_reg(s, rd, rn, tmp64);
8711 tcg_temp_free_i64(tmp64);
8712 } else {
8713 /* smuad, smusd, smlad, smlsd */
8714 if (insn & (1 << 6)) {
8715 /* This subtraction cannot overflow. */
8716 tcg_gen_sub_i32(tmp, tmp, tmp2);
8717 } else {
8718 /* This addition cannot overflow 32 bits;
8719 * however it may overflow considered as a
8720 * signed operation, in which case we must set
8721 * the Q flag.
8723 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8725 tcg_temp_free_i32(tmp2);
8726 if (rd != 15)
8728 tmp2 = load_reg(s, rd);
8729 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8730 tcg_temp_free_i32(tmp2);
8732 store_reg(s, rn, tmp);
8734 break;
8735 case 1:
8736 case 3:
8737 /* SDIV, UDIV */
8738 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
8739 goto illegal_op;
8741 if (((insn >> 5) & 7) || (rd != 15)) {
8742 goto illegal_op;
8744 tmp = load_reg(s, rm);
8745 tmp2 = load_reg(s, rs);
8746 if (insn & (1 << 21)) {
8747 gen_helper_udiv(tmp, tmp, tmp2);
8748 } else {
8749 gen_helper_sdiv(tmp, tmp, tmp2);
8751 tcg_temp_free_i32(tmp2);
8752 store_reg(s, rn, tmp);
8753 break;
8754 default:
8755 goto illegal_op;
8757 break;
8758 case 3:
8759 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8760 switch (op1) {
8761 case 0: /* Unsigned sum of absolute differences. */
8762 ARCH(6);
8763 tmp = load_reg(s, rm);
8764 tmp2 = load_reg(s, rs);
8765 gen_helper_usad8(tmp, tmp, tmp2);
8766 tcg_temp_free_i32(tmp2);
8767 if (rd != 15) {
8768 tmp2 = load_reg(s, rd);
8769 tcg_gen_add_i32(tmp, tmp, tmp2);
8770 tcg_temp_free_i32(tmp2);
8772 store_reg(s, rn, tmp);
8773 break;
8774 case 0x20: case 0x24: case 0x28: case 0x2c:
8775 /* Bitfield insert/clear. */
8776 ARCH(6T2);
8777 shift = (insn >> 7) & 0x1f;
8778 i = (insn >> 16) & 0x1f;
8779 if (i < shift) {
8780 /* UNPREDICTABLE; we choose to UNDEF */
8781 goto illegal_op;
8783 i = i + 1 - shift;
8784 if (rm == 15) {
8785 tmp = tcg_temp_new_i32();
8786 tcg_gen_movi_i32(tmp, 0);
8787 } else {
8788 tmp = load_reg(s, rm);
8790 if (i != 32) {
8791 tmp2 = load_reg(s, rd);
8792 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8793 tcg_temp_free_i32(tmp2);
8795 store_reg(s, rd, tmp);
8796 break;
8797 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8798 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8799 ARCH(6T2);
8800 tmp = load_reg(s, rm);
8801 shift = (insn >> 7) & 0x1f;
8802 i = ((insn >> 16) & 0x1f) + 1;
8803 if (shift + i > 32)
8804 goto illegal_op;
8805 if (i < 32) {
8806 if (op1 & 0x20) {
8807 gen_ubfx(tmp, shift, (1u << i) - 1);
8808 } else {
8809 gen_sbfx(tmp, shift, i);
8812 store_reg(s, rd, tmp);
8813 break;
8814 default:
8815 goto illegal_op;
8817 break;
8819 break;
8821 do_ldst:
8822 /* Check for undefined extension instructions
8823 * per the ARM Bible IE:
8824 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8826 sh = (0xf << 20) | (0xf << 4);
8827 if (op1 == 0x7 && ((insn & sh) == sh))
8829 goto illegal_op;
8831 /* load/store byte/word */
8832 rn = (insn >> 16) & 0xf;
8833 rd = (insn >> 12) & 0xf;
8834 tmp2 = load_reg(s, rn);
8835 if ((insn & 0x01200000) == 0x00200000) {
8836 /* ldrt/strt */
8837 i = get_a32_user_mem_index(s);
8838 } else {
8839 i = get_mem_index(s);
8841 if (insn & (1 << 24))
8842 gen_add_data_offset(s, insn, tmp2);
8843 if (insn & (1 << 20)) {
8844 /* load */
8845 tmp = tcg_temp_new_i32();
8846 if (insn & (1 << 22)) {
8847 gen_aa32_ld8u(tmp, tmp2, i);
8848 } else {
8849 gen_aa32_ld32u(tmp, tmp2, i);
8851 } else {
8852 /* store */
8853 tmp = load_reg(s, rd);
8854 if (insn & (1 << 22)) {
8855 gen_aa32_st8(tmp, tmp2, i);
8856 } else {
8857 gen_aa32_st32(tmp, tmp2, i);
8859 tcg_temp_free_i32(tmp);
8861 if (!(insn & (1 << 24))) {
8862 gen_add_data_offset(s, insn, tmp2);
8863 store_reg(s, rn, tmp2);
8864 } else if (insn & (1 << 21)) {
8865 store_reg(s, rn, tmp2);
8866 } else {
8867 tcg_temp_free_i32(tmp2);
8869 if (insn & (1 << 20)) {
8870 /* Complete the load. */
8871 store_reg_from_load(s, rd, tmp);
8873 break;
8874 case 0x08:
8875 case 0x09:
8877 int j, n, loaded_base;
8878 bool exc_return = false;
8879 bool is_load = extract32(insn, 20, 1);
8880 bool user = false;
8881 TCGv_i32 loaded_var;
8882 /* load/store multiple words */
8883 /* XXX: store correct base if write back */
8884 if (insn & (1 << 22)) {
8885 /* LDM (user), LDM (exception return) and STM (user) */
8886 if (IS_USER(s))
8887 goto illegal_op; /* only usable in supervisor mode */
8889 if (is_load && extract32(insn, 15, 1)) {
8890 exc_return = true;
8891 } else {
8892 user = true;
8895 rn = (insn >> 16) & 0xf;
8896 addr = load_reg(s, rn);
8898 /* compute total size */
8899 loaded_base = 0;
8900 TCGV_UNUSED_I32(loaded_var);
8901 n = 0;
8902 for(i=0;i<16;i++) {
8903 if (insn & (1 << i))
8904 n++;
8906 /* XXX: test invalid n == 0 case ? */
8907 if (insn & (1 << 23)) {
8908 if (insn & (1 << 24)) {
8909 /* pre increment */
8910 tcg_gen_addi_i32(addr, addr, 4);
8911 } else {
8912 /* post increment */
8914 } else {
8915 if (insn & (1 << 24)) {
8916 /* pre decrement */
8917 tcg_gen_addi_i32(addr, addr, -(n * 4));
8918 } else {
8919 /* post decrement */
8920 if (n != 1)
8921 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8924 j = 0;
8925 for(i=0;i<16;i++) {
8926 if (insn & (1 << i)) {
8927 if (is_load) {
8928 /* load */
8929 tmp = tcg_temp_new_i32();
8930 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8931 if (user) {
8932 tmp2 = tcg_const_i32(i);
8933 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8934 tcg_temp_free_i32(tmp2);
8935 tcg_temp_free_i32(tmp);
8936 } else if (i == rn) {
8937 loaded_var = tmp;
8938 loaded_base = 1;
8939 } else {
8940 store_reg_from_load(s, i, tmp);
8942 } else {
8943 /* store */
8944 if (i == 15) {
8945 /* special case: r15 = PC + 8 */
8946 val = (long)s->pc + 4;
8947 tmp = tcg_temp_new_i32();
8948 tcg_gen_movi_i32(tmp, val);
8949 } else if (user) {
8950 tmp = tcg_temp_new_i32();
8951 tmp2 = tcg_const_i32(i);
8952 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8953 tcg_temp_free_i32(tmp2);
8954 } else {
8955 tmp = load_reg(s, i);
8957 gen_aa32_st32(tmp, addr, get_mem_index(s));
8958 tcg_temp_free_i32(tmp);
8960 j++;
8961 /* no need to add after the last transfer */
8962 if (j != n)
8963 tcg_gen_addi_i32(addr, addr, 4);
8966 if (insn & (1 << 21)) {
8967 /* write back */
8968 if (insn & (1 << 23)) {
8969 if (insn & (1 << 24)) {
8970 /* pre increment */
8971 } else {
8972 /* post increment */
8973 tcg_gen_addi_i32(addr, addr, 4);
8975 } else {
8976 if (insn & (1 << 24)) {
8977 /* pre decrement */
8978 if (n != 1)
8979 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8980 } else {
8981 /* post decrement */
8982 tcg_gen_addi_i32(addr, addr, -(n * 4));
8985 store_reg(s, rn, addr);
8986 } else {
8987 tcg_temp_free_i32(addr);
8989 if (loaded_base) {
8990 store_reg(s, rn, loaded_var);
8992 if (exc_return) {
8993 /* Restore CPSR from SPSR. */
8994 tmp = load_cpu_field(spsr);
8995 gen_set_cpsr(tmp, CPSR_ERET_MASK);
8996 tcg_temp_free_i32(tmp);
8997 s->is_jmp = DISAS_UPDATE;
9000 break;
9001 case 0xa:
9002 case 0xb:
9004 int32_t offset;
9006 /* branch (and link) */
9007 val = (int32_t)s->pc;
9008 if (insn & (1 << 24)) {
9009 tmp = tcg_temp_new_i32();
9010 tcg_gen_movi_i32(tmp, val);
9011 store_reg(s, 14, tmp);
9013 offset = sextract32(insn << 2, 0, 26);
9014 val += offset + 4;
9015 gen_jmp(s, val);
9017 break;
9018 case 0xc:
9019 case 0xd:
9020 case 0xe:
9021 if (((insn >> 8) & 0xe) == 10) {
9022 /* VFP. */
9023 if (disas_vfp_insn(s, insn)) {
9024 goto illegal_op;
9026 } else if (disas_coproc_insn(s, insn)) {
9027 /* Coprocessor. */
9028 goto illegal_op;
9030 break;
9031 case 0xf:
9032 /* swi */
9033 gen_set_pc_im(s, s->pc);
9034 s->svc_imm = extract32(insn, 0, 24);
9035 s->is_jmp = DISAS_SWI;
9036 break;
9037 default:
9038 illegal_op:
9039 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9040 default_exception_el(s));
9041 break;
9046 /* Return true if this is a Thumb-2 logical op. */
9047 static int
9048 thumb2_logic_op(int op)
9050 return (op < 8);
9053 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9054 then set condition code flags based on the result of the operation.
9055 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9056 to the high bit of T1.
9057 Returns zero if the opcode is valid. */
9059 static int
9060 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9061 TCGv_i32 t0, TCGv_i32 t1)
9063 int logic_cc;
9065 logic_cc = 0;
9066 switch (op) {
9067 case 0: /* and */
9068 tcg_gen_and_i32(t0, t0, t1);
9069 logic_cc = conds;
9070 break;
9071 case 1: /* bic */
9072 tcg_gen_andc_i32(t0, t0, t1);
9073 logic_cc = conds;
9074 break;
9075 case 2: /* orr */
9076 tcg_gen_or_i32(t0, t0, t1);
9077 logic_cc = conds;
9078 break;
9079 case 3: /* orn */
9080 tcg_gen_orc_i32(t0, t0, t1);
9081 logic_cc = conds;
9082 break;
9083 case 4: /* eor */
9084 tcg_gen_xor_i32(t0, t0, t1);
9085 logic_cc = conds;
9086 break;
9087 case 8: /* add */
9088 if (conds)
9089 gen_add_CC(t0, t0, t1);
9090 else
9091 tcg_gen_add_i32(t0, t0, t1);
9092 break;
9093 case 10: /* adc */
9094 if (conds)
9095 gen_adc_CC(t0, t0, t1);
9096 else
9097 gen_adc(t0, t1);
9098 break;
9099 case 11: /* sbc */
9100 if (conds) {
9101 gen_sbc_CC(t0, t0, t1);
9102 } else {
9103 gen_sub_carry(t0, t0, t1);
9105 break;
9106 case 13: /* sub */
9107 if (conds)
9108 gen_sub_CC(t0, t0, t1);
9109 else
9110 tcg_gen_sub_i32(t0, t0, t1);
9111 break;
9112 case 14: /* rsb */
9113 if (conds)
9114 gen_sub_CC(t0, t1, t0);
9115 else
9116 tcg_gen_sub_i32(t0, t1, t0);
9117 break;
9118 default: /* 5, 6, 7, 9, 12, 15. */
9119 return 1;
9121 if (logic_cc) {
9122 gen_logic_CC(t0);
9123 if (shifter_out)
9124 gen_set_CF_bit31(t1);
9126 return 0;
9129 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9130 is not legal. */
9131 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9133 uint32_t insn, imm, shift, offset;
9134 uint32_t rd, rn, rm, rs;
9135 TCGv_i32 tmp;
9136 TCGv_i32 tmp2;
9137 TCGv_i32 tmp3;
9138 TCGv_i32 addr;
9139 TCGv_i64 tmp64;
9140 int op;
9141 int shiftop;
9142 int conds;
9143 int logic_cc;
9145 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9146 || arm_dc_feature(s, ARM_FEATURE_M))) {
9147 /* Thumb-1 cores may need to treat bl and blx as a pair of
9148 16-bit instructions to get correct prefetch abort behavior. */
9149 insn = insn_hw1;
9150 if ((insn & (1 << 12)) == 0) {
9151 ARCH(5);
9152 /* Second half of blx. */
9153 offset = ((insn & 0x7ff) << 1);
9154 tmp = load_reg(s, 14);
9155 tcg_gen_addi_i32(tmp, tmp, offset);
9156 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9158 tmp2 = tcg_temp_new_i32();
9159 tcg_gen_movi_i32(tmp2, s->pc | 1);
9160 store_reg(s, 14, tmp2);
9161 gen_bx(s, tmp);
9162 return 0;
9164 if (insn & (1 << 11)) {
9165 /* Second half of bl. */
9166 offset = ((insn & 0x7ff) << 1) | 1;
9167 tmp = load_reg(s, 14);
9168 tcg_gen_addi_i32(tmp, tmp, offset);
9170 tmp2 = tcg_temp_new_i32();
9171 tcg_gen_movi_i32(tmp2, s->pc | 1);
9172 store_reg(s, 14, tmp2);
9173 gen_bx(s, tmp);
9174 return 0;
9176 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9177 /* Instruction spans a page boundary. Implement it as two
9178 16-bit instructions in case the second half causes an
9179 prefetch abort. */
9180 offset = ((int32_t)insn << 21) >> 9;
9181 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9182 return 0;
9184 /* Fall through to 32-bit decode. */
9187 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9188 s->pc += 2;
9189 insn |= (uint32_t)insn_hw1 << 16;
9191 if ((insn & 0xf800e800) != 0xf000e800) {
9192 ARCH(6T2);
9195 rn = (insn >> 16) & 0xf;
9196 rs = (insn >> 12) & 0xf;
9197 rd = (insn >> 8) & 0xf;
9198 rm = insn & 0xf;
9199 switch ((insn >> 25) & 0xf) {
9200 case 0: case 1: case 2: case 3:
9201 /* 16-bit instructions. Should never happen. */
9202 abort();
9203 case 4:
9204 if (insn & (1 << 22)) {
9205 /* Other load/store, table branch. */
9206 if (insn & 0x01200000) {
9207 /* Load/store doubleword. */
9208 if (rn == 15) {
9209 addr = tcg_temp_new_i32();
9210 tcg_gen_movi_i32(addr, s->pc & ~3);
9211 } else {
9212 addr = load_reg(s, rn);
9214 offset = (insn & 0xff) * 4;
9215 if ((insn & (1 << 23)) == 0)
9216 offset = -offset;
9217 if (insn & (1 << 24)) {
9218 tcg_gen_addi_i32(addr, addr, offset);
9219 offset = 0;
9221 if (insn & (1 << 20)) {
9222 /* ldrd */
9223 tmp = tcg_temp_new_i32();
9224 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9225 store_reg(s, rs, tmp);
9226 tcg_gen_addi_i32(addr, addr, 4);
9227 tmp = tcg_temp_new_i32();
9228 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9229 store_reg(s, rd, tmp);
9230 } else {
9231 /* strd */
9232 tmp = load_reg(s, rs);
9233 gen_aa32_st32(tmp, addr, get_mem_index(s));
9234 tcg_temp_free_i32(tmp);
9235 tcg_gen_addi_i32(addr, addr, 4);
9236 tmp = load_reg(s, rd);
9237 gen_aa32_st32(tmp, addr, get_mem_index(s));
9238 tcg_temp_free_i32(tmp);
9240 if (insn & (1 << 21)) {
9241 /* Base writeback. */
9242 if (rn == 15)
9243 goto illegal_op;
9244 tcg_gen_addi_i32(addr, addr, offset - 4);
9245 store_reg(s, rn, addr);
9246 } else {
9247 tcg_temp_free_i32(addr);
9249 } else if ((insn & (1 << 23)) == 0) {
9250 /* Load/store exclusive word. */
9251 addr = tcg_temp_local_new_i32();
9252 load_reg_var(s, addr, rn);
9253 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9254 if (insn & (1 << 20)) {
9255 gen_load_exclusive(s, rs, 15, addr, 2);
9256 } else {
9257 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9259 tcg_temp_free_i32(addr);
9260 } else if ((insn & (7 << 5)) == 0) {
9261 /* Table Branch. */
9262 if (rn == 15) {
9263 addr = tcg_temp_new_i32();
9264 tcg_gen_movi_i32(addr, s->pc);
9265 } else {
9266 addr = load_reg(s, rn);
9268 tmp = load_reg(s, rm);
9269 tcg_gen_add_i32(addr, addr, tmp);
9270 if (insn & (1 << 4)) {
9271 /* tbh */
9272 tcg_gen_add_i32(addr, addr, tmp);
9273 tcg_temp_free_i32(tmp);
9274 tmp = tcg_temp_new_i32();
9275 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9276 } else { /* tbb */
9277 tcg_temp_free_i32(tmp);
9278 tmp = tcg_temp_new_i32();
9279 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9281 tcg_temp_free_i32(addr);
9282 tcg_gen_shli_i32(tmp, tmp, 1);
9283 tcg_gen_addi_i32(tmp, tmp, s->pc);
9284 store_reg(s, 15, tmp);
9285 } else {
9286 int op2 = (insn >> 6) & 0x3;
9287 op = (insn >> 4) & 0x3;
9288 switch (op2) {
9289 case 0:
9290 goto illegal_op;
9291 case 1:
9292 /* Load/store exclusive byte/halfword/doubleword */
9293 if (op == 2) {
9294 goto illegal_op;
9296 ARCH(7);
9297 break;
9298 case 2:
9299 /* Load-acquire/store-release */
9300 if (op == 3) {
9301 goto illegal_op;
9303 /* Fall through */
9304 case 3:
9305 /* Load-acquire/store-release exclusive */
9306 ARCH(8);
9307 break;
9309 addr = tcg_temp_local_new_i32();
9310 load_reg_var(s, addr, rn);
9311 if (!(op2 & 1)) {
9312 if (insn & (1 << 20)) {
9313 tmp = tcg_temp_new_i32();
9314 switch (op) {
9315 case 0: /* ldab */
9316 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9317 break;
9318 case 1: /* ldah */
9319 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9320 break;
9321 case 2: /* lda */
9322 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9323 break;
9324 default:
9325 abort();
9327 store_reg(s, rs, tmp);
9328 } else {
9329 tmp = load_reg(s, rs);
9330 switch (op) {
9331 case 0: /* stlb */
9332 gen_aa32_st8(tmp, addr, get_mem_index(s));
9333 break;
9334 case 1: /* stlh */
9335 gen_aa32_st16(tmp, addr, get_mem_index(s));
9336 break;
9337 case 2: /* stl */
9338 gen_aa32_st32(tmp, addr, get_mem_index(s));
9339 break;
9340 default:
9341 abort();
9343 tcg_temp_free_i32(tmp);
9345 } else if (insn & (1 << 20)) {
9346 gen_load_exclusive(s, rs, rd, addr, op);
9347 } else {
9348 gen_store_exclusive(s, rm, rs, rd, addr, op);
9350 tcg_temp_free_i32(addr);
9352 } else {
9353 /* Load/store multiple, RFE, SRS. */
9354 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9355 /* RFE, SRS: not available in user mode or on M profile */
9356 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9357 goto illegal_op;
9359 if (insn & (1 << 20)) {
9360 /* rfe */
9361 addr = load_reg(s, rn);
9362 if ((insn & (1 << 24)) == 0)
9363 tcg_gen_addi_i32(addr, addr, -8);
9364 /* Load PC into tmp and CPSR into tmp2. */
9365 tmp = tcg_temp_new_i32();
9366 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9367 tcg_gen_addi_i32(addr, addr, 4);
9368 tmp2 = tcg_temp_new_i32();
9369 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
9370 if (insn & (1 << 21)) {
9371 /* Base writeback. */
9372 if (insn & (1 << 24)) {
9373 tcg_gen_addi_i32(addr, addr, 4);
9374 } else {
9375 tcg_gen_addi_i32(addr, addr, -4);
9377 store_reg(s, rn, addr);
9378 } else {
9379 tcg_temp_free_i32(addr);
9381 gen_rfe(s, tmp, tmp2);
9382 } else {
9383 /* srs */
9384 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9385 insn & (1 << 21));
9387 } else {
9388 int i, loaded_base = 0;
9389 TCGv_i32 loaded_var;
9390 /* Load/store multiple. */
9391 addr = load_reg(s, rn);
9392 offset = 0;
9393 for (i = 0; i < 16; i++) {
9394 if (insn & (1 << i))
9395 offset += 4;
9397 if (insn & (1 << 24)) {
9398 tcg_gen_addi_i32(addr, addr, -offset);
9401 TCGV_UNUSED_I32(loaded_var);
9402 for (i = 0; i < 16; i++) {
9403 if ((insn & (1 << i)) == 0)
9404 continue;
9405 if (insn & (1 << 20)) {
9406 /* Load. */
9407 tmp = tcg_temp_new_i32();
9408 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9409 if (i == 15) {
9410 gen_bx(s, tmp);
9411 } else if (i == rn) {
9412 loaded_var = tmp;
9413 loaded_base = 1;
9414 } else {
9415 store_reg(s, i, tmp);
9417 } else {
9418 /* Store. */
9419 tmp = load_reg(s, i);
9420 gen_aa32_st32(tmp, addr, get_mem_index(s));
9421 tcg_temp_free_i32(tmp);
9423 tcg_gen_addi_i32(addr, addr, 4);
9425 if (loaded_base) {
9426 store_reg(s, rn, loaded_var);
9428 if (insn & (1 << 21)) {
9429 /* Base register writeback. */
9430 if (insn & (1 << 24)) {
9431 tcg_gen_addi_i32(addr, addr, -offset);
9433 /* Fault if writeback register is in register list. */
9434 if (insn & (1 << rn))
9435 goto illegal_op;
9436 store_reg(s, rn, addr);
9437 } else {
9438 tcg_temp_free_i32(addr);
9442 break;
9443 case 5:
9445 op = (insn >> 21) & 0xf;
9446 if (op == 6) {
9447 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9448 goto illegal_op;
9450 /* Halfword pack. */
9451 tmp = load_reg(s, rn);
9452 tmp2 = load_reg(s, rm);
9453 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9454 if (insn & (1 << 5)) {
9455 /* pkhtb */
9456 if (shift == 0)
9457 shift = 31;
9458 tcg_gen_sari_i32(tmp2, tmp2, shift);
9459 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9460 tcg_gen_ext16u_i32(tmp2, tmp2);
9461 } else {
9462 /* pkhbt */
9463 if (shift)
9464 tcg_gen_shli_i32(tmp2, tmp2, shift);
9465 tcg_gen_ext16u_i32(tmp, tmp);
9466 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9468 tcg_gen_or_i32(tmp, tmp, tmp2);
9469 tcg_temp_free_i32(tmp2);
9470 store_reg(s, rd, tmp);
9471 } else {
9472 /* Data processing register constant shift. */
9473 if (rn == 15) {
9474 tmp = tcg_temp_new_i32();
9475 tcg_gen_movi_i32(tmp, 0);
9476 } else {
9477 tmp = load_reg(s, rn);
9479 tmp2 = load_reg(s, rm);
9481 shiftop = (insn >> 4) & 3;
9482 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9483 conds = (insn & (1 << 20)) != 0;
9484 logic_cc = (conds && thumb2_logic_op(op));
9485 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9486 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9487 goto illegal_op;
9488 tcg_temp_free_i32(tmp2);
9489 if (rd != 15) {
9490 store_reg(s, rd, tmp);
9491 } else {
9492 tcg_temp_free_i32(tmp);
9495 break;
9496 case 13: /* Misc data processing. */
9497 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9498 if (op < 4 && (insn & 0xf000) != 0xf000)
9499 goto illegal_op;
9500 switch (op) {
9501 case 0: /* Register controlled shift. */
9502 tmp = load_reg(s, rn);
9503 tmp2 = load_reg(s, rm);
9504 if ((insn & 0x70) != 0)
9505 goto illegal_op;
9506 op = (insn >> 21) & 3;
9507 logic_cc = (insn & (1 << 20)) != 0;
9508 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9509 if (logic_cc)
9510 gen_logic_CC(tmp);
9511 store_reg_bx(s, rd, tmp);
9512 break;
9513 case 1: /* Sign/zero extend. */
9514 op = (insn >> 20) & 7;
9515 switch (op) {
9516 case 0: /* SXTAH, SXTH */
9517 case 1: /* UXTAH, UXTH */
9518 case 4: /* SXTAB, SXTB */
9519 case 5: /* UXTAB, UXTB */
9520 break;
9521 case 2: /* SXTAB16, SXTB16 */
9522 case 3: /* UXTAB16, UXTB16 */
9523 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9524 goto illegal_op;
9526 break;
9527 default:
9528 goto illegal_op;
9530 if (rn != 15) {
9531 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9532 goto illegal_op;
9535 tmp = load_reg(s, rm);
9536 shift = (insn >> 4) & 3;
9537 /* ??? In many cases it's not necessary to do a
9538 rotate, a shift is sufficient. */
9539 if (shift != 0)
9540 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9541 op = (insn >> 20) & 7;
9542 switch (op) {
9543 case 0: gen_sxth(tmp); break;
9544 case 1: gen_uxth(tmp); break;
9545 case 2: gen_sxtb16(tmp); break;
9546 case 3: gen_uxtb16(tmp); break;
9547 case 4: gen_sxtb(tmp); break;
9548 case 5: gen_uxtb(tmp); break;
9549 default:
9550 g_assert_not_reached();
9552 if (rn != 15) {
9553 tmp2 = load_reg(s, rn);
9554 if ((op >> 1) == 1) {
9555 gen_add16(tmp, tmp2);
9556 } else {
9557 tcg_gen_add_i32(tmp, tmp, tmp2);
9558 tcg_temp_free_i32(tmp2);
9561 store_reg(s, rd, tmp);
9562 break;
9563 case 2: /* SIMD add/subtract. */
9564 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9565 goto illegal_op;
9567 op = (insn >> 20) & 7;
9568 shift = (insn >> 4) & 7;
9569 if ((op & 3) == 3 || (shift & 3) == 3)
9570 goto illegal_op;
9571 tmp = load_reg(s, rn);
9572 tmp2 = load_reg(s, rm);
9573 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9574 tcg_temp_free_i32(tmp2);
9575 store_reg(s, rd, tmp);
9576 break;
9577 case 3: /* Other data processing. */
9578 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9579 if (op < 4) {
9580 /* Saturating add/subtract. */
9581 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9582 goto illegal_op;
9584 tmp = load_reg(s, rn);
9585 tmp2 = load_reg(s, rm);
9586 if (op & 1)
9587 gen_helper_double_saturate(tmp, cpu_env, tmp);
9588 if (op & 2)
9589 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9590 else
9591 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9592 tcg_temp_free_i32(tmp2);
9593 } else {
9594 switch (op) {
9595 case 0x0a: /* rbit */
9596 case 0x08: /* rev */
9597 case 0x09: /* rev16 */
9598 case 0x0b: /* revsh */
9599 case 0x18: /* clz */
9600 break;
9601 case 0x10: /* sel */
9602 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9603 goto illegal_op;
9605 break;
9606 case 0x20: /* crc32/crc32c */
9607 case 0x21:
9608 case 0x22:
9609 case 0x28:
9610 case 0x29:
9611 case 0x2a:
9612 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
9613 goto illegal_op;
9615 break;
9616 default:
9617 goto illegal_op;
9619 tmp = load_reg(s, rn);
9620 switch (op) {
9621 case 0x0a: /* rbit */
9622 gen_helper_rbit(tmp, tmp);
9623 break;
9624 case 0x08: /* rev */
9625 tcg_gen_bswap32_i32(tmp, tmp);
9626 break;
9627 case 0x09: /* rev16 */
9628 gen_rev16(tmp);
9629 break;
9630 case 0x0b: /* revsh */
9631 gen_revsh(tmp);
9632 break;
9633 case 0x10: /* sel */
9634 tmp2 = load_reg(s, rm);
9635 tmp3 = tcg_temp_new_i32();
9636 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9637 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9638 tcg_temp_free_i32(tmp3);
9639 tcg_temp_free_i32(tmp2);
9640 break;
9641 case 0x18: /* clz */
9642 gen_helper_clz(tmp, tmp);
9643 break;
9644 case 0x20:
9645 case 0x21:
9646 case 0x22:
9647 case 0x28:
9648 case 0x29:
9649 case 0x2a:
9651 /* crc32/crc32c */
9652 uint32_t sz = op & 0x3;
9653 uint32_t c = op & 0x8;
9655 tmp2 = load_reg(s, rm);
9656 if (sz == 0) {
9657 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9658 } else if (sz == 1) {
9659 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9661 tmp3 = tcg_const_i32(1 << sz);
9662 if (c) {
9663 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9664 } else {
9665 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9667 tcg_temp_free_i32(tmp2);
9668 tcg_temp_free_i32(tmp3);
9669 break;
9671 default:
9672 g_assert_not_reached();
9675 store_reg(s, rd, tmp);
9676 break;
9677 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9678 switch ((insn >> 20) & 7) {
9679 case 0: /* 32 x 32 -> 32 */
9680 case 7: /* Unsigned sum of absolute differences. */
9681 break;
9682 case 1: /* 16 x 16 -> 32 */
9683 case 2: /* Dual multiply add. */
9684 case 3: /* 32 * 16 -> 32msb */
9685 case 4: /* Dual multiply subtract. */
9686 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9687 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9688 goto illegal_op;
9690 break;
9692 op = (insn >> 4) & 0xf;
9693 tmp = load_reg(s, rn);
9694 tmp2 = load_reg(s, rm);
9695 switch ((insn >> 20) & 7) {
9696 case 0: /* 32 x 32 -> 32 */
9697 tcg_gen_mul_i32(tmp, tmp, tmp2);
9698 tcg_temp_free_i32(tmp2);
9699 if (rs != 15) {
9700 tmp2 = load_reg(s, rs);
9701 if (op)
9702 tcg_gen_sub_i32(tmp, tmp2, tmp);
9703 else
9704 tcg_gen_add_i32(tmp, tmp, tmp2);
9705 tcg_temp_free_i32(tmp2);
9707 break;
9708 case 1: /* 16 x 16 -> 32 */
9709 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9710 tcg_temp_free_i32(tmp2);
9711 if (rs != 15) {
9712 tmp2 = load_reg(s, rs);
9713 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9714 tcg_temp_free_i32(tmp2);
9716 break;
9717 case 2: /* Dual multiply add. */
9718 case 4: /* Dual multiply subtract. */
9719 if (op)
9720 gen_swap_half(tmp2);
9721 gen_smul_dual(tmp, tmp2);
9722 if (insn & (1 << 22)) {
9723 /* This subtraction cannot overflow. */
9724 tcg_gen_sub_i32(tmp, tmp, tmp2);
9725 } else {
9726 /* This addition cannot overflow 32 bits;
9727 * however it may overflow considered as a signed
9728 * operation, in which case we must set the Q flag.
9730 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9732 tcg_temp_free_i32(tmp2);
9733 if (rs != 15)
9735 tmp2 = load_reg(s, rs);
9736 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9737 tcg_temp_free_i32(tmp2);
9739 break;
9740 case 3: /* 32 * 16 -> 32msb */
9741 if (op)
9742 tcg_gen_sari_i32(tmp2, tmp2, 16);
9743 else
9744 gen_sxth(tmp2);
9745 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9746 tcg_gen_shri_i64(tmp64, tmp64, 16);
9747 tmp = tcg_temp_new_i32();
9748 tcg_gen_trunc_i64_i32(tmp, tmp64);
9749 tcg_temp_free_i64(tmp64);
9750 if (rs != 15)
9752 tmp2 = load_reg(s, rs);
9753 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9754 tcg_temp_free_i32(tmp2);
9756 break;
9757 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9758 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9759 if (rs != 15) {
9760 tmp = load_reg(s, rs);
9761 if (insn & (1 << 20)) {
9762 tmp64 = gen_addq_msw(tmp64, tmp);
9763 } else {
9764 tmp64 = gen_subq_msw(tmp64, tmp);
9767 if (insn & (1 << 4)) {
9768 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9770 tcg_gen_shri_i64(tmp64, tmp64, 32);
9771 tmp = tcg_temp_new_i32();
9772 tcg_gen_trunc_i64_i32(tmp, tmp64);
9773 tcg_temp_free_i64(tmp64);
9774 break;
9775 case 7: /* Unsigned sum of absolute differences. */
9776 gen_helper_usad8(tmp, tmp, tmp2);
9777 tcg_temp_free_i32(tmp2);
9778 if (rs != 15) {
9779 tmp2 = load_reg(s, rs);
9780 tcg_gen_add_i32(tmp, tmp, tmp2);
9781 tcg_temp_free_i32(tmp2);
9783 break;
9785 store_reg(s, rd, tmp);
9786 break;
9787 case 6: case 7: /* 64-bit multiply, Divide. */
9788 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9789 tmp = load_reg(s, rn);
9790 tmp2 = load_reg(s, rm);
9791 if ((op & 0x50) == 0x10) {
9792 /* sdiv, udiv */
9793 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
9794 goto illegal_op;
9796 if (op & 0x20)
9797 gen_helper_udiv(tmp, tmp, tmp2);
9798 else
9799 gen_helper_sdiv(tmp, tmp, tmp2);
9800 tcg_temp_free_i32(tmp2);
9801 store_reg(s, rd, tmp);
9802 } else if ((op & 0xe) == 0xc) {
9803 /* Dual multiply accumulate long. */
9804 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9805 tcg_temp_free_i32(tmp);
9806 tcg_temp_free_i32(tmp2);
9807 goto illegal_op;
9809 if (op & 1)
9810 gen_swap_half(tmp2);
9811 gen_smul_dual(tmp, tmp2);
9812 if (op & 0x10) {
9813 tcg_gen_sub_i32(tmp, tmp, tmp2);
9814 } else {
9815 tcg_gen_add_i32(tmp, tmp, tmp2);
9817 tcg_temp_free_i32(tmp2);
9818 /* BUGFIX */
9819 tmp64 = tcg_temp_new_i64();
9820 tcg_gen_ext_i32_i64(tmp64, tmp);
9821 tcg_temp_free_i32(tmp);
9822 gen_addq(s, tmp64, rs, rd);
9823 gen_storeq_reg(s, rs, rd, tmp64);
9824 tcg_temp_free_i64(tmp64);
9825 } else {
9826 if (op & 0x20) {
9827 /* Unsigned 64-bit multiply */
9828 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9829 } else {
9830 if (op & 8) {
9831 /* smlalxy */
9832 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9833 tcg_temp_free_i32(tmp2);
9834 tcg_temp_free_i32(tmp);
9835 goto illegal_op;
9837 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9838 tcg_temp_free_i32(tmp2);
9839 tmp64 = tcg_temp_new_i64();
9840 tcg_gen_ext_i32_i64(tmp64, tmp);
9841 tcg_temp_free_i32(tmp);
9842 } else {
9843 /* Signed 64-bit multiply */
9844 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9847 if (op & 4) {
9848 /* umaal */
9849 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9850 tcg_temp_free_i64(tmp64);
9851 goto illegal_op;
9853 gen_addq_lo(s, tmp64, rs);
9854 gen_addq_lo(s, tmp64, rd);
9855 } else if (op & 0x40) {
9856 /* 64-bit accumulate. */
9857 gen_addq(s, tmp64, rs, rd);
9859 gen_storeq_reg(s, rs, rd, tmp64);
9860 tcg_temp_free_i64(tmp64);
9862 break;
9864 break;
9865 case 6: case 7: case 14: case 15:
9866 /* Coprocessor. */
9867 if (((insn >> 24) & 3) == 3) {
9868 /* Translate into the equivalent ARM encoding. */
9869 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9870 if (disas_neon_data_insn(s, insn)) {
9871 goto illegal_op;
9873 } else if (((insn >> 8) & 0xe) == 10) {
9874 if (disas_vfp_insn(s, insn)) {
9875 goto illegal_op;
9877 } else {
9878 if (insn & (1 << 28))
9879 goto illegal_op;
9880 if (disas_coproc_insn(s, insn)) {
9881 goto illegal_op;
9884 break;
9885 case 8: case 9: case 10: case 11:
9886 if (insn & (1 << 15)) {
9887 /* Branches, misc control. */
9888 if (insn & 0x5000) {
9889 /* Unconditional branch. */
9890 /* signextend(hw1[10:0]) -> offset[:12]. */
9891 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9892 /* hw1[10:0] -> offset[11:1]. */
9893 offset |= (insn & 0x7ff) << 1;
9894 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9895 offset[24:22] already have the same value because of the
9896 sign extension above. */
9897 offset ^= ((~insn) & (1 << 13)) << 10;
9898 offset ^= ((~insn) & (1 << 11)) << 11;
9900 if (insn & (1 << 14)) {
9901 /* Branch and link. */
9902 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9905 offset += s->pc;
9906 if (insn & (1 << 12)) {
9907 /* b/bl */
9908 gen_jmp(s, offset);
9909 } else {
9910 /* blx */
9911 offset &= ~(uint32_t)2;
9912 /* thumb2 bx, no need to check */
9913 gen_bx_im(s, offset);
9915 } else if (((insn >> 23) & 7) == 7) {
9916 /* Misc control */
9917 if (insn & (1 << 13))
9918 goto illegal_op;
9920 if (insn & (1 << 26)) {
9921 if (!(insn & (1 << 20))) {
9922 /* Hypervisor call (v7) */
9923 int imm16 = extract32(insn, 16, 4) << 12
9924 | extract32(insn, 0, 12);
9925 ARCH(7);
9926 if (IS_USER(s)) {
9927 goto illegal_op;
9929 gen_hvc(s, imm16);
9930 } else {
9931 /* Secure monitor call (v6+) */
9932 ARCH(6K);
9933 if (IS_USER(s)) {
9934 goto illegal_op;
9936 gen_smc(s);
9938 } else {
9939 op = (insn >> 20) & 7;
9940 switch (op) {
9941 case 0: /* msr cpsr. */
9942 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9943 tmp = load_reg(s, rn);
9944 addr = tcg_const_i32(insn & 0xff);
9945 gen_helper_v7m_msr(cpu_env, addr, tmp);
9946 tcg_temp_free_i32(addr);
9947 tcg_temp_free_i32(tmp);
9948 gen_lookup_tb(s);
9949 break;
9951 /* fall through */
9952 case 1: /* msr spsr. */
9953 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9954 goto illegal_op;
9956 tmp = load_reg(s, rn);
9957 if (gen_set_psr(s,
9958 msr_mask(s, (insn >> 8) & 0xf, op == 1),
9959 op == 1, tmp))
9960 goto illegal_op;
9961 break;
9962 case 2: /* cps, nop-hint. */
9963 if (((insn >> 8) & 7) == 0) {
9964 gen_nop_hint(s, insn & 0xff);
9966 /* Implemented as NOP in user mode. */
9967 if (IS_USER(s))
9968 break;
9969 offset = 0;
9970 imm = 0;
9971 if (insn & (1 << 10)) {
9972 if (insn & (1 << 7))
9973 offset |= CPSR_A;
9974 if (insn & (1 << 6))
9975 offset |= CPSR_I;
9976 if (insn & (1 << 5))
9977 offset |= CPSR_F;
9978 if (insn & (1 << 9))
9979 imm = CPSR_A | CPSR_I | CPSR_F;
9981 if (insn & (1 << 8)) {
9982 offset |= 0x1f;
9983 imm |= (insn & 0x1f);
9985 if (offset) {
9986 gen_set_psr_im(s, offset, 0, imm);
9988 break;
9989 case 3: /* Special control operations. */
9990 ARCH(7);
9991 op = (insn >> 4) & 0xf;
9992 switch (op) {
9993 case 2: /* clrex */
9994 gen_clrex(s);
9995 break;
9996 case 4: /* dsb */
9997 case 5: /* dmb */
9998 case 6: /* isb */
9999 /* These execute as NOPs. */
10000 break;
10001 default:
10002 goto illegal_op;
10004 break;
10005 case 4: /* bxj */
10006 /* Trivial implementation equivalent to bx. */
10007 tmp = load_reg(s, rn);
10008 gen_bx(s, tmp);
10009 break;
10010 case 5: /* Exception return. */
10011 if (IS_USER(s)) {
10012 goto illegal_op;
10014 if (rn != 14 || rd != 15) {
10015 goto illegal_op;
10017 tmp = load_reg(s, rn);
10018 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10019 gen_exception_return(s, tmp);
10020 break;
10021 case 6: /* mrs cpsr. */
10022 tmp = tcg_temp_new_i32();
10023 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10024 addr = tcg_const_i32(insn & 0xff);
10025 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10026 tcg_temp_free_i32(addr);
10027 } else {
10028 gen_helper_cpsr_read(tmp, cpu_env);
10030 store_reg(s, rd, tmp);
10031 break;
10032 case 7: /* mrs spsr. */
10033 /* Not accessible in user mode. */
10034 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10035 goto illegal_op;
10037 tmp = load_cpu_field(spsr);
10038 store_reg(s, rd, tmp);
10039 break;
10042 } else {
10043 /* Conditional branch. */
10044 op = (insn >> 22) & 0xf;
10045 /* Generate a conditional jump to next instruction. */
10046 s->condlabel = gen_new_label();
10047 arm_gen_test_cc(op ^ 1, s->condlabel);
10048 s->condjmp = 1;
10050 /* offset[11:1] = insn[10:0] */
10051 offset = (insn & 0x7ff) << 1;
10052 /* offset[17:12] = insn[21:16]. */
10053 offset |= (insn & 0x003f0000) >> 4;
10054 /* offset[31:20] = insn[26]. */
10055 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10056 /* offset[18] = insn[13]. */
10057 offset |= (insn & (1 << 13)) << 5;
10058 /* offset[19] = insn[11]. */
10059 offset |= (insn & (1 << 11)) << 8;
10061 /* jump to the offset */
10062 gen_jmp(s, s->pc + offset);
10064 } else {
10065 /* Data processing immediate. */
10066 if (insn & (1 << 25)) {
10067 if (insn & (1 << 24)) {
10068 if (insn & (1 << 20))
10069 goto illegal_op;
10070 /* Bitfield/Saturate. */
10071 op = (insn >> 21) & 7;
10072 imm = insn & 0x1f;
10073 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10074 if (rn == 15) {
10075 tmp = tcg_temp_new_i32();
10076 tcg_gen_movi_i32(tmp, 0);
10077 } else {
10078 tmp = load_reg(s, rn);
10080 switch (op) {
10081 case 2: /* Signed bitfield extract. */
10082 imm++;
10083 if (shift + imm > 32)
10084 goto illegal_op;
10085 if (imm < 32)
10086 gen_sbfx(tmp, shift, imm);
10087 break;
10088 case 6: /* Unsigned bitfield extract. */
10089 imm++;
10090 if (shift + imm > 32)
10091 goto illegal_op;
10092 if (imm < 32)
10093 gen_ubfx(tmp, shift, (1u << imm) - 1);
10094 break;
10095 case 3: /* Bitfield insert/clear. */
10096 if (imm < shift)
10097 goto illegal_op;
10098 imm = imm + 1 - shift;
10099 if (imm != 32) {
10100 tmp2 = load_reg(s, rd);
10101 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10102 tcg_temp_free_i32(tmp2);
10104 break;
10105 case 7:
10106 goto illegal_op;
10107 default: /* Saturate. */
10108 if (shift) {
10109 if (op & 1)
10110 tcg_gen_sari_i32(tmp, tmp, shift);
10111 else
10112 tcg_gen_shli_i32(tmp, tmp, shift);
10114 tmp2 = tcg_const_i32(imm);
10115 if (op & 4) {
10116 /* Unsigned. */
10117 if ((op & 1) && shift == 0) {
10118 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10119 tcg_temp_free_i32(tmp);
10120 tcg_temp_free_i32(tmp2);
10121 goto illegal_op;
10123 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10124 } else {
10125 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10127 } else {
10128 /* Signed. */
10129 if ((op & 1) && shift == 0) {
10130 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10131 tcg_temp_free_i32(tmp);
10132 tcg_temp_free_i32(tmp2);
10133 goto illegal_op;
10135 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10136 } else {
10137 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10140 tcg_temp_free_i32(tmp2);
10141 break;
10143 store_reg(s, rd, tmp);
10144 } else {
10145 imm = ((insn & 0x04000000) >> 15)
10146 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10147 if (insn & (1 << 22)) {
10148 /* 16-bit immediate. */
10149 imm |= (insn >> 4) & 0xf000;
10150 if (insn & (1 << 23)) {
10151 /* movt */
10152 tmp = load_reg(s, rd);
10153 tcg_gen_ext16u_i32(tmp, tmp);
10154 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10155 } else {
10156 /* movw */
10157 tmp = tcg_temp_new_i32();
10158 tcg_gen_movi_i32(tmp, imm);
10160 } else {
10161 /* Add/sub 12-bit immediate. */
10162 if (rn == 15) {
10163 offset = s->pc & ~(uint32_t)3;
10164 if (insn & (1 << 23))
10165 offset -= imm;
10166 else
10167 offset += imm;
10168 tmp = tcg_temp_new_i32();
10169 tcg_gen_movi_i32(tmp, offset);
10170 } else {
10171 tmp = load_reg(s, rn);
10172 if (insn & (1 << 23))
10173 tcg_gen_subi_i32(tmp, tmp, imm);
10174 else
10175 tcg_gen_addi_i32(tmp, tmp, imm);
10178 store_reg(s, rd, tmp);
10180 } else {
10181 int shifter_out = 0;
10182 /* modified 12-bit immediate. */
10183 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10184 imm = (insn & 0xff);
10185 switch (shift) {
10186 case 0: /* XY */
10187 /* Nothing to do. */
10188 break;
10189 case 1: /* 00XY00XY */
10190 imm |= imm << 16;
10191 break;
10192 case 2: /* XY00XY00 */
10193 imm |= imm << 16;
10194 imm <<= 8;
10195 break;
10196 case 3: /* XYXYXYXY */
10197 imm |= imm << 16;
10198 imm |= imm << 8;
10199 break;
10200 default: /* Rotated constant. */
10201 shift = (shift << 1) | (imm >> 7);
10202 imm |= 0x80;
10203 imm = imm << (32 - shift);
10204 shifter_out = 1;
10205 break;
10207 tmp2 = tcg_temp_new_i32();
10208 tcg_gen_movi_i32(tmp2, imm);
10209 rn = (insn >> 16) & 0xf;
10210 if (rn == 15) {
10211 tmp = tcg_temp_new_i32();
10212 tcg_gen_movi_i32(tmp, 0);
10213 } else {
10214 tmp = load_reg(s, rn);
10216 op = (insn >> 21) & 0xf;
10217 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10218 shifter_out, tmp, tmp2))
10219 goto illegal_op;
10220 tcg_temp_free_i32(tmp2);
10221 rd = (insn >> 8) & 0xf;
10222 if (rd != 15) {
10223 store_reg(s, rd, tmp);
10224 } else {
10225 tcg_temp_free_i32(tmp);
10229 break;
10230 case 12: /* Load/store single data item. */
10232 int postinc = 0;
10233 int writeback = 0;
10234 int memidx;
10235 if ((insn & 0x01100000) == 0x01000000) {
10236 if (disas_neon_ls_insn(s, insn)) {
10237 goto illegal_op;
10239 break;
10241 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10242 if (rs == 15) {
10243 if (!(insn & (1 << 20))) {
10244 goto illegal_op;
10246 if (op != 2) {
10247 /* Byte or halfword load space with dest == r15 : memory hints.
10248 * Catch them early so we don't emit pointless addressing code.
10249 * This space is a mix of:
10250 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10251 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10252 * cores)
10253 * unallocated hints, which must be treated as NOPs
10254 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10255 * which is easiest for the decoding logic
10256 * Some space which must UNDEF
10258 int op1 = (insn >> 23) & 3;
10259 int op2 = (insn >> 6) & 0x3f;
10260 if (op & 2) {
10261 goto illegal_op;
10263 if (rn == 15) {
10264 /* UNPREDICTABLE, unallocated hint or
10265 * PLD/PLDW/PLI (literal)
10267 return 0;
10269 if (op1 & 1) {
10270 return 0; /* PLD/PLDW/PLI or unallocated hint */
10272 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10273 return 0; /* PLD/PLDW/PLI or unallocated hint */
10275 /* UNDEF space, or an UNPREDICTABLE */
10276 return 1;
10279 memidx = get_mem_index(s);
10280 if (rn == 15) {
10281 addr = tcg_temp_new_i32();
10282 /* PC relative. */
10283 /* s->pc has already been incremented by 4. */
10284 imm = s->pc & 0xfffffffc;
10285 if (insn & (1 << 23))
10286 imm += insn & 0xfff;
10287 else
10288 imm -= insn & 0xfff;
10289 tcg_gen_movi_i32(addr, imm);
10290 } else {
10291 addr = load_reg(s, rn);
10292 if (insn & (1 << 23)) {
10293 /* Positive offset. */
10294 imm = insn & 0xfff;
10295 tcg_gen_addi_i32(addr, addr, imm);
10296 } else {
10297 imm = insn & 0xff;
10298 switch ((insn >> 8) & 0xf) {
10299 case 0x0: /* Shifted Register. */
10300 shift = (insn >> 4) & 0xf;
10301 if (shift > 3) {
10302 tcg_temp_free_i32(addr);
10303 goto illegal_op;
10305 tmp = load_reg(s, rm);
10306 if (shift)
10307 tcg_gen_shli_i32(tmp, tmp, shift);
10308 tcg_gen_add_i32(addr, addr, tmp);
10309 tcg_temp_free_i32(tmp);
10310 break;
10311 case 0xc: /* Negative offset. */
10312 tcg_gen_addi_i32(addr, addr, -imm);
10313 break;
10314 case 0xe: /* User privilege. */
10315 tcg_gen_addi_i32(addr, addr, imm);
10316 memidx = get_a32_user_mem_index(s);
10317 break;
10318 case 0x9: /* Post-decrement. */
10319 imm = -imm;
10320 /* Fall through. */
10321 case 0xb: /* Post-increment. */
10322 postinc = 1;
10323 writeback = 1;
10324 break;
10325 case 0xd: /* Pre-decrement. */
10326 imm = -imm;
10327 /* Fall through. */
10328 case 0xf: /* Pre-increment. */
10329 tcg_gen_addi_i32(addr, addr, imm);
10330 writeback = 1;
10331 break;
10332 default:
10333 tcg_temp_free_i32(addr);
10334 goto illegal_op;
10338 if (insn & (1 << 20)) {
10339 /* Load. */
10340 tmp = tcg_temp_new_i32();
10341 switch (op) {
10342 case 0:
10343 gen_aa32_ld8u(tmp, addr, memidx);
10344 break;
10345 case 4:
10346 gen_aa32_ld8s(tmp, addr, memidx);
10347 break;
10348 case 1:
10349 gen_aa32_ld16u(tmp, addr, memidx);
10350 break;
10351 case 5:
10352 gen_aa32_ld16s(tmp, addr, memidx);
10353 break;
10354 case 2:
10355 gen_aa32_ld32u(tmp, addr, memidx);
10356 break;
10357 default:
10358 tcg_temp_free_i32(tmp);
10359 tcg_temp_free_i32(addr);
10360 goto illegal_op;
10362 if (rs == 15) {
10363 gen_bx(s, tmp);
10364 } else {
10365 store_reg(s, rs, tmp);
10367 } else {
10368 /* Store. */
10369 tmp = load_reg(s, rs);
10370 switch (op) {
10371 case 0:
10372 gen_aa32_st8(tmp, addr, memidx);
10373 break;
10374 case 1:
10375 gen_aa32_st16(tmp, addr, memidx);
10376 break;
10377 case 2:
10378 gen_aa32_st32(tmp, addr, memidx);
10379 break;
10380 default:
10381 tcg_temp_free_i32(tmp);
10382 tcg_temp_free_i32(addr);
10383 goto illegal_op;
10385 tcg_temp_free_i32(tmp);
10387 if (postinc)
10388 tcg_gen_addi_i32(addr, addr, imm);
10389 if (writeback) {
10390 store_reg(s, rn, addr);
10391 } else {
10392 tcg_temp_free_i32(addr);
10395 break;
10396 default:
10397 goto illegal_op;
10399 return 0;
10400 illegal_op:
10401 return 1;
10404 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10406 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10407 int32_t offset;
10408 int i;
10409 TCGv_i32 tmp;
10410 TCGv_i32 tmp2;
10411 TCGv_i32 addr;
10413 if (s->condexec_mask) {
10414 cond = s->condexec_cond;
10415 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10416 s->condlabel = gen_new_label();
10417 arm_gen_test_cc(cond ^ 1, s->condlabel);
10418 s->condjmp = 1;
10422 insn = arm_lduw_code(env, s->pc, s->bswap_code);
10423 s->pc += 2;
10425 switch (insn >> 12) {
10426 case 0: case 1:
10428 rd = insn & 7;
10429 op = (insn >> 11) & 3;
10430 if (op == 3) {
10431 /* add/subtract */
10432 rn = (insn >> 3) & 7;
10433 tmp = load_reg(s, rn);
10434 if (insn & (1 << 10)) {
10435 /* immediate */
10436 tmp2 = tcg_temp_new_i32();
10437 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10438 } else {
10439 /* reg */
10440 rm = (insn >> 6) & 7;
10441 tmp2 = load_reg(s, rm);
10443 if (insn & (1 << 9)) {
10444 if (s->condexec_mask)
10445 tcg_gen_sub_i32(tmp, tmp, tmp2);
10446 else
10447 gen_sub_CC(tmp, tmp, tmp2);
10448 } else {
10449 if (s->condexec_mask)
10450 tcg_gen_add_i32(tmp, tmp, tmp2);
10451 else
10452 gen_add_CC(tmp, tmp, tmp2);
10454 tcg_temp_free_i32(tmp2);
10455 store_reg(s, rd, tmp);
10456 } else {
10457 /* shift immediate */
10458 rm = (insn >> 3) & 7;
10459 shift = (insn >> 6) & 0x1f;
10460 tmp = load_reg(s, rm);
10461 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10462 if (!s->condexec_mask)
10463 gen_logic_CC(tmp);
10464 store_reg(s, rd, tmp);
10466 break;
10467 case 2: case 3:
10468 /* arithmetic large immediate */
10469 op = (insn >> 11) & 3;
10470 rd = (insn >> 8) & 0x7;
10471 if (op == 0) { /* mov */
10472 tmp = tcg_temp_new_i32();
10473 tcg_gen_movi_i32(tmp, insn & 0xff);
10474 if (!s->condexec_mask)
10475 gen_logic_CC(tmp);
10476 store_reg(s, rd, tmp);
10477 } else {
10478 tmp = load_reg(s, rd);
10479 tmp2 = tcg_temp_new_i32();
10480 tcg_gen_movi_i32(tmp2, insn & 0xff);
10481 switch (op) {
10482 case 1: /* cmp */
10483 gen_sub_CC(tmp, tmp, tmp2);
10484 tcg_temp_free_i32(tmp);
10485 tcg_temp_free_i32(tmp2);
10486 break;
10487 case 2: /* add */
10488 if (s->condexec_mask)
10489 tcg_gen_add_i32(tmp, tmp, tmp2);
10490 else
10491 gen_add_CC(tmp, tmp, tmp2);
10492 tcg_temp_free_i32(tmp2);
10493 store_reg(s, rd, tmp);
10494 break;
10495 case 3: /* sub */
10496 if (s->condexec_mask)
10497 tcg_gen_sub_i32(tmp, tmp, tmp2);
10498 else
10499 gen_sub_CC(tmp, tmp, tmp2);
10500 tcg_temp_free_i32(tmp2);
10501 store_reg(s, rd, tmp);
10502 break;
10505 break;
10506 case 4:
10507 if (insn & (1 << 11)) {
10508 rd = (insn >> 8) & 7;
10509 /* load pc-relative. Bit 1 of PC is ignored. */
10510 val = s->pc + 2 + ((insn & 0xff) * 4);
10511 val &= ~(uint32_t)2;
10512 addr = tcg_temp_new_i32();
10513 tcg_gen_movi_i32(addr, val);
10514 tmp = tcg_temp_new_i32();
10515 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10516 tcg_temp_free_i32(addr);
10517 store_reg(s, rd, tmp);
10518 break;
10520 if (insn & (1 << 10)) {
10521 /* data processing extended or blx */
10522 rd = (insn & 7) | ((insn >> 4) & 8);
10523 rm = (insn >> 3) & 0xf;
10524 op = (insn >> 8) & 3;
10525 switch (op) {
10526 case 0: /* add */
10527 tmp = load_reg(s, rd);
10528 tmp2 = load_reg(s, rm);
10529 tcg_gen_add_i32(tmp, tmp, tmp2);
10530 tcg_temp_free_i32(tmp2);
10531 store_reg(s, rd, tmp);
10532 break;
10533 case 1: /* cmp */
10534 tmp = load_reg(s, rd);
10535 tmp2 = load_reg(s, rm);
10536 gen_sub_CC(tmp, tmp, tmp2);
10537 tcg_temp_free_i32(tmp2);
10538 tcg_temp_free_i32(tmp);
10539 break;
10540 case 2: /* mov/cpy */
10541 tmp = load_reg(s, rm);
10542 store_reg(s, rd, tmp);
10543 break;
10544 case 3:/* branch [and link] exchange thumb register */
10545 tmp = load_reg(s, rm);
10546 if (insn & (1 << 7)) {
10547 ARCH(5);
10548 val = (uint32_t)s->pc | 1;
10549 tmp2 = tcg_temp_new_i32();
10550 tcg_gen_movi_i32(tmp2, val);
10551 store_reg(s, 14, tmp2);
10553 /* already thumb, no need to check */
10554 gen_bx(s, tmp);
10555 break;
10557 break;
10560 /* data processing register */
10561 rd = insn & 7;
10562 rm = (insn >> 3) & 7;
10563 op = (insn >> 6) & 0xf;
10564 if (op == 2 || op == 3 || op == 4 || op == 7) {
10565 /* the shift/rotate ops want the operands backwards */
10566 val = rm;
10567 rm = rd;
10568 rd = val;
10569 val = 1;
10570 } else {
10571 val = 0;
10574 if (op == 9) { /* neg */
10575 tmp = tcg_temp_new_i32();
10576 tcg_gen_movi_i32(tmp, 0);
10577 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10578 tmp = load_reg(s, rd);
10579 } else {
10580 TCGV_UNUSED_I32(tmp);
10583 tmp2 = load_reg(s, rm);
10584 switch (op) {
10585 case 0x0: /* and */
10586 tcg_gen_and_i32(tmp, tmp, tmp2);
10587 if (!s->condexec_mask)
10588 gen_logic_CC(tmp);
10589 break;
10590 case 0x1: /* eor */
10591 tcg_gen_xor_i32(tmp, tmp, tmp2);
10592 if (!s->condexec_mask)
10593 gen_logic_CC(tmp);
10594 break;
10595 case 0x2: /* lsl */
10596 if (s->condexec_mask) {
10597 gen_shl(tmp2, tmp2, tmp);
10598 } else {
10599 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10600 gen_logic_CC(tmp2);
10602 break;
10603 case 0x3: /* lsr */
10604 if (s->condexec_mask) {
10605 gen_shr(tmp2, tmp2, tmp);
10606 } else {
10607 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10608 gen_logic_CC(tmp2);
10610 break;
10611 case 0x4: /* asr */
10612 if (s->condexec_mask) {
10613 gen_sar(tmp2, tmp2, tmp);
10614 } else {
10615 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10616 gen_logic_CC(tmp2);
10618 break;
10619 case 0x5: /* adc */
10620 if (s->condexec_mask) {
10621 gen_adc(tmp, tmp2);
10622 } else {
10623 gen_adc_CC(tmp, tmp, tmp2);
10625 break;
10626 case 0x6: /* sbc */
10627 if (s->condexec_mask) {
10628 gen_sub_carry(tmp, tmp, tmp2);
10629 } else {
10630 gen_sbc_CC(tmp, tmp, tmp2);
10632 break;
10633 case 0x7: /* ror */
10634 if (s->condexec_mask) {
10635 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10636 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10637 } else {
10638 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10639 gen_logic_CC(tmp2);
10641 break;
10642 case 0x8: /* tst */
10643 tcg_gen_and_i32(tmp, tmp, tmp2);
10644 gen_logic_CC(tmp);
10645 rd = 16;
10646 break;
10647 case 0x9: /* neg */
10648 if (s->condexec_mask)
10649 tcg_gen_neg_i32(tmp, tmp2);
10650 else
10651 gen_sub_CC(tmp, tmp, tmp2);
10652 break;
10653 case 0xa: /* cmp */
10654 gen_sub_CC(tmp, tmp, tmp2);
10655 rd = 16;
10656 break;
10657 case 0xb: /* cmn */
10658 gen_add_CC(tmp, tmp, tmp2);
10659 rd = 16;
10660 break;
10661 case 0xc: /* orr */
10662 tcg_gen_or_i32(tmp, tmp, tmp2);
10663 if (!s->condexec_mask)
10664 gen_logic_CC(tmp);
10665 break;
10666 case 0xd: /* mul */
10667 tcg_gen_mul_i32(tmp, tmp, tmp2);
10668 if (!s->condexec_mask)
10669 gen_logic_CC(tmp);
10670 break;
10671 case 0xe: /* bic */
10672 tcg_gen_andc_i32(tmp, tmp, tmp2);
10673 if (!s->condexec_mask)
10674 gen_logic_CC(tmp);
10675 break;
10676 case 0xf: /* mvn */
10677 tcg_gen_not_i32(tmp2, tmp2);
10678 if (!s->condexec_mask)
10679 gen_logic_CC(tmp2);
10680 val = 1;
10681 rm = rd;
10682 break;
10684 if (rd != 16) {
10685 if (val) {
10686 store_reg(s, rm, tmp2);
10687 if (op != 0xf)
10688 tcg_temp_free_i32(tmp);
10689 } else {
10690 store_reg(s, rd, tmp);
10691 tcg_temp_free_i32(tmp2);
10693 } else {
10694 tcg_temp_free_i32(tmp);
10695 tcg_temp_free_i32(tmp2);
10697 break;
10699 case 5:
10700 /* load/store register offset. */
10701 rd = insn & 7;
10702 rn = (insn >> 3) & 7;
10703 rm = (insn >> 6) & 7;
10704 op = (insn >> 9) & 7;
10705 addr = load_reg(s, rn);
10706 tmp = load_reg(s, rm);
10707 tcg_gen_add_i32(addr, addr, tmp);
10708 tcg_temp_free_i32(tmp);
10710 if (op < 3) { /* store */
10711 tmp = load_reg(s, rd);
10712 } else {
10713 tmp = tcg_temp_new_i32();
10716 switch (op) {
10717 case 0: /* str */
10718 gen_aa32_st32(tmp, addr, get_mem_index(s));
10719 break;
10720 case 1: /* strh */
10721 gen_aa32_st16(tmp, addr, get_mem_index(s));
10722 break;
10723 case 2: /* strb */
10724 gen_aa32_st8(tmp, addr, get_mem_index(s));
10725 break;
10726 case 3: /* ldrsb */
10727 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
10728 break;
10729 case 4: /* ldr */
10730 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10731 break;
10732 case 5: /* ldrh */
10733 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10734 break;
10735 case 6: /* ldrb */
10736 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10737 break;
10738 case 7: /* ldrsh */
10739 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
10740 break;
10742 if (op >= 3) { /* load */
10743 store_reg(s, rd, tmp);
10744 } else {
10745 tcg_temp_free_i32(tmp);
10747 tcg_temp_free_i32(addr);
10748 break;
10750 case 6:
10751 /* load/store word immediate offset */
10752 rd = insn & 7;
10753 rn = (insn >> 3) & 7;
10754 addr = load_reg(s, rn);
10755 val = (insn >> 4) & 0x7c;
10756 tcg_gen_addi_i32(addr, addr, val);
10758 if (insn & (1 << 11)) {
10759 /* load */
10760 tmp = tcg_temp_new_i32();
10761 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10762 store_reg(s, rd, tmp);
10763 } else {
10764 /* store */
10765 tmp = load_reg(s, rd);
10766 gen_aa32_st32(tmp, addr, get_mem_index(s));
10767 tcg_temp_free_i32(tmp);
10769 tcg_temp_free_i32(addr);
10770 break;
10772 case 7:
10773 /* load/store byte immediate offset */
10774 rd = insn & 7;
10775 rn = (insn >> 3) & 7;
10776 addr = load_reg(s, rn);
10777 val = (insn >> 6) & 0x1f;
10778 tcg_gen_addi_i32(addr, addr, val);
10780 if (insn & (1 << 11)) {
10781 /* load */
10782 tmp = tcg_temp_new_i32();
10783 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10784 store_reg(s, rd, tmp);
10785 } else {
10786 /* store */
10787 tmp = load_reg(s, rd);
10788 gen_aa32_st8(tmp, addr, get_mem_index(s));
10789 tcg_temp_free_i32(tmp);
10791 tcg_temp_free_i32(addr);
10792 break;
10794 case 8:
10795 /* load/store halfword immediate offset */
10796 rd = insn & 7;
10797 rn = (insn >> 3) & 7;
10798 addr = load_reg(s, rn);
10799 val = (insn >> 5) & 0x3e;
10800 tcg_gen_addi_i32(addr, addr, val);
10802 if (insn & (1 << 11)) {
10803 /* load */
10804 tmp = tcg_temp_new_i32();
10805 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10806 store_reg(s, rd, tmp);
10807 } else {
10808 /* store */
10809 tmp = load_reg(s, rd);
10810 gen_aa32_st16(tmp, addr, get_mem_index(s));
10811 tcg_temp_free_i32(tmp);
10813 tcg_temp_free_i32(addr);
10814 break;
10816 case 9:
10817 /* load/store from stack */
10818 rd = (insn >> 8) & 7;
10819 addr = load_reg(s, 13);
10820 val = (insn & 0xff) * 4;
10821 tcg_gen_addi_i32(addr, addr, val);
10823 if (insn & (1 << 11)) {
10824 /* load */
10825 tmp = tcg_temp_new_i32();
10826 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10827 store_reg(s, rd, tmp);
10828 } else {
10829 /* store */
10830 tmp = load_reg(s, rd);
10831 gen_aa32_st32(tmp, addr, get_mem_index(s));
10832 tcg_temp_free_i32(tmp);
10834 tcg_temp_free_i32(addr);
10835 break;
10837 case 10:
10838 /* add to high reg */
10839 rd = (insn >> 8) & 7;
10840 if (insn & (1 << 11)) {
10841 /* SP */
10842 tmp = load_reg(s, 13);
10843 } else {
10844 /* PC. bit 1 is ignored. */
10845 tmp = tcg_temp_new_i32();
10846 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10848 val = (insn & 0xff) * 4;
10849 tcg_gen_addi_i32(tmp, tmp, val);
10850 store_reg(s, rd, tmp);
10851 break;
10853 case 11:
10854 /* misc */
10855 op = (insn >> 8) & 0xf;
10856 switch (op) {
10857 case 0:
10858 /* adjust stack pointer */
10859 tmp = load_reg(s, 13);
10860 val = (insn & 0x7f) * 4;
10861 if (insn & (1 << 7))
10862 val = -(int32_t)val;
10863 tcg_gen_addi_i32(tmp, tmp, val);
10864 store_reg(s, 13, tmp);
10865 break;
10867 case 2: /* sign/zero extend. */
10868 ARCH(6);
10869 rd = insn & 7;
10870 rm = (insn >> 3) & 7;
10871 tmp = load_reg(s, rm);
10872 switch ((insn >> 6) & 3) {
10873 case 0: gen_sxth(tmp); break;
10874 case 1: gen_sxtb(tmp); break;
10875 case 2: gen_uxth(tmp); break;
10876 case 3: gen_uxtb(tmp); break;
10878 store_reg(s, rd, tmp);
10879 break;
10880 case 4: case 5: case 0xc: case 0xd:
10881 /* push/pop */
10882 addr = load_reg(s, 13);
10883 if (insn & (1 << 8))
10884 offset = 4;
10885 else
10886 offset = 0;
10887 for (i = 0; i < 8; i++) {
10888 if (insn & (1 << i))
10889 offset += 4;
10891 if ((insn & (1 << 11)) == 0) {
10892 tcg_gen_addi_i32(addr, addr, -offset);
10894 for (i = 0; i < 8; i++) {
10895 if (insn & (1 << i)) {
10896 if (insn & (1 << 11)) {
10897 /* pop */
10898 tmp = tcg_temp_new_i32();
10899 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10900 store_reg(s, i, tmp);
10901 } else {
10902 /* push */
10903 tmp = load_reg(s, i);
10904 gen_aa32_st32(tmp, addr, get_mem_index(s));
10905 tcg_temp_free_i32(tmp);
10907 /* advance to the next address. */
10908 tcg_gen_addi_i32(addr, addr, 4);
10911 TCGV_UNUSED_I32(tmp);
10912 if (insn & (1 << 8)) {
10913 if (insn & (1 << 11)) {
10914 /* pop pc */
10915 tmp = tcg_temp_new_i32();
10916 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10917 /* don't set the pc until the rest of the instruction
10918 has completed */
10919 } else {
10920 /* push lr */
10921 tmp = load_reg(s, 14);
10922 gen_aa32_st32(tmp, addr, get_mem_index(s));
10923 tcg_temp_free_i32(tmp);
10925 tcg_gen_addi_i32(addr, addr, 4);
10927 if ((insn & (1 << 11)) == 0) {
10928 tcg_gen_addi_i32(addr, addr, -offset);
10930 /* write back the new stack pointer */
10931 store_reg(s, 13, addr);
10932 /* set the new PC value */
10933 if ((insn & 0x0900) == 0x0900) {
10934 store_reg_from_load(s, 15, tmp);
10936 break;
10938 case 1: case 3: case 9: case 11: /* czb */
10939 rm = insn & 7;
10940 tmp = load_reg(s, rm);
10941 s->condlabel = gen_new_label();
10942 s->condjmp = 1;
10943 if (insn & (1 << 11))
10944 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10945 else
10946 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10947 tcg_temp_free_i32(tmp);
10948 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10949 val = (uint32_t)s->pc + 2;
10950 val += offset;
10951 gen_jmp(s, val);
10952 break;
10954 case 15: /* IT, nop-hint. */
10955 if ((insn & 0xf) == 0) {
10956 gen_nop_hint(s, (insn >> 4) & 0xf);
10957 break;
10959 /* If Then. */
10960 s->condexec_cond = (insn >> 4) & 0xe;
10961 s->condexec_mask = insn & 0x1f;
10962 /* No actual code generated for this insn, just setup state. */
10963 break;
10965 case 0xe: /* bkpt */
10967 int imm8 = extract32(insn, 0, 8);
10968 ARCH(5);
10969 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
10970 default_exception_el(s));
10971 break;
10974 case 0xa: /* rev */
10975 ARCH(6);
10976 rn = (insn >> 3) & 0x7;
10977 rd = insn & 0x7;
10978 tmp = load_reg(s, rn);
10979 switch ((insn >> 6) & 3) {
10980 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10981 case 1: gen_rev16(tmp); break;
10982 case 3: gen_revsh(tmp); break;
10983 default: goto illegal_op;
10985 store_reg(s, rd, tmp);
10986 break;
10988 case 6:
10989 switch ((insn >> 5) & 7) {
10990 case 2:
10991 /* setend */
10992 ARCH(6);
10993 if (((insn >> 3) & 1) != s->bswap_code) {
10994 /* Dynamic endianness switching not implemented. */
10995 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10996 goto illegal_op;
10998 break;
10999 case 3:
11000 /* cps */
11001 ARCH(6);
11002 if (IS_USER(s)) {
11003 break;
11005 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11006 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11007 /* FAULTMASK */
11008 if (insn & 1) {
11009 addr = tcg_const_i32(19);
11010 gen_helper_v7m_msr(cpu_env, addr, tmp);
11011 tcg_temp_free_i32(addr);
11013 /* PRIMASK */
11014 if (insn & 2) {
11015 addr = tcg_const_i32(16);
11016 gen_helper_v7m_msr(cpu_env, addr, tmp);
11017 tcg_temp_free_i32(addr);
11019 tcg_temp_free_i32(tmp);
11020 gen_lookup_tb(s);
11021 } else {
11022 if (insn & (1 << 4)) {
11023 shift = CPSR_A | CPSR_I | CPSR_F;
11024 } else {
11025 shift = 0;
11027 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11029 break;
11030 default:
11031 goto undef;
11033 break;
11035 default:
11036 goto undef;
11038 break;
11040 case 12:
11042 /* load/store multiple */
11043 TCGv_i32 loaded_var;
11044 TCGV_UNUSED_I32(loaded_var);
11045 rn = (insn >> 8) & 0x7;
11046 addr = load_reg(s, rn);
11047 for (i = 0; i < 8; i++) {
11048 if (insn & (1 << i)) {
11049 if (insn & (1 << 11)) {
11050 /* load */
11051 tmp = tcg_temp_new_i32();
11052 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
11053 if (i == rn) {
11054 loaded_var = tmp;
11055 } else {
11056 store_reg(s, i, tmp);
11058 } else {
11059 /* store */
11060 tmp = load_reg(s, i);
11061 gen_aa32_st32(tmp, addr, get_mem_index(s));
11062 tcg_temp_free_i32(tmp);
11064 /* advance to the next address */
11065 tcg_gen_addi_i32(addr, addr, 4);
11068 if ((insn & (1 << rn)) == 0) {
11069 /* base reg not in list: base register writeback */
11070 store_reg(s, rn, addr);
11071 } else {
11072 /* base reg in list: if load, complete it now */
11073 if (insn & (1 << 11)) {
11074 store_reg(s, rn, loaded_var);
11076 tcg_temp_free_i32(addr);
11078 break;
11080 case 13:
11081 /* conditional branch or swi */
11082 cond = (insn >> 8) & 0xf;
11083 if (cond == 0xe)
11084 goto undef;
11086 if (cond == 0xf) {
11087 /* swi */
11088 gen_set_pc_im(s, s->pc);
11089 s->svc_imm = extract32(insn, 0, 8);
11090 s->is_jmp = DISAS_SWI;
11091 break;
11093 /* generate a conditional jump to next instruction */
11094 s->condlabel = gen_new_label();
11095 arm_gen_test_cc(cond ^ 1, s->condlabel);
11096 s->condjmp = 1;
11098 /* jump to the offset */
11099 val = (uint32_t)s->pc + 2;
11100 offset = ((int32_t)insn << 24) >> 24;
11101 val += offset << 1;
11102 gen_jmp(s, val);
11103 break;
11105 case 14:
11106 if (insn & (1 << 11)) {
11107 if (disas_thumb2_insn(env, s, insn))
11108 goto undef32;
11109 break;
11111 /* unconditional branch */
11112 val = (uint32_t)s->pc;
11113 offset = ((int32_t)insn << 21) >> 21;
11114 val += (offset << 1) + 2;
11115 gen_jmp(s, val);
11116 break;
11118 case 15:
11119 if (disas_thumb2_insn(env, s, insn))
11120 goto undef32;
11121 break;
11123 return;
11124 undef32:
11125 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11126 default_exception_el(s));
11127 return;
11128 illegal_op:
11129 undef:
11130 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11131 default_exception_el(s));
11134 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
11135 basic block 'tb'. If search_pc is TRUE, also generate PC
11136 information for each intermediate instruction. */
11137 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
11138 TranslationBlock *tb,
11139 bool search_pc)
11141 CPUState *cs = CPU(cpu);
11142 CPUARMState *env = &cpu->env;
11143 DisasContext dc1, *dc = &dc1;
11144 CPUBreakpoint *bp;
11145 int j, lj;
11146 target_ulong pc_start;
11147 target_ulong next_page_start;
11148 int num_insns;
11149 int max_insns;
11151 /* generate intermediate code */
11153 /* The A64 decoder has its own top level loop, because it doesn't need
11154 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11156 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11157 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
11158 return;
11161 pc_start = tb->pc;
11163 dc->tb = tb;
11165 dc->is_jmp = DISAS_NEXT;
11166 dc->pc = pc_start;
11167 dc->singlestep_enabled = cs->singlestep_enabled;
11168 dc->condjmp = 0;
11170 dc->aarch64 = 0;
11171 dc->el3_is_aa64 = arm_el_is_aa64(env, 3);
11172 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11173 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
11174 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11175 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11176 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11177 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11178 #if !defined(CONFIG_USER_ONLY)
11179 dc->user = (dc->current_el == 0);
11180 #endif
11181 dc->ns = ARM_TBFLAG_NS(tb->flags);
11182 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11183 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11184 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11185 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11186 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11187 dc->cp_regs = cpu->cp_regs;
11188 dc->features = env->features;
11190 /* Single step state. The code-generation logic here is:
11191 * SS_ACTIVE == 0:
11192 * generate code with no special handling for single-stepping (except
11193 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11194 * this happens anyway because those changes are all system register or
11195 * PSTATE writes).
11196 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11197 * emit code for one insn
11198 * emit code to clear PSTATE.SS
11199 * emit code to generate software step exception for completed step
11200 * end TB (as usual for having generated an exception)
11201 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11202 * emit code to generate a software step exception
11203 * end the TB
11205 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11206 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11207 dc->is_ldex = false;
11208 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11210 cpu_F0s = tcg_temp_new_i32();
11211 cpu_F1s = tcg_temp_new_i32();
11212 cpu_F0d = tcg_temp_new_i64();
11213 cpu_F1d = tcg_temp_new_i64();
11214 cpu_V0 = cpu_F0d;
11215 cpu_V1 = cpu_F1d;
11216 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11217 cpu_M0 = tcg_temp_new_i64();
11218 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11219 lj = -1;
11220 num_insns = 0;
11221 max_insns = tb->cflags & CF_COUNT_MASK;
11222 if (max_insns == 0)
11223 max_insns = CF_COUNT_MASK;
11225 gen_tb_start(tb);
11227 tcg_clear_temp_count();
11229 /* A note on handling of the condexec (IT) bits:
11231 * We want to avoid the overhead of having to write the updated condexec
11232 * bits back to the CPUARMState for every instruction in an IT block. So:
11233 * (1) if the condexec bits are not already zero then we write
11234 * zero back into the CPUARMState now. This avoids complications trying
11235 * to do it at the end of the block. (For example if we don't do this
11236 * it's hard to identify whether we can safely skip writing condexec
11237 * at the end of the TB, which we definitely want to do for the case
11238 * where a TB doesn't do anything with the IT state at all.)
11239 * (2) if we are going to leave the TB then we call gen_set_condexec()
11240 * which will write the correct value into CPUARMState if zero is wrong.
11241 * This is done both for leaving the TB at the end, and for leaving
11242 * it because of an exception we know will happen, which is done in
11243 * gen_exception_insn(). The latter is necessary because we need to
11244 * leave the TB with the PC/IT state just prior to execution of the
11245 * instruction which caused the exception.
11246 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11247 * then the CPUARMState will be wrong and we need to reset it.
11248 * This is handled in the same way as restoration of the
11249 * PC in these situations: we will be called again with search_pc=1
11250 * and generate a mapping of the condexec bits for each PC in
11251 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11252 * this to restore the condexec bits.
11254 * Note that there are no instructions which can read the condexec
11255 * bits, and none which can write non-static values to them, so
11256 * we don't need to care about whether CPUARMState is correct in the
11257 * middle of a TB.
11260 /* Reset the conditional execution bits immediately. This avoids
11261 complications trying to do it at the end of the block. */
11262 if (dc->condexec_mask || dc->condexec_cond)
11264 TCGv_i32 tmp = tcg_temp_new_i32();
11265 tcg_gen_movi_i32(tmp, 0);
11266 store_cpu_field(tmp, condexec_bits);
11268 do {
11269 #ifdef CONFIG_USER_ONLY
11270 /* Intercept jump to the magic kernel page. */
11271 if (dc->pc >= 0xffff0000) {
11272 /* We always get here via a jump, so know we are not in a
11273 conditional execution block. */
11274 gen_exception_internal(EXCP_KERNEL_TRAP);
11275 dc->is_jmp = DISAS_UPDATE;
11276 break;
11278 #else
11279 if (dc->pc >= 0xfffffff0 && arm_dc_feature(dc, ARM_FEATURE_M)) {
11280 /* We always get here via a jump, so know we are not in a
11281 conditional execution block. */
11282 gen_exception_internal(EXCP_EXCEPTION_EXIT);
11283 dc->is_jmp = DISAS_UPDATE;
11284 break;
11286 #endif
11288 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11289 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11290 if (bp->pc == dc->pc) {
11291 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11292 /* Advance PC so that clearing the breakpoint will
11293 invalidate this TB. */
11294 dc->pc += 2;
11295 goto done_generating;
11299 if (search_pc) {
11300 j = tcg_op_buf_count();
11301 if (lj < j) {
11302 lj++;
11303 while (lj < j)
11304 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11306 tcg_ctx.gen_opc_pc[lj] = dc->pc;
11307 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
11308 tcg_ctx.gen_opc_instr_start[lj] = 1;
11309 tcg_ctx.gen_opc_icount[lj] = num_insns;
11312 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
11313 gen_io_start();
11315 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
11316 tcg_gen_debug_insn_start(dc->pc);
11319 if (dc->ss_active && !dc->pstate_ss) {
11320 /* Singlestep state is Active-pending.
11321 * If we're in this state at the start of a TB then either
11322 * a) we just took an exception to an EL which is being debugged
11323 * and this is the first insn in the exception handler
11324 * b) debug exceptions were masked and we just unmasked them
11325 * without changing EL (eg by clearing PSTATE.D)
11326 * In either case we're going to take a swstep exception in the
11327 * "did not step an insn" case, and so the syndrome ISV and EX
11328 * bits should be zero.
11330 assert(num_insns == 0);
11331 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11332 default_exception_el(dc));
11333 goto done_generating;
11336 if (dc->thumb) {
11337 disas_thumb_insn(env, dc);
11338 if (dc->condexec_mask) {
11339 dc->condexec_cond = (dc->condexec_cond & 0xe)
11340 | ((dc->condexec_mask >> 4) & 1);
11341 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11342 if (dc->condexec_mask == 0) {
11343 dc->condexec_cond = 0;
11346 } else {
11347 unsigned int insn = arm_ldl_code(env, dc->pc, dc->bswap_code);
11348 dc->pc += 4;
11349 disas_arm_insn(dc, insn);
11352 if (dc->condjmp && !dc->is_jmp) {
11353 gen_set_label(dc->condlabel);
11354 dc->condjmp = 0;
11357 if (tcg_check_temp_count()) {
11358 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11359 dc->pc);
11362 /* Translation stops when a conditional branch is encountered.
11363 * Otherwise the subsequent code could get translated several times.
11364 * Also stop translation when a page boundary is reached. This
11365 * ensures prefetch aborts occur at the right place. */
11366 num_insns ++;
11367 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11368 !cs->singlestep_enabled &&
11369 !singlestep &&
11370 !dc->ss_active &&
11371 dc->pc < next_page_start &&
11372 num_insns < max_insns);
11374 if (tb->cflags & CF_LAST_IO) {
11375 if (dc->condjmp) {
11376 /* FIXME: This can theoretically happen with self-modifying
11377 code. */
11378 cpu_abort(cs, "IO on conditional branch instruction");
11380 gen_io_end();
11383 /* At this stage dc->condjmp will only be set when the skipped
11384 instruction was a conditional branch or trap, and the PC has
11385 already been written. */
11386 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11387 /* Make sure the pc is updated, and raise a debug exception. */
11388 if (dc->condjmp) {
11389 gen_set_condexec(dc);
11390 if (dc->is_jmp == DISAS_SWI) {
11391 gen_ss_advance(dc);
11392 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11393 default_exception_el(dc));
11394 } else if (dc->is_jmp == DISAS_HVC) {
11395 gen_ss_advance(dc);
11396 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11397 } else if (dc->is_jmp == DISAS_SMC) {
11398 gen_ss_advance(dc);
11399 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11400 } else if (dc->ss_active) {
11401 gen_step_complete_exception(dc);
11402 } else {
11403 gen_exception_internal(EXCP_DEBUG);
11405 gen_set_label(dc->condlabel);
11407 if (dc->condjmp || !dc->is_jmp) {
11408 gen_set_pc_im(dc, dc->pc);
11409 dc->condjmp = 0;
11411 gen_set_condexec(dc);
11412 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
11413 gen_ss_advance(dc);
11414 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11415 default_exception_el(dc));
11416 } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
11417 gen_ss_advance(dc);
11418 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11419 } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
11420 gen_ss_advance(dc);
11421 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11422 } else if (dc->ss_active) {
11423 gen_step_complete_exception(dc);
11424 } else {
11425 /* FIXME: Single stepping a WFI insn will not halt
11426 the CPU. */
11427 gen_exception_internal(EXCP_DEBUG);
11429 } else {
11430 /* While branches must always occur at the end of an IT block,
11431 there are a few other things that can cause us to terminate
11432 the TB in the middle of an IT block:
11433 - Exception generating instructions (bkpt, swi, undefined).
11434 - Page boundaries.
11435 - Hardware watchpoints.
11436 Hardware breakpoints have already been handled and skip this code.
11438 gen_set_condexec(dc);
11439 switch(dc->is_jmp) {
11440 case DISAS_NEXT:
11441 gen_goto_tb(dc, 1, dc->pc);
11442 break;
11443 default:
11444 case DISAS_JUMP:
11445 case DISAS_UPDATE:
11446 /* indicate that the hash table must be used to find the next TB */
11447 tcg_gen_exit_tb(0);
11448 break;
11449 case DISAS_TB_JUMP:
11450 /* nothing more to generate */
11451 break;
11452 case DISAS_WFI:
11453 gen_helper_wfi(cpu_env);
11454 /* The helper doesn't necessarily throw an exception, but we
11455 * must go back to the main loop to check for interrupts anyway.
11457 tcg_gen_exit_tb(0);
11458 break;
11459 case DISAS_WFE:
11460 gen_helper_wfe(cpu_env);
11461 break;
11462 case DISAS_SWI:
11463 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11464 default_exception_el(dc));
11465 break;
11466 case DISAS_HVC:
11467 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11468 break;
11469 case DISAS_SMC:
11470 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11471 break;
11473 if (dc->condjmp) {
11474 gen_set_label(dc->condlabel);
11475 gen_set_condexec(dc);
11476 gen_goto_tb(dc, 1, dc->pc);
11477 dc->condjmp = 0;
11481 done_generating:
11482 gen_tb_end(tb, num_insns);
11484 #ifdef DEBUG_DISAS
11485 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11486 qemu_log("----------------\n");
11487 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11488 log_target_disas(env, pc_start, dc->pc - pc_start,
11489 dc->thumb | (dc->bswap_code << 1));
11490 qemu_log("\n");
11492 #endif
11493 if (search_pc) {
11494 j = tcg_op_buf_count();
11495 lj++;
11496 while (lj <= j)
11497 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11498 } else {
11499 tb->size = dc->pc - pc_start;
11500 tb->icount = num_insns;
11504 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11506 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
11509 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
11511 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
11514 static const char *cpu_mode_names[16] = {
11515 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11516 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11519 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11520 int flags)
11522 ARMCPU *cpu = ARM_CPU(cs);
11523 CPUARMState *env = &cpu->env;
11524 int i;
11525 uint32_t psr;
11527 if (is_a64(env)) {
11528 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11529 return;
11532 for(i=0;i<16;i++) {
11533 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11534 if ((i % 4) == 3)
11535 cpu_fprintf(f, "\n");
11536 else
11537 cpu_fprintf(f, " ");
11539 psr = cpsr_read(env);
11540 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11541 psr,
11542 psr & (1 << 31) ? 'N' : '-',
11543 psr & (1 << 30) ? 'Z' : '-',
11544 psr & (1 << 29) ? 'C' : '-',
11545 psr & (1 << 28) ? 'V' : '-',
11546 psr & CPSR_T ? 'T' : 'A',
11547 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11549 if (flags & CPU_DUMP_FPU) {
11550 int numvfpregs = 0;
11551 if (arm_feature(env, ARM_FEATURE_VFP)) {
11552 numvfpregs += 16;
11554 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11555 numvfpregs += 16;
11557 for (i = 0; i < numvfpregs; i++) {
11558 uint64_t v = float64_val(env->vfp.regs[i]);
11559 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11560 i * 2, (uint32_t)v,
11561 i * 2 + 1, (uint32_t)(v >> 32),
11562 i, v);
11564 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11568 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11570 if (is_a64(env)) {
11571 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
11572 env->condexec_bits = 0;
11573 } else {
11574 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
11575 env->condexec_bits = gen_opc_condexec_bits[pc_pos];