target-arm: Define and use ARM_FEATURE_CBAR
[qemu.git] / target-arm / translate.c
blob913146752af79ae35b0184e82a167959a7a2ca8a
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 "disas/disas.h"
29 #include "tcg-op.h"
30 #include "qemu/log.h"
31 #include "qemu/bitops.h"
33 #include "helper.h"
34 #define GEN_HELPER 1
35 #include "helper.h"
37 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53 #if defined(CONFIG_USER_ONLY)
54 #define IS_USER(s) 1
55 #else
56 #define IS_USER(s) (s->user)
57 #endif
59 /* These instructions trap after executing, so defer them until after the
60 conditional execution state has been updated. */
61 #define DISAS_WFI 4
62 #define DISAS_SWI 5
64 TCGv_ptr cpu_env;
65 /* We reuse the same 64-bit temporaries for efficiency. */
66 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
67 static TCGv_i32 cpu_R[16];
68 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
69 static TCGv_i32 cpu_exclusive_addr;
70 static TCGv_i32 cpu_exclusive_val;
71 static TCGv_i32 cpu_exclusive_high;
72 #ifdef CONFIG_USER_ONLY
73 static TCGv_i32 cpu_exclusive_test;
74 static TCGv_i32 cpu_exclusive_info;
75 #endif
77 /* FIXME: These should be removed. */
78 static TCGv_i32 cpu_F0s, cpu_F1s;
79 static TCGv_i64 cpu_F0d, cpu_F1d;
81 #include "exec/gen-icount.h"
83 static const char *regnames[] =
84 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
85 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
87 /* initialize TCG globals. */
88 void arm_translate_init(void)
90 int i;
92 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
94 for (i = 0; i < 16; i++) {
95 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
96 offsetof(CPUARMState, regs[i]),
97 regnames[i]);
99 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
100 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
101 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
102 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
104 cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
105 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
106 cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
107 offsetof(CPUARMState, exclusive_val), "exclusive_val");
108 cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
109 offsetof(CPUARMState, exclusive_high), "exclusive_high");
110 #ifdef CONFIG_USER_ONLY
111 cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
112 offsetof(CPUARMState, exclusive_test), "exclusive_test");
113 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
114 offsetof(CPUARMState, exclusive_info), "exclusive_info");
115 #endif
117 a64_translate_init();
120 static inline TCGv_i32 load_cpu_offset(int offset)
122 TCGv_i32 tmp = tcg_temp_new_i32();
123 tcg_gen_ld_i32(tmp, cpu_env, offset);
124 return tmp;
127 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
129 static inline void store_cpu_offset(TCGv_i32 var, int offset)
131 tcg_gen_st_i32(var, cpu_env, offset);
132 tcg_temp_free_i32(var);
135 #define store_cpu_field(var, name) \
136 store_cpu_offset(var, offsetof(CPUARMState, name))
138 /* Set a variable to the value of a CPU register. */
139 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
141 if (reg == 15) {
142 uint32_t addr;
143 /* normally, since we updated PC, we need only to add one insn */
144 if (s->thumb)
145 addr = (long)s->pc + 2;
146 else
147 addr = (long)s->pc + 4;
148 tcg_gen_movi_i32(var, addr);
149 } else {
150 tcg_gen_mov_i32(var, cpu_R[reg]);
154 /* Create a new temporary and set it to the value of a CPU register. */
155 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
157 TCGv_i32 tmp = tcg_temp_new_i32();
158 load_reg_var(s, tmp, reg);
159 return tmp;
162 /* Set a CPU register. The source must be a temporary and will be
163 marked as dead. */
164 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
166 if (reg == 15) {
167 tcg_gen_andi_i32(var, var, ~1);
168 s->is_jmp = DISAS_JUMP;
170 tcg_gen_mov_i32(cpu_R[reg], var);
171 tcg_temp_free_i32(var);
174 /* Value extensions. */
175 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
176 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
177 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
178 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
180 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
181 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
184 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
186 TCGv_i32 tmp_mask = tcg_const_i32(mask);
187 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
188 tcg_temp_free_i32(tmp_mask);
190 /* Set NZCV flags from the high 4 bits of var. */
191 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
193 static void gen_exception(int excp)
195 TCGv_i32 tmp = tcg_temp_new_i32();
196 tcg_gen_movi_i32(tmp, excp);
197 gen_helper_exception(cpu_env, tmp);
198 tcg_temp_free_i32(tmp);
201 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
203 TCGv_i32 tmp1 = tcg_temp_new_i32();
204 TCGv_i32 tmp2 = tcg_temp_new_i32();
205 tcg_gen_ext16s_i32(tmp1, a);
206 tcg_gen_ext16s_i32(tmp2, b);
207 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
208 tcg_temp_free_i32(tmp2);
209 tcg_gen_sari_i32(a, a, 16);
210 tcg_gen_sari_i32(b, b, 16);
211 tcg_gen_mul_i32(b, b, a);
212 tcg_gen_mov_i32(a, tmp1);
213 tcg_temp_free_i32(tmp1);
216 /* Byteswap each halfword. */
217 static void gen_rev16(TCGv_i32 var)
219 TCGv_i32 tmp = tcg_temp_new_i32();
220 tcg_gen_shri_i32(tmp, var, 8);
221 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
222 tcg_gen_shli_i32(var, var, 8);
223 tcg_gen_andi_i32(var, var, 0xff00ff00);
224 tcg_gen_or_i32(var, var, tmp);
225 tcg_temp_free_i32(tmp);
228 /* Byteswap low halfword and sign extend. */
229 static void gen_revsh(TCGv_i32 var)
231 tcg_gen_ext16u_i32(var, var);
232 tcg_gen_bswap16_i32(var, var);
233 tcg_gen_ext16s_i32(var, var);
236 /* Unsigned bitfield extract. */
237 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
239 if (shift)
240 tcg_gen_shri_i32(var, var, shift);
241 tcg_gen_andi_i32(var, var, mask);
244 /* Signed bitfield extract. */
245 static void gen_sbfx(TCGv_i32 var, int shift, int width)
247 uint32_t signbit;
249 if (shift)
250 tcg_gen_sari_i32(var, var, shift);
251 if (shift + width < 32) {
252 signbit = 1u << (width - 1);
253 tcg_gen_andi_i32(var, var, (1u << width) - 1);
254 tcg_gen_xori_i32(var, var, signbit);
255 tcg_gen_subi_i32(var, var, signbit);
259 /* Return (b << 32) + a. Mark inputs as dead */
260 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
262 TCGv_i64 tmp64 = tcg_temp_new_i64();
264 tcg_gen_extu_i32_i64(tmp64, b);
265 tcg_temp_free_i32(b);
266 tcg_gen_shli_i64(tmp64, tmp64, 32);
267 tcg_gen_add_i64(a, tmp64, a);
269 tcg_temp_free_i64(tmp64);
270 return a;
273 /* Return (b << 32) - a. Mark inputs as dead. */
274 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
276 TCGv_i64 tmp64 = tcg_temp_new_i64();
278 tcg_gen_extu_i32_i64(tmp64, b);
279 tcg_temp_free_i32(b);
280 tcg_gen_shli_i64(tmp64, tmp64, 32);
281 tcg_gen_sub_i64(a, tmp64, a);
283 tcg_temp_free_i64(tmp64);
284 return a;
287 /* 32x32->64 multiply. Marks inputs as dead. */
288 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
290 TCGv_i32 lo = tcg_temp_new_i32();
291 TCGv_i32 hi = tcg_temp_new_i32();
292 TCGv_i64 ret;
294 tcg_gen_mulu2_i32(lo, hi, a, b);
295 tcg_temp_free_i32(a);
296 tcg_temp_free_i32(b);
298 ret = tcg_temp_new_i64();
299 tcg_gen_concat_i32_i64(ret, lo, hi);
300 tcg_temp_free_i32(lo);
301 tcg_temp_free_i32(hi);
303 return ret;
306 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
308 TCGv_i32 lo = tcg_temp_new_i32();
309 TCGv_i32 hi = tcg_temp_new_i32();
310 TCGv_i64 ret;
312 tcg_gen_muls2_i32(lo, hi, a, b);
313 tcg_temp_free_i32(a);
314 tcg_temp_free_i32(b);
316 ret = tcg_temp_new_i64();
317 tcg_gen_concat_i32_i64(ret, lo, hi);
318 tcg_temp_free_i32(lo);
319 tcg_temp_free_i32(hi);
321 return ret;
324 /* Swap low and high halfwords. */
325 static void gen_swap_half(TCGv_i32 var)
327 TCGv_i32 tmp = tcg_temp_new_i32();
328 tcg_gen_shri_i32(tmp, var, 16);
329 tcg_gen_shli_i32(var, var, 16);
330 tcg_gen_or_i32(var, var, tmp);
331 tcg_temp_free_i32(tmp);
334 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
335 tmp = (t0 ^ t1) & 0x8000;
336 t0 &= ~0x8000;
337 t1 &= ~0x8000;
338 t0 = (t0 + t1) ^ tmp;
341 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
343 TCGv_i32 tmp = tcg_temp_new_i32();
344 tcg_gen_xor_i32(tmp, t0, t1);
345 tcg_gen_andi_i32(tmp, tmp, 0x8000);
346 tcg_gen_andi_i32(t0, t0, ~0x8000);
347 tcg_gen_andi_i32(t1, t1, ~0x8000);
348 tcg_gen_add_i32(t0, t0, t1);
349 tcg_gen_xor_i32(t0, t0, tmp);
350 tcg_temp_free_i32(tmp);
351 tcg_temp_free_i32(t1);
354 /* Set CF to the top bit of var. */
355 static void gen_set_CF_bit31(TCGv_i32 var)
357 tcg_gen_shri_i32(cpu_CF, var, 31);
360 /* Set N and Z flags from var. */
361 static inline void gen_logic_CC(TCGv_i32 var)
363 tcg_gen_mov_i32(cpu_NF, var);
364 tcg_gen_mov_i32(cpu_ZF, var);
367 /* T0 += T1 + CF. */
368 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
370 tcg_gen_add_i32(t0, t0, t1);
371 tcg_gen_add_i32(t0, t0, cpu_CF);
374 /* dest = T0 + T1 + CF. */
375 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
377 tcg_gen_add_i32(dest, t0, t1);
378 tcg_gen_add_i32(dest, dest, cpu_CF);
381 /* dest = T0 - T1 + CF - 1. */
382 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
384 tcg_gen_sub_i32(dest, t0, t1);
385 tcg_gen_add_i32(dest, dest, cpu_CF);
386 tcg_gen_subi_i32(dest, dest, 1);
389 /* dest = T0 + T1. Compute C, N, V and Z flags */
390 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
392 TCGv_i32 tmp = tcg_temp_new_i32();
393 tcg_gen_movi_i32(tmp, 0);
394 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
395 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
396 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
397 tcg_gen_xor_i32(tmp, t0, t1);
398 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
399 tcg_temp_free_i32(tmp);
400 tcg_gen_mov_i32(dest, cpu_NF);
403 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
404 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
406 TCGv_i32 tmp = tcg_temp_new_i32();
407 if (TCG_TARGET_HAS_add2_i32) {
408 tcg_gen_movi_i32(tmp, 0);
409 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
410 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
411 } else {
412 TCGv_i64 q0 = tcg_temp_new_i64();
413 TCGv_i64 q1 = tcg_temp_new_i64();
414 tcg_gen_extu_i32_i64(q0, t0);
415 tcg_gen_extu_i32_i64(q1, t1);
416 tcg_gen_add_i64(q0, q0, q1);
417 tcg_gen_extu_i32_i64(q1, cpu_CF);
418 tcg_gen_add_i64(q0, q0, q1);
419 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
420 tcg_temp_free_i64(q0);
421 tcg_temp_free_i64(q1);
423 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
424 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
425 tcg_gen_xor_i32(tmp, t0, t1);
426 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
427 tcg_temp_free_i32(tmp);
428 tcg_gen_mov_i32(dest, cpu_NF);
431 /* dest = T0 - T1. Compute C, N, V and Z flags */
432 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
434 TCGv_i32 tmp;
435 tcg_gen_sub_i32(cpu_NF, t0, t1);
436 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
437 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
438 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
439 tmp = tcg_temp_new_i32();
440 tcg_gen_xor_i32(tmp, t0, t1);
441 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
442 tcg_temp_free_i32(tmp);
443 tcg_gen_mov_i32(dest, cpu_NF);
446 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
447 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
449 TCGv_i32 tmp = tcg_temp_new_i32();
450 tcg_gen_not_i32(tmp, t1);
451 gen_adc_CC(dest, t0, tmp);
452 tcg_temp_free_i32(tmp);
455 #define GEN_SHIFT(name) \
456 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
458 TCGv_i32 tmp1, tmp2, tmp3; \
459 tmp1 = tcg_temp_new_i32(); \
460 tcg_gen_andi_i32(tmp1, t1, 0xff); \
461 tmp2 = tcg_const_i32(0); \
462 tmp3 = tcg_const_i32(0x1f); \
463 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
464 tcg_temp_free_i32(tmp3); \
465 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
466 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
467 tcg_temp_free_i32(tmp2); \
468 tcg_temp_free_i32(tmp1); \
470 GEN_SHIFT(shl)
471 GEN_SHIFT(shr)
472 #undef GEN_SHIFT
474 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
476 TCGv_i32 tmp1, tmp2;
477 tmp1 = tcg_temp_new_i32();
478 tcg_gen_andi_i32(tmp1, t1, 0xff);
479 tmp2 = tcg_const_i32(0x1f);
480 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
481 tcg_temp_free_i32(tmp2);
482 tcg_gen_sar_i32(dest, t0, tmp1);
483 tcg_temp_free_i32(tmp1);
486 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
488 TCGv_i32 c0 = tcg_const_i32(0);
489 TCGv_i32 tmp = tcg_temp_new_i32();
490 tcg_gen_neg_i32(tmp, src);
491 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
492 tcg_temp_free_i32(c0);
493 tcg_temp_free_i32(tmp);
496 static void shifter_out_im(TCGv_i32 var, int shift)
498 if (shift == 0) {
499 tcg_gen_andi_i32(cpu_CF, var, 1);
500 } else {
501 tcg_gen_shri_i32(cpu_CF, var, shift);
502 if (shift != 31) {
503 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
508 /* Shift by immediate. Includes special handling for shift == 0. */
509 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
510 int shift, int flags)
512 switch (shiftop) {
513 case 0: /* LSL */
514 if (shift != 0) {
515 if (flags)
516 shifter_out_im(var, 32 - shift);
517 tcg_gen_shli_i32(var, var, shift);
519 break;
520 case 1: /* LSR */
521 if (shift == 0) {
522 if (flags) {
523 tcg_gen_shri_i32(cpu_CF, var, 31);
525 tcg_gen_movi_i32(var, 0);
526 } else {
527 if (flags)
528 shifter_out_im(var, shift - 1);
529 tcg_gen_shri_i32(var, var, shift);
531 break;
532 case 2: /* ASR */
533 if (shift == 0)
534 shift = 32;
535 if (flags)
536 shifter_out_im(var, shift - 1);
537 if (shift == 32)
538 shift = 31;
539 tcg_gen_sari_i32(var, var, shift);
540 break;
541 case 3: /* ROR/RRX */
542 if (shift != 0) {
543 if (flags)
544 shifter_out_im(var, shift - 1);
545 tcg_gen_rotri_i32(var, var, shift); break;
546 } else {
547 TCGv_i32 tmp = tcg_temp_new_i32();
548 tcg_gen_shli_i32(tmp, cpu_CF, 31);
549 if (flags)
550 shifter_out_im(var, 0);
551 tcg_gen_shri_i32(var, var, 1);
552 tcg_gen_or_i32(var, var, tmp);
553 tcg_temp_free_i32(tmp);
558 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
559 TCGv_i32 shift, int flags)
561 if (flags) {
562 switch (shiftop) {
563 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
564 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
565 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
566 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
568 } else {
569 switch (shiftop) {
570 case 0:
571 gen_shl(var, var, shift);
572 break;
573 case 1:
574 gen_shr(var, var, shift);
575 break;
576 case 2:
577 gen_sar(var, var, shift);
578 break;
579 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
580 tcg_gen_rotr_i32(var, var, shift); break;
583 tcg_temp_free_i32(shift);
586 #define PAS_OP(pfx) \
587 switch (op2) { \
588 case 0: gen_pas_helper(glue(pfx,add16)); break; \
589 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
590 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
591 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
592 case 4: gen_pas_helper(glue(pfx,add8)); break; \
593 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
595 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
597 TCGv_ptr tmp;
599 switch (op1) {
600 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
601 case 1:
602 tmp = tcg_temp_new_ptr();
603 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
604 PAS_OP(s)
605 tcg_temp_free_ptr(tmp);
606 break;
607 case 5:
608 tmp = tcg_temp_new_ptr();
609 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
610 PAS_OP(u)
611 tcg_temp_free_ptr(tmp);
612 break;
613 #undef gen_pas_helper
614 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
615 case 2:
616 PAS_OP(q);
617 break;
618 case 3:
619 PAS_OP(sh);
620 break;
621 case 6:
622 PAS_OP(uq);
623 break;
624 case 7:
625 PAS_OP(uh);
626 break;
627 #undef gen_pas_helper
630 #undef PAS_OP
632 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
633 #define PAS_OP(pfx) \
634 switch (op1) { \
635 case 0: gen_pas_helper(glue(pfx,add8)); break; \
636 case 1: gen_pas_helper(glue(pfx,add16)); break; \
637 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
638 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
639 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
640 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
642 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
644 TCGv_ptr tmp;
646 switch (op2) {
647 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
648 case 0:
649 tmp = tcg_temp_new_ptr();
650 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
651 PAS_OP(s)
652 tcg_temp_free_ptr(tmp);
653 break;
654 case 4:
655 tmp = tcg_temp_new_ptr();
656 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
657 PAS_OP(u)
658 tcg_temp_free_ptr(tmp);
659 break;
660 #undef gen_pas_helper
661 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
662 case 1:
663 PAS_OP(q);
664 break;
665 case 2:
666 PAS_OP(sh);
667 break;
668 case 5:
669 PAS_OP(uq);
670 break;
671 case 6:
672 PAS_OP(uh);
673 break;
674 #undef gen_pas_helper
677 #undef PAS_OP
679 static void gen_test_cc(int cc, int label)
681 TCGv_i32 tmp;
682 int inv;
684 switch (cc) {
685 case 0: /* eq: Z */
686 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
687 break;
688 case 1: /* ne: !Z */
689 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
690 break;
691 case 2: /* cs: C */
692 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
693 break;
694 case 3: /* cc: !C */
695 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
696 break;
697 case 4: /* mi: N */
698 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
699 break;
700 case 5: /* pl: !N */
701 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
702 break;
703 case 6: /* vs: V */
704 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
705 break;
706 case 7: /* vc: !V */
707 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
708 break;
709 case 8: /* hi: C && !Z */
710 inv = gen_new_label();
711 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
712 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
713 gen_set_label(inv);
714 break;
715 case 9: /* ls: !C || Z */
716 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
717 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
718 break;
719 case 10: /* ge: N == V -> N ^ V == 0 */
720 tmp = tcg_temp_new_i32();
721 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
722 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
723 tcg_temp_free_i32(tmp);
724 break;
725 case 11: /* lt: N != V -> N ^ V != 0 */
726 tmp = tcg_temp_new_i32();
727 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
728 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
729 tcg_temp_free_i32(tmp);
730 break;
731 case 12: /* gt: !Z && N == V */
732 inv = gen_new_label();
733 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
734 tmp = tcg_temp_new_i32();
735 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
736 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
737 tcg_temp_free_i32(tmp);
738 gen_set_label(inv);
739 break;
740 case 13: /* le: Z || N != V */
741 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
742 tmp = tcg_temp_new_i32();
743 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
744 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
745 tcg_temp_free_i32(tmp);
746 break;
747 default:
748 fprintf(stderr, "Bad condition code 0x%x\n", cc);
749 abort();
753 static const uint8_t table_logic_cc[16] = {
754 1, /* and */
755 1, /* xor */
756 0, /* sub */
757 0, /* rsb */
758 0, /* add */
759 0, /* adc */
760 0, /* sbc */
761 0, /* rsc */
762 1, /* andl */
763 1, /* xorl */
764 0, /* cmp */
765 0, /* cmn */
766 1, /* orr */
767 1, /* mov */
768 1, /* bic */
769 1, /* mvn */
772 /* Set PC and Thumb state from an immediate address. */
773 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
775 TCGv_i32 tmp;
777 s->is_jmp = DISAS_UPDATE;
778 if (s->thumb != (addr & 1)) {
779 tmp = tcg_temp_new_i32();
780 tcg_gen_movi_i32(tmp, addr & 1);
781 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
782 tcg_temp_free_i32(tmp);
784 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
787 /* Set PC and Thumb state from var. var is marked as dead. */
788 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
790 s->is_jmp = DISAS_UPDATE;
791 tcg_gen_andi_i32(cpu_R[15], var, ~1);
792 tcg_gen_andi_i32(var, var, 1);
793 store_cpu_field(var, thumb);
796 /* Variant of store_reg which uses branch&exchange logic when storing
797 to r15 in ARM architecture v7 and above. The source must be a temporary
798 and will be marked as dead. */
799 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
800 int reg, TCGv_i32 var)
802 if (reg == 15 && ENABLE_ARCH_7) {
803 gen_bx(s, var);
804 } else {
805 store_reg(s, reg, var);
809 /* Variant of store_reg which uses branch&exchange logic when storing
810 * to r15 in ARM architecture v5T and above. This is used for storing
811 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
812 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
813 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
814 int reg, TCGv_i32 var)
816 if (reg == 15 && ENABLE_ARCH_5) {
817 gen_bx(s, var);
818 } else {
819 store_reg(s, reg, var);
823 /* Abstractions of "generate code to do a guest load/store for
824 * AArch32", where a vaddr is always 32 bits (and is zero
825 * extended if we're a 64 bit core) and data is also
826 * 32 bits unless specifically doing a 64 bit access.
827 * These functions work like tcg_gen_qemu_{ld,st}* except
828 * that the address argument is TCGv_i32 rather than TCGv.
830 #if TARGET_LONG_BITS == 32
832 #define DO_GEN_LD(SUFF, OPC) \
833 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
835 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
838 #define DO_GEN_ST(SUFF, OPC) \
839 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
841 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
844 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
846 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
849 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
851 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
854 #else
856 #define DO_GEN_LD(SUFF, OPC) \
857 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
859 TCGv addr64 = tcg_temp_new(); \
860 tcg_gen_extu_i32_i64(addr64, addr); \
861 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
862 tcg_temp_free(addr64); \
865 #define DO_GEN_ST(SUFF, OPC) \
866 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
868 TCGv addr64 = tcg_temp_new(); \
869 tcg_gen_extu_i32_i64(addr64, addr); \
870 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
871 tcg_temp_free(addr64); \
874 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
876 TCGv addr64 = tcg_temp_new();
877 tcg_gen_extu_i32_i64(addr64, addr);
878 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
879 tcg_temp_free(addr64);
882 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
884 TCGv addr64 = tcg_temp_new();
885 tcg_gen_extu_i32_i64(addr64, addr);
886 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
887 tcg_temp_free(addr64);
890 #endif
892 DO_GEN_LD(8s, MO_SB)
893 DO_GEN_LD(8u, MO_UB)
894 DO_GEN_LD(16s, MO_TESW)
895 DO_GEN_LD(16u, MO_TEUW)
896 DO_GEN_LD(32u, MO_TEUL)
897 DO_GEN_ST(8, MO_UB)
898 DO_GEN_ST(16, MO_TEUW)
899 DO_GEN_ST(32, MO_TEUL)
901 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
903 if (s->aarch64) {
904 gen_a64_set_pc_im(val);
905 } else {
906 tcg_gen_movi_i32(cpu_R[15], val);
910 /* Force a TB lookup after an instruction that changes the CPU state. */
911 static inline void gen_lookup_tb(DisasContext *s)
913 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
914 s->is_jmp = DISAS_UPDATE;
917 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
918 TCGv_i32 var)
920 int val, rm, shift, shiftop;
921 TCGv_i32 offset;
923 if (!(insn & (1 << 25))) {
924 /* immediate */
925 val = insn & 0xfff;
926 if (!(insn & (1 << 23)))
927 val = -val;
928 if (val != 0)
929 tcg_gen_addi_i32(var, var, val);
930 } else {
931 /* shift/register */
932 rm = (insn) & 0xf;
933 shift = (insn >> 7) & 0x1f;
934 shiftop = (insn >> 5) & 3;
935 offset = load_reg(s, rm);
936 gen_arm_shift_im(offset, shiftop, shift, 0);
937 if (!(insn & (1 << 23)))
938 tcg_gen_sub_i32(var, var, offset);
939 else
940 tcg_gen_add_i32(var, var, offset);
941 tcg_temp_free_i32(offset);
945 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
946 int extra, TCGv_i32 var)
948 int val, rm;
949 TCGv_i32 offset;
951 if (insn & (1 << 22)) {
952 /* immediate */
953 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
954 if (!(insn & (1 << 23)))
955 val = -val;
956 val += extra;
957 if (val != 0)
958 tcg_gen_addi_i32(var, var, val);
959 } else {
960 /* register */
961 if (extra)
962 tcg_gen_addi_i32(var, var, extra);
963 rm = (insn) & 0xf;
964 offset = load_reg(s, rm);
965 if (!(insn & (1 << 23)))
966 tcg_gen_sub_i32(var, var, offset);
967 else
968 tcg_gen_add_i32(var, var, offset);
969 tcg_temp_free_i32(offset);
973 static TCGv_ptr get_fpstatus_ptr(int neon)
975 TCGv_ptr statusptr = tcg_temp_new_ptr();
976 int offset;
977 if (neon) {
978 offset = offsetof(CPUARMState, vfp.standard_fp_status);
979 } else {
980 offset = offsetof(CPUARMState, vfp.fp_status);
982 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
983 return statusptr;
986 #define VFP_OP2(name) \
987 static inline void gen_vfp_##name(int dp) \
989 TCGv_ptr fpst = get_fpstatus_ptr(0); \
990 if (dp) { \
991 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
992 } else { \
993 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
995 tcg_temp_free_ptr(fpst); \
998 VFP_OP2(add)
999 VFP_OP2(sub)
1000 VFP_OP2(mul)
1001 VFP_OP2(div)
1003 #undef VFP_OP2
1005 static inline void gen_vfp_F1_mul(int dp)
1007 /* Like gen_vfp_mul() but put result in F1 */
1008 TCGv_ptr fpst = get_fpstatus_ptr(0);
1009 if (dp) {
1010 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1011 } else {
1012 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1014 tcg_temp_free_ptr(fpst);
1017 static inline void gen_vfp_F1_neg(int dp)
1019 /* Like gen_vfp_neg() but put result in F1 */
1020 if (dp) {
1021 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1022 } else {
1023 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1027 static inline void gen_vfp_abs(int dp)
1029 if (dp)
1030 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1031 else
1032 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1035 static inline void gen_vfp_neg(int dp)
1037 if (dp)
1038 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1039 else
1040 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1043 static inline void gen_vfp_sqrt(int dp)
1045 if (dp)
1046 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1047 else
1048 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1051 static inline void gen_vfp_cmp(int dp)
1053 if (dp)
1054 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1055 else
1056 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1059 static inline void gen_vfp_cmpe(int dp)
1061 if (dp)
1062 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1063 else
1064 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1067 static inline void gen_vfp_F1_ld0(int dp)
1069 if (dp)
1070 tcg_gen_movi_i64(cpu_F1d, 0);
1071 else
1072 tcg_gen_movi_i32(cpu_F1s, 0);
1075 #define VFP_GEN_ITOF(name) \
1076 static inline void gen_vfp_##name(int dp, int neon) \
1078 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1079 if (dp) { \
1080 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1081 } else { \
1082 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1084 tcg_temp_free_ptr(statusptr); \
1087 VFP_GEN_ITOF(uito)
1088 VFP_GEN_ITOF(sito)
1089 #undef VFP_GEN_ITOF
1091 #define VFP_GEN_FTOI(name) \
1092 static inline void gen_vfp_##name(int dp, int neon) \
1094 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1095 if (dp) { \
1096 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1097 } else { \
1098 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1100 tcg_temp_free_ptr(statusptr); \
1103 VFP_GEN_FTOI(toui)
1104 VFP_GEN_FTOI(touiz)
1105 VFP_GEN_FTOI(tosi)
1106 VFP_GEN_FTOI(tosiz)
1107 #undef VFP_GEN_FTOI
1109 #define VFP_GEN_FIX(name) \
1110 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1112 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1113 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1114 if (dp) { \
1115 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1116 } else { \
1117 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1119 tcg_temp_free_i32(tmp_shift); \
1120 tcg_temp_free_ptr(statusptr); \
1122 VFP_GEN_FIX(tosh)
1123 VFP_GEN_FIX(tosl)
1124 VFP_GEN_FIX(touh)
1125 VFP_GEN_FIX(toul)
1126 VFP_GEN_FIX(shto)
1127 VFP_GEN_FIX(slto)
1128 VFP_GEN_FIX(uhto)
1129 VFP_GEN_FIX(ulto)
1130 #undef VFP_GEN_FIX
1132 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1134 if (dp) {
1135 gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1136 } else {
1137 gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1141 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1143 if (dp) {
1144 gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1145 } else {
1146 gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1150 static inline long
1151 vfp_reg_offset (int dp, int reg)
1153 if (dp)
1154 return offsetof(CPUARMState, vfp.regs[reg]);
1155 else if (reg & 1) {
1156 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1157 + offsetof(CPU_DoubleU, l.upper);
1158 } else {
1159 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1160 + offsetof(CPU_DoubleU, l.lower);
1164 /* Return the offset of a 32-bit piece of a NEON register.
1165 zero is the least significant end of the register. */
1166 static inline long
1167 neon_reg_offset (int reg, int n)
1169 int sreg;
1170 sreg = reg * 2 + n;
1171 return vfp_reg_offset(0, sreg);
1174 static TCGv_i32 neon_load_reg(int reg, int pass)
1176 TCGv_i32 tmp = tcg_temp_new_i32();
1177 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1178 return tmp;
1181 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1183 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1184 tcg_temp_free_i32(var);
1187 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1189 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1194 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1197 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1198 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1199 #define tcg_gen_st_f32 tcg_gen_st_i32
1200 #define tcg_gen_st_f64 tcg_gen_st_i64
1202 static inline void gen_mov_F0_vreg(int dp, int reg)
1204 if (dp)
1205 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1206 else
1207 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1210 static inline void gen_mov_F1_vreg(int dp, int reg)
1212 if (dp)
1213 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1214 else
1215 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1218 static inline void gen_mov_vreg_F0(int dp, int reg)
1220 if (dp)
1221 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1222 else
1223 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1226 #define ARM_CP_RW_BIT (1 << 20)
1228 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1230 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1233 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1235 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1238 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1240 TCGv_i32 var = tcg_temp_new_i32();
1241 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1242 return var;
1245 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1247 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1248 tcg_temp_free_i32(var);
1251 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1253 iwmmxt_store_reg(cpu_M0, rn);
1256 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1258 iwmmxt_load_reg(cpu_M0, rn);
1261 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1263 iwmmxt_load_reg(cpu_V1, rn);
1264 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1267 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1269 iwmmxt_load_reg(cpu_V1, rn);
1270 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1273 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1275 iwmmxt_load_reg(cpu_V1, rn);
1276 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1279 #define IWMMXT_OP(name) \
1280 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1282 iwmmxt_load_reg(cpu_V1, rn); \
1283 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1286 #define IWMMXT_OP_ENV(name) \
1287 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1289 iwmmxt_load_reg(cpu_V1, rn); \
1290 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1293 #define IWMMXT_OP_ENV_SIZE(name) \
1294 IWMMXT_OP_ENV(name##b) \
1295 IWMMXT_OP_ENV(name##w) \
1296 IWMMXT_OP_ENV(name##l)
1298 #define IWMMXT_OP_ENV1(name) \
1299 static inline void gen_op_iwmmxt_##name##_M0(void) \
1301 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1304 IWMMXT_OP(maddsq)
1305 IWMMXT_OP(madduq)
1306 IWMMXT_OP(sadb)
1307 IWMMXT_OP(sadw)
1308 IWMMXT_OP(mulslw)
1309 IWMMXT_OP(mulshw)
1310 IWMMXT_OP(mululw)
1311 IWMMXT_OP(muluhw)
1312 IWMMXT_OP(macsw)
1313 IWMMXT_OP(macuw)
1315 IWMMXT_OP_ENV_SIZE(unpackl)
1316 IWMMXT_OP_ENV_SIZE(unpackh)
1318 IWMMXT_OP_ENV1(unpacklub)
1319 IWMMXT_OP_ENV1(unpackluw)
1320 IWMMXT_OP_ENV1(unpacklul)
1321 IWMMXT_OP_ENV1(unpackhub)
1322 IWMMXT_OP_ENV1(unpackhuw)
1323 IWMMXT_OP_ENV1(unpackhul)
1324 IWMMXT_OP_ENV1(unpacklsb)
1325 IWMMXT_OP_ENV1(unpacklsw)
1326 IWMMXT_OP_ENV1(unpacklsl)
1327 IWMMXT_OP_ENV1(unpackhsb)
1328 IWMMXT_OP_ENV1(unpackhsw)
1329 IWMMXT_OP_ENV1(unpackhsl)
1331 IWMMXT_OP_ENV_SIZE(cmpeq)
1332 IWMMXT_OP_ENV_SIZE(cmpgtu)
1333 IWMMXT_OP_ENV_SIZE(cmpgts)
1335 IWMMXT_OP_ENV_SIZE(mins)
1336 IWMMXT_OP_ENV_SIZE(minu)
1337 IWMMXT_OP_ENV_SIZE(maxs)
1338 IWMMXT_OP_ENV_SIZE(maxu)
1340 IWMMXT_OP_ENV_SIZE(subn)
1341 IWMMXT_OP_ENV_SIZE(addn)
1342 IWMMXT_OP_ENV_SIZE(subu)
1343 IWMMXT_OP_ENV_SIZE(addu)
1344 IWMMXT_OP_ENV_SIZE(subs)
1345 IWMMXT_OP_ENV_SIZE(adds)
1347 IWMMXT_OP_ENV(avgb0)
1348 IWMMXT_OP_ENV(avgb1)
1349 IWMMXT_OP_ENV(avgw0)
1350 IWMMXT_OP_ENV(avgw1)
1352 IWMMXT_OP(msadb)
1354 IWMMXT_OP_ENV(packuw)
1355 IWMMXT_OP_ENV(packul)
1356 IWMMXT_OP_ENV(packuq)
1357 IWMMXT_OP_ENV(packsw)
1358 IWMMXT_OP_ENV(packsl)
1359 IWMMXT_OP_ENV(packsq)
1361 static void gen_op_iwmmxt_set_mup(void)
1363 TCGv_i32 tmp;
1364 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1365 tcg_gen_ori_i32(tmp, tmp, 2);
1366 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1369 static void gen_op_iwmmxt_set_cup(void)
1371 TCGv_i32 tmp;
1372 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1373 tcg_gen_ori_i32(tmp, tmp, 1);
1374 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1377 static void gen_op_iwmmxt_setpsr_nz(void)
1379 TCGv_i32 tmp = tcg_temp_new_i32();
1380 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1381 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1384 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1386 iwmmxt_load_reg(cpu_V1, rn);
1387 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1388 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1391 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1392 TCGv_i32 dest)
1394 int rd;
1395 uint32_t offset;
1396 TCGv_i32 tmp;
1398 rd = (insn >> 16) & 0xf;
1399 tmp = load_reg(s, rd);
1401 offset = (insn & 0xff) << ((insn >> 7) & 2);
1402 if (insn & (1 << 24)) {
1403 /* Pre indexed */
1404 if (insn & (1 << 23))
1405 tcg_gen_addi_i32(tmp, tmp, offset);
1406 else
1407 tcg_gen_addi_i32(tmp, tmp, -offset);
1408 tcg_gen_mov_i32(dest, tmp);
1409 if (insn & (1 << 21))
1410 store_reg(s, rd, tmp);
1411 else
1412 tcg_temp_free_i32(tmp);
1413 } else if (insn & (1 << 21)) {
1414 /* Post indexed */
1415 tcg_gen_mov_i32(dest, tmp);
1416 if (insn & (1 << 23))
1417 tcg_gen_addi_i32(tmp, tmp, offset);
1418 else
1419 tcg_gen_addi_i32(tmp, tmp, -offset);
1420 store_reg(s, rd, tmp);
1421 } else if (!(insn & (1 << 23)))
1422 return 1;
1423 return 0;
1426 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1428 int rd = (insn >> 0) & 0xf;
1429 TCGv_i32 tmp;
1431 if (insn & (1 << 8)) {
1432 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1433 return 1;
1434 } else {
1435 tmp = iwmmxt_load_creg(rd);
1437 } else {
1438 tmp = tcg_temp_new_i32();
1439 iwmmxt_load_reg(cpu_V0, rd);
1440 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1442 tcg_gen_andi_i32(tmp, tmp, mask);
1443 tcg_gen_mov_i32(dest, tmp);
1444 tcg_temp_free_i32(tmp);
1445 return 0;
1448 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1449 (ie. an undefined instruction). */
1450 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1452 int rd, wrd;
1453 int rdhi, rdlo, rd0, rd1, i;
1454 TCGv_i32 addr;
1455 TCGv_i32 tmp, tmp2, tmp3;
1457 if ((insn & 0x0e000e00) == 0x0c000000) {
1458 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1459 wrd = insn & 0xf;
1460 rdlo = (insn >> 12) & 0xf;
1461 rdhi = (insn >> 16) & 0xf;
1462 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1463 iwmmxt_load_reg(cpu_V0, wrd);
1464 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1465 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1466 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1467 } else { /* TMCRR */
1468 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1469 iwmmxt_store_reg(cpu_V0, wrd);
1470 gen_op_iwmmxt_set_mup();
1472 return 0;
1475 wrd = (insn >> 12) & 0xf;
1476 addr = tcg_temp_new_i32();
1477 if (gen_iwmmxt_address(s, insn, addr)) {
1478 tcg_temp_free_i32(addr);
1479 return 1;
1481 if (insn & ARM_CP_RW_BIT) {
1482 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1483 tmp = tcg_temp_new_i32();
1484 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1485 iwmmxt_store_creg(wrd, tmp);
1486 } else {
1487 i = 1;
1488 if (insn & (1 << 8)) {
1489 if (insn & (1 << 22)) { /* WLDRD */
1490 gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1491 i = 0;
1492 } else { /* WLDRW wRd */
1493 tmp = tcg_temp_new_i32();
1494 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1496 } else {
1497 tmp = tcg_temp_new_i32();
1498 if (insn & (1 << 22)) { /* WLDRH */
1499 gen_aa32_ld16u(tmp, addr, IS_USER(s));
1500 } else { /* WLDRB */
1501 gen_aa32_ld8u(tmp, addr, IS_USER(s));
1504 if (i) {
1505 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1506 tcg_temp_free_i32(tmp);
1508 gen_op_iwmmxt_movq_wRn_M0(wrd);
1510 } else {
1511 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1512 tmp = iwmmxt_load_creg(wrd);
1513 gen_aa32_st32(tmp, addr, IS_USER(s));
1514 } else {
1515 gen_op_iwmmxt_movq_M0_wRn(wrd);
1516 tmp = tcg_temp_new_i32();
1517 if (insn & (1 << 8)) {
1518 if (insn & (1 << 22)) { /* WSTRD */
1519 gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1520 } else { /* WSTRW wRd */
1521 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1522 gen_aa32_st32(tmp, addr, IS_USER(s));
1524 } else {
1525 if (insn & (1 << 22)) { /* WSTRH */
1526 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1527 gen_aa32_st16(tmp, addr, IS_USER(s));
1528 } else { /* WSTRB */
1529 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1530 gen_aa32_st8(tmp, addr, IS_USER(s));
1534 tcg_temp_free_i32(tmp);
1536 tcg_temp_free_i32(addr);
1537 return 0;
1540 if ((insn & 0x0f000000) != 0x0e000000)
1541 return 1;
1543 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1544 case 0x000: /* WOR */
1545 wrd = (insn >> 12) & 0xf;
1546 rd0 = (insn >> 0) & 0xf;
1547 rd1 = (insn >> 16) & 0xf;
1548 gen_op_iwmmxt_movq_M0_wRn(rd0);
1549 gen_op_iwmmxt_orq_M0_wRn(rd1);
1550 gen_op_iwmmxt_setpsr_nz();
1551 gen_op_iwmmxt_movq_wRn_M0(wrd);
1552 gen_op_iwmmxt_set_mup();
1553 gen_op_iwmmxt_set_cup();
1554 break;
1555 case 0x011: /* TMCR */
1556 if (insn & 0xf)
1557 return 1;
1558 rd = (insn >> 12) & 0xf;
1559 wrd = (insn >> 16) & 0xf;
1560 switch (wrd) {
1561 case ARM_IWMMXT_wCID:
1562 case ARM_IWMMXT_wCASF:
1563 break;
1564 case ARM_IWMMXT_wCon:
1565 gen_op_iwmmxt_set_cup();
1566 /* Fall through. */
1567 case ARM_IWMMXT_wCSSF:
1568 tmp = iwmmxt_load_creg(wrd);
1569 tmp2 = load_reg(s, rd);
1570 tcg_gen_andc_i32(tmp, tmp, tmp2);
1571 tcg_temp_free_i32(tmp2);
1572 iwmmxt_store_creg(wrd, tmp);
1573 break;
1574 case ARM_IWMMXT_wCGR0:
1575 case ARM_IWMMXT_wCGR1:
1576 case ARM_IWMMXT_wCGR2:
1577 case ARM_IWMMXT_wCGR3:
1578 gen_op_iwmmxt_set_cup();
1579 tmp = load_reg(s, rd);
1580 iwmmxt_store_creg(wrd, tmp);
1581 break;
1582 default:
1583 return 1;
1585 break;
1586 case 0x100: /* WXOR */
1587 wrd = (insn >> 12) & 0xf;
1588 rd0 = (insn >> 0) & 0xf;
1589 rd1 = (insn >> 16) & 0xf;
1590 gen_op_iwmmxt_movq_M0_wRn(rd0);
1591 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1592 gen_op_iwmmxt_setpsr_nz();
1593 gen_op_iwmmxt_movq_wRn_M0(wrd);
1594 gen_op_iwmmxt_set_mup();
1595 gen_op_iwmmxt_set_cup();
1596 break;
1597 case 0x111: /* TMRC */
1598 if (insn & 0xf)
1599 return 1;
1600 rd = (insn >> 12) & 0xf;
1601 wrd = (insn >> 16) & 0xf;
1602 tmp = iwmmxt_load_creg(wrd);
1603 store_reg(s, rd, tmp);
1604 break;
1605 case 0x300: /* WANDN */
1606 wrd = (insn >> 12) & 0xf;
1607 rd0 = (insn >> 0) & 0xf;
1608 rd1 = (insn >> 16) & 0xf;
1609 gen_op_iwmmxt_movq_M0_wRn(rd0);
1610 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1611 gen_op_iwmmxt_andq_M0_wRn(rd1);
1612 gen_op_iwmmxt_setpsr_nz();
1613 gen_op_iwmmxt_movq_wRn_M0(wrd);
1614 gen_op_iwmmxt_set_mup();
1615 gen_op_iwmmxt_set_cup();
1616 break;
1617 case 0x200: /* WAND */
1618 wrd = (insn >> 12) & 0xf;
1619 rd0 = (insn >> 0) & 0xf;
1620 rd1 = (insn >> 16) & 0xf;
1621 gen_op_iwmmxt_movq_M0_wRn(rd0);
1622 gen_op_iwmmxt_andq_M0_wRn(rd1);
1623 gen_op_iwmmxt_setpsr_nz();
1624 gen_op_iwmmxt_movq_wRn_M0(wrd);
1625 gen_op_iwmmxt_set_mup();
1626 gen_op_iwmmxt_set_cup();
1627 break;
1628 case 0x810: case 0xa10: /* WMADD */
1629 wrd = (insn >> 12) & 0xf;
1630 rd0 = (insn >> 0) & 0xf;
1631 rd1 = (insn >> 16) & 0xf;
1632 gen_op_iwmmxt_movq_M0_wRn(rd0);
1633 if (insn & (1 << 21))
1634 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1635 else
1636 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1637 gen_op_iwmmxt_movq_wRn_M0(wrd);
1638 gen_op_iwmmxt_set_mup();
1639 break;
1640 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1641 wrd = (insn >> 12) & 0xf;
1642 rd0 = (insn >> 16) & 0xf;
1643 rd1 = (insn >> 0) & 0xf;
1644 gen_op_iwmmxt_movq_M0_wRn(rd0);
1645 switch ((insn >> 22) & 3) {
1646 case 0:
1647 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1648 break;
1649 case 1:
1650 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1651 break;
1652 case 2:
1653 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1654 break;
1655 case 3:
1656 return 1;
1658 gen_op_iwmmxt_movq_wRn_M0(wrd);
1659 gen_op_iwmmxt_set_mup();
1660 gen_op_iwmmxt_set_cup();
1661 break;
1662 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1663 wrd = (insn >> 12) & 0xf;
1664 rd0 = (insn >> 16) & 0xf;
1665 rd1 = (insn >> 0) & 0xf;
1666 gen_op_iwmmxt_movq_M0_wRn(rd0);
1667 switch ((insn >> 22) & 3) {
1668 case 0:
1669 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1670 break;
1671 case 1:
1672 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1673 break;
1674 case 2:
1675 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1676 break;
1677 case 3:
1678 return 1;
1680 gen_op_iwmmxt_movq_wRn_M0(wrd);
1681 gen_op_iwmmxt_set_mup();
1682 gen_op_iwmmxt_set_cup();
1683 break;
1684 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1685 wrd = (insn >> 12) & 0xf;
1686 rd0 = (insn >> 16) & 0xf;
1687 rd1 = (insn >> 0) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0);
1689 if (insn & (1 << 22))
1690 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1691 else
1692 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1693 if (!(insn & (1 << 20)))
1694 gen_op_iwmmxt_addl_M0_wRn(wrd);
1695 gen_op_iwmmxt_movq_wRn_M0(wrd);
1696 gen_op_iwmmxt_set_mup();
1697 break;
1698 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1699 wrd = (insn >> 12) & 0xf;
1700 rd0 = (insn >> 16) & 0xf;
1701 rd1 = (insn >> 0) & 0xf;
1702 gen_op_iwmmxt_movq_M0_wRn(rd0);
1703 if (insn & (1 << 21)) {
1704 if (insn & (1 << 20))
1705 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1706 else
1707 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1708 } else {
1709 if (insn & (1 << 20))
1710 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1711 else
1712 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1714 gen_op_iwmmxt_movq_wRn_M0(wrd);
1715 gen_op_iwmmxt_set_mup();
1716 break;
1717 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1718 wrd = (insn >> 12) & 0xf;
1719 rd0 = (insn >> 16) & 0xf;
1720 rd1 = (insn >> 0) & 0xf;
1721 gen_op_iwmmxt_movq_M0_wRn(rd0);
1722 if (insn & (1 << 21))
1723 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1724 else
1725 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1726 if (!(insn & (1 << 20))) {
1727 iwmmxt_load_reg(cpu_V1, wrd);
1728 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1730 gen_op_iwmmxt_movq_wRn_M0(wrd);
1731 gen_op_iwmmxt_set_mup();
1732 break;
1733 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1734 wrd = (insn >> 12) & 0xf;
1735 rd0 = (insn >> 16) & 0xf;
1736 rd1 = (insn >> 0) & 0xf;
1737 gen_op_iwmmxt_movq_M0_wRn(rd0);
1738 switch ((insn >> 22) & 3) {
1739 case 0:
1740 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1741 break;
1742 case 1:
1743 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1744 break;
1745 case 2:
1746 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1747 break;
1748 case 3:
1749 return 1;
1751 gen_op_iwmmxt_movq_wRn_M0(wrd);
1752 gen_op_iwmmxt_set_mup();
1753 gen_op_iwmmxt_set_cup();
1754 break;
1755 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1756 wrd = (insn >> 12) & 0xf;
1757 rd0 = (insn >> 16) & 0xf;
1758 rd1 = (insn >> 0) & 0xf;
1759 gen_op_iwmmxt_movq_M0_wRn(rd0);
1760 if (insn & (1 << 22)) {
1761 if (insn & (1 << 20))
1762 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1763 else
1764 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1765 } else {
1766 if (insn & (1 << 20))
1767 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1768 else
1769 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1771 gen_op_iwmmxt_movq_wRn_M0(wrd);
1772 gen_op_iwmmxt_set_mup();
1773 gen_op_iwmmxt_set_cup();
1774 break;
1775 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1776 wrd = (insn >> 12) & 0xf;
1777 rd0 = (insn >> 16) & 0xf;
1778 rd1 = (insn >> 0) & 0xf;
1779 gen_op_iwmmxt_movq_M0_wRn(rd0);
1780 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1781 tcg_gen_andi_i32(tmp, tmp, 7);
1782 iwmmxt_load_reg(cpu_V1, rd1);
1783 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1784 tcg_temp_free_i32(tmp);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd);
1786 gen_op_iwmmxt_set_mup();
1787 break;
1788 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1789 if (((insn >> 6) & 3) == 3)
1790 return 1;
1791 rd = (insn >> 12) & 0xf;
1792 wrd = (insn >> 16) & 0xf;
1793 tmp = load_reg(s, rd);
1794 gen_op_iwmmxt_movq_M0_wRn(wrd);
1795 switch ((insn >> 6) & 3) {
1796 case 0:
1797 tmp2 = tcg_const_i32(0xff);
1798 tmp3 = tcg_const_i32((insn & 7) << 3);
1799 break;
1800 case 1:
1801 tmp2 = tcg_const_i32(0xffff);
1802 tmp3 = tcg_const_i32((insn & 3) << 4);
1803 break;
1804 case 2:
1805 tmp2 = tcg_const_i32(0xffffffff);
1806 tmp3 = tcg_const_i32((insn & 1) << 5);
1807 break;
1808 default:
1809 TCGV_UNUSED_I32(tmp2);
1810 TCGV_UNUSED_I32(tmp3);
1812 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1813 tcg_temp_free_i32(tmp3);
1814 tcg_temp_free_i32(tmp2);
1815 tcg_temp_free_i32(tmp);
1816 gen_op_iwmmxt_movq_wRn_M0(wrd);
1817 gen_op_iwmmxt_set_mup();
1818 break;
1819 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1820 rd = (insn >> 12) & 0xf;
1821 wrd = (insn >> 16) & 0xf;
1822 if (rd == 15 || ((insn >> 22) & 3) == 3)
1823 return 1;
1824 gen_op_iwmmxt_movq_M0_wRn(wrd);
1825 tmp = tcg_temp_new_i32();
1826 switch ((insn >> 22) & 3) {
1827 case 0:
1828 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1829 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1830 if (insn & 8) {
1831 tcg_gen_ext8s_i32(tmp, tmp);
1832 } else {
1833 tcg_gen_andi_i32(tmp, tmp, 0xff);
1835 break;
1836 case 1:
1837 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1838 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1839 if (insn & 8) {
1840 tcg_gen_ext16s_i32(tmp, tmp);
1841 } else {
1842 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1844 break;
1845 case 2:
1846 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1847 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1848 break;
1850 store_reg(s, rd, tmp);
1851 break;
1852 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1853 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1854 return 1;
1855 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1856 switch ((insn >> 22) & 3) {
1857 case 0:
1858 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1859 break;
1860 case 1:
1861 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1862 break;
1863 case 2:
1864 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1865 break;
1867 tcg_gen_shli_i32(tmp, tmp, 28);
1868 gen_set_nzcv(tmp);
1869 tcg_temp_free_i32(tmp);
1870 break;
1871 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1872 if (((insn >> 6) & 3) == 3)
1873 return 1;
1874 rd = (insn >> 12) & 0xf;
1875 wrd = (insn >> 16) & 0xf;
1876 tmp = load_reg(s, rd);
1877 switch ((insn >> 6) & 3) {
1878 case 0:
1879 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1880 break;
1881 case 1:
1882 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1883 break;
1884 case 2:
1885 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1886 break;
1888 tcg_temp_free_i32(tmp);
1889 gen_op_iwmmxt_movq_wRn_M0(wrd);
1890 gen_op_iwmmxt_set_mup();
1891 break;
1892 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1893 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1894 return 1;
1895 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1896 tmp2 = tcg_temp_new_i32();
1897 tcg_gen_mov_i32(tmp2, tmp);
1898 switch ((insn >> 22) & 3) {
1899 case 0:
1900 for (i = 0; i < 7; i ++) {
1901 tcg_gen_shli_i32(tmp2, tmp2, 4);
1902 tcg_gen_and_i32(tmp, tmp, tmp2);
1904 break;
1905 case 1:
1906 for (i = 0; i < 3; i ++) {
1907 tcg_gen_shli_i32(tmp2, tmp2, 8);
1908 tcg_gen_and_i32(tmp, tmp, tmp2);
1910 break;
1911 case 2:
1912 tcg_gen_shli_i32(tmp2, tmp2, 16);
1913 tcg_gen_and_i32(tmp, tmp, tmp2);
1914 break;
1916 gen_set_nzcv(tmp);
1917 tcg_temp_free_i32(tmp2);
1918 tcg_temp_free_i32(tmp);
1919 break;
1920 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1921 wrd = (insn >> 12) & 0xf;
1922 rd0 = (insn >> 16) & 0xf;
1923 gen_op_iwmmxt_movq_M0_wRn(rd0);
1924 switch ((insn >> 22) & 3) {
1925 case 0:
1926 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1927 break;
1928 case 1:
1929 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1930 break;
1931 case 2:
1932 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1933 break;
1934 case 3:
1935 return 1;
1937 gen_op_iwmmxt_movq_wRn_M0(wrd);
1938 gen_op_iwmmxt_set_mup();
1939 break;
1940 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1941 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1942 return 1;
1943 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1944 tmp2 = tcg_temp_new_i32();
1945 tcg_gen_mov_i32(tmp2, tmp);
1946 switch ((insn >> 22) & 3) {
1947 case 0:
1948 for (i = 0; i < 7; i ++) {
1949 tcg_gen_shli_i32(tmp2, tmp2, 4);
1950 tcg_gen_or_i32(tmp, tmp, tmp2);
1952 break;
1953 case 1:
1954 for (i = 0; i < 3; i ++) {
1955 tcg_gen_shli_i32(tmp2, tmp2, 8);
1956 tcg_gen_or_i32(tmp, tmp, tmp2);
1958 break;
1959 case 2:
1960 tcg_gen_shli_i32(tmp2, tmp2, 16);
1961 tcg_gen_or_i32(tmp, tmp, tmp2);
1962 break;
1964 gen_set_nzcv(tmp);
1965 tcg_temp_free_i32(tmp2);
1966 tcg_temp_free_i32(tmp);
1967 break;
1968 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1969 rd = (insn >> 12) & 0xf;
1970 rd0 = (insn >> 16) & 0xf;
1971 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1972 return 1;
1973 gen_op_iwmmxt_movq_M0_wRn(rd0);
1974 tmp = tcg_temp_new_i32();
1975 switch ((insn >> 22) & 3) {
1976 case 0:
1977 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1978 break;
1979 case 1:
1980 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1981 break;
1982 case 2:
1983 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1984 break;
1986 store_reg(s, rd, tmp);
1987 break;
1988 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1989 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1990 wrd = (insn >> 12) & 0xf;
1991 rd0 = (insn >> 16) & 0xf;
1992 rd1 = (insn >> 0) & 0xf;
1993 gen_op_iwmmxt_movq_M0_wRn(rd0);
1994 switch ((insn >> 22) & 3) {
1995 case 0:
1996 if (insn & (1 << 21))
1997 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1998 else
1999 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2000 break;
2001 case 1:
2002 if (insn & (1 << 21))
2003 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2004 else
2005 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2006 break;
2007 case 2:
2008 if (insn & (1 << 21))
2009 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2010 else
2011 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2012 break;
2013 case 3:
2014 return 1;
2016 gen_op_iwmmxt_movq_wRn_M0(wrd);
2017 gen_op_iwmmxt_set_mup();
2018 gen_op_iwmmxt_set_cup();
2019 break;
2020 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2021 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2022 wrd = (insn >> 12) & 0xf;
2023 rd0 = (insn >> 16) & 0xf;
2024 gen_op_iwmmxt_movq_M0_wRn(rd0);
2025 switch ((insn >> 22) & 3) {
2026 case 0:
2027 if (insn & (1 << 21))
2028 gen_op_iwmmxt_unpacklsb_M0();
2029 else
2030 gen_op_iwmmxt_unpacklub_M0();
2031 break;
2032 case 1:
2033 if (insn & (1 << 21))
2034 gen_op_iwmmxt_unpacklsw_M0();
2035 else
2036 gen_op_iwmmxt_unpackluw_M0();
2037 break;
2038 case 2:
2039 if (insn & (1 << 21))
2040 gen_op_iwmmxt_unpacklsl_M0();
2041 else
2042 gen_op_iwmmxt_unpacklul_M0();
2043 break;
2044 case 3:
2045 return 1;
2047 gen_op_iwmmxt_movq_wRn_M0(wrd);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2050 break;
2051 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2052 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2053 wrd = (insn >> 12) & 0xf;
2054 rd0 = (insn >> 16) & 0xf;
2055 gen_op_iwmmxt_movq_M0_wRn(rd0);
2056 switch ((insn >> 22) & 3) {
2057 case 0:
2058 if (insn & (1 << 21))
2059 gen_op_iwmmxt_unpackhsb_M0();
2060 else
2061 gen_op_iwmmxt_unpackhub_M0();
2062 break;
2063 case 1:
2064 if (insn & (1 << 21))
2065 gen_op_iwmmxt_unpackhsw_M0();
2066 else
2067 gen_op_iwmmxt_unpackhuw_M0();
2068 break;
2069 case 2:
2070 if (insn & (1 << 21))
2071 gen_op_iwmmxt_unpackhsl_M0();
2072 else
2073 gen_op_iwmmxt_unpackhul_M0();
2074 break;
2075 case 3:
2076 return 1;
2078 gen_op_iwmmxt_movq_wRn_M0(wrd);
2079 gen_op_iwmmxt_set_mup();
2080 gen_op_iwmmxt_set_cup();
2081 break;
2082 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2083 case 0x214: case 0x614: case 0xa14: case 0xe14:
2084 if (((insn >> 22) & 3) == 0)
2085 return 1;
2086 wrd = (insn >> 12) & 0xf;
2087 rd0 = (insn >> 16) & 0xf;
2088 gen_op_iwmmxt_movq_M0_wRn(rd0);
2089 tmp = tcg_temp_new_i32();
2090 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2091 tcg_temp_free_i32(tmp);
2092 return 1;
2094 switch ((insn >> 22) & 3) {
2095 case 1:
2096 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2097 break;
2098 case 2:
2099 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2100 break;
2101 case 3:
2102 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2103 break;
2105 tcg_temp_free_i32(tmp);
2106 gen_op_iwmmxt_movq_wRn_M0(wrd);
2107 gen_op_iwmmxt_set_mup();
2108 gen_op_iwmmxt_set_cup();
2109 break;
2110 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2111 case 0x014: case 0x414: case 0x814: case 0xc14:
2112 if (((insn >> 22) & 3) == 0)
2113 return 1;
2114 wrd = (insn >> 12) & 0xf;
2115 rd0 = (insn >> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0);
2117 tmp = tcg_temp_new_i32();
2118 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2119 tcg_temp_free_i32(tmp);
2120 return 1;
2122 switch ((insn >> 22) & 3) {
2123 case 1:
2124 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2125 break;
2126 case 2:
2127 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2128 break;
2129 case 3:
2130 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2131 break;
2133 tcg_temp_free_i32(tmp);
2134 gen_op_iwmmxt_movq_wRn_M0(wrd);
2135 gen_op_iwmmxt_set_mup();
2136 gen_op_iwmmxt_set_cup();
2137 break;
2138 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2139 case 0x114: case 0x514: case 0x914: case 0xd14:
2140 if (((insn >> 22) & 3) == 0)
2141 return 1;
2142 wrd = (insn >> 12) & 0xf;
2143 rd0 = (insn >> 16) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0);
2145 tmp = tcg_temp_new_i32();
2146 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2147 tcg_temp_free_i32(tmp);
2148 return 1;
2150 switch ((insn >> 22) & 3) {
2151 case 1:
2152 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2153 break;
2154 case 2:
2155 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2156 break;
2157 case 3:
2158 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2159 break;
2161 tcg_temp_free_i32(tmp);
2162 gen_op_iwmmxt_movq_wRn_M0(wrd);
2163 gen_op_iwmmxt_set_mup();
2164 gen_op_iwmmxt_set_cup();
2165 break;
2166 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2167 case 0x314: case 0x714: case 0xb14: case 0xf14:
2168 if (((insn >> 22) & 3) == 0)
2169 return 1;
2170 wrd = (insn >> 12) & 0xf;
2171 rd0 = (insn >> 16) & 0xf;
2172 gen_op_iwmmxt_movq_M0_wRn(rd0);
2173 tmp = tcg_temp_new_i32();
2174 switch ((insn >> 22) & 3) {
2175 case 1:
2176 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2177 tcg_temp_free_i32(tmp);
2178 return 1;
2180 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2181 break;
2182 case 2:
2183 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2184 tcg_temp_free_i32(tmp);
2185 return 1;
2187 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2188 break;
2189 case 3:
2190 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2191 tcg_temp_free_i32(tmp);
2192 return 1;
2194 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2195 break;
2197 tcg_temp_free_i32(tmp);
2198 gen_op_iwmmxt_movq_wRn_M0(wrd);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2201 break;
2202 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2203 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2204 wrd = (insn >> 12) & 0xf;
2205 rd0 = (insn >> 16) & 0xf;
2206 rd1 = (insn >> 0) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0);
2208 switch ((insn >> 22) & 3) {
2209 case 0:
2210 if (insn & (1 << 21))
2211 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2212 else
2213 gen_op_iwmmxt_minub_M0_wRn(rd1);
2214 break;
2215 case 1:
2216 if (insn & (1 << 21))
2217 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2218 else
2219 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2220 break;
2221 case 2:
2222 if (insn & (1 << 21))
2223 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2224 else
2225 gen_op_iwmmxt_minul_M0_wRn(rd1);
2226 break;
2227 case 3:
2228 return 1;
2230 gen_op_iwmmxt_movq_wRn_M0(wrd);
2231 gen_op_iwmmxt_set_mup();
2232 break;
2233 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2234 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2235 wrd = (insn >> 12) & 0xf;
2236 rd0 = (insn >> 16) & 0xf;
2237 rd1 = (insn >> 0) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0);
2239 switch ((insn >> 22) & 3) {
2240 case 0:
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2243 else
2244 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2245 break;
2246 case 1:
2247 if (insn & (1 << 21))
2248 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2249 else
2250 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2251 break;
2252 case 2:
2253 if (insn & (1 << 21))
2254 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2255 else
2256 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2257 break;
2258 case 3:
2259 return 1;
2261 gen_op_iwmmxt_movq_wRn_M0(wrd);
2262 gen_op_iwmmxt_set_mup();
2263 break;
2264 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2265 case 0x402: case 0x502: case 0x602: case 0x702:
2266 wrd = (insn >> 12) & 0xf;
2267 rd0 = (insn >> 16) & 0xf;
2268 rd1 = (insn >> 0) & 0xf;
2269 gen_op_iwmmxt_movq_M0_wRn(rd0);
2270 tmp = tcg_const_i32((insn >> 20) & 3);
2271 iwmmxt_load_reg(cpu_V1, rd1);
2272 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2273 tcg_temp_free_i32(tmp);
2274 gen_op_iwmmxt_movq_wRn_M0(wrd);
2275 gen_op_iwmmxt_set_mup();
2276 break;
2277 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2278 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2279 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2280 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2281 wrd = (insn >> 12) & 0xf;
2282 rd0 = (insn >> 16) & 0xf;
2283 rd1 = (insn >> 0) & 0xf;
2284 gen_op_iwmmxt_movq_M0_wRn(rd0);
2285 switch ((insn >> 20) & 0xf) {
2286 case 0x0:
2287 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2288 break;
2289 case 0x1:
2290 gen_op_iwmmxt_subub_M0_wRn(rd1);
2291 break;
2292 case 0x3:
2293 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2294 break;
2295 case 0x4:
2296 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2297 break;
2298 case 0x5:
2299 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2300 break;
2301 case 0x7:
2302 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2303 break;
2304 case 0x8:
2305 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2306 break;
2307 case 0x9:
2308 gen_op_iwmmxt_subul_M0_wRn(rd1);
2309 break;
2310 case 0xb:
2311 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2312 break;
2313 default:
2314 return 1;
2316 gen_op_iwmmxt_movq_wRn_M0(wrd);
2317 gen_op_iwmmxt_set_mup();
2318 gen_op_iwmmxt_set_cup();
2319 break;
2320 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2321 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2322 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2323 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2324 wrd = (insn >> 12) & 0xf;
2325 rd0 = (insn >> 16) & 0xf;
2326 gen_op_iwmmxt_movq_M0_wRn(rd0);
2327 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2328 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2329 tcg_temp_free_i32(tmp);
2330 gen_op_iwmmxt_movq_wRn_M0(wrd);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2333 break;
2334 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2335 case 0x418: case 0x518: case 0x618: case 0x718:
2336 case 0x818: case 0x918: case 0xa18: case 0xb18:
2337 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2338 wrd = (insn >> 12) & 0xf;
2339 rd0 = (insn >> 16) & 0xf;
2340 rd1 = (insn >> 0) & 0xf;
2341 gen_op_iwmmxt_movq_M0_wRn(rd0);
2342 switch ((insn >> 20) & 0xf) {
2343 case 0x0:
2344 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2345 break;
2346 case 0x1:
2347 gen_op_iwmmxt_addub_M0_wRn(rd1);
2348 break;
2349 case 0x3:
2350 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2351 break;
2352 case 0x4:
2353 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2354 break;
2355 case 0x5:
2356 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2357 break;
2358 case 0x7:
2359 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2360 break;
2361 case 0x8:
2362 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2363 break;
2364 case 0x9:
2365 gen_op_iwmmxt_addul_M0_wRn(rd1);
2366 break;
2367 case 0xb:
2368 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2369 break;
2370 default:
2371 return 1;
2373 gen_op_iwmmxt_movq_wRn_M0(wrd);
2374 gen_op_iwmmxt_set_mup();
2375 gen_op_iwmmxt_set_cup();
2376 break;
2377 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2378 case 0x408: case 0x508: case 0x608: case 0x708:
2379 case 0x808: case 0x908: case 0xa08: case 0xb08:
2380 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2381 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2382 return 1;
2383 wrd = (insn >> 12) & 0xf;
2384 rd0 = (insn >> 16) & 0xf;
2385 rd1 = (insn >> 0) & 0xf;
2386 gen_op_iwmmxt_movq_M0_wRn(rd0);
2387 switch ((insn >> 22) & 3) {
2388 case 1:
2389 if (insn & (1 << 21))
2390 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2391 else
2392 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2393 break;
2394 case 2:
2395 if (insn & (1 << 21))
2396 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2397 else
2398 gen_op_iwmmxt_packul_M0_wRn(rd1);
2399 break;
2400 case 3:
2401 if (insn & (1 << 21))
2402 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2403 else
2404 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2405 break;
2407 gen_op_iwmmxt_movq_wRn_M0(wrd);
2408 gen_op_iwmmxt_set_mup();
2409 gen_op_iwmmxt_set_cup();
2410 break;
2411 case 0x201: case 0x203: case 0x205: case 0x207:
2412 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2413 case 0x211: case 0x213: case 0x215: case 0x217:
2414 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2415 wrd = (insn >> 5) & 0xf;
2416 rd0 = (insn >> 12) & 0xf;
2417 rd1 = (insn >> 0) & 0xf;
2418 if (rd0 == 0xf || rd1 == 0xf)
2419 return 1;
2420 gen_op_iwmmxt_movq_M0_wRn(wrd);
2421 tmp = load_reg(s, rd0);
2422 tmp2 = load_reg(s, rd1);
2423 switch ((insn >> 16) & 0xf) {
2424 case 0x0: /* TMIA */
2425 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2426 break;
2427 case 0x8: /* TMIAPH */
2428 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2429 break;
2430 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2431 if (insn & (1 << 16))
2432 tcg_gen_shri_i32(tmp, tmp, 16);
2433 if (insn & (1 << 17))
2434 tcg_gen_shri_i32(tmp2, tmp2, 16);
2435 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2436 break;
2437 default:
2438 tcg_temp_free_i32(tmp2);
2439 tcg_temp_free_i32(tmp);
2440 return 1;
2442 tcg_temp_free_i32(tmp2);
2443 tcg_temp_free_i32(tmp);
2444 gen_op_iwmmxt_movq_wRn_M0(wrd);
2445 gen_op_iwmmxt_set_mup();
2446 break;
2447 default:
2448 return 1;
2451 return 0;
2454 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2455 (ie. an undefined instruction). */
2456 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2458 int acc, rd0, rd1, rdhi, rdlo;
2459 TCGv_i32 tmp, tmp2;
2461 if ((insn & 0x0ff00f10) == 0x0e200010) {
2462 /* Multiply with Internal Accumulate Format */
2463 rd0 = (insn >> 12) & 0xf;
2464 rd1 = insn & 0xf;
2465 acc = (insn >> 5) & 7;
2467 if (acc != 0)
2468 return 1;
2470 tmp = load_reg(s, rd0);
2471 tmp2 = load_reg(s, rd1);
2472 switch ((insn >> 16) & 0xf) {
2473 case 0x0: /* MIA */
2474 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2475 break;
2476 case 0x8: /* MIAPH */
2477 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2478 break;
2479 case 0xc: /* MIABB */
2480 case 0xd: /* MIABT */
2481 case 0xe: /* MIATB */
2482 case 0xf: /* MIATT */
2483 if (insn & (1 << 16))
2484 tcg_gen_shri_i32(tmp, tmp, 16);
2485 if (insn & (1 << 17))
2486 tcg_gen_shri_i32(tmp2, tmp2, 16);
2487 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2488 break;
2489 default:
2490 return 1;
2492 tcg_temp_free_i32(tmp2);
2493 tcg_temp_free_i32(tmp);
2495 gen_op_iwmmxt_movq_wRn_M0(acc);
2496 return 0;
2499 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2500 /* Internal Accumulator Access Format */
2501 rdhi = (insn >> 16) & 0xf;
2502 rdlo = (insn >> 12) & 0xf;
2503 acc = insn & 7;
2505 if (acc != 0)
2506 return 1;
2508 if (insn & ARM_CP_RW_BIT) { /* MRA */
2509 iwmmxt_load_reg(cpu_V0, acc);
2510 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2511 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2512 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2513 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2514 } else { /* MAR */
2515 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2516 iwmmxt_store_reg(cpu_V0, acc);
2518 return 0;
2521 return 1;
2524 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2525 #define VFP_SREG(insn, bigbit, smallbit) \
2526 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2527 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2528 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2529 reg = (((insn) >> (bigbit)) & 0x0f) \
2530 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2531 } else { \
2532 if (insn & (1 << (smallbit))) \
2533 return 1; \
2534 reg = ((insn) >> (bigbit)) & 0x0f; \
2535 }} while (0)
2537 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2538 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2539 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2540 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2541 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2542 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2544 /* Move between integer and VFP cores. */
2545 static TCGv_i32 gen_vfp_mrs(void)
2547 TCGv_i32 tmp = tcg_temp_new_i32();
2548 tcg_gen_mov_i32(tmp, cpu_F0s);
2549 return tmp;
2552 static void gen_vfp_msr(TCGv_i32 tmp)
2554 tcg_gen_mov_i32(cpu_F0s, tmp);
2555 tcg_temp_free_i32(tmp);
2558 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2560 TCGv_i32 tmp = tcg_temp_new_i32();
2561 if (shift)
2562 tcg_gen_shri_i32(var, var, shift);
2563 tcg_gen_ext8u_i32(var, var);
2564 tcg_gen_shli_i32(tmp, var, 8);
2565 tcg_gen_or_i32(var, var, tmp);
2566 tcg_gen_shli_i32(tmp, var, 16);
2567 tcg_gen_or_i32(var, var, tmp);
2568 tcg_temp_free_i32(tmp);
2571 static void gen_neon_dup_low16(TCGv_i32 var)
2573 TCGv_i32 tmp = tcg_temp_new_i32();
2574 tcg_gen_ext16u_i32(var, var);
2575 tcg_gen_shli_i32(tmp, var, 16);
2576 tcg_gen_or_i32(var, var, tmp);
2577 tcg_temp_free_i32(tmp);
2580 static void gen_neon_dup_high16(TCGv_i32 var)
2582 TCGv_i32 tmp = tcg_temp_new_i32();
2583 tcg_gen_andi_i32(var, var, 0xffff0000);
2584 tcg_gen_shri_i32(tmp, var, 16);
2585 tcg_gen_or_i32(var, var, tmp);
2586 tcg_temp_free_i32(tmp);
2589 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2591 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2592 TCGv_i32 tmp = tcg_temp_new_i32();
2593 switch (size) {
2594 case 0:
2595 gen_aa32_ld8u(tmp, addr, IS_USER(s));
2596 gen_neon_dup_u8(tmp, 0);
2597 break;
2598 case 1:
2599 gen_aa32_ld16u(tmp, addr, IS_USER(s));
2600 gen_neon_dup_low16(tmp);
2601 break;
2602 case 2:
2603 gen_aa32_ld32u(tmp, addr, IS_USER(s));
2604 break;
2605 default: /* Avoid compiler warnings. */
2606 abort();
2608 return tmp;
2611 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2612 uint32_t dp)
2614 uint32_t cc = extract32(insn, 20, 2);
2616 if (dp) {
2617 TCGv_i64 frn, frm, dest;
2618 TCGv_i64 tmp, zero, zf, nf, vf;
2620 zero = tcg_const_i64(0);
2622 frn = tcg_temp_new_i64();
2623 frm = tcg_temp_new_i64();
2624 dest = tcg_temp_new_i64();
2626 zf = tcg_temp_new_i64();
2627 nf = tcg_temp_new_i64();
2628 vf = tcg_temp_new_i64();
2630 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2631 tcg_gen_ext_i32_i64(nf, cpu_NF);
2632 tcg_gen_ext_i32_i64(vf, cpu_VF);
2634 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2635 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2636 switch (cc) {
2637 case 0: /* eq: Z */
2638 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2639 frn, frm);
2640 break;
2641 case 1: /* vs: V */
2642 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2643 frn, frm);
2644 break;
2645 case 2: /* ge: N == V -> N ^ V == 0 */
2646 tmp = tcg_temp_new_i64();
2647 tcg_gen_xor_i64(tmp, vf, nf);
2648 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2649 frn, frm);
2650 tcg_temp_free_i64(tmp);
2651 break;
2652 case 3: /* gt: !Z && N == V */
2653 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2654 frn, frm);
2655 tmp = tcg_temp_new_i64();
2656 tcg_gen_xor_i64(tmp, vf, nf);
2657 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2658 dest, frm);
2659 tcg_temp_free_i64(tmp);
2660 break;
2662 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2663 tcg_temp_free_i64(frn);
2664 tcg_temp_free_i64(frm);
2665 tcg_temp_free_i64(dest);
2667 tcg_temp_free_i64(zf);
2668 tcg_temp_free_i64(nf);
2669 tcg_temp_free_i64(vf);
2671 tcg_temp_free_i64(zero);
2672 } else {
2673 TCGv_i32 frn, frm, dest;
2674 TCGv_i32 tmp, zero;
2676 zero = tcg_const_i32(0);
2678 frn = tcg_temp_new_i32();
2679 frm = tcg_temp_new_i32();
2680 dest = tcg_temp_new_i32();
2681 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2682 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2683 switch (cc) {
2684 case 0: /* eq: Z */
2685 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2686 frn, frm);
2687 break;
2688 case 1: /* vs: V */
2689 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2690 frn, frm);
2691 break;
2692 case 2: /* ge: N == V -> N ^ V == 0 */
2693 tmp = tcg_temp_new_i32();
2694 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2695 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2696 frn, frm);
2697 tcg_temp_free_i32(tmp);
2698 break;
2699 case 3: /* gt: !Z && N == V */
2700 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2701 frn, frm);
2702 tmp = tcg_temp_new_i32();
2703 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2704 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2705 dest, frm);
2706 tcg_temp_free_i32(tmp);
2707 break;
2709 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2710 tcg_temp_free_i32(frn);
2711 tcg_temp_free_i32(frm);
2712 tcg_temp_free_i32(dest);
2714 tcg_temp_free_i32(zero);
2717 return 0;
2720 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2721 uint32_t rm, uint32_t dp)
2723 uint32_t vmin = extract32(insn, 6, 1);
2724 TCGv_ptr fpst = get_fpstatus_ptr(0);
2726 if (dp) {
2727 TCGv_i64 frn, frm, dest;
2729 frn = tcg_temp_new_i64();
2730 frm = tcg_temp_new_i64();
2731 dest = tcg_temp_new_i64();
2733 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2734 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2735 if (vmin) {
2736 gen_helper_vfp_minnmd(dest, frn, frm, fpst);
2737 } else {
2738 gen_helper_vfp_maxnmd(dest, frn, frm, fpst);
2740 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2741 tcg_temp_free_i64(frn);
2742 tcg_temp_free_i64(frm);
2743 tcg_temp_free_i64(dest);
2744 } else {
2745 TCGv_i32 frn, frm, dest;
2747 frn = tcg_temp_new_i32();
2748 frm = tcg_temp_new_i32();
2749 dest = tcg_temp_new_i32();
2751 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2752 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2753 if (vmin) {
2754 gen_helper_vfp_minnms(dest, frn, frm, fpst);
2755 } else {
2756 gen_helper_vfp_maxnms(dest, frn, frm, fpst);
2758 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2759 tcg_temp_free_i32(frn);
2760 tcg_temp_free_i32(frm);
2761 tcg_temp_free_i32(dest);
2764 tcg_temp_free_ptr(fpst);
2765 return 0;
2768 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2770 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2772 if (!arm_feature(env, ARM_FEATURE_V8)) {
2773 return 1;
2776 if (dp) {
2777 VFP_DREG_D(rd, insn);
2778 VFP_DREG_N(rn, insn);
2779 VFP_DREG_M(rm, insn);
2780 } else {
2781 rd = VFP_SREG_D(insn);
2782 rn = VFP_SREG_N(insn);
2783 rm = VFP_SREG_M(insn);
2786 if ((insn & 0x0f800e50) == 0x0e000a00) {
2787 return handle_vsel(insn, rd, rn, rm, dp);
2788 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2789 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2791 return 1;
2794 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2795 (ie. an undefined instruction). */
2796 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2798 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2799 int dp, veclen;
2800 TCGv_i32 addr;
2801 TCGv_i32 tmp;
2802 TCGv_i32 tmp2;
2804 if (!arm_feature(env, ARM_FEATURE_VFP))
2805 return 1;
2807 if (!s->vfp_enabled) {
2808 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2809 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2810 return 1;
2811 rn = (insn >> 16) & 0xf;
2812 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2813 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2814 return 1;
2817 if (extract32(insn, 28, 4) == 0xf) {
2818 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2819 * only used in v8 and above.
2821 return disas_vfp_v8_insn(env, s, insn);
2824 dp = ((insn & 0xf00) == 0xb00);
2825 switch ((insn >> 24) & 0xf) {
2826 case 0xe:
2827 if (insn & (1 << 4)) {
2828 /* single register transfer */
2829 rd = (insn >> 12) & 0xf;
2830 if (dp) {
2831 int size;
2832 int pass;
2834 VFP_DREG_N(rn, insn);
2835 if (insn & 0xf)
2836 return 1;
2837 if (insn & 0x00c00060
2838 && !arm_feature(env, ARM_FEATURE_NEON))
2839 return 1;
2841 pass = (insn >> 21) & 1;
2842 if (insn & (1 << 22)) {
2843 size = 0;
2844 offset = ((insn >> 5) & 3) * 8;
2845 } else if (insn & (1 << 5)) {
2846 size = 1;
2847 offset = (insn & (1 << 6)) ? 16 : 0;
2848 } else {
2849 size = 2;
2850 offset = 0;
2852 if (insn & ARM_CP_RW_BIT) {
2853 /* vfp->arm */
2854 tmp = neon_load_reg(rn, pass);
2855 switch (size) {
2856 case 0:
2857 if (offset)
2858 tcg_gen_shri_i32(tmp, tmp, offset);
2859 if (insn & (1 << 23))
2860 gen_uxtb(tmp);
2861 else
2862 gen_sxtb(tmp);
2863 break;
2864 case 1:
2865 if (insn & (1 << 23)) {
2866 if (offset) {
2867 tcg_gen_shri_i32(tmp, tmp, 16);
2868 } else {
2869 gen_uxth(tmp);
2871 } else {
2872 if (offset) {
2873 tcg_gen_sari_i32(tmp, tmp, 16);
2874 } else {
2875 gen_sxth(tmp);
2878 break;
2879 case 2:
2880 break;
2882 store_reg(s, rd, tmp);
2883 } else {
2884 /* arm->vfp */
2885 tmp = load_reg(s, rd);
2886 if (insn & (1 << 23)) {
2887 /* VDUP */
2888 if (size == 0) {
2889 gen_neon_dup_u8(tmp, 0);
2890 } else if (size == 1) {
2891 gen_neon_dup_low16(tmp);
2893 for (n = 0; n <= pass * 2; n++) {
2894 tmp2 = tcg_temp_new_i32();
2895 tcg_gen_mov_i32(tmp2, tmp);
2896 neon_store_reg(rn, n, tmp2);
2898 neon_store_reg(rn, n, tmp);
2899 } else {
2900 /* VMOV */
2901 switch (size) {
2902 case 0:
2903 tmp2 = neon_load_reg(rn, pass);
2904 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2905 tcg_temp_free_i32(tmp2);
2906 break;
2907 case 1:
2908 tmp2 = neon_load_reg(rn, pass);
2909 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2910 tcg_temp_free_i32(tmp2);
2911 break;
2912 case 2:
2913 break;
2915 neon_store_reg(rn, pass, tmp);
2918 } else { /* !dp */
2919 if ((insn & 0x6f) != 0x00)
2920 return 1;
2921 rn = VFP_SREG_N(insn);
2922 if (insn & ARM_CP_RW_BIT) {
2923 /* vfp->arm */
2924 if (insn & (1 << 21)) {
2925 /* system register */
2926 rn >>= 1;
2928 switch (rn) {
2929 case ARM_VFP_FPSID:
2930 /* VFP2 allows access to FSID from userspace.
2931 VFP3 restricts all id registers to privileged
2932 accesses. */
2933 if (IS_USER(s)
2934 && arm_feature(env, ARM_FEATURE_VFP3))
2935 return 1;
2936 tmp = load_cpu_field(vfp.xregs[rn]);
2937 break;
2938 case ARM_VFP_FPEXC:
2939 if (IS_USER(s))
2940 return 1;
2941 tmp = load_cpu_field(vfp.xregs[rn]);
2942 break;
2943 case ARM_VFP_FPINST:
2944 case ARM_VFP_FPINST2:
2945 /* Not present in VFP3. */
2946 if (IS_USER(s)
2947 || arm_feature(env, ARM_FEATURE_VFP3))
2948 return 1;
2949 tmp = load_cpu_field(vfp.xregs[rn]);
2950 break;
2951 case ARM_VFP_FPSCR:
2952 if (rd == 15) {
2953 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2954 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2955 } else {
2956 tmp = tcg_temp_new_i32();
2957 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2959 break;
2960 case ARM_VFP_MVFR0:
2961 case ARM_VFP_MVFR1:
2962 if (IS_USER(s)
2963 || !arm_feature(env, ARM_FEATURE_MVFR))
2964 return 1;
2965 tmp = load_cpu_field(vfp.xregs[rn]);
2966 break;
2967 default:
2968 return 1;
2970 } else {
2971 gen_mov_F0_vreg(0, rn);
2972 tmp = gen_vfp_mrs();
2974 if (rd == 15) {
2975 /* Set the 4 flag bits in the CPSR. */
2976 gen_set_nzcv(tmp);
2977 tcg_temp_free_i32(tmp);
2978 } else {
2979 store_reg(s, rd, tmp);
2981 } else {
2982 /* arm->vfp */
2983 if (insn & (1 << 21)) {
2984 rn >>= 1;
2985 /* system register */
2986 switch (rn) {
2987 case ARM_VFP_FPSID:
2988 case ARM_VFP_MVFR0:
2989 case ARM_VFP_MVFR1:
2990 /* Writes are ignored. */
2991 break;
2992 case ARM_VFP_FPSCR:
2993 tmp = load_reg(s, rd);
2994 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2995 tcg_temp_free_i32(tmp);
2996 gen_lookup_tb(s);
2997 break;
2998 case ARM_VFP_FPEXC:
2999 if (IS_USER(s))
3000 return 1;
3001 /* TODO: VFP subarchitecture support.
3002 * For now, keep the EN bit only */
3003 tmp = load_reg(s, rd);
3004 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3005 store_cpu_field(tmp, vfp.xregs[rn]);
3006 gen_lookup_tb(s);
3007 break;
3008 case ARM_VFP_FPINST:
3009 case ARM_VFP_FPINST2:
3010 tmp = load_reg(s, rd);
3011 store_cpu_field(tmp, vfp.xregs[rn]);
3012 break;
3013 default:
3014 return 1;
3016 } else {
3017 tmp = load_reg(s, rd);
3018 gen_vfp_msr(tmp);
3019 gen_mov_vreg_F0(0, rn);
3023 } else {
3024 /* data processing */
3025 /* The opcode is in bits 23, 21, 20 and 6. */
3026 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3027 if (dp) {
3028 if (op == 15) {
3029 /* rn is opcode */
3030 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3031 } else {
3032 /* rn is register number */
3033 VFP_DREG_N(rn, insn);
3036 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
3037 /* Integer or single precision destination. */
3038 rd = VFP_SREG_D(insn);
3039 } else {
3040 VFP_DREG_D(rd, insn);
3042 if (op == 15 &&
3043 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3044 /* VCVT from int is always from S reg regardless of dp bit.
3045 * VCVT with immediate frac_bits has same format as SREG_M
3047 rm = VFP_SREG_M(insn);
3048 } else {
3049 VFP_DREG_M(rm, insn);
3051 } else {
3052 rn = VFP_SREG_N(insn);
3053 if (op == 15 && rn == 15) {
3054 /* Double precision destination. */
3055 VFP_DREG_D(rd, insn);
3056 } else {
3057 rd = VFP_SREG_D(insn);
3059 /* NB that we implicitly rely on the encoding for the frac_bits
3060 * in VCVT of fixed to float being the same as that of an SREG_M
3062 rm = VFP_SREG_M(insn);
3065 veclen = s->vec_len;
3066 if (op == 15 && rn > 3)
3067 veclen = 0;
3069 /* Shut up compiler warnings. */
3070 delta_m = 0;
3071 delta_d = 0;
3072 bank_mask = 0;
3074 if (veclen > 0) {
3075 if (dp)
3076 bank_mask = 0xc;
3077 else
3078 bank_mask = 0x18;
3080 /* Figure out what type of vector operation this is. */
3081 if ((rd & bank_mask) == 0) {
3082 /* scalar */
3083 veclen = 0;
3084 } else {
3085 if (dp)
3086 delta_d = (s->vec_stride >> 1) + 1;
3087 else
3088 delta_d = s->vec_stride + 1;
3090 if ((rm & bank_mask) == 0) {
3091 /* mixed scalar/vector */
3092 delta_m = 0;
3093 } else {
3094 /* vector */
3095 delta_m = delta_d;
3100 /* Load the initial operands. */
3101 if (op == 15) {
3102 switch (rn) {
3103 case 16:
3104 case 17:
3105 /* Integer source */
3106 gen_mov_F0_vreg(0, rm);
3107 break;
3108 case 8:
3109 case 9:
3110 /* Compare */
3111 gen_mov_F0_vreg(dp, rd);
3112 gen_mov_F1_vreg(dp, rm);
3113 break;
3114 case 10:
3115 case 11:
3116 /* Compare with zero */
3117 gen_mov_F0_vreg(dp, rd);
3118 gen_vfp_F1_ld0(dp);
3119 break;
3120 case 20:
3121 case 21:
3122 case 22:
3123 case 23:
3124 case 28:
3125 case 29:
3126 case 30:
3127 case 31:
3128 /* Source and destination the same. */
3129 gen_mov_F0_vreg(dp, rd);
3130 break;
3131 case 4:
3132 case 5:
3133 case 6:
3134 case 7:
3135 /* VCVTB, VCVTT: only present with the halfprec extension,
3136 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3138 if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3139 return 1;
3141 /* Otherwise fall through */
3142 default:
3143 /* One source operand. */
3144 gen_mov_F0_vreg(dp, rm);
3145 break;
3147 } else {
3148 /* Two source operands. */
3149 gen_mov_F0_vreg(dp, rn);
3150 gen_mov_F1_vreg(dp, rm);
3153 for (;;) {
3154 /* Perform the calculation. */
3155 switch (op) {
3156 case 0: /* VMLA: fd + (fn * fm) */
3157 /* Note that order of inputs to the add matters for NaNs */
3158 gen_vfp_F1_mul(dp);
3159 gen_mov_F0_vreg(dp, rd);
3160 gen_vfp_add(dp);
3161 break;
3162 case 1: /* VMLS: fd + -(fn * fm) */
3163 gen_vfp_mul(dp);
3164 gen_vfp_F1_neg(dp);
3165 gen_mov_F0_vreg(dp, rd);
3166 gen_vfp_add(dp);
3167 break;
3168 case 2: /* VNMLS: -fd + (fn * fm) */
3169 /* Note that it isn't valid to replace (-A + B) with (B - A)
3170 * or similar plausible looking simplifications
3171 * because this will give wrong results for NaNs.
3173 gen_vfp_F1_mul(dp);
3174 gen_mov_F0_vreg(dp, rd);
3175 gen_vfp_neg(dp);
3176 gen_vfp_add(dp);
3177 break;
3178 case 3: /* VNMLA: -fd + -(fn * fm) */
3179 gen_vfp_mul(dp);
3180 gen_vfp_F1_neg(dp);
3181 gen_mov_F0_vreg(dp, rd);
3182 gen_vfp_neg(dp);
3183 gen_vfp_add(dp);
3184 break;
3185 case 4: /* mul: fn * fm */
3186 gen_vfp_mul(dp);
3187 break;
3188 case 5: /* nmul: -(fn * fm) */
3189 gen_vfp_mul(dp);
3190 gen_vfp_neg(dp);
3191 break;
3192 case 6: /* add: fn + fm */
3193 gen_vfp_add(dp);
3194 break;
3195 case 7: /* sub: fn - fm */
3196 gen_vfp_sub(dp);
3197 break;
3198 case 8: /* div: fn / fm */
3199 gen_vfp_div(dp);
3200 break;
3201 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3202 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3203 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3204 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3205 /* These are fused multiply-add, and must be done as one
3206 * floating point operation with no rounding between the
3207 * multiplication and addition steps.
3208 * NB that doing the negations here as separate steps is
3209 * correct : an input NaN should come out with its sign bit
3210 * flipped if it is a negated-input.
3212 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3213 return 1;
3215 if (dp) {
3216 TCGv_ptr fpst;
3217 TCGv_i64 frd;
3218 if (op & 1) {
3219 /* VFNMS, VFMS */
3220 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3222 frd = tcg_temp_new_i64();
3223 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3224 if (op & 2) {
3225 /* VFNMA, VFNMS */
3226 gen_helper_vfp_negd(frd, frd);
3228 fpst = get_fpstatus_ptr(0);
3229 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3230 cpu_F1d, frd, fpst);
3231 tcg_temp_free_ptr(fpst);
3232 tcg_temp_free_i64(frd);
3233 } else {
3234 TCGv_ptr fpst;
3235 TCGv_i32 frd;
3236 if (op & 1) {
3237 /* VFNMS, VFMS */
3238 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3240 frd = tcg_temp_new_i32();
3241 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3242 if (op & 2) {
3243 gen_helper_vfp_negs(frd, frd);
3245 fpst = get_fpstatus_ptr(0);
3246 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3247 cpu_F1s, frd, fpst);
3248 tcg_temp_free_ptr(fpst);
3249 tcg_temp_free_i32(frd);
3251 break;
3252 case 14: /* fconst */
3253 if (!arm_feature(env, ARM_FEATURE_VFP3))
3254 return 1;
3256 n = (insn << 12) & 0x80000000;
3257 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3258 if (dp) {
3259 if (i & 0x40)
3260 i |= 0x3f80;
3261 else
3262 i |= 0x4000;
3263 n |= i << 16;
3264 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3265 } else {
3266 if (i & 0x40)
3267 i |= 0x780;
3268 else
3269 i |= 0x800;
3270 n |= i << 19;
3271 tcg_gen_movi_i32(cpu_F0s, n);
3273 break;
3274 case 15: /* extension space */
3275 switch (rn) {
3276 case 0: /* cpy */
3277 /* no-op */
3278 break;
3279 case 1: /* abs */
3280 gen_vfp_abs(dp);
3281 break;
3282 case 2: /* neg */
3283 gen_vfp_neg(dp);
3284 break;
3285 case 3: /* sqrt */
3286 gen_vfp_sqrt(dp);
3287 break;
3288 case 4: /* vcvtb.f32.f16 */
3289 tmp = gen_vfp_mrs();
3290 tcg_gen_ext16u_i32(tmp, tmp);
3291 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3292 tcg_temp_free_i32(tmp);
3293 break;
3294 case 5: /* vcvtt.f32.f16 */
3295 tmp = gen_vfp_mrs();
3296 tcg_gen_shri_i32(tmp, tmp, 16);
3297 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3298 tcg_temp_free_i32(tmp);
3299 break;
3300 case 6: /* vcvtb.f16.f32 */
3301 tmp = tcg_temp_new_i32();
3302 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3303 gen_mov_F0_vreg(0, rd);
3304 tmp2 = gen_vfp_mrs();
3305 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3306 tcg_gen_or_i32(tmp, tmp, tmp2);
3307 tcg_temp_free_i32(tmp2);
3308 gen_vfp_msr(tmp);
3309 break;
3310 case 7: /* vcvtt.f16.f32 */
3311 tmp = tcg_temp_new_i32();
3312 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3313 tcg_gen_shli_i32(tmp, tmp, 16);
3314 gen_mov_F0_vreg(0, rd);
3315 tmp2 = gen_vfp_mrs();
3316 tcg_gen_ext16u_i32(tmp2, tmp2);
3317 tcg_gen_or_i32(tmp, tmp, tmp2);
3318 tcg_temp_free_i32(tmp2);
3319 gen_vfp_msr(tmp);
3320 break;
3321 case 8: /* cmp */
3322 gen_vfp_cmp(dp);
3323 break;
3324 case 9: /* cmpe */
3325 gen_vfp_cmpe(dp);
3326 break;
3327 case 10: /* cmpz */
3328 gen_vfp_cmp(dp);
3329 break;
3330 case 11: /* cmpez */
3331 gen_vfp_F1_ld0(dp);
3332 gen_vfp_cmpe(dp);
3333 break;
3334 case 15: /* single<->double conversion */
3335 if (dp)
3336 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3337 else
3338 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3339 break;
3340 case 16: /* fuito */
3341 gen_vfp_uito(dp, 0);
3342 break;
3343 case 17: /* fsito */
3344 gen_vfp_sito(dp, 0);
3345 break;
3346 case 20: /* fshto */
3347 if (!arm_feature(env, ARM_FEATURE_VFP3))
3348 return 1;
3349 gen_vfp_shto(dp, 16 - rm, 0);
3350 break;
3351 case 21: /* fslto */
3352 if (!arm_feature(env, ARM_FEATURE_VFP3))
3353 return 1;
3354 gen_vfp_slto(dp, 32 - rm, 0);
3355 break;
3356 case 22: /* fuhto */
3357 if (!arm_feature(env, ARM_FEATURE_VFP3))
3358 return 1;
3359 gen_vfp_uhto(dp, 16 - rm, 0);
3360 break;
3361 case 23: /* fulto */
3362 if (!arm_feature(env, ARM_FEATURE_VFP3))
3363 return 1;
3364 gen_vfp_ulto(dp, 32 - rm, 0);
3365 break;
3366 case 24: /* ftoui */
3367 gen_vfp_toui(dp, 0);
3368 break;
3369 case 25: /* ftouiz */
3370 gen_vfp_touiz(dp, 0);
3371 break;
3372 case 26: /* ftosi */
3373 gen_vfp_tosi(dp, 0);
3374 break;
3375 case 27: /* ftosiz */
3376 gen_vfp_tosiz(dp, 0);
3377 break;
3378 case 28: /* ftosh */
3379 if (!arm_feature(env, ARM_FEATURE_VFP3))
3380 return 1;
3381 gen_vfp_tosh(dp, 16 - rm, 0);
3382 break;
3383 case 29: /* ftosl */
3384 if (!arm_feature(env, ARM_FEATURE_VFP3))
3385 return 1;
3386 gen_vfp_tosl(dp, 32 - rm, 0);
3387 break;
3388 case 30: /* ftouh */
3389 if (!arm_feature(env, ARM_FEATURE_VFP3))
3390 return 1;
3391 gen_vfp_touh(dp, 16 - rm, 0);
3392 break;
3393 case 31: /* ftoul */
3394 if (!arm_feature(env, ARM_FEATURE_VFP3))
3395 return 1;
3396 gen_vfp_toul(dp, 32 - rm, 0);
3397 break;
3398 default: /* undefined */
3399 return 1;
3401 break;
3402 default: /* undefined */
3403 return 1;
3406 /* Write back the result. */
3407 if (op == 15 && (rn >= 8 && rn <= 11))
3408 ; /* Comparison, do nothing. */
3409 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3410 /* VCVT double to int: always integer result. */
3411 gen_mov_vreg_F0(0, rd);
3412 else if (op == 15 && rn == 15)
3413 /* conversion */
3414 gen_mov_vreg_F0(!dp, rd);
3415 else
3416 gen_mov_vreg_F0(dp, rd);
3418 /* break out of the loop if we have finished */
3419 if (veclen == 0)
3420 break;
3422 if (op == 15 && delta_m == 0) {
3423 /* single source one-many */
3424 while (veclen--) {
3425 rd = ((rd + delta_d) & (bank_mask - 1))
3426 | (rd & bank_mask);
3427 gen_mov_vreg_F0(dp, rd);
3429 break;
3431 /* Setup the next operands. */
3432 veclen--;
3433 rd = ((rd + delta_d) & (bank_mask - 1))
3434 | (rd & bank_mask);
3436 if (op == 15) {
3437 /* One source operand. */
3438 rm = ((rm + delta_m) & (bank_mask - 1))
3439 | (rm & bank_mask);
3440 gen_mov_F0_vreg(dp, rm);
3441 } else {
3442 /* Two source operands. */
3443 rn = ((rn + delta_d) & (bank_mask - 1))
3444 | (rn & bank_mask);
3445 gen_mov_F0_vreg(dp, rn);
3446 if (delta_m) {
3447 rm = ((rm + delta_m) & (bank_mask - 1))
3448 | (rm & bank_mask);
3449 gen_mov_F1_vreg(dp, rm);
3454 break;
3455 case 0xc:
3456 case 0xd:
3457 if ((insn & 0x03e00000) == 0x00400000) {
3458 /* two-register transfer */
3459 rn = (insn >> 16) & 0xf;
3460 rd = (insn >> 12) & 0xf;
3461 if (dp) {
3462 VFP_DREG_M(rm, insn);
3463 } else {
3464 rm = VFP_SREG_M(insn);
3467 if (insn & ARM_CP_RW_BIT) {
3468 /* vfp->arm */
3469 if (dp) {
3470 gen_mov_F0_vreg(0, rm * 2);
3471 tmp = gen_vfp_mrs();
3472 store_reg(s, rd, tmp);
3473 gen_mov_F0_vreg(0, rm * 2 + 1);
3474 tmp = gen_vfp_mrs();
3475 store_reg(s, rn, tmp);
3476 } else {
3477 gen_mov_F0_vreg(0, rm);
3478 tmp = gen_vfp_mrs();
3479 store_reg(s, rd, tmp);
3480 gen_mov_F0_vreg(0, rm + 1);
3481 tmp = gen_vfp_mrs();
3482 store_reg(s, rn, tmp);
3484 } else {
3485 /* arm->vfp */
3486 if (dp) {
3487 tmp = load_reg(s, rd);
3488 gen_vfp_msr(tmp);
3489 gen_mov_vreg_F0(0, rm * 2);
3490 tmp = load_reg(s, rn);
3491 gen_vfp_msr(tmp);
3492 gen_mov_vreg_F0(0, rm * 2 + 1);
3493 } else {
3494 tmp = load_reg(s, rd);
3495 gen_vfp_msr(tmp);
3496 gen_mov_vreg_F0(0, rm);
3497 tmp = load_reg(s, rn);
3498 gen_vfp_msr(tmp);
3499 gen_mov_vreg_F0(0, rm + 1);
3502 } else {
3503 /* Load/store */
3504 rn = (insn >> 16) & 0xf;
3505 if (dp)
3506 VFP_DREG_D(rd, insn);
3507 else
3508 rd = VFP_SREG_D(insn);
3509 if ((insn & 0x01200000) == 0x01000000) {
3510 /* Single load/store */
3511 offset = (insn & 0xff) << 2;
3512 if ((insn & (1 << 23)) == 0)
3513 offset = -offset;
3514 if (s->thumb && rn == 15) {
3515 /* This is actually UNPREDICTABLE */
3516 addr = tcg_temp_new_i32();
3517 tcg_gen_movi_i32(addr, s->pc & ~2);
3518 } else {
3519 addr = load_reg(s, rn);
3521 tcg_gen_addi_i32(addr, addr, offset);
3522 if (insn & (1 << 20)) {
3523 gen_vfp_ld(s, dp, addr);
3524 gen_mov_vreg_F0(dp, rd);
3525 } else {
3526 gen_mov_F0_vreg(dp, rd);
3527 gen_vfp_st(s, dp, addr);
3529 tcg_temp_free_i32(addr);
3530 } else {
3531 /* load/store multiple */
3532 int w = insn & (1 << 21);
3533 if (dp)
3534 n = (insn >> 1) & 0x7f;
3535 else
3536 n = insn & 0xff;
3538 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3539 /* P == U , W == 1 => UNDEF */
3540 return 1;
3542 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3543 /* UNPREDICTABLE cases for bad immediates: we choose to
3544 * UNDEF to avoid generating huge numbers of TCG ops
3546 return 1;
3548 if (rn == 15 && w) {
3549 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3550 return 1;
3553 if (s->thumb && rn == 15) {
3554 /* This is actually UNPREDICTABLE */
3555 addr = tcg_temp_new_i32();
3556 tcg_gen_movi_i32(addr, s->pc & ~2);
3557 } else {
3558 addr = load_reg(s, rn);
3560 if (insn & (1 << 24)) /* pre-decrement */
3561 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3563 if (dp)
3564 offset = 8;
3565 else
3566 offset = 4;
3567 for (i = 0; i < n; i++) {
3568 if (insn & ARM_CP_RW_BIT) {
3569 /* load */
3570 gen_vfp_ld(s, dp, addr);
3571 gen_mov_vreg_F0(dp, rd + i);
3572 } else {
3573 /* store */
3574 gen_mov_F0_vreg(dp, rd + i);
3575 gen_vfp_st(s, dp, addr);
3577 tcg_gen_addi_i32(addr, addr, offset);
3579 if (w) {
3580 /* writeback */
3581 if (insn & (1 << 24))
3582 offset = -offset * n;
3583 else if (dp && (insn & 1))
3584 offset = 4;
3585 else
3586 offset = 0;
3588 if (offset != 0)
3589 tcg_gen_addi_i32(addr, addr, offset);
3590 store_reg(s, rn, addr);
3591 } else {
3592 tcg_temp_free_i32(addr);
3596 break;
3597 default:
3598 /* Should never happen. */
3599 return 1;
3601 return 0;
3604 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3606 TranslationBlock *tb;
3608 tb = s->tb;
3609 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3610 tcg_gen_goto_tb(n);
3611 gen_set_pc_im(s, dest);
3612 tcg_gen_exit_tb((uintptr_t)tb + n);
3613 } else {
3614 gen_set_pc_im(s, dest);
3615 tcg_gen_exit_tb(0);
3619 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3621 if (unlikely(s->singlestep_enabled)) {
3622 /* An indirect jump so that we still trigger the debug exception. */
3623 if (s->thumb)
3624 dest |= 1;
3625 gen_bx_im(s, dest);
3626 } else {
3627 gen_goto_tb(s, 0, dest);
3628 s->is_jmp = DISAS_TB_JUMP;
3632 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3634 if (x)
3635 tcg_gen_sari_i32(t0, t0, 16);
3636 else
3637 gen_sxth(t0);
3638 if (y)
3639 tcg_gen_sari_i32(t1, t1, 16);
3640 else
3641 gen_sxth(t1);
3642 tcg_gen_mul_i32(t0, t0, t1);
3645 /* Return the mask of PSR bits set by a MSR instruction. */
3646 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3647 uint32_t mask;
3649 mask = 0;
3650 if (flags & (1 << 0))
3651 mask |= 0xff;
3652 if (flags & (1 << 1))
3653 mask |= 0xff00;
3654 if (flags & (1 << 2))
3655 mask |= 0xff0000;
3656 if (flags & (1 << 3))
3657 mask |= 0xff000000;
3659 /* Mask out undefined bits. */
3660 mask &= ~CPSR_RESERVED;
3661 if (!arm_feature(env, ARM_FEATURE_V4T))
3662 mask &= ~CPSR_T;
3663 if (!arm_feature(env, ARM_FEATURE_V5))
3664 mask &= ~CPSR_Q; /* V5TE in reality*/
3665 if (!arm_feature(env, ARM_FEATURE_V6))
3666 mask &= ~(CPSR_E | CPSR_GE);
3667 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3668 mask &= ~CPSR_IT;
3669 /* Mask out execution state bits. */
3670 if (!spsr)
3671 mask &= ~CPSR_EXEC;
3672 /* Mask out privileged bits. */
3673 if (IS_USER(s))
3674 mask &= CPSR_USER;
3675 return mask;
3678 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3679 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3681 TCGv_i32 tmp;
3682 if (spsr) {
3683 /* ??? This is also undefined in system mode. */
3684 if (IS_USER(s))
3685 return 1;
3687 tmp = load_cpu_field(spsr);
3688 tcg_gen_andi_i32(tmp, tmp, ~mask);
3689 tcg_gen_andi_i32(t0, t0, mask);
3690 tcg_gen_or_i32(tmp, tmp, t0);
3691 store_cpu_field(tmp, spsr);
3692 } else {
3693 gen_set_cpsr(t0, mask);
3695 tcg_temp_free_i32(t0);
3696 gen_lookup_tb(s);
3697 return 0;
3700 /* Returns nonzero if access to the PSR is not permitted. */
3701 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3703 TCGv_i32 tmp;
3704 tmp = tcg_temp_new_i32();
3705 tcg_gen_movi_i32(tmp, val);
3706 return gen_set_psr(s, mask, spsr, tmp);
3709 /* Generate an old-style exception return. Marks pc as dead. */
3710 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3712 TCGv_i32 tmp;
3713 store_reg(s, 15, pc);
3714 tmp = load_cpu_field(spsr);
3715 gen_set_cpsr(tmp, 0xffffffff);
3716 tcg_temp_free_i32(tmp);
3717 s->is_jmp = DISAS_UPDATE;
3720 /* Generate a v6 exception return. Marks both values as dead. */
3721 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3723 gen_set_cpsr(cpsr, 0xffffffff);
3724 tcg_temp_free_i32(cpsr);
3725 store_reg(s, 15, pc);
3726 s->is_jmp = DISAS_UPDATE;
3729 static inline void
3730 gen_set_condexec (DisasContext *s)
3732 if (s->condexec_mask) {
3733 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3734 TCGv_i32 tmp = tcg_temp_new_i32();
3735 tcg_gen_movi_i32(tmp, val);
3736 store_cpu_field(tmp, condexec_bits);
3740 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3742 gen_set_condexec(s);
3743 gen_set_pc_im(s, s->pc - offset);
3744 gen_exception(excp);
3745 s->is_jmp = DISAS_JUMP;
3748 static void gen_nop_hint(DisasContext *s, int val)
3750 switch (val) {
3751 case 3: /* wfi */
3752 gen_set_pc_im(s, s->pc);
3753 s->is_jmp = DISAS_WFI;
3754 break;
3755 case 2: /* wfe */
3756 case 4: /* sev */
3757 case 5: /* sevl */
3758 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3759 default: /* nop */
3760 break;
3764 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3766 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3768 switch (size) {
3769 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3770 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3771 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3772 default: abort();
3776 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3778 switch (size) {
3779 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3780 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3781 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3782 default: return;
3786 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3787 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3788 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3789 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3790 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3792 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3793 switch ((size << 1) | u) { \
3794 case 0: \
3795 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3796 break; \
3797 case 1: \
3798 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3799 break; \
3800 case 2: \
3801 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3802 break; \
3803 case 3: \
3804 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3805 break; \
3806 case 4: \
3807 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3808 break; \
3809 case 5: \
3810 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3811 break; \
3812 default: return 1; \
3813 }} while (0)
3815 #define GEN_NEON_INTEGER_OP(name) do { \
3816 switch ((size << 1) | u) { \
3817 case 0: \
3818 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3819 break; \
3820 case 1: \
3821 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3822 break; \
3823 case 2: \
3824 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3825 break; \
3826 case 3: \
3827 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3828 break; \
3829 case 4: \
3830 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3831 break; \
3832 case 5: \
3833 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3834 break; \
3835 default: return 1; \
3836 }} while (0)
3838 static TCGv_i32 neon_load_scratch(int scratch)
3840 TCGv_i32 tmp = tcg_temp_new_i32();
3841 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3842 return tmp;
3845 static void neon_store_scratch(int scratch, TCGv_i32 var)
3847 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3848 tcg_temp_free_i32(var);
3851 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3853 TCGv_i32 tmp;
3854 if (size == 1) {
3855 tmp = neon_load_reg(reg & 7, reg >> 4);
3856 if (reg & 8) {
3857 gen_neon_dup_high16(tmp);
3858 } else {
3859 gen_neon_dup_low16(tmp);
3861 } else {
3862 tmp = neon_load_reg(reg & 15, reg >> 4);
3864 return tmp;
3867 static int gen_neon_unzip(int rd, int rm, int size, int q)
3869 TCGv_i32 tmp, tmp2;
3870 if (!q && size == 2) {
3871 return 1;
3873 tmp = tcg_const_i32(rd);
3874 tmp2 = tcg_const_i32(rm);
3875 if (q) {
3876 switch (size) {
3877 case 0:
3878 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3879 break;
3880 case 1:
3881 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3882 break;
3883 case 2:
3884 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3885 break;
3886 default:
3887 abort();
3889 } else {
3890 switch (size) {
3891 case 0:
3892 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3893 break;
3894 case 1:
3895 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3896 break;
3897 default:
3898 abort();
3901 tcg_temp_free_i32(tmp);
3902 tcg_temp_free_i32(tmp2);
3903 return 0;
3906 static int gen_neon_zip(int rd, int rm, int size, int q)
3908 TCGv_i32 tmp, tmp2;
3909 if (!q && size == 2) {
3910 return 1;
3912 tmp = tcg_const_i32(rd);
3913 tmp2 = tcg_const_i32(rm);
3914 if (q) {
3915 switch (size) {
3916 case 0:
3917 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3918 break;
3919 case 1:
3920 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3921 break;
3922 case 2:
3923 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3924 break;
3925 default:
3926 abort();
3928 } else {
3929 switch (size) {
3930 case 0:
3931 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3932 break;
3933 case 1:
3934 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3935 break;
3936 default:
3937 abort();
3940 tcg_temp_free_i32(tmp);
3941 tcg_temp_free_i32(tmp2);
3942 return 0;
3945 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3947 TCGv_i32 rd, tmp;
3949 rd = tcg_temp_new_i32();
3950 tmp = tcg_temp_new_i32();
3952 tcg_gen_shli_i32(rd, t0, 8);
3953 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3954 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3955 tcg_gen_or_i32(rd, rd, tmp);
3957 tcg_gen_shri_i32(t1, t1, 8);
3958 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3959 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3960 tcg_gen_or_i32(t1, t1, tmp);
3961 tcg_gen_mov_i32(t0, rd);
3963 tcg_temp_free_i32(tmp);
3964 tcg_temp_free_i32(rd);
3967 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3969 TCGv_i32 rd, tmp;
3971 rd = tcg_temp_new_i32();
3972 tmp = tcg_temp_new_i32();
3974 tcg_gen_shli_i32(rd, t0, 16);
3975 tcg_gen_andi_i32(tmp, t1, 0xffff);
3976 tcg_gen_or_i32(rd, rd, tmp);
3977 tcg_gen_shri_i32(t1, t1, 16);
3978 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3979 tcg_gen_or_i32(t1, t1, tmp);
3980 tcg_gen_mov_i32(t0, rd);
3982 tcg_temp_free_i32(tmp);
3983 tcg_temp_free_i32(rd);
3987 static struct {
3988 int nregs;
3989 int interleave;
3990 int spacing;
3991 } neon_ls_element_type[11] = {
3992 {4, 4, 1},
3993 {4, 4, 2},
3994 {4, 1, 1},
3995 {4, 2, 1},
3996 {3, 3, 1},
3997 {3, 3, 2},
3998 {3, 1, 1},
3999 {1, 1, 1},
4000 {2, 2, 1},
4001 {2, 2, 2},
4002 {2, 1, 1}
4005 /* Translate a NEON load/store element instruction. Return nonzero if the
4006 instruction is invalid. */
4007 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4009 int rd, rn, rm;
4010 int op;
4011 int nregs;
4012 int interleave;
4013 int spacing;
4014 int stride;
4015 int size;
4016 int reg;
4017 int pass;
4018 int load;
4019 int shift;
4020 int n;
4021 TCGv_i32 addr;
4022 TCGv_i32 tmp;
4023 TCGv_i32 tmp2;
4024 TCGv_i64 tmp64;
4026 if (!s->vfp_enabled)
4027 return 1;
4028 VFP_DREG_D(rd, insn);
4029 rn = (insn >> 16) & 0xf;
4030 rm = insn & 0xf;
4031 load = (insn & (1 << 21)) != 0;
4032 if ((insn & (1 << 23)) == 0) {
4033 /* Load store all elements. */
4034 op = (insn >> 8) & 0xf;
4035 size = (insn >> 6) & 3;
4036 if (op > 10)
4037 return 1;
4038 /* Catch UNDEF cases for bad values of align field */
4039 switch (op & 0xc) {
4040 case 4:
4041 if (((insn >> 5) & 1) == 1) {
4042 return 1;
4044 break;
4045 case 8:
4046 if (((insn >> 4) & 3) == 3) {
4047 return 1;
4049 break;
4050 default:
4051 break;
4053 nregs = neon_ls_element_type[op].nregs;
4054 interleave = neon_ls_element_type[op].interleave;
4055 spacing = neon_ls_element_type[op].spacing;
4056 if (size == 3 && (interleave | spacing) != 1)
4057 return 1;
4058 addr = tcg_temp_new_i32();
4059 load_reg_var(s, addr, rn);
4060 stride = (1 << size) * interleave;
4061 for (reg = 0; reg < nregs; reg++) {
4062 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4063 load_reg_var(s, addr, rn);
4064 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4065 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4066 load_reg_var(s, addr, rn);
4067 tcg_gen_addi_i32(addr, addr, 1 << size);
4069 if (size == 3) {
4070 tmp64 = tcg_temp_new_i64();
4071 if (load) {
4072 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4073 neon_store_reg64(tmp64, rd);
4074 } else {
4075 neon_load_reg64(tmp64, rd);
4076 gen_aa32_st64(tmp64, addr, IS_USER(s));
4078 tcg_temp_free_i64(tmp64);
4079 tcg_gen_addi_i32(addr, addr, stride);
4080 } else {
4081 for (pass = 0; pass < 2; pass++) {
4082 if (size == 2) {
4083 if (load) {
4084 tmp = tcg_temp_new_i32();
4085 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4086 neon_store_reg(rd, pass, tmp);
4087 } else {
4088 tmp = neon_load_reg(rd, pass);
4089 gen_aa32_st32(tmp, addr, IS_USER(s));
4090 tcg_temp_free_i32(tmp);
4092 tcg_gen_addi_i32(addr, addr, stride);
4093 } else if (size == 1) {
4094 if (load) {
4095 tmp = tcg_temp_new_i32();
4096 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4097 tcg_gen_addi_i32(addr, addr, stride);
4098 tmp2 = tcg_temp_new_i32();
4099 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4100 tcg_gen_addi_i32(addr, addr, stride);
4101 tcg_gen_shli_i32(tmp2, tmp2, 16);
4102 tcg_gen_or_i32(tmp, tmp, tmp2);
4103 tcg_temp_free_i32(tmp2);
4104 neon_store_reg(rd, pass, tmp);
4105 } else {
4106 tmp = neon_load_reg(rd, pass);
4107 tmp2 = tcg_temp_new_i32();
4108 tcg_gen_shri_i32(tmp2, tmp, 16);
4109 gen_aa32_st16(tmp, addr, IS_USER(s));
4110 tcg_temp_free_i32(tmp);
4111 tcg_gen_addi_i32(addr, addr, stride);
4112 gen_aa32_st16(tmp2, addr, IS_USER(s));
4113 tcg_temp_free_i32(tmp2);
4114 tcg_gen_addi_i32(addr, addr, stride);
4116 } else /* size == 0 */ {
4117 if (load) {
4118 TCGV_UNUSED_I32(tmp2);
4119 for (n = 0; n < 4; n++) {
4120 tmp = tcg_temp_new_i32();
4121 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4122 tcg_gen_addi_i32(addr, addr, stride);
4123 if (n == 0) {
4124 tmp2 = tmp;
4125 } else {
4126 tcg_gen_shli_i32(tmp, tmp, n * 8);
4127 tcg_gen_or_i32(tmp2, tmp2, tmp);
4128 tcg_temp_free_i32(tmp);
4131 neon_store_reg(rd, pass, tmp2);
4132 } else {
4133 tmp2 = neon_load_reg(rd, pass);
4134 for (n = 0; n < 4; n++) {
4135 tmp = tcg_temp_new_i32();
4136 if (n == 0) {
4137 tcg_gen_mov_i32(tmp, tmp2);
4138 } else {
4139 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4141 gen_aa32_st8(tmp, addr, IS_USER(s));
4142 tcg_temp_free_i32(tmp);
4143 tcg_gen_addi_i32(addr, addr, stride);
4145 tcg_temp_free_i32(tmp2);
4150 rd += spacing;
4152 tcg_temp_free_i32(addr);
4153 stride = nregs * 8;
4154 } else {
4155 size = (insn >> 10) & 3;
4156 if (size == 3) {
4157 /* Load single element to all lanes. */
4158 int a = (insn >> 4) & 1;
4159 if (!load) {
4160 return 1;
4162 size = (insn >> 6) & 3;
4163 nregs = ((insn >> 8) & 3) + 1;
4165 if (size == 3) {
4166 if (nregs != 4 || a == 0) {
4167 return 1;
4169 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4170 size = 2;
4172 if (nregs == 1 && a == 1 && size == 0) {
4173 return 1;
4175 if (nregs == 3 && a == 1) {
4176 return 1;
4178 addr = tcg_temp_new_i32();
4179 load_reg_var(s, addr, rn);
4180 if (nregs == 1) {
4181 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4182 tmp = gen_load_and_replicate(s, addr, size);
4183 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4184 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4185 if (insn & (1 << 5)) {
4186 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4187 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4189 tcg_temp_free_i32(tmp);
4190 } else {
4191 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4192 stride = (insn & (1 << 5)) ? 2 : 1;
4193 for (reg = 0; reg < nregs; reg++) {
4194 tmp = gen_load_and_replicate(s, addr, size);
4195 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4196 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4197 tcg_temp_free_i32(tmp);
4198 tcg_gen_addi_i32(addr, addr, 1 << size);
4199 rd += stride;
4202 tcg_temp_free_i32(addr);
4203 stride = (1 << size) * nregs;
4204 } else {
4205 /* Single element. */
4206 int idx = (insn >> 4) & 0xf;
4207 pass = (insn >> 7) & 1;
4208 switch (size) {
4209 case 0:
4210 shift = ((insn >> 5) & 3) * 8;
4211 stride = 1;
4212 break;
4213 case 1:
4214 shift = ((insn >> 6) & 1) * 16;
4215 stride = (insn & (1 << 5)) ? 2 : 1;
4216 break;
4217 case 2:
4218 shift = 0;
4219 stride = (insn & (1 << 6)) ? 2 : 1;
4220 break;
4221 default:
4222 abort();
4224 nregs = ((insn >> 8) & 3) + 1;
4225 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4226 switch (nregs) {
4227 case 1:
4228 if (((idx & (1 << size)) != 0) ||
4229 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4230 return 1;
4232 break;
4233 case 3:
4234 if ((idx & 1) != 0) {
4235 return 1;
4237 /* fall through */
4238 case 2:
4239 if (size == 2 && (idx & 2) != 0) {
4240 return 1;
4242 break;
4243 case 4:
4244 if ((size == 2) && ((idx & 3) == 3)) {
4245 return 1;
4247 break;
4248 default:
4249 abort();
4251 if ((rd + stride * (nregs - 1)) > 31) {
4252 /* Attempts to write off the end of the register file
4253 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4254 * the neon_load_reg() would write off the end of the array.
4256 return 1;
4258 addr = tcg_temp_new_i32();
4259 load_reg_var(s, addr, rn);
4260 for (reg = 0; reg < nregs; reg++) {
4261 if (load) {
4262 tmp = tcg_temp_new_i32();
4263 switch (size) {
4264 case 0:
4265 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4266 break;
4267 case 1:
4268 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4269 break;
4270 case 2:
4271 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4272 break;
4273 default: /* Avoid compiler warnings. */
4274 abort();
4276 if (size != 2) {
4277 tmp2 = neon_load_reg(rd, pass);
4278 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4279 shift, size ? 16 : 8);
4280 tcg_temp_free_i32(tmp2);
4282 neon_store_reg(rd, pass, tmp);
4283 } else { /* Store */
4284 tmp = neon_load_reg(rd, pass);
4285 if (shift)
4286 tcg_gen_shri_i32(tmp, tmp, shift);
4287 switch (size) {
4288 case 0:
4289 gen_aa32_st8(tmp, addr, IS_USER(s));
4290 break;
4291 case 1:
4292 gen_aa32_st16(tmp, addr, IS_USER(s));
4293 break;
4294 case 2:
4295 gen_aa32_st32(tmp, addr, IS_USER(s));
4296 break;
4298 tcg_temp_free_i32(tmp);
4300 rd += stride;
4301 tcg_gen_addi_i32(addr, addr, 1 << size);
4303 tcg_temp_free_i32(addr);
4304 stride = nregs * (1 << size);
4307 if (rm != 15) {
4308 TCGv_i32 base;
4310 base = load_reg(s, rn);
4311 if (rm == 13) {
4312 tcg_gen_addi_i32(base, base, stride);
4313 } else {
4314 TCGv_i32 index;
4315 index = load_reg(s, rm);
4316 tcg_gen_add_i32(base, base, index);
4317 tcg_temp_free_i32(index);
4319 store_reg(s, rn, base);
4321 return 0;
4324 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4325 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4327 tcg_gen_and_i32(t, t, c);
4328 tcg_gen_andc_i32(f, f, c);
4329 tcg_gen_or_i32(dest, t, f);
4332 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4334 switch (size) {
4335 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4336 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4337 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4338 default: abort();
4342 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4344 switch (size) {
4345 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4346 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4347 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4348 default: abort();
4352 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4354 switch (size) {
4355 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4356 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4357 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4358 default: abort();
4362 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4364 switch (size) {
4365 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4366 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4367 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4368 default: abort();
4372 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4373 int q, int u)
4375 if (q) {
4376 if (u) {
4377 switch (size) {
4378 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4379 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4380 default: abort();
4382 } else {
4383 switch (size) {
4384 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4385 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4386 default: abort();
4389 } else {
4390 if (u) {
4391 switch (size) {
4392 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4393 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4394 default: abort();
4396 } else {
4397 switch (size) {
4398 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4399 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4400 default: abort();
4406 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4408 if (u) {
4409 switch (size) {
4410 case 0: gen_helper_neon_widen_u8(dest, src); break;
4411 case 1: gen_helper_neon_widen_u16(dest, src); break;
4412 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4413 default: abort();
4415 } else {
4416 switch (size) {
4417 case 0: gen_helper_neon_widen_s8(dest, src); break;
4418 case 1: gen_helper_neon_widen_s16(dest, src); break;
4419 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4420 default: abort();
4423 tcg_temp_free_i32(src);
4426 static inline void gen_neon_addl(int size)
4428 switch (size) {
4429 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4430 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4431 case 2: tcg_gen_add_i64(CPU_V001); break;
4432 default: abort();
4436 static inline void gen_neon_subl(int size)
4438 switch (size) {
4439 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4440 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4441 case 2: tcg_gen_sub_i64(CPU_V001); break;
4442 default: abort();
4446 static inline void gen_neon_negl(TCGv_i64 var, int size)
4448 switch (size) {
4449 case 0: gen_helper_neon_negl_u16(var, var); break;
4450 case 1: gen_helper_neon_negl_u32(var, var); break;
4451 case 2:
4452 tcg_gen_neg_i64(var, var);
4453 break;
4454 default: abort();
4458 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4460 switch (size) {
4461 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4462 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4463 default: abort();
4467 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4468 int size, int u)
4470 TCGv_i64 tmp;
4472 switch ((size << 1) | u) {
4473 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4474 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4475 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4476 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4477 case 4:
4478 tmp = gen_muls_i64_i32(a, b);
4479 tcg_gen_mov_i64(dest, tmp);
4480 tcg_temp_free_i64(tmp);
4481 break;
4482 case 5:
4483 tmp = gen_mulu_i64_i32(a, b);
4484 tcg_gen_mov_i64(dest, tmp);
4485 tcg_temp_free_i64(tmp);
4486 break;
4487 default: abort();
4490 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4491 Don't forget to clean them now. */
4492 if (size < 2) {
4493 tcg_temp_free_i32(a);
4494 tcg_temp_free_i32(b);
4498 static void gen_neon_narrow_op(int op, int u, int size,
4499 TCGv_i32 dest, TCGv_i64 src)
4501 if (op) {
4502 if (u) {
4503 gen_neon_unarrow_sats(size, dest, src);
4504 } else {
4505 gen_neon_narrow(size, dest, src);
4507 } else {
4508 if (u) {
4509 gen_neon_narrow_satu(size, dest, src);
4510 } else {
4511 gen_neon_narrow_sats(size, dest, src);
4516 /* Symbolic constants for op fields for Neon 3-register same-length.
4517 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4518 * table A7-9.
4520 #define NEON_3R_VHADD 0
4521 #define NEON_3R_VQADD 1
4522 #define NEON_3R_VRHADD 2
4523 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4524 #define NEON_3R_VHSUB 4
4525 #define NEON_3R_VQSUB 5
4526 #define NEON_3R_VCGT 6
4527 #define NEON_3R_VCGE 7
4528 #define NEON_3R_VSHL 8
4529 #define NEON_3R_VQSHL 9
4530 #define NEON_3R_VRSHL 10
4531 #define NEON_3R_VQRSHL 11
4532 #define NEON_3R_VMAX 12
4533 #define NEON_3R_VMIN 13
4534 #define NEON_3R_VABD 14
4535 #define NEON_3R_VABA 15
4536 #define NEON_3R_VADD_VSUB 16
4537 #define NEON_3R_VTST_VCEQ 17
4538 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4539 #define NEON_3R_VMUL 19
4540 #define NEON_3R_VPMAX 20
4541 #define NEON_3R_VPMIN 21
4542 #define NEON_3R_VQDMULH_VQRDMULH 22
4543 #define NEON_3R_VPADD 23
4544 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4545 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4546 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4547 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4548 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4549 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4550 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4552 static const uint8_t neon_3r_sizes[] = {
4553 [NEON_3R_VHADD] = 0x7,
4554 [NEON_3R_VQADD] = 0xf,
4555 [NEON_3R_VRHADD] = 0x7,
4556 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4557 [NEON_3R_VHSUB] = 0x7,
4558 [NEON_3R_VQSUB] = 0xf,
4559 [NEON_3R_VCGT] = 0x7,
4560 [NEON_3R_VCGE] = 0x7,
4561 [NEON_3R_VSHL] = 0xf,
4562 [NEON_3R_VQSHL] = 0xf,
4563 [NEON_3R_VRSHL] = 0xf,
4564 [NEON_3R_VQRSHL] = 0xf,
4565 [NEON_3R_VMAX] = 0x7,
4566 [NEON_3R_VMIN] = 0x7,
4567 [NEON_3R_VABD] = 0x7,
4568 [NEON_3R_VABA] = 0x7,
4569 [NEON_3R_VADD_VSUB] = 0xf,
4570 [NEON_3R_VTST_VCEQ] = 0x7,
4571 [NEON_3R_VML] = 0x7,
4572 [NEON_3R_VMUL] = 0x7,
4573 [NEON_3R_VPMAX] = 0x7,
4574 [NEON_3R_VPMIN] = 0x7,
4575 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4576 [NEON_3R_VPADD] = 0x7,
4577 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4578 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4579 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4580 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4581 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4582 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4583 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4586 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4587 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4588 * table A7-13.
4590 #define NEON_2RM_VREV64 0
4591 #define NEON_2RM_VREV32 1
4592 #define NEON_2RM_VREV16 2
4593 #define NEON_2RM_VPADDL 4
4594 #define NEON_2RM_VPADDL_U 5
4595 #define NEON_2RM_AESE 6 /* Includes AESD */
4596 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4597 #define NEON_2RM_VCLS 8
4598 #define NEON_2RM_VCLZ 9
4599 #define NEON_2RM_VCNT 10
4600 #define NEON_2RM_VMVN 11
4601 #define NEON_2RM_VPADAL 12
4602 #define NEON_2RM_VPADAL_U 13
4603 #define NEON_2RM_VQABS 14
4604 #define NEON_2RM_VQNEG 15
4605 #define NEON_2RM_VCGT0 16
4606 #define NEON_2RM_VCGE0 17
4607 #define NEON_2RM_VCEQ0 18
4608 #define NEON_2RM_VCLE0 19
4609 #define NEON_2RM_VCLT0 20
4610 #define NEON_2RM_VABS 22
4611 #define NEON_2RM_VNEG 23
4612 #define NEON_2RM_VCGT0_F 24
4613 #define NEON_2RM_VCGE0_F 25
4614 #define NEON_2RM_VCEQ0_F 26
4615 #define NEON_2RM_VCLE0_F 27
4616 #define NEON_2RM_VCLT0_F 28
4617 #define NEON_2RM_VABS_F 30
4618 #define NEON_2RM_VNEG_F 31
4619 #define NEON_2RM_VSWP 32
4620 #define NEON_2RM_VTRN 33
4621 #define NEON_2RM_VUZP 34
4622 #define NEON_2RM_VZIP 35
4623 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4624 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4625 #define NEON_2RM_VSHLL 38
4626 #define NEON_2RM_VCVT_F16_F32 44
4627 #define NEON_2RM_VCVT_F32_F16 46
4628 #define NEON_2RM_VRECPE 56
4629 #define NEON_2RM_VRSQRTE 57
4630 #define NEON_2RM_VRECPE_F 58
4631 #define NEON_2RM_VRSQRTE_F 59
4632 #define NEON_2RM_VCVT_FS 60
4633 #define NEON_2RM_VCVT_FU 61
4634 #define NEON_2RM_VCVT_SF 62
4635 #define NEON_2RM_VCVT_UF 63
4637 static int neon_2rm_is_float_op(int op)
4639 /* Return true if this neon 2reg-misc op is float-to-float */
4640 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4641 op >= NEON_2RM_VRECPE_F);
4644 /* Each entry in this array has bit n set if the insn allows
4645 * size value n (otherwise it will UNDEF). Since unallocated
4646 * op values will have no bits set they always UNDEF.
4648 static const uint8_t neon_2rm_sizes[] = {
4649 [NEON_2RM_VREV64] = 0x7,
4650 [NEON_2RM_VREV32] = 0x3,
4651 [NEON_2RM_VREV16] = 0x1,
4652 [NEON_2RM_VPADDL] = 0x7,
4653 [NEON_2RM_VPADDL_U] = 0x7,
4654 [NEON_2RM_AESE] = 0x1,
4655 [NEON_2RM_AESMC] = 0x1,
4656 [NEON_2RM_VCLS] = 0x7,
4657 [NEON_2RM_VCLZ] = 0x7,
4658 [NEON_2RM_VCNT] = 0x1,
4659 [NEON_2RM_VMVN] = 0x1,
4660 [NEON_2RM_VPADAL] = 0x7,
4661 [NEON_2RM_VPADAL_U] = 0x7,
4662 [NEON_2RM_VQABS] = 0x7,
4663 [NEON_2RM_VQNEG] = 0x7,
4664 [NEON_2RM_VCGT0] = 0x7,
4665 [NEON_2RM_VCGE0] = 0x7,
4666 [NEON_2RM_VCEQ0] = 0x7,
4667 [NEON_2RM_VCLE0] = 0x7,
4668 [NEON_2RM_VCLT0] = 0x7,
4669 [NEON_2RM_VABS] = 0x7,
4670 [NEON_2RM_VNEG] = 0x7,
4671 [NEON_2RM_VCGT0_F] = 0x4,
4672 [NEON_2RM_VCGE0_F] = 0x4,
4673 [NEON_2RM_VCEQ0_F] = 0x4,
4674 [NEON_2RM_VCLE0_F] = 0x4,
4675 [NEON_2RM_VCLT0_F] = 0x4,
4676 [NEON_2RM_VABS_F] = 0x4,
4677 [NEON_2RM_VNEG_F] = 0x4,
4678 [NEON_2RM_VSWP] = 0x1,
4679 [NEON_2RM_VTRN] = 0x7,
4680 [NEON_2RM_VUZP] = 0x7,
4681 [NEON_2RM_VZIP] = 0x7,
4682 [NEON_2RM_VMOVN] = 0x7,
4683 [NEON_2RM_VQMOVN] = 0x7,
4684 [NEON_2RM_VSHLL] = 0x7,
4685 [NEON_2RM_VCVT_F16_F32] = 0x2,
4686 [NEON_2RM_VCVT_F32_F16] = 0x2,
4687 [NEON_2RM_VRECPE] = 0x4,
4688 [NEON_2RM_VRSQRTE] = 0x4,
4689 [NEON_2RM_VRECPE_F] = 0x4,
4690 [NEON_2RM_VRSQRTE_F] = 0x4,
4691 [NEON_2RM_VCVT_FS] = 0x4,
4692 [NEON_2RM_VCVT_FU] = 0x4,
4693 [NEON_2RM_VCVT_SF] = 0x4,
4694 [NEON_2RM_VCVT_UF] = 0x4,
4697 /* Translate a NEON data processing instruction. Return nonzero if the
4698 instruction is invalid.
4699 We process data in a mixture of 32-bit and 64-bit chunks.
4700 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4702 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4704 int op;
4705 int q;
4706 int rd, rn, rm;
4707 int size;
4708 int shift;
4709 int pass;
4710 int count;
4711 int pairwise;
4712 int u;
4713 uint32_t imm, mask;
4714 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4715 TCGv_i64 tmp64;
4717 if (!s->vfp_enabled)
4718 return 1;
4719 q = (insn & (1 << 6)) != 0;
4720 u = (insn >> 24) & 1;
4721 VFP_DREG_D(rd, insn);
4722 VFP_DREG_N(rn, insn);
4723 VFP_DREG_M(rm, insn);
4724 size = (insn >> 20) & 3;
4725 if ((insn & (1 << 23)) == 0) {
4726 /* Three register same length. */
4727 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4728 /* Catch invalid op and bad size combinations: UNDEF */
4729 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4730 return 1;
4732 /* All insns of this form UNDEF for either this condition or the
4733 * superset of cases "Q==1"; we catch the latter later.
4735 if (q && ((rd | rn | rm) & 1)) {
4736 return 1;
4738 if (size == 3 && op != NEON_3R_LOGIC) {
4739 /* 64-bit element instructions. */
4740 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4741 neon_load_reg64(cpu_V0, rn + pass);
4742 neon_load_reg64(cpu_V1, rm + pass);
4743 switch (op) {
4744 case NEON_3R_VQADD:
4745 if (u) {
4746 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4747 cpu_V0, cpu_V1);
4748 } else {
4749 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4750 cpu_V0, cpu_V1);
4752 break;
4753 case NEON_3R_VQSUB:
4754 if (u) {
4755 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4756 cpu_V0, cpu_V1);
4757 } else {
4758 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4759 cpu_V0, cpu_V1);
4761 break;
4762 case NEON_3R_VSHL:
4763 if (u) {
4764 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4765 } else {
4766 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4768 break;
4769 case NEON_3R_VQSHL:
4770 if (u) {
4771 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4772 cpu_V1, cpu_V0);
4773 } else {
4774 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4775 cpu_V1, cpu_V0);
4777 break;
4778 case NEON_3R_VRSHL:
4779 if (u) {
4780 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4781 } else {
4782 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4784 break;
4785 case NEON_3R_VQRSHL:
4786 if (u) {
4787 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4788 cpu_V1, cpu_V0);
4789 } else {
4790 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4791 cpu_V1, cpu_V0);
4793 break;
4794 case NEON_3R_VADD_VSUB:
4795 if (u) {
4796 tcg_gen_sub_i64(CPU_V001);
4797 } else {
4798 tcg_gen_add_i64(CPU_V001);
4800 break;
4801 default:
4802 abort();
4804 neon_store_reg64(cpu_V0, rd + pass);
4806 return 0;
4808 pairwise = 0;
4809 switch (op) {
4810 case NEON_3R_VSHL:
4811 case NEON_3R_VQSHL:
4812 case NEON_3R_VRSHL:
4813 case NEON_3R_VQRSHL:
4815 int rtmp;
4816 /* Shift instruction operands are reversed. */
4817 rtmp = rn;
4818 rn = rm;
4819 rm = rtmp;
4821 break;
4822 case NEON_3R_VPADD:
4823 if (u) {
4824 return 1;
4826 /* Fall through */
4827 case NEON_3R_VPMAX:
4828 case NEON_3R_VPMIN:
4829 pairwise = 1;
4830 break;
4831 case NEON_3R_FLOAT_ARITH:
4832 pairwise = (u && size < 2); /* if VPADD (float) */
4833 break;
4834 case NEON_3R_FLOAT_MINMAX:
4835 pairwise = u; /* if VPMIN/VPMAX (float) */
4836 break;
4837 case NEON_3R_FLOAT_CMP:
4838 if (!u && size) {
4839 /* no encoding for U=0 C=1x */
4840 return 1;
4842 break;
4843 case NEON_3R_FLOAT_ACMP:
4844 if (!u) {
4845 return 1;
4847 break;
4848 case NEON_3R_FLOAT_MISC:
4849 /* VMAXNM/VMINNM in ARMv8 */
4850 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
4851 return 1;
4853 break;
4854 case NEON_3R_VMUL:
4855 if (u && (size != 0)) {
4856 /* UNDEF on invalid size for polynomial subcase */
4857 return 1;
4859 break;
4860 case NEON_3R_VFM:
4861 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4862 return 1;
4864 break;
4865 default:
4866 break;
4869 if (pairwise && q) {
4870 /* All the pairwise insns UNDEF if Q is set */
4871 return 1;
4874 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4876 if (pairwise) {
4877 /* Pairwise. */
4878 if (pass < 1) {
4879 tmp = neon_load_reg(rn, 0);
4880 tmp2 = neon_load_reg(rn, 1);
4881 } else {
4882 tmp = neon_load_reg(rm, 0);
4883 tmp2 = neon_load_reg(rm, 1);
4885 } else {
4886 /* Elementwise. */
4887 tmp = neon_load_reg(rn, pass);
4888 tmp2 = neon_load_reg(rm, pass);
4890 switch (op) {
4891 case NEON_3R_VHADD:
4892 GEN_NEON_INTEGER_OP(hadd);
4893 break;
4894 case NEON_3R_VQADD:
4895 GEN_NEON_INTEGER_OP_ENV(qadd);
4896 break;
4897 case NEON_3R_VRHADD:
4898 GEN_NEON_INTEGER_OP(rhadd);
4899 break;
4900 case NEON_3R_LOGIC: /* Logic ops. */
4901 switch ((u << 2) | size) {
4902 case 0: /* VAND */
4903 tcg_gen_and_i32(tmp, tmp, tmp2);
4904 break;
4905 case 1: /* BIC */
4906 tcg_gen_andc_i32(tmp, tmp, tmp2);
4907 break;
4908 case 2: /* VORR */
4909 tcg_gen_or_i32(tmp, tmp, tmp2);
4910 break;
4911 case 3: /* VORN */
4912 tcg_gen_orc_i32(tmp, tmp, tmp2);
4913 break;
4914 case 4: /* VEOR */
4915 tcg_gen_xor_i32(tmp, tmp, tmp2);
4916 break;
4917 case 5: /* VBSL */
4918 tmp3 = neon_load_reg(rd, pass);
4919 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4920 tcg_temp_free_i32(tmp3);
4921 break;
4922 case 6: /* VBIT */
4923 tmp3 = neon_load_reg(rd, pass);
4924 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4925 tcg_temp_free_i32(tmp3);
4926 break;
4927 case 7: /* VBIF */
4928 tmp3 = neon_load_reg(rd, pass);
4929 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4930 tcg_temp_free_i32(tmp3);
4931 break;
4933 break;
4934 case NEON_3R_VHSUB:
4935 GEN_NEON_INTEGER_OP(hsub);
4936 break;
4937 case NEON_3R_VQSUB:
4938 GEN_NEON_INTEGER_OP_ENV(qsub);
4939 break;
4940 case NEON_3R_VCGT:
4941 GEN_NEON_INTEGER_OP(cgt);
4942 break;
4943 case NEON_3R_VCGE:
4944 GEN_NEON_INTEGER_OP(cge);
4945 break;
4946 case NEON_3R_VSHL:
4947 GEN_NEON_INTEGER_OP(shl);
4948 break;
4949 case NEON_3R_VQSHL:
4950 GEN_NEON_INTEGER_OP_ENV(qshl);
4951 break;
4952 case NEON_3R_VRSHL:
4953 GEN_NEON_INTEGER_OP(rshl);
4954 break;
4955 case NEON_3R_VQRSHL:
4956 GEN_NEON_INTEGER_OP_ENV(qrshl);
4957 break;
4958 case NEON_3R_VMAX:
4959 GEN_NEON_INTEGER_OP(max);
4960 break;
4961 case NEON_3R_VMIN:
4962 GEN_NEON_INTEGER_OP(min);
4963 break;
4964 case NEON_3R_VABD:
4965 GEN_NEON_INTEGER_OP(abd);
4966 break;
4967 case NEON_3R_VABA:
4968 GEN_NEON_INTEGER_OP(abd);
4969 tcg_temp_free_i32(tmp2);
4970 tmp2 = neon_load_reg(rd, pass);
4971 gen_neon_add(size, tmp, tmp2);
4972 break;
4973 case NEON_3R_VADD_VSUB:
4974 if (!u) { /* VADD */
4975 gen_neon_add(size, tmp, tmp2);
4976 } else { /* VSUB */
4977 switch (size) {
4978 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4979 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4980 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4981 default: abort();
4984 break;
4985 case NEON_3R_VTST_VCEQ:
4986 if (!u) { /* VTST */
4987 switch (size) {
4988 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4989 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4990 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4991 default: abort();
4993 } else { /* VCEQ */
4994 switch (size) {
4995 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4996 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4997 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4998 default: abort();
5001 break;
5002 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5003 switch (size) {
5004 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5005 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5006 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5007 default: abort();
5009 tcg_temp_free_i32(tmp2);
5010 tmp2 = neon_load_reg(rd, pass);
5011 if (u) { /* VMLS */
5012 gen_neon_rsb(size, tmp, tmp2);
5013 } else { /* VMLA */
5014 gen_neon_add(size, tmp, tmp2);
5016 break;
5017 case NEON_3R_VMUL:
5018 if (u) { /* polynomial */
5019 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5020 } else { /* Integer */
5021 switch (size) {
5022 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5023 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5024 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5025 default: abort();
5028 break;
5029 case NEON_3R_VPMAX:
5030 GEN_NEON_INTEGER_OP(pmax);
5031 break;
5032 case NEON_3R_VPMIN:
5033 GEN_NEON_INTEGER_OP(pmin);
5034 break;
5035 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5036 if (!u) { /* VQDMULH */
5037 switch (size) {
5038 case 1:
5039 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5040 break;
5041 case 2:
5042 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5043 break;
5044 default: abort();
5046 } else { /* VQRDMULH */
5047 switch (size) {
5048 case 1:
5049 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5050 break;
5051 case 2:
5052 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5053 break;
5054 default: abort();
5057 break;
5058 case NEON_3R_VPADD:
5059 switch (size) {
5060 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5061 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5062 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5063 default: abort();
5065 break;
5066 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5068 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5069 switch ((u << 2) | size) {
5070 case 0: /* VADD */
5071 case 4: /* VPADD */
5072 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5073 break;
5074 case 2: /* VSUB */
5075 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5076 break;
5077 case 6: /* VABD */
5078 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5079 break;
5080 default:
5081 abort();
5083 tcg_temp_free_ptr(fpstatus);
5084 break;
5086 case NEON_3R_FLOAT_MULTIPLY:
5088 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5089 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5090 if (!u) {
5091 tcg_temp_free_i32(tmp2);
5092 tmp2 = neon_load_reg(rd, pass);
5093 if (size == 0) {
5094 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5095 } else {
5096 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5099 tcg_temp_free_ptr(fpstatus);
5100 break;
5102 case NEON_3R_FLOAT_CMP:
5104 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5105 if (!u) {
5106 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5107 } else {
5108 if (size == 0) {
5109 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5110 } else {
5111 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5114 tcg_temp_free_ptr(fpstatus);
5115 break;
5117 case NEON_3R_FLOAT_ACMP:
5119 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5120 if (size == 0) {
5121 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5122 } else {
5123 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5125 tcg_temp_free_ptr(fpstatus);
5126 break;
5128 case NEON_3R_FLOAT_MINMAX:
5130 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5131 if (size == 0) {
5132 gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
5133 } else {
5134 gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
5136 tcg_temp_free_ptr(fpstatus);
5137 break;
5139 case NEON_3R_FLOAT_MISC:
5140 if (u) {
5141 /* VMAXNM/VMINNM */
5142 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5143 if (size == 0) {
5144 gen_helper_vfp_maxnms(tmp, tmp, tmp2, fpstatus);
5145 } else {
5146 gen_helper_vfp_minnms(tmp, tmp, tmp2, fpstatus);
5148 tcg_temp_free_ptr(fpstatus);
5149 } else {
5150 if (size == 0) {
5151 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5152 } else {
5153 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5156 break;
5157 case NEON_3R_VFM:
5159 /* VFMA, VFMS: fused multiply-add */
5160 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5161 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5162 if (size) {
5163 /* VFMS */
5164 gen_helper_vfp_negs(tmp, tmp);
5166 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5167 tcg_temp_free_i32(tmp3);
5168 tcg_temp_free_ptr(fpstatus);
5169 break;
5171 default:
5172 abort();
5174 tcg_temp_free_i32(tmp2);
5176 /* Save the result. For elementwise operations we can put it
5177 straight into the destination register. For pairwise operations
5178 we have to be careful to avoid clobbering the source operands. */
5179 if (pairwise && rd == rm) {
5180 neon_store_scratch(pass, tmp);
5181 } else {
5182 neon_store_reg(rd, pass, tmp);
5185 } /* for pass */
5186 if (pairwise && rd == rm) {
5187 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5188 tmp = neon_load_scratch(pass);
5189 neon_store_reg(rd, pass, tmp);
5192 /* End of 3 register same size operations. */
5193 } else if (insn & (1 << 4)) {
5194 if ((insn & 0x00380080) != 0) {
5195 /* Two registers and shift. */
5196 op = (insn >> 8) & 0xf;
5197 if (insn & (1 << 7)) {
5198 /* 64-bit shift. */
5199 if (op > 7) {
5200 return 1;
5202 size = 3;
5203 } else {
5204 size = 2;
5205 while ((insn & (1 << (size + 19))) == 0)
5206 size--;
5208 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5209 /* To avoid excessive duplication of ops we implement shift
5210 by immediate using the variable shift operations. */
5211 if (op < 8) {
5212 /* Shift by immediate:
5213 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5214 if (q && ((rd | rm) & 1)) {
5215 return 1;
5217 if (!u && (op == 4 || op == 6)) {
5218 return 1;
5220 /* Right shifts are encoded as N - shift, where N is the
5221 element size in bits. */
5222 if (op <= 4)
5223 shift = shift - (1 << (size + 3));
5224 if (size == 3) {
5225 count = q + 1;
5226 } else {
5227 count = q ? 4: 2;
5229 switch (size) {
5230 case 0:
5231 imm = (uint8_t) shift;
5232 imm |= imm << 8;
5233 imm |= imm << 16;
5234 break;
5235 case 1:
5236 imm = (uint16_t) shift;
5237 imm |= imm << 16;
5238 break;
5239 case 2:
5240 case 3:
5241 imm = shift;
5242 break;
5243 default:
5244 abort();
5247 for (pass = 0; pass < count; pass++) {
5248 if (size == 3) {
5249 neon_load_reg64(cpu_V0, rm + pass);
5250 tcg_gen_movi_i64(cpu_V1, imm);
5251 switch (op) {
5252 case 0: /* VSHR */
5253 case 1: /* VSRA */
5254 if (u)
5255 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5256 else
5257 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5258 break;
5259 case 2: /* VRSHR */
5260 case 3: /* VRSRA */
5261 if (u)
5262 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5263 else
5264 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5265 break;
5266 case 4: /* VSRI */
5267 case 5: /* VSHL, VSLI */
5268 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5269 break;
5270 case 6: /* VQSHLU */
5271 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5272 cpu_V0, cpu_V1);
5273 break;
5274 case 7: /* VQSHL */
5275 if (u) {
5276 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5277 cpu_V0, cpu_V1);
5278 } else {
5279 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5280 cpu_V0, cpu_V1);
5282 break;
5284 if (op == 1 || op == 3) {
5285 /* Accumulate. */
5286 neon_load_reg64(cpu_V1, rd + pass);
5287 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5288 } else if (op == 4 || (op == 5 && u)) {
5289 /* Insert */
5290 neon_load_reg64(cpu_V1, rd + pass);
5291 uint64_t mask;
5292 if (shift < -63 || shift > 63) {
5293 mask = 0;
5294 } else {
5295 if (op == 4) {
5296 mask = 0xffffffffffffffffull >> -shift;
5297 } else {
5298 mask = 0xffffffffffffffffull << shift;
5301 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5302 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5304 neon_store_reg64(cpu_V0, rd + pass);
5305 } else { /* size < 3 */
5306 /* Operands in T0 and T1. */
5307 tmp = neon_load_reg(rm, pass);
5308 tmp2 = tcg_temp_new_i32();
5309 tcg_gen_movi_i32(tmp2, imm);
5310 switch (op) {
5311 case 0: /* VSHR */
5312 case 1: /* VSRA */
5313 GEN_NEON_INTEGER_OP(shl);
5314 break;
5315 case 2: /* VRSHR */
5316 case 3: /* VRSRA */
5317 GEN_NEON_INTEGER_OP(rshl);
5318 break;
5319 case 4: /* VSRI */
5320 case 5: /* VSHL, VSLI */
5321 switch (size) {
5322 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5323 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5324 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5325 default: abort();
5327 break;
5328 case 6: /* VQSHLU */
5329 switch (size) {
5330 case 0:
5331 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5332 tmp, tmp2);
5333 break;
5334 case 1:
5335 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5336 tmp, tmp2);
5337 break;
5338 case 2:
5339 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5340 tmp, tmp2);
5341 break;
5342 default:
5343 abort();
5345 break;
5346 case 7: /* VQSHL */
5347 GEN_NEON_INTEGER_OP_ENV(qshl);
5348 break;
5350 tcg_temp_free_i32(tmp2);
5352 if (op == 1 || op == 3) {
5353 /* Accumulate. */
5354 tmp2 = neon_load_reg(rd, pass);
5355 gen_neon_add(size, tmp, tmp2);
5356 tcg_temp_free_i32(tmp2);
5357 } else if (op == 4 || (op == 5 && u)) {
5358 /* Insert */
5359 switch (size) {
5360 case 0:
5361 if (op == 4)
5362 mask = 0xff >> -shift;
5363 else
5364 mask = (uint8_t)(0xff << shift);
5365 mask |= mask << 8;
5366 mask |= mask << 16;
5367 break;
5368 case 1:
5369 if (op == 4)
5370 mask = 0xffff >> -shift;
5371 else
5372 mask = (uint16_t)(0xffff << shift);
5373 mask |= mask << 16;
5374 break;
5375 case 2:
5376 if (shift < -31 || shift > 31) {
5377 mask = 0;
5378 } else {
5379 if (op == 4)
5380 mask = 0xffffffffu >> -shift;
5381 else
5382 mask = 0xffffffffu << shift;
5384 break;
5385 default:
5386 abort();
5388 tmp2 = neon_load_reg(rd, pass);
5389 tcg_gen_andi_i32(tmp, tmp, mask);
5390 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5391 tcg_gen_or_i32(tmp, tmp, tmp2);
5392 tcg_temp_free_i32(tmp2);
5394 neon_store_reg(rd, pass, tmp);
5396 } /* for pass */
5397 } else if (op < 10) {
5398 /* Shift by immediate and narrow:
5399 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5400 int input_unsigned = (op == 8) ? !u : u;
5401 if (rm & 1) {
5402 return 1;
5404 shift = shift - (1 << (size + 3));
5405 size++;
5406 if (size == 3) {
5407 tmp64 = tcg_const_i64(shift);
5408 neon_load_reg64(cpu_V0, rm);
5409 neon_load_reg64(cpu_V1, rm + 1);
5410 for (pass = 0; pass < 2; pass++) {
5411 TCGv_i64 in;
5412 if (pass == 0) {
5413 in = cpu_V0;
5414 } else {
5415 in = cpu_V1;
5417 if (q) {
5418 if (input_unsigned) {
5419 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5420 } else {
5421 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5423 } else {
5424 if (input_unsigned) {
5425 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5426 } else {
5427 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5430 tmp = tcg_temp_new_i32();
5431 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5432 neon_store_reg(rd, pass, tmp);
5433 } /* for pass */
5434 tcg_temp_free_i64(tmp64);
5435 } else {
5436 if (size == 1) {
5437 imm = (uint16_t)shift;
5438 imm |= imm << 16;
5439 } else {
5440 /* size == 2 */
5441 imm = (uint32_t)shift;
5443 tmp2 = tcg_const_i32(imm);
5444 tmp4 = neon_load_reg(rm + 1, 0);
5445 tmp5 = neon_load_reg(rm + 1, 1);
5446 for (pass = 0; pass < 2; pass++) {
5447 if (pass == 0) {
5448 tmp = neon_load_reg(rm, 0);
5449 } else {
5450 tmp = tmp4;
5452 gen_neon_shift_narrow(size, tmp, tmp2, q,
5453 input_unsigned);
5454 if (pass == 0) {
5455 tmp3 = neon_load_reg(rm, 1);
5456 } else {
5457 tmp3 = tmp5;
5459 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5460 input_unsigned);
5461 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5462 tcg_temp_free_i32(tmp);
5463 tcg_temp_free_i32(tmp3);
5464 tmp = tcg_temp_new_i32();
5465 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5466 neon_store_reg(rd, pass, tmp);
5467 } /* for pass */
5468 tcg_temp_free_i32(tmp2);
5470 } else if (op == 10) {
5471 /* VSHLL, VMOVL */
5472 if (q || (rd & 1)) {
5473 return 1;
5475 tmp = neon_load_reg(rm, 0);
5476 tmp2 = neon_load_reg(rm, 1);
5477 for (pass = 0; pass < 2; pass++) {
5478 if (pass == 1)
5479 tmp = tmp2;
5481 gen_neon_widen(cpu_V0, tmp, size, u);
5483 if (shift != 0) {
5484 /* The shift is less than the width of the source
5485 type, so we can just shift the whole register. */
5486 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5487 /* Widen the result of shift: we need to clear
5488 * the potential overflow bits resulting from
5489 * left bits of the narrow input appearing as
5490 * right bits of left the neighbour narrow
5491 * input. */
5492 if (size < 2 || !u) {
5493 uint64_t imm64;
5494 if (size == 0) {
5495 imm = (0xffu >> (8 - shift));
5496 imm |= imm << 16;
5497 } else if (size == 1) {
5498 imm = 0xffff >> (16 - shift);
5499 } else {
5500 /* size == 2 */
5501 imm = 0xffffffff >> (32 - shift);
5503 if (size < 2) {
5504 imm64 = imm | (((uint64_t)imm) << 32);
5505 } else {
5506 imm64 = imm;
5508 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5511 neon_store_reg64(cpu_V0, rd + pass);
5513 } else if (op >= 14) {
5514 /* VCVT fixed-point. */
5515 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5516 return 1;
5518 /* We have already masked out the must-be-1 top bit of imm6,
5519 * hence this 32-shift where the ARM ARM has 64-imm6.
5521 shift = 32 - shift;
5522 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5523 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5524 if (!(op & 1)) {
5525 if (u)
5526 gen_vfp_ulto(0, shift, 1);
5527 else
5528 gen_vfp_slto(0, shift, 1);
5529 } else {
5530 if (u)
5531 gen_vfp_toul(0, shift, 1);
5532 else
5533 gen_vfp_tosl(0, shift, 1);
5535 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5537 } else {
5538 return 1;
5540 } else { /* (insn & 0x00380080) == 0 */
5541 int invert;
5542 if (q && (rd & 1)) {
5543 return 1;
5546 op = (insn >> 8) & 0xf;
5547 /* One register and immediate. */
5548 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5549 invert = (insn & (1 << 5)) != 0;
5550 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5551 * We choose to not special-case this and will behave as if a
5552 * valid constant encoding of 0 had been given.
5554 switch (op) {
5555 case 0: case 1:
5556 /* no-op */
5557 break;
5558 case 2: case 3:
5559 imm <<= 8;
5560 break;
5561 case 4: case 5:
5562 imm <<= 16;
5563 break;
5564 case 6: case 7:
5565 imm <<= 24;
5566 break;
5567 case 8: case 9:
5568 imm |= imm << 16;
5569 break;
5570 case 10: case 11:
5571 imm = (imm << 8) | (imm << 24);
5572 break;
5573 case 12:
5574 imm = (imm << 8) | 0xff;
5575 break;
5576 case 13:
5577 imm = (imm << 16) | 0xffff;
5578 break;
5579 case 14:
5580 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5581 if (invert)
5582 imm = ~imm;
5583 break;
5584 case 15:
5585 if (invert) {
5586 return 1;
5588 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5589 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5590 break;
5592 if (invert)
5593 imm = ~imm;
5595 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5596 if (op & 1 && op < 12) {
5597 tmp = neon_load_reg(rd, pass);
5598 if (invert) {
5599 /* The immediate value has already been inverted, so
5600 BIC becomes AND. */
5601 tcg_gen_andi_i32(tmp, tmp, imm);
5602 } else {
5603 tcg_gen_ori_i32(tmp, tmp, imm);
5605 } else {
5606 /* VMOV, VMVN. */
5607 tmp = tcg_temp_new_i32();
5608 if (op == 14 && invert) {
5609 int n;
5610 uint32_t val;
5611 val = 0;
5612 for (n = 0; n < 4; n++) {
5613 if (imm & (1 << (n + (pass & 1) * 4)))
5614 val |= 0xff << (n * 8);
5616 tcg_gen_movi_i32(tmp, val);
5617 } else {
5618 tcg_gen_movi_i32(tmp, imm);
5621 neon_store_reg(rd, pass, tmp);
5624 } else { /* (insn & 0x00800010 == 0x00800000) */
5625 if (size != 3) {
5626 op = (insn >> 8) & 0xf;
5627 if ((insn & (1 << 6)) == 0) {
5628 /* Three registers of different lengths. */
5629 int src1_wide;
5630 int src2_wide;
5631 int prewiden;
5632 /* undefreq: bit 0 : UNDEF if size != 0
5633 * bit 1 : UNDEF if size == 0
5634 * bit 2 : UNDEF if U == 1
5635 * Note that [1:0] set implies 'always UNDEF'
5637 int undefreq;
5638 /* prewiden, src1_wide, src2_wide, undefreq */
5639 static const int neon_3reg_wide[16][4] = {
5640 {1, 0, 0, 0}, /* VADDL */
5641 {1, 1, 0, 0}, /* VADDW */
5642 {1, 0, 0, 0}, /* VSUBL */
5643 {1, 1, 0, 0}, /* VSUBW */
5644 {0, 1, 1, 0}, /* VADDHN */
5645 {0, 0, 0, 0}, /* VABAL */
5646 {0, 1, 1, 0}, /* VSUBHN */
5647 {0, 0, 0, 0}, /* VABDL */
5648 {0, 0, 0, 0}, /* VMLAL */
5649 {0, 0, 0, 6}, /* VQDMLAL */
5650 {0, 0, 0, 0}, /* VMLSL */
5651 {0, 0, 0, 6}, /* VQDMLSL */
5652 {0, 0, 0, 0}, /* Integer VMULL */
5653 {0, 0, 0, 2}, /* VQDMULL */
5654 {0, 0, 0, 5}, /* Polynomial VMULL */
5655 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5658 prewiden = neon_3reg_wide[op][0];
5659 src1_wide = neon_3reg_wide[op][1];
5660 src2_wide = neon_3reg_wide[op][2];
5661 undefreq = neon_3reg_wide[op][3];
5663 if (((undefreq & 1) && (size != 0)) ||
5664 ((undefreq & 2) && (size == 0)) ||
5665 ((undefreq & 4) && u)) {
5666 return 1;
5668 if ((src1_wide && (rn & 1)) ||
5669 (src2_wide && (rm & 1)) ||
5670 (!src2_wide && (rd & 1))) {
5671 return 1;
5674 /* Avoid overlapping operands. Wide source operands are
5675 always aligned so will never overlap with wide
5676 destinations in problematic ways. */
5677 if (rd == rm && !src2_wide) {
5678 tmp = neon_load_reg(rm, 1);
5679 neon_store_scratch(2, tmp);
5680 } else if (rd == rn && !src1_wide) {
5681 tmp = neon_load_reg(rn, 1);
5682 neon_store_scratch(2, tmp);
5684 TCGV_UNUSED_I32(tmp3);
5685 for (pass = 0; pass < 2; pass++) {
5686 if (src1_wide) {
5687 neon_load_reg64(cpu_V0, rn + pass);
5688 TCGV_UNUSED_I32(tmp);
5689 } else {
5690 if (pass == 1 && rd == rn) {
5691 tmp = neon_load_scratch(2);
5692 } else {
5693 tmp = neon_load_reg(rn, pass);
5695 if (prewiden) {
5696 gen_neon_widen(cpu_V0, tmp, size, u);
5699 if (src2_wide) {
5700 neon_load_reg64(cpu_V1, rm + pass);
5701 TCGV_UNUSED_I32(tmp2);
5702 } else {
5703 if (pass == 1 && rd == rm) {
5704 tmp2 = neon_load_scratch(2);
5705 } else {
5706 tmp2 = neon_load_reg(rm, pass);
5708 if (prewiden) {
5709 gen_neon_widen(cpu_V1, tmp2, size, u);
5712 switch (op) {
5713 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5714 gen_neon_addl(size);
5715 break;
5716 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5717 gen_neon_subl(size);
5718 break;
5719 case 5: case 7: /* VABAL, VABDL */
5720 switch ((size << 1) | u) {
5721 case 0:
5722 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5723 break;
5724 case 1:
5725 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5726 break;
5727 case 2:
5728 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5729 break;
5730 case 3:
5731 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5732 break;
5733 case 4:
5734 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5735 break;
5736 case 5:
5737 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5738 break;
5739 default: abort();
5741 tcg_temp_free_i32(tmp2);
5742 tcg_temp_free_i32(tmp);
5743 break;
5744 case 8: case 9: case 10: case 11: case 12: case 13:
5745 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5746 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5747 break;
5748 case 14: /* Polynomial VMULL */
5749 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5750 tcg_temp_free_i32(tmp2);
5751 tcg_temp_free_i32(tmp);
5752 break;
5753 default: /* 15 is RESERVED: caught earlier */
5754 abort();
5756 if (op == 13) {
5757 /* VQDMULL */
5758 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5759 neon_store_reg64(cpu_V0, rd + pass);
5760 } else if (op == 5 || (op >= 8 && op <= 11)) {
5761 /* Accumulate. */
5762 neon_load_reg64(cpu_V1, rd + pass);
5763 switch (op) {
5764 case 10: /* VMLSL */
5765 gen_neon_negl(cpu_V0, size);
5766 /* Fall through */
5767 case 5: case 8: /* VABAL, VMLAL */
5768 gen_neon_addl(size);
5769 break;
5770 case 9: case 11: /* VQDMLAL, VQDMLSL */
5771 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5772 if (op == 11) {
5773 gen_neon_negl(cpu_V0, size);
5775 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5776 break;
5777 default:
5778 abort();
5780 neon_store_reg64(cpu_V0, rd + pass);
5781 } else if (op == 4 || op == 6) {
5782 /* Narrowing operation. */
5783 tmp = tcg_temp_new_i32();
5784 if (!u) {
5785 switch (size) {
5786 case 0:
5787 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5788 break;
5789 case 1:
5790 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5791 break;
5792 case 2:
5793 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5794 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5795 break;
5796 default: abort();
5798 } else {
5799 switch (size) {
5800 case 0:
5801 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5802 break;
5803 case 1:
5804 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5805 break;
5806 case 2:
5807 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5808 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5809 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5810 break;
5811 default: abort();
5814 if (pass == 0) {
5815 tmp3 = tmp;
5816 } else {
5817 neon_store_reg(rd, 0, tmp3);
5818 neon_store_reg(rd, 1, tmp);
5820 } else {
5821 /* Write back the result. */
5822 neon_store_reg64(cpu_V0, rd + pass);
5825 } else {
5826 /* Two registers and a scalar. NB that for ops of this form
5827 * the ARM ARM labels bit 24 as Q, but it is in our variable
5828 * 'u', not 'q'.
5830 if (size == 0) {
5831 return 1;
5833 switch (op) {
5834 case 1: /* Float VMLA scalar */
5835 case 5: /* Floating point VMLS scalar */
5836 case 9: /* Floating point VMUL scalar */
5837 if (size == 1) {
5838 return 1;
5840 /* fall through */
5841 case 0: /* Integer VMLA scalar */
5842 case 4: /* Integer VMLS scalar */
5843 case 8: /* Integer VMUL scalar */
5844 case 12: /* VQDMULH scalar */
5845 case 13: /* VQRDMULH scalar */
5846 if (u && ((rd | rn) & 1)) {
5847 return 1;
5849 tmp = neon_get_scalar(size, rm);
5850 neon_store_scratch(0, tmp);
5851 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5852 tmp = neon_load_scratch(0);
5853 tmp2 = neon_load_reg(rn, pass);
5854 if (op == 12) {
5855 if (size == 1) {
5856 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5857 } else {
5858 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5860 } else if (op == 13) {
5861 if (size == 1) {
5862 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5863 } else {
5864 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5866 } else if (op & 1) {
5867 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5868 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5869 tcg_temp_free_ptr(fpstatus);
5870 } else {
5871 switch (size) {
5872 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5873 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5874 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5875 default: abort();
5878 tcg_temp_free_i32(tmp2);
5879 if (op < 8) {
5880 /* Accumulate. */
5881 tmp2 = neon_load_reg(rd, pass);
5882 switch (op) {
5883 case 0:
5884 gen_neon_add(size, tmp, tmp2);
5885 break;
5886 case 1:
5888 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5889 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5890 tcg_temp_free_ptr(fpstatus);
5891 break;
5893 case 4:
5894 gen_neon_rsb(size, tmp, tmp2);
5895 break;
5896 case 5:
5898 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5899 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5900 tcg_temp_free_ptr(fpstatus);
5901 break;
5903 default:
5904 abort();
5906 tcg_temp_free_i32(tmp2);
5908 neon_store_reg(rd, pass, tmp);
5910 break;
5911 case 3: /* VQDMLAL scalar */
5912 case 7: /* VQDMLSL scalar */
5913 case 11: /* VQDMULL scalar */
5914 if (u == 1) {
5915 return 1;
5917 /* fall through */
5918 case 2: /* VMLAL sclar */
5919 case 6: /* VMLSL scalar */
5920 case 10: /* VMULL scalar */
5921 if (rd & 1) {
5922 return 1;
5924 tmp2 = neon_get_scalar(size, rm);
5925 /* We need a copy of tmp2 because gen_neon_mull
5926 * deletes it during pass 0. */
5927 tmp4 = tcg_temp_new_i32();
5928 tcg_gen_mov_i32(tmp4, tmp2);
5929 tmp3 = neon_load_reg(rn, 1);
5931 for (pass = 0; pass < 2; pass++) {
5932 if (pass == 0) {
5933 tmp = neon_load_reg(rn, 0);
5934 } else {
5935 tmp = tmp3;
5936 tmp2 = tmp4;
5938 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5939 if (op != 11) {
5940 neon_load_reg64(cpu_V1, rd + pass);
5942 switch (op) {
5943 case 6:
5944 gen_neon_negl(cpu_V0, size);
5945 /* Fall through */
5946 case 2:
5947 gen_neon_addl(size);
5948 break;
5949 case 3: case 7:
5950 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5951 if (op == 7) {
5952 gen_neon_negl(cpu_V0, size);
5954 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5955 break;
5956 case 10:
5957 /* no-op */
5958 break;
5959 case 11:
5960 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5961 break;
5962 default:
5963 abort();
5965 neon_store_reg64(cpu_V0, rd + pass);
5969 break;
5970 default: /* 14 and 15 are RESERVED */
5971 return 1;
5974 } else { /* size == 3 */
5975 if (!u) {
5976 /* Extract. */
5977 imm = (insn >> 8) & 0xf;
5979 if (imm > 7 && !q)
5980 return 1;
5982 if (q && ((rd | rn | rm) & 1)) {
5983 return 1;
5986 if (imm == 0) {
5987 neon_load_reg64(cpu_V0, rn);
5988 if (q) {
5989 neon_load_reg64(cpu_V1, rn + 1);
5991 } else if (imm == 8) {
5992 neon_load_reg64(cpu_V0, rn + 1);
5993 if (q) {
5994 neon_load_reg64(cpu_V1, rm);
5996 } else if (q) {
5997 tmp64 = tcg_temp_new_i64();
5998 if (imm < 8) {
5999 neon_load_reg64(cpu_V0, rn);
6000 neon_load_reg64(tmp64, rn + 1);
6001 } else {
6002 neon_load_reg64(cpu_V0, rn + 1);
6003 neon_load_reg64(tmp64, rm);
6005 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6006 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6007 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6008 if (imm < 8) {
6009 neon_load_reg64(cpu_V1, rm);
6010 } else {
6011 neon_load_reg64(cpu_V1, rm + 1);
6012 imm -= 8;
6014 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6015 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6016 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6017 tcg_temp_free_i64(tmp64);
6018 } else {
6019 /* BUGFIX */
6020 neon_load_reg64(cpu_V0, rn);
6021 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6022 neon_load_reg64(cpu_V1, rm);
6023 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6024 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6026 neon_store_reg64(cpu_V0, rd);
6027 if (q) {
6028 neon_store_reg64(cpu_V1, rd + 1);
6030 } else if ((insn & (1 << 11)) == 0) {
6031 /* Two register misc. */
6032 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6033 size = (insn >> 18) & 3;
6034 /* UNDEF for unknown op values and bad op-size combinations */
6035 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6036 return 1;
6038 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6039 q && ((rm | rd) & 1)) {
6040 return 1;
6042 switch (op) {
6043 case NEON_2RM_VREV64:
6044 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6045 tmp = neon_load_reg(rm, pass * 2);
6046 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6047 switch (size) {
6048 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6049 case 1: gen_swap_half(tmp); break;
6050 case 2: /* no-op */ break;
6051 default: abort();
6053 neon_store_reg(rd, pass * 2 + 1, tmp);
6054 if (size == 2) {
6055 neon_store_reg(rd, pass * 2, tmp2);
6056 } else {
6057 switch (size) {
6058 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6059 case 1: gen_swap_half(tmp2); break;
6060 default: abort();
6062 neon_store_reg(rd, pass * 2, tmp2);
6065 break;
6066 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6067 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6068 for (pass = 0; pass < q + 1; pass++) {
6069 tmp = neon_load_reg(rm, pass * 2);
6070 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6071 tmp = neon_load_reg(rm, pass * 2 + 1);
6072 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6073 switch (size) {
6074 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6075 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6076 case 2: tcg_gen_add_i64(CPU_V001); break;
6077 default: abort();
6079 if (op >= NEON_2RM_VPADAL) {
6080 /* Accumulate. */
6081 neon_load_reg64(cpu_V1, rd + pass);
6082 gen_neon_addl(size);
6084 neon_store_reg64(cpu_V0, rd + pass);
6086 break;
6087 case NEON_2RM_VTRN:
6088 if (size == 2) {
6089 int n;
6090 for (n = 0; n < (q ? 4 : 2); n += 2) {
6091 tmp = neon_load_reg(rm, n);
6092 tmp2 = neon_load_reg(rd, n + 1);
6093 neon_store_reg(rm, n, tmp2);
6094 neon_store_reg(rd, n + 1, tmp);
6096 } else {
6097 goto elementwise;
6099 break;
6100 case NEON_2RM_VUZP:
6101 if (gen_neon_unzip(rd, rm, size, q)) {
6102 return 1;
6104 break;
6105 case NEON_2RM_VZIP:
6106 if (gen_neon_zip(rd, rm, size, q)) {
6107 return 1;
6109 break;
6110 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6111 /* also VQMOVUN; op field and mnemonics don't line up */
6112 if (rm & 1) {
6113 return 1;
6115 TCGV_UNUSED_I32(tmp2);
6116 for (pass = 0; pass < 2; pass++) {
6117 neon_load_reg64(cpu_V0, rm + pass);
6118 tmp = tcg_temp_new_i32();
6119 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6120 tmp, cpu_V0);
6121 if (pass == 0) {
6122 tmp2 = tmp;
6123 } else {
6124 neon_store_reg(rd, 0, tmp2);
6125 neon_store_reg(rd, 1, tmp);
6128 break;
6129 case NEON_2RM_VSHLL:
6130 if (q || (rd & 1)) {
6131 return 1;
6133 tmp = neon_load_reg(rm, 0);
6134 tmp2 = neon_load_reg(rm, 1);
6135 for (pass = 0; pass < 2; pass++) {
6136 if (pass == 1)
6137 tmp = tmp2;
6138 gen_neon_widen(cpu_V0, tmp, size, 1);
6139 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6140 neon_store_reg64(cpu_V0, rd + pass);
6142 break;
6143 case NEON_2RM_VCVT_F16_F32:
6144 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6145 q || (rm & 1)) {
6146 return 1;
6148 tmp = tcg_temp_new_i32();
6149 tmp2 = tcg_temp_new_i32();
6150 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6151 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6152 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6153 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6154 tcg_gen_shli_i32(tmp2, tmp2, 16);
6155 tcg_gen_or_i32(tmp2, tmp2, tmp);
6156 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6157 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6158 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6159 neon_store_reg(rd, 0, tmp2);
6160 tmp2 = tcg_temp_new_i32();
6161 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6162 tcg_gen_shli_i32(tmp2, tmp2, 16);
6163 tcg_gen_or_i32(tmp2, tmp2, tmp);
6164 neon_store_reg(rd, 1, tmp2);
6165 tcg_temp_free_i32(tmp);
6166 break;
6167 case NEON_2RM_VCVT_F32_F16:
6168 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6169 q || (rd & 1)) {
6170 return 1;
6172 tmp3 = tcg_temp_new_i32();
6173 tmp = neon_load_reg(rm, 0);
6174 tmp2 = neon_load_reg(rm, 1);
6175 tcg_gen_ext16u_i32(tmp3, tmp);
6176 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6177 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6178 tcg_gen_shri_i32(tmp3, tmp, 16);
6179 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6180 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6181 tcg_temp_free_i32(tmp);
6182 tcg_gen_ext16u_i32(tmp3, tmp2);
6183 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6184 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6185 tcg_gen_shri_i32(tmp3, tmp2, 16);
6186 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6187 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6188 tcg_temp_free_i32(tmp2);
6189 tcg_temp_free_i32(tmp3);
6190 break;
6191 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6192 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6193 || ((rm | rd) & 1)) {
6194 return 1;
6196 tmp = tcg_const_i32(rd);
6197 tmp2 = tcg_const_i32(rm);
6199 /* Bit 6 is the lowest opcode bit; it distinguishes between
6200 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6202 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6204 if (op == NEON_2RM_AESE) {
6205 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6206 } else {
6207 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6209 tcg_temp_free_i32(tmp);
6210 tcg_temp_free_i32(tmp2);
6211 tcg_temp_free_i32(tmp3);
6212 break;
6213 default:
6214 elementwise:
6215 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6216 if (neon_2rm_is_float_op(op)) {
6217 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6218 neon_reg_offset(rm, pass));
6219 TCGV_UNUSED_I32(tmp);
6220 } else {
6221 tmp = neon_load_reg(rm, pass);
6223 switch (op) {
6224 case NEON_2RM_VREV32:
6225 switch (size) {
6226 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6227 case 1: gen_swap_half(tmp); break;
6228 default: abort();
6230 break;
6231 case NEON_2RM_VREV16:
6232 gen_rev16(tmp);
6233 break;
6234 case NEON_2RM_VCLS:
6235 switch (size) {
6236 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6237 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6238 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6239 default: abort();
6241 break;
6242 case NEON_2RM_VCLZ:
6243 switch (size) {
6244 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6245 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6246 case 2: gen_helper_clz(tmp, tmp); break;
6247 default: abort();
6249 break;
6250 case NEON_2RM_VCNT:
6251 gen_helper_neon_cnt_u8(tmp, tmp);
6252 break;
6253 case NEON_2RM_VMVN:
6254 tcg_gen_not_i32(tmp, tmp);
6255 break;
6256 case NEON_2RM_VQABS:
6257 switch (size) {
6258 case 0:
6259 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6260 break;
6261 case 1:
6262 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6263 break;
6264 case 2:
6265 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6266 break;
6267 default: abort();
6269 break;
6270 case NEON_2RM_VQNEG:
6271 switch (size) {
6272 case 0:
6273 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6274 break;
6275 case 1:
6276 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6277 break;
6278 case 2:
6279 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6280 break;
6281 default: abort();
6283 break;
6284 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6285 tmp2 = tcg_const_i32(0);
6286 switch(size) {
6287 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6288 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6289 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6290 default: abort();
6292 tcg_temp_free_i32(tmp2);
6293 if (op == NEON_2RM_VCLE0) {
6294 tcg_gen_not_i32(tmp, tmp);
6296 break;
6297 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6298 tmp2 = tcg_const_i32(0);
6299 switch(size) {
6300 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6301 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6302 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6303 default: abort();
6305 tcg_temp_free_i32(tmp2);
6306 if (op == NEON_2RM_VCLT0) {
6307 tcg_gen_not_i32(tmp, tmp);
6309 break;
6310 case NEON_2RM_VCEQ0:
6311 tmp2 = tcg_const_i32(0);
6312 switch(size) {
6313 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6314 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6315 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6316 default: abort();
6318 tcg_temp_free_i32(tmp2);
6319 break;
6320 case NEON_2RM_VABS:
6321 switch(size) {
6322 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6323 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6324 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6325 default: abort();
6327 break;
6328 case NEON_2RM_VNEG:
6329 tmp2 = tcg_const_i32(0);
6330 gen_neon_rsb(size, tmp, tmp2);
6331 tcg_temp_free_i32(tmp2);
6332 break;
6333 case NEON_2RM_VCGT0_F:
6335 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6336 tmp2 = tcg_const_i32(0);
6337 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6338 tcg_temp_free_i32(tmp2);
6339 tcg_temp_free_ptr(fpstatus);
6340 break;
6342 case NEON_2RM_VCGE0_F:
6344 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6345 tmp2 = tcg_const_i32(0);
6346 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6347 tcg_temp_free_i32(tmp2);
6348 tcg_temp_free_ptr(fpstatus);
6349 break;
6351 case NEON_2RM_VCEQ0_F:
6353 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6354 tmp2 = tcg_const_i32(0);
6355 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6356 tcg_temp_free_i32(tmp2);
6357 tcg_temp_free_ptr(fpstatus);
6358 break;
6360 case NEON_2RM_VCLE0_F:
6362 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6363 tmp2 = tcg_const_i32(0);
6364 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6365 tcg_temp_free_i32(tmp2);
6366 tcg_temp_free_ptr(fpstatus);
6367 break;
6369 case NEON_2RM_VCLT0_F:
6371 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6372 tmp2 = tcg_const_i32(0);
6373 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6374 tcg_temp_free_i32(tmp2);
6375 tcg_temp_free_ptr(fpstatus);
6376 break;
6378 case NEON_2RM_VABS_F:
6379 gen_vfp_abs(0);
6380 break;
6381 case NEON_2RM_VNEG_F:
6382 gen_vfp_neg(0);
6383 break;
6384 case NEON_2RM_VSWP:
6385 tmp2 = neon_load_reg(rd, pass);
6386 neon_store_reg(rm, pass, tmp2);
6387 break;
6388 case NEON_2RM_VTRN:
6389 tmp2 = neon_load_reg(rd, pass);
6390 switch (size) {
6391 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6392 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6393 default: abort();
6395 neon_store_reg(rm, pass, tmp2);
6396 break;
6397 case NEON_2RM_VRECPE:
6398 gen_helper_recpe_u32(tmp, tmp, cpu_env);
6399 break;
6400 case NEON_2RM_VRSQRTE:
6401 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6402 break;
6403 case NEON_2RM_VRECPE_F:
6404 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6405 break;
6406 case NEON_2RM_VRSQRTE_F:
6407 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6408 break;
6409 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6410 gen_vfp_sito(0, 1);
6411 break;
6412 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6413 gen_vfp_uito(0, 1);
6414 break;
6415 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6416 gen_vfp_tosiz(0, 1);
6417 break;
6418 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6419 gen_vfp_touiz(0, 1);
6420 break;
6421 default:
6422 /* Reserved op values were caught by the
6423 * neon_2rm_sizes[] check earlier.
6425 abort();
6427 if (neon_2rm_is_float_op(op)) {
6428 tcg_gen_st_f32(cpu_F0s, cpu_env,
6429 neon_reg_offset(rd, pass));
6430 } else {
6431 neon_store_reg(rd, pass, tmp);
6434 break;
6436 } else if ((insn & (1 << 10)) == 0) {
6437 /* VTBL, VTBX. */
6438 int n = ((insn >> 8) & 3) + 1;
6439 if ((rn + n) > 32) {
6440 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6441 * helper function running off the end of the register file.
6443 return 1;
6445 n <<= 3;
6446 if (insn & (1 << 6)) {
6447 tmp = neon_load_reg(rd, 0);
6448 } else {
6449 tmp = tcg_temp_new_i32();
6450 tcg_gen_movi_i32(tmp, 0);
6452 tmp2 = neon_load_reg(rm, 0);
6453 tmp4 = tcg_const_i32(rn);
6454 tmp5 = tcg_const_i32(n);
6455 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6456 tcg_temp_free_i32(tmp);
6457 if (insn & (1 << 6)) {
6458 tmp = neon_load_reg(rd, 1);
6459 } else {
6460 tmp = tcg_temp_new_i32();
6461 tcg_gen_movi_i32(tmp, 0);
6463 tmp3 = neon_load_reg(rm, 1);
6464 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6465 tcg_temp_free_i32(tmp5);
6466 tcg_temp_free_i32(tmp4);
6467 neon_store_reg(rd, 0, tmp2);
6468 neon_store_reg(rd, 1, tmp3);
6469 tcg_temp_free_i32(tmp);
6470 } else if ((insn & 0x380) == 0) {
6471 /* VDUP */
6472 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6473 return 1;
6475 if (insn & (1 << 19)) {
6476 tmp = neon_load_reg(rm, 1);
6477 } else {
6478 tmp = neon_load_reg(rm, 0);
6480 if (insn & (1 << 16)) {
6481 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6482 } else if (insn & (1 << 17)) {
6483 if ((insn >> 18) & 1)
6484 gen_neon_dup_high16(tmp);
6485 else
6486 gen_neon_dup_low16(tmp);
6488 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6489 tmp2 = tcg_temp_new_i32();
6490 tcg_gen_mov_i32(tmp2, tmp);
6491 neon_store_reg(rd, pass, tmp2);
6493 tcg_temp_free_i32(tmp);
6494 } else {
6495 return 1;
6499 return 0;
6502 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6504 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6505 const ARMCPRegInfo *ri;
6506 ARMCPU *cpu = arm_env_get_cpu(env);
6508 cpnum = (insn >> 8) & 0xf;
6509 if (arm_feature(env, ARM_FEATURE_XSCALE)
6510 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6511 return 1;
6513 /* First check for coprocessor space used for actual instructions */
6514 switch (cpnum) {
6515 case 0:
6516 case 1:
6517 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6518 return disas_iwmmxt_insn(env, s, insn);
6519 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6520 return disas_dsp_insn(env, s, insn);
6522 return 1;
6523 default:
6524 break;
6527 /* Otherwise treat as a generic register access */
6528 is64 = (insn & (1 << 25)) == 0;
6529 if (!is64 && ((insn & (1 << 4)) == 0)) {
6530 /* cdp */
6531 return 1;
6534 crm = insn & 0xf;
6535 if (is64) {
6536 crn = 0;
6537 opc1 = (insn >> 4) & 0xf;
6538 opc2 = 0;
6539 rt2 = (insn >> 16) & 0xf;
6540 } else {
6541 crn = (insn >> 16) & 0xf;
6542 opc1 = (insn >> 21) & 7;
6543 opc2 = (insn >> 5) & 7;
6544 rt2 = 0;
6546 isread = (insn >> 20) & 1;
6547 rt = (insn >> 12) & 0xf;
6549 ri = get_arm_cp_reginfo(cpu,
6550 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6551 if (ri) {
6552 /* Check access permissions */
6553 if (!cp_access_ok(env, ri, isread)) {
6554 return 1;
6557 /* Handle special cases first */
6558 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6559 case ARM_CP_NOP:
6560 return 0;
6561 case ARM_CP_WFI:
6562 if (isread) {
6563 return 1;
6565 gen_set_pc_im(s, s->pc);
6566 s->is_jmp = DISAS_WFI;
6567 return 0;
6568 default:
6569 break;
6572 if (use_icount && (ri->type & ARM_CP_IO)) {
6573 gen_io_start();
6576 if (isread) {
6577 /* Read */
6578 if (is64) {
6579 TCGv_i64 tmp64;
6580 TCGv_i32 tmp;
6581 if (ri->type & ARM_CP_CONST) {
6582 tmp64 = tcg_const_i64(ri->resetvalue);
6583 } else if (ri->readfn) {
6584 TCGv_ptr tmpptr;
6585 gen_set_pc_im(s, s->pc);
6586 tmp64 = tcg_temp_new_i64();
6587 tmpptr = tcg_const_ptr(ri);
6588 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6589 tcg_temp_free_ptr(tmpptr);
6590 } else {
6591 tmp64 = tcg_temp_new_i64();
6592 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6594 tmp = tcg_temp_new_i32();
6595 tcg_gen_trunc_i64_i32(tmp, tmp64);
6596 store_reg(s, rt, tmp);
6597 tcg_gen_shri_i64(tmp64, tmp64, 32);
6598 tmp = tcg_temp_new_i32();
6599 tcg_gen_trunc_i64_i32(tmp, tmp64);
6600 tcg_temp_free_i64(tmp64);
6601 store_reg(s, rt2, tmp);
6602 } else {
6603 TCGv_i32 tmp;
6604 if (ri->type & ARM_CP_CONST) {
6605 tmp = tcg_const_i32(ri->resetvalue);
6606 } else if (ri->readfn) {
6607 TCGv_ptr tmpptr;
6608 gen_set_pc_im(s, s->pc);
6609 tmp = tcg_temp_new_i32();
6610 tmpptr = tcg_const_ptr(ri);
6611 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6612 tcg_temp_free_ptr(tmpptr);
6613 } else {
6614 tmp = load_cpu_offset(ri->fieldoffset);
6616 if (rt == 15) {
6617 /* Destination register of r15 for 32 bit loads sets
6618 * the condition codes from the high 4 bits of the value
6620 gen_set_nzcv(tmp);
6621 tcg_temp_free_i32(tmp);
6622 } else {
6623 store_reg(s, rt, tmp);
6626 } else {
6627 /* Write */
6628 if (ri->type & ARM_CP_CONST) {
6629 /* If not forbidden by access permissions, treat as WI */
6630 return 0;
6633 if (is64) {
6634 TCGv_i32 tmplo, tmphi;
6635 TCGv_i64 tmp64 = tcg_temp_new_i64();
6636 tmplo = load_reg(s, rt);
6637 tmphi = load_reg(s, rt2);
6638 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6639 tcg_temp_free_i32(tmplo);
6640 tcg_temp_free_i32(tmphi);
6641 if (ri->writefn) {
6642 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6643 gen_set_pc_im(s, s->pc);
6644 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6645 tcg_temp_free_ptr(tmpptr);
6646 } else {
6647 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6649 tcg_temp_free_i64(tmp64);
6650 } else {
6651 if (ri->writefn) {
6652 TCGv_i32 tmp;
6653 TCGv_ptr tmpptr;
6654 gen_set_pc_im(s, s->pc);
6655 tmp = load_reg(s, rt);
6656 tmpptr = tcg_const_ptr(ri);
6657 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6658 tcg_temp_free_ptr(tmpptr);
6659 tcg_temp_free_i32(tmp);
6660 } else {
6661 TCGv_i32 tmp = load_reg(s, rt);
6662 store_cpu_offset(tmp, ri->fieldoffset);
6667 if (use_icount && (ri->type & ARM_CP_IO)) {
6668 /* I/O operations must end the TB here (whether read or write) */
6669 gen_io_end();
6670 gen_lookup_tb(s);
6671 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6672 /* We default to ending the TB on a coprocessor register write,
6673 * but allow this to be suppressed by the register definition
6674 * (usually only necessary to work around guest bugs).
6676 gen_lookup_tb(s);
6679 return 0;
6682 return 1;
6686 /* Store a 64-bit value to a register pair. Clobbers val. */
6687 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6689 TCGv_i32 tmp;
6690 tmp = tcg_temp_new_i32();
6691 tcg_gen_trunc_i64_i32(tmp, val);
6692 store_reg(s, rlow, tmp);
6693 tmp = tcg_temp_new_i32();
6694 tcg_gen_shri_i64(val, val, 32);
6695 tcg_gen_trunc_i64_i32(tmp, val);
6696 store_reg(s, rhigh, tmp);
6699 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6700 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6702 TCGv_i64 tmp;
6703 TCGv_i32 tmp2;
6705 /* Load value and extend to 64 bits. */
6706 tmp = tcg_temp_new_i64();
6707 tmp2 = load_reg(s, rlow);
6708 tcg_gen_extu_i32_i64(tmp, tmp2);
6709 tcg_temp_free_i32(tmp2);
6710 tcg_gen_add_i64(val, val, tmp);
6711 tcg_temp_free_i64(tmp);
6714 /* load and add a 64-bit value from a register pair. */
6715 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6717 TCGv_i64 tmp;
6718 TCGv_i32 tmpl;
6719 TCGv_i32 tmph;
6721 /* Load 64-bit value rd:rn. */
6722 tmpl = load_reg(s, rlow);
6723 tmph = load_reg(s, rhigh);
6724 tmp = tcg_temp_new_i64();
6725 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6726 tcg_temp_free_i32(tmpl);
6727 tcg_temp_free_i32(tmph);
6728 tcg_gen_add_i64(val, val, tmp);
6729 tcg_temp_free_i64(tmp);
6732 /* Set N and Z flags from hi|lo. */
6733 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6735 tcg_gen_mov_i32(cpu_NF, hi);
6736 tcg_gen_or_i32(cpu_ZF, lo, hi);
6739 /* Load/Store exclusive instructions are implemented by remembering
6740 the value/address loaded, and seeing if these are the same
6741 when the store is performed. This should be sufficient to implement
6742 the architecturally mandated semantics, and avoids having to monitor
6743 regular stores.
6745 In system emulation mode only one CPU will be running at once, so
6746 this sequence is effectively atomic. In user emulation mode we
6747 throw an exception and handle the atomic operation elsewhere. */
6748 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6749 TCGv_i32 addr, int size)
6751 TCGv_i32 tmp = tcg_temp_new_i32();
6753 switch (size) {
6754 case 0:
6755 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6756 break;
6757 case 1:
6758 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6759 break;
6760 case 2:
6761 case 3:
6762 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6763 break;
6764 default:
6765 abort();
6767 tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6768 store_reg(s, rt, tmp);
6769 if (size == 3) {
6770 TCGv_i32 tmp2 = tcg_temp_new_i32();
6771 tcg_gen_addi_i32(tmp2, addr, 4);
6772 tmp = tcg_temp_new_i32();
6773 gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6774 tcg_temp_free_i32(tmp2);
6775 tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6776 store_reg(s, rt2, tmp);
6778 tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6781 static void gen_clrex(DisasContext *s)
6783 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6786 #ifdef CONFIG_USER_ONLY
6787 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6788 TCGv_i32 addr, int size)
6790 tcg_gen_mov_i32(cpu_exclusive_test, addr);
6791 tcg_gen_movi_i32(cpu_exclusive_info,
6792 size | (rd << 4) | (rt << 8) | (rt2 << 12));
6793 gen_exception_insn(s, 4, EXCP_STREX);
6795 #else
6796 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6797 TCGv_i32 addr, int size)
6799 TCGv_i32 tmp;
6800 int done_label;
6801 int fail_label;
6803 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6804 [addr] = {Rt};
6805 {Rd} = 0;
6806 } else {
6807 {Rd} = 1;
6808 } */
6809 fail_label = gen_new_label();
6810 done_label = gen_new_label();
6811 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6812 tmp = tcg_temp_new_i32();
6813 switch (size) {
6814 case 0:
6815 gen_aa32_ld8u(tmp, addr, IS_USER(s));
6816 break;
6817 case 1:
6818 gen_aa32_ld16u(tmp, addr, IS_USER(s));
6819 break;
6820 case 2:
6821 case 3:
6822 gen_aa32_ld32u(tmp, addr, IS_USER(s));
6823 break;
6824 default:
6825 abort();
6827 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6828 tcg_temp_free_i32(tmp);
6829 if (size == 3) {
6830 TCGv_i32 tmp2 = tcg_temp_new_i32();
6831 tcg_gen_addi_i32(tmp2, addr, 4);
6832 tmp = tcg_temp_new_i32();
6833 gen_aa32_ld32u(tmp, tmp2, IS_USER(s));
6834 tcg_temp_free_i32(tmp2);
6835 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6836 tcg_temp_free_i32(tmp);
6838 tmp = load_reg(s, rt);
6839 switch (size) {
6840 case 0:
6841 gen_aa32_st8(tmp, addr, IS_USER(s));
6842 break;
6843 case 1:
6844 gen_aa32_st16(tmp, addr, IS_USER(s));
6845 break;
6846 case 2:
6847 case 3:
6848 gen_aa32_st32(tmp, addr, IS_USER(s));
6849 break;
6850 default:
6851 abort();
6853 tcg_temp_free_i32(tmp);
6854 if (size == 3) {
6855 tcg_gen_addi_i32(addr, addr, 4);
6856 tmp = load_reg(s, rt2);
6857 gen_aa32_st32(tmp, addr, IS_USER(s));
6858 tcg_temp_free_i32(tmp);
6860 tcg_gen_movi_i32(cpu_R[rd], 0);
6861 tcg_gen_br(done_label);
6862 gen_set_label(fail_label);
6863 tcg_gen_movi_i32(cpu_R[rd], 1);
6864 gen_set_label(done_label);
6865 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6867 #endif
6869 /* gen_srs:
6870 * @env: CPUARMState
6871 * @s: DisasContext
6872 * @mode: mode field from insn (which stack to store to)
6873 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6874 * @writeback: true if writeback bit set
6876 * Generate code for the SRS (Store Return State) insn.
6878 static void gen_srs(DisasContext *s,
6879 uint32_t mode, uint32_t amode, bool writeback)
6881 int32_t offset;
6882 TCGv_i32 addr = tcg_temp_new_i32();
6883 TCGv_i32 tmp = tcg_const_i32(mode);
6884 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6885 tcg_temp_free_i32(tmp);
6886 switch (amode) {
6887 case 0: /* DA */
6888 offset = -4;
6889 break;
6890 case 1: /* IA */
6891 offset = 0;
6892 break;
6893 case 2: /* DB */
6894 offset = -8;
6895 break;
6896 case 3: /* IB */
6897 offset = 4;
6898 break;
6899 default:
6900 abort();
6902 tcg_gen_addi_i32(addr, addr, offset);
6903 tmp = load_reg(s, 14);
6904 gen_aa32_st32(tmp, addr, 0);
6905 tcg_temp_free_i32(tmp);
6906 tmp = load_cpu_field(spsr);
6907 tcg_gen_addi_i32(addr, addr, 4);
6908 gen_aa32_st32(tmp, addr, 0);
6909 tcg_temp_free_i32(tmp);
6910 if (writeback) {
6911 switch (amode) {
6912 case 0:
6913 offset = -8;
6914 break;
6915 case 1:
6916 offset = 4;
6917 break;
6918 case 2:
6919 offset = -4;
6920 break;
6921 case 3:
6922 offset = 0;
6923 break;
6924 default:
6925 abort();
6927 tcg_gen_addi_i32(addr, addr, offset);
6928 tmp = tcg_const_i32(mode);
6929 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6930 tcg_temp_free_i32(tmp);
6932 tcg_temp_free_i32(addr);
6935 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6937 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6938 TCGv_i32 tmp;
6939 TCGv_i32 tmp2;
6940 TCGv_i32 tmp3;
6941 TCGv_i32 addr;
6942 TCGv_i64 tmp64;
6944 insn = arm_ldl_code(env, s->pc, s->bswap_code);
6945 s->pc += 4;
6947 /* M variants do not implement ARM mode. */
6948 if (IS_M(env))
6949 goto illegal_op;
6950 cond = insn >> 28;
6951 if (cond == 0xf){
6952 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6953 * choose to UNDEF. In ARMv5 and above the space is used
6954 * for miscellaneous unconditional instructions.
6956 ARCH(5);
6958 /* Unconditional instructions. */
6959 if (((insn >> 25) & 7) == 1) {
6960 /* NEON Data processing. */
6961 if (!arm_feature(env, ARM_FEATURE_NEON))
6962 goto illegal_op;
6964 if (disas_neon_data_insn(env, s, insn))
6965 goto illegal_op;
6966 return;
6968 if ((insn & 0x0f100000) == 0x04000000) {
6969 /* NEON load/store. */
6970 if (!arm_feature(env, ARM_FEATURE_NEON))
6971 goto illegal_op;
6973 if (disas_neon_ls_insn(env, s, insn))
6974 goto illegal_op;
6975 return;
6977 if ((insn & 0x0f000e10) == 0x0e000a00) {
6978 /* VFP. */
6979 if (disas_vfp_insn(env, s, insn)) {
6980 goto illegal_op;
6982 return;
6984 if (((insn & 0x0f30f000) == 0x0510f000) ||
6985 ((insn & 0x0f30f010) == 0x0710f000)) {
6986 if ((insn & (1 << 22)) == 0) {
6987 /* PLDW; v7MP */
6988 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6989 goto illegal_op;
6992 /* Otherwise PLD; v5TE+ */
6993 ARCH(5TE);
6994 return;
6996 if (((insn & 0x0f70f000) == 0x0450f000) ||
6997 ((insn & 0x0f70f010) == 0x0650f000)) {
6998 ARCH(7);
6999 return; /* PLI; V7 */
7001 if (((insn & 0x0f700000) == 0x04100000) ||
7002 ((insn & 0x0f700010) == 0x06100000)) {
7003 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7004 goto illegal_op;
7006 return; /* v7MP: Unallocated memory hint: must NOP */
7009 if ((insn & 0x0ffffdff) == 0x01010000) {
7010 ARCH(6);
7011 /* setend */
7012 if (((insn >> 9) & 1) != s->bswap_code) {
7013 /* Dynamic endianness switching not implemented. */
7014 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7015 goto illegal_op;
7017 return;
7018 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7019 switch ((insn >> 4) & 0xf) {
7020 case 1: /* clrex */
7021 ARCH(6K);
7022 gen_clrex(s);
7023 return;
7024 case 4: /* dsb */
7025 case 5: /* dmb */
7026 case 6: /* isb */
7027 ARCH(7);
7028 /* We don't emulate caches so these are a no-op. */
7029 return;
7030 default:
7031 goto illegal_op;
7033 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7034 /* srs */
7035 if (IS_USER(s)) {
7036 goto illegal_op;
7038 ARCH(6);
7039 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7040 return;
7041 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7042 /* rfe */
7043 int32_t offset;
7044 if (IS_USER(s))
7045 goto illegal_op;
7046 ARCH(6);
7047 rn = (insn >> 16) & 0xf;
7048 addr = load_reg(s, rn);
7049 i = (insn >> 23) & 3;
7050 switch (i) {
7051 case 0: offset = -4; break; /* DA */
7052 case 1: offset = 0; break; /* IA */
7053 case 2: offset = -8; break; /* DB */
7054 case 3: offset = 4; break; /* IB */
7055 default: abort();
7057 if (offset)
7058 tcg_gen_addi_i32(addr, addr, offset);
7059 /* Load PC into tmp and CPSR into tmp2. */
7060 tmp = tcg_temp_new_i32();
7061 gen_aa32_ld32u(tmp, addr, 0);
7062 tcg_gen_addi_i32(addr, addr, 4);
7063 tmp2 = tcg_temp_new_i32();
7064 gen_aa32_ld32u(tmp2, addr, 0);
7065 if (insn & (1 << 21)) {
7066 /* Base writeback. */
7067 switch (i) {
7068 case 0: offset = -8; break;
7069 case 1: offset = 4; break;
7070 case 2: offset = -4; break;
7071 case 3: offset = 0; break;
7072 default: abort();
7074 if (offset)
7075 tcg_gen_addi_i32(addr, addr, offset);
7076 store_reg(s, rn, addr);
7077 } else {
7078 tcg_temp_free_i32(addr);
7080 gen_rfe(s, tmp, tmp2);
7081 return;
7082 } else if ((insn & 0x0e000000) == 0x0a000000) {
7083 /* branch link and change to thumb (blx <offset>) */
7084 int32_t offset;
7086 val = (uint32_t)s->pc;
7087 tmp = tcg_temp_new_i32();
7088 tcg_gen_movi_i32(tmp, val);
7089 store_reg(s, 14, tmp);
7090 /* Sign-extend the 24-bit offset */
7091 offset = (((int32_t)insn) << 8) >> 8;
7092 /* offset * 4 + bit24 * 2 + (thumb bit) */
7093 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7094 /* pipeline offset */
7095 val += 4;
7096 /* protected by ARCH(5); above, near the start of uncond block */
7097 gen_bx_im(s, val);
7098 return;
7099 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7100 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7101 /* iWMMXt register transfer. */
7102 if (env->cp15.c15_cpar & (1 << 1))
7103 if (!disas_iwmmxt_insn(env, s, insn))
7104 return;
7106 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7107 /* Coprocessor double register transfer. */
7108 ARCH(5TE);
7109 } else if ((insn & 0x0f000010) == 0x0e000010) {
7110 /* Additional coprocessor register transfer. */
7111 } else if ((insn & 0x0ff10020) == 0x01000000) {
7112 uint32_t mask;
7113 uint32_t val;
7114 /* cps (privileged) */
7115 if (IS_USER(s))
7116 return;
7117 mask = val = 0;
7118 if (insn & (1 << 19)) {
7119 if (insn & (1 << 8))
7120 mask |= CPSR_A;
7121 if (insn & (1 << 7))
7122 mask |= CPSR_I;
7123 if (insn & (1 << 6))
7124 mask |= CPSR_F;
7125 if (insn & (1 << 18))
7126 val |= mask;
7128 if (insn & (1 << 17)) {
7129 mask |= CPSR_M;
7130 val |= (insn & 0x1f);
7132 if (mask) {
7133 gen_set_psr_im(s, mask, 0, val);
7135 return;
7137 goto illegal_op;
7139 if (cond != 0xe) {
7140 /* if not always execute, we generate a conditional jump to
7141 next instruction */
7142 s->condlabel = gen_new_label();
7143 gen_test_cc(cond ^ 1, s->condlabel);
7144 s->condjmp = 1;
7146 if ((insn & 0x0f900000) == 0x03000000) {
7147 if ((insn & (1 << 21)) == 0) {
7148 ARCH(6T2);
7149 rd = (insn >> 12) & 0xf;
7150 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7151 if ((insn & (1 << 22)) == 0) {
7152 /* MOVW */
7153 tmp = tcg_temp_new_i32();
7154 tcg_gen_movi_i32(tmp, val);
7155 } else {
7156 /* MOVT */
7157 tmp = load_reg(s, rd);
7158 tcg_gen_ext16u_i32(tmp, tmp);
7159 tcg_gen_ori_i32(tmp, tmp, val << 16);
7161 store_reg(s, rd, tmp);
7162 } else {
7163 if (((insn >> 12) & 0xf) != 0xf)
7164 goto illegal_op;
7165 if (((insn >> 16) & 0xf) == 0) {
7166 gen_nop_hint(s, insn & 0xff);
7167 } else {
7168 /* CPSR = immediate */
7169 val = insn & 0xff;
7170 shift = ((insn >> 8) & 0xf) * 2;
7171 if (shift)
7172 val = (val >> shift) | (val << (32 - shift));
7173 i = ((insn & (1 << 22)) != 0);
7174 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7175 goto illegal_op;
7178 } else if ((insn & 0x0f900000) == 0x01000000
7179 && (insn & 0x00000090) != 0x00000090) {
7180 /* miscellaneous instructions */
7181 op1 = (insn >> 21) & 3;
7182 sh = (insn >> 4) & 0xf;
7183 rm = insn & 0xf;
7184 switch (sh) {
7185 case 0x0: /* move program status register */
7186 if (op1 & 1) {
7187 /* PSR = reg */
7188 tmp = load_reg(s, rm);
7189 i = ((op1 & 2) != 0);
7190 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7191 goto illegal_op;
7192 } else {
7193 /* reg = PSR */
7194 rd = (insn >> 12) & 0xf;
7195 if (op1 & 2) {
7196 if (IS_USER(s))
7197 goto illegal_op;
7198 tmp = load_cpu_field(spsr);
7199 } else {
7200 tmp = tcg_temp_new_i32();
7201 gen_helper_cpsr_read(tmp, cpu_env);
7203 store_reg(s, rd, tmp);
7205 break;
7206 case 0x1:
7207 if (op1 == 1) {
7208 /* branch/exchange thumb (bx). */
7209 ARCH(4T);
7210 tmp = load_reg(s, rm);
7211 gen_bx(s, tmp);
7212 } else if (op1 == 3) {
7213 /* clz */
7214 ARCH(5);
7215 rd = (insn >> 12) & 0xf;
7216 tmp = load_reg(s, rm);
7217 gen_helper_clz(tmp, tmp);
7218 store_reg(s, rd, tmp);
7219 } else {
7220 goto illegal_op;
7222 break;
7223 case 0x2:
7224 if (op1 == 1) {
7225 ARCH(5J); /* bxj */
7226 /* Trivial implementation equivalent to bx. */
7227 tmp = load_reg(s, rm);
7228 gen_bx(s, tmp);
7229 } else {
7230 goto illegal_op;
7232 break;
7233 case 0x3:
7234 if (op1 != 1)
7235 goto illegal_op;
7237 ARCH(5);
7238 /* branch link/exchange thumb (blx) */
7239 tmp = load_reg(s, rm);
7240 tmp2 = tcg_temp_new_i32();
7241 tcg_gen_movi_i32(tmp2, s->pc);
7242 store_reg(s, 14, tmp2);
7243 gen_bx(s, tmp);
7244 break;
7245 case 0x5: /* saturating add/subtract */
7246 ARCH(5TE);
7247 rd = (insn >> 12) & 0xf;
7248 rn = (insn >> 16) & 0xf;
7249 tmp = load_reg(s, rm);
7250 tmp2 = load_reg(s, rn);
7251 if (op1 & 2)
7252 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7253 if (op1 & 1)
7254 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7255 else
7256 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7257 tcg_temp_free_i32(tmp2);
7258 store_reg(s, rd, tmp);
7259 break;
7260 case 7:
7261 /* SMC instruction (op1 == 3)
7262 and undefined instructions (op1 == 0 || op1 == 2)
7263 will trap */
7264 if (op1 != 1) {
7265 goto illegal_op;
7267 /* bkpt */
7268 ARCH(5);
7269 gen_exception_insn(s, 4, EXCP_BKPT);
7270 break;
7271 case 0x8: /* signed multiply */
7272 case 0xa:
7273 case 0xc:
7274 case 0xe:
7275 ARCH(5TE);
7276 rs = (insn >> 8) & 0xf;
7277 rn = (insn >> 12) & 0xf;
7278 rd = (insn >> 16) & 0xf;
7279 if (op1 == 1) {
7280 /* (32 * 16) >> 16 */
7281 tmp = load_reg(s, rm);
7282 tmp2 = load_reg(s, rs);
7283 if (sh & 4)
7284 tcg_gen_sari_i32(tmp2, tmp2, 16);
7285 else
7286 gen_sxth(tmp2);
7287 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7288 tcg_gen_shri_i64(tmp64, tmp64, 16);
7289 tmp = tcg_temp_new_i32();
7290 tcg_gen_trunc_i64_i32(tmp, tmp64);
7291 tcg_temp_free_i64(tmp64);
7292 if ((sh & 2) == 0) {
7293 tmp2 = load_reg(s, rn);
7294 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7295 tcg_temp_free_i32(tmp2);
7297 store_reg(s, rd, tmp);
7298 } else {
7299 /* 16 * 16 */
7300 tmp = load_reg(s, rm);
7301 tmp2 = load_reg(s, rs);
7302 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7303 tcg_temp_free_i32(tmp2);
7304 if (op1 == 2) {
7305 tmp64 = tcg_temp_new_i64();
7306 tcg_gen_ext_i32_i64(tmp64, tmp);
7307 tcg_temp_free_i32(tmp);
7308 gen_addq(s, tmp64, rn, rd);
7309 gen_storeq_reg(s, rn, rd, tmp64);
7310 tcg_temp_free_i64(tmp64);
7311 } else {
7312 if (op1 == 0) {
7313 tmp2 = load_reg(s, rn);
7314 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7315 tcg_temp_free_i32(tmp2);
7317 store_reg(s, rd, tmp);
7320 break;
7321 default:
7322 goto illegal_op;
7324 } else if (((insn & 0x0e000000) == 0 &&
7325 (insn & 0x00000090) != 0x90) ||
7326 ((insn & 0x0e000000) == (1 << 25))) {
7327 int set_cc, logic_cc, shiftop;
7329 op1 = (insn >> 21) & 0xf;
7330 set_cc = (insn >> 20) & 1;
7331 logic_cc = table_logic_cc[op1] & set_cc;
7333 /* data processing instruction */
7334 if (insn & (1 << 25)) {
7335 /* immediate operand */
7336 val = insn & 0xff;
7337 shift = ((insn >> 8) & 0xf) * 2;
7338 if (shift) {
7339 val = (val >> shift) | (val << (32 - shift));
7341 tmp2 = tcg_temp_new_i32();
7342 tcg_gen_movi_i32(tmp2, val);
7343 if (logic_cc && shift) {
7344 gen_set_CF_bit31(tmp2);
7346 } else {
7347 /* register */
7348 rm = (insn) & 0xf;
7349 tmp2 = load_reg(s, rm);
7350 shiftop = (insn >> 5) & 3;
7351 if (!(insn & (1 << 4))) {
7352 shift = (insn >> 7) & 0x1f;
7353 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7354 } else {
7355 rs = (insn >> 8) & 0xf;
7356 tmp = load_reg(s, rs);
7357 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7360 if (op1 != 0x0f && op1 != 0x0d) {
7361 rn = (insn >> 16) & 0xf;
7362 tmp = load_reg(s, rn);
7363 } else {
7364 TCGV_UNUSED_I32(tmp);
7366 rd = (insn >> 12) & 0xf;
7367 switch(op1) {
7368 case 0x00:
7369 tcg_gen_and_i32(tmp, tmp, tmp2);
7370 if (logic_cc) {
7371 gen_logic_CC(tmp);
7373 store_reg_bx(env, s, rd, tmp);
7374 break;
7375 case 0x01:
7376 tcg_gen_xor_i32(tmp, tmp, tmp2);
7377 if (logic_cc) {
7378 gen_logic_CC(tmp);
7380 store_reg_bx(env, s, rd, tmp);
7381 break;
7382 case 0x02:
7383 if (set_cc && rd == 15) {
7384 /* SUBS r15, ... is used for exception return. */
7385 if (IS_USER(s)) {
7386 goto illegal_op;
7388 gen_sub_CC(tmp, tmp, tmp2);
7389 gen_exception_return(s, tmp);
7390 } else {
7391 if (set_cc) {
7392 gen_sub_CC(tmp, tmp, tmp2);
7393 } else {
7394 tcg_gen_sub_i32(tmp, tmp, tmp2);
7396 store_reg_bx(env, s, rd, tmp);
7398 break;
7399 case 0x03:
7400 if (set_cc) {
7401 gen_sub_CC(tmp, tmp2, tmp);
7402 } else {
7403 tcg_gen_sub_i32(tmp, tmp2, tmp);
7405 store_reg_bx(env, s, rd, tmp);
7406 break;
7407 case 0x04:
7408 if (set_cc) {
7409 gen_add_CC(tmp, tmp, tmp2);
7410 } else {
7411 tcg_gen_add_i32(tmp, tmp, tmp2);
7413 store_reg_bx(env, s, rd, tmp);
7414 break;
7415 case 0x05:
7416 if (set_cc) {
7417 gen_adc_CC(tmp, tmp, tmp2);
7418 } else {
7419 gen_add_carry(tmp, tmp, tmp2);
7421 store_reg_bx(env, s, rd, tmp);
7422 break;
7423 case 0x06:
7424 if (set_cc) {
7425 gen_sbc_CC(tmp, tmp, tmp2);
7426 } else {
7427 gen_sub_carry(tmp, tmp, tmp2);
7429 store_reg_bx(env, s, rd, tmp);
7430 break;
7431 case 0x07:
7432 if (set_cc) {
7433 gen_sbc_CC(tmp, tmp2, tmp);
7434 } else {
7435 gen_sub_carry(tmp, tmp2, tmp);
7437 store_reg_bx(env, s, rd, tmp);
7438 break;
7439 case 0x08:
7440 if (set_cc) {
7441 tcg_gen_and_i32(tmp, tmp, tmp2);
7442 gen_logic_CC(tmp);
7444 tcg_temp_free_i32(tmp);
7445 break;
7446 case 0x09:
7447 if (set_cc) {
7448 tcg_gen_xor_i32(tmp, tmp, tmp2);
7449 gen_logic_CC(tmp);
7451 tcg_temp_free_i32(tmp);
7452 break;
7453 case 0x0a:
7454 if (set_cc) {
7455 gen_sub_CC(tmp, tmp, tmp2);
7457 tcg_temp_free_i32(tmp);
7458 break;
7459 case 0x0b:
7460 if (set_cc) {
7461 gen_add_CC(tmp, tmp, tmp2);
7463 tcg_temp_free_i32(tmp);
7464 break;
7465 case 0x0c:
7466 tcg_gen_or_i32(tmp, tmp, tmp2);
7467 if (logic_cc) {
7468 gen_logic_CC(tmp);
7470 store_reg_bx(env, s, rd, tmp);
7471 break;
7472 case 0x0d:
7473 if (logic_cc && rd == 15) {
7474 /* MOVS r15, ... is used for exception return. */
7475 if (IS_USER(s)) {
7476 goto illegal_op;
7478 gen_exception_return(s, tmp2);
7479 } else {
7480 if (logic_cc) {
7481 gen_logic_CC(tmp2);
7483 store_reg_bx(env, s, rd, tmp2);
7485 break;
7486 case 0x0e:
7487 tcg_gen_andc_i32(tmp, tmp, tmp2);
7488 if (logic_cc) {
7489 gen_logic_CC(tmp);
7491 store_reg_bx(env, s, rd, tmp);
7492 break;
7493 default:
7494 case 0x0f:
7495 tcg_gen_not_i32(tmp2, tmp2);
7496 if (logic_cc) {
7497 gen_logic_CC(tmp2);
7499 store_reg_bx(env, s, rd, tmp2);
7500 break;
7502 if (op1 != 0x0f && op1 != 0x0d) {
7503 tcg_temp_free_i32(tmp2);
7505 } else {
7506 /* other instructions */
7507 op1 = (insn >> 24) & 0xf;
7508 switch(op1) {
7509 case 0x0:
7510 case 0x1:
7511 /* multiplies, extra load/stores */
7512 sh = (insn >> 5) & 3;
7513 if (sh == 0) {
7514 if (op1 == 0x0) {
7515 rd = (insn >> 16) & 0xf;
7516 rn = (insn >> 12) & 0xf;
7517 rs = (insn >> 8) & 0xf;
7518 rm = (insn) & 0xf;
7519 op1 = (insn >> 20) & 0xf;
7520 switch (op1) {
7521 case 0: case 1: case 2: case 3: case 6:
7522 /* 32 bit mul */
7523 tmp = load_reg(s, rs);
7524 tmp2 = load_reg(s, rm);
7525 tcg_gen_mul_i32(tmp, tmp, tmp2);
7526 tcg_temp_free_i32(tmp2);
7527 if (insn & (1 << 22)) {
7528 /* Subtract (mls) */
7529 ARCH(6T2);
7530 tmp2 = load_reg(s, rn);
7531 tcg_gen_sub_i32(tmp, tmp2, tmp);
7532 tcg_temp_free_i32(tmp2);
7533 } else if (insn & (1 << 21)) {
7534 /* Add */
7535 tmp2 = load_reg(s, rn);
7536 tcg_gen_add_i32(tmp, tmp, tmp2);
7537 tcg_temp_free_i32(tmp2);
7539 if (insn & (1 << 20))
7540 gen_logic_CC(tmp);
7541 store_reg(s, rd, tmp);
7542 break;
7543 case 4:
7544 /* 64 bit mul double accumulate (UMAAL) */
7545 ARCH(6);
7546 tmp = load_reg(s, rs);
7547 tmp2 = load_reg(s, rm);
7548 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7549 gen_addq_lo(s, tmp64, rn);
7550 gen_addq_lo(s, tmp64, rd);
7551 gen_storeq_reg(s, rn, rd, tmp64);
7552 tcg_temp_free_i64(tmp64);
7553 break;
7554 case 8: case 9: case 10: case 11:
7555 case 12: case 13: case 14: case 15:
7556 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7557 tmp = load_reg(s, rs);
7558 tmp2 = load_reg(s, rm);
7559 if (insn & (1 << 22)) {
7560 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7561 } else {
7562 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7564 if (insn & (1 << 21)) { /* mult accumulate */
7565 TCGv_i32 al = load_reg(s, rn);
7566 TCGv_i32 ah = load_reg(s, rd);
7567 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7568 tcg_temp_free_i32(al);
7569 tcg_temp_free_i32(ah);
7571 if (insn & (1 << 20)) {
7572 gen_logicq_cc(tmp, tmp2);
7574 store_reg(s, rn, tmp);
7575 store_reg(s, rd, tmp2);
7576 break;
7577 default:
7578 goto illegal_op;
7580 } else {
7581 rn = (insn >> 16) & 0xf;
7582 rd = (insn >> 12) & 0xf;
7583 if (insn & (1 << 23)) {
7584 /* load/store exclusive */
7585 int op2 = (insn >> 8) & 3;
7586 op1 = (insn >> 21) & 0x3;
7588 switch (op2) {
7589 case 0: /* lda/stl */
7590 if (op1 == 1) {
7591 goto illegal_op;
7593 ARCH(8);
7594 break;
7595 case 1: /* reserved */
7596 goto illegal_op;
7597 case 2: /* ldaex/stlex */
7598 ARCH(8);
7599 break;
7600 case 3: /* ldrex/strex */
7601 if (op1) {
7602 ARCH(6K);
7603 } else {
7604 ARCH(6);
7606 break;
7609 addr = tcg_temp_local_new_i32();
7610 load_reg_var(s, addr, rn);
7612 /* Since the emulation does not have barriers,
7613 the acquire/release semantics need no special
7614 handling */
7615 if (op2 == 0) {
7616 if (insn & (1 << 20)) {
7617 tmp = tcg_temp_new_i32();
7618 switch (op1) {
7619 case 0: /* lda */
7620 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7621 break;
7622 case 2: /* ldab */
7623 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7624 break;
7625 case 3: /* ldah */
7626 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7627 break;
7628 default:
7629 abort();
7631 store_reg(s, rd, tmp);
7632 } else {
7633 rm = insn & 0xf;
7634 tmp = load_reg(s, rm);
7635 switch (op1) {
7636 case 0: /* stl */
7637 gen_aa32_st32(tmp, addr, IS_USER(s));
7638 break;
7639 case 2: /* stlb */
7640 gen_aa32_st8(tmp, addr, IS_USER(s));
7641 break;
7642 case 3: /* stlh */
7643 gen_aa32_st16(tmp, addr, IS_USER(s));
7644 break;
7645 default:
7646 abort();
7648 tcg_temp_free_i32(tmp);
7650 } else if (insn & (1 << 20)) {
7651 switch (op1) {
7652 case 0: /* ldrex */
7653 gen_load_exclusive(s, rd, 15, addr, 2);
7654 break;
7655 case 1: /* ldrexd */
7656 gen_load_exclusive(s, rd, rd + 1, addr, 3);
7657 break;
7658 case 2: /* ldrexb */
7659 gen_load_exclusive(s, rd, 15, addr, 0);
7660 break;
7661 case 3: /* ldrexh */
7662 gen_load_exclusive(s, rd, 15, addr, 1);
7663 break;
7664 default:
7665 abort();
7667 } else {
7668 rm = insn & 0xf;
7669 switch (op1) {
7670 case 0: /* strex */
7671 gen_store_exclusive(s, rd, rm, 15, addr, 2);
7672 break;
7673 case 1: /* strexd */
7674 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7675 break;
7676 case 2: /* strexb */
7677 gen_store_exclusive(s, rd, rm, 15, addr, 0);
7678 break;
7679 case 3: /* strexh */
7680 gen_store_exclusive(s, rd, rm, 15, addr, 1);
7681 break;
7682 default:
7683 abort();
7686 tcg_temp_free_i32(addr);
7687 } else {
7688 /* SWP instruction */
7689 rm = (insn) & 0xf;
7691 /* ??? This is not really atomic. However we know
7692 we never have multiple CPUs running in parallel,
7693 so it is good enough. */
7694 addr = load_reg(s, rn);
7695 tmp = load_reg(s, rm);
7696 tmp2 = tcg_temp_new_i32();
7697 if (insn & (1 << 22)) {
7698 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7699 gen_aa32_st8(tmp, addr, IS_USER(s));
7700 } else {
7701 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7702 gen_aa32_st32(tmp, addr, IS_USER(s));
7704 tcg_temp_free_i32(tmp);
7705 tcg_temp_free_i32(addr);
7706 store_reg(s, rd, tmp2);
7709 } else {
7710 int address_offset;
7711 int load;
7712 /* Misc load/store */
7713 rn = (insn >> 16) & 0xf;
7714 rd = (insn >> 12) & 0xf;
7715 addr = load_reg(s, rn);
7716 if (insn & (1 << 24))
7717 gen_add_datah_offset(s, insn, 0, addr);
7718 address_offset = 0;
7719 if (insn & (1 << 20)) {
7720 /* load */
7721 tmp = tcg_temp_new_i32();
7722 switch(sh) {
7723 case 1:
7724 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7725 break;
7726 case 2:
7727 gen_aa32_ld8s(tmp, addr, IS_USER(s));
7728 break;
7729 default:
7730 case 3:
7731 gen_aa32_ld16s(tmp, addr, IS_USER(s));
7732 break;
7734 load = 1;
7735 } else if (sh & 2) {
7736 ARCH(5TE);
7737 /* doubleword */
7738 if (sh & 1) {
7739 /* store */
7740 tmp = load_reg(s, rd);
7741 gen_aa32_st32(tmp, addr, IS_USER(s));
7742 tcg_temp_free_i32(tmp);
7743 tcg_gen_addi_i32(addr, addr, 4);
7744 tmp = load_reg(s, rd + 1);
7745 gen_aa32_st32(tmp, addr, IS_USER(s));
7746 tcg_temp_free_i32(tmp);
7747 load = 0;
7748 } else {
7749 /* load */
7750 tmp = tcg_temp_new_i32();
7751 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7752 store_reg(s, rd, tmp);
7753 tcg_gen_addi_i32(addr, addr, 4);
7754 tmp = tcg_temp_new_i32();
7755 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7756 rd++;
7757 load = 1;
7759 address_offset = -4;
7760 } else {
7761 /* store */
7762 tmp = load_reg(s, rd);
7763 gen_aa32_st16(tmp, addr, IS_USER(s));
7764 tcg_temp_free_i32(tmp);
7765 load = 0;
7767 /* Perform base writeback before the loaded value to
7768 ensure correct behavior with overlapping index registers.
7769 ldrd with base writeback is is undefined if the
7770 destination and index registers overlap. */
7771 if (!(insn & (1 << 24))) {
7772 gen_add_datah_offset(s, insn, address_offset, addr);
7773 store_reg(s, rn, addr);
7774 } else if (insn & (1 << 21)) {
7775 if (address_offset)
7776 tcg_gen_addi_i32(addr, addr, address_offset);
7777 store_reg(s, rn, addr);
7778 } else {
7779 tcg_temp_free_i32(addr);
7781 if (load) {
7782 /* Complete the load. */
7783 store_reg(s, rd, tmp);
7786 break;
7787 case 0x4:
7788 case 0x5:
7789 goto do_ldst;
7790 case 0x6:
7791 case 0x7:
7792 if (insn & (1 << 4)) {
7793 ARCH(6);
7794 /* Armv6 Media instructions. */
7795 rm = insn & 0xf;
7796 rn = (insn >> 16) & 0xf;
7797 rd = (insn >> 12) & 0xf;
7798 rs = (insn >> 8) & 0xf;
7799 switch ((insn >> 23) & 3) {
7800 case 0: /* Parallel add/subtract. */
7801 op1 = (insn >> 20) & 7;
7802 tmp = load_reg(s, rn);
7803 tmp2 = load_reg(s, rm);
7804 sh = (insn >> 5) & 7;
7805 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7806 goto illegal_op;
7807 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7808 tcg_temp_free_i32(tmp2);
7809 store_reg(s, rd, tmp);
7810 break;
7811 case 1:
7812 if ((insn & 0x00700020) == 0) {
7813 /* Halfword pack. */
7814 tmp = load_reg(s, rn);
7815 tmp2 = load_reg(s, rm);
7816 shift = (insn >> 7) & 0x1f;
7817 if (insn & (1 << 6)) {
7818 /* pkhtb */
7819 if (shift == 0)
7820 shift = 31;
7821 tcg_gen_sari_i32(tmp2, tmp2, shift);
7822 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7823 tcg_gen_ext16u_i32(tmp2, tmp2);
7824 } else {
7825 /* pkhbt */
7826 if (shift)
7827 tcg_gen_shli_i32(tmp2, tmp2, shift);
7828 tcg_gen_ext16u_i32(tmp, tmp);
7829 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7831 tcg_gen_or_i32(tmp, tmp, tmp2);
7832 tcg_temp_free_i32(tmp2);
7833 store_reg(s, rd, tmp);
7834 } else if ((insn & 0x00200020) == 0x00200000) {
7835 /* [us]sat */
7836 tmp = load_reg(s, rm);
7837 shift = (insn >> 7) & 0x1f;
7838 if (insn & (1 << 6)) {
7839 if (shift == 0)
7840 shift = 31;
7841 tcg_gen_sari_i32(tmp, tmp, shift);
7842 } else {
7843 tcg_gen_shli_i32(tmp, tmp, shift);
7845 sh = (insn >> 16) & 0x1f;
7846 tmp2 = tcg_const_i32(sh);
7847 if (insn & (1 << 22))
7848 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7849 else
7850 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7851 tcg_temp_free_i32(tmp2);
7852 store_reg(s, rd, tmp);
7853 } else if ((insn & 0x00300fe0) == 0x00200f20) {
7854 /* [us]sat16 */
7855 tmp = load_reg(s, rm);
7856 sh = (insn >> 16) & 0x1f;
7857 tmp2 = tcg_const_i32(sh);
7858 if (insn & (1 << 22))
7859 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7860 else
7861 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7862 tcg_temp_free_i32(tmp2);
7863 store_reg(s, rd, tmp);
7864 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7865 /* Select bytes. */
7866 tmp = load_reg(s, rn);
7867 tmp2 = load_reg(s, rm);
7868 tmp3 = tcg_temp_new_i32();
7869 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7870 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7871 tcg_temp_free_i32(tmp3);
7872 tcg_temp_free_i32(tmp2);
7873 store_reg(s, rd, tmp);
7874 } else if ((insn & 0x000003e0) == 0x00000060) {
7875 tmp = load_reg(s, rm);
7876 shift = (insn >> 10) & 3;
7877 /* ??? In many cases it's not necessary to do a
7878 rotate, a shift is sufficient. */
7879 if (shift != 0)
7880 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7881 op1 = (insn >> 20) & 7;
7882 switch (op1) {
7883 case 0: gen_sxtb16(tmp); break;
7884 case 2: gen_sxtb(tmp); break;
7885 case 3: gen_sxth(tmp); break;
7886 case 4: gen_uxtb16(tmp); break;
7887 case 6: gen_uxtb(tmp); break;
7888 case 7: gen_uxth(tmp); break;
7889 default: goto illegal_op;
7891 if (rn != 15) {
7892 tmp2 = load_reg(s, rn);
7893 if ((op1 & 3) == 0) {
7894 gen_add16(tmp, tmp2);
7895 } else {
7896 tcg_gen_add_i32(tmp, tmp, tmp2);
7897 tcg_temp_free_i32(tmp2);
7900 store_reg(s, rd, tmp);
7901 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7902 /* rev */
7903 tmp = load_reg(s, rm);
7904 if (insn & (1 << 22)) {
7905 if (insn & (1 << 7)) {
7906 gen_revsh(tmp);
7907 } else {
7908 ARCH(6T2);
7909 gen_helper_rbit(tmp, tmp);
7911 } else {
7912 if (insn & (1 << 7))
7913 gen_rev16(tmp);
7914 else
7915 tcg_gen_bswap32_i32(tmp, tmp);
7917 store_reg(s, rd, tmp);
7918 } else {
7919 goto illegal_op;
7921 break;
7922 case 2: /* Multiplies (Type 3). */
7923 switch ((insn >> 20) & 0x7) {
7924 case 5:
7925 if (((insn >> 6) ^ (insn >> 7)) & 1) {
7926 /* op2 not 00x or 11x : UNDEF */
7927 goto illegal_op;
7929 /* Signed multiply most significant [accumulate].
7930 (SMMUL, SMMLA, SMMLS) */
7931 tmp = load_reg(s, rm);
7932 tmp2 = load_reg(s, rs);
7933 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7935 if (rd != 15) {
7936 tmp = load_reg(s, rd);
7937 if (insn & (1 << 6)) {
7938 tmp64 = gen_subq_msw(tmp64, tmp);
7939 } else {
7940 tmp64 = gen_addq_msw(tmp64, tmp);
7943 if (insn & (1 << 5)) {
7944 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7946 tcg_gen_shri_i64(tmp64, tmp64, 32);
7947 tmp = tcg_temp_new_i32();
7948 tcg_gen_trunc_i64_i32(tmp, tmp64);
7949 tcg_temp_free_i64(tmp64);
7950 store_reg(s, rn, tmp);
7951 break;
7952 case 0:
7953 case 4:
7954 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7955 if (insn & (1 << 7)) {
7956 goto illegal_op;
7958 tmp = load_reg(s, rm);
7959 tmp2 = load_reg(s, rs);
7960 if (insn & (1 << 5))
7961 gen_swap_half(tmp2);
7962 gen_smul_dual(tmp, tmp2);
7963 if (insn & (1 << 6)) {
7964 /* This subtraction cannot overflow. */
7965 tcg_gen_sub_i32(tmp, tmp, tmp2);
7966 } else {
7967 /* This addition cannot overflow 32 bits;
7968 * however it may overflow considered as a signed
7969 * operation, in which case we must set the Q flag.
7971 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7973 tcg_temp_free_i32(tmp2);
7974 if (insn & (1 << 22)) {
7975 /* smlald, smlsld */
7976 tmp64 = tcg_temp_new_i64();
7977 tcg_gen_ext_i32_i64(tmp64, tmp);
7978 tcg_temp_free_i32(tmp);
7979 gen_addq(s, tmp64, rd, rn);
7980 gen_storeq_reg(s, rd, rn, tmp64);
7981 tcg_temp_free_i64(tmp64);
7982 } else {
7983 /* smuad, smusd, smlad, smlsd */
7984 if (rd != 15)
7986 tmp2 = load_reg(s, rd);
7987 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7988 tcg_temp_free_i32(tmp2);
7990 store_reg(s, rn, tmp);
7992 break;
7993 case 1:
7994 case 3:
7995 /* SDIV, UDIV */
7996 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7997 goto illegal_op;
7999 if (((insn >> 5) & 7) || (rd != 15)) {
8000 goto illegal_op;
8002 tmp = load_reg(s, rm);
8003 tmp2 = load_reg(s, rs);
8004 if (insn & (1 << 21)) {
8005 gen_helper_udiv(tmp, tmp, tmp2);
8006 } else {
8007 gen_helper_sdiv(tmp, tmp, tmp2);
8009 tcg_temp_free_i32(tmp2);
8010 store_reg(s, rn, tmp);
8011 break;
8012 default:
8013 goto illegal_op;
8015 break;
8016 case 3:
8017 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8018 switch (op1) {
8019 case 0: /* Unsigned sum of absolute differences. */
8020 ARCH(6);
8021 tmp = load_reg(s, rm);
8022 tmp2 = load_reg(s, rs);
8023 gen_helper_usad8(tmp, tmp, tmp2);
8024 tcg_temp_free_i32(tmp2);
8025 if (rd != 15) {
8026 tmp2 = load_reg(s, rd);
8027 tcg_gen_add_i32(tmp, tmp, tmp2);
8028 tcg_temp_free_i32(tmp2);
8030 store_reg(s, rn, tmp);
8031 break;
8032 case 0x20: case 0x24: case 0x28: case 0x2c:
8033 /* Bitfield insert/clear. */
8034 ARCH(6T2);
8035 shift = (insn >> 7) & 0x1f;
8036 i = (insn >> 16) & 0x1f;
8037 i = i + 1 - shift;
8038 if (rm == 15) {
8039 tmp = tcg_temp_new_i32();
8040 tcg_gen_movi_i32(tmp, 0);
8041 } else {
8042 tmp = load_reg(s, rm);
8044 if (i != 32) {
8045 tmp2 = load_reg(s, rd);
8046 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8047 tcg_temp_free_i32(tmp2);
8049 store_reg(s, rd, tmp);
8050 break;
8051 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8052 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8053 ARCH(6T2);
8054 tmp = load_reg(s, rm);
8055 shift = (insn >> 7) & 0x1f;
8056 i = ((insn >> 16) & 0x1f) + 1;
8057 if (shift + i > 32)
8058 goto illegal_op;
8059 if (i < 32) {
8060 if (op1 & 0x20) {
8061 gen_ubfx(tmp, shift, (1u << i) - 1);
8062 } else {
8063 gen_sbfx(tmp, shift, i);
8066 store_reg(s, rd, tmp);
8067 break;
8068 default:
8069 goto illegal_op;
8071 break;
8073 break;
8075 do_ldst:
8076 /* Check for undefined extension instructions
8077 * per the ARM Bible IE:
8078 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8080 sh = (0xf << 20) | (0xf << 4);
8081 if (op1 == 0x7 && ((insn & sh) == sh))
8083 goto illegal_op;
8085 /* load/store byte/word */
8086 rn = (insn >> 16) & 0xf;
8087 rd = (insn >> 12) & 0xf;
8088 tmp2 = load_reg(s, rn);
8089 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8090 if (insn & (1 << 24))
8091 gen_add_data_offset(s, insn, tmp2);
8092 if (insn & (1 << 20)) {
8093 /* load */
8094 tmp = tcg_temp_new_i32();
8095 if (insn & (1 << 22)) {
8096 gen_aa32_ld8u(tmp, tmp2, i);
8097 } else {
8098 gen_aa32_ld32u(tmp, tmp2, i);
8100 } else {
8101 /* store */
8102 tmp = load_reg(s, rd);
8103 if (insn & (1 << 22)) {
8104 gen_aa32_st8(tmp, tmp2, i);
8105 } else {
8106 gen_aa32_st32(tmp, tmp2, i);
8108 tcg_temp_free_i32(tmp);
8110 if (!(insn & (1 << 24))) {
8111 gen_add_data_offset(s, insn, tmp2);
8112 store_reg(s, rn, tmp2);
8113 } else if (insn & (1 << 21)) {
8114 store_reg(s, rn, tmp2);
8115 } else {
8116 tcg_temp_free_i32(tmp2);
8118 if (insn & (1 << 20)) {
8119 /* Complete the load. */
8120 store_reg_from_load(env, s, rd, tmp);
8122 break;
8123 case 0x08:
8124 case 0x09:
8126 int j, n, user, loaded_base;
8127 TCGv_i32 loaded_var;
8128 /* load/store multiple words */
8129 /* XXX: store correct base if write back */
8130 user = 0;
8131 if (insn & (1 << 22)) {
8132 if (IS_USER(s))
8133 goto illegal_op; /* only usable in supervisor mode */
8135 if ((insn & (1 << 15)) == 0)
8136 user = 1;
8138 rn = (insn >> 16) & 0xf;
8139 addr = load_reg(s, rn);
8141 /* compute total size */
8142 loaded_base = 0;
8143 TCGV_UNUSED_I32(loaded_var);
8144 n = 0;
8145 for(i=0;i<16;i++) {
8146 if (insn & (1 << i))
8147 n++;
8149 /* XXX: test invalid n == 0 case ? */
8150 if (insn & (1 << 23)) {
8151 if (insn & (1 << 24)) {
8152 /* pre increment */
8153 tcg_gen_addi_i32(addr, addr, 4);
8154 } else {
8155 /* post increment */
8157 } else {
8158 if (insn & (1 << 24)) {
8159 /* pre decrement */
8160 tcg_gen_addi_i32(addr, addr, -(n * 4));
8161 } else {
8162 /* post decrement */
8163 if (n != 1)
8164 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8167 j = 0;
8168 for(i=0;i<16;i++) {
8169 if (insn & (1 << i)) {
8170 if (insn & (1 << 20)) {
8171 /* load */
8172 tmp = tcg_temp_new_i32();
8173 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8174 if (user) {
8175 tmp2 = tcg_const_i32(i);
8176 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8177 tcg_temp_free_i32(tmp2);
8178 tcg_temp_free_i32(tmp);
8179 } else if (i == rn) {
8180 loaded_var = tmp;
8181 loaded_base = 1;
8182 } else {
8183 store_reg_from_load(env, s, i, tmp);
8185 } else {
8186 /* store */
8187 if (i == 15) {
8188 /* special case: r15 = PC + 8 */
8189 val = (long)s->pc + 4;
8190 tmp = tcg_temp_new_i32();
8191 tcg_gen_movi_i32(tmp, val);
8192 } else if (user) {
8193 tmp = tcg_temp_new_i32();
8194 tmp2 = tcg_const_i32(i);
8195 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8196 tcg_temp_free_i32(tmp2);
8197 } else {
8198 tmp = load_reg(s, i);
8200 gen_aa32_st32(tmp, addr, IS_USER(s));
8201 tcg_temp_free_i32(tmp);
8203 j++;
8204 /* no need to add after the last transfer */
8205 if (j != n)
8206 tcg_gen_addi_i32(addr, addr, 4);
8209 if (insn & (1 << 21)) {
8210 /* write back */
8211 if (insn & (1 << 23)) {
8212 if (insn & (1 << 24)) {
8213 /* pre increment */
8214 } else {
8215 /* post increment */
8216 tcg_gen_addi_i32(addr, addr, 4);
8218 } else {
8219 if (insn & (1 << 24)) {
8220 /* pre decrement */
8221 if (n != 1)
8222 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8223 } else {
8224 /* post decrement */
8225 tcg_gen_addi_i32(addr, addr, -(n * 4));
8228 store_reg(s, rn, addr);
8229 } else {
8230 tcg_temp_free_i32(addr);
8232 if (loaded_base) {
8233 store_reg(s, rn, loaded_var);
8235 if ((insn & (1 << 22)) && !user) {
8236 /* Restore CPSR from SPSR. */
8237 tmp = load_cpu_field(spsr);
8238 gen_set_cpsr(tmp, 0xffffffff);
8239 tcg_temp_free_i32(tmp);
8240 s->is_jmp = DISAS_UPDATE;
8243 break;
8244 case 0xa:
8245 case 0xb:
8247 int32_t offset;
8249 /* branch (and link) */
8250 val = (int32_t)s->pc;
8251 if (insn & (1 << 24)) {
8252 tmp = tcg_temp_new_i32();
8253 tcg_gen_movi_i32(tmp, val);
8254 store_reg(s, 14, tmp);
8256 offset = sextract32(insn << 2, 0, 26);
8257 val += offset + 4;
8258 gen_jmp(s, val);
8260 break;
8261 case 0xc:
8262 case 0xd:
8263 case 0xe:
8264 if (((insn >> 8) & 0xe) == 10) {
8265 /* VFP. */
8266 if (disas_vfp_insn(env, s, insn)) {
8267 goto illegal_op;
8269 } else if (disas_coproc_insn(env, s, insn)) {
8270 /* Coprocessor. */
8271 goto illegal_op;
8273 break;
8274 case 0xf:
8275 /* swi */
8276 gen_set_pc_im(s, s->pc);
8277 s->is_jmp = DISAS_SWI;
8278 break;
8279 default:
8280 illegal_op:
8281 gen_exception_insn(s, 4, EXCP_UDEF);
8282 break;
8287 /* Return true if this is a Thumb-2 logical op. */
8288 static int
8289 thumb2_logic_op(int op)
8291 return (op < 8);
8294 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8295 then set condition code flags based on the result of the operation.
8296 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8297 to the high bit of T1.
8298 Returns zero if the opcode is valid. */
8300 static int
8301 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8302 TCGv_i32 t0, TCGv_i32 t1)
8304 int logic_cc;
8306 logic_cc = 0;
8307 switch (op) {
8308 case 0: /* and */
8309 tcg_gen_and_i32(t0, t0, t1);
8310 logic_cc = conds;
8311 break;
8312 case 1: /* bic */
8313 tcg_gen_andc_i32(t0, t0, t1);
8314 logic_cc = conds;
8315 break;
8316 case 2: /* orr */
8317 tcg_gen_or_i32(t0, t0, t1);
8318 logic_cc = conds;
8319 break;
8320 case 3: /* orn */
8321 tcg_gen_orc_i32(t0, t0, t1);
8322 logic_cc = conds;
8323 break;
8324 case 4: /* eor */
8325 tcg_gen_xor_i32(t0, t0, t1);
8326 logic_cc = conds;
8327 break;
8328 case 8: /* add */
8329 if (conds)
8330 gen_add_CC(t0, t0, t1);
8331 else
8332 tcg_gen_add_i32(t0, t0, t1);
8333 break;
8334 case 10: /* adc */
8335 if (conds)
8336 gen_adc_CC(t0, t0, t1);
8337 else
8338 gen_adc(t0, t1);
8339 break;
8340 case 11: /* sbc */
8341 if (conds) {
8342 gen_sbc_CC(t0, t0, t1);
8343 } else {
8344 gen_sub_carry(t0, t0, t1);
8346 break;
8347 case 13: /* sub */
8348 if (conds)
8349 gen_sub_CC(t0, t0, t1);
8350 else
8351 tcg_gen_sub_i32(t0, t0, t1);
8352 break;
8353 case 14: /* rsb */
8354 if (conds)
8355 gen_sub_CC(t0, t1, t0);
8356 else
8357 tcg_gen_sub_i32(t0, t1, t0);
8358 break;
8359 default: /* 5, 6, 7, 9, 12, 15. */
8360 return 1;
8362 if (logic_cc) {
8363 gen_logic_CC(t0);
8364 if (shifter_out)
8365 gen_set_CF_bit31(t1);
8367 return 0;
8370 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8371 is not legal. */
8372 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8374 uint32_t insn, imm, shift, offset;
8375 uint32_t rd, rn, rm, rs;
8376 TCGv_i32 tmp;
8377 TCGv_i32 tmp2;
8378 TCGv_i32 tmp3;
8379 TCGv_i32 addr;
8380 TCGv_i64 tmp64;
8381 int op;
8382 int shiftop;
8383 int conds;
8384 int logic_cc;
8386 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8387 || arm_feature (env, ARM_FEATURE_M))) {
8388 /* Thumb-1 cores may need to treat bl and blx as a pair of
8389 16-bit instructions to get correct prefetch abort behavior. */
8390 insn = insn_hw1;
8391 if ((insn & (1 << 12)) == 0) {
8392 ARCH(5);
8393 /* Second half of blx. */
8394 offset = ((insn & 0x7ff) << 1);
8395 tmp = load_reg(s, 14);
8396 tcg_gen_addi_i32(tmp, tmp, offset);
8397 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8399 tmp2 = tcg_temp_new_i32();
8400 tcg_gen_movi_i32(tmp2, s->pc | 1);
8401 store_reg(s, 14, tmp2);
8402 gen_bx(s, tmp);
8403 return 0;
8405 if (insn & (1 << 11)) {
8406 /* Second half of bl. */
8407 offset = ((insn & 0x7ff) << 1) | 1;
8408 tmp = load_reg(s, 14);
8409 tcg_gen_addi_i32(tmp, tmp, offset);
8411 tmp2 = tcg_temp_new_i32();
8412 tcg_gen_movi_i32(tmp2, s->pc | 1);
8413 store_reg(s, 14, tmp2);
8414 gen_bx(s, tmp);
8415 return 0;
8417 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8418 /* Instruction spans a page boundary. Implement it as two
8419 16-bit instructions in case the second half causes an
8420 prefetch abort. */
8421 offset = ((int32_t)insn << 21) >> 9;
8422 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8423 return 0;
8425 /* Fall through to 32-bit decode. */
8428 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8429 s->pc += 2;
8430 insn |= (uint32_t)insn_hw1 << 16;
8432 if ((insn & 0xf800e800) != 0xf000e800) {
8433 ARCH(6T2);
8436 rn = (insn >> 16) & 0xf;
8437 rs = (insn >> 12) & 0xf;
8438 rd = (insn >> 8) & 0xf;
8439 rm = insn & 0xf;
8440 switch ((insn >> 25) & 0xf) {
8441 case 0: case 1: case 2: case 3:
8442 /* 16-bit instructions. Should never happen. */
8443 abort();
8444 case 4:
8445 if (insn & (1 << 22)) {
8446 /* Other load/store, table branch. */
8447 if (insn & 0x01200000) {
8448 /* Load/store doubleword. */
8449 if (rn == 15) {
8450 addr = tcg_temp_new_i32();
8451 tcg_gen_movi_i32(addr, s->pc & ~3);
8452 } else {
8453 addr = load_reg(s, rn);
8455 offset = (insn & 0xff) * 4;
8456 if ((insn & (1 << 23)) == 0)
8457 offset = -offset;
8458 if (insn & (1 << 24)) {
8459 tcg_gen_addi_i32(addr, addr, offset);
8460 offset = 0;
8462 if (insn & (1 << 20)) {
8463 /* ldrd */
8464 tmp = tcg_temp_new_i32();
8465 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8466 store_reg(s, rs, tmp);
8467 tcg_gen_addi_i32(addr, addr, 4);
8468 tmp = tcg_temp_new_i32();
8469 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8470 store_reg(s, rd, tmp);
8471 } else {
8472 /* strd */
8473 tmp = load_reg(s, rs);
8474 gen_aa32_st32(tmp, addr, IS_USER(s));
8475 tcg_temp_free_i32(tmp);
8476 tcg_gen_addi_i32(addr, addr, 4);
8477 tmp = load_reg(s, rd);
8478 gen_aa32_st32(tmp, addr, IS_USER(s));
8479 tcg_temp_free_i32(tmp);
8481 if (insn & (1 << 21)) {
8482 /* Base writeback. */
8483 if (rn == 15)
8484 goto illegal_op;
8485 tcg_gen_addi_i32(addr, addr, offset - 4);
8486 store_reg(s, rn, addr);
8487 } else {
8488 tcg_temp_free_i32(addr);
8490 } else if ((insn & (1 << 23)) == 0) {
8491 /* Load/store exclusive word. */
8492 addr = tcg_temp_local_new_i32();
8493 load_reg_var(s, addr, rn);
8494 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8495 if (insn & (1 << 20)) {
8496 gen_load_exclusive(s, rs, 15, addr, 2);
8497 } else {
8498 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8500 tcg_temp_free_i32(addr);
8501 } else if ((insn & (7 << 5)) == 0) {
8502 /* Table Branch. */
8503 if (rn == 15) {
8504 addr = tcg_temp_new_i32();
8505 tcg_gen_movi_i32(addr, s->pc);
8506 } else {
8507 addr = load_reg(s, rn);
8509 tmp = load_reg(s, rm);
8510 tcg_gen_add_i32(addr, addr, tmp);
8511 if (insn & (1 << 4)) {
8512 /* tbh */
8513 tcg_gen_add_i32(addr, addr, tmp);
8514 tcg_temp_free_i32(tmp);
8515 tmp = tcg_temp_new_i32();
8516 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8517 } else { /* tbb */
8518 tcg_temp_free_i32(tmp);
8519 tmp = tcg_temp_new_i32();
8520 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8522 tcg_temp_free_i32(addr);
8523 tcg_gen_shli_i32(tmp, tmp, 1);
8524 tcg_gen_addi_i32(tmp, tmp, s->pc);
8525 store_reg(s, 15, tmp);
8526 } else {
8527 int op2 = (insn >> 6) & 0x3;
8528 op = (insn >> 4) & 0x3;
8529 switch (op2) {
8530 case 0:
8531 goto illegal_op;
8532 case 1:
8533 /* Load/store exclusive byte/halfword/doubleword */
8534 if (op == 2) {
8535 goto illegal_op;
8537 ARCH(7);
8538 break;
8539 case 2:
8540 /* Load-acquire/store-release */
8541 if (op == 3) {
8542 goto illegal_op;
8544 /* Fall through */
8545 case 3:
8546 /* Load-acquire/store-release exclusive */
8547 ARCH(8);
8548 break;
8550 addr = tcg_temp_local_new_i32();
8551 load_reg_var(s, addr, rn);
8552 if (!(op2 & 1)) {
8553 if (insn & (1 << 20)) {
8554 tmp = tcg_temp_new_i32();
8555 switch (op) {
8556 case 0: /* ldab */
8557 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8558 break;
8559 case 1: /* ldah */
8560 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8561 break;
8562 case 2: /* lda */
8563 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8564 break;
8565 default:
8566 abort();
8568 store_reg(s, rs, tmp);
8569 } else {
8570 tmp = load_reg(s, rs);
8571 switch (op) {
8572 case 0: /* stlb */
8573 gen_aa32_st8(tmp, addr, IS_USER(s));
8574 break;
8575 case 1: /* stlh */
8576 gen_aa32_st16(tmp, addr, IS_USER(s));
8577 break;
8578 case 2: /* stl */
8579 gen_aa32_st32(tmp, addr, IS_USER(s));
8580 break;
8581 default:
8582 abort();
8584 tcg_temp_free_i32(tmp);
8586 } else if (insn & (1 << 20)) {
8587 gen_load_exclusive(s, rs, rd, addr, op);
8588 } else {
8589 gen_store_exclusive(s, rm, rs, rd, addr, op);
8591 tcg_temp_free_i32(addr);
8593 } else {
8594 /* Load/store multiple, RFE, SRS. */
8595 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8596 /* RFE, SRS: not available in user mode or on M profile */
8597 if (IS_USER(s) || IS_M(env)) {
8598 goto illegal_op;
8600 if (insn & (1 << 20)) {
8601 /* rfe */
8602 addr = load_reg(s, rn);
8603 if ((insn & (1 << 24)) == 0)
8604 tcg_gen_addi_i32(addr, addr, -8);
8605 /* Load PC into tmp and CPSR into tmp2. */
8606 tmp = tcg_temp_new_i32();
8607 gen_aa32_ld32u(tmp, addr, 0);
8608 tcg_gen_addi_i32(addr, addr, 4);
8609 tmp2 = tcg_temp_new_i32();
8610 gen_aa32_ld32u(tmp2, addr, 0);
8611 if (insn & (1 << 21)) {
8612 /* Base writeback. */
8613 if (insn & (1 << 24)) {
8614 tcg_gen_addi_i32(addr, addr, 4);
8615 } else {
8616 tcg_gen_addi_i32(addr, addr, -4);
8618 store_reg(s, rn, addr);
8619 } else {
8620 tcg_temp_free_i32(addr);
8622 gen_rfe(s, tmp, tmp2);
8623 } else {
8624 /* srs */
8625 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8626 insn & (1 << 21));
8628 } else {
8629 int i, loaded_base = 0;
8630 TCGv_i32 loaded_var;
8631 /* Load/store multiple. */
8632 addr = load_reg(s, rn);
8633 offset = 0;
8634 for (i = 0; i < 16; i++) {
8635 if (insn & (1 << i))
8636 offset += 4;
8638 if (insn & (1 << 24)) {
8639 tcg_gen_addi_i32(addr, addr, -offset);
8642 TCGV_UNUSED_I32(loaded_var);
8643 for (i = 0; i < 16; i++) {
8644 if ((insn & (1 << i)) == 0)
8645 continue;
8646 if (insn & (1 << 20)) {
8647 /* Load. */
8648 tmp = tcg_temp_new_i32();
8649 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8650 if (i == 15) {
8651 gen_bx(s, tmp);
8652 } else if (i == rn) {
8653 loaded_var = tmp;
8654 loaded_base = 1;
8655 } else {
8656 store_reg(s, i, tmp);
8658 } else {
8659 /* Store. */
8660 tmp = load_reg(s, i);
8661 gen_aa32_st32(tmp, addr, IS_USER(s));
8662 tcg_temp_free_i32(tmp);
8664 tcg_gen_addi_i32(addr, addr, 4);
8666 if (loaded_base) {
8667 store_reg(s, rn, loaded_var);
8669 if (insn & (1 << 21)) {
8670 /* Base register writeback. */
8671 if (insn & (1 << 24)) {
8672 tcg_gen_addi_i32(addr, addr, -offset);
8674 /* Fault if writeback register is in register list. */
8675 if (insn & (1 << rn))
8676 goto illegal_op;
8677 store_reg(s, rn, addr);
8678 } else {
8679 tcg_temp_free_i32(addr);
8683 break;
8684 case 5:
8686 op = (insn >> 21) & 0xf;
8687 if (op == 6) {
8688 /* Halfword pack. */
8689 tmp = load_reg(s, rn);
8690 tmp2 = load_reg(s, rm);
8691 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8692 if (insn & (1 << 5)) {
8693 /* pkhtb */
8694 if (shift == 0)
8695 shift = 31;
8696 tcg_gen_sari_i32(tmp2, tmp2, shift);
8697 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8698 tcg_gen_ext16u_i32(tmp2, tmp2);
8699 } else {
8700 /* pkhbt */
8701 if (shift)
8702 tcg_gen_shli_i32(tmp2, tmp2, shift);
8703 tcg_gen_ext16u_i32(tmp, tmp);
8704 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8706 tcg_gen_or_i32(tmp, tmp, tmp2);
8707 tcg_temp_free_i32(tmp2);
8708 store_reg(s, rd, tmp);
8709 } else {
8710 /* Data processing register constant shift. */
8711 if (rn == 15) {
8712 tmp = tcg_temp_new_i32();
8713 tcg_gen_movi_i32(tmp, 0);
8714 } else {
8715 tmp = load_reg(s, rn);
8717 tmp2 = load_reg(s, rm);
8719 shiftop = (insn >> 4) & 3;
8720 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8721 conds = (insn & (1 << 20)) != 0;
8722 logic_cc = (conds && thumb2_logic_op(op));
8723 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8724 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8725 goto illegal_op;
8726 tcg_temp_free_i32(tmp2);
8727 if (rd != 15) {
8728 store_reg(s, rd, tmp);
8729 } else {
8730 tcg_temp_free_i32(tmp);
8733 break;
8734 case 13: /* Misc data processing. */
8735 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8736 if (op < 4 && (insn & 0xf000) != 0xf000)
8737 goto illegal_op;
8738 switch (op) {
8739 case 0: /* Register controlled shift. */
8740 tmp = load_reg(s, rn);
8741 tmp2 = load_reg(s, rm);
8742 if ((insn & 0x70) != 0)
8743 goto illegal_op;
8744 op = (insn >> 21) & 3;
8745 logic_cc = (insn & (1 << 20)) != 0;
8746 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8747 if (logic_cc)
8748 gen_logic_CC(tmp);
8749 store_reg_bx(env, s, rd, tmp);
8750 break;
8751 case 1: /* Sign/zero extend. */
8752 tmp = load_reg(s, rm);
8753 shift = (insn >> 4) & 3;
8754 /* ??? In many cases it's not necessary to do a
8755 rotate, a shift is sufficient. */
8756 if (shift != 0)
8757 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8758 op = (insn >> 20) & 7;
8759 switch (op) {
8760 case 0: gen_sxth(tmp); break;
8761 case 1: gen_uxth(tmp); break;
8762 case 2: gen_sxtb16(tmp); break;
8763 case 3: gen_uxtb16(tmp); break;
8764 case 4: gen_sxtb(tmp); break;
8765 case 5: gen_uxtb(tmp); break;
8766 default: goto illegal_op;
8768 if (rn != 15) {
8769 tmp2 = load_reg(s, rn);
8770 if ((op >> 1) == 1) {
8771 gen_add16(tmp, tmp2);
8772 } else {
8773 tcg_gen_add_i32(tmp, tmp, tmp2);
8774 tcg_temp_free_i32(tmp2);
8777 store_reg(s, rd, tmp);
8778 break;
8779 case 2: /* SIMD add/subtract. */
8780 op = (insn >> 20) & 7;
8781 shift = (insn >> 4) & 7;
8782 if ((op & 3) == 3 || (shift & 3) == 3)
8783 goto illegal_op;
8784 tmp = load_reg(s, rn);
8785 tmp2 = load_reg(s, rm);
8786 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8787 tcg_temp_free_i32(tmp2);
8788 store_reg(s, rd, tmp);
8789 break;
8790 case 3: /* Other data processing. */
8791 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8792 if (op < 4) {
8793 /* Saturating add/subtract. */
8794 tmp = load_reg(s, rn);
8795 tmp2 = load_reg(s, rm);
8796 if (op & 1)
8797 gen_helper_double_saturate(tmp, cpu_env, tmp);
8798 if (op & 2)
8799 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8800 else
8801 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8802 tcg_temp_free_i32(tmp2);
8803 } else {
8804 tmp = load_reg(s, rn);
8805 switch (op) {
8806 case 0x0a: /* rbit */
8807 gen_helper_rbit(tmp, tmp);
8808 break;
8809 case 0x08: /* rev */
8810 tcg_gen_bswap32_i32(tmp, tmp);
8811 break;
8812 case 0x09: /* rev16 */
8813 gen_rev16(tmp);
8814 break;
8815 case 0x0b: /* revsh */
8816 gen_revsh(tmp);
8817 break;
8818 case 0x10: /* sel */
8819 tmp2 = load_reg(s, rm);
8820 tmp3 = tcg_temp_new_i32();
8821 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8822 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8823 tcg_temp_free_i32(tmp3);
8824 tcg_temp_free_i32(tmp2);
8825 break;
8826 case 0x18: /* clz */
8827 gen_helper_clz(tmp, tmp);
8828 break;
8829 default:
8830 goto illegal_op;
8833 store_reg(s, rd, tmp);
8834 break;
8835 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8836 op = (insn >> 4) & 0xf;
8837 tmp = load_reg(s, rn);
8838 tmp2 = load_reg(s, rm);
8839 switch ((insn >> 20) & 7) {
8840 case 0: /* 32 x 32 -> 32 */
8841 tcg_gen_mul_i32(tmp, tmp, tmp2);
8842 tcg_temp_free_i32(tmp2);
8843 if (rs != 15) {
8844 tmp2 = load_reg(s, rs);
8845 if (op)
8846 tcg_gen_sub_i32(tmp, tmp2, tmp);
8847 else
8848 tcg_gen_add_i32(tmp, tmp, tmp2);
8849 tcg_temp_free_i32(tmp2);
8851 break;
8852 case 1: /* 16 x 16 -> 32 */
8853 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8854 tcg_temp_free_i32(tmp2);
8855 if (rs != 15) {
8856 tmp2 = load_reg(s, rs);
8857 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8858 tcg_temp_free_i32(tmp2);
8860 break;
8861 case 2: /* Dual multiply add. */
8862 case 4: /* Dual multiply subtract. */
8863 if (op)
8864 gen_swap_half(tmp2);
8865 gen_smul_dual(tmp, tmp2);
8866 if (insn & (1 << 22)) {
8867 /* This subtraction cannot overflow. */
8868 tcg_gen_sub_i32(tmp, tmp, tmp2);
8869 } else {
8870 /* This addition cannot overflow 32 bits;
8871 * however it may overflow considered as a signed
8872 * operation, in which case we must set the Q flag.
8874 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8876 tcg_temp_free_i32(tmp2);
8877 if (rs != 15)
8879 tmp2 = load_reg(s, rs);
8880 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8881 tcg_temp_free_i32(tmp2);
8883 break;
8884 case 3: /* 32 * 16 -> 32msb */
8885 if (op)
8886 tcg_gen_sari_i32(tmp2, tmp2, 16);
8887 else
8888 gen_sxth(tmp2);
8889 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8890 tcg_gen_shri_i64(tmp64, tmp64, 16);
8891 tmp = tcg_temp_new_i32();
8892 tcg_gen_trunc_i64_i32(tmp, tmp64);
8893 tcg_temp_free_i64(tmp64);
8894 if (rs != 15)
8896 tmp2 = load_reg(s, rs);
8897 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8898 tcg_temp_free_i32(tmp2);
8900 break;
8901 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8902 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8903 if (rs != 15) {
8904 tmp = load_reg(s, rs);
8905 if (insn & (1 << 20)) {
8906 tmp64 = gen_addq_msw(tmp64, tmp);
8907 } else {
8908 tmp64 = gen_subq_msw(tmp64, tmp);
8911 if (insn & (1 << 4)) {
8912 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8914 tcg_gen_shri_i64(tmp64, tmp64, 32);
8915 tmp = tcg_temp_new_i32();
8916 tcg_gen_trunc_i64_i32(tmp, tmp64);
8917 tcg_temp_free_i64(tmp64);
8918 break;
8919 case 7: /* Unsigned sum of absolute differences. */
8920 gen_helper_usad8(tmp, tmp, tmp2);
8921 tcg_temp_free_i32(tmp2);
8922 if (rs != 15) {
8923 tmp2 = load_reg(s, rs);
8924 tcg_gen_add_i32(tmp, tmp, tmp2);
8925 tcg_temp_free_i32(tmp2);
8927 break;
8929 store_reg(s, rd, tmp);
8930 break;
8931 case 6: case 7: /* 64-bit multiply, Divide. */
8932 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8933 tmp = load_reg(s, rn);
8934 tmp2 = load_reg(s, rm);
8935 if ((op & 0x50) == 0x10) {
8936 /* sdiv, udiv */
8937 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8938 goto illegal_op;
8940 if (op & 0x20)
8941 gen_helper_udiv(tmp, tmp, tmp2);
8942 else
8943 gen_helper_sdiv(tmp, tmp, tmp2);
8944 tcg_temp_free_i32(tmp2);
8945 store_reg(s, rd, tmp);
8946 } else if ((op & 0xe) == 0xc) {
8947 /* Dual multiply accumulate long. */
8948 if (op & 1)
8949 gen_swap_half(tmp2);
8950 gen_smul_dual(tmp, tmp2);
8951 if (op & 0x10) {
8952 tcg_gen_sub_i32(tmp, tmp, tmp2);
8953 } else {
8954 tcg_gen_add_i32(tmp, tmp, tmp2);
8956 tcg_temp_free_i32(tmp2);
8957 /* BUGFIX */
8958 tmp64 = tcg_temp_new_i64();
8959 tcg_gen_ext_i32_i64(tmp64, tmp);
8960 tcg_temp_free_i32(tmp);
8961 gen_addq(s, tmp64, rs, rd);
8962 gen_storeq_reg(s, rs, rd, tmp64);
8963 tcg_temp_free_i64(tmp64);
8964 } else {
8965 if (op & 0x20) {
8966 /* Unsigned 64-bit multiply */
8967 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8968 } else {
8969 if (op & 8) {
8970 /* smlalxy */
8971 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8972 tcg_temp_free_i32(tmp2);
8973 tmp64 = tcg_temp_new_i64();
8974 tcg_gen_ext_i32_i64(tmp64, tmp);
8975 tcg_temp_free_i32(tmp);
8976 } else {
8977 /* Signed 64-bit multiply */
8978 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8981 if (op & 4) {
8982 /* umaal */
8983 gen_addq_lo(s, tmp64, rs);
8984 gen_addq_lo(s, tmp64, rd);
8985 } else if (op & 0x40) {
8986 /* 64-bit accumulate. */
8987 gen_addq(s, tmp64, rs, rd);
8989 gen_storeq_reg(s, rs, rd, tmp64);
8990 tcg_temp_free_i64(tmp64);
8992 break;
8994 break;
8995 case 6: case 7: case 14: case 15:
8996 /* Coprocessor. */
8997 if (((insn >> 24) & 3) == 3) {
8998 /* Translate into the equivalent ARM encoding. */
8999 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9000 if (disas_neon_data_insn(env, s, insn))
9001 goto illegal_op;
9002 } else if (((insn >> 8) & 0xe) == 10) {
9003 if (disas_vfp_insn(env, s, insn)) {
9004 goto illegal_op;
9006 } else {
9007 if (insn & (1 << 28))
9008 goto illegal_op;
9009 if (disas_coproc_insn (env, s, insn))
9010 goto illegal_op;
9012 break;
9013 case 8: case 9: case 10: case 11:
9014 if (insn & (1 << 15)) {
9015 /* Branches, misc control. */
9016 if (insn & 0x5000) {
9017 /* Unconditional branch. */
9018 /* signextend(hw1[10:0]) -> offset[:12]. */
9019 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9020 /* hw1[10:0] -> offset[11:1]. */
9021 offset |= (insn & 0x7ff) << 1;
9022 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9023 offset[24:22] already have the same value because of the
9024 sign extension above. */
9025 offset ^= ((~insn) & (1 << 13)) << 10;
9026 offset ^= ((~insn) & (1 << 11)) << 11;
9028 if (insn & (1 << 14)) {
9029 /* Branch and link. */
9030 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9033 offset += s->pc;
9034 if (insn & (1 << 12)) {
9035 /* b/bl */
9036 gen_jmp(s, offset);
9037 } else {
9038 /* blx */
9039 offset &= ~(uint32_t)2;
9040 /* thumb2 bx, no need to check */
9041 gen_bx_im(s, offset);
9043 } else if (((insn >> 23) & 7) == 7) {
9044 /* Misc control */
9045 if (insn & (1 << 13))
9046 goto illegal_op;
9048 if (insn & (1 << 26)) {
9049 /* Secure monitor call (v6Z) */
9050 qemu_log_mask(LOG_UNIMP,
9051 "arm: unimplemented secure monitor call\n");
9052 goto illegal_op; /* not implemented. */
9053 } else {
9054 op = (insn >> 20) & 7;
9055 switch (op) {
9056 case 0: /* msr cpsr. */
9057 if (IS_M(env)) {
9058 tmp = load_reg(s, rn);
9059 addr = tcg_const_i32(insn & 0xff);
9060 gen_helper_v7m_msr(cpu_env, addr, tmp);
9061 tcg_temp_free_i32(addr);
9062 tcg_temp_free_i32(tmp);
9063 gen_lookup_tb(s);
9064 break;
9066 /* fall through */
9067 case 1: /* msr spsr. */
9068 if (IS_M(env))
9069 goto illegal_op;
9070 tmp = load_reg(s, rn);
9071 if (gen_set_psr(s,
9072 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9073 op == 1, tmp))
9074 goto illegal_op;
9075 break;
9076 case 2: /* cps, nop-hint. */
9077 if (((insn >> 8) & 7) == 0) {
9078 gen_nop_hint(s, insn & 0xff);
9080 /* Implemented as NOP in user mode. */
9081 if (IS_USER(s))
9082 break;
9083 offset = 0;
9084 imm = 0;
9085 if (insn & (1 << 10)) {
9086 if (insn & (1 << 7))
9087 offset |= CPSR_A;
9088 if (insn & (1 << 6))
9089 offset |= CPSR_I;
9090 if (insn & (1 << 5))
9091 offset |= CPSR_F;
9092 if (insn & (1 << 9))
9093 imm = CPSR_A | CPSR_I | CPSR_F;
9095 if (insn & (1 << 8)) {
9096 offset |= 0x1f;
9097 imm |= (insn & 0x1f);
9099 if (offset) {
9100 gen_set_psr_im(s, offset, 0, imm);
9102 break;
9103 case 3: /* Special control operations. */
9104 ARCH(7);
9105 op = (insn >> 4) & 0xf;
9106 switch (op) {
9107 case 2: /* clrex */
9108 gen_clrex(s);
9109 break;
9110 case 4: /* dsb */
9111 case 5: /* dmb */
9112 case 6: /* isb */
9113 /* These execute as NOPs. */
9114 break;
9115 default:
9116 goto illegal_op;
9118 break;
9119 case 4: /* bxj */
9120 /* Trivial implementation equivalent to bx. */
9121 tmp = load_reg(s, rn);
9122 gen_bx(s, tmp);
9123 break;
9124 case 5: /* Exception return. */
9125 if (IS_USER(s)) {
9126 goto illegal_op;
9128 if (rn != 14 || rd != 15) {
9129 goto illegal_op;
9131 tmp = load_reg(s, rn);
9132 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9133 gen_exception_return(s, tmp);
9134 break;
9135 case 6: /* mrs cpsr. */
9136 tmp = tcg_temp_new_i32();
9137 if (IS_M(env)) {
9138 addr = tcg_const_i32(insn & 0xff);
9139 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9140 tcg_temp_free_i32(addr);
9141 } else {
9142 gen_helper_cpsr_read(tmp, cpu_env);
9144 store_reg(s, rd, tmp);
9145 break;
9146 case 7: /* mrs spsr. */
9147 /* Not accessible in user mode. */
9148 if (IS_USER(s) || IS_M(env))
9149 goto illegal_op;
9150 tmp = load_cpu_field(spsr);
9151 store_reg(s, rd, tmp);
9152 break;
9155 } else {
9156 /* Conditional branch. */
9157 op = (insn >> 22) & 0xf;
9158 /* Generate a conditional jump to next instruction. */
9159 s->condlabel = gen_new_label();
9160 gen_test_cc(op ^ 1, s->condlabel);
9161 s->condjmp = 1;
9163 /* offset[11:1] = insn[10:0] */
9164 offset = (insn & 0x7ff) << 1;
9165 /* offset[17:12] = insn[21:16]. */
9166 offset |= (insn & 0x003f0000) >> 4;
9167 /* offset[31:20] = insn[26]. */
9168 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9169 /* offset[18] = insn[13]. */
9170 offset |= (insn & (1 << 13)) << 5;
9171 /* offset[19] = insn[11]. */
9172 offset |= (insn & (1 << 11)) << 8;
9174 /* jump to the offset */
9175 gen_jmp(s, s->pc + offset);
9177 } else {
9178 /* Data processing immediate. */
9179 if (insn & (1 << 25)) {
9180 if (insn & (1 << 24)) {
9181 if (insn & (1 << 20))
9182 goto illegal_op;
9183 /* Bitfield/Saturate. */
9184 op = (insn >> 21) & 7;
9185 imm = insn & 0x1f;
9186 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9187 if (rn == 15) {
9188 tmp = tcg_temp_new_i32();
9189 tcg_gen_movi_i32(tmp, 0);
9190 } else {
9191 tmp = load_reg(s, rn);
9193 switch (op) {
9194 case 2: /* Signed bitfield extract. */
9195 imm++;
9196 if (shift + imm > 32)
9197 goto illegal_op;
9198 if (imm < 32)
9199 gen_sbfx(tmp, shift, imm);
9200 break;
9201 case 6: /* Unsigned bitfield extract. */
9202 imm++;
9203 if (shift + imm > 32)
9204 goto illegal_op;
9205 if (imm < 32)
9206 gen_ubfx(tmp, shift, (1u << imm) - 1);
9207 break;
9208 case 3: /* Bitfield insert/clear. */
9209 if (imm < shift)
9210 goto illegal_op;
9211 imm = imm + 1 - shift;
9212 if (imm != 32) {
9213 tmp2 = load_reg(s, rd);
9214 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9215 tcg_temp_free_i32(tmp2);
9217 break;
9218 case 7:
9219 goto illegal_op;
9220 default: /* Saturate. */
9221 if (shift) {
9222 if (op & 1)
9223 tcg_gen_sari_i32(tmp, tmp, shift);
9224 else
9225 tcg_gen_shli_i32(tmp, tmp, shift);
9227 tmp2 = tcg_const_i32(imm);
9228 if (op & 4) {
9229 /* Unsigned. */
9230 if ((op & 1) && shift == 0)
9231 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9232 else
9233 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9234 } else {
9235 /* Signed. */
9236 if ((op & 1) && shift == 0)
9237 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9238 else
9239 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9241 tcg_temp_free_i32(tmp2);
9242 break;
9244 store_reg(s, rd, tmp);
9245 } else {
9246 imm = ((insn & 0x04000000) >> 15)
9247 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9248 if (insn & (1 << 22)) {
9249 /* 16-bit immediate. */
9250 imm |= (insn >> 4) & 0xf000;
9251 if (insn & (1 << 23)) {
9252 /* movt */
9253 tmp = load_reg(s, rd);
9254 tcg_gen_ext16u_i32(tmp, tmp);
9255 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9256 } else {
9257 /* movw */
9258 tmp = tcg_temp_new_i32();
9259 tcg_gen_movi_i32(tmp, imm);
9261 } else {
9262 /* Add/sub 12-bit immediate. */
9263 if (rn == 15) {
9264 offset = s->pc & ~(uint32_t)3;
9265 if (insn & (1 << 23))
9266 offset -= imm;
9267 else
9268 offset += imm;
9269 tmp = tcg_temp_new_i32();
9270 tcg_gen_movi_i32(tmp, offset);
9271 } else {
9272 tmp = load_reg(s, rn);
9273 if (insn & (1 << 23))
9274 tcg_gen_subi_i32(tmp, tmp, imm);
9275 else
9276 tcg_gen_addi_i32(tmp, tmp, imm);
9279 store_reg(s, rd, tmp);
9281 } else {
9282 int shifter_out = 0;
9283 /* modified 12-bit immediate. */
9284 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9285 imm = (insn & 0xff);
9286 switch (shift) {
9287 case 0: /* XY */
9288 /* Nothing to do. */
9289 break;
9290 case 1: /* 00XY00XY */
9291 imm |= imm << 16;
9292 break;
9293 case 2: /* XY00XY00 */
9294 imm |= imm << 16;
9295 imm <<= 8;
9296 break;
9297 case 3: /* XYXYXYXY */
9298 imm |= imm << 16;
9299 imm |= imm << 8;
9300 break;
9301 default: /* Rotated constant. */
9302 shift = (shift << 1) | (imm >> 7);
9303 imm |= 0x80;
9304 imm = imm << (32 - shift);
9305 shifter_out = 1;
9306 break;
9308 tmp2 = tcg_temp_new_i32();
9309 tcg_gen_movi_i32(tmp2, imm);
9310 rn = (insn >> 16) & 0xf;
9311 if (rn == 15) {
9312 tmp = tcg_temp_new_i32();
9313 tcg_gen_movi_i32(tmp, 0);
9314 } else {
9315 tmp = load_reg(s, rn);
9317 op = (insn >> 21) & 0xf;
9318 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9319 shifter_out, tmp, tmp2))
9320 goto illegal_op;
9321 tcg_temp_free_i32(tmp2);
9322 rd = (insn >> 8) & 0xf;
9323 if (rd != 15) {
9324 store_reg(s, rd, tmp);
9325 } else {
9326 tcg_temp_free_i32(tmp);
9330 break;
9331 case 12: /* Load/store single data item. */
9333 int postinc = 0;
9334 int writeback = 0;
9335 int user;
9336 if ((insn & 0x01100000) == 0x01000000) {
9337 if (disas_neon_ls_insn(env, s, insn))
9338 goto illegal_op;
9339 break;
9341 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9342 if (rs == 15) {
9343 if (!(insn & (1 << 20))) {
9344 goto illegal_op;
9346 if (op != 2) {
9347 /* Byte or halfword load space with dest == r15 : memory hints.
9348 * Catch them early so we don't emit pointless addressing code.
9349 * This space is a mix of:
9350 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9351 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9352 * cores)
9353 * unallocated hints, which must be treated as NOPs
9354 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9355 * which is easiest for the decoding logic
9356 * Some space which must UNDEF
9358 int op1 = (insn >> 23) & 3;
9359 int op2 = (insn >> 6) & 0x3f;
9360 if (op & 2) {
9361 goto illegal_op;
9363 if (rn == 15) {
9364 /* UNPREDICTABLE, unallocated hint or
9365 * PLD/PLDW/PLI (literal)
9367 return 0;
9369 if (op1 & 1) {
9370 return 0; /* PLD/PLDW/PLI or unallocated hint */
9372 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9373 return 0; /* PLD/PLDW/PLI or unallocated hint */
9375 /* UNDEF space, or an UNPREDICTABLE */
9376 return 1;
9379 user = IS_USER(s);
9380 if (rn == 15) {
9381 addr = tcg_temp_new_i32();
9382 /* PC relative. */
9383 /* s->pc has already been incremented by 4. */
9384 imm = s->pc & 0xfffffffc;
9385 if (insn & (1 << 23))
9386 imm += insn & 0xfff;
9387 else
9388 imm -= insn & 0xfff;
9389 tcg_gen_movi_i32(addr, imm);
9390 } else {
9391 addr = load_reg(s, rn);
9392 if (insn & (1 << 23)) {
9393 /* Positive offset. */
9394 imm = insn & 0xfff;
9395 tcg_gen_addi_i32(addr, addr, imm);
9396 } else {
9397 imm = insn & 0xff;
9398 switch ((insn >> 8) & 0xf) {
9399 case 0x0: /* Shifted Register. */
9400 shift = (insn >> 4) & 0xf;
9401 if (shift > 3) {
9402 tcg_temp_free_i32(addr);
9403 goto illegal_op;
9405 tmp = load_reg(s, rm);
9406 if (shift)
9407 tcg_gen_shli_i32(tmp, tmp, shift);
9408 tcg_gen_add_i32(addr, addr, tmp);
9409 tcg_temp_free_i32(tmp);
9410 break;
9411 case 0xc: /* Negative offset. */
9412 tcg_gen_addi_i32(addr, addr, -imm);
9413 break;
9414 case 0xe: /* User privilege. */
9415 tcg_gen_addi_i32(addr, addr, imm);
9416 user = 1;
9417 break;
9418 case 0x9: /* Post-decrement. */
9419 imm = -imm;
9420 /* Fall through. */
9421 case 0xb: /* Post-increment. */
9422 postinc = 1;
9423 writeback = 1;
9424 break;
9425 case 0xd: /* Pre-decrement. */
9426 imm = -imm;
9427 /* Fall through. */
9428 case 0xf: /* Pre-increment. */
9429 tcg_gen_addi_i32(addr, addr, imm);
9430 writeback = 1;
9431 break;
9432 default:
9433 tcg_temp_free_i32(addr);
9434 goto illegal_op;
9438 if (insn & (1 << 20)) {
9439 /* Load. */
9440 tmp = tcg_temp_new_i32();
9441 switch (op) {
9442 case 0:
9443 gen_aa32_ld8u(tmp, addr, user);
9444 break;
9445 case 4:
9446 gen_aa32_ld8s(tmp, addr, user);
9447 break;
9448 case 1:
9449 gen_aa32_ld16u(tmp, addr, user);
9450 break;
9451 case 5:
9452 gen_aa32_ld16s(tmp, addr, user);
9453 break;
9454 case 2:
9455 gen_aa32_ld32u(tmp, addr, user);
9456 break;
9457 default:
9458 tcg_temp_free_i32(tmp);
9459 tcg_temp_free_i32(addr);
9460 goto illegal_op;
9462 if (rs == 15) {
9463 gen_bx(s, tmp);
9464 } else {
9465 store_reg(s, rs, tmp);
9467 } else {
9468 /* Store. */
9469 tmp = load_reg(s, rs);
9470 switch (op) {
9471 case 0:
9472 gen_aa32_st8(tmp, addr, user);
9473 break;
9474 case 1:
9475 gen_aa32_st16(tmp, addr, user);
9476 break;
9477 case 2:
9478 gen_aa32_st32(tmp, addr, user);
9479 break;
9480 default:
9481 tcg_temp_free_i32(tmp);
9482 tcg_temp_free_i32(addr);
9483 goto illegal_op;
9485 tcg_temp_free_i32(tmp);
9487 if (postinc)
9488 tcg_gen_addi_i32(addr, addr, imm);
9489 if (writeback) {
9490 store_reg(s, rn, addr);
9491 } else {
9492 tcg_temp_free_i32(addr);
9495 break;
9496 default:
9497 goto illegal_op;
9499 return 0;
9500 illegal_op:
9501 return 1;
9504 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9506 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9507 int32_t offset;
9508 int i;
9509 TCGv_i32 tmp;
9510 TCGv_i32 tmp2;
9511 TCGv_i32 addr;
9513 if (s->condexec_mask) {
9514 cond = s->condexec_cond;
9515 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9516 s->condlabel = gen_new_label();
9517 gen_test_cc(cond ^ 1, s->condlabel);
9518 s->condjmp = 1;
9522 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9523 s->pc += 2;
9525 switch (insn >> 12) {
9526 case 0: case 1:
9528 rd = insn & 7;
9529 op = (insn >> 11) & 3;
9530 if (op == 3) {
9531 /* add/subtract */
9532 rn = (insn >> 3) & 7;
9533 tmp = load_reg(s, rn);
9534 if (insn & (1 << 10)) {
9535 /* immediate */
9536 tmp2 = tcg_temp_new_i32();
9537 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9538 } else {
9539 /* reg */
9540 rm = (insn >> 6) & 7;
9541 tmp2 = load_reg(s, rm);
9543 if (insn & (1 << 9)) {
9544 if (s->condexec_mask)
9545 tcg_gen_sub_i32(tmp, tmp, tmp2);
9546 else
9547 gen_sub_CC(tmp, tmp, tmp2);
9548 } else {
9549 if (s->condexec_mask)
9550 tcg_gen_add_i32(tmp, tmp, tmp2);
9551 else
9552 gen_add_CC(tmp, tmp, tmp2);
9554 tcg_temp_free_i32(tmp2);
9555 store_reg(s, rd, tmp);
9556 } else {
9557 /* shift immediate */
9558 rm = (insn >> 3) & 7;
9559 shift = (insn >> 6) & 0x1f;
9560 tmp = load_reg(s, rm);
9561 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9562 if (!s->condexec_mask)
9563 gen_logic_CC(tmp);
9564 store_reg(s, rd, tmp);
9566 break;
9567 case 2: case 3:
9568 /* arithmetic large immediate */
9569 op = (insn >> 11) & 3;
9570 rd = (insn >> 8) & 0x7;
9571 if (op == 0) { /* mov */
9572 tmp = tcg_temp_new_i32();
9573 tcg_gen_movi_i32(tmp, insn & 0xff);
9574 if (!s->condexec_mask)
9575 gen_logic_CC(tmp);
9576 store_reg(s, rd, tmp);
9577 } else {
9578 tmp = load_reg(s, rd);
9579 tmp2 = tcg_temp_new_i32();
9580 tcg_gen_movi_i32(tmp2, insn & 0xff);
9581 switch (op) {
9582 case 1: /* cmp */
9583 gen_sub_CC(tmp, tmp, tmp2);
9584 tcg_temp_free_i32(tmp);
9585 tcg_temp_free_i32(tmp2);
9586 break;
9587 case 2: /* add */
9588 if (s->condexec_mask)
9589 tcg_gen_add_i32(tmp, tmp, tmp2);
9590 else
9591 gen_add_CC(tmp, tmp, tmp2);
9592 tcg_temp_free_i32(tmp2);
9593 store_reg(s, rd, tmp);
9594 break;
9595 case 3: /* sub */
9596 if (s->condexec_mask)
9597 tcg_gen_sub_i32(tmp, tmp, tmp2);
9598 else
9599 gen_sub_CC(tmp, tmp, tmp2);
9600 tcg_temp_free_i32(tmp2);
9601 store_reg(s, rd, tmp);
9602 break;
9605 break;
9606 case 4:
9607 if (insn & (1 << 11)) {
9608 rd = (insn >> 8) & 7;
9609 /* load pc-relative. Bit 1 of PC is ignored. */
9610 val = s->pc + 2 + ((insn & 0xff) * 4);
9611 val &= ~(uint32_t)2;
9612 addr = tcg_temp_new_i32();
9613 tcg_gen_movi_i32(addr, val);
9614 tmp = tcg_temp_new_i32();
9615 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9616 tcg_temp_free_i32(addr);
9617 store_reg(s, rd, tmp);
9618 break;
9620 if (insn & (1 << 10)) {
9621 /* data processing extended or blx */
9622 rd = (insn & 7) | ((insn >> 4) & 8);
9623 rm = (insn >> 3) & 0xf;
9624 op = (insn >> 8) & 3;
9625 switch (op) {
9626 case 0: /* add */
9627 tmp = load_reg(s, rd);
9628 tmp2 = load_reg(s, rm);
9629 tcg_gen_add_i32(tmp, tmp, tmp2);
9630 tcg_temp_free_i32(tmp2);
9631 store_reg(s, rd, tmp);
9632 break;
9633 case 1: /* cmp */
9634 tmp = load_reg(s, rd);
9635 tmp2 = load_reg(s, rm);
9636 gen_sub_CC(tmp, tmp, tmp2);
9637 tcg_temp_free_i32(tmp2);
9638 tcg_temp_free_i32(tmp);
9639 break;
9640 case 2: /* mov/cpy */
9641 tmp = load_reg(s, rm);
9642 store_reg(s, rd, tmp);
9643 break;
9644 case 3:/* branch [and link] exchange thumb register */
9645 tmp = load_reg(s, rm);
9646 if (insn & (1 << 7)) {
9647 ARCH(5);
9648 val = (uint32_t)s->pc | 1;
9649 tmp2 = tcg_temp_new_i32();
9650 tcg_gen_movi_i32(tmp2, val);
9651 store_reg(s, 14, tmp2);
9653 /* already thumb, no need to check */
9654 gen_bx(s, tmp);
9655 break;
9657 break;
9660 /* data processing register */
9661 rd = insn & 7;
9662 rm = (insn >> 3) & 7;
9663 op = (insn >> 6) & 0xf;
9664 if (op == 2 || op == 3 || op == 4 || op == 7) {
9665 /* the shift/rotate ops want the operands backwards */
9666 val = rm;
9667 rm = rd;
9668 rd = val;
9669 val = 1;
9670 } else {
9671 val = 0;
9674 if (op == 9) { /* neg */
9675 tmp = tcg_temp_new_i32();
9676 tcg_gen_movi_i32(tmp, 0);
9677 } else if (op != 0xf) { /* mvn doesn't read its first operand */
9678 tmp = load_reg(s, rd);
9679 } else {
9680 TCGV_UNUSED_I32(tmp);
9683 tmp2 = load_reg(s, rm);
9684 switch (op) {
9685 case 0x0: /* and */
9686 tcg_gen_and_i32(tmp, tmp, tmp2);
9687 if (!s->condexec_mask)
9688 gen_logic_CC(tmp);
9689 break;
9690 case 0x1: /* eor */
9691 tcg_gen_xor_i32(tmp, tmp, tmp2);
9692 if (!s->condexec_mask)
9693 gen_logic_CC(tmp);
9694 break;
9695 case 0x2: /* lsl */
9696 if (s->condexec_mask) {
9697 gen_shl(tmp2, tmp2, tmp);
9698 } else {
9699 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9700 gen_logic_CC(tmp2);
9702 break;
9703 case 0x3: /* lsr */
9704 if (s->condexec_mask) {
9705 gen_shr(tmp2, tmp2, tmp);
9706 } else {
9707 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9708 gen_logic_CC(tmp2);
9710 break;
9711 case 0x4: /* asr */
9712 if (s->condexec_mask) {
9713 gen_sar(tmp2, tmp2, tmp);
9714 } else {
9715 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9716 gen_logic_CC(tmp2);
9718 break;
9719 case 0x5: /* adc */
9720 if (s->condexec_mask) {
9721 gen_adc(tmp, tmp2);
9722 } else {
9723 gen_adc_CC(tmp, tmp, tmp2);
9725 break;
9726 case 0x6: /* sbc */
9727 if (s->condexec_mask) {
9728 gen_sub_carry(tmp, tmp, tmp2);
9729 } else {
9730 gen_sbc_CC(tmp, tmp, tmp2);
9732 break;
9733 case 0x7: /* ror */
9734 if (s->condexec_mask) {
9735 tcg_gen_andi_i32(tmp, tmp, 0x1f);
9736 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9737 } else {
9738 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9739 gen_logic_CC(tmp2);
9741 break;
9742 case 0x8: /* tst */
9743 tcg_gen_and_i32(tmp, tmp, tmp2);
9744 gen_logic_CC(tmp);
9745 rd = 16;
9746 break;
9747 case 0x9: /* neg */
9748 if (s->condexec_mask)
9749 tcg_gen_neg_i32(tmp, tmp2);
9750 else
9751 gen_sub_CC(tmp, tmp, tmp2);
9752 break;
9753 case 0xa: /* cmp */
9754 gen_sub_CC(tmp, tmp, tmp2);
9755 rd = 16;
9756 break;
9757 case 0xb: /* cmn */
9758 gen_add_CC(tmp, tmp, tmp2);
9759 rd = 16;
9760 break;
9761 case 0xc: /* orr */
9762 tcg_gen_or_i32(tmp, tmp, tmp2);
9763 if (!s->condexec_mask)
9764 gen_logic_CC(tmp);
9765 break;
9766 case 0xd: /* mul */
9767 tcg_gen_mul_i32(tmp, tmp, tmp2);
9768 if (!s->condexec_mask)
9769 gen_logic_CC(tmp);
9770 break;
9771 case 0xe: /* bic */
9772 tcg_gen_andc_i32(tmp, tmp, tmp2);
9773 if (!s->condexec_mask)
9774 gen_logic_CC(tmp);
9775 break;
9776 case 0xf: /* mvn */
9777 tcg_gen_not_i32(tmp2, tmp2);
9778 if (!s->condexec_mask)
9779 gen_logic_CC(tmp2);
9780 val = 1;
9781 rm = rd;
9782 break;
9784 if (rd != 16) {
9785 if (val) {
9786 store_reg(s, rm, tmp2);
9787 if (op != 0xf)
9788 tcg_temp_free_i32(tmp);
9789 } else {
9790 store_reg(s, rd, tmp);
9791 tcg_temp_free_i32(tmp2);
9793 } else {
9794 tcg_temp_free_i32(tmp);
9795 tcg_temp_free_i32(tmp2);
9797 break;
9799 case 5:
9800 /* load/store register offset. */
9801 rd = insn & 7;
9802 rn = (insn >> 3) & 7;
9803 rm = (insn >> 6) & 7;
9804 op = (insn >> 9) & 7;
9805 addr = load_reg(s, rn);
9806 tmp = load_reg(s, rm);
9807 tcg_gen_add_i32(addr, addr, tmp);
9808 tcg_temp_free_i32(tmp);
9810 if (op < 3) { /* store */
9811 tmp = load_reg(s, rd);
9812 } else {
9813 tmp = tcg_temp_new_i32();
9816 switch (op) {
9817 case 0: /* str */
9818 gen_aa32_st32(tmp, addr, IS_USER(s));
9819 break;
9820 case 1: /* strh */
9821 gen_aa32_st16(tmp, addr, IS_USER(s));
9822 break;
9823 case 2: /* strb */
9824 gen_aa32_st8(tmp, addr, IS_USER(s));
9825 break;
9826 case 3: /* ldrsb */
9827 gen_aa32_ld8s(tmp, addr, IS_USER(s));
9828 break;
9829 case 4: /* ldr */
9830 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9831 break;
9832 case 5: /* ldrh */
9833 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9834 break;
9835 case 6: /* ldrb */
9836 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9837 break;
9838 case 7: /* ldrsh */
9839 gen_aa32_ld16s(tmp, addr, IS_USER(s));
9840 break;
9842 if (op >= 3) { /* load */
9843 store_reg(s, rd, tmp);
9844 } else {
9845 tcg_temp_free_i32(tmp);
9847 tcg_temp_free_i32(addr);
9848 break;
9850 case 6:
9851 /* load/store word immediate offset */
9852 rd = insn & 7;
9853 rn = (insn >> 3) & 7;
9854 addr = load_reg(s, rn);
9855 val = (insn >> 4) & 0x7c;
9856 tcg_gen_addi_i32(addr, addr, val);
9858 if (insn & (1 << 11)) {
9859 /* load */
9860 tmp = tcg_temp_new_i32();
9861 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9862 store_reg(s, rd, tmp);
9863 } else {
9864 /* store */
9865 tmp = load_reg(s, rd);
9866 gen_aa32_st32(tmp, addr, IS_USER(s));
9867 tcg_temp_free_i32(tmp);
9869 tcg_temp_free_i32(addr);
9870 break;
9872 case 7:
9873 /* load/store byte immediate offset */
9874 rd = insn & 7;
9875 rn = (insn >> 3) & 7;
9876 addr = load_reg(s, rn);
9877 val = (insn >> 6) & 0x1f;
9878 tcg_gen_addi_i32(addr, addr, val);
9880 if (insn & (1 << 11)) {
9881 /* load */
9882 tmp = tcg_temp_new_i32();
9883 gen_aa32_ld8u(tmp, addr, IS_USER(s));
9884 store_reg(s, rd, tmp);
9885 } else {
9886 /* store */
9887 tmp = load_reg(s, rd);
9888 gen_aa32_st8(tmp, addr, IS_USER(s));
9889 tcg_temp_free_i32(tmp);
9891 tcg_temp_free_i32(addr);
9892 break;
9894 case 8:
9895 /* load/store halfword immediate offset */
9896 rd = insn & 7;
9897 rn = (insn >> 3) & 7;
9898 addr = load_reg(s, rn);
9899 val = (insn >> 5) & 0x3e;
9900 tcg_gen_addi_i32(addr, addr, val);
9902 if (insn & (1 << 11)) {
9903 /* load */
9904 tmp = tcg_temp_new_i32();
9905 gen_aa32_ld16u(tmp, addr, IS_USER(s));
9906 store_reg(s, rd, tmp);
9907 } else {
9908 /* store */
9909 tmp = load_reg(s, rd);
9910 gen_aa32_st16(tmp, addr, IS_USER(s));
9911 tcg_temp_free_i32(tmp);
9913 tcg_temp_free_i32(addr);
9914 break;
9916 case 9:
9917 /* load/store from stack */
9918 rd = (insn >> 8) & 7;
9919 addr = load_reg(s, 13);
9920 val = (insn & 0xff) * 4;
9921 tcg_gen_addi_i32(addr, addr, val);
9923 if (insn & (1 << 11)) {
9924 /* load */
9925 tmp = tcg_temp_new_i32();
9926 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9927 store_reg(s, rd, tmp);
9928 } else {
9929 /* store */
9930 tmp = load_reg(s, rd);
9931 gen_aa32_st32(tmp, addr, IS_USER(s));
9932 tcg_temp_free_i32(tmp);
9934 tcg_temp_free_i32(addr);
9935 break;
9937 case 10:
9938 /* add to high reg */
9939 rd = (insn >> 8) & 7;
9940 if (insn & (1 << 11)) {
9941 /* SP */
9942 tmp = load_reg(s, 13);
9943 } else {
9944 /* PC. bit 1 is ignored. */
9945 tmp = tcg_temp_new_i32();
9946 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9948 val = (insn & 0xff) * 4;
9949 tcg_gen_addi_i32(tmp, tmp, val);
9950 store_reg(s, rd, tmp);
9951 break;
9953 case 11:
9954 /* misc */
9955 op = (insn >> 8) & 0xf;
9956 switch (op) {
9957 case 0:
9958 /* adjust stack pointer */
9959 tmp = load_reg(s, 13);
9960 val = (insn & 0x7f) * 4;
9961 if (insn & (1 << 7))
9962 val = -(int32_t)val;
9963 tcg_gen_addi_i32(tmp, tmp, val);
9964 store_reg(s, 13, tmp);
9965 break;
9967 case 2: /* sign/zero extend. */
9968 ARCH(6);
9969 rd = insn & 7;
9970 rm = (insn >> 3) & 7;
9971 tmp = load_reg(s, rm);
9972 switch ((insn >> 6) & 3) {
9973 case 0: gen_sxth(tmp); break;
9974 case 1: gen_sxtb(tmp); break;
9975 case 2: gen_uxth(tmp); break;
9976 case 3: gen_uxtb(tmp); break;
9978 store_reg(s, rd, tmp);
9979 break;
9980 case 4: case 5: case 0xc: case 0xd:
9981 /* push/pop */
9982 addr = load_reg(s, 13);
9983 if (insn & (1 << 8))
9984 offset = 4;
9985 else
9986 offset = 0;
9987 for (i = 0; i < 8; i++) {
9988 if (insn & (1 << i))
9989 offset += 4;
9991 if ((insn & (1 << 11)) == 0) {
9992 tcg_gen_addi_i32(addr, addr, -offset);
9994 for (i = 0; i < 8; i++) {
9995 if (insn & (1 << i)) {
9996 if (insn & (1 << 11)) {
9997 /* pop */
9998 tmp = tcg_temp_new_i32();
9999 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10000 store_reg(s, i, tmp);
10001 } else {
10002 /* push */
10003 tmp = load_reg(s, i);
10004 gen_aa32_st32(tmp, addr, IS_USER(s));
10005 tcg_temp_free_i32(tmp);
10007 /* advance to the next address. */
10008 tcg_gen_addi_i32(addr, addr, 4);
10011 TCGV_UNUSED_I32(tmp);
10012 if (insn & (1 << 8)) {
10013 if (insn & (1 << 11)) {
10014 /* pop pc */
10015 tmp = tcg_temp_new_i32();
10016 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10017 /* don't set the pc until the rest of the instruction
10018 has completed */
10019 } else {
10020 /* push lr */
10021 tmp = load_reg(s, 14);
10022 gen_aa32_st32(tmp, addr, IS_USER(s));
10023 tcg_temp_free_i32(tmp);
10025 tcg_gen_addi_i32(addr, addr, 4);
10027 if ((insn & (1 << 11)) == 0) {
10028 tcg_gen_addi_i32(addr, addr, -offset);
10030 /* write back the new stack pointer */
10031 store_reg(s, 13, addr);
10032 /* set the new PC value */
10033 if ((insn & 0x0900) == 0x0900) {
10034 store_reg_from_load(env, s, 15, tmp);
10036 break;
10038 case 1: case 3: case 9: case 11: /* czb */
10039 rm = insn & 7;
10040 tmp = load_reg(s, rm);
10041 s->condlabel = gen_new_label();
10042 s->condjmp = 1;
10043 if (insn & (1 << 11))
10044 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10045 else
10046 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10047 tcg_temp_free_i32(tmp);
10048 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10049 val = (uint32_t)s->pc + 2;
10050 val += offset;
10051 gen_jmp(s, val);
10052 break;
10054 case 15: /* IT, nop-hint. */
10055 if ((insn & 0xf) == 0) {
10056 gen_nop_hint(s, (insn >> 4) & 0xf);
10057 break;
10059 /* If Then. */
10060 s->condexec_cond = (insn >> 4) & 0xe;
10061 s->condexec_mask = insn & 0x1f;
10062 /* No actual code generated for this insn, just setup state. */
10063 break;
10065 case 0xe: /* bkpt */
10066 ARCH(5);
10067 gen_exception_insn(s, 2, EXCP_BKPT);
10068 break;
10070 case 0xa: /* rev */
10071 ARCH(6);
10072 rn = (insn >> 3) & 0x7;
10073 rd = insn & 0x7;
10074 tmp = load_reg(s, rn);
10075 switch ((insn >> 6) & 3) {
10076 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10077 case 1: gen_rev16(tmp); break;
10078 case 3: gen_revsh(tmp); break;
10079 default: goto illegal_op;
10081 store_reg(s, rd, tmp);
10082 break;
10084 case 6:
10085 switch ((insn >> 5) & 7) {
10086 case 2:
10087 /* setend */
10088 ARCH(6);
10089 if (((insn >> 3) & 1) != s->bswap_code) {
10090 /* Dynamic endianness switching not implemented. */
10091 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10092 goto illegal_op;
10094 break;
10095 case 3:
10096 /* cps */
10097 ARCH(6);
10098 if (IS_USER(s)) {
10099 break;
10101 if (IS_M(env)) {
10102 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10103 /* FAULTMASK */
10104 if (insn & 1) {
10105 addr = tcg_const_i32(19);
10106 gen_helper_v7m_msr(cpu_env, addr, tmp);
10107 tcg_temp_free_i32(addr);
10109 /* PRIMASK */
10110 if (insn & 2) {
10111 addr = tcg_const_i32(16);
10112 gen_helper_v7m_msr(cpu_env, addr, tmp);
10113 tcg_temp_free_i32(addr);
10115 tcg_temp_free_i32(tmp);
10116 gen_lookup_tb(s);
10117 } else {
10118 if (insn & (1 << 4)) {
10119 shift = CPSR_A | CPSR_I | CPSR_F;
10120 } else {
10121 shift = 0;
10123 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10125 break;
10126 default:
10127 goto undef;
10129 break;
10131 default:
10132 goto undef;
10134 break;
10136 case 12:
10138 /* load/store multiple */
10139 TCGv_i32 loaded_var;
10140 TCGV_UNUSED_I32(loaded_var);
10141 rn = (insn >> 8) & 0x7;
10142 addr = load_reg(s, rn);
10143 for (i = 0; i < 8; i++) {
10144 if (insn & (1 << i)) {
10145 if (insn & (1 << 11)) {
10146 /* load */
10147 tmp = tcg_temp_new_i32();
10148 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10149 if (i == rn) {
10150 loaded_var = tmp;
10151 } else {
10152 store_reg(s, i, tmp);
10154 } else {
10155 /* store */
10156 tmp = load_reg(s, i);
10157 gen_aa32_st32(tmp, addr, IS_USER(s));
10158 tcg_temp_free_i32(tmp);
10160 /* advance to the next address */
10161 tcg_gen_addi_i32(addr, addr, 4);
10164 if ((insn & (1 << rn)) == 0) {
10165 /* base reg not in list: base register writeback */
10166 store_reg(s, rn, addr);
10167 } else {
10168 /* base reg in list: if load, complete it now */
10169 if (insn & (1 << 11)) {
10170 store_reg(s, rn, loaded_var);
10172 tcg_temp_free_i32(addr);
10174 break;
10176 case 13:
10177 /* conditional branch or swi */
10178 cond = (insn >> 8) & 0xf;
10179 if (cond == 0xe)
10180 goto undef;
10182 if (cond == 0xf) {
10183 /* swi */
10184 gen_set_pc_im(s, s->pc);
10185 s->is_jmp = DISAS_SWI;
10186 break;
10188 /* generate a conditional jump to next instruction */
10189 s->condlabel = gen_new_label();
10190 gen_test_cc(cond ^ 1, s->condlabel);
10191 s->condjmp = 1;
10193 /* jump to the offset */
10194 val = (uint32_t)s->pc + 2;
10195 offset = ((int32_t)insn << 24) >> 24;
10196 val += offset << 1;
10197 gen_jmp(s, val);
10198 break;
10200 case 14:
10201 if (insn & (1 << 11)) {
10202 if (disas_thumb2_insn(env, s, insn))
10203 goto undef32;
10204 break;
10206 /* unconditional branch */
10207 val = (uint32_t)s->pc;
10208 offset = ((int32_t)insn << 21) >> 21;
10209 val += (offset << 1) + 2;
10210 gen_jmp(s, val);
10211 break;
10213 case 15:
10214 if (disas_thumb2_insn(env, s, insn))
10215 goto undef32;
10216 break;
10218 return;
10219 undef32:
10220 gen_exception_insn(s, 4, EXCP_UDEF);
10221 return;
10222 illegal_op:
10223 undef:
10224 gen_exception_insn(s, 2, EXCP_UDEF);
10227 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10228 basic block 'tb'. If search_pc is TRUE, also generate PC
10229 information for each intermediate instruction. */
10230 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10231 TranslationBlock *tb,
10232 bool search_pc)
10234 CPUState *cs = CPU(cpu);
10235 CPUARMState *env = &cpu->env;
10236 DisasContext dc1, *dc = &dc1;
10237 CPUBreakpoint *bp;
10238 uint16_t *gen_opc_end;
10239 int j, lj;
10240 target_ulong pc_start;
10241 target_ulong next_page_start;
10242 int num_insns;
10243 int max_insns;
10245 /* generate intermediate code */
10246 pc_start = tb->pc;
10248 dc->tb = tb;
10250 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10252 dc->is_jmp = DISAS_NEXT;
10253 dc->pc = pc_start;
10254 dc->singlestep_enabled = cs->singlestep_enabled;
10255 dc->condjmp = 0;
10257 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10258 dc->aarch64 = 1;
10259 dc->thumb = 0;
10260 dc->bswap_code = 0;
10261 dc->condexec_mask = 0;
10262 dc->condexec_cond = 0;
10263 #if !defined(CONFIG_USER_ONLY)
10264 dc->user = 0;
10265 #endif
10266 dc->vfp_enabled = 0;
10267 dc->vec_len = 0;
10268 dc->vec_stride = 0;
10269 } else {
10270 dc->aarch64 = 0;
10271 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10272 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10273 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10274 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10275 #if !defined(CONFIG_USER_ONLY)
10276 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10277 #endif
10278 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10279 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10280 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10282 cpu_F0s = tcg_temp_new_i32();
10283 cpu_F1s = tcg_temp_new_i32();
10284 cpu_F0d = tcg_temp_new_i64();
10285 cpu_F1d = tcg_temp_new_i64();
10286 cpu_V0 = cpu_F0d;
10287 cpu_V1 = cpu_F1d;
10288 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10289 cpu_M0 = tcg_temp_new_i64();
10290 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10291 lj = -1;
10292 num_insns = 0;
10293 max_insns = tb->cflags & CF_COUNT_MASK;
10294 if (max_insns == 0)
10295 max_insns = CF_COUNT_MASK;
10297 gen_tb_start();
10299 tcg_clear_temp_count();
10301 /* A note on handling of the condexec (IT) bits:
10303 * We want to avoid the overhead of having to write the updated condexec
10304 * bits back to the CPUARMState for every instruction in an IT block. So:
10305 * (1) if the condexec bits are not already zero then we write
10306 * zero back into the CPUARMState now. This avoids complications trying
10307 * to do it at the end of the block. (For example if we don't do this
10308 * it's hard to identify whether we can safely skip writing condexec
10309 * at the end of the TB, which we definitely want to do for the case
10310 * where a TB doesn't do anything with the IT state at all.)
10311 * (2) if we are going to leave the TB then we call gen_set_condexec()
10312 * which will write the correct value into CPUARMState if zero is wrong.
10313 * This is done both for leaving the TB at the end, and for leaving
10314 * it because of an exception we know will happen, which is done in
10315 * gen_exception_insn(). The latter is necessary because we need to
10316 * leave the TB with the PC/IT state just prior to execution of the
10317 * instruction which caused the exception.
10318 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10319 * then the CPUARMState will be wrong and we need to reset it.
10320 * This is handled in the same way as restoration of the
10321 * PC in these situations: we will be called again with search_pc=1
10322 * and generate a mapping of the condexec bits for each PC in
10323 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10324 * this to restore the condexec bits.
10326 * Note that there are no instructions which can read the condexec
10327 * bits, and none which can write non-static values to them, so
10328 * we don't need to care about whether CPUARMState is correct in the
10329 * middle of a TB.
10332 /* Reset the conditional execution bits immediately. This avoids
10333 complications trying to do it at the end of the block. */
10334 if (dc->condexec_mask || dc->condexec_cond)
10336 TCGv_i32 tmp = tcg_temp_new_i32();
10337 tcg_gen_movi_i32(tmp, 0);
10338 store_cpu_field(tmp, condexec_bits);
10340 do {
10341 #ifdef CONFIG_USER_ONLY
10342 /* Intercept jump to the magic kernel page. */
10343 if (!dc->aarch64 && dc->pc >= 0xffff0000) {
10344 /* We always get here via a jump, so know we are not in a
10345 conditional execution block. */
10346 gen_exception(EXCP_KERNEL_TRAP);
10347 dc->is_jmp = DISAS_UPDATE;
10348 break;
10350 #else
10351 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10352 /* We always get here via a jump, so know we are not in a
10353 conditional execution block. */
10354 gen_exception(EXCP_EXCEPTION_EXIT);
10355 dc->is_jmp = DISAS_UPDATE;
10356 break;
10358 #endif
10360 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10361 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10362 if (bp->pc == dc->pc) {
10363 gen_exception_insn(dc, 0, EXCP_DEBUG);
10364 /* Advance PC so that clearing the breakpoint will
10365 invalidate this TB. */
10366 dc->pc += 2;
10367 goto done_generating;
10371 if (search_pc) {
10372 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10373 if (lj < j) {
10374 lj++;
10375 while (lj < j)
10376 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10378 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10379 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10380 tcg_ctx.gen_opc_instr_start[lj] = 1;
10381 tcg_ctx.gen_opc_icount[lj] = num_insns;
10384 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10385 gen_io_start();
10387 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10388 tcg_gen_debug_insn_start(dc->pc);
10391 if (dc->aarch64) {
10392 disas_a64_insn(env, dc);
10393 } else if (dc->thumb) {
10394 disas_thumb_insn(env, dc);
10395 if (dc->condexec_mask) {
10396 dc->condexec_cond = (dc->condexec_cond & 0xe)
10397 | ((dc->condexec_mask >> 4) & 1);
10398 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10399 if (dc->condexec_mask == 0) {
10400 dc->condexec_cond = 0;
10403 } else {
10404 disas_arm_insn(env, dc);
10407 if (dc->condjmp && !dc->is_jmp) {
10408 gen_set_label(dc->condlabel);
10409 dc->condjmp = 0;
10412 if (tcg_check_temp_count()) {
10413 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10414 dc->pc);
10417 /* Translation stops when a conditional branch is encountered.
10418 * Otherwise the subsequent code could get translated several times.
10419 * Also stop translation when a page boundary is reached. This
10420 * ensures prefetch aborts occur at the right place. */
10421 num_insns ++;
10422 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10423 !cs->singlestep_enabled &&
10424 !singlestep &&
10425 dc->pc < next_page_start &&
10426 num_insns < max_insns);
10428 if (tb->cflags & CF_LAST_IO) {
10429 if (dc->condjmp) {
10430 /* FIXME: This can theoretically happen with self-modifying
10431 code. */
10432 cpu_abort(env, "IO on conditional branch instruction");
10434 gen_io_end();
10437 /* At this stage dc->condjmp will only be set when the skipped
10438 instruction was a conditional branch or trap, and the PC has
10439 already been written. */
10440 if (unlikely(cs->singlestep_enabled)) {
10441 /* Make sure the pc is updated, and raise a debug exception. */
10442 if (dc->condjmp) {
10443 gen_set_condexec(dc);
10444 if (dc->is_jmp == DISAS_SWI) {
10445 gen_exception(EXCP_SWI);
10446 } else {
10447 gen_exception(EXCP_DEBUG);
10449 gen_set_label(dc->condlabel);
10451 if (dc->condjmp || !dc->is_jmp) {
10452 gen_set_pc_im(dc, dc->pc);
10453 dc->condjmp = 0;
10455 gen_set_condexec(dc);
10456 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10457 gen_exception(EXCP_SWI);
10458 } else {
10459 /* FIXME: Single stepping a WFI insn will not halt
10460 the CPU. */
10461 gen_exception(EXCP_DEBUG);
10463 } else {
10464 /* While branches must always occur at the end of an IT block,
10465 there are a few other things that can cause us to terminate
10466 the TB in the middle of an IT block:
10467 - Exception generating instructions (bkpt, swi, undefined).
10468 - Page boundaries.
10469 - Hardware watchpoints.
10470 Hardware breakpoints have already been handled and skip this code.
10472 gen_set_condexec(dc);
10473 switch(dc->is_jmp) {
10474 case DISAS_NEXT:
10475 gen_goto_tb(dc, 1, dc->pc);
10476 break;
10477 default:
10478 case DISAS_JUMP:
10479 case DISAS_UPDATE:
10480 /* indicate that the hash table must be used to find the next TB */
10481 tcg_gen_exit_tb(0);
10482 break;
10483 case DISAS_TB_JUMP:
10484 /* nothing more to generate */
10485 break;
10486 case DISAS_WFI:
10487 gen_helper_wfi(cpu_env);
10488 break;
10489 case DISAS_SWI:
10490 gen_exception(EXCP_SWI);
10491 break;
10493 if (dc->condjmp) {
10494 gen_set_label(dc->condlabel);
10495 gen_set_condexec(dc);
10496 gen_goto_tb(dc, 1, dc->pc);
10497 dc->condjmp = 0;
10501 done_generating:
10502 gen_tb_end(tb, num_insns);
10503 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10505 #ifdef DEBUG_DISAS
10506 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10507 qemu_log("----------------\n");
10508 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10509 log_target_disas(env, pc_start, dc->pc - pc_start,
10510 dc->thumb | (dc->bswap_code << 1));
10511 qemu_log("\n");
10513 #endif
10514 if (search_pc) {
10515 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10516 lj++;
10517 while (lj <= j)
10518 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10519 } else {
10520 tb->size = dc->pc - pc_start;
10521 tb->icount = num_insns;
10525 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10527 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10530 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10532 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10535 static const char *cpu_mode_names[16] = {
10536 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10537 "???", "???", "???", "und", "???", "???", "???", "sys"
10540 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10541 int flags)
10543 ARMCPU *cpu = ARM_CPU(cs);
10544 CPUARMState *env = &cpu->env;
10545 int i;
10546 uint32_t psr;
10548 for(i=0;i<16;i++) {
10549 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10550 if ((i % 4) == 3)
10551 cpu_fprintf(f, "\n");
10552 else
10553 cpu_fprintf(f, " ");
10555 psr = cpsr_read(env);
10556 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10557 psr,
10558 psr & (1 << 31) ? 'N' : '-',
10559 psr & (1 << 30) ? 'Z' : '-',
10560 psr & (1 << 29) ? 'C' : '-',
10561 psr & (1 << 28) ? 'V' : '-',
10562 psr & CPSR_T ? 'T' : 'A',
10563 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10565 if (flags & CPU_DUMP_FPU) {
10566 int numvfpregs = 0;
10567 if (arm_feature(env, ARM_FEATURE_VFP)) {
10568 numvfpregs += 16;
10570 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10571 numvfpregs += 16;
10573 for (i = 0; i < numvfpregs; i++) {
10574 uint64_t v = float64_val(env->vfp.regs[i]);
10575 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10576 i * 2, (uint32_t)v,
10577 i * 2 + 1, (uint32_t)(v >> 32),
10578 i, v);
10580 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10584 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10586 if (is_a64(env)) {
10587 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10588 } else {
10589 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10591 env->condexec_bits = gen_opc_condexec_bits[pc_pos];