target-arm: introduce tbflag for CPSR.E
[qemu/ar7.git] / target-arm / translate.c
blobf659254dcb907dad07609ef52e06f94d17082e44
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/>.
22 #include "qemu-common.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "tcg-op.h"
27 #include "qemu/log.h"
28 #include "qemu/bitops.h"
29 #include "arm_ldst.h"
31 #include "exec/helper-proto.h"
32 #include "exec/helper-gen.h"
34 #include "trace-tcg.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 TCGv_ptr cpu_env;
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
62 static TCGv_i32 cpu_R[16];
63 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
64 static TCGv_i64 cpu_exclusive_addr;
65 static TCGv_i64 cpu_exclusive_val;
66 #ifdef CONFIG_USER_ONLY
67 static TCGv_i64 cpu_exclusive_test;
68 static TCGv_i32 cpu_exclusive_info;
69 #endif
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s, cpu_F1s;
73 static TCGv_i64 cpu_F0d, cpu_F1d;
75 #include "exec/gen-icount.h"
77 static const char *regnames[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
84 int i;
86 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
90 offsetof(CPUARMState, regs[i]),
91 regnames[i]);
93 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
104 offsetof(CPUARMState, exclusive_test), "exclusive_test");
105 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
106 offsetof(CPUARMState, exclusive_info), "exclusive_info");
107 #endif
109 a64_translate_init();
112 static inline TCGv_i32 load_cpu_offset(int offset)
114 TCGv_i32 tmp = tcg_temp_new_i32();
115 tcg_gen_ld_i32(tmp, cpu_env, offset);
116 return tmp;
119 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
121 static inline void store_cpu_offset(TCGv_i32 var, int offset)
123 tcg_gen_st_i32(var, cpu_env, offset);
124 tcg_temp_free_i32(var);
127 #define store_cpu_field(var, name) \
128 store_cpu_offset(var, offsetof(CPUARMState, name))
130 /* Set a variable to the value of a CPU register. */
131 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
133 if (reg == 15) {
134 uint32_t addr;
135 /* normally, since we updated PC, we need only to add one insn */
136 if (s->thumb)
137 addr = (long)s->pc + 2;
138 else
139 addr = (long)s->pc + 4;
140 tcg_gen_movi_i32(var, addr);
141 } else {
142 tcg_gen_mov_i32(var, cpu_R[reg]);
146 /* Create a new temporary and set it to the value of a CPU register. */
147 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
149 TCGv_i32 tmp = tcg_temp_new_i32();
150 load_reg_var(s, tmp, reg);
151 return tmp;
154 /* Set a CPU register. The source must be a temporary and will be
155 marked as dead. */
156 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
158 if (reg == 15) {
159 tcg_gen_andi_i32(var, var, ~1);
160 s->is_jmp = DISAS_JUMP;
162 tcg_gen_mov_i32(cpu_R[reg], var);
163 tcg_temp_free_i32(var);
166 /* Value extensions. */
167 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
168 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
169 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
170 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
172 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
173 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
176 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
178 TCGv_i32 tmp_mask = tcg_const_i32(mask);
179 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
180 tcg_temp_free_i32(tmp_mask);
182 /* Set NZCV flags from the high 4 bits of var. */
183 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
185 static void gen_exception_internal(int excp)
187 TCGv_i32 tcg_excp = tcg_const_i32(excp);
189 assert(excp_is_internal(excp));
190 gen_helper_exception_internal(cpu_env, tcg_excp);
191 tcg_temp_free_i32(tcg_excp);
194 static void gen_exception(int excp, uint32_t syndrome)
196 TCGv_i32 tcg_excp = tcg_const_i32(excp);
197 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
199 gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn);
200 tcg_temp_free_i32(tcg_syn);
201 tcg_temp_free_i32(tcg_excp);
204 static void gen_ss_advance(DisasContext *s)
206 /* If the singlestep state is Active-not-pending, advance to
207 * Active-pending.
209 if (s->ss_active) {
210 s->pstate_ss = 0;
211 gen_helper_clear_pstate_ss(cpu_env);
215 static void gen_step_complete_exception(DisasContext *s)
217 /* We just completed step of an insn. Move from Active-not-pending
218 * to Active-pending, and then also take the swstep exception.
219 * This corresponds to making the (IMPDEF) choice to prioritize
220 * swstep exceptions over asynchronous exceptions taken to an exception
221 * level where debug is disabled. This choice has the advantage that
222 * we do not need to maintain internal state corresponding to the
223 * ISV/EX syndrome bits between completion of the step and generation
224 * of the exception, and our syndrome information is always correct.
226 gen_ss_advance(s);
227 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex));
228 s->is_jmp = DISAS_EXC;
231 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
233 TCGv_i32 tmp1 = tcg_temp_new_i32();
234 TCGv_i32 tmp2 = tcg_temp_new_i32();
235 tcg_gen_ext16s_i32(tmp1, a);
236 tcg_gen_ext16s_i32(tmp2, b);
237 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
238 tcg_temp_free_i32(tmp2);
239 tcg_gen_sari_i32(a, a, 16);
240 tcg_gen_sari_i32(b, b, 16);
241 tcg_gen_mul_i32(b, b, a);
242 tcg_gen_mov_i32(a, tmp1);
243 tcg_temp_free_i32(tmp1);
246 /* Byteswap each halfword. */
247 static void gen_rev16(TCGv_i32 var)
249 TCGv_i32 tmp = tcg_temp_new_i32();
250 tcg_gen_shri_i32(tmp, var, 8);
251 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
252 tcg_gen_shli_i32(var, var, 8);
253 tcg_gen_andi_i32(var, var, 0xff00ff00);
254 tcg_gen_or_i32(var, var, tmp);
255 tcg_temp_free_i32(tmp);
258 /* Byteswap low halfword and sign extend. */
259 static void gen_revsh(TCGv_i32 var)
261 tcg_gen_ext16u_i32(var, var);
262 tcg_gen_bswap16_i32(var, var);
263 tcg_gen_ext16s_i32(var, var);
266 /* Unsigned bitfield extract. */
267 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
269 if (shift)
270 tcg_gen_shri_i32(var, var, shift);
271 tcg_gen_andi_i32(var, var, mask);
274 /* Signed bitfield extract. */
275 static void gen_sbfx(TCGv_i32 var, int shift, int width)
277 uint32_t signbit;
279 if (shift)
280 tcg_gen_sari_i32(var, var, shift);
281 if (shift + width < 32) {
282 signbit = 1u << (width - 1);
283 tcg_gen_andi_i32(var, var, (1u << width) - 1);
284 tcg_gen_xori_i32(var, var, signbit);
285 tcg_gen_subi_i32(var, var, signbit);
289 /* Return (b << 32) + a. Mark inputs as dead */
290 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
292 TCGv_i64 tmp64 = tcg_temp_new_i64();
294 tcg_gen_extu_i32_i64(tmp64, b);
295 tcg_temp_free_i32(b);
296 tcg_gen_shli_i64(tmp64, tmp64, 32);
297 tcg_gen_add_i64(a, tmp64, a);
299 tcg_temp_free_i64(tmp64);
300 return a;
303 /* Return (b << 32) - a. Mark inputs as dead. */
304 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
306 TCGv_i64 tmp64 = tcg_temp_new_i64();
308 tcg_gen_extu_i32_i64(tmp64, b);
309 tcg_temp_free_i32(b);
310 tcg_gen_shli_i64(tmp64, tmp64, 32);
311 tcg_gen_sub_i64(a, tmp64, a);
313 tcg_temp_free_i64(tmp64);
314 return a;
317 /* 32x32->64 multiply. Marks inputs as dead. */
318 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
320 TCGv_i32 lo = tcg_temp_new_i32();
321 TCGv_i32 hi = tcg_temp_new_i32();
322 TCGv_i64 ret;
324 tcg_gen_mulu2_i32(lo, hi, a, b);
325 tcg_temp_free_i32(a);
326 tcg_temp_free_i32(b);
328 ret = tcg_temp_new_i64();
329 tcg_gen_concat_i32_i64(ret, lo, hi);
330 tcg_temp_free_i32(lo);
331 tcg_temp_free_i32(hi);
333 return ret;
336 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
338 TCGv_i32 lo = tcg_temp_new_i32();
339 TCGv_i32 hi = tcg_temp_new_i32();
340 TCGv_i64 ret;
342 tcg_gen_muls2_i32(lo, hi, a, b);
343 tcg_temp_free_i32(a);
344 tcg_temp_free_i32(b);
346 ret = tcg_temp_new_i64();
347 tcg_gen_concat_i32_i64(ret, lo, hi);
348 tcg_temp_free_i32(lo);
349 tcg_temp_free_i32(hi);
351 return ret;
354 /* Swap low and high halfwords. */
355 static void gen_swap_half(TCGv_i32 var)
357 TCGv_i32 tmp = tcg_temp_new_i32();
358 tcg_gen_shri_i32(tmp, var, 16);
359 tcg_gen_shli_i32(var, var, 16);
360 tcg_gen_or_i32(var, var, tmp);
361 tcg_temp_free_i32(tmp);
364 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
365 tmp = (t0 ^ t1) & 0x8000;
366 t0 &= ~0x8000;
367 t1 &= ~0x8000;
368 t0 = (t0 + t1) ^ tmp;
371 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
373 TCGv_i32 tmp = tcg_temp_new_i32();
374 tcg_gen_xor_i32(tmp, t0, t1);
375 tcg_gen_andi_i32(tmp, tmp, 0x8000);
376 tcg_gen_andi_i32(t0, t0, ~0x8000);
377 tcg_gen_andi_i32(t1, t1, ~0x8000);
378 tcg_gen_add_i32(t0, t0, t1);
379 tcg_gen_xor_i32(t0, t0, tmp);
380 tcg_temp_free_i32(tmp);
381 tcg_temp_free_i32(t1);
384 /* Set CF to the top bit of var. */
385 static void gen_set_CF_bit31(TCGv_i32 var)
387 tcg_gen_shri_i32(cpu_CF, var, 31);
390 /* Set N and Z flags from var. */
391 static inline void gen_logic_CC(TCGv_i32 var)
393 tcg_gen_mov_i32(cpu_NF, var);
394 tcg_gen_mov_i32(cpu_ZF, var);
397 /* T0 += T1 + CF. */
398 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
400 tcg_gen_add_i32(t0, t0, t1);
401 tcg_gen_add_i32(t0, t0, cpu_CF);
404 /* dest = T0 + T1 + CF. */
405 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
407 tcg_gen_add_i32(dest, t0, t1);
408 tcg_gen_add_i32(dest, dest, cpu_CF);
411 /* dest = T0 - T1 + CF - 1. */
412 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
414 tcg_gen_sub_i32(dest, t0, t1);
415 tcg_gen_add_i32(dest, dest, cpu_CF);
416 tcg_gen_subi_i32(dest, dest, 1);
419 /* dest = T0 + T1. Compute C, N, V and Z flags */
420 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
422 TCGv_i32 tmp = tcg_temp_new_i32();
423 tcg_gen_movi_i32(tmp, 0);
424 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
425 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
426 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
427 tcg_gen_xor_i32(tmp, t0, t1);
428 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
429 tcg_temp_free_i32(tmp);
430 tcg_gen_mov_i32(dest, cpu_NF);
433 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
434 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
436 TCGv_i32 tmp = tcg_temp_new_i32();
437 if (TCG_TARGET_HAS_add2_i32) {
438 tcg_gen_movi_i32(tmp, 0);
439 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
440 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
441 } else {
442 TCGv_i64 q0 = tcg_temp_new_i64();
443 TCGv_i64 q1 = tcg_temp_new_i64();
444 tcg_gen_extu_i32_i64(q0, t0);
445 tcg_gen_extu_i32_i64(q1, t1);
446 tcg_gen_add_i64(q0, q0, q1);
447 tcg_gen_extu_i32_i64(q1, cpu_CF);
448 tcg_gen_add_i64(q0, q0, q1);
449 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
450 tcg_temp_free_i64(q0);
451 tcg_temp_free_i64(q1);
453 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
454 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
455 tcg_gen_xor_i32(tmp, t0, t1);
456 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
457 tcg_temp_free_i32(tmp);
458 tcg_gen_mov_i32(dest, cpu_NF);
461 /* dest = T0 - T1. Compute C, N, V and Z flags */
462 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
464 TCGv_i32 tmp;
465 tcg_gen_sub_i32(cpu_NF, t0, t1);
466 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
467 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
468 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
469 tmp = tcg_temp_new_i32();
470 tcg_gen_xor_i32(tmp, t0, t1);
471 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
472 tcg_temp_free_i32(tmp);
473 tcg_gen_mov_i32(dest, cpu_NF);
476 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
477 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
479 TCGv_i32 tmp = tcg_temp_new_i32();
480 tcg_gen_not_i32(tmp, t1);
481 gen_adc_CC(dest, t0, tmp);
482 tcg_temp_free_i32(tmp);
485 #define GEN_SHIFT(name) \
486 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
488 TCGv_i32 tmp1, tmp2, tmp3; \
489 tmp1 = tcg_temp_new_i32(); \
490 tcg_gen_andi_i32(tmp1, t1, 0xff); \
491 tmp2 = tcg_const_i32(0); \
492 tmp3 = tcg_const_i32(0x1f); \
493 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
494 tcg_temp_free_i32(tmp3); \
495 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
496 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
497 tcg_temp_free_i32(tmp2); \
498 tcg_temp_free_i32(tmp1); \
500 GEN_SHIFT(shl)
501 GEN_SHIFT(shr)
502 #undef GEN_SHIFT
504 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
506 TCGv_i32 tmp1, tmp2;
507 tmp1 = tcg_temp_new_i32();
508 tcg_gen_andi_i32(tmp1, t1, 0xff);
509 tmp2 = tcg_const_i32(0x1f);
510 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
511 tcg_temp_free_i32(tmp2);
512 tcg_gen_sar_i32(dest, t0, tmp1);
513 tcg_temp_free_i32(tmp1);
516 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
518 TCGv_i32 c0 = tcg_const_i32(0);
519 TCGv_i32 tmp = tcg_temp_new_i32();
520 tcg_gen_neg_i32(tmp, src);
521 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
522 tcg_temp_free_i32(c0);
523 tcg_temp_free_i32(tmp);
526 static void shifter_out_im(TCGv_i32 var, int shift)
528 if (shift == 0) {
529 tcg_gen_andi_i32(cpu_CF, var, 1);
530 } else {
531 tcg_gen_shri_i32(cpu_CF, var, shift);
532 if (shift != 31) {
533 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
538 /* Shift by immediate. Includes special handling for shift == 0. */
539 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
540 int shift, int flags)
542 switch (shiftop) {
543 case 0: /* LSL */
544 if (shift != 0) {
545 if (flags)
546 shifter_out_im(var, 32 - shift);
547 tcg_gen_shli_i32(var, var, shift);
549 break;
550 case 1: /* LSR */
551 if (shift == 0) {
552 if (flags) {
553 tcg_gen_shri_i32(cpu_CF, var, 31);
555 tcg_gen_movi_i32(var, 0);
556 } else {
557 if (flags)
558 shifter_out_im(var, shift - 1);
559 tcg_gen_shri_i32(var, var, shift);
561 break;
562 case 2: /* ASR */
563 if (shift == 0)
564 shift = 32;
565 if (flags)
566 shifter_out_im(var, shift - 1);
567 if (shift == 32)
568 shift = 31;
569 tcg_gen_sari_i32(var, var, shift);
570 break;
571 case 3: /* ROR/RRX */
572 if (shift != 0) {
573 if (flags)
574 shifter_out_im(var, shift - 1);
575 tcg_gen_rotri_i32(var, var, shift); break;
576 } else {
577 TCGv_i32 tmp = tcg_temp_new_i32();
578 tcg_gen_shli_i32(tmp, cpu_CF, 31);
579 if (flags)
580 shifter_out_im(var, 0);
581 tcg_gen_shri_i32(var, var, 1);
582 tcg_gen_or_i32(var, var, tmp);
583 tcg_temp_free_i32(tmp);
588 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
589 TCGv_i32 shift, int flags)
591 if (flags) {
592 switch (shiftop) {
593 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
594 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
595 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
596 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
598 } else {
599 switch (shiftop) {
600 case 0:
601 gen_shl(var, var, shift);
602 break;
603 case 1:
604 gen_shr(var, var, shift);
605 break;
606 case 2:
607 gen_sar(var, var, shift);
608 break;
609 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
610 tcg_gen_rotr_i32(var, var, shift); break;
613 tcg_temp_free_i32(shift);
616 #define PAS_OP(pfx) \
617 switch (op2) { \
618 case 0: gen_pas_helper(glue(pfx,add16)); break; \
619 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
620 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
621 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
622 case 4: gen_pas_helper(glue(pfx,add8)); break; \
623 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
625 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
627 TCGv_ptr tmp;
629 switch (op1) {
630 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
631 case 1:
632 tmp = tcg_temp_new_ptr();
633 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
634 PAS_OP(s)
635 tcg_temp_free_ptr(tmp);
636 break;
637 case 5:
638 tmp = tcg_temp_new_ptr();
639 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
640 PAS_OP(u)
641 tcg_temp_free_ptr(tmp);
642 break;
643 #undef gen_pas_helper
644 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
645 case 2:
646 PAS_OP(q);
647 break;
648 case 3:
649 PAS_OP(sh);
650 break;
651 case 6:
652 PAS_OP(uq);
653 break;
654 case 7:
655 PAS_OP(uh);
656 break;
657 #undef gen_pas_helper
660 #undef PAS_OP
662 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
663 #define PAS_OP(pfx) \
664 switch (op1) { \
665 case 0: gen_pas_helper(glue(pfx,add8)); break; \
666 case 1: gen_pas_helper(glue(pfx,add16)); break; \
667 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
668 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
669 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
670 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
672 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
674 TCGv_ptr tmp;
676 switch (op2) {
677 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
678 case 0:
679 tmp = tcg_temp_new_ptr();
680 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
681 PAS_OP(s)
682 tcg_temp_free_ptr(tmp);
683 break;
684 case 4:
685 tmp = tcg_temp_new_ptr();
686 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
687 PAS_OP(u)
688 tcg_temp_free_ptr(tmp);
689 break;
690 #undef gen_pas_helper
691 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
692 case 1:
693 PAS_OP(q);
694 break;
695 case 2:
696 PAS_OP(sh);
697 break;
698 case 5:
699 PAS_OP(uq);
700 break;
701 case 6:
702 PAS_OP(uh);
703 break;
704 #undef gen_pas_helper
707 #undef PAS_OP
710 * generate a conditional branch based on ARM condition code cc.
711 * This is common between ARM and Aarch64 targets.
713 void arm_gen_test_cc(int cc, int label)
715 TCGv_i32 tmp;
716 int inv;
718 switch (cc) {
719 case 0: /* eq: Z */
720 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
721 break;
722 case 1: /* ne: !Z */
723 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
724 break;
725 case 2: /* cs: C */
726 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
727 break;
728 case 3: /* cc: !C */
729 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
730 break;
731 case 4: /* mi: N */
732 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
733 break;
734 case 5: /* pl: !N */
735 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
736 break;
737 case 6: /* vs: V */
738 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
739 break;
740 case 7: /* vc: !V */
741 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
742 break;
743 case 8: /* hi: C && !Z */
744 inv = gen_new_label();
745 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
746 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
747 gen_set_label(inv);
748 break;
749 case 9: /* ls: !C || Z */
750 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
751 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
752 break;
753 case 10: /* ge: N == V -> N ^ V == 0 */
754 tmp = tcg_temp_new_i32();
755 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
756 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
757 tcg_temp_free_i32(tmp);
758 break;
759 case 11: /* lt: N != V -> N ^ V != 0 */
760 tmp = tcg_temp_new_i32();
761 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
762 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
763 tcg_temp_free_i32(tmp);
764 break;
765 case 12: /* gt: !Z && N == V */
766 inv = gen_new_label();
767 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
768 tmp = tcg_temp_new_i32();
769 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
770 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
771 tcg_temp_free_i32(tmp);
772 gen_set_label(inv);
773 break;
774 case 13: /* le: Z || N != V */
775 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
776 tmp = tcg_temp_new_i32();
777 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
778 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
779 tcg_temp_free_i32(tmp);
780 break;
781 default:
782 fprintf(stderr, "Bad condition code 0x%x\n", cc);
783 abort();
787 static const uint8_t table_logic_cc[16] = {
788 1, /* and */
789 1, /* xor */
790 0, /* sub */
791 0, /* rsb */
792 0, /* add */
793 0, /* adc */
794 0, /* sbc */
795 0, /* rsc */
796 1, /* andl */
797 1, /* xorl */
798 0, /* cmp */
799 0, /* cmn */
800 1, /* orr */
801 1, /* mov */
802 1, /* bic */
803 1, /* mvn */
806 /* Set PC and Thumb state from an immediate address. */
807 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
809 TCGv_i32 tmp;
811 s->is_jmp = DISAS_UPDATE;
812 if (s->thumb != (addr & 1)) {
813 tmp = tcg_temp_new_i32();
814 tcg_gen_movi_i32(tmp, addr & 1);
815 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
816 tcg_temp_free_i32(tmp);
818 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
821 /* Set PC and Thumb state from var. var is marked as dead. */
822 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
824 s->is_jmp = DISAS_UPDATE;
825 tcg_gen_andi_i32(cpu_R[15], var, ~1);
826 tcg_gen_andi_i32(var, var, 1);
827 store_cpu_field(var, thumb);
830 /* Variant of store_reg which uses branch&exchange logic when storing
831 to r15 in ARM architecture v7 and above. The source must be a temporary
832 and will be marked as dead. */
833 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
834 int reg, TCGv_i32 var)
836 if (reg == 15 && ENABLE_ARCH_7) {
837 gen_bx(s, var);
838 } else {
839 store_reg(s, reg, var);
843 /* Variant of store_reg which uses branch&exchange logic when storing
844 * to r15 in ARM architecture v5T and above. This is used for storing
845 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
846 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
847 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
848 int reg, TCGv_i32 var)
850 if (reg == 15 && ENABLE_ARCH_5) {
851 gen_bx(s, var);
852 } else {
853 store_reg(s, reg, var);
857 /* Abstractions of "generate code to do a guest load/store for
858 * AArch32", where a vaddr is always 32 bits (and is zero
859 * extended if we're a 64 bit core) and data is also
860 * 32 bits unless specifically doing a 64 bit access.
861 * These functions work like tcg_gen_qemu_{ld,st}* except
862 * that the address argument is TCGv_i32 rather than TCGv.
864 #if TARGET_LONG_BITS == 32
866 #define DO_GEN_LD(SUFF, OPC) \
867 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
869 TCGMemOp opc = (OPC) | s->mo_endianness; \
870 tcg_gen_qemu_ld_i32(val, addr, index, opc); \
873 #define DO_GEN_ST(SUFF, OPC) \
874 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
876 TCGMemOp opc = (OPC) | s->mo_endianness; \
877 tcg_gen_qemu_st_i32(val, addr, index, opc); \
880 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
882 TCGMemOp opc = MO_Q | s->mo_endianness;
883 tcg_gen_qemu_ld_i64(val, addr, index, opc);
886 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
888 TCGMemOp opc = MO_Q | s->mo_endianness;
889 tcg_gen_qemu_st_i64(val, addr, index, opc);
892 #else
894 #define DO_GEN_LD(SUFF, OPC) \
895 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
897 TCGMemOp opc = (OPC) | s->mo_endianness; \
898 TCGv addr64 = tcg_temp_new(); \
899 tcg_gen_extu_i32_i64(addr64, addr); \
900 tcg_gen_qemu_ld_i32(val, addr64, index, opc); \
901 tcg_temp_free(addr64); \
904 #define DO_GEN_ST(SUFF, OPC) \
905 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, TCGv_i32 addr, int index) \
907 TCGMemOp opc = (OPC) | s->mo_endianness; \
908 TCGv addr64 = tcg_temp_new(); \
909 tcg_gen_extu_i32_i64(addr64, addr); \
910 tcg_gen_qemu_st_i32(val, addr64, index, opc); \
911 tcg_temp_free(addr64); \
914 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
916 TCGMemOp opc = MO_Q | s->mo_endianness;
917 TCGv addr64 = tcg_temp_new();
918 tcg_gen_extu_i32_i64(addr64, addr);
919 tcg_gen_qemu_ld_i64(val, addr64, index, opc);
920 tcg_temp_free(addr64);
923 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, TCGv_i32 addr, int index)
925 TCGMemOp opc = MO_Q | s->mo_endianness;
926 TCGv addr64 = tcg_temp_new();
927 tcg_gen_extu_i32_i64(addr64, addr);
928 tcg_gen_qemu_st_i64(val, addr64, index, opc);
929 tcg_temp_free(addr64);
932 #endif
934 DO_GEN_LD(8s, MO_SB)
935 DO_GEN_LD(8u, MO_UB)
936 DO_GEN_LD(16s, MO_SW)
937 DO_GEN_LD(16u, MO_UW)
938 DO_GEN_LD(32u, MO_UL)
939 DO_GEN_ST(8, MO_UB)
940 DO_GEN_ST(16, MO_UW)
941 DO_GEN_ST(32, MO_UL)
943 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
945 tcg_gen_movi_i32(cpu_R[15], val);
948 static inline void gen_hvc(DisasContext *s, int imm16)
950 /* The pre HVC helper handles cases when HVC gets trapped
951 * as an undefined insn by runtime configuration (ie before
952 * the insn really executes).
954 gen_set_pc_im(s, s->pc - 4);
955 gen_helper_pre_hvc(cpu_env);
956 /* Otherwise we will treat this as a real exception which
957 * happens after execution of the insn. (The distinction matters
958 * for the PC value reported to the exception handler and also
959 * for single stepping.)
961 s->svc_imm = imm16;
962 gen_set_pc_im(s, s->pc);
963 s->is_jmp = DISAS_HVC;
966 static inline void gen_smc(DisasContext *s)
968 /* As with HVC, we may take an exception either before or after
969 * the insn executes.
971 TCGv_i32 tmp;
973 gen_set_pc_im(s, s->pc - 4);
974 tmp = tcg_const_i32(syn_aa32_smc());
975 gen_helper_pre_smc(cpu_env, tmp);
976 tcg_temp_free_i32(tmp);
977 gen_set_pc_im(s, s->pc);
978 s->is_jmp = DISAS_SMC;
981 static inline void
982 gen_set_condexec (DisasContext *s)
984 if (s->condexec_mask) {
985 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
986 TCGv_i32 tmp = tcg_temp_new_i32();
987 tcg_gen_movi_i32(tmp, val);
988 store_cpu_field(tmp, condexec_bits);
992 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
994 gen_set_condexec(s);
995 gen_set_pc_im(s, s->pc - offset);
996 gen_exception_internal(excp);
997 s->is_jmp = DISAS_JUMP;
1000 static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn)
1002 gen_set_condexec(s);
1003 gen_set_pc_im(s, s->pc - offset);
1004 gen_exception(excp, syn);
1005 s->is_jmp = DISAS_JUMP;
1008 /* Force a TB lookup after an instruction that changes the CPU state. */
1009 static inline void gen_lookup_tb(DisasContext *s)
1011 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1012 s->is_jmp = DISAS_UPDATE;
1015 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1016 TCGv_i32 var)
1018 int val, rm, shift, shiftop;
1019 TCGv_i32 offset;
1021 if (!(insn & (1 << 25))) {
1022 /* immediate */
1023 val = insn & 0xfff;
1024 if (!(insn & (1 << 23)))
1025 val = -val;
1026 if (val != 0)
1027 tcg_gen_addi_i32(var, var, val);
1028 } else {
1029 /* shift/register */
1030 rm = (insn) & 0xf;
1031 shift = (insn >> 7) & 0x1f;
1032 shiftop = (insn >> 5) & 3;
1033 offset = load_reg(s, rm);
1034 gen_arm_shift_im(offset, shiftop, shift, 0);
1035 if (!(insn & (1 << 23)))
1036 tcg_gen_sub_i32(var, var, offset);
1037 else
1038 tcg_gen_add_i32(var, var, offset);
1039 tcg_temp_free_i32(offset);
1043 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1044 int extra, TCGv_i32 var)
1046 int val, rm;
1047 TCGv_i32 offset;
1049 if (insn & (1 << 22)) {
1050 /* immediate */
1051 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1052 if (!(insn & (1 << 23)))
1053 val = -val;
1054 val += extra;
1055 if (val != 0)
1056 tcg_gen_addi_i32(var, var, val);
1057 } else {
1058 /* register */
1059 if (extra)
1060 tcg_gen_addi_i32(var, var, extra);
1061 rm = (insn) & 0xf;
1062 offset = load_reg(s, rm);
1063 if (!(insn & (1 << 23)))
1064 tcg_gen_sub_i32(var, var, offset);
1065 else
1066 tcg_gen_add_i32(var, var, offset);
1067 tcg_temp_free_i32(offset);
1071 static TCGv_ptr get_fpstatus_ptr(int neon)
1073 TCGv_ptr statusptr = tcg_temp_new_ptr();
1074 int offset;
1075 if (neon) {
1076 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1077 } else {
1078 offset = offsetof(CPUARMState, vfp.fp_status);
1080 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1081 return statusptr;
1084 #define VFP_OP2(name) \
1085 static inline void gen_vfp_##name(int dp) \
1087 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1088 if (dp) { \
1089 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1090 } else { \
1091 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1093 tcg_temp_free_ptr(fpst); \
1096 VFP_OP2(add)
1097 VFP_OP2(sub)
1098 VFP_OP2(mul)
1099 VFP_OP2(div)
1101 #undef VFP_OP2
1103 static inline void gen_vfp_F1_mul(int dp)
1105 /* Like gen_vfp_mul() but put result in F1 */
1106 TCGv_ptr fpst = get_fpstatus_ptr(0);
1107 if (dp) {
1108 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1109 } else {
1110 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1112 tcg_temp_free_ptr(fpst);
1115 static inline void gen_vfp_F1_neg(int dp)
1117 /* Like gen_vfp_neg() but put result in F1 */
1118 if (dp) {
1119 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1120 } else {
1121 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1125 static inline void gen_vfp_abs(int dp)
1127 if (dp)
1128 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1129 else
1130 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1133 static inline void gen_vfp_neg(int dp)
1135 if (dp)
1136 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1137 else
1138 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1141 static inline void gen_vfp_sqrt(int dp)
1143 if (dp)
1144 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1145 else
1146 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1149 static inline void gen_vfp_cmp(int dp)
1151 if (dp)
1152 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1153 else
1154 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1157 static inline void gen_vfp_cmpe(int dp)
1159 if (dp)
1160 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1161 else
1162 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1165 static inline void gen_vfp_F1_ld0(int dp)
1167 if (dp)
1168 tcg_gen_movi_i64(cpu_F1d, 0);
1169 else
1170 tcg_gen_movi_i32(cpu_F1s, 0);
1173 #define VFP_GEN_ITOF(name) \
1174 static inline void gen_vfp_##name(int dp, int neon) \
1176 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1177 if (dp) { \
1178 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1179 } else { \
1180 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1182 tcg_temp_free_ptr(statusptr); \
1185 VFP_GEN_ITOF(uito)
1186 VFP_GEN_ITOF(sito)
1187 #undef VFP_GEN_ITOF
1189 #define VFP_GEN_FTOI(name) \
1190 static inline void gen_vfp_##name(int dp, int neon) \
1192 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1193 if (dp) { \
1194 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1195 } else { \
1196 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1198 tcg_temp_free_ptr(statusptr); \
1201 VFP_GEN_FTOI(toui)
1202 VFP_GEN_FTOI(touiz)
1203 VFP_GEN_FTOI(tosi)
1204 VFP_GEN_FTOI(tosiz)
1205 #undef VFP_GEN_FTOI
1207 #define VFP_GEN_FIX(name, round) \
1208 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1210 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1211 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1212 if (dp) { \
1213 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1214 statusptr); \
1215 } else { \
1216 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1217 statusptr); \
1219 tcg_temp_free_i32(tmp_shift); \
1220 tcg_temp_free_ptr(statusptr); \
1222 VFP_GEN_FIX(tosh, _round_to_zero)
1223 VFP_GEN_FIX(tosl, _round_to_zero)
1224 VFP_GEN_FIX(touh, _round_to_zero)
1225 VFP_GEN_FIX(toul, _round_to_zero)
1226 VFP_GEN_FIX(shto, )
1227 VFP_GEN_FIX(slto, )
1228 VFP_GEN_FIX(uhto, )
1229 VFP_GEN_FIX(ulto, )
1230 #undef VFP_GEN_FIX
1232 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1234 if (dp) {
1235 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1236 } else {
1237 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1241 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1243 if (dp) {
1244 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1245 } else {
1246 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1250 static inline long
1251 vfp_reg_offset (int dp, int reg)
1253 if (dp)
1254 return offsetof(CPUARMState, vfp.regs[reg]);
1255 else if (reg & 1) {
1256 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1257 + offsetof(CPU_DoubleU, l.upper);
1258 } else {
1259 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1260 + offsetof(CPU_DoubleU, l.lower);
1264 /* Return the offset of a 32-bit piece of a NEON register.
1265 zero is the least significant end of the register. */
1266 static inline long
1267 neon_reg_offset (int reg, int n)
1269 int sreg;
1270 sreg = reg * 2 + n;
1271 return vfp_reg_offset(0, sreg);
1274 static TCGv_i32 neon_load_reg(int reg, int pass)
1276 TCGv_i32 tmp = tcg_temp_new_i32();
1277 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1278 return tmp;
1281 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1283 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1284 tcg_temp_free_i32(var);
1287 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1289 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1292 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1294 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1297 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1298 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1299 #define tcg_gen_st_f32 tcg_gen_st_i32
1300 #define tcg_gen_st_f64 tcg_gen_st_i64
1302 static inline void gen_mov_F0_vreg(int dp, int reg)
1304 if (dp)
1305 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1306 else
1307 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1310 static inline void gen_mov_F1_vreg(int dp, int reg)
1312 if (dp)
1313 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1314 else
1315 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1318 static inline void gen_mov_vreg_F0(int dp, int reg)
1320 if (dp)
1321 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1322 else
1323 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1326 #define ARM_CP_RW_BIT (1 << 20)
1328 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1330 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1333 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1335 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1338 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1340 TCGv_i32 var = tcg_temp_new_i32();
1341 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1342 return var;
1345 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1347 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1348 tcg_temp_free_i32(var);
1351 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1353 iwmmxt_store_reg(cpu_M0, rn);
1356 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1358 iwmmxt_load_reg(cpu_M0, rn);
1361 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1363 iwmmxt_load_reg(cpu_V1, rn);
1364 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1367 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1369 iwmmxt_load_reg(cpu_V1, rn);
1370 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1373 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1375 iwmmxt_load_reg(cpu_V1, rn);
1376 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1379 #define IWMMXT_OP(name) \
1380 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1382 iwmmxt_load_reg(cpu_V1, rn); \
1383 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1386 #define IWMMXT_OP_ENV(name) \
1387 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1389 iwmmxt_load_reg(cpu_V1, rn); \
1390 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1393 #define IWMMXT_OP_ENV_SIZE(name) \
1394 IWMMXT_OP_ENV(name##b) \
1395 IWMMXT_OP_ENV(name##w) \
1396 IWMMXT_OP_ENV(name##l)
1398 #define IWMMXT_OP_ENV1(name) \
1399 static inline void gen_op_iwmmxt_##name##_M0(void) \
1401 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1404 IWMMXT_OP(maddsq)
1405 IWMMXT_OP(madduq)
1406 IWMMXT_OP(sadb)
1407 IWMMXT_OP(sadw)
1408 IWMMXT_OP(mulslw)
1409 IWMMXT_OP(mulshw)
1410 IWMMXT_OP(mululw)
1411 IWMMXT_OP(muluhw)
1412 IWMMXT_OP(macsw)
1413 IWMMXT_OP(macuw)
1415 IWMMXT_OP_ENV_SIZE(unpackl)
1416 IWMMXT_OP_ENV_SIZE(unpackh)
1418 IWMMXT_OP_ENV1(unpacklub)
1419 IWMMXT_OP_ENV1(unpackluw)
1420 IWMMXT_OP_ENV1(unpacklul)
1421 IWMMXT_OP_ENV1(unpackhub)
1422 IWMMXT_OP_ENV1(unpackhuw)
1423 IWMMXT_OP_ENV1(unpackhul)
1424 IWMMXT_OP_ENV1(unpacklsb)
1425 IWMMXT_OP_ENV1(unpacklsw)
1426 IWMMXT_OP_ENV1(unpacklsl)
1427 IWMMXT_OP_ENV1(unpackhsb)
1428 IWMMXT_OP_ENV1(unpackhsw)
1429 IWMMXT_OP_ENV1(unpackhsl)
1431 IWMMXT_OP_ENV_SIZE(cmpeq)
1432 IWMMXT_OP_ENV_SIZE(cmpgtu)
1433 IWMMXT_OP_ENV_SIZE(cmpgts)
1435 IWMMXT_OP_ENV_SIZE(mins)
1436 IWMMXT_OP_ENV_SIZE(minu)
1437 IWMMXT_OP_ENV_SIZE(maxs)
1438 IWMMXT_OP_ENV_SIZE(maxu)
1440 IWMMXT_OP_ENV_SIZE(subn)
1441 IWMMXT_OP_ENV_SIZE(addn)
1442 IWMMXT_OP_ENV_SIZE(subu)
1443 IWMMXT_OP_ENV_SIZE(addu)
1444 IWMMXT_OP_ENV_SIZE(subs)
1445 IWMMXT_OP_ENV_SIZE(adds)
1447 IWMMXT_OP_ENV(avgb0)
1448 IWMMXT_OP_ENV(avgb1)
1449 IWMMXT_OP_ENV(avgw0)
1450 IWMMXT_OP_ENV(avgw1)
1452 IWMMXT_OP_ENV(packuw)
1453 IWMMXT_OP_ENV(packul)
1454 IWMMXT_OP_ENV(packuq)
1455 IWMMXT_OP_ENV(packsw)
1456 IWMMXT_OP_ENV(packsl)
1457 IWMMXT_OP_ENV(packsq)
1459 static void gen_op_iwmmxt_set_mup(void)
1461 TCGv_i32 tmp;
1462 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1463 tcg_gen_ori_i32(tmp, tmp, 2);
1464 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1467 static void gen_op_iwmmxt_set_cup(void)
1469 TCGv_i32 tmp;
1470 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1471 tcg_gen_ori_i32(tmp, tmp, 1);
1472 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1475 static void gen_op_iwmmxt_setpsr_nz(void)
1477 TCGv_i32 tmp = tcg_temp_new_i32();
1478 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1479 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1482 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1484 iwmmxt_load_reg(cpu_V1, rn);
1485 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1486 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1489 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1490 TCGv_i32 dest)
1492 int rd;
1493 uint32_t offset;
1494 TCGv_i32 tmp;
1496 rd = (insn >> 16) & 0xf;
1497 tmp = load_reg(s, rd);
1499 offset = (insn & 0xff) << ((insn >> 7) & 2);
1500 if (insn & (1 << 24)) {
1501 /* Pre indexed */
1502 if (insn & (1 << 23))
1503 tcg_gen_addi_i32(tmp, tmp, offset);
1504 else
1505 tcg_gen_addi_i32(tmp, tmp, -offset);
1506 tcg_gen_mov_i32(dest, tmp);
1507 if (insn & (1 << 21))
1508 store_reg(s, rd, tmp);
1509 else
1510 tcg_temp_free_i32(tmp);
1511 } else if (insn & (1 << 21)) {
1512 /* Post indexed */
1513 tcg_gen_mov_i32(dest, tmp);
1514 if (insn & (1 << 23))
1515 tcg_gen_addi_i32(tmp, tmp, offset);
1516 else
1517 tcg_gen_addi_i32(tmp, tmp, -offset);
1518 store_reg(s, rd, tmp);
1519 } else if (!(insn & (1 << 23)))
1520 return 1;
1521 return 0;
1524 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1526 int rd = (insn >> 0) & 0xf;
1527 TCGv_i32 tmp;
1529 if (insn & (1 << 8)) {
1530 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1531 return 1;
1532 } else {
1533 tmp = iwmmxt_load_creg(rd);
1535 } else {
1536 tmp = tcg_temp_new_i32();
1537 iwmmxt_load_reg(cpu_V0, rd);
1538 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1540 tcg_gen_andi_i32(tmp, tmp, mask);
1541 tcg_gen_mov_i32(dest, tmp);
1542 tcg_temp_free_i32(tmp);
1543 return 0;
1546 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1547 (ie. an undefined instruction). */
1548 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1550 int rd, wrd;
1551 int rdhi, rdlo, rd0, rd1, i;
1552 TCGv_i32 addr;
1553 TCGv_i32 tmp, tmp2, tmp3;
1555 if ((insn & 0x0e000e00) == 0x0c000000) {
1556 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1557 wrd = insn & 0xf;
1558 rdlo = (insn >> 12) & 0xf;
1559 rdhi = (insn >> 16) & 0xf;
1560 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1561 iwmmxt_load_reg(cpu_V0, wrd);
1562 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1563 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1564 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1565 } else { /* TMCRR */
1566 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1567 iwmmxt_store_reg(cpu_V0, wrd);
1568 gen_op_iwmmxt_set_mup();
1570 return 0;
1573 wrd = (insn >> 12) & 0xf;
1574 addr = tcg_temp_new_i32();
1575 if (gen_iwmmxt_address(s, insn, addr)) {
1576 tcg_temp_free_i32(addr);
1577 return 1;
1579 if (insn & ARM_CP_RW_BIT) {
1580 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1581 tmp = tcg_temp_new_i32();
1582 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1583 iwmmxt_store_creg(wrd, tmp);
1584 } else {
1585 i = 1;
1586 if (insn & (1 << 8)) {
1587 if (insn & (1 << 22)) { /* WLDRD */
1588 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1589 i = 0;
1590 } else { /* WLDRW wRd */
1591 tmp = tcg_temp_new_i32();
1592 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1594 } else {
1595 tmp = tcg_temp_new_i32();
1596 if (insn & (1 << 22)) { /* WLDRH */
1597 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1598 } else { /* WLDRB */
1599 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1602 if (i) {
1603 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1604 tcg_temp_free_i32(tmp);
1606 gen_op_iwmmxt_movq_wRn_M0(wrd);
1608 } else {
1609 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1610 tmp = iwmmxt_load_creg(wrd);
1611 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1612 } else {
1613 gen_op_iwmmxt_movq_M0_wRn(wrd);
1614 tmp = tcg_temp_new_i32();
1615 if (insn & (1 << 8)) {
1616 if (insn & (1 << 22)) { /* WSTRD */
1617 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1618 } else { /* WSTRW wRd */
1619 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1620 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1622 } else {
1623 if (insn & (1 << 22)) { /* WSTRH */
1624 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1625 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1626 } else { /* WSTRB */
1627 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1628 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1632 tcg_temp_free_i32(tmp);
1634 tcg_temp_free_i32(addr);
1635 return 0;
1638 if ((insn & 0x0f000000) != 0x0e000000)
1639 return 1;
1641 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1642 case 0x000: /* WOR */
1643 wrd = (insn >> 12) & 0xf;
1644 rd0 = (insn >> 0) & 0xf;
1645 rd1 = (insn >> 16) & 0xf;
1646 gen_op_iwmmxt_movq_M0_wRn(rd0);
1647 gen_op_iwmmxt_orq_M0_wRn(rd1);
1648 gen_op_iwmmxt_setpsr_nz();
1649 gen_op_iwmmxt_movq_wRn_M0(wrd);
1650 gen_op_iwmmxt_set_mup();
1651 gen_op_iwmmxt_set_cup();
1652 break;
1653 case 0x011: /* TMCR */
1654 if (insn & 0xf)
1655 return 1;
1656 rd = (insn >> 12) & 0xf;
1657 wrd = (insn >> 16) & 0xf;
1658 switch (wrd) {
1659 case ARM_IWMMXT_wCID:
1660 case ARM_IWMMXT_wCASF:
1661 break;
1662 case ARM_IWMMXT_wCon:
1663 gen_op_iwmmxt_set_cup();
1664 /* Fall through. */
1665 case ARM_IWMMXT_wCSSF:
1666 tmp = iwmmxt_load_creg(wrd);
1667 tmp2 = load_reg(s, rd);
1668 tcg_gen_andc_i32(tmp, tmp, tmp2);
1669 tcg_temp_free_i32(tmp2);
1670 iwmmxt_store_creg(wrd, tmp);
1671 break;
1672 case ARM_IWMMXT_wCGR0:
1673 case ARM_IWMMXT_wCGR1:
1674 case ARM_IWMMXT_wCGR2:
1675 case ARM_IWMMXT_wCGR3:
1676 gen_op_iwmmxt_set_cup();
1677 tmp = load_reg(s, rd);
1678 iwmmxt_store_creg(wrd, tmp);
1679 break;
1680 default:
1681 return 1;
1683 break;
1684 case 0x100: /* WXOR */
1685 wrd = (insn >> 12) & 0xf;
1686 rd0 = (insn >> 0) & 0xf;
1687 rd1 = (insn >> 16) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0);
1689 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1690 gen_op_iwmmxt_setpsr_nz();
1691 gen_op_iwmmxt_movq_wRn_M0(wrd);
1692 gen_op_iwmmxt_set_mup();
1693 gen_op_iwmmxt_set_cup();
1694 break;
1695 case 0x111: /* TMRC */
1696 if (insn & 0xf)
1697 return 1;
1698 rd = (insn >> 12) & 0xf;
1699 wrd = (insn >> 16) & 0xf;
1700 tmp = iwmmxt_load_creg(wrd);
1701 store_reg(s, rd, tmp);
1702 break;
1703 case 0x300: /* WANDN */
1704 wrd = (insn >> 12) & 0xf;
1705 rd0 = (insn >> 0) & 0xf;
1706 rd1 = (insn >> 16) & 0xf;
1707 gen_op_iwmmxt_movq_M0_wRn(rd0);
1708 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1709 gen_op_iwmmxt_andq_M0_wRn(rd1);
1710 gen_op_iwmmxt_setpsr_nz();
1711 gen_op_iwmmxt_movq_wRn_M0(wrd);
1712 gen_op_iwmmxt_set_mup();
1713 gen_op_iwmmxt_set_cup();
1714 break;
1715 case 0x200: /* WAND */
1716 wrd = (insn >> 12) & 0xf;
1717 rd0 = (insn >> 0) & 0xf;
1718 rd1 = (insn >> 16) & 0xf;
1719 gen_op_iwmmxt_movq_M0_wRn(rd0);
1720 gen_op_iwmmxt_andq_M0_wRn(rd1);
1721 gen_op_iwmmxt_setpsr_nz();
1722 gen_op_iwmmxt_movq_wRn_M0(wrd);
1723 gen_op_iwmmxt_set_mup();
1724 gen_op_iwmmxt_set_cup();
1725 break;
1726 case 0x810: case 0xa10: /* WMADD */
1727 wrd = (insn >> 12) & 0xf;
1728 rd0 = (insn >> 0) & 0xf;
1729 rd1 = (insn >> 16) & 0xf;
1730 gen_op_iwmmxt_movq_M0_wRn(rd0);
1731 if (insn & (1 << 21))
1732 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1733 else
1734 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1735 gen_op_iwmmxt_movq_wRn_M0(wrd);
1736 gen_op_iwmmxt_set_mup();
1737 break;
1738 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1739 wrd = (insn >> 12) & 0xf;
1740 rd0 = (insn >> 16) & 0xf;
1741 rd1 = (insn >> 0) & 0xf;
1742 gen_op_iwmmxt_movq_M0_wRn(rd0);
1743 switch ((insn >> 22) & 3) {
1744 case 0:
1745 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1746 break;
1747 case 1:
1748 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1749 break;
1750 case 2:
1751 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1752 break;
1753 case 3:
1754 return 1;
1756 gen_op_iwmmxt_movq_wRn_M0(wrd);
1757 gen_op_iwmmxt_set_mup();
1758 gen_op_iwmmxt_set_cup();
1759 break;
1760 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1761 wrd = (insn >> 12) & 0xf;
1762 rd0 = (insn >> 16) & 0xf;
1763 rd1 = (insn >> 0) & 0xf;
1764 gen_op_iwmmxt_movq_M0_wRn(rd0);
1765 switch ((insn >> 22) & 3) {
1766 case 0:
1767 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1768 break;
1769 case 1:
1770 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1771 break;
1772 case 2:
1773 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1774 break;
1775 case 3:
1776 return 1;
1778 gen_op_iwmmxt_movq_wRn_M0(wrd);
1779 gen_op_iwmmxt_set_mup();
1780 gen_op_iwmmxt_set_cup();
1781 break;
1782 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1783 wrd = (insn >> 12) & 0xf;
1784 rd0 = (insn >> 16) & 0xf;
1785 rd1 = (insn >> 0) & 0xf;
1786 gen_op_iwmmxt_movq_M0_wRn(rd0);
1787 if (insn & (1 << 22))
1788 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1789 else
1790 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1791 if (!(insn & (1 << 20)))
1792 gen_op_iwmmxt_addl_M0_wRn(wrd);
1793 gen_op_iwmmxt_movq_wRn_M0(wrd);
1794 gen_op_iwmmxt_set_mup();
1795 break;
1796 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1797 wrd = (insn >> 12) & 0xf;
1798 rd0 = (insn >> 16) & 0xf;
1799 rd1 = (insn >> 0) & 0xf;
1800 gen_op_iwmmxt_movq_M0_wRn(rd0);
1801 if (insn & (1 << 21)) {
1802 if (insn & (1 << 20))
1803 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1804 else
1805 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1806 } else {
1807 if (insn & (1 << 20))
1808 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1809 else
1810 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1812 gen_op_iwmmxt_movq_wRn_M0(wrd);
1813 gen_op_iwmmxt_set_mup();
1814 break;
1815 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1816 wrd = (insn >> 12) & 0xf;
1817 rd0 = (insn >> 16) & 0xf;
1818 rd1 = (insn >> 0) & 0xf;
1819 gen_op_iwmmxt_movq_M0_wRn(rd0);
1820 if (insn & (1 << 21))
1821 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1822 else
1823 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1824 if (!(insn & (1 << 20))) {
1825 iwmmxt_load_reg(cpu_V1, wrd);
1826 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1828 gen_op_iwmmxt_movq_wRn_M0(wrd);
1829 gen_op_iwmmxt_set_mup();
1830 break;
1831 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1832 wrd = (insn >> 12) & 0xf;
1833 rd0 = (insn >> 16) & 0xf;
1834 rd1 = (insn >> 0) & 0xf;
1835 gen_op_iwmmxt_movq_M0_wRn(rd0);
1836 switch ((insn >> 22) & 3) {
1837 case 0:
1838 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1839 break;
1840 case 1:
1841 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1842 break;
1843 case 2:
1844 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1845 break;
1846 case 3:
1847 return 1;
1849 gen_op_iwmmxt_movq_wRn_M0(wrd);
1850 gen_op_iwmmxt_set_mup();
1851 gen_op_iwmmxt_set_cup();
1852 break;
1853 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1854 wrd = (insn >> 12) & 0xf;
1855 rd0 = (insn >> 16) & 0xf;
1856 rd1 = (insn >> 0) & 0xf;
1857 gen_op_iwmmxt_movq_M0_wRn(rd0);
1858 if (insn & (1 << 22)) {
1859 if (insn & (1 << 20))
1860 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1861 else
1862 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1863 } else {
1864 if (insn & (1 << 20))
1865 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1866 else
1867 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1869 gen_op_iwmmxt_movq_wRn_M0(wrd);
1870 gen_op_iwmmxt_set_mup();
1871 gen_op_iwmmxt_set_cup();
1872 break;
1873 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1874 wrd = (insn >> 12) & 0xf;
1875 rd0 = (insn >> 16) & 0xf;
1876 rd1 = (insn >> 0) & 0xf;
1877 gen_op_iwmmxt_movq_M0_wRn(rd0);
1878 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1879 tcg_gen_andi_i32(tmp, tmp, 7);
1880 iwmmxt_load_reg(cpu_V1, rd1);
1881 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1882 tcg_temp_free_i32(tmp);
1883 gen_op_iwmmxt_movq_wRn_M0(wrd);
1884 gen_op_iwmmxt_set_mup();
1885 break;
1886 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1887 if (((insn >> 6) & 3) == 3)
1888 return 1;
1889 rd = (insn >> 12) & 0xf;
1890 wrd = (insn >> 16) & 0xf;
1891 tmp = load_reg(s, rd);
1892 gen_op_iwmmxt_movq_M0_wRn(wrd);
1893 switch ((insn >> 6) & 3) {
1894 case 0:
1895 tmp2 = tcg_const_i32(0xff);
1896 tmp3 = tcg_const_i32((insn & 7) << 3);
1897 break;
1898 case 1:
1899 tmp2 = tcg_const_i32(0xffff);
1900 tmp3 = tcg_const_i32((insn & 3) << 4);
1901 break;
1902 case 2:
1903 tmp2 = tcg_const_i32(0xffffffff);
1904 tmp3 = tcg_const_i32((insn & 1) << 5);
1905 break;
1906 default:
1907 TCGV_UNUSED_I32(tmp2);
1908 TCGV_UNUSED_I32(tmp3);
1910 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1911 tcg_temp_free_i32(tmp3);
1912 tcg_temp_free_i32(tmp2);
1913 tcg_temp_free_i32(tmp);
1914 gen_op_iwmmxt_movq_wRn_M0(wrd);
1915 gen_op_iwmmxt_set_mup();
1916 break;
1917 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1918 rd = (insn >> 12) & 0xf;
1919 wrd = (insn >> 16) & 0xf;
1920 if (rd == 15 || ((insn >> 22) & 3) == 3)
1921 return 1;
1922 gen_op_iwmmxt_movq_M0_wRn(wrd);
1923 tmp = tcg_temp_new_i32();
1924 switch ((insn >> 22) & 3) {
1925 case 0:
1926 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1927 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1928 if (insn & 8) {
1929 tcg_gen_ext8s_i32(tmp, tmp);
1930 } else {
1931 tcg_gen_andi_i32(tmp, tmp, 0xff);
1933 break;
1934 case 1:
1935 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1936 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1937 if (insn & 8) {
1938 tcg_gen_ext16s_i32(tmp, tmp);
1939 } else {
1940 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1942 break;
1943 case 2:
1944 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1945 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1946 break;
1948 store_reg(s, rd, tmp);
1949 break;
1950 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1951 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1952 return 1;
1953 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1954 switch ((insn >> 22) & 3) {
1955 case 0:
1956 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1957 break;
1958 case 1:
1959 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1960 break;
1961 case 2:
1962 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1963 break;
1965 tcg_gen_shli_i32(tmp, tmp, 28);
1966 gen_set_nzcv(tmp);
1967 tcg_temp_free_i32(tmp);
1968 break;
1969 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1970 if (((insn >> 6) & 3) == 3)
1971 return 1;
1972 rd = (insn >> 12) & 0xf;
1973 wrd = (insn >> 16) & 0xf;
1974 tmp = load_reg(s, rd);
1975 switch ((insn >> 6) & 3) {
1976 case 0:
1977 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1978 break;
1979 case 1:
1980 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1981 break;
1982 case 2:
1983 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1984 break;
1986 tcg_temp_free_i32(tmp);
1987 gen_op_iwmmxt_movq_wRn_M0(wrd);
1988 gen_op_iwmmxt_set_mup();
1989 break;
1990 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1991 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1992 return 1;
1993 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1994 tmp2 = tcg_temp_new_i32();
1995 tcg_gen_mov_i32(tmp2, tmp);
1996 switch ((insn >> 22) & 3) {
1997 case 0:
1998 for (i = 0; i < 7; i ++) {
1999 tcg_gen_shli_i32(tmp2, tmp2, 4);
2000 tcg_gen_and_i32(tmp, tmp, tmp2);
2002 break;
2003 case 1:
2004 for (i = 0; i < 3; i ++) {
2005 tcg_gen_shli_i32(tmp2, tmp2, 8);
2006 tcg_gen_and_i32(tmp, tmp, tmp2);
2008 break;
2009 case 2:
2010 tcg_gen_shli_i32(tmp2, tmp2, 16);
2011 tcg_gen_and_i32(tmp, tmp, tmp2);
2012 break;
2014 gen_set_nzcv(tmp);
2015 tcg_temp_free_i32(tmp2);
2016 tcg_temp_free_i32(tmp);
2017 break;
2018 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2019 wrd = (insn >> 12) & 0xf;
2020 rd0 = (insn >> 16) & 0xf;
2021 gen_op_iwmmxt_movq_M0_wRn(rd0);
2022 switch ((insn >> 22) & 3) {
2023 case 0:
2024 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2025 break;
2026 case 1:
2027 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2028 break;
2029 case 2:
2030 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2031 break;
2032 case 3:
2033 return 1;
2035 gen_op_iwmmxt_movq_wRn_M0(wrd);
2036 gen_op_iwmmxt_set_mup();
2037 break;
2038 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2039 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2040 return 1;
2041 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2042 tmp2 = tcg_temp_new_i32();
2043 tcg_gen_mov_i32(tmp2, tmp);
2044 switch ((insn >> 22) & 3) {
2045 case 0:
2046 for (i = 0; i < 7; i ++) {
2047 tcg_gen_shli_i32(tmp2, tmp2, 4);
2048 tcg_gen_or_i32(tmp, tmp, tmp2);
2050 break;
2051 case 1:
2052 for (i = 0; i < 3; i ++) {
2053 tcg_gen_shli_i32(tmp2, tmp2, 8);
2054 tcg_gen_or_i32(tmp, tmp, tmp2);
2056 break;
2057 case 2:
2058 tcg_gen_shli_i32(tmp2, tmp2, 16);
2059 tcg_gen_or_i32(tmp, tmp, tmp2);
2060 break;
2062 gen_set_nzcv(tmp);
2063 tcg_temp_free_i32(tmp2);
2064 tcg_temp_free_i32(tmp);
2065 break;
2066 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2067 rd = (insn >> 12) & 0xf;
2068 rd0 = (insn >> 16) & 0xf;
2069 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2070 return 1;
2071 gen_op_iwmmxt_movq_M0_wRn(rd0);
2072 tmp = tcg_temp_new_i32();
2073 switch ((insn >> 22) & 3) {
2074 case 0:
2075 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2076 break;
2077 case 1:
2078 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2079 break;
2080 case 2:
2081 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2082 break;
2084 store_reg(s, rd, tmp);
2085 break;
2086 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2087 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2088 wrd = (insn >> 12) & 0xf;
2089 rd0 = (insn >> 16) & 0xf;
2090 rd1 = (insn >> 0) & 0xf;
2091 gen_op_iwmmxt_movq_M0_wRn(rd0);
2092 switch ((insn >> 22) & 3) {
2093 case 0:
2094 if (insn & (1 << 21))
2095 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2096 else
2097 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2098 break;
2099 case 1:
2100 if (insn & (1 << 21))
2101 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2102 else
2103 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2104 break;
2105 case 2:
2106 if (insn & (1 << 21))
2107 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2108 else
2109 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2110 break;
2111 case 3:
2112 return 1;
2114 gen_op_iwmmxt_movq_wRn_M0(wrd);
2115 gen_op_iwmmxt_set_mup();
2116 gen_op_iwmmxt_set_cup();
2117 break;
2118 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2119 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2120 wrd = (insn >> 12) & 0xf;
2121 rd0 = (insn >> 16) & 0xf;
2122 gen_op_iwmmxt_movq_M0_wRn(rd0);
2123 switch ((insn >> 22) & 3) {
2124 case 0:
2125 if (insn & (1 << 21))
2126 gen_op_iwmmxt_unpacklsb_M0();
2127 else
2128 gen_op_iwmmxt_unpacklub_M0();
2129 break;
2130 case 1:
2131 if (insn & (1 << 21))
2132 gen_op_iwmmxt_unpacklsw_M0();
2133 else
2134 gen_op_iwmmxt_unpackluw_M0();
2135 break;
2136 case 2:
2137 if (insn & (1 << 21))
2138 gen_op_iwmmxt_unpacklsl_M0();
2139 else
2140 gen_op_iwmmxt_unpacklul_M0();
2141 break;
2142 case 3:
2143 return 1;
2145 gen_op_iwmmxt_movq_wRn_M0(wrd);
2146 gen_op_iwmmxt_set_mup();
2147 gen_op_iwmmxt_set_cup();
2148 break;
2149 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2150 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2151 wrd = (insn >> 12) & 0xf;
2152 rd0 = (insn >> 16) & 0xf;
2153 gen_op_iwmmxt_movq_M0_wRn(rd0);
2154 switch ((insn >> 22) & 3) {
2155 case 0:
2156 if (insn & (1 << 21))
2157 gen_op_iwmmxt_unpackhsb_M0();
2158 else
2159 gen_op_iwmmxt_unpackhub_M0();
2160 break;
2161 case 1:
2162 if (insn & (1 << 21))
2163 gen_op_iwmmxt_unpackhsw_M0();
2164 else
2165 gen_op_iwmmxt_unpackhuw_M0();
2166 break;
2167 case 2:
2168 if (insn & (1 << 21))
2169 gen_op_iwmmxt_unpackhsl_M0();
2170 else
2171 gen_op_iwmmxt_unpackhul_M0();
2172 break;
2173 case 3:
2174 return 1;
2176 gen_op_iwmmxt_movq_wRn_M0(wrd);
2177 gen_op_iwmmxt_set_mup();
2178 gen_op_iwmmxt_set_cup();
2179 break;
2180 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2181 case 0x214: case 0x614: case 0xa14: case 0xe14:
2182 if (((insn >> 22) & 3) == 0)
2183 return 1;
2184 wrd = (insn >> 12) & 0xf;
2185 rd0 = (insn >> 16) & 0xf;
2186 gen_op_iwmmxt_movq_M0_wRn(rd0);
2187 tmp = tcg_temp_new_i32();
2188 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2189 tcg_temp_free_i32(tmp);
2190 return 1;
2192 switch ((insn >> 22) & 3) {
2193 case 1:
2194 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2195 break;
2196 case 2:
2197 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2198 break;
2199 case 3:
2200 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2201 break;
2203 tcg_temp_free_i32(tmp);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd);
2205 gen_op_iwmmxt_set_mup();
2206 gen_op_iwmmxt_set_cup();
2207 break;
2208 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2209 case 0x014: case 0x414: case 0x814: case 0xc14:
2210 if (((insn >> 22) & 3) == 0)
2211 return 1;
2212 wrd = (insn >> 12) & 0xf;
2213 rd0 = (insn >> 16) & 0xf;
2214 gen_op_iwmmxt_movq_M0_wRn(rd0);
2215 tmp = tcg_temp_new_i32();
2216 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2217 tcg_temp_free_i32(tmp);
2218 return 1;
2220 switch ((insn >> 22) & 3) {
2221 case 1:
2222 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2223 break;
2224 case 2:
2225 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2226 break;
2227 case 3:
2228 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2229 break;
2231 tcg_temp_free_i32(tmp);
2232 gen_op_iwmmxt_movq_wRn_M0(wrd);
2233 gen_op_iwmmxt_set_mup();
2234 gen_op_iwmmxt_set_cup();
2235 break;
2236 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2237 case 0x114: case 0x514: case 0x914: case 0xd14:
2238 if (((insn >> 22) & 3) == 0)
2239 return 1;
2240 wrd = (insn >> 12) & 0xf;
2241 rd0 = (insn >> 16) & 0xf;
2242 gen_op_iwmmxt_movq_M0_wRn(rd0);
2243 tmp = tcg_temp_new_i32();
2244 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2245 tcg_temp_free_i32(tmp);
2246 return 1;
2248 switch ((insn >> 22) & 3) {
2249 case 1:
2250 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2251 break;
2252 case 2:
2253 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2254 break;
2255 case 3:
2256 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2257 break;
2259 tcg_temp_free_i32(tmp);
2260 gen_op_iwmmxt_movq_wRn_M0(wrd);
2261 gen_op_iwmmxt_set_mup();
2262 gen_op_iwmmxt_set_cup();
2263 break;
2264 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2265 case 0x314: case 0x714: case 0xb14: case 0xf14:
2266 if (((insn >> 22) & 3) == 0)
2267 return 1;
2268 wrd = (insn >> 12) & 0xf;
2269 rd0 = (insn >> 16) & 0xf;
2270 gen_op_iwmmxt_movq_M0_wRn(rd0);
2271 tmp = tcg_temp_new_i32();
2272 switch ((insn >> 22) & 3) {
2273 case 1:
2274 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2275 tcg_temp_free_i32(tmp);
2276 return 1;
2278 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2279 break;
2280 case 2:
2281 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2282 tcg_temp_free_i32(tmp);
2283 return 1;
2285 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2286 break;
2287 case 3:
2288 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2289 tcg_temp_free_i32(tmp);
2290 return 1;
2292 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2293 break;
2295 tcg_temp_free_i32(tmp);
2296 gen_op_iwmmxt_movq_wRn_M0(wrd);
2297 gen_op_iwmmxt_set_mup();
2298 gen_op_iwmmxt_set_cup();
2299 break;
2300 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2301 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2302 wrd = (insn >> 12) & 0xf;
2303 rd0 = (insn >> 16) & 0xf;
2304 rd1 = (insn >> 0) & 0xf;
2305 gen_op_iwmmxt_movq_M0_wRn(rd0);
2306 switch ((insn >> 22) & 3) {
2307 case 0:
2308 if (insn & (1 << 21))
2309 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2310 else
2311 gen_op_iwmmxt_minub_M0_wRn(rd1);
2312 break;
2313 case 1:
2314 if (insn & (1 << 21))
2315 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2316 else
2317 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2318 break;
2319 case 2:
2320 if (insn & (1 << 21))
2321 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2322 else
2323 gen_op_iwmmxt_minul_M0_wRn(rd1);
2324 break;
2325 case 3:
2326 return 1;
2328 gen_op_iwmmxt_movq_wRn_M0(wrd);
2329 gen_op_iwmmxt_set_mup();
2330 break;
2331 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2332 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2333 wrd = (insn >> 12) & 0xf;
2334 rd0 = (insn >> 16) & 0xf;
2335 rd1 = (insn >> 0) & 0xf;
2336 gen_op_iwmmxt_movq_M0_wRn(rd0);
2337 switch ((insn >> 22) & 3) {
2338 case 0:
2339 if (insn & (1 << 21))
2340 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2341 else
2342 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2343 break;
2344 case 1:
2345 if (insn & (1 << 21))
2346 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2347 else
2348 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2349 break;
2350 case 2:
2351 if (insn & (1 << 21))
2352 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2353 else
2354 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2355 break;
2356 case 3:
2357 return 1;
2359 gen_op_iwmmxt_movq_wRn_M0(wrd);
2360 gen_op_iwmmxt_set_mup();
2361 break;
2362 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2363 case 0x402: case 0x502: case 0x602: case 0x702:
2364 wrd = (insn >> 12) & 0xf;
2365 rd0 = (insn >> 16) & 0xf;
2366 rd1 = (insn >> 0) & 0xf;
2367 gen_op_iwmmxt_movq_M0_wRn(rd0);
2368 tmp = tcg_const_i32((insn >> 20) & 3);
2369 iwmmxt_load_reg(cpu_V1, rd1);
2370 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2371 tcg_temp_free_i32(tmp);
2372 gen_op_iwmmxt_movq_wRn_M0(wrd);
2373 gen_op_iwmmxt_set_mup();
2374 break;
2375 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2376 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2377 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2378 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2379 wrd = (insn >> 12) & 0xf;
2380 rd0 = (insn >> 16) & 0xf;
2381 rd1 = (insn >> 0) & 0xf;
2382 gen_op_iwmmxt_movq_M0_wRn(rd0);
2383 switch ((insn >> 20) & 0xf) {
2384 case 0x0:
2385 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2386 break;
2387 case 0x1:
2388 gen_op_iwmmxt_subub_M0_wRn(rd1);
2389 break;
2390 case 0x3:
2391 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2392 break;
2393 case 0x4:
2394 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2395 break;
2396 case 0x5:
2397 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2398 break;
2399 case 0x7:
2400 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2401 break;
2402 case 0x8:
2403 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2404 break;
2405 case 0x9:
2406 gen_op_iwmmxt_subul_M0_wRn(rd1);
2407 break;
2408 case 0xb:
2409 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2410 break;
2411 default:
2412 return 1;
2414 gen_op_iwmmxt_movq_wRn_M0(wrd);
2415 gen_op_iwmmxt_set_mup();
2416 gen_op_iwmmxt_set_cup();
2417 break;
2418 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2419 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2420 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2421 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2422 wrd = (insn >> 12) & 0xf;
2423 rd0 = (insn >> 16) & 0xf;
2424 gen_op_iwmmxt_movq_M0_wRn(rd0);
2425 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2426 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2427 tcg_temp_free_i32(tmp);
2428 gen_op_iwmmxt_movq_wRn_M0(wrd);
2429 gen_op_iwmmxt_set_mup();
2430 gen_op_iwmmxt_set_cup();
2431 break;
2432 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2433 case 0x418: case 0x518: case 0x618: case 0x718:
2434 case 0x818: case 0x918: case 0xa18: case 0xb18:
2435 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2436 wrd = (insn >> 12) & 0xf;
2437 rd0 = (insn >> 16) & 0xf;
2438 rd1 = (insn >> 0) & 0xf;
2439 gen_op_iwmmxt_movq_M0_wRn(rd0);
2440 switch ((insn >> 20) & 0xf) {
2441 case 0x0:
2442 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2443 break;
2444 case 0x1:
2445 gen_op_iwmmxt_addub_M0_wRn(rd1);
2446 break;
2447 case 0x3:
2448 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2449 break;
2450 case 0x4:
2451 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2452 break;
2453 case 0x5:
2454 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2455 break;
2456 case 0x7:
2457 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2458 break;
2459 case 0x8:
2460 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2461 break;
2462 case 0x9:
2463 gen_op_iwmmxt_addul_M0_wRn(rd1);
2464 break;
2465 case 0xb:
2466 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2467 break;
2468 default:
2469 return 1;
2471 gen_op_iwmmxt_movq_wRn_M0(wrd);
2472 gen_op_iwmmxt_set_mup();
2473 gen_op_iwmmxt_set_cup();
2474 break;
2475 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2476 case 0x408: case 0x508: case 0x608: case 0x708:
2477 case 0x808: case 0x908: case 0xa08: case 0xb08:
2478 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2479 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2480 return 1;
2481 wrd = (insn >> 12) & 0xf;
2482 rd0 = (insn >> 16) & 0xf;
2483 rd1 = (insn >> 0) & 0xf;
2484 gen_op_iwmmxt_movq_M0_wRn(rd0);
2485 switch ((insn >> 22) & 3) {
2486 case 1:
2487 if (insn & (1 << 21))
2488 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2489 else
2490 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2491 break;
2492 case 2:
2493 if (insn & (1 << 21))
2494 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2495 else
2496 gen_op_iwmmxt_packul_M0_wRn(rd1);
2497 break;
2498 case 3:
2499 if (insn & (1 << 21))
2500 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2501 else
2502 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2503 break;
2505 gen_op_iwmmxt_movq_wRn_M0(wrd);
2506 gen_op_iwmmxt_set_mup();
2507 gen_op_iwmmxt_set_cup();
2508 break;
2509 case 0x201: case 0x203: case 0x205: case 0x207:
2510 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2511 case 0x211: case 0x213: case 0x215: case 0x217:
2512 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2513 wrd = (insn >> 5) & 0xf;
2514 rd0 = (insn >> 12) & 0xf;
2515 rd1 = (insn >> 0) & 0xf;
2516 if (rd0 == 0xf || rd1 == 0xf)
2517 return 1;
2518 gen_op_iwmmxt_movq_M0_wRn(wrd);
2519 tmp = load_reg(s, rd0);
2520 tmp2 = load_reg(s, rd1);
2521 switch ((insn >> 16) & 0xf) {
2522 case 0x0: /* TMIA */
2523 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2524 break;
2525 case 0x8: /* TMIAPH */
2526 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2527 break;
2528 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2529 if (insn & (1 << 16))
2530 tcg_gen_shri_i32(tmp, tmp, 16);
2531 if (insn & (1 << 17))
2532 tcg_gen_shri_i32(tmp2, tmp2, 16);
2533 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2534 break;
2535 default:
2536 tcg_temp_free_i32(tmp2);
2537 tcg_temp_free_i32(tmp);
2538 return 1;
2540 tcg_temp_free_i32(tmp2);
2541 tcg_temp_free_i32(tmp);
2542 gen_op_iwmmxt_movq_wRn_M0(wrd);
2543 gen_op_iwmmxt_set_mup();
2544 break;
2545 default:
2546 return 1;
2549 return 0;
2552 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2553 (ie. an undefined instruction). */
2554 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2556 int acc, rd0, rd1, rdhi, rdlo;
2557 TCGv_i32 tmp, tmp2;
2559 if ((insn & 0x0ff00f10) == 0x0e200010) {
2560 /* Multiply with Internal Accumulate Format */
2561 rd0 = (insn >> 12) & 0xf;
2562 rd1 = insn & 0xf;
2563 acc = (insn >> 5) & 7;
2565 if (acc != 0)
2566 return 1;
2568 tmp = load_reg(s, rd0);
2569 tmp2 = load_reg(s, rd1);
2570 switch ((insn >> 16) & 0xf) {
2571 case 0x0: /* MIA */
2572 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2573 break;
2574 case 0x8: /* MIAPH */
2575 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2576 break;
2577 case 0xc: /* MIABB */
2578 case 0xd: /* MIABT */
2579 case 0xe: /* MIATB */
2580 case 0xf: /* MIATT */
2581 if (insn & (1 << 16))
2582 tcg_gen_shri_i32(tmp, tmp, 16);
2583 if (insn & (1 << 17))
2584 tcg_gen_shri_i32(tmp2, tmp2, 16);
2585 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2586 break;
2587 default:
2588 return 1;
2590 tcg_temp_free_i32(tmp2);
2591 tcg_temp_free_i32(tmp);
2593 gen_op_iwmmxt_movq_wRn_M0(acc);
2594 return 0;
2597 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2598 /* Internal Accumulator Access Format */
2599 rdhi = (insn >> 16) & 0xf;
2600 rdlo = (insn >> 12) & 0xf;
2601 acc = insn & 7;
2603 if (acc != 0)
2604 return 1;
2606 if (insn & ARM_CP_RW_BIT) { /* MRA */
2607 iwmmxt_load_reg(cpu_V0, acc);
2608 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2609 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2610 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2611 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2612 } else { /* MAR */
2613 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2614 iwmmxt_store_reg(cpu_V0, acc);
2616 return 0;
2619 return 1;
2622 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2623 #define VFP_SREG(insn, bigbit, smallbit) \
2624 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2625 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2626 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2627 reg = (((insn) >> (bigbit)) & 0x0f) \
2628 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2629 } else { \
2630 if (insn & (1 << (smallbit))) \
2631 return 1; \
2632 reg = ((insn) >> (bigbit)) & 0x0f; \
2633 }} while (0)
2635 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2636 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2637 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2638 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2639 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2640 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2642 /* Move between integer and VFP cores. */
2643 static TCGv_i32 gen_vfp_mrs(void)
2645 TCGv_i32 tmp = tcg_temp_new_i32();
2646 tcg_gen_mov_i32(tmp, cpu_F0s);
2647 return tmp;
2650 static void gen_vfp_msr(TCGv_i32 tmp)
2652 tcg_gen_mov_i32(cpu_F0s, tmp);
2653 tcg_temp_free_i32(tmp);
2656 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2658 TCGv_i32 tmp = tcg_temp_new_i32();
2659 if (shift)
2660 tcg_gen_shri_i32(var, var, shift);
2661 tcg_gen_ext8u_i32(var, var);
2662 tcg_gen_shli_i32(tmp, var, 8);
2663 tcg_gen_or_i32(var, var, tmp);
2664 tcg_gen_shli_i32(tmp, var, 16);
2665 tcg_gen_or_i32(var, var, tmp);
2666 tcg_temp_free_i32(tmp);
2669 static void gen_neon_dup_low16(TCGv_i32 var)
2671 TCGv_i32 tmp = tcg_temp_new_i32();
2672 tcg_gen_ext16u_i32(var, var);
2673 tcg_gen_shli_i32(tmp, var, 16);
2674 tcg_gen_or_i32(var, var, tmp);
2675 tcg_temp_free_i32(tmp);
2678 static void gen_neon_dup_high16(TCGv_i32 var)
2680 TCGv_i32 tmp = tcg_temp_new_i32();
2681 tcg_gen_andi_i32(var, var, 0xffff0000);
2682 tcg_gen_shri_i32(tmp, var, 16);
2683 tcg_gen_or_i32(var, var, tmp);
2684 tcg_temp_free_i32(tmp);
2687 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2689 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2690 TCGv_i32 tmp = tcg_temp_new_i32();
2691 switch (size) {
2692 case 0:
2693 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2694 gen_neon_dup_u8(tmp, 0);
2695 break;
2696 case 1:
2697 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2698 gen_neon_dup_low16(tmp);
2699 break;
2700 case 2:
2701 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2702 break;
2703 default: /* Avoid compiler warnings. */
2704 abort();
2706 return tmp;
2709 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2710 uint32_t dp)
2712 uint32_t cc = extract32(insn, 20, 2);
2714 if (dp) {
2715 TCGv_i64 frn, frm, dest;
2716 TCGv_i64 tmp, zero, zf, nf, vf;
2718 zero = tcg_const_i64(0);
2720 frn = tcg_temp_new_i64();
2721 frm = tcg_temp_new_i64();
2722 dest = tcg_temp_new_i64();
2724 zf = tcg_temp_new_i64();
2725 nf = tcg_temp_new_i64();
2726 vf = tcg_temp_new_i64();
2728 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2729 tcg_gen_ext_i32_i64(nf, cpu_NF);
2730 tcg_gen_ext_i32_i64(vf, cpu_VF);
2732 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2733 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2734 switch (cc) {
2735 case 0: /* eq: Z */
2736 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2737 frn, frm);
2738 break;
2739 case 1: /* vs: V */
2740 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2741 frn, frm);
2742 break;
2743 case 2: /* ge: N == V -> N ^ V == 0 */
2744 tmp = tcg_temp_new_i64();
2745 tcg_gen_xor_i64(tmp, vf, nf);
2746 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2747 frn, frm);
2748 tcg_temp_free_i64(tmp);
2749 break;
2750 case 3: /* gt: !Z && N == V */
2751 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2752 frn, frm);
2753 tmp = tcg_temp_new_i64();
2754 tcg_gen_xor_i64(tmp, vf, nf);
2755 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2756 dest, frm);
2757 tcg_temp_free_i64(tmp);
2758 break;
2760 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2761 tcg_temp_free_i64(frn);
2762 tcg_temp_free_i64(frm);
2763 tcg_temp_free_i64(dest);
2765 tcg_temp_free_i64(zf);
2766 tcg_temp_free_i64(nf);
2767 tcg_temp_free_i64(vf);
2769 tcg_temp_free_i64(zero);
2770 } else {
2771 TCGv_i32 frn, frm, dest;
2772 TCGv_i32 tmp, zero;
2774 zero = tcg_const_i32(0);
2776 frn = tcg_temp_new_i32();
2777 frm = tcg_temp_new_i32();
2778 dest = tcg_temp_new_i32();
2779 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2780 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2781 switch (cc) {
2782 case 0: /* eq: Z */
2783 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2784 frn, frm);
2785 break;
2786 case 1: /* vs: V */
2787 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2788 frn, frm);
2789 break;
2790 case 2: /* ge: N == V -> N ^ V == 0 */
2791 tmp = tcg_temp_new_i32();
2792 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2793 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2794 frn, frm);
2795 tcg_temp_free_i32(tmp);
2796 break;
2797 case 3: /* gt: !Z && N == V */
2798 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2799 frn, frm);
2800 tmp = tcg_temp_new_i32();
2801 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2802 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2803 dest, frm);
2804 tcg_temp_free_i32(tmp);
2805 break;
2807 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2808 tcg_temp_free_i32(frn);
2809 tcg_temp_free_i32(frm);
2810 tcg_temp_free_i32(dest);
2812 tcg_temp_free_i32(zero);
2815 return 0;
2818 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2819 uint32_t rm, uint32_t dp)
2821 uint32_t vmin = extract32(insn, 6, 1);
2822 TCGv_ptr fpst = get_fpstatus_ptr(0);
2824 if (dp) {
2825 TCGv_i64 frn, frm, dest;
2827 frn = tcg_temp_new_i64();
2828 frm = tcg_temp_new_i64();
2829 dest = tcg_temp_new_i64();
2831 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2832 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2833 if (vmin) {
2834 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2835 } else {
2836 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2838 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2839 tcg_temp_free_i64(frn);
2840 tcg_temp_free_i64(frm);
2841 tcg_temp_free_i64(dest);
2842 } else {
2843 TCGv_i32 frn, frm, dest;
2845 frn = tcg_temp_new_i32();
2846 frm = tcg_temp_new_i32();
2847 dest = tcg_temp_new_i32();
2849 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2850 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2851 if (vmin) {
2852 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2853 } else {
2854 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2856 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2857 tcg_temp_free_i32(frn);
2858 tcg_temp_free_i32(frm);
2859 tcg_temp_free_i32(dest);
2862 tcg_temp_free_ptr(fpst);
2863 return 0;
2866 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2867 int rounding)
2869 TCGv_ptr fpst = get_fpstatus_ptr(0);
2870 TCGv_i32 tcg_rmode;
2872 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2873 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2875 if (dp) {
2876 TCGv_i64 tcg_op;
2877 TCGv_i64 tcg_res;
2878 tcg_op = tcg_temp_new_i64();
2879 tcg_res = tcg_temp_new_i64();
2880 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2881 gen_helper_rintd(tcg_res, tcg_op, fpst);
2882 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2883 tcg_temp_free_i64(tcg_op);
2884 tcg_temp_free_i64(tcg_res);
2885 } else {
2886 TCGv_i32 tcg_op;
2887 TCGv_i32 tcg_res;
2888 tcg_op = tcg_temp_new_i32();
2889 tcg_res = tcg_temp_new_i32();
2890 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2891 gen_helper_rints(tcg_res, tcg_op, fpst);
2892 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2893 tcg_temp_free_i32(tcg_op);
2894 tcg_temp_free_i32(tcg_res);
2897 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2898 tcg_temp_free_i32(tcg_rmode);
2900 tcg_temp_free_ptr(fpst);
2901 return 0;
2904 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2905 int rounding)
2907 bool is_signed = extract32(insn, 7, 1);
2908 TCGv_ptr fpst = get_fpstatus_ptr(0);
2909 TCGv_i32 tcg_rmode, tcg_shift;
2911 tcg_shift = tcg_const_i32(0);
2913 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2914 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2916 if (dp) {
2917 TCGv_i64 tcg_double, tcg_res;
2918 TCGv_i32 tcg_tmp;
2919 /* Rd is encoded as a single precision register even when the source
2920 * is double precision.
2922 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2923 tcg_double = tcg_temp_new_i64();
2924 tcg_res = tcg_temp_new_i64();
2925 tcg_tmp = tcg_temp_new_i32();
2926 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2927 if (is_signed) {
2928 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2929 } else {
2930 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2932 tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2933 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2934 tcg_temp_free_i32(tcg_tmp);
2935 tcg_temp_free_i64(tcg_res);
2936 tcg_temp_free_i64(tcg_double);
2937 } else {
2938 TCGv_i32 tcg_single, tcg_res;
2939 tcg_single = tcg_temp_new_i32();
2940 tcg_res = tcg_temp_new_i32();
2941 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2942 if (is_signed) {
2943 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2944 } else {
2945 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2947 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2948 tcg_temp_free_i32(tcg_res);
2949 tcg_temp_free_i32(tcg_single);
2952 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2953 tcg_temp_free_i32(tcg_rmode);
2955 tcg_temp_free_i32(tcg_shift);
2957 tcg_temp_free_ptr(fpst);
2959 return 0;
2962 /* Table for converting the most common AArch32 encoding of
2963 * rounding mode to arm_fprounding order (which matches the
2964 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2966 static const uint8_t fp_decode_rm[] = {
2967 FPROUNDING_TIEAWAY,
2968 FPROUNDING_TIEEVEN,
2969 FPROUNDING_POSINF,
2970 FPROUNDING_NEGINF,
2973 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2975 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2977 if (!arm_feature(env, ARM_FEATURE_V8)) {
2978 return 1;
2981 if (dp) {
2982 VFP_DREG_D(rd, insn);
2983 VFP_DREG_N(rn, insn);
2984 VFP_DREG_M(rm, insn);
2985 } else {
2986 rd = VFP_SREG_D(insn);
2987 rn = VFP_SREG_N(insn);
2988 rm = VFP_SREG_M(insn);
2991 if ((insn & 0x0f800e50) == 0x0e000a00) {
2992 return handle_vsel(insn, rd, rn, rm, dp);
2993 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2994 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2995 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2996 /* VRINTA, VRINTN, VRINTP, VRINTM */
2997 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2998 return handle_vrint(insn, rd, rm, dp, rounding);
2999 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3000 /* VCVTA, VCVTN, VCVTP, VCVTM */
3001 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3002 return handle_vcvt(insn, rd, rm, dp, rounding);
3004 return 1;
3007 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3008 (ie. an undefined instruction). */
3009 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3011 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3012 int dp, veclen;
3013 TCGv_i32 addr;
3014 TCGv_i32 tmp;
3015 TCGv_i32 tmp2;
3017 if (!arm_feature(env, ARM_FEATURE_VFP))
3018 return 1;
3020 /* FIXME: this access check should not take precedence over UNDEF
3021 * for invalid encodings; we will generate incorrect syndrome information
3022 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3024 if (!s->cpacr_fpen) {
3025 gen_exception_insn(s, 4, EXCP_UDEF,
3026 syn_fp_access_trap(1, 0xe, s->thumb));
3027 return 0;
3030 if (!s->vfp_enabled) {
3031 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3032 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3033 return 1;
3034 rn = (insn >> 16) & 0xf;
3035 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3036 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3037 return 1;
3041 if (extract32(insn, 28, 4) == 0xf) {
3042 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3043 * only used in v8 and above.
3045 return disas_vfp_v8_insn(env, s, insn);
3048 dp = ((insn & 0xf00) == 0xb00);
3049 switch ((insn >> 24) & 0xf) {
3050 case 0xe:
3051 if (insn & (1 << 4)) {
3052 /* single register transfer */
3053 rd = (insn >> 12) & 0xf;
3054 if (dp) {
3055 int size;
3056 int pass;
3058 VFP_DREG_N(rn, insn);
3059 if (insn & 0xf)
3060 return 1;
3061 if (insn & 0x00c00060
3062 && !arm_feature(env, ARM_FEATURE_NEON))
3063 return 1;
3065 pass = (insn >> 21) & 1;
3066 if (insn & (1 << 22)) {
3067 size = 0;
3068 offset = ((insn >> 5) & 3) * 8;
3069 } else if (insn & (1 << 5)) {
3070 size = 1;
3071 offset = (insn & (1 << 6)) ? 16 : 0;
3072 } else {
3073 size = 2;
3074 offset = 0;
3076 if (insn & ARM_CP_RW_BIT) {
3077 /* vfp->arm */
3078 tmp = neon_load_reg(rn, pass);
3079 switch (size) {
3080 case 0:
3081 if (offset)
3082 tcg_gen_shri_i32(tmp, tmp, offset);
3083 if (insn & (1 << 23))
3084 gen_uxtb(tmp);
3085 else
3086 gen_sxtb(tmp);
3087 break;
3088 case 1:
3089 if (insn & (1 << 23)) {
3090 if (offset) {
3091 tcg_gen_shri_i32(tmp, tmp, 16);
3092 } else {
3093 gen_uxth(tmp);
3095 } else {
3096 if (offset) {
3097 tcg_gen_sari_i32(tmp, tmp, 16);
3098 } else {
3099 gen_sxth(tmp);
3102 break;
3103 case 2:
3104 break;
3106 store_reg(s, rd, tmp);
3107 } else {
3108 /* arm->vfp */
3109 tmp = load_reg(s, rd);
3110 if (insn & (1 << 23)) {
3111 /* VDUP */
3112 if (size == 0) {
3113 gen_neon_dup_u8(tmp, 0);
3114 } else if (size == 1) {
3115 gen_neon_dup_low16(tmp);
3117 for (n = 0; n <= pass * 2; n++) {
3118 tmp2 = tcg_temp_new_i32();
3119 tcg_gen_mov_i32(tmp2, tmp);
3120 neon_store_reg(rn, n, tmp2);
3122 neon_store_reg(rn, n, tmp);
3123 } else {
3124 /* VMOV */
3125 switch (size) {
3126 case 0:
3127 tmp2 = neon_load_reg(rn, pass);
3128 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3129 tcg_temp_free_i32(tmp2);
3130 break;
3131 case 1:
3132 tmp2 = neon_load_reg(rn, pass);
3133 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3134 tcg_temp_free_i32(tmp2);
3135 break;
3136 case 2:
3137 break;
3139 neon_store_reg(rn, pass, tmp);
3142 } else { /* !dp */
3143 if ((insn & 0x6f) != 0x00)
3144 return 1;
3145 rn = VFP_SREG_N(insn);
3146 if (insn & ARM_CP_RW_BIT) {
3147 /* vfp->arm */
3148 if (insn & (1 << 21)) {
3149 /* system register */
3150 rn >>= 1;
3152 switch (rn) {
3153 case ARM_VFP_FPSID:
3154 /* VFP2 allows access to FSID from userspace.
3155 VFP3 restricts all id registers to privileged
3156 accesses. */
3157 if (IS_USER(s)
3158 && arm_feature(env, ARM_FEATURE_VFP3))
3159 return 1;
3160 tmp = load_cpu_field(vfp.xregs[rn]);
3161 break;
3162 case ARM_VFP_FPEXC:
3163 if (IS_USER(s))
3164 return 1;
3165 tmp = load_cpu_field(vfp.xregs[rn]);
3166 break;
3167 case ARM_VFP_FPINST:
3168 case ARM_VFP_FPINST2:
3169 /* Not present in VFP3. */
3170 if (IS_USER(s)
3171 || arm_feature(env, ARM_FEATURE_VFP3))
3172 return 1;
3173 tmp = load_cpu_field(vfp.xregs[rn]);
3174 break;
3175 case ARM_VFP_FPSCR:
3176 if (rd == 15) {
3177 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3178 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3179 } else {
3180 tmp = tcg_temp_new_i32();
3181 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3183 break;
3184 case ARM_VFP_MVFR2:
3185 if (!arm_feature(env, ARM_FEATURE_V8)) {
3186 return 1;
3188 /* fall through */
3189 case ARM_VFP_MVFR0:
3190 case ARM_VFP_MVFR1:
3191 if (IS_USER(s)
3192 || !arm_feature(env, ARM_FEATURE_MVFR))
3193 return 1;
3194 tmp = load_cpu_field(vfp.xregs[rn]);
3195 break;
3196 default:
3197 return 1;
3199 } else {
3200 gen_mov_F0_vreg(0, rn);
3201 tmp = gen_vfp_mrs();
3203 if (rd == 15) {
3204 /* Set the 4 flag bits in the CPSR. */
3205 gen_set_nzcv(tmp);
3206 tcg_temp_free_i32(tmp);
3207 } else {
3208 store_reg(s, rd, tmp);
3210 } else {
3211 /* arm->vfp */
3212 if (insn & (1 << 21)) {
3213 rn >>= 1;
3214 /* system register */
3215 switch (rn) {
3216 case ARM_VFP_FPSID:
3217 case ARM_VFP_MVFR0:
3218 case ARM_VFP_MVFR1:
3219 /* Writes are ignored. */
3220 break;
3221 case ARM_VFP_FPSCR:
3222 tmp = load_reg(s, rd);
3223 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3224 tcg_temp_free_i32(tmp);
3225 gen_lookup_tb(s);
3226 break;
3227 case ARM_VFP_FPEXC:
3228 if (IS_USER(s))
3229 return 1;
3230 /* TODO: VFP subarchitecture support.
3231 * For now, keep the EN bit only */
3232 tmp = load_reg(s, rd);
3233 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3234 store_cpu_field(tmp, vfp.xregs[rn]);
3235 gen_lookup_tb(s);
3236 break;
3237 case ARM_VFP_FPINST:
3238 case ARM_VFP_FPINST2:
3239 if (IS_USER(s)) {
3240 return 1;
3242 tmp = load_reg(s, rd);
3243 store_cpu_field(tmp, vfp.xregs[rn]);
3244 break;
3245 default:
3246 return 1;
3248 } else {
3249 tmp = load_reg(s, rd);
3250 gen_vfp_msr(tmp);
3251 gen_mov_vreg_F0(0, rn);
3255 } else {
3256 /* data processing */
3257 /* The opcode is in bits 23, 21, 20 and 6. */
3258 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3259 if (dp) {
3260 if (op == 15) {
3261 /* rn is opcode */
3262 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3263 } else {
3264 /* rn is register number */
3265 VFP_DREG_N(rn, insn);
3268 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3269 ((rn & 0x1e) == 0x6))) {
3270 /* Integer or single/half precision destination. */
3271 rd = VFP_SREG_D(insn);
3272 } else {
3273 VFP_DREG_D(rd, insn);
3275 if (op == 15 &&
3276 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3277 ((rn & 0x1e) == 0x4))) {
3278 /* VCVT from int or half precision is always from S reg
3279 * regardless of dp bit. VCVT with immediate frac_bits
3280 * has same format as SREG_M.
3282 rm = VFP_SREG_M(insn);
3283 } else {
3284 VFP_DREG_M(rm, insn);
3286 } else {
3287 rn = VFP_SREG_N(insn);
3288 if (op == 15 && rn == 15) {
3289 /* Double precision destination. */
3290 VFP_DREG_D(rd, insn);
3291 } else {
3292 rd = VFP_SREG_D(insn);
3294 /* NB that we implicitly rely on the encoding for the frac_bits
3295 * in VCVT of fixed to float being the same as that of an SREG_M
3297 rm = VFP_SREG_M(insn);
3300 veclen = s->vec_len;
3301 if (op == 15 && rn > 3)
3302 veclen = 0;
3304 /* Shut up compiler warnings. */
3305 delta_m = 0;
3306 delta_d = 0;
3307 bank_mask = 0;
3309 if (veclen > 0) {
3310 if (dp)
3311 bank_mask = 0xc;
3312 else
3313 bank_mask = 0x18;
3315 /* Figure out what type of vector operation this is. */
3316 if ((rd & bank_mask) == 0) {
3317 /* scalar */
3318 veclen = 0;
3319 } else {
3320 if (dp)
3321 delta_d = (s->vec_stride >> 1) + 1;
3322 else
3323 delta_d = s->vec_stride + 1;
3325 if ((rm & bank_mask) == 0) {
3326 /* mixed scalar/vector */
3327 delta_m = 0;
3328 } else {
3329 /* vector */
3330 delta_m = delta_d;
3335 /* Load the initial operands. */
3336 if (op == 15) {
3337 switch (rn) {
3338 case 16:
3339 case 17:
3340 /* Integer source */
3341 gen_mov_F0_vreg(0, rm);
3342 break;
3343 case 8:
3344 case 9:
3345 /* Compare */
3346 gen_mov_F0_vreg(dp, rd);
3347 gen_mov_F1_vreg(dp, rm);
3348 break;
3349 case 10:
3350 case 11:
3351 /* Compare with zero */
3352 gen_mov_F0_vreg(dp, rd);
3353 gen_vfp_F1_ld0(dp);
3354 break;
3355 case 20:
3356 case 21:
3357 case 22:
3358 case 23:
3359 case 28:
3360 case 29:
3361 case 30:
3362 case 31:
3363 /* Source and destination the same. */
3364 gen_mov_F0_vreg(dp, rd);
3365 break;
3366 case 4:
3367 case 5:
3368 case 6:
3369 case 7:
3370 /* VCVTB, VCVTT: only present with the halfprec extension
3371 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3372 * (we choose to UNDEF)
3374 if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
3375 !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3376 return 1;
3378 if (!extract32(rn, 1, 1)) {
3379 /* Half precision source. */
3380 gen_mov_F0_vreg(0, rm);
3381 break;
3383 /* Otherwise fall through */
3384 default:
3385 /* One source operand. */
3386 gen_mov_F0_vreg(dp, rm);
3387 break;
3389 } else {
3390 /* Two source operands. */
3391 gen_mov_F0_vreg(dp, rn);
3392 gen_mov_F1_vreg(dp, rm);
3395 for (;;) {
3396 /* Perform the calculation. */
3397 switch (op) {
3398 case 0: /* VMLA: fd + (fn * fm) */
3399 /* Note that order of inputs to the add matters for NaNs */
3400 gen_vfp_F1_mul(dp);
3401 gen_mov_F0_vreg(dp, rd);
3402 gen_vfp_add(dp);
3403 break;
3404 case 1: /* VMLS: fd + -(fn * fm) */
3405 gen_vfp_mul(dp);
3406 gen_vfp_F1_neg(dp);
3407 gen_mov_F0_vreg(dp, rd);
3408 gen_vfp_add(dp);
3409 break;
3410 case 2: /* VNMLS: -fd + (fn * fm) */
3411 /* Note that it isn't valid to replace (-A + B) with (B - A)
3412 * or similar plausible looking simplifications
3413 * because this will give wrong results for NaNs.
3415 gen_vfp_F1_mul(dp);
3416 gen_mov_F0_vreg(dp, rd);
3417 gen_vfp_neg(dp);
3418 gen_vfp_add(dp);
3419 break;
3420 case 3: /* VNMLA: -fd + -(fn * fm) */
3421 gen_vfp_mul(dp);
3422 gen_vfp_F1_neg(dp);
3423 gen_mov_F0_vreg(dp, rd);
3424 gen_vfp_neg(dp);
3425 gen_vfp_add(dp);
3426 break;
3427 case 4: /* mul: fn * fm */
3428 gen_vfp_mul(dp);
3429 break;
3430 case 5: /* nmul: -(fn * fm) */
3431 gen_vfp_mul(dp);
3432 gen_vfp_neg(dp);
3433 break;
3434 case 6: /* add: fn + fm */
3435 gen_vfp_add(dp);
3436 break;
3437 case 7: /* sub: fn - fm */
3438 gen_vfp_sub(dp);
3439 break;
3440 case 8: /* div: fn / fm */
3441 gen_vfp_div(dp);
3442 break;
3443 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3444 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3445 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3446 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3447 /* These are fused multiply-add, and must be done as one
3448 * floating point operation with no rounding between the
3449 * multiplication and addition steps.
3450 * NB that doing the negations here as separate steps is
3451 * correct : an input NaN should come out with its sign bit
3452 * flipped if it is a negated-input.
3454 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3455 return 1;
3457 if (dp) {
3458 TCGv_ptr fpst;
3459 TCGv_i64 frd;
3460 if (op & 1) {
3461 /* VFNMS, VFMS */
3462 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3464 frd = tcg_temp_new_i64();
3465 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3466 if (op & 2) {
3467 /* VFNMA, VFNMS */
3468 gen_helper_vfp_negd(frd, frd);
3470 fpst = get_fpstatus_ptr(0);
3471 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3472 cpu_F1d, frd, fpst);
3473 tcg_temp_free_ptr(fpst);
3474 tcg_temp_free_i64(frd);
3475 } else {
3476 TCGv_ptr fpst;
3477 TCGv_i32 frd;
3478 if (op & 1) {
3479 /* VFNMS, VFMS */
3480 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3482 frd = tcg_temp_new_i32();
3483 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3484 if (op & 2) {
3485 gen_helper_vfp_negs(frd, frd);
3487 fpst = get_fpstatus_ptr(0);
3488 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3489 cpu_F1s, frd, fpst);
3490 tcg_temp_free_ptr(fpst);
3491 tcg_temp_free_i32(frd);
3493 break;
3494 case 14: /* fconst */
3495 if (!arm_feature(env, ARM_FEATURE_VFP3))
3496 return 1;
3498 n = (insn << 12) & 0x80000000;
3499 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3500 if (dp) {
3501 if (i & 0x40)
3502 i |= 0x3f80;
3503 else
3504 i |= 0x4000;
3505 n |= i << 16;
3506 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3507 } else {
3508 if (i & 0x40)
3509 i |= 0x780;
3510 else
3511 i |= 0x800;
3512 n |= i << 19;
3513 tcg_gen_movi_i32(cpu_F0s, n);
3515 break;
3516 case 15: /* extension space */
3517 switch (rn) {
3518 case 0: /* cpy */
3519 /* no-op */
3520 break;
3521 case 1: /* abs */
3522 gen_vfp_abs(dp);
3523 break;
3524 case 2: /* neg */
3525 gen_vfp_neg(dp);
3526 break;
3527 case 3: /* sqrt */
3528 gen_vfp_sqrt(dp);
3529 break;
3530 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3531 tmp = gen_vfp_mrs();
3532 tcg_gen_ext16u_i32(tmp, tmp);
3533 if (dp) {
3534 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3535 cpu_env);
3536 } else {
3537 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3538 cpu_env);
3540 tcg_temp_free_i32(tmp);
3541 break;
3542 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3543 tmp = gen_vfp_mrs();
3544 tcg_gen_shri_i32(tmp, tmp, 16);
3545 if (dp) {
3546 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3547 cpu_env);
3548 } else {
3549 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3550 cpu_env);
3552 tcg_temp_free_i32(tmp);
3553 break;
3554 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3555 tmp = tcg_temp_new_i32();
3556 if (dp) {
3557 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3558 cpu_env);
3559 } else {
3560 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3561 cpu_env);
3563 gen_mov_F0_vreg(0, rd);
3564 tmp2 = gen_vfp_mrs();
3565 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3566 tcg_gen_or_i32(tmp, tmp, tmp2);
3567 tcg_temp_free_i32(tmp2);
3568 gen_vfp_msr(tmp);
3569 break;
3570 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3571 tmp = tcg_temp_new_i32();
3572 if (dp) {
3573 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3574 cpu_env);
3575 } else {
3576 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3577 cpu_env);
3579 tcg_gen_shli_i32(tmp, tmp, 16);
3580 gen_mov_F0_vreg(0, rd);
3581 tmp2 = gen_vfp_mrs();
3582 tcg_gen_ext16u_i32(tmp2, tmp2);
3583 tcg_gen_or_i32(tmp, tmp, tmp2);
3584 tcg_temp_free_i32(tmp2);
3585 gen_vfp_msr(tmp);
3586 break;
3587 case 8: /* cmp */
3588 gen_vfp_cmp(dp);
3589 break;
3590 case 9: /* cmpe */
3591 gen_vfp_cmpe(dp);
3592 break;
3593 case 10: /* cmpz */
3594 gen_vfp_cmp(dp);
3595 break;
3596 case 11: /* cmpez */
3597 gen_vfp_F1_ld0(dp);
3598 gen_vfp_cmpe(dp);
3599 break;
3600 case 12: /* vrintr */
3602 TCGv_ptr fpst = get_fpstatus_ptr(0);
3603 if (dp) {
3604 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3605 } else {
3606 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3608 tcg_temp_free_ptr(fpst);
3609 break;
3611 case 13: /* vrintz */
3613 TCGv_ptr fpst = get_fpstatus_ptr(0);
3614 TCGv_i32 tcg_rmode;
3615 tcg_rmode = tcg_const_i32(float_round_to_zero);
3616 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3617 if (dp) {
3618 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3619 } else {
3620 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3622 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3623 tcg_temp_free_i32(tcg_rmode);
3624 tcg_temp_free_ptr(fpst);
3625 break;
3627 case 14: /* vrintx */
3629 TCGv_ptr fpst = get_fpstatus_ptr(0);
3630 if (dp) {
3631 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3632 } else {
3633 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3635 tcg_temp_free_ptr(fpst);
3636 break;
3638 case 15: /* single<->double conversion */
3639 if (dp)
3640 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3641 else
3642 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3643 break;
3644 case 16: /* fuito */
3645 gen_vfp_uito(dp, 0);
3646 break;
3647 case 17: /* fsito */
3648 gen_vfp_sito(dp, 0);
3649 break;
3650 case 20: /* fshto */
3651 if (!arm_feature(env, ARM_FEATURE_VFP3))
3652 return 1;
3653 gen_vfp_shto(dp, 16 - rm, 0);
3654 break;
3655 case 21: /* fslto */
3656 if (!arm_feature(env, ARM_FEATURE_VFP3))
3657 return 1;
3658 gen_vfp_slto(dp, 32 - rm, 0);
3659 break;
3660 case 22: /* fuhto */
3661 if (!arm_feature(env, ARM_FEATURE_VFP3))
3662 return 1;
3663 gen_vfp_uhto(dp, 16 - rm, 0);
3664 break;
3665 case 23: /* fulto */
3666 if (!arm_feature(env, ARM_FEATURE_VFP3))
3667 return 1;
3668 gen_vfp_ulto(dp, 32 - rm, 0);
3669 break;
3670 case 24: /* ftoui */
3671 gen_vfp_toui(dp, 0);
3672 break;
3673 case 25: /* ftouiz */
3674 gen_vfp_touiz(dp, 0);
3675 break;
3676 case 26: /* ftosi */
3677 gen_vfp_tosi(dp, 0);
3678 break;
3679 case 27: /* ftosiz */
3680 gen_vfp_tosiz(dp, 0);
3681 break;
3682 case 28: /* ftosh */
3683 if (!arm_feature(env, ARM_FEATURE_VFP3))
3684 return 1;
3685 gen_vfp_tosh(dp, 16 - rm, 0);
3686 break;
3687 case 29: /* ftosl */
3688 if (!arm_feature(env, ARM_FEATURE_VFP3))
3689 return 1;
3690 gen_vfp_tosl(dp, 32 - rm, 0);
3691 break;
3692 case 30: /* ftouh */
3693 if (!arm_feature(env, ARM_FEATURE_VFP3))
3694 return 1;
3695 gen_vfp_touh(dp, 16 - rm, 0);
3696 break;
3697 case 31: /* ftoul */
3698 if (!arm_feature(env, ARM_FEATURE_VFP3))
3699 return 1;
3700 gen_vfp_toul(dp, 32 - rm, 0);
3701 break;
3702 default: /* undefined */
3703 return 1;
3705 break;
3706 default: /* undefined */
3707 return 1;
3710 /* Write back the result. */
3711 if (op == 15 && (rn >= 8 && rn <= 11)) {
3712 /* Comparison, do nothing. */
3713 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3714 (rn & 0x1e) == 0x6)) {
3715 /* VCVT double to int: always integer result.
3716 * VCVT double to half precision is always a single
3717 * precision result.
3719 gen_mov_vreg_F0(0, rd);
3720 } else if (op == 15 && rn == 15) {
3721 /* conversion */
3722 gen_mov_vreg_F0(!dp, rd);
3723 } else {
3724 gen_mov_vreg_F0(dp, rd);
3727 /* break out of the loop if we have finished */
3728 if (veclen == 0)
3729 break;
3731 if (op == 15 && delta_m == 0) {
3732 /* single source one-many */
3733 while (veclen--) {
3734 rd = ((rd + delta_d) & (bank_mask - 1))
3735 | (rd & bank_mask);
3736 gen_mov_vreg_F0(dp, rd);
3738 break;
3740 /* Setup the next operands. */
3741 veclen--;
3742 rd = ((rd + delta_d) & (bank_mask - 1))
3743 | (rd & bank_mask);
3745 if (op == 15) {
3746 /* One source operand. */
3747 rm = ((rm + delta_m) & (bank_mask - 1))
3748 | (rm & bank_mask);
3749 gen_mov_F0_vreg(dp, rm);
3750 } else {
3751 /* Two source operands. */
3752 rn = ((rn + delta_d) & (bank_mask - 1))
3753 | (rn & bank_mask);
3754 gen_mov_F0_vreg(dp, rn);
3755 if (delta_m) {
3756 rm = ((rm + delta_m) & (bank_mask - 1))
3757 | (rm & bank_mask);
3758 gen_mov_F1_vreg(dp, rm);
3763 break;
3764 case 0xc:
3765 case 0xd:
3766 if ((insn & 0x03e00000) == 0x00400000) {
3767 /* two-register transfer */
3768 rn = (insn >> 16) & 0xf;
3769 rd = (insn >> 12) & 0xf;
3770 if (dp) {
3771 VFP_DREG_M(rm, insn);
3772 } else {
3773 rm = VFP_SREG_M(insn);
3776 if (insn & ARM_CP_RW_BIT) {
3777 /* vfp->arm */
3778 if (dp) {
3779 gen_mov_F0_vreg(0, rm * 2);
3780 tmp = gen_vfp_mrs();
3781 store_reg(s, rd, tmp);
3782 gen_mov_F0_vreg(0, rm * 2 + 1);
3783 tmp = gen_vfp_mrs();
3784 store_reg(s, rn, tmp);
3785 } else {
3786 gen_mov_F0_vreg(0, rm);
3787 tmp = gen_vfp_mrs();
3788 store_reg(s, rd, tmp);
3789 gen_mov_F0_vreg(0, rm + 1);
3790 tmp = gen_vfp_mrs();
3791 store_reg(s, rn, tmp);
3793 } else {
3794 /* arm->vfp */
3795 if (dp) {
3796 tmp = load_reg(s, rd);
3797 gen_vfp_msr(tmp);
3798 gen_mov_vreg_F0(0, rm * 2);
3799 tmp = load_reg(s, rn);
3800 gen_vfp_msr(tmp);
3801 gen_mov_vreg_F0(0, rm * 2 + 1);
3802 } else {
3803 tmp = load_reg(s, rd);
3804 gen_vfp_msr(tmp);
3805 gen_mov_vreg_F0(0, rm);
3806 tmp = load_reg(s, rn);
3807 gen_vfp_msr(tmp);
3808 gen_mov_vreg_F0(0, rm + 1);
3811 } else {
3812 /* Load/store */
3813 rn = (insn >> 16) & 0xf;
3814 if (dp)
3815 VFP_DREG_D(rd, insn);
3816 else
3817 rd = VFP_SREG_D(insn);
3818 if ((insn & 0x01200000) == 0x01000000) {
3819 /* Single load/store */
3820 offset = (insn & 0xff) << 2;
3821 if ((insn & (1 << 23)) == 0)
3822 offset = -offset;
3823 if (s->thumb && rn == 15) {
3824 /* This is actually UNPREDICTABLE */
3825 addr = tcg_temp_new_i32();
3826 tcg_gen_movi_i32(addr, s->pc & ~2);
3827 } else {
3828 addr = load_reg(s, rn);
3830 tcg_gen_addi_i32(addr, addr, offset);
3831 if (insn & (1 << 20)) {
3832 gen_vfp_ld(s, dp, addr);
3833 gen_mov_vreg_F0(dp, rd);
3834 } else {
3835 gen_mov_F0_vreg(dp, rd);
3836 gen_vfp_st(s, dp, addr);
3838 tcg_temp_free_i32(addr);
3839 } else {
3840 /* load/store multiple */
3841 int w = insn & (1 << 21);
3842 if (dp)
3843 n = (insn >> 1) & 0x7f;
3844 else
3845 n = insn & 0xff;
3847 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3848 /* P == U , W == 1 => UNDEF */
3849 return 1;
3851 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3852 /* UNPREDICTABLE cases for bad immediates: we choose to
3853 * UNDEF to avoid generating huge numbers of TCG ops
3855 return 1;
3857 if (rn == 15 && w) {
3858 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3859 return 1;
3862 if (s->thumb && rn == 15) {
3863 /* This is actually UNPREDICTABLE */
3864 addr = tcg_temp_new_i32();
3865 tcg_gen_movi_i32(addr, s->pc & ~2);
3866 } else {
3867 addr = load_reg(s, rn);
3869 if (insn & (1 << 24)) /* pre-decrement */
3870 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3872 if (dp)
3873 offset = 8;
3874 else
3875 offset = 4;
3876 for (i = 0; i < n; i++) {
3877 if (insn & ARM_CP_RW_BIT) {
3878 /* load */
3879 gen_vfp_ld(s, dp, addr);
3880 gen_mov_vreg_F0(dp, rd + i);
3881 } else {
3882 /* store */
3883 gen_mov_F0_vreg(dp, rd + i);
3884 gen_vfp_st(s, dp, addr);
3886 tcg_gen_addi_i32(addr, addr, offset);
3888 if (w) {
3889 /* writeback */
3890 if (insn & (1 << 24))
3891 offset = -offset * n;
3892 else if (dp && (insn & 1))
3893 offset = 4;
3894 else
3895 offset = 0;
3897 if (offset != 0)
3898 tcg_gen_addi_i32(addr, addr, offset);
3899 store_reg(s, rn, addr);
3900 } else {
3901 tcg_temp_free_i32(addr);
3905 break;
3906 default:
3907 /* Should never happen. */
3908 return 1;
3910 return 0;
3913 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3915 TranslationBlock *tb;
3917 tb = s->tb;
3918 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3919 tcg_gen_goto_tb(n);
3920 gen_set_pc_im(s, dest);
3921 tcg_gen_exit_tb((uintptr_t)tb + n);
3922 } else {
3923 gen_set_pc_im(s, dest);
3924 tcg_gen_exit_tb(0);
3928 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3930 if (unlikely(s->singlestep_enabled || s->ss_active)) {
3931 /* An indirect jump so that we still trigger the debug exception. */
3932 if (s->thumb)
3933 dest |= 1;
3934 gen_bx_im(s, dest);
3935 } else {
3936 gen_goto_tb(s, 0, dest);
3937 s->is_jmp = DISAS_TB_JUMP;
3941 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3943 if (x)
3944 tcg_gen_sari_i32(t0, t0, 16);
3945 else
3946 gen_sxth(t0);
3947 if (y)
3948 tcg_gen_sari_i32(t1, t1, 16);
3949 else
3950 gen_sxth(t1);
3951 tcg_gen_mul_i32(t0, t0, t1);
3954 /* Return the mask of PSR bits set by a MSR instruction. */
3955 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3956 uint32_t mask;
3958 mask = 0;
3959 if (flags & (1 << 0))
3960 mask |= 0xff;
3961 if (flags & (1 << 1))
3962 mask |= 0xff00;
3963 if (flags & (1 << 2))
3964 mask |= 0xff0000;
3965 if (flags & (1 << 3))
3966 mask |= 0xff000000;
3968 /* Mask out undefined bits. */
3969 mask &= ~CPSR_RESERVED;
3970 if (!arm_feature(env, ARM_FEATURE_V4T))
3971 mask &= ~CPSR_T;
3972 if (!arm_feature(env, ARM_FEATURE_V5))
3973 mask &= ~CPSR_Q; /* V5TE in reality*/
3974 if (!arm_feature(env, ARM_FEATURE_V6))
3975 mask &= ~(CPSR_E | CPSR_GE);
3976 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3977 mask &= ~CPSR_IT;
3978 /* Mask out execution state and reserved bits. */
3979 if (!spsr) {
3980 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
3982 /* Mask out privileged bits. */
3983 if (IS_USER(s))
3984 mask &= CPSR_USER;
3985 return mask;
3988 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3989 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3991 TCGv_i32 tmp;
3992 if (spsr) {
3993 /* ??? This is also undefined in system mode. */
3994 if (IS_USER(s))
3995 return 1;
3997 tmp = load_cpu_field(spsr);
3998 tcg_gen_andi_i32(tmp, tmp, ~mask);
3999 tcg_gen_andi_i32(t0, t0, mask);
4000 tcg_gen_or_i32(tmp, tmp, t0);
4001 store_cpu_field(tmp, spsr);
4002 } else {
4003 gen_set_cpsr(t0, mask);
4005 tcg_temp_free_i32(t0);
4006 gen_lookup_tb(s);
4007 return 0;
4010 /* Returns nonzero if access to the PSR is not permitted. */
4011 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4013 TCGv_i32 tmp;
4014 tmp = tcg_temp_new_i32();
4015 tcg_gen_movi_i32(tmp, val);
4016 return gen_set_psr(s, mask, spsr, tmp);
4019 /* Generate an old-style exception return. Marks pc as dead. */
4020 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4022 TCGv_i32 tmp;
4023 store_reg(s, 15, pc);
4024 tmp = load_cpu_field(spsr);
4025 gen_set_cpsr(tmp, CPSR_ERET_MASK);
4026 tcg_temp_free_i32(tmp);
4027 s->is_jmp = DISAS_UPDATE;
4030 /* Generate a v6 exception return. Marks both values as dead. */
4031 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4033 gen_set_cpsr(cpsr, CPSR_ERET_MASK);
4034 tcg_temp_free_i32(cpsr);
4035 store_reg(s, 15, pc);
4036 s->is_jmp = DISAS_UPDATE;
4039 static void gen_nop_hint(DisasContext *s, int val)
4041 switch (val) {
4042 case 3: /* wfi */
4043 gen_set_pc_im(s, s->pc);
4044 s->is_jmp = DISAS_WFI;
4045 break;
4046 case 2: /* wfe */
4047 gen_set_pc_im(s, s->pc);
4048 s->is_jmp = DISAS_WFE;
4049 break;
4050 case 4: /* sev */
4051 case 5: /* sevl */
4052 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4053 default: /* nop */
4054 break;
4058 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4060 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4062 switch (size) {
4063 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4064 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4065 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4066 default: abort();
4070 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4072 switch (size) {
4073 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4074 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4075 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4076 default: return;
4080 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4081 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4082 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4083 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4084 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4086 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4087 switch ((size << 1) | u) { \
4088 case 0: \
4089 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4090 break; \
4091 case 1: \
4092 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4093 break; \
4094 case 2: \
4095 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4096 break; \
4097 case 3: \
4098 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4099 break; \
4100 case 4: \
4101 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4102 break; \
4103 case 5: \
4104 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4105 break; \
4106 default: return 1; \
4107 }} while (0)
4109 #define GEN_NEON_INTEGER_OP(name) do { \
4110 switch ((size << 1) | u) { \
4111 case 0: \
4112 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4113 break; \
4114 case 1: \
4115 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4116 break; \
4117 case 2: \
4118 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4119 break; \
4120 case 3: \
4121 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4122 break; \
4123 case 4: \
4124 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4125 break; \
4126 case 5: \
4127 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4128 break; \
4129 default: return 1; \
4130 }} while (0)
4132 static TCGv_i32 neon_load_scratch(int scratch)
4134 TCGv_i32 tmp = tcg_temp_new_i32();
4135 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4136 return tmp;
4139 static void neon_store_scratch(int scratch, TCGv_i32 var)
4141 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4142 tcg_temp_free_i32(var);
4145 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4147 TCGv_i32 tmp;
4148 if (size == 1) {
4149 tmp = neon_load_reg(reg & 7, reg >> 4);
4150 if (reg & 8) {
4151 gen_neon_dup_high16(tmp);
4152 } else {
4153 gen_neon_dup_low16(tmp);
4155 } else {
4156 tmp = neon_load_reg(reg & 15, reg >> 4);
4158 return tmp;
4161 static int gen_neon_unzip(int rd, int rm, int size, int q)
4163 TCGv_i32 tmp, tmp2;
4164 if (!q && size == 2) {
4165 return 1;
4167 tmp = tcg_const_i32(rd);
4168 tmp2 = tcg_const_i32(rm);
4169 if (q) {
4170 switch (size) {
4171 case 0:
4172 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4173 break;
4174 case 1:
4175 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4176 break;
4177 case 2:
4178 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4179 break;
4180 default:
4181 abort();
4183 } else {
4184 switch (size) {
4185 case 0:
4186 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4187 break;
4188 case 1:
4189 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4190 break;
4191 default:
4192 abort();
4195 tcg_temp_free_i32(tmp);
4196 tcg_temp_free_i32(tmp2);
4197 return 0;
4200 static int gen_neon_zip(int rd, int rm, int size, int q)
4202 TCGv_i32 tmp, tmp2;
4203 if (!q && size == 2) {
4204 return 1;
4206 tmp = tcg_const_i32(rd);
4207 tmp2 = tcg_const_i32(rm);
4208 if (q) {
4209 switch (size) {
4210 case 0:
4211 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4212 break;
4213 case 1:
4214 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4215 break;
4216 case 2:
4217 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4218 break;
4219 default:
4220 abort();
4222 } else {
4223 switch (size) {
4224 case 0:
4225 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4226 break;
4227 case 1:
4228 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4229 break;
4230 default:
4231 abort();
4234 tcg_temp_free_i32(tmp);
4235 tcg_temp_free_i32(tmp2);
4236 return 0;
4239 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4241 TCGv_i32 rd, tmp;
4243 rd = tcg_temp_new_i32();
4244 tmp = tcg_temp_new_i32();
4246 tcg_gen_shli_i32(rd, t0, 8);
4247 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4248 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4249 tcg_gen_or_i32(rd, rd, tmp);
4251 tcg_gen_shri_i32(t1, t1, 8);
4252 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4253 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4254 tcg_gen_or_i32(t1, t1, tmp);
4255 tcg_gen_mov_i32(t0, rd);
4257 tcg_temp_free_i32(tmp);
4258 tcg_temp_free_i32(rd);
4261 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4263 TCGv_i32 rd, tmp;
4265 rd = tcg_temp_new_i32();
4266 tmp = tcg_temp_new_i32();
4268 tcg_gen_shli_i32(rd, t0, 16);
4269 tcg_gen_andi_i32(tmp, t1, 0xffff);
4270 tcg_gen_or_i32(rd, rd, tmp);
4271 tcg_gen_shri_i32(t1, t1, 16);
4272 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4273 tcg_gen_or_i32(t1, t1, tmp);
4274 tcg_gen_mov_i32(t0, rd);
4276 tcg_temp_free_i32(tmp);
4277 tcg_temp_free_i32(rd);
4281 static struct {
4282 int nregs;
4283 int interleave;
4284 int spacing;
4285 } neon_ls_element_type[11] = {
4286 {4, 4, 1},
4287 {4, 4, 2},
4288 {4, 1, 1},
4289 {4, 2, 1},
4290 {3, 3, 1},
4291 {3, 3, 2},
4292 {3, 1, 1},
4293 {1, 1, 1},
4294 {2, 2, 1},
4295 {2, 2, 2},
4296 {2, 1, 1}
4299 /* Translate a NEON load/store element instruction. Return nonzero if the
4300 instruction is invalid. */
4301 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4303 int rd, rn, rm;
4304 int op;
4305 int nregs;
4306 int interleave;
4307 int spacing;
4308 int stride;
4309 int size;
4310 int reg;
4311 int pass;
4312 int load;
4313 int shift;
4314 int n;
4315 TCGv_i32 addr;
4316 TCGv_i32 tmp;
4317 TCGv_i32 tmp2;
4318 TCGv_i64 tmp64;
4320 /* FIXME: this access check should not take precedence over UNDEF
4321 * for invalid encodings; we will generate incorrect syndrome information
4322 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4324 if (!s->cpacr_fpen) {
4325 gen_exception_insn(s, 4, EXCP_UDEF,
4326 syn_fp_access_trap(1, 0xe, s->thumb));
4327 return 0;
4330 if (!s->vfp_enabled)
4331 return 1;
4332 VFP_DREG_D(rd, insn);
4333 rn = (insn >> 16) & 0xf;
4334 rm = insn & 0xf;
4335 load = (insn & (1 << 21)) != 0;
4336 if ((insn & (1 << 23)) == 0) {
4337 /* Load store all elements. */
4338 op = (insn >> 8) & 0xf;
4339 size = (insn >> 6) & 3;
4340 if (op > 10)
4341 return 1;
4342 /* Catch UNDEF cases for bad values of align field */
4343 switch (op & 0xc) {
4344 case 4:
4345 if (((insn >> 5) & 1) == 1) {
4346 return 1;
4348 break;
4349 case 8:
4350 if (((insn >> 4) & 3) == 3) {
4351 return 1;
4353 break;
4354 default:
4355 break;
4357 nregs = neon_ls_element_type[op].nregs;
4358 interleave = neon_ls_element_type[op].interleave;
4359 spacing = neon_ls_element_type[op].spacing;
4360 if (size == 3 && (interleave | spacing) != 1)
4361 return 1;
4362 addr = tcg_temp_new_i32();
4363 load_reg_var(s, addr, rn);
4364 stride = (1 << size) * interleave;
4365 for (reg = 0; reg < nregs; reg++) {
4366 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4367 load_reg_var(s, addr, rn);
4368 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4369 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4370 load_reg_var(s, addr, rn);
4371 tcg_gen_addi_i32(addr, addr, 1 << size);
4373 if (size == 3) {
4374 tmp64 = tcg_temp_new_i64();
4375 if (load) {
4376 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4377 neon_store_reg64(tmp64, rd);
4378 } else {
4379 neon_load_reg64(tmp64, rd);
4380 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4382 tcg_temp_free_i64(tmp64);
4383 tcg_gen_addi_i32(addr, addr, stride);
4384 } else {
4385 for (pass = 0; pass < 2; pass++) {
4386 if (size == 2) {
4387 if (load) {
4388 tmp = tcg_temp_new_i32();
4389 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4390 neon_store_reg(rd, pass, tmp);
4391 } else {
4392 tmp = neon_load_reg(rd, pass);
4393 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4394 tcg_temp_free_i32(tmp);
4396 tcg_gen_addi_i32(addr, addr, stride);
4397 } else if (size == 1) {
4398 if (load) {
4399 tmp = tcg_temp_new_i32();
4400 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4401 tcg_gen_addi_i32(addr, addr, stride);
4402 tmp2 = tcg_temp_new_i32();
4403 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4404 tcg_gen_addi_i32(addr, addr, stride);
4405 tcg_gen_shli_i32(tmp2, tmp2, 16);
4406 tcg_gen_or_i32(tmp, tmp, tmp2);
4407 tcg_temp_free_i32(tmp2);
4408 neon_store_reg(rd, pass, tmp);
4409 } else {
4410 tmp = neon_load_reg(rd, pass);
4411 tmp2 = tcg_temp_new_i32();
4412 tcg_gen_shri_i32(tmp2, tmp, 16);
4413 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4414 tcg_temp_free_i32(tmp);
4415 tcg_gen_addi_i32(addr, addr, stride);
4416 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4417 tcg_temp_free_i32(tmp2);
4418 tcg_gen_addi_i32(addr, addr, stride);
4420 } else /* size == 0 */ {
4421 if (load) {
4422 TCGV_UNUSED_I32(tmp2);
4423 for (n = 0; n < 4; n++) {
4424 tmp = tcg_temp_new_i32();
4425 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4426 tcg_gen_addi_i32(addr, addr, stride);
4427 if (n == 0) {
4428 tmp2 = tmp;
4429 } else {
4430 tcg_gen_shli_i32(tmp, tmp, n * 8);
4431 tcg_gen_or_i32(tmp2, tmp2, tmp);
4432 tcg_temp_free_i32(tmp);
4435 neon_store_reg(rd, pass, tmp2);
4436 } else {
4437 tmp2 = neon_load_reg(rd, pass);
4438 for (n = 0; n < 4; n++) {
4439 tmp = tcg_temp_new_i32();
4440 if (n == 0) {
4441 tcg_gen_mov_i32(tmp, tmp2);
4442 } else {
4443 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4445 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4446 tcg_temp_free_i32(tmp);
4447 tcg_gen_addi_i32(addr, addr, stride);
4449 tcg_temp_free_i32(tmp2);
4454 rd += spacing;
4456 tcg_temp_free_i32(addr);
4457 stride = nregs * 8;
4458 } else {
4459 size = (insn >> 10) & 3;
4460 if (size == 3) {
4461 /* Load single element to all lanes. */
4462 int a = (insn >> 4) & 1;
4463 if (!load) {
4464 return 1;
4466 size = (insn >> 6) & 3;
4467 nregs = ((insn >> 8) & 3) + 1;
4469 if (size == 3) {
4470 if (nregs != 4 || a == 0) {
4471 return 1;
4473 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4474 size = 2;
4476 if (nregs == 1 && a == 1 && size == 0) {
4477 return 1;
4479 if (nregs == 3 && a == 1) {
4480 return 1;
4482 addr = tcg_temp_new_i32();
4483 load_reg_var(s, addr, rn);
4484 if (nregs == 1) {
4485 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4486 tmp = gen_load_and_replicate(s, addr, size);
4487 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4488 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4489 if (insn & (1 << 5)) {
4490 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4491 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4493 tcg_temp_free_i32(tmp);
4494 } else {
4495 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4496 stride = (insn & (1 << 5)) ? 2 : 1;
4497 for (reg = 0; reg < nregs; reg++) {
4498 tmp = gen_load_and_replicate(s, addr, size);
4499 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4500 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4501 tcg_temp_free_i32(tmp);
4502 tcg_gen_addi_i32(addr, addr, 1 << size);
4503 rd += stride;
4506 tcg_temp_free_i32(addr);
4507 stride = (1 << size) * nregs;
4508 } else {
4509 /* Single element. */
4510 int idx = (insn >> 4) & 0xf;
4511 pass = (insn >> 7) & 1;
4512 switch (size) {
4513 case 0:
4514 shift = ((insn >> 5) & 3) * 8;
4515 stride = 1;
4516 break;
4517 case 1:
4518 shift = ((insn >> 6) & 1) * 16;
4519 stride = (insn & (1 << 5)) ? 2 : 1;
4520 break;
4521 case 2:
4522 shift = 0;
4523 stride = (insn & (1 << 6)) ? 2 : 1;
4524 break;
4525 default:
4526 abort();
4528 nregs = ((insn >> 8) & 3) + 1;
4529 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4530 switch (nregs) {
4531 case 1:
4532 if (((idx & (1 << size)) != 0) ||
4533 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4534 return 1;
4536 break;
4537 case 3:
4538 if ((idx & 1) != 0) {
4539 return 1;
4541 /* fall through */
4542 case 2:
4543 if (size == 2 && (idx & 2) != 0) {
4544 return 1;
4546 break;
4547 case 4:
4548 if ((size == 2) && ((idx & 3) == 3)) {
4549 return 1;
4551 break;
4552 default:
4553 abort();
4555 if ((rd + stride * (nregs - 1)) > 31) {
4556 /* Attempts to write off the end of the register file
4557 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4558 * the neon_load_reg() would write off the end of the array.
4560 return 1;
4562 addr = tcg_temp_new_i32();
4563 load_reg_var(s, addr, rn);
4564 for (reg = 0; reg < nregs; reg++) {
4565 if (load) {
4566 tmp = tcg_temp_new_i32();
4567 switch (size) {
4568 case 0:
4569 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4570 break;
4571 case 1:
4572 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4573 break;
4574 case 2:
4575 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4576 break;
4577 default: /* Avoid compiler warnings. */
4578 abort();
4580 if (size != 2) {
4581 tmp2 = neon_load_reg(rd, pass);
4582 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4583 shift, size ? 16 : 8);
4584 tcg_temp_free_i32(tmp2);
4586 neon_store_reg(rd, pass, tmp);
4587 } else { /* Store */
4588 tmp = neon_load_reg(rd, pass);
4589 if (shift)
4590 tcg_gen_shri_i32(tmp, tmp, shift);
4591 switch (size) {
4592 case 0:
4593 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4594 break;
4595 case 1:
4596 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4597 break;
4598 case 2:
4599 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4600 break;
4602 tcg_temp_free_i32(tmp);
4604 rd += stride;
4605 tcg_gen_addi_i32(addr, addr, 1 << size);
4607 tcg_temp_free_i32(addr);
4608 stride = nregs * (1 << size);
4611 if (rm != 15) {
4612 TCGv_i32 base;
4614 base = load_reg(s, rn);
4615 if (rm == 13) {
4616 tcg_gen_addi_i32(base, base, stride);
4617 } else {
4618 TCGv_i32 index;
4619 index = load_reg(s, rm);
4620 tcg_gen_add_i32(base, base, index);
4621 tcg_temp_free_i32(index);
4623 store_reg(s, rn, base);
4625 return 0;
4628 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4629 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4631 tcg_gen_and_i32(t, t, c);
4632 tcg_gen_andc_i32(f, f, c);
4633 tcg_gen_or_i32(dest, t, f);
4636 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4638 switch (size) {
4639 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4640 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4641 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4642 default: abort();
4646 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4648 switch (size) {
4649 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4650 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4651 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4652 default: abort();
4656 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4658 switch (size) {
4659 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4660 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4661 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4662 default: abort();
4666 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4668 switch (size) {
4669 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4670 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4671 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4672 default: abort();
4676 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4677 int q, int u)
4679 if (q) {
4680 if (u) {
4681 switch (size) {
4682 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4683 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4684 default: abort();
4686 } else {
4687 switch (size) {
4688 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4689 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4690 default: abort();
4693 } else {
4694 if (u) {
4695 switch (size) {
4696 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4697 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4698 default: abort();
4700 } else {
4701 switch (size) {
4702 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4703 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4704 default: abort();
4710 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4712 if (u) {
4713 switch (size) {
4714 case 0: gen_helper_neon_widen_u8(dest, src); break;
4715 case 1: gen_helper_neon_widen_u16(dest, src); break;
4716 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4717 default: abort();
4719 } else {
4720 switch (size) {
4721 case 0: gen_helper_neon_widen_s8(dest, src); break;
4722 case 1: gen_helper_neon_widen_s16(dest, src); break;
4723 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4724 default: abort();
4727 tcg_temp_free_i32(src);
4730 static inline void gen_neon_addl(int size)
4732 switch (size) {
4733 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4734 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4735 case 2: tcg_gen_add_i64(CPU_V001); break;
4736 default: abort();
4740 static inline void gen_neon_subl(int size)
4742 switch (size) {
4743 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4744 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4745 case 2: tcg_gen_sub_i64(CPU_V001); break;
4746 default: abort();
4750 static inline void gen_neon_negl(TCGv_i64 var, int size)
4752 switch (size) {
4753 case 0: gen_helper_neon_negl_u16(var, var); break;
4754 case 1: gen_helper_neon_negl_u32(var, var); break;
4755 case 2:
4756 tcg_gen_neg_i64(var, var);
4757 break;
4758 default: abort();
4762 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4764 switch (size) {
4765 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4766 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4767 default: abort();
4771 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4772 int size, int u)
4774 TCGv_i64 tmp;
4776 switch ((size << 1) | u) {
4777 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4778 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4779 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4780 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4781 case 4:
4782 tmp = gen_muls_i64_i32(a, b);
4783 tcg_gen_mov_i64(dest, tmp);
4784 tcg_temp_free_i64(tmp);
4785 break;
4786 case 5:
4787 tmp = gen_mulu_i64_i32(a, b);
4788 tcg_gen_mov_i64(dest, tmp);
4789 tcg_temp_free_i64(tmp);
4790 break;
4791 default: abort();
4794 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4795 Don't forget to clean them now. */
4796 if (size < 2) {
4797 tcg_temp_free_i32(a);
4798 tcg_temp_free_i32(b);
4802 static void gen_neon_narrow_op(int op, int u, int size,
4803 TCGv_i32 dest, TCGv_i64 src)
4805 if (op) {
4806 if (u) {
4807 gen_neon_unarrow_sats(size, dest, src);
4808 } else {
4809 gen_neon_narrow(size, dest, src);
4811 } else {
4812 if (u) {
4813 gen_neon_narrow_satu(size, dest, src);
4814 } else {
4815 gen_neon_narrow_sats(size, dest, src);
4820 /* Symbolic constants for op fields for Neon 3-register same-length.
4821 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4822 * table A7-9.
4824 #define NEON_3R_VHADD 0
4825 #define NEON_3R_VQADD 1
4826 #define NEON_3R_VRHADD 2
4827 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4828 #define NEON_3R_VHSUB 4
4829 #define NEON_3R_VQSUB 5
4830 #define NEON_3R_VCGT 6
4831 #define NEON_3R_VCGE 7
4832 #define NEON_3R_VSHL 8
4833 #define NEON_3R_VQSHL 9
4834 #define NEON_3R_VRSHL 10
4835 #define NEON_3R_VQRSHL 11
4836 #define NEON_3R_VMAX 12
4837 #define NEON_3R_VMIN 13
4838 #define NEON_3R_VABD 14
4839 #define NEON_3R_VABA 15
4840 #define NEON_3R_VADD_VSUB 16
4841 #define NEON_3R_VTST_VCEQ 17
4842 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4843 #define NEON_3R_VMUL 19
4844 #define NEON_3R_VPMAX 20
4845 #define NEON_3R_VPMIN 21
4846 #define NEON_3R_VQDMULH_VQRDMULH 22
4847 #define NEON_3R_VPADD 23
4848 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4849 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4850 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4851 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4852 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4853 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4854 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4855 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4857 static const uint8_t neon_3r_sizes[] = {
4858 [NEON_3R_VHADD] = 0x7,
4859 [NEON_3R_VQADD] = 0xf,
4860 [NEON_3R_VRHADD] = 0x7,
4861 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4862 [NEON_3R_VHSUB] = 0x7,
4863 [NEON_3R_VQSUB] = 0xf,
4864 [NEON_3R_VCGT] = 0x7,
4865 [NEON_3R_VCGE] = 0x7,
4866 [NEON_3R_VSHL] = 0xf,
4867 [NEON_3R_VQSHL] = 0xf,
4868 [NEON_3R_VRSHL] = 0xf,
4869 [NEON_3R_VQRSHL] = 0xf,
4870 [NEON_3R_VMAX] = 0x7,
4871 [NEON_3R_VMIN] = 0x7,
4872 [NEON_3R_VABD] = 0x7,
4873 [NEON_3R_VABA] = 0x7,
4874 [NEON_3R_VADD_VSUB] = 0xf,
4875 [NEON_3R_VTST_VCEQ] = 0x7,
4876 [NEON_3R_VML] = 0x7,
4877 [NEON_3R_VMUL] = 0x7,
4878 [NEON_3R_VPMAX] = 0x7,
4879 [NEON_3R_VPMIN] = 0x7,
4880 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4881 [NEON_3R_VPADD] = 0x7,
4882 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4883 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4884 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4885 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4886 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4887 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4888 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4889 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4892 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4893 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4894 * table A7-13.
4896 #define NEON_2RM_VREV64 0
4897 #define NEON_2RM_VREV32 1
4898 #define NEON_2RM_VREV16 2
4899 #define NEON_2RM_VPADDL 4
4900 #define NEON_2RM_VPADDL_U 5
4901 #define NEON_2RM_AESE 6 /* Includes AESD */
4902 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4903 #define NEON_2RM_VCLS 8
4904 #define NEON_2RM_VCLZ 9
4905 #define NEON_2RM_VCNT 10
4906 #define NEON_2RM_VMVN 11
4907 #define NEON_2RM_VPADAL 12
4908 #define NEON_2RM_VPADAL_U 13
4909 #define NEON_2RM_VQABS 14
4910 #define NEON_2RM_VQNEG 15
4911 #define NEON_2RM_VCGT0 16
4912 #define NEON_2RM_VCGE0 17
4913 #define NEON_2RM_VCEQ0 18
4914 #define NEON_2RM_VCLE0 19
4915 #define NEON_2RM_VCLT0 20
4916 #define NEON_2RM_SHA1H 21
4917 #define NEON_2RM_VABS 22
4918 #define NEON_2RM_VNEG 23
4919 #define NEON_2RM_VCGT0_F 24
4920 #define NEON_2RM_VCGE0_F 25
4921 #define NEON_2RM_VCEQ0_F 26
4922 #define NEON_2RM_VCLE0_F 27
4923 #define NEON_2RM_VCLT0_F 28
4924 #define NEON_2RM_VABS_F 30
4925 #define NEON_2RM_VNEG_F 31
4926 #define NEON_2RM_VSWP 32
4927 #define NEON_2RM_VTRN 33
4928 #define NEON_2RM_VUZP 34
4929 #define NEON_2RM_VZIP 35
4930 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4931 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4932 #define NEON_2RM_VSHLL 38
4933 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4934 #define NEON_2RM_VRINTN 40
4935 #define NEON_2RM_VRINTX 41
4936 #define NEON_2RM_VRINTA 42
4937 #define NEON_2RM_VRINTZ 43
4938 #define NEON_2RM_VCVT_F16_F32 44
4939 #define NEON_2RM_VRINTM 45
4940 #define NEON_2RM_VCVT_F32_F16 46
4941 #define NEON_2RM_VRINTP 47
4942 #define NEON_2RM_VCVTAU 48
4943 #define NEON_2RM_VCVTAS 49
4944 #define NEON_2RM_VCVTNU 50
4945 #define NEON_2RM_VCVTNS 51
4946 #define NEON_2RM_VCVTPU 52
4947 #define NEON_2RM_VCVTPS 53
4948 #define NEON_2RM_VCVTMU 54
4949 #define NEON_2RM_VCVTMS 55
4950 #define NEON_2RM_VRECPE 56
4951 #define NEON_2RM_VRSQRTE 57
4952 #define NEON_2RM_VRECPE_F 58
4953 #define NEON_2RM_VRSQRTE_F 59
4954 #define NEON_2RM_VCVT_FS 60
4955 #define NEON_2RM_VCVT_FU 61
4956 #define NEON_2RM_VCVT_SF 62
4957 #define NEON_2RM_VCVT_UF 63
4959 static int neon_2rm_is_float_op(int op)
4961 /* Return true if this neon 2reg-misc op is float-to-float */
4962 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4963 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4964 op == NEON_2RM_VRINTM ||
4965 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4966 op >= NEON_2RM_VRECPE_F);
4969 /* Each entry in this array has bit n set if the insn allows
4970 * size value n (otherwise it will UNDEF). Since unallocated
4971 * op values will have no bits set they always UNDEF.
4973 static const uint8_t neon_2rm_sizes[] = {
4974 [NEON_2RM_VREV64] = 0x7,
4975 [NEON_2RM_VREV32] = 0x3,
4976 [NEON_2RM_VREV16] = 0x1,
4977 [NEON_2RM_VPADDL] = 0x7,
4978 [NEON_2RM_VPADDL_U] = 0x7,
4979 [NEON_2RM_AESE] = 0x1,
4980 [NEON_2RM_AESMC] = 0x1,
4981 [NEON_2RM_VCLS] = 0x7,
4982 [NEON_2RM_VCLZ] = 0x7,
4983 [NEON_2RM_VCNT] = 0x1,
4984 [NEON_2RM_VMVN] = 0x1,
4985 [NEON_2RM_VPADAL] = 0x7,
4986 [NEON_2RM_VPADAL_U] = 0x7,
4987 [NEON_2RM_VQABS] = 0x7,
4988 [NEON_2RM_VQNEG] = 0x7,
4989 [NEON_2RM_VCGT0] = 0x7,
4990 [NEON_2RM_VCGE0] = 0x7,
4991 [NEON_2RM_VCEQ0] = 0x7,
4992 [NEON_2RM_VCLE0] = 0x7,
4993 [NEON_2RM_VCLT0] = 0x7,
4994 [NEON_2RM_SHA1H] = 0x4,
4995 [NEON_2RM_VABS] = 0x7,
4996 [NEON_2RM_VNEG] = 0x7,
4997 [NEON_2RM_VCGT0_F] = 0x4,
4998 [NEON_2RM_VCGE0_F] = 0x4,
4999 [NEON_2RM_VCEQ0_F] = 0x4,
5000 [NEON_2RM_VCLE0_F] = 0x4,
5001 [NEON_2RM_VCLT0_F] = 0x4,
5002 [NEON_2RM_VABS_F] = 0x4,
5003 [NEON_2RM_VNEG_F] = 0x4,
5004 [NEON_2RM_VSWP] = 0x1,
5005 [NEON_2RM_VTRN] = 0x7,
5006 [NEON_2RM_VUZP] = 0x7,
5007 [NEON_2RM_VZIP] = 0x7,
5008 [NEON_2RM_VMOVN] = 0x7,
5009 [NEON_2RM_VQMOVN] = 0x7,
5010 [NEON_2RM_VSHLL] = 0x7,
5011 [NEON_2RM_SHA1SU1] = 0x4,
5012 [NEON_2RM_VRINTN] = 0x4,
5013 [NEON_2RM_VRINTX] = 0x4,
5014 [NEON_2RM_VRINTA] = 0x4,
5015 [NEON_2RM_VRINTZ] = 0x4,
5016 [NEON_2RM_VCVT_F16_F32] = 0x2,
5017 [NEON_2RM_VRINTM] = 0x4,
5018 [NEON_2RM_VCVT_F32_F16] = 0x2,
5019 [NEON_2RM_VRINTP] = 0x4,
5020 [NEON_2RM_VCVTAU] = 0x4,
5021 [NEON_2RM_VCVTAS] = 0x4,
5022 [NEON_2RM_VCVTNU] = 0x4,
5023 [NEON_2RM_VCVTNS] = 0x4,
5024 [NEON_2RM_VCVTPU] = 0x4,
5025 [NEON_2RM_VCVTPS] = 0x4,
5026 [NEON_2RM_VCVTMU] = 0x4,
5027 [NEON_2RM_VCVTMS] = 0x4,
5028 [NEON_2RM_VRECPE] = 0x4,
5029 [NEON_2RM_VRSQRTE] = 0x4,
5030 [NEON_2RM_VRECPE_F] = 0x4,
5031 [NEON_2RM_VRSQRTE_F] = 0x4,
5032 [NEON_2RM_VCVT_FS] = 0x4,
5033 [NEON_2RM_VCVT_FU] = 0x4,
5034 [NEON_2RM_VCVT_SF] = 0x4,
5035 [NEON_2RM_VCVT_UF] = 0x4,
5038 /* Translate a NEON data processing instruction. Return nonzero if the
5039 instruction is invalid.
5040 We process data in a mixture of 32-bit and 64-bit chunks.
5041 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5043 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
5045 int op;
5046 int q;
5047 int rd, rn, rm;
5048 int size;
5049 int shift;
5050 int pass;
5051 int count;
5052 int pairwise;
5053 int u;
5054 uint32_t imm, mask;
5055 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5056 TCGv_i64 tmp64;
5058 /* FIXME: this access check should not take precedence over UNDEF
5059 * for invalid encodings; we will generate incorrect syndrome information
5060 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5062 if (!s->cpacr_fpen) {
5063 gen_exception_insn(s, 4, EXCP_UDEF,
5064 syn_fp_access_trap(1, 0xe, s->thumb));
5065 return 0;
5068 if (!s->vfp_enabled)
5069 return 1;
5070 q = (insn & (1 << 6)) != 0;
5071 u = (insn >> 24) & 1;
5072 VFP_DREG_D(rd, insn);
5073 VFP_DREG_N(rn, insn);
5074 VFP_DREG_M(rm, insn);
5075 size = (insn >> 20) & 3;
5076 if ((insn & (1 << 23)) == 0) {
5077 /* Three register same length. */
5078 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5079 /* Catch invalid op and bad size combinations: UNDEF */
5080 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5081 return 1;
5083 /* All insns of this form UNDEF for either this condition or the
5084 * superset of cases "Q==1"; we catch the latter later.
5086 if (q && ((rd | rn | rm) & 1)) {
5087 return 1;
5090 * The SHA-1/SHA-256 3-register instructions require special treatment
5091 * here, as their size field is overloaded as an op type selector, and
5092 * they all consume their input in a single pass.
5094 if (op == NEON_3R_SHA) {
5095 if (!q) {
5096 return 1;
5098 if (!u) { /* SHA-1 */
5099 if (!arm_feature(env, ARM_FEATURE_V8_SHA1)) {
5100 return 1;
5102 tmp = tcg_const_i32(rd);
5103 tmp2 = tcg_const_i32(rn);
5104 tmp3 = tcg_const_i32(rm);
5105 tmp4 = tcg_const_i32(size);
5106 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5107 tcg_temp_free_i32(tmp4);
5108 } else { /* SHA-256 */
5109 if (!arm_feature(env, ARM_FEATURE_V8_SHA256) || size == 3) {
5110 return 1;
5112 tmp = tcg_const_i32(rd);
5113 tmp2 = tcg_const_i32(rn);
5114 tmp3 = tcg_const_i32(rm);
5115 switch (size) {
5116 case 0:
5117 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5118 break;
5119 case 1:
5120 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5121 break;
5122 case 2:
5123 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5124 break;
5127 tcg_temp_free_i32(tmp);
5128 tcg_temp_free_i32(tmp2);
5129 tcg_temp_free_i32(tmp3);
5130 return 0;
5132 if (size == 3 && op != NEON_3R_LOGIC) {
5133 /* 64-bit element instructions. */
5134 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5135 neon_load_reg64(cpu_V0, rn + pass);
5136 neon_load_reg64(cpu_V1, rm + pass);
5137 switch (op) {
5138 case NEON_3R_VQADD:
5139 if (u) {
5140 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5141 cpu_V0, cpu_V1);
5142 } else {
5143 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5144 cpu_V0, cpu_V1);
5146 break;
5147 case NEON_3R_VQSUB:
5148 if (u) {
5149 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5150 cpu_V0, cpu_V1);
5151 } else {
5152 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5153 cpu_V0, cpu_V1);
5155 break;
5156 case NEON_3R_VSHL:
5157 if (u) {
5158 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5159 } else {
5160 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5162 break;
5163 case NEON_3R_VQSHL:
5164 if (u) {
5165 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5166 cpu_V1, cpu_V0);
5167 } else {
5168 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5169 cpu_V1, cpu_V0);
5171 break;
5172 case NEON_3R_VRSHL:
5173 if (u) {
5174 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5175 } else {
5176 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5178 break;
5179 case NEON_3R_VQRSHL:
5180 if (u) {
5181 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5182 cpu_V1, cpu_V0);
5183 } else {
5184 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5185 cpu_V1, cpu_V0);
5187 break;
5188 case NEON_3R_VADD_VSUB:
5189 if (u) {
5190 tcg_gen_sub_i64(CPU_V001);
5191 } else {
5192 tcg_gen_add_i64(CPU_V001);
5194 break;
5195 default:
5196 abort();
5198 neon_store_reg64(cpu_V0, rd + pass);
5200 return 0;
5202 pairwise = 0;
5203 switch (op) {
5204 case NEON_3R_VSHL:
5205 case NEON_3R_VQSHL:
5206 case NEON_3R_VRSHL:
5207 case NEON_3R_VQRSHL:
5209 int rtmp;
5210 /* Shift instruction operands are reversed. */
5211 rtmp = rn;
5212 rn = rm;
5213 rm = rtmp;
5215 break;
5216 case NEON_3R_VPADD:
5217 if (u) {
5218 return 1;
5220 /* Fall through */
5221 case NEON_3R_VPMAX:
5222 case NEON_3R_VPMIN:
5223 pairwise = 1;
5224 break;
5225 case NEON_3R_FLOAT_ARITH:
5226 pairwise = (u && size < 2); /* if VPADD (float) */
5227 break;
5228 case NEON_3R_FLOAT_MINMAX:
5229 pairwise = u; /* if VPMIN/VPMAX (float) */
5230 break;
5231 case NEON_3R_FLOAT_CMP:
5232 if (!u && size) {
5233 /* no encoding for U=0 C=1x */
5234 return 1;
5236 break;
5237 case NEON_3R_FLOAT_ACMP:
5238 if (!u) {
5239 return 1;
5241 break;
5242 case NEON_3R_FLOAT_MISC:
5243 /* VMAXNM/VMINNM in ARMv8 */
5244 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5245 return 1;
5247 break;
5248 case NEON_3R_VMUL:
5249 if (u && (size != 0)) {
5250 /* UNDEF on invalid size for polynomial subcase */
5251 return 1;
5253 break;
5254 case NEON_3R_VFM:
5255 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5256 return 1;
5258 break;
5259 default:
5260 break;
5263 if (pairwise && q) {
5264 /* All the pairwise insns UNDEF if Q is set */
5265 return 1;
5268 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5270 if (pairwise) {
5271 /* Pairwise. */
5272 if (pass < 1) {
5273 tmp = neon_load_reg(rn, 0);
5274 tmp2 = neon_load_reg(rn, 1);
5275 } else {
5276 tmp = neon_load_reg(rm, 0);
5277 tmp2 = neon_load_reg(rm, 1);
5279 } else {
5280 /* Elementwise. */
5281 tmp = neon_load_reg(rn, pass);
5282 tmp2 = neon_load_reg(rm, pass);
5284 switch (op) {
5285 case NEON_3R_VHADD:
5286 GEN_NEON_INTEGER_OP(hadd);
5287 break;
5288 case NEON_3R_VQADD:
5289 GEN_NEON_INTEGER_OP_ENV(qadd);
5290 break;
5291 case NEON_3R_VRHADD:
5292 GEN_NEON_INTEGER_OP(rhadd);
5293 break;
5294 case NEON_3R_LOGIC: /* Logic ops. */
5295 switch ((u << 2) | size) {
5296 case 0: /* VAND */
5297 tcg_gen_and_i32(tmp, tmp, tmp2);
5298 break;
5299 case 1: /* BIC */
5300 tcg_gen_andc_i32(tmp, tmp, tmp2);
5301 break;
5302 case 2: /* VORR */
5303 tcg_gen_or_i32(tmp, tmp, tmp2);
5304 break;
5305 case 3: /* VORN */
5306 tcg_gen_orc_i32(tmp, tmp, tmp2);
5307 break;
5308 case 4: /* VEOR */
5309 tcg_gen_xor_i32(tmp, tmp, tmp2);
5310 break;
5311 case 5: /* VBSL */
5312 tmp3 = neon_load_reg(rd, pass);
5313 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5314 tcg_temp_free_i32(tmp3);
5315 break;
5316 case 6: /* VBIT */
5317 tmp3 = neon_load_reg(rd, pass);
5318 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5319 tcg_temp_free_i32(tmp3);
5320 break;
5321 case 7: /* VBIF */
5322 tmp3 = neon_load_reg(rd, pass);
5323 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5324 tcg_temp_free_i32(tmp3);
5325 break;
5327 break;
5328 case NEON_3R_VHSUB:
5329 GEN_NEON_INTEGER_OP(hsub);
5330 break;
5331 case NEON_3R_VQSUB:
5332 GEN_NEON_INTEGER_OP_ENV(qsub);
5333 break;
5334 case NEON_3R_VCGT:
5335 GEN_NEON_INTEGER_OP(cgt);
5336 break;
5337 case NEON_3R_VCGE:
5338 GEN_NEON_INTEGER_OP(cge);
5339 break;
5340 case NEON_3R_VSHL:
5341 GEN_NEON_INTEGER_OP(shl);
5342 break;
5343 case NEON_3R_VQSHL:
5344 GEN_NEON_INTEGER_OP_ENV(qshl);
5345 break;
5346 case NEON_3R_VRSHL:
5347 GEN_NEON_INTEGER_OP(rshl);
5348 break;
5349 case NEON_3R_VQRSHL:
5350 GEN_NEON_INTEGER_OP_ENV(qrshl);
5351 break;
5352 case NEON_3R_VMAX:
5353 GEN_NEON_INTEGER_OP(max);
5354 break;
5355 case NEON_3R_VMIN:
5356 GEN_NEON_INTEGER_OP(min);
5357 break;
5358 case NEON_3R_VABD:
5359 GEN_NEON_INTEGER_OP(abd);
5360 break;
5361 case NEON_3R_VABA:
5362 GEN_NEON_INTEGER_OP(abd);
5363 tcg_temp_free_i32(tmp2);
5364 tmp2 = neon_load_reg(rd, pass);
5365 gen_neon_add(size, tmp, tmp2);
5366 break;
5367 case NEON_3R_VADD_VSUB:
5368 if (!u) { /* VADD */
5369 gen_neon_add(size, tmp, tmp2);
5370 } else { /* VSUB */
5371 switch (size) {
5372 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5373 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5374 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5375 default: abort();
5378 break;
5379 case NEON_3R_VTST_VCEQ:
5380 if (!u) { /* VTST */
5381 switch (size) {
5382 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5383 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5384 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5385 default: abort();
5387 } else { /* VCEQ */
5388 switch (size) {
5389 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5390 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5391 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5392 default: abort();
5395 break;
5396 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5397 switch (size) {
5398 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5399 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5400 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5401 default: abort();
5403 tcg_temp_free_i32(tmp2);
5404 tmp2 = neon_load_reg(rd, pass);
5405 if (u) { /* VMLS */
5406 gen_neon_rsb(size, tmp, tmp2);
5407 } else { /* VMLA */
5408 gen_neon_add(size, tmp, tmp2);
5410 break;
5411 case NEON_3R_VMUL:
5412 if (u) { /* polynomial */
5413 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5414 } else { /* Integer */
5415 switch (size) {
5416 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5417 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5418 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5419 default: abort();
5422 break;
5423 case NEON_3R_VPMAX:
5424 GEN_NEON_INTEGER_OP(pmax);
5425 break;
5426 case NEON_3R_VPMIN:
5427 GEN_NEON_INTEGER_OP(pmin);
5428 break;
5429 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5430 if (!u) { /* VQDMULH */
5431 switch (size) {
5432 case 1:
5433 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5434 break;
5435 case 2:
5436 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5437 break;
5438 default: abort();
5440 } else { /* VQRDMULH */
5441 switch (size) {
5442 case 1:
5443 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5444 break;
5445 case 2:
5446 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5447 break;
5448 default: abort();
5451 break;
5452 case NEON_3R_VPADD:
5453 switch (size) {
5454 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5455 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5456 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5457 default: abort();
5459 break;
5460 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5462 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5463 switch ((u << 2) | size) {
5464 case 0: /* VADD */
5465 case 4: /* VPADD */
5466 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5467 break;
5468 case 2: /* VSUB */
5469 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5470 break;
5471 case 6: /* VABD */
5472 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5473 break;
5474 default:
5475 abort();
5477 tcg_temp_free_ptr(fpstatus);
5478 break;
5480 case NEON_3R_FLOAT_MULTIPLY:
5482 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5483 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5484 if (!u) {
5485 tcg_temp_free_i32(tmp2);
5486 tmp2 = neon_load_reg(rd, pass);
5487 if (size == 0) {
5488 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5489 } else {
5490 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5493 tcg_temp_free_ptr(fpstatus);
5494 break;
5496 case NEON_3R_FLOAT_CMP:
5498 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5499 if (!u) {
5500 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5501 } else {
5502 if (size == 0) {
5503 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5504 } else {
5505 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5508 tcg_temp_free_ptr(fpstatus);
5509 break;
5511 case NEON_3R_FLOAT_ACMP:
5513 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5514 if (size == 0) {
5515 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5516 } else {
5517 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5519 tcg_temp_free_ptr(fpstatus);
5520 break;
5522 case NEON_3R_FLOAT_MINMAX:
5524 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5525 if (size == 0) {
5526 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5527 } else {
5528 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5530 tcg_temp_free_ptr(fpstatus);
5531 break;
5533 case NEON_3R_FLOAT_MISC:
5534 if (u) {
5535 /* VMAXNM/VMINNM */
5536 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5537 if (size == 0) {
5538 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5539 } else {
5540 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5542 tcg_temp_free_ptr(fpstatus);
5543 } else {
5544 if (size == 0) {
5545 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5546 } else {
5547 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5550 break;
5551 case NEON_3R_VFM:
5553 /* VFMA, VFMS: fused multiply-add */
5554 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5555 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5556 if (size) {
5557 /* VFMS */
5558 gen_helper_vfp_negs(tmp, tmp);
5560 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5561 tcg_temp_free_i32(tmp3);
5562 tcg_temp_free_ptr(fpstatus);
5563 break;
5565 default:
5566 abort();
5568 tcg_temp_free_i32(tmp2);
5570 /* Save the result. For elementwise operations we can put it
5571 straight into the destination register. For pairwise operations
5572 we have to be careful to avoid clobbering the source operands. */
5573 if (pairwise && rd == rm) {
5574 neon_store_scratch(pass, tmp);
5575 } else {
5576 neon_store_reg(rd, pass, tmp);
5579 } /* for pass */
5580 if (pairwise && rd == rm) {
5581 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5582 tmp = neon_load_scratch(pass);
5583 neon_store_reg(rd, pass, tmp);
5586 /* End of 3 register same size operations. */
5587 } else if (insn & (1 << 4)) {
5588 if ((insn & 0x00380080) != 0) {
5589 /* Two registers and shift. */
5590 op = (insn >> 8) & 0xf;
5591 if (insn & (1 << 7)) {
5592 /* 64-bit shift. */
5593 if (op > 7) {
5594 return 1;
5596 size = 3;
5597 } else {
5598 size = 2;
5599 while ((insn & (1 << (size + 19))) == 0)
5600 size--;
5602 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5603 /* To avoid excessive duplication of ops we implement shift
5604 by immediate using the variable shift operations. */
5605 if (op < 8) {
5606 /* Shift by immediate:
5607 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5608 if (q && ((rd | rm) & 1)) {
5609 return 1;
5611 if (!u && (op == 4 || op == 6)) {
5612 return 1;
5614 /* Right shifts are encoded as N - shift, where N is the
5615 element size in bits. */
5616 if (op <= 4)
5617 shift = shift - (1 << (size + 3));
5618 if (size == 3) {
5619 count = q + 1;
5620 } else {
5621 count = q ? 4: 2;
5623 switch (size) {
5624 case 0:
5625 imm = (uint8_t) shift;
5626 imm |= imm << 8;
5627 imm |= imm << 16;
5628 break;
5629 case 1:
5630 imm = (uint16_t) shift;
5631 imm |= imm << 16;
5632 break;
5633 case 2:
5634 case 3:
5635 imm = shift;
5636 break;
5637 default:
5638 abort();
5641 for (pass = 0; pass < count; pass++) {
5642 if (size == 3) {
5643 neon_load_reg64(cpu_V0, rm + pass);
5644 tcg_gen_movi_i64(cpu_V1, imm);
5645 switch (op) {
5646 case 0: /* VSHR */
5647 case 1: /* VSRA */
5648 if (u)
5649 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5650 else
5651 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5652 break;
5653 case 2: /* VRSHR */
5654 case 3: /* VRSRA */
5655 if (u)
5656 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5657 else
5658 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5659 break;
5660 case 4: /* VSRI */
5661 case 5: /* VSHL, VSLI */
5662 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5663 break;
5664 case 6: /* VQSHLU */
5665 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5666 cpu_V0, cpu_V1);
5667 break;
5668 case 7: /* VQSHL */
5669 if (u) {
5670 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5671 cpu_V0, cpu_V1);
5672 } else {
5673 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5674 cpu_V0, cpu_V1);
5676 break;
5678 if (op == 1 || op == 3) {
5679 /* Accumulate. */
5680 neon_load_reg64(cpu_V1, rd + pass);
5681 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5682 } else if (op == 4 || (op == 5 && u)) {
5683 /* Insert */
5684 neon_load_reg64(cpu_V1, rd + pass);
5685 uint64_t mask;
5686 if (shift < -63 || shift > 63) {
5687 mask = 0;
5688 } else {
5689 if (op == 4) {
5690 mask = 0xffffffffffffffffull >> -shift;
5691 } else {
5692 mask = 0xffffffffffffffffull << shift;
5695 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5696 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5698 neon_store_reg64(cpu_V0, rd + pass);
5699 } else { /* size < 3 */
5700 /* Operands in T0 and T1. */
5701 tmp = neon_load_reg(rm, pass);
5702 tmp2 = tcg_temp_new_i32();
5703 tcg_gen_movi_i32(tmp2, imm);
5704 switch (op) {
5705 case 0: /* VSHR */
5706 case 1: /* VSRA */
5707 GEN_NEON_INTEGER_OP(shl);
5708 break;
5709 case 2: /* VRSHR */
5710 case 3: /* VRSRA */
5711 GEN_NEON_INTEGER_OP(rshl);
5712 break;
5713 case 4: /* VSRI */
5714 case 5: /* VSHL, VSLI */
5715 switch (size) {
5716 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5717 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5718 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5719 default: abort();
5721 break;
5722 case 6: /* VQSHLU */
5723 switch (size) {
5724 case 0:
5725 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5726 tmp, tmp2);
5727 break;
5728 case 1:
5729 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5730 tmp, tmp2);
5731 break;
5732 case 2:
5733 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5734 tmp, tmp2);
5735 break;
5736 default:
5737 abort();
5739 break;
5740 case 7: /* VQSHL */
5741 GEN_NEON_INTEGER_OP_ENV(qshl);
5742 break;
5744 tcg_temp_free_i32(tmp2);
5746 if (op == 1 || op == 3) {
5747 /* Accumulate. */
5748 tmp2 = neon_load_reg(rd, pass);
5749 gen_neon_add(size, tmp, tmp2);
5750 tcg_temp_free_i32(tmp2);
5751 } else if (op == 4 || (op == 5 && u)) {
5752 /* Insert */
5753 switch (size) {
5754 case 0:
5755 if (op == 4)
5756 mask = 0xff >> -shift;
5757 else
5758 mask = (uint8_t)(0xff << shift);
5759 mask |= mask << 8;
5760 mask |= mask << 16;
5761 break;
5762 case 1:
5763 if (op == 4)
5764 mask = 0xffff >> -shift;
5765 else
5766 mask = (uint16_t)(0xffff << shift);
5767 mask |= mask << 16;
5768 break;
5769 case 2:
5770 if (shift < -31 || shift > 31) {
5771 mask = 0;
5772 } else {
5773 if (op == 4)
5774 mask = 0xffffffffu >> -shift;
5775 else
5776 mask = 0xffffffffu << shift;
5778 break;
5779 default:
5780 abort();
5782 tmp2 = neon_load_reg(rd, pass);
5783 tcg_gen_andi_i32(tmp, tmp, mask);
5784 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5785 tcg_gen_or_i32(tmp, tmp, tmp2);
5786 tcg_temp_free_i32(tmp2);
5788 neon_store_reg(rd, pass, tmp);
5790 } /* for pass */
5791 } else if (op < 10) {
5792 /* Shift by immediate and narrow:
5793 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5794 int input_unsigned = (op == 8) ? !u : u;
5795 if (rm & 1) {
5796 return 1;
5798 shift = shift - (1 << (size + 3));
5799 size++;
5800 if (size == 3) {
5801 tmp64 = tcg_const_i64(shift);
5802 neon_load_reg64(cpu_V0, rm);
5803 neon_load_reg64(cpu_V1, rm + 1);
5804 for (pass = 0; pass < 2; pass++) {
5805 TCGv_i64 in;
5806 if (pass == 0) {
5807 in = cpu_V0;
5808 } else {
5809 in = cpu_V1;
5811 if (q) {
5812 if (input_unsigned) {
5813 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5814 } else {
5815 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5817 } else {
5818 if (input_unsigned) {
5819 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5820 } else {
5821 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5824 tmp = tcg_temp_new_i32();
5825 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5826 neon_store_reg(rd, pass, tmp);
5827 } /* for pass */
5828 tcg_temp_free_i64(tmp64);
5829 } else {
5830 if (size == 1) {
5831 imm = (uint16_t)shift;
5832 imm |= imm << 16;
5833 } else {
5834 /* size == 2 */
5835 imm = (uint32_t)shift;
5837 tmp2 = tcg_const_i32(imm);
5838 tmp4 = neon_load_reg(rm + 1, 0);
5839 tmp5 = neon_load_reg(rm + 1, 1);
5840 for (pass = 0; pass < 2; pass++) {
5841 if (pass == 0) {
5842 tmp = neon_load_reg(rm, 0);
5843 } else {
5844 tmp = tmp4;
5846 gen_neon_shift_narrow(size, tmp, tmp2, q,
5847 input_unsigned);
5848 if (pass == 0) {
5849 tmp3 = neon_load_reg(rm, 1);
5850 } else {
5851 tmp3 = tmp5;
5853 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5854 input_unsigned);
5855 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5856 tcg_temp_free_i32(tmp);
5857 tcg_temp_free_i32(tmp3);
5858 tmp = tcg_temp_new_i32();
5859 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5860 neon_store_reg(rd, pass, tmp);
5861 } /* for pass */
5862 tcg_temp_free_i32(tmp2);
5864 } else if (op == 10) {
5865 /* VSHLL, VMOVL */
5866 if (q || (rd & 1)) {
5867 return 1;
5869 tmp = neon_load_reg(rm, 0);
5870 tmp2 = neon_load_reg(rm, 1);
5871 for (pass = 0; pass < 2; pass++) {
5872 if (pass == 1)
5873 tmp = tmp2;
5875 gen_neon_widen(cpu_V0, tmp, size, u);
5877 if (shift != 0) {
5878 /* The shift is less than the width of the source
5879 type, so we can just shift the whole register. */
5880 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5881 /* Widen the result of shift: we need to clear
5882 * the potential overflow bits resulting from
5883 * left bits of the narrow input appearing as
5884 * right bits of left the neighbour narrow
5885 * input. */
5886 if (size < 2 || !u) {
5887 uint64_t imm64;
5888 if (size == 0) {
5889 imm = (0xffu >> (8 - shift));
5890 imm |= imm << 16;
5891 } else if (size == 1) {
5892 imm = 0xffff >> (16 - shift);
5893 } else {
5894 /* size == 2 */
5895 imm = 0xffffffff >> (32 - shift);
5897 if (size < 2) {
5898 imm64 = imm | (((uint64_t)imm) << 32);
5899 } else {
5900 imm64 = imm;
5902 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5905 neon_store_reg64(cpu_V0, rd + pass);
5907 } else if (op >= 14) {
5908 /* VCVT fixed-point. */
5909 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5910 return 1;
5912 /* We have already masked out the must-be-1 top bit of imm6,
5913 * hence this 32-shift where the ARM ARM has 64-imm6.
5915 shift = 32 - shift;
5916 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5917 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5918 if (!(op & 1)) {
5919 if (u)
5920 gen_vfp_ulto(0, shift, 1);
5921 else
5922 gen_vfp_slto(0, shift, 1);
5923 } else {
5924 if (u)
5925 gen_vfp_toul(0, shift, 1);
5926 else
5927 gen_vfp_tosl(0, shift, 1);
5929 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5931 } else {
5932 return 1;
5934 } else { /* (insn & 0x00380080) == 0 */
5935 int invert;
5936 if (q && (rd & 1)) {
5937 return 1;
5940 op = (insn >> 8) & 0xf;
5941 /* One register and immediate. */
5942 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5943 invert = (insn & (1 << 5)) != 0;
5944 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5945 * We choose to not special-case this and will behave as if a
5946 * valid constant encoding of 0 had been given.
5948 switch (op) {
5949 case 0: case 1:
5950 /* no-op */
5951 break;
5952 case 2: case 3:
5953 imm <<= 8;
5954 break;
5955 case 4: case 5:
5956 imm <<= 16;
5957 break;
5958 case 6: case 7:
5959 imm <<= 24;
5960 break;
5961 case 8: case 9:
5962 imm |= imm << 16;
5963 break;
5964 case 10: case 11:
5965 imm = (imm << 8) | (imm << 24);
5966 break;
5967 case 12:
5968 imm = (imm << 8) | 0xff;
5969 break;
5970 case 13:
5971 imm = (imm << 16) | 0xffff;
5972 break;
5973 case 14:
5974 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5975 if (invert)
5976 imm = ~imm;
5977 break;
5978 case 15:
5979 if (invert) {
5980 return 1;
5982 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5983 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5984 break;
5986 if (invert)
5987 imm = ~imm;
5989 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5990 if (op & 1 && op < 12) {
5991 tmp = neon_load_reg(rd, pass);
5992 if (invert) {
5993 /* The immediate value has already been inverted, so
5994 BIC becomes AND. */
5995 tcg_gen_andi_i32(tmp, tmp, imm);
5996 } else {
5997 tcg_gen_ori_i32(tmp, tmp, imm);
5999 } else {
6000 /* VMOV, VMVN. */
6001 tmp = tcg_temp_new_i32();
6002 if (op == 14 && invert) {
6003 int n;
6004 uint32_t val;
6005 val = 0;
6006 for (n = 0; n < 4; n++) {
6007 if (imm & (1 << (n + (pass & 1) * 4)))
6008 val |= 0xff << (n * 8);
6010 tcg_gen_movi_i32(tmp, val);
6011 } else {
6012 tcg_gen_movi_i32(tmp, imm);
6015 neon_store_reg(rd, pass, tmp);
6018 } else { /* (insn & 0x00800010 == 0x00800000) */
6019 if (size != 3) {
6020 op = (insn >> 8) & 0xf;
6021 if ((insn & (1 << 6)) == 0) {
6022 /* Three registers of different lengths. */
6023 int src1_wide;
6024 int src2_wide;
6025 int prewiden;
6026 /* undefreq: bit 0 : UNDEF if size == 0
6027 * bit 1 : UNDEF if size == 1
6028 * bit 2 : UNDEF if size == 2
6029 * bit 3 : UNDEF if U == 1
6030 * Note that [2:0] set implies 'always UNDEF'
6032 int undefreq;
6033 /* prewiden, src1_wide, src2_wide, undefreq */
6034 static const int neon_3reg_wide[16][4] = {
6035 {1, 0, 0, 0}, /* VADDL */
6036 {1, 1, 0, 0}, /* VADDW */
6037 {1, 0, 0, 0}, /* VSUBL */
6038 {1, 1, 0, 0}, /* VSUBW */
6039 {0, 1, 1, 0}, /* VADDHN */
6040 {0, 0, 0, 0}, /* VABAL */
6041 {0, 1, 1, 0}, /* VSUBHN */
6042 {0, 0, 0, 0}, /* VABDL */
6043 {0, 0, 0, 0}, /* VMLAL */
6044 {0, 0, 0, 9}, /* VQDMLAL */
6045 {0, 0, 0, 0}, /* VMLSL */
6046 {0, 0, 0, 9}, /* VQDMLSL */
6047 {0, 0, 0, 0}, /* Integer VMULL */
6048 {0, 0, 0, 1}, /* VQDMULL */
6049 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6050 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6053 prewiden = neon_3reg_wide[op][0];
6054 src1_wide = neon_3reg_wide[op][1];
6055 src2_wide = neon_3reg_wide[op][2];
6056 undefreq = neon_3reg_wide[op][3];
6058 if ((undefreq & (1 << size)) ||
6059 ((undefreq & 8) && u)) {
6060 return 1;
6062 if ((src1_wide && (rn & 1)) ||
6063 (src2_wide && (rm & 1)) ||
6064 (!src2_wide && (rd & 1))) {
6065 return 1;
6068 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6069 * outside the loop below as it only performs a single pass.
6071 if (op == 14 && size == 2) {
6072 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6074 if (!arm_feature(env, ARM_FEATURE_V8_PMULL)) {
6075 return 1;
6077 tcg_rn = tcg_temp_new_i64();
6078 tcg_rm = tcg_temp_new_i64();
6079 tcg_rd = tcg_temp_new_i64();
6080 neon_load_reg64(tcg_rn, rn);
6081 neon_load_reg64(tcg_rm, rm);
6082 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6083 neon_store_reg64(tcg_rd, rd);
6084 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6085 neon_store_reg64(tcg_rd, rd + 1);
6086 tcg_temp_free_i64(tcg_rn);
6087 tcg_temp_free_i64(tcg_rm);
6088 tcg_temp_free_i64(tcg_rd);
6089 return 0;
6092 /* Avoid overlapping operands. Wide source operands are
6093 always aligned so will never overlap with wide
6094 destinations in problematic ways. */
6095 if (rd == rm && !src2_wide) {
6096 tmp = neon_load_reg(rm, 1);
6097 neon_store_scratch(2, tmp);
6098 } else if (rd == rn && !src1_wide) {
6099 tmp = neon_load_reg(rn, 1);
6100 neon_store_scratch(2, tmp);
6102 TCGV_UNUSED_I32(tmp3);
6103 for (pass = 0; pass < 2; pass++) {
6104 if (src1_wide) {
6105 neon_load_reg64(cpu_V0, rn + pass);
6106 TCGV_UNUSED_I32(tmp);
6107 } else {
6108 if (pass == 1 && rd == rn) {
6109 tmp = neon_load_scratch(2);
6110 } else {
6111 tmp = neon_load_reg(rn, pass);
6113 if (prewiden) {
6114 gen_neon_widen(cpu_V0, tmp, size, u);
6117 if (src2_wide) {
6118 neon_load_reg64(cpu_V1, rm + pass);
6119 TCGV_UNUSED_I32(tmp2);
6120 } else {
6121 if (pass == 1 && rd == rm) {
6122 tmp2 = neon_load_scratch(2);
6123 } else {
6124 tmp2 = neon_load_reg(rm, pass);
6126 if (prewiden) {
6127 gen_neon_widen(cpu_V1, tmp2, size, u);
6130 switch (op) {
6131 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6132 gen_neon_addl(size);
6133 break;
6134 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6135 gen_neon_subl(size);
6136 break;
6137 case 5: case 7: /* VABAL, VABDL */
6138 switch ((size << 1) | u) {
6139 case 0:
6140 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6141 break;
6142 case 1:
6143 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6144 break;
6145 case 2:
6146 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6147 break;
6148 case 3:
6149 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6150 break;
6151 case 4:
6152 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6153 break;
6154 case 5:
6155 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6156 break;
6157 default: abort();
6159 tcg_temp_free_i32(tmp2);
6160 tcg_temp_free_i32(tmp);
6161 break;
6162 case 8: case 9: case 10: case 11: case 12: case 13:
6163 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6164 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6165 break;
6166 case 14: /* Polynomial VMULL */
6167 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6168 tcg_temp_free_i32(tmp2);
6169 tcg_temp_free_i32(tmp);
6170 break;
6171 default: /* 15 is RESERVED: caught earlier */
6172 abort();
6174 if (op == 13) {
6175 /* VQDMULL */
6176 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6177 neon_store_reg64(cpu_V0, rd + pass);
6178 } else if (op == 5 || (op >= 8 && op <= 11)) {
6179 /* Accumulate. */
6180 neon_load_reg64(cpu_V1, rd + pass);
6181 switch (op) {
6182 case 10: /* VMLSL */
6183 gen_neon_negl(cpu_V0, size);
6184 /* Fall through */
6185 case 5: case 8: /* VABAL, VMLAL */
6186 gen_neon_addl(size);
6187 break;
6188 case 9: case 11: /* VQDMLAL, VQDMLSL */
6189 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6190 if (op == 11) {
6191 gen_neon_negl(cpu_V0, size);
6193 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6194 break;
6195 default:
6196 abort();
6198 neon_store_reg64(cpu_V0, rd + pass);
6199 } else if (op == 4 || op == 6) {
6200 /* Narrowing operation. */
6201 tmp = tcg_temp_new_i32();
6202 if (!u) {
6203 switch (size) {
6204 case 0:
6205 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6206 break;
6207 case 1:
6208 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6209 break;
6210 case 2:
6211 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6212 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6213 break;
6214 default: abort();
6216 } else {
6217 switch (size) {
6218 case 0:
6219 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6220 break;
6221 case 1:
6222 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6223 break;
6224 case 2:
6225 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6226 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6227 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6228 break;
6229 default: abort();
6232 if (pass == 0) {
6233 tmp3 = tmp;
6234 } else {
6235 neon_store_reg(rd, 0, tmp3);
6236 neon_store_reg(rd, 1, tmp);
6238 } else {
6239 /* Write back the result. */
6240 neon_store_reg64(cpu_V0, rd + pass);
6243 } else {
6244 /* Two registers and a scalar. NB that for ops of this form
6245 * the ARM ARM labels bit 24 as Q, but it is in our variable
6246 * 'u', not 'q'.
6248 if (size == 0) {
6249 return 1;
6251 switch (op) {
6252 case 1: /* Float VMLA scalar */
6253 case 5: /* Floating point VMLS scalar */
6254 case 9: /* Floating point VMUL scalar */
6255 if (size == 1) {
6256 return 1;
6258 /* fall through */
6259 case 0: /* Integer VMLA scalar */
6260 case 4: /* Integer VMLS scalar */
6261 case 8: /* Integer VMUL scalar */
6262 case 12: /* VQDMULH scalar */
6263 case 13: /* VQRDMULH scalar */
6264 if (u && ((rd | rn) & 1)) {
6265 return 1;
6267 tmp = neon_get_scalar(size, rm);
6268 neon_store_scratch(0, tmp);
6269 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6270 tmp = neon_load_scratch(0);
6271 tmp2 = neon_load_reg(rn, pass);
6272 if (op == 12) {
6273 if (size == 1) {
6274 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6275 } else {
6276 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6278 } else if (op == 13) {
6279 if (size == 1) {
6280 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6281 } else {
6282 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6284 } else if (op & 1) {
6285 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6286 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6287 tcg_temp_free_ptr(fpstatus);
6288 } else {
6289 switch (size) {
6290 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6291 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6292 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6293 default: abort();
6296 tcg_temp_free_i32(tmp2);
6297 if (op < 8) {
6298 /* Accumulate. */
6299 tmp2 = neon_load_reg(rd, pass);
6300 switch (op) {
6301 case 0:
6302 gen_neon_add(size, tmp, tmp2);
6303 break;
6304 case 1:
6306 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6307 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6308 tcg_temp_free_ptr(fpstatus);
6309 break;
6311 case 4:
6312 gen_neon_rsb(size, tmp, tmp2);
6313 break;
6314 case 5:
6316 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6317 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6318 tcg_temp_free_ptr(fpstatus);
6319 break;
6321 default:
6322 abort();
6324 tcg_temp_free_i32(tmp2);
6326 neon_store_reg(rd, pass, tmp);
6328 break;
6329 case 3: /* VQDMLAL scalar */
6330 case 7: /* VQDMLSL scalar */
6331 case 11: /* VQDMULL scalar */
6332 if (u == 1) {
6333 return 1;
6335 /* fall through */
6336 case 2: /* VMLAL sclar */
6337 case 6: /* VMLSL scalar */
6338 case 10: /* VMULL scalar */
6339 if (rd & 1) {
6340 return 1;
6342 tmp2 = neon_get_scalar(size, rm);
6343 /* We need a copy of tmp2 because gen_neon_mull
6344 * deletes it during pass 0. */
6345 tmp4 = tcg_temp_new_i32();
6346 tcg_gen_mov_i32(tmp4, tmp2);
6347 tmp3 = neon_load_reg(rn, 1);
6349 for (pass = 0; pass < 2; pass++) {
6350 if (pass == 0) {
6351 tmp = neon_load_reg(rn, 0);
6352 } else {
6353 tmp = tmp3;
6354 tmp2 = tmp4;
6356 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6357 if (op != 11) {
6358 neon_load_reg64(cpu_V1, rd + pass);
6360 switch (op) {
6361 case 6:
6362 gen_neon_negl(cpu_V0, size);
6363 /* Fall through */
6364 case 2:
6365 gen_neon_addl(size);
6366 break;
6367 case 3: case 7:
6368 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6369 if (op == 7) {
6370 gen_neon_negl(cpu_V0, size);
6372 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6373 break;
6374 case 10:
6375 /* no-op */
6376 break;
6377 case 11:
6378 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6379 break;
6380 default:
6381 abort();
6383 neon_store_reg64(cpu_V0, rd + pass);
6387 break;
6388 default: /* 14 and 15 are RESERVED */
6389 return 1;
6392 } else { /* size == 3 */
6393 if (!u) {
6394 /* Extract. */
6395 imm = (insn >> 8) & 0xf;
6397 if (imm > 7 && !q)
6398 return 1;
6400 if (q && ((rd | rn | rm) & 1)) {
6401 return 1;
6404 if (imm == 0) {
6405 neon_load_reg64(cpu_V0, rn);
6406 if (q) {
6407 neon_load_reg64(cpu_V1, rn + 1);
6409 } else if (imm == 8) {
6410 neon_load_reg64(cpu_V0, rn + 1);
6411 if (q) {
6412 neon_load_reg64(cpu_V1, rm);
6414 } else if (q) {
6415 tmp64 = tcg_temp_new_i64();
6416 if (imm < 8) {
6417 neon_load_reg64(cpu_V0, rn);
6418 neon_load_reg64(tmp64, rn + 1);
6419 } else {
6420 neon_load_reg64(cpu_V0, rn + 1);
6421 neon_load_reg64(tmp64, rm);
6423 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6424 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6425 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6426 if (imm < 8) {
6427 neon_load_reg64(cpu_V1, rm);
6428 } else {
6429 neon_load_reg64(cpu_V1, rm + 1);
6430 imm -= 8;
6432 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6433 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6434 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6435 tcg_temp_free_i64(tmp64);
6436 } else {
6437 /* BUGFIX */
6438 neon_load_reg64(cpu_V0, rn);
6439 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6440 neon_load_reg64(cpu_V1, rm);
6441 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6442 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6444 neon_store_reg64(cpu_V0, rd);
6445 if (q) {
6446 neon_store_reg64(cpu_V1, rd + 1);
6448 } else if ((insn & (1 << 11)) == 0) {
6449 /* Two register misc. */
6450 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6451 size = (insn >> 18) & 3;
6452 /* UNDEF for unknown op values and bad op-size combinations */
6453 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6454 return 1;
6456 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6457 q && ((rm | rd) & 1)) {
6458 return 1;
6460 switch (op) {
6461 case NEON_2RM_VREV64:
6462 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6463 tmp = neon_load_reg(rm, pass * 2);
6464 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6465 switch (size) {
6466 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6467 case 1: gen_swap_half(tmp); break;
6468 case 2: /* no-op */ break;
6469 default: abort();
6471 neon_store_reg(rd, pass * 2 + 1, tmp);
6472 if (size == 2) {
6473 neon_store_reg(rd, pass * 2, tmp2);
6474 } else {
6475 switch (size) {
6476 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6477 case 1: gen_swap_half(tmp2); break;
6478 default: abort();
6480 neon_store_reg(rd, pass * 2, tmp2);
6483 break;
6484 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6485 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6486 for (pass = 0; pass < q + 1; pass++) {
6487 tmp = neon_load_reg(rm, pass * 2);
6488 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6489 tmp = neon_load_reg(rm, pass * 2 + 1);
6490 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6491 switch (size) {
6492 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6493 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6494 case 2: tcg_gen_add_i64(CPU_V001); break;
6495 default: abort();
6497 if (op >= NEON_2RM_VPADAL) {
6498 /* Accumulate. */
6499 neon_load_reg64(cpu_V1, rd + pass);
6500 gen_neon_addl(size);
6502 neon_store_reg64(cpu_V0, rd + pass);
6504 break;
6505 case NEON_2RM_VTRN:
6506 if (size == 2) {
6507 int n;
6508 for (n = 0; n < (q ? 4 : 2); n += 2) {
6509 tmp = neon_load_reg(rm, n);
6510 tmp2 = neon_load_reg(rd, n + 1);
6511 neon_store_reg(rm, n, tmp2);
6512 neon_store_reg(rd, n + 1, tmp);
6514 } else {
6515 goto elementwise;
6517 break;
6518 case NEON_2RM_VUZP:
6519 if (gen_neon_unzip(rd, rm, size, q)) {
6520 return 1;
6522 break;
6523 case NEON_2RM_VZIP:
6524 if (gen_neon_zip(rd, rm, size, q)) {
6525 return 1;
6527 break;
6528 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6529 /* also VQMOVUN; op field and mnemonics don't line up */
6530 if (rm & 1) {
6531 return 1;
6533 TCGV_UNUSED_I32(tmp2);
6534 for (pass = 0; pass < 2; pass++) {
6535 neon_load_reg64(cpu_V0, rm + pass);
6536 tmp = tcg_temp_new_i32();
6537 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6538 tmp, cpu_V0);
6539 if (pass == 0) {
6540 tmp2 = tmp;
6541 } else {
6542 neon_store_reg(rd, 0, tmp2);
6543 neon_store_reg(rd, 1, tmp);
6546 break;
6547 case NEON_2RM_VSHLL:
6548 if (q || (rd & 1)) {
6549 return 1;
6551 tmp = neon_load_reg(rm, 0);
6552 tmp2 = neon_load_reg(rm, 1);
6553 for (pass = 0; pass < 2; pass++) {
6554 if (pass == 1)
6555 tmp = tmp2;
6556 gen_neon_widen(cpu_V0, tmp, size, 1);
6557 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6558 neon_store_reg64(cpu_V0, rd + pass);
6560 break;
6561 case NEON_2RM_VCVT_F16_F32:
6562 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6563 q || (rm & 1)) {
6564 return 1;
6566 tmp = tcg_temp_new_i32();
6567 tmp2 = tcg_temp_new_i32();
6568 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6569 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6570 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6571 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6572 tcg_gen_shli_i32(tmp2, tmp2, 16);
6573 tcg_gen_or_i32(tmp2, tmp2, tmp);
6574 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6575 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6576 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6577 neon_store_reg(rd, 0, tmp2);
6578 tmp2 = tcg_temp_new_i32();
6579 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6580 tcg_gen_shli_i32(tmp2, tmp2, 16);
6581 tcg_gen_or_i32(tmp2, tmp2, tmp);
6582 neon_store_reg(rd, 1, tmp2);
6583 tcg_temp_free_i32(tmp);
6584 break;
6585 case NEON_2RM_VCVT_F32_F16:
6586 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6587 q || (rd & 1)) {
6588 return 1;
6590 tmp3 = tcg_temp_new_i32();
6591 tmp = neon_load_reg(rm, 0);
6592 tmp2 = neon_load_reg(rm, 1);
6593 tcg_gen_ext16u_i32(tmp3, tmp);
6594 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6595 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6596 tcg_gen_shri_i32(tmp3, tmp, 16);
6597 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6598 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6599 tcg_temp_free_i32(tmp);
6600 tcg_gen_ext16u_i32(tmp3, tmp2);
6601 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6602 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6603 tcg_gen_shri_i32(tmp3, tmp2, 16);
6604 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6605 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6606 tcg_temp_free_i32(tmp2);
6607 tcg_temp_free_i32(tmp3);
6608 break;
6609 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6610 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6611 || ((rm | rd) & 1)) {
6612 return 1;
6614 tmp = tcg_const_i32(rd);
6615 tmp2 = tcg_const_i32(rm);
6617 /* Bit 6 is the lowest opcode bit; it distinguishes between
6618 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6620 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6622 if (op == NEON_2RM_AESE) {
6623 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6624 } else {
6625 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6627 tcg_temp_free_i32(tmp);
6628 tcg_temp_free_i32(tmp2);
6629 tcg_temp_free_i32(tmp3);
6630 break;
6631 case NEON_2RM_SHA1H:
6632 if (!arm_feature(env, ARM_FEATURE_V8_SHA1)
6633 || ((rm | rd) & 1)) {
6634 return 1;
6636 tmp = tcg_const_i32(rd);
6637 tmp2 = tcg_const_i32(rm);
6639 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
6641 tcg_temp_free_i32(tmp);
6642 tcg_temp_free_i32(tmp2);
6643 break;
6644 case NEON_2RM_SHA1SU1:
6645 if ((rm | rd) & 1) {
6646 return 1;
6648 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6649 if (q) {
6650 if (!arm_feature(env, ARM_FEATURE_V8_SHA256)) {
6651 return 1;
6653 } else if (!arm_feature(env, ARM_FEATURE_V8_SHA1)) {
6654 return 1;
6656 tmp = tcg_const_i32(rd);
6657 tmp2 = tcg_const_i32(rm);
6658 if (q) {
6659 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
6660 } else {
6661 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
6663 tcg_temp_free_i32(tmp);
6664 tcg_temp_free_i32(tmp2);
6665 break;
6666 default:
6667 elementwise:
6668 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6669 if (neon_2rm_is_float_op(op)) {
6670 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6671 neon_reg_offset(rm, pass));
6672 TCGV_UNUSED_I32(tmp);
6673 } else {
6674 tmp = neon_load_reg(rm, pass);
6676 switch (op) {
6677 case NEON_2RM_VREV32:
6678 switch (size) {
6679 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6680 case 1: gen_swap_half(tmp); break;
6681 default: abort();
6683 break;
6684 case NEON_2RM_VREV16:
6685 gen_rev16(tmp);
6686 break;
6687 case NEON_2RM_VCLS:
6688 switch (size) {
6689 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6690 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6691 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6692 default: abort();
6694 break;
6695 case NEON_2RM_VCLZ:
6696 switch (size) {
6697 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6698 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6699 case 2: gen_helper_clz(tmp, tmp); break;
6700 default: abort();
6702 break;
6703 case NEON_2RM_VCNT:
6704 gen_helper_neon_cnt_u8(tmp, tmp);
6705 break;
6706 case NEON_2RM_VMVN:
6707 tcg_gen_not_i32(tmp, tmp);
6708 break;
6709 case NEON_2RM_VQABS:
6710 switch (size) {
6711 case 0:
6712 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6713 break;
6714 case 1:
6715 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6716 break;
6717 case 2:
6718 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6719 break;
6720 default: abort();
6722 break;
6723 case NEON_2RM_VQNEG:
6724 switch (size) {
6725 case 0:
6726 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6727 break;
6728 case 1:
6729 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6730 break;
6731 case 2:
6732 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6733 break;
6734 default: abort();
6736 break;
6737 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6738 tmp2 = tcg_const_i32(0);
6739 switch(size) {
6740 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6741 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6742 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6743 default: abort();
6745 tcg_temp_free_i32(tmp2);
6746 if (op == NEON_2RM_VCLE0) {
6747 tcg_gen_not_i32(tmp, tmp);
6749 break;
6750 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6751 tmp2 = tcg_const_i32(0);
6752 switch(size) {
6753 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6754 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6755 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6756 default: abort();
6758 tcg_temp_free_i32(tmp2);
6759 if (op == NEON_2RM_VCLT0) {
6760 tcg_gen_not_i32(tmp, tmp);
6762 break;
6763 case NEON_2RM_VCEQ0:
6764 tmp2 = tcg_const_i32(0);
6765 switch(size) {
6766 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6767 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6768 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6769 default: abort();
6771 tcg_temp_free_i32(tmp2);
6772 break;
6773 case NEON_2RM_VABS:
6774 switch(size) {
6775 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6776 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6777 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6778 default: abort();
6780 break;
6781 case NEON_2RM_VNEG:
6782 tmp2 = tcg_const_i32(0);
6783 gen_neon_rsb(size, tmp, tmp2);
6784 tcg_temp_free_i32(tmp2);
6785 break;
6786 case NEON_2RM_VCGT0_F:
6788 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6789 tmp2 = tcg_const_i32(0);
6790 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6791 tcg_temp_free_i32(tmp2);
6792 tcg_temp_free_ptr(fpstatus);
6793 break;
6795 case NEON_2RM_VCGE0_F:
6797 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6798 tmp2 = tcg_const_i32(0);
6799 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6800 tcg_temp_free_i32(tmp2);
6801 tcg_temp_free_ptr(fpstatus);
6802 break;
6804 case NEON_2RM_VCEQ0_F:
6806 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6807 tmp2 = tcg_const_i32(0);
6808 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6809 tcg_temp_free_i32(tmp2);
6810 tcg_temp_free_ptr(fpstatus);
6811 break;
6813 case NEON_2RM_VCLE0_F:
6815 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6816 tmp2 = tcg_const_i32(0);
6817 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6818 tcg_temp_free_i32(tmp2);
6819 tcg_temp_free_ptr(fpstatus);
6820 break;
6822 case NEON_2RM_VCLT0_F:
6824 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6825 tmp2 = tcg_const_i32(0);
6826 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6827 tcg_temp_free_i32(tmp2);
6828 tcg_temp_free_ptr(fpstatus);
6829 break;
6831 case NEON_2RM_VABS_F:
6832 gen_vfp_abs(0);
6833 break;
6834 case NEON_2RM_VNEG_F:
6835 gen_vfp_neg(0);
6836 break;
6837 case NEON_2RM_VSWP:
6838 tmp2 = neon_load_reg(rd, pass);
6839 neon_store_reg(rm, pass, tmp2);
6840 break;
6841 case NEON_2RM_VTRN:
6842 tmp2 = neon_load_reg(rd, pass);
6843 switch (size) {
6844 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6845 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6846 default: abort();
6848 neon_store_reg(rm, pass, tmp2);
6849 break;
6850 case NEON_2RM_VRINTN:
6851 case NEON_2RM_VRINTA:
6852 case NEON_2RM_VRINTM:
6853 case NEON_2RM_VRINTP:
6854 case NEON_2RM_VRINTZ:
6856 TCGv_i32 tcg_rmode;
6857 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6858 int rmode;
6860 if (op == NEON_2RM_VRINTZ) {
6861 rmode = FPROUNDING_ZERO;
6862 } else {
6863 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6866 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6867 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6868 cpu_env);
6869 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6870 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6871 cpu_env);
6872 tcg_temp_free_ptr(fpstatus);
6873 tcg_temp_free_i32(tcg_rmode);
6874 break;
6876 case NEON_2RM_VRINTX:
6878 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6879 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6880 tcg_temp_free_ptr(fpstatus);
6881 break;
6883 case NEON_2RM_VCVTAU:
6884 case NEON_2RM_VCVTAS:
6885 case NEON_2RM_VCVTNU:
6886 case NEON_2RM_VCVTNS:
6887 case NEON_2RM_VCVTPU:
6888 case NEON_2RM_VCVTPS:
6889 case NEON_2RM_VCVTMU:
6890 case NEON_2RM_VCVTMS:
6892 bool is_signed = !extract32(insn, 7, 1);
6893 TCGv_ptr fpst = get_fpstatus_ptr(1);
6894 TCGv_i32 tcg_rmode, tcg_shift;
6895 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6897 tcg_shift = tcg_const_i32(0);
6898 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6899 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6900 cpu_env);
6902 if (is_signed) {
6903 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6904 tcg_shift, fpst);
6905 } else {
6906 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6907 tcg_shift, fpst);
6910 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6911 cpu_env);
6912 tcg_temp_free_i32(tcg_rmode);
6913 tcg_temp_free_i32(tcg_shift);
6914 tcg_temp_free_ptr(fpst);
6915 break;
6917 case NEON_2RM_VRECPE:
6919 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6920 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6921 tcg_temp_free_ptr(fpstatus);
6922 break;
6924 case NEON_2RM_VRSQRTE:
6926 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6927 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6928 tcg_temp_free_ptr(fpstatus);
6929 break;
6931 case NEON_2RM_VRECPE_F:
6933 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6934 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
6935 tcg_temp_free_ptr(fpstatus);
6936 break;
6938 case NEON_2RM_VRSQRTE_F:
6940 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6941 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
6942 tcg_temp_free_ptr(fpstatus);
6943 break;
6945 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6946 gen_vfp_sito(0, 1);
6947 break;
6948 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6949 gen_vfp_uito(0, 1);
6950 break;
6951 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6952 gen_vfp_tosiz(0, 1);
6953 break;
6954 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6955 gen_vfp_touiz(0, 1);
6956 break;
6957 default:
6958 /* Reserved op values were caught by the
6959 * neon_2rm_sizes[] check earlier.
6961 abort();
6963 if (neon_2rm_is_float_op(op)) {
6964 tcg_gen_st_f32(cpu_F0s, cpu_env,
6965 neon_reg_offset(rd, pass));
6966 } else {
6967 neon_store_reg(rd, pass, tmp);
6970 break;
6972 } else if ((insn & (1 << 10)) == 0) {
6973 /* VTBL, VTBX. */
6974 int n = ((insn >> 8) & 3) + 1;
6975 if ((rn + n) > 32) {
6976 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6977 * helper function running off the end of the register file.
6979 return 1;
6981 n <<= 3;
6982 if (insn & (1 << 6)) {
6983 tmp = neon_load_reg(rd, 0);
6984 } else {
6985 tmp = tcg_temp_new_i32();
6986 tcg_gen_movi_i32(tmp, 0);
6988 tmp2 = neon_load_reg(rm, 0);
6989 tmp4 = tcg_const_i32(rn);
6990 tmp5 = tcg_const_i32(n);
6991 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6992 tcg_temp_free_i32(tmp);
6993 if (insn & (1 << 6)) {
6994 tmp = neon_load_reg(rd, 1);
6995 } else {
6996 tmp = tcg_temp_new_i32();
6997 tcg_gen_movi_i32(tmp, 0);
6999 tmp3 = neon_load_reg(rm, 1);
7000 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7001 tcg_temp_free_i32(tmp5);
7002 tcg_temp_free_i32(tmp4);
7003 neon_store_reg(rd, 0, tmp2);
7004 neon_store_reg(rd, 1, tmp3);
7005 tcg_temp_free_i32(tmp);
7006 } else if ((insn & 0x380) == 0) {
7007 /* VDUP */
7008 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7009 return 1;
7011 if (insn & (1 << 19)) {
7012 tmp = neon_load_reg(rm, 1);
7013 } else {
7014 tmp = neon_load_reg(rm, 0);
7016 if (insn & (1 << 16)) {
7017 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7018 } else if (insn & (1 << 17)) {
7019 if ((insn >> 18) & 1)
7020 gen_neon_dup_high16(tmp);
7021 else
7022 gen_neon_dup_low16(tmp);
7024 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7025 tmp2 = tcg_temp_new_i32();
7026 tcg_gen_mov_i32(tmp2, tmp);
7027 neon_store_reg(rd, pass, tmp2);
7029 tcg_temp_free_i32(tmp);
7030 } else {
7031 return 1;
7035 return 0;
7038 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
7040 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7041 const ARMCPRegInfo *ri;
7043 cpnum = (insn >> 8) & 0xf;
7045 /* First check for coprocessor space used for XScale/iwMMXt insns */
7046 if (arm_feature(env, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7047 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7048 return 1;
7050 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7051 return disas_iwmmxt_insn(env, s, insn);
7052 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
7053 return disas_dsp_insn(env, s, insn);
7055 return 1;
7058 /* Otherwise treat as a generic register access */
7059 is64 = (insn & (1 << 25)) == 0;
7060 if (!is64 && ((insn & (1 << 4)) == 0)) {
7061 /* cdp */
7062 return 1;
7065 crm = insn & 0xf;
7066 if (is64) {
7067 crn = 0;
7068 opc1 = (insn >> 4) & 0xf;
7069 opc2 = 0;
7070 rt2 = (insn >> 16) & 0xf;
7071 } else {
7072 crn = (insn >> 16) & 0xf;
7073 opc1 = (insn >> 21) & 7;
7074 opc2 = (insn >> 5) & 7;
7075 rt2 = 0;
7077 isread = (insn >> 20) & 1;
7078 rt = (insn >> 12) & 0xf;
7080 ri = get_arm_cp_reginfo(s->cp_regs,
7081 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
7082 if (ri) {
7083 /* Check access permissions */
7084 if (!cp_access_ok(s->current_el, ri, isread)) {
7085 return 1;
7088 if (ri->accessfn ||
7089 (arm_feature(env, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7090 /* Emit code to perform further access permissions checks at
7091 * runtime; this may result in an exception.
7092 * Note that on XScale all cp0..c13 registers do an access check
7093 * call in order to handle c15_cpar.
7095 TCGv_ptr tmpptr;
7096 TCGv_i32 tcg_syn;
7097 uint32_t syndrome;
7099 /* Note that since we are an implementation which takes an
7100 * exception on a trapped conditional instruction only if the
7101 * instruction passes its condition code check, we can take
7102 * advantage of the clause in the ARM ARM that allows us to set
7103 * the COND field in the instruction to 0xE in all cases.
7104 * We could fish the actual condition out of the insn (ARM)
7105 * or the condexec bits (Thumb) but it isn't necessary.
7107 switch (cpnum) {
7108 case 14:
7109 if (is64) {
7110 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7111 isread, s->thumb);
7112 } else {
7113 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7114 rt, isread, s->thumb);
7116 break;
7117 case 15:
7118 if (is64) {
7119 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7120 isread, s->thumb);
7121 } else {
7122 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7123 rt, isread, s->thumb);
7125 break;
7126 default:
7127 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7128 * so this can only happen if this is an ARMv7 or earlier CPU,
7129 * in which case the syndrome information won't actually be
7130 * guest visible.
7132 assert(!arm_feature(env, ARM_FEATURE_V8));
7133 syndrome = syn_uncategorized();
7134 break;
7137 gen_set_pc_im(s, s->pc);
7138 tmpptr = tcg_const_ptr(ri);
7139 tcg_syn = tcg_const_i32(syndrome);
7140 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
7141 tcg_temp_free_ptr(tmpptr);
7142 tcg_temp_free_i32(tcg_syn);
7145 /* Handle special cases first */
7146 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7147 case ARM_CP_NOP:
7148 return 0;
7149 case ARM_CP_WFI:
7150 if (isread) {
7151 return 1;
7153 gen_set_pc_im(s, s->pc);
7154 s->is_jmp = DISAS_WFI;
7155 return 0;
7156 default:
7157 break;
7160 if (use_icount && (ri->type & ARM_CP_IO)) {
7161 gen_io_start();
7164 if (isread) {
7165 /* Read */
7166 if (is64) {
7167 TCGv_i64 tmp64;
7168 TCGv_i32 tmp;
7169 if (ri->type & ARM_CP_CONST) {
7170 tmp64 = tcg_const_i64(ri->resetvalue);
7171 } else if (ri->readfn) {
7172 TCGv_ptr tmpptr;
7173 tmp64 = tcg_temp_new_i64();
7174 tmpptr = tcg_const_ptr(ri);
7175 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7176 tcg_temp_free_ptr(tmpptr);
7177 } else {
7178 tmp64 = tcg_temp_new_i64();
7179 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7181 tmp = tcg_temp_new_i32();
7182 tcg_gen_trunc_i64_i32(tmp, tmp64);
7183 store_reg(s, rt, tmp);
7184 tcg_gen_shri_i64(tmp64, tmp64, 32);
7185 tmp = tcg_temp_new_i32();
7186 tcg_gen_trunc_i64_i32(tmp, tmp64);
7187 tcg_temp_free_i64(tmp64);
7188 store_reg(s, rt2, tmp);
7189 } else {
7190 TCGv_i32 tmp;
7191 if (ri->type & ARM_CP_CONST) {
7192 tmp = tcg_const_i32(ri->resetvalue);
7193 } else if (ri->readfn) {
7194 TCGv_ptr tmpptr;
7195 tmp = tcg_temp_new_i32();
7196 tmpptr = tcg_const_ptr(ri);
7197 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7198 tcg_temp_free_ptr(tmpptr);
7199 } else {
7200 tmp = load_cpu_offset(ri->fieldoffset);
7202 if (rt == 15) {
7203 /* Destination register of r15 for 32 bit loads sets
7204 * the condition codes from the high 4 bits of the value
7206 gen_set_nzcv(tmp);
7207 tcg_temp_free_i32(tmp);
7208 } else {
7209 store_reg(s, rt, tmp);
7212 } else {
7213 /* Write */
7214 if (ri->type & ARM_CP_CONST) {
7215 /* If not forbidden by access permissions, treat as WI */
7216 return 0;
7219 if (is64) {
7220 TCGv_i32 tmplo, tmphi;
7221 TCGv_i64 tmp64 = tcg_temp_new_i64();
7222 tmplo = load_reg(s, rt);
7223 tmphi = load_reg(s, rt2);
7224 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7225 tcg_temp_free_i32(tmplo);
7226 tcg_temp_free_i32(tmphi);
7227 if (ri->writefn) {
7228 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7229 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7230 tcg_temp_free_ptr(tmpptr);
7231 } else {
7232 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7234 tcg_temp_free_i64(tmp64);
7235 } else {
7236 if (ri->writefn) {
7237 TCGv_i32 tmp;
7238 TCGv_ptr tmpptr;
7239 tmp = load_reg(s, rt);
7240 tmpptr = tcg_const_ptr(ri);
7241 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7242 tcg_temp_free_ptr(tmpptr);
7243 tcg_temp_free_i32(tmp);
7244 } else {
7245 TCGv_i32 tmp = load_reg(s, rt);
7246 store_cpu_offset(tmp, ri->fieldoffset);
7251 if (use_icount && (ri->type & ARM_CP_IO)) {
7252 /* I/O operations must end the TB here (whether read or write) */
7253 gen_io_end();
7254 gen_lookup_tb(s);
7255 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7256 /* We default to ending the TB on a coprocessor register write,
7257 * but allow this to be suppressed by the register definition
7258 * (usually only necessary to work around guest bugs).
7260 gen_lookup_tb(s);
7263 return 0;
7266 /* Unknown register; this might be a guest error or a QEMU
7267 * unimplemented feature.
7269 if (is64) {
7270 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7271 "64 bit system register cp:%d opc1: %d crm:%d\n",
7272 isread ? "read" : "write", cpnum, opc1, crm);
7273 } else {
7274 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7275 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7276 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
7279 return 1;
7283 /* Store a 64-bit value to a register pair. Clobbers val. */
7284 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7286 TCGv_i32 tmp;
7287 tmp = tcg_temp_new_i32();
7288 tcg_gen_trunc_i64_i32(tmp, val);
7289 store_reg(s, rlow, tmp);
7290 tmp = tcg_temp_new_i32();
7291 tcg_gen_shri_i64(val, val, 32);
7292 tcg_gen_trunc_i64_i32(tmp, val);
7293 store_reg(s, rhigh, tmp);
7296 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7297 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7299 TCGv_i64 tmp;
7300 TCGv_i32 tmp2;
7302 /* Load value and extend to 64 bits. */
7303 tmp = tcg_temp_new_i64();
7304 tmp2 = load_reg(s, rlow);
7305 tcg_gen_extu_i32_i64(tmp, tmp2);
7306 tcg_temp_free_i32(tmp2);
7307 tcg_gen_add_i64(val, val, tmp);
7308 tcg_temp_free_i64(tmp);
7311 /* load and add a 64-bit value from a register pair. */
7312 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7314 TCGv_i64 tmp;
7315 TCGv_i32 tmpl;
7316 TCGv_i32 tmph;
7318 /* Load 64-bit value rd:rn. */
7319 tmpl = load_reg(s, rlow);
7320 tmph = load_reg(s, rhigh);
7321 tmp = tcg_temp_new_i64();
7322 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7323 tcg_temp_free_i32(tmpl);
7324 tcg_temp_free_i32(tmph);
7325 tcg_gen_add_i64(val, val, tmp);
7326 tcg_temp_free_i64(tmp);
7329 /* Set N and Z flags from hi|lo. */
7330 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7332 tcg_gen_mov_i32(cpu_NF, hi);
7333 tcg_gen_or_i32(cpu_ZF, lo, hi);
7336 /* Load/Store exclusive instructions are implemented by remembering
7337 the value/address loaded, and seeing if these are the same
7338 when the store is performed. This should be sufficient to implement
7339 the architecturally mandated semantics, and avoids having to monitor
7340 regular stores.
7342 In system emulation mode only one CPU will be running at once, so
7343 this sequence is effectively atomic. In user emulation mode we
7344 throw an exception and handle the atomic operation elsewhere. */
7345 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7346 TCGv_i32 addr, int size)
7348 TCGv_i32 tmp = tcg_temp_new_i32();
7350 s->is_ldex = true;
7352 switch (size) {
7353 case 0:
7354 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7355 break;
7356 case 1:
7357 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7358 break;
7359 case 2:
7360 case 3:
7361 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7362 break;
7363 default:
7364 abort();
7367 if (size == 3) {
7368 TCGv_i32 tmp2 = tcg_temp_new_i32();
7369 TCGv_i32 tmp3 = tcg_temp_new_i32();
7371 tcg_gen_addi_i32(tmp2, addr, 4);
7372 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7373 tcg_temp_free_i32(tmp2);
7374 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7375 store_reg(s, rt2, tmp3);
7376 } else {
7377 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7380 store_reg(s, rt, tmp);
7381 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7384 static void gen_clrex(DisasContext *s)
7386 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7389 #ifdef CONFIG_USER_ONLY
7390 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7391 TCGv_i32 addr, int size)
7393 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7394 tcg_gen_movi_i32(cpu_exclusive_info,
7395 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7396 gen_exception_internal_insn(s, 4, EXCP_STREX);
7398 #else
7399 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7400 TCGv_i32 addr, int size)
7402 TCGv_i32 tmp;
7403 TCGv_i64 val64, extaddr;
7404 int done_label;
7405 int fail_label;
7407 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7408 [addr] = {Rt};
7409 {Rd} = 0;
7410 } else {
7411 {Rd} = 1;
7412 } */
7413 fail_label = gen_new_label();
7414 done_label = gen_new_label();
7415 extaddr = tcg_temp_new_i64();
7416 tcg_gen_extu_i32_i64(extaddr, addr);
7417 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7418 tcg_temp_free_i64(extaddr);
7420 tmp = tcg_temp_new_i32();
7421 switch (size) {
7422 case 0:
7423 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
7424 break;
7425 case 1:
7426 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
7427 break;
7428 case 2:
7429 case 3:
7430 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7431 break;
7432 default:
7433 abort();
7436 val64 = tcg_temp_new_i64();
7437 if (size == 3) {
7438 TCGv_i32 tmp2 = tcg_temp_new_i32();
7439 TCGv_i32 tmp3 = tcg_temp_new_i32();
7440 tcg_gen_addi_i32(tmp2, addr, 4);
7441 gen_aa32_ld32u(s, tmp3, tmp2, get_mem_index(s));
7442 tcg_temp_free_i32(tmp2);
7443 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7444 tcg_temp_free_i32(tmp3);
7445 } else {
7446 tcg_gen_extu_i32_i64(val64, tmp);
7448 tcg_temp_free_i32(tmp);
7450 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7451 tcg_temp_free_i64(val64);
7453 tmp = load_reg(s, rt);
7454 switch (size) {
7455 case 0:
7456 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
7457 break;
7458 case 1:
7459 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
7460 break;
7461 case 2:
7462 case 3:
7463 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7464 break;
7465 default:
7466 abort();
7468 tcg_temp_free_i32(tmp);
7469 if (size == 3) {
7470 tcg_gen_addi_i32(addr, addr, 4);
7471 tmp = load_reg(s, rt2);
7472 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7473 tcg_temp_free_i32(tmp);
7475 tcg_gen_movi_i32(cpu_R[rd], 0);
7476 tcg_gen_br(done_label);
7477 gen_set_label(fail_label);
7478 tcg_gen_movi_i32(cpu_R[rd], 1);
7479 gen_set_label(done_label);
7480 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7482 #endif
7484 /* gen_srs:
7485 * @env: CPUARMState
7486 * @s: DisasContext
7487 * @mode: mode field from insn (which stack to store to)
7488 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7489 * @writeback: true if writeback bit set
7491 * Generate code for the SRS (Store Return State) insn.
7493 static void gen_srs(DisasContext *s,
7494 uint32_t mode, uint32_t amode, bool writeback)
7496 int32_t offset;
7497 TCGv_i32 addr = tcg_temp_new_i32();
7498 TCGv_i32 tmp = tcg_const_i32(mode);
7499 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7500 tcg_temp_free_i32(tmp);
7501 switch (amode) {
7502 case 0: /* DA */
7503 offset = -4;
7504 break;
7505 case 1: /* IA */
7506 offset = 0;
7507 break;
7508 case 2: /* DB */
7509 offset = -8;
7510 break;
7511 case 3: /* IB */
7512 offset = 4;
7513 break;
7514 default:
7515 abort();
7517 tcg_gen_addi_i32(addr, addr, offset);
7518 tmp = load_reg(s, 14);
7519 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7520 tcg_temp_free_i32(tmp);
7521 tmp = load_cpu_field(spsr);
7522 tcg_gen_addi_i32(addr, addr, 4);
7523 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7524 tcg_temp_free_i32(tmp);
7525 if (writeback) {
7526 switch (amode) {
7527 case 0:
7528 offset = -8;
7529 break;
7530 case 1:
7531 offset = 4;
7532 break;
7533 case 2:
7534 offset = -4;
7535 break;
7536 case 3:
7537 offset = 0;
7538 break;
7539 default:
7540 abort();
7542 tcg_gen_addi_i32(addr, addr, offset);
7543 tmp = tcg_const_i32(mode);
7544 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7545 tcg_temp_free_i32(tmp);
7547 tcg_temp_free_i32(addr);
7550 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7552 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7553 TCGv_i32 tmp;
7554 TCGv_i32 tmp2;
7555 TCGv_i32 tmp3;
7556 TCGv_i32 addr;
7557 TCGv_i64 tmp64;
7559 insn = arm_ldl_code(env, s->pc, s->sctlr_b);
7560 s->pc += 4;
7562 /* M variants do not implement ARM mode. */
7563 if (IS_M(env))
7564 goto illegal_op;
7565 cond = insn >> 28;
7566 if (cond == 0xf){
7567 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7568 * choose to UNDEF. In ARMv5 and above the space is used
7569 * for miscellaneous unconditional instructions.
7571 ARCH(5);
7573 /* Unconditional instructions. */
7574 if (((insn >> 25) & 7) == 1) {
7575 /* NEON Data processing. */
7576 if (!arm_feature(env, ARM_FEATURE_NEON))
7577 goto illegal_op;
7579 if (disas_neon_data_insn(env, s, insn))
7580 goto illegal_op;
7581 return;
7583 if ((insn & 0x0f100000) == 0x04000000) {
7584 /* NEON load/store. */
7585 if (!arm_feature(env, ARM_FEATURE_NEON))
7586 goto illegal_op;
7588 if (disas_neon_ls_insn(env, s, insn))
7589 goto illegal_op;
7590 return;
7592 if ((insn & 0x0f000e10) == 0x0e000a00) {
7593 /* VFP. */
7594 if (disas_vfp_insn(env, s, insn)) {
7595 goto illegal_op;
7597 return;
7599 if (((insn & 0x0f30f000) == 0x0510f000) ||
7600 ((insn & 0x0f30f010) == 0x0710f000)) {
7601 if ((insn & (1 << 22)) == 0) {
7602 /* PLDW; v7MP */
7603 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7604 goto illegal_op;
7607 /* Otherwise PLD; v5TE+ */
7608 ARCH(5TE);
7609 return;
7611 if (((insn & 0x0f70f000) == 0x0450f000) ||
7612 ((insn & 0x0f70f010) == 0x0650f000)) {
7613 ARCH(7);
7614 return; /* PLI; V7 */
7616 if (((insn & 0x0f700000) == 0x04100000) ||
7617 ((insn & 0x0f700010) == 0x06100000)) {
7618 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7619 goto illegal_op;
7621 return; /* v7MP: Unallocated memory hint: must NOP */
7624 if ((insn & 0x0ffffdff) == 0x01010000) {
7625 ARCH(6);
7626 /* setend */
7627 if (((insn >> 9) & 1) != s->cpsr_e) {
7628 /* Dynamic endianness switching not implemented. */
7629 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7630 goto illegal_op;
7632 return;
7633 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7634 switch ((insn >> 4) & 0xf) {
7635 case 1: /* clrex */
7636 ARCH(6K);
7637 gen_clrex(s);
7638 return;
7639 case 4: /* dsb */
7640 case 5: /* dmb */
7641 case 6: /* isb */
7642 ARCH(7);
7643 /* We don't emulate caches so these are a no-op. */
7644 return;
7645 default:
7646 goto illegal_op;
7648 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7649 /* srs */
7650 if (IS_USER(s)) {
7651 goto illegal_op;
7653 ARCH(6);
7654 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7655 return;
7656 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7657 /* rfe */
7658 int32_t offset;
7659 if (IS_USER(s))
7660 goto illegal_op;
7661 ARCH(6);
7662 rn = (insn >> 16) & 0xf;
7663 addr = load_reg(s, rn);
7664 i = (insn >> 23) & 3;
7665 switch (i) {
7666 case 0: offset = -4; break; /* DA */
7667 case 1: offset = 0; break; /* IA */
7668 case 2: offset = -8; break; /* DB */
7669 case 3: offset = 4; break; /* IB */
7670 default: abort();
7672 if (offset)
7673 tcg_gen_addi_i32(addr, addr, offset);
7674 /* Load PC into tmp and CPSR into tmp2. */
7675 tmp = tcg_temp_new_i32();
7676 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7677 tcg_gen_addi_i32(addr, addr, 4);
7678 tmp2 = tcg_temp_new_i32();
7679 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7680 if (insn & (1 << 21)) {
7681 /* Base writeback. */
7682 switch (i) {
7683 case 0: offset = -8; break;
7684 case 1: offset = 4; break;
7685 case 2: offset = -4; break;
7686 case 3: offset = 0; break;
7687 default: abort();
7689 if (offset)
7690 tcg_gen_addi_i32(addr, addr, offset);
7691 store_reg(s, rn, addr);
7692 } else {
7693 tcg_temp_free_i32(addr);
7695 gen_rfe(s, tmp, tmp2);
7696 return;
7697 } else if ((insn & 0x0e000000) == 0x0a000000) {
7698 /* branch link and change to thumb (blx <offset>) */
7699 int32_t offset;
7701 val = (uint32_t)s->pc;
7702 tmp = tcg_temp_new_i32();
7703 tcg_gen_movi_i32(tmp, val);
7704 store_reg(s, 14, tmp);
7705 /* Sign-extend the 24-bit offset */
7706 offset = (((int32_t)insn) << 8) >> 8;
7707 /* offset * 4 + bit24 * 2 + (thumb bit) */
7708 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7709 /* pipeline offset */
7710 val += 4;
7711 /* protected by ARCH(5); above, near the start of uncond block */
7712 gen_bx_im(s, val);
7713 return;
7714 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7715 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7716 /* iWMMXt register transfer. */
7717 if (extract32(s->c15_cpar, 1, 1)) {
7718 if (!disas_iwmmxt_insn(env, s, insn)) {
7719 return;
7723 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7724 /* Coprocessor double register transfer. */
7725 ARCH(5TE);
7726 } else if ((insn & 0x0f000010) == 0x0e000010) {
7727 /* Additional coprocessor register transfer. */
7728 } else if ((insn & 0x0ff10020) == 0x01000000) {
7729 uint32_t mask;
7730 uint32_t val;
7731 /* cps (privileged) */
7732 if (IS_USER(s))
7733 return;
7734 mask = val = 0;
7735 if (insn & (1 << 19)) {
7736 if (insn & (1 << 8))
7737 mask |= CPSR_A;
7738 if (insn & (1 << 7))
7739 mask |= CPSR_I;
7740 if (insn & (1 << 6))
7741 mask |= CPSR_F;
7742 if (insn & (1 << 18))
7743 val |= mask;
7745 if (insn & (1 << 17)) {
7746 mask |= CPSR_M;
7747 val |= (insn & 0x1f);
7749 if (mask) {
7750 gen_set_psr_im(s, mask, 0, val);
7752 return;
7754 goto illegal_op;
7756 if (cond != 0xe) {
7757 /* if not always execute, we generate a conditional jump to
7758 next instruction */
7759 s->condlabel = gen_new_label();
7760 arm_gen_test_cc(cond ^ 1, s->condlabel);
7761 s->condjmp = 1;
7763 if ((insn & 0x0f900000) == 0x03000000) {
7764 if ((insn & (1 << 21)) == 0) {
7765 ARCH(6T2);
7766 rd = (insn >> 12) & 0xf;
7767 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7768 if ((insn & (1 << 22)) == 0) {
7769 /* MOVW */
7770 tmp = tcg_temp_new_i32();
7771 tcg_gen_movi_i32(tmp, val);
7772 } else {
7773 /* MOVT */
7774 tmp = load_reg(s, rd);
7775 tcg_gen_ext16u_i32(tmp, tmp);
7776 tcg_gen_ori_i32(tmp, tmp, val << 16);
7778 store_reg(s, rd, tmp);
7779 } else {
7780 if (((insn >> 12) & 0xf) != 0xf)
7781 goto illegal_op;
7782 if (((insn >> 16) & 0xf) == 0) {
7783 gen_nop_hint(s, insn & 0xff);
7784 } else {
7785 /* CPSR = immediate */
7786 val = insn & 0xff;
7787 shift = ((insn >> 8) & 0xf) * 2;
7788 if (shift)
7789 val = (val >> shift) | (val << (32 - shift));
7790 i = ((insn & (1 << 22)) != 0);
7791 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7792 goto illegal_op;
7795 } else if ((insn & 0x0f900000) == 0x01000000
7796 && (insn & 0x00000090) != 0x00000090) {
7797 /* miscellaneous instructions */
7798 op1 = (insn >> 21) & 3;
7799 sh = (insn >> 4) & 0xf;
7800 rm = insn & 0xf;
7801 switch (sh) {
7802 case 0x0: /* move program status register */
7803 if (op1 & 1) {
7804 /* PSR = reg */
7805 tmp = load_reg(s, rm);
7806 i = ((op1 & 2) != 0);
7807 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7808 goto illegal_op;
7809 } else {
7810 /* reg = PSR */
7811 rd = (insn >> 12) & 0xf;
7812 if (op1 & 2) {
7813 if (IS_USER(s))
7814 goto illegal_op;
7815 tmp = load_cpu_field(spsr);
7816 } else {
7817 tmp = tcg_temp_new_i32();
7818 gen_helper_cpsr_read(tmp, cpu_env);
7820 store_reg(s, rd, tmp);
7822 break;
7823 case 0x1:
7824 if (op1 == 1) {
7825 /* branch/exchange thumb (bx). */
7826 ARCH(4T);
7827 tmp = load_reg(s, rm);
7828 gen_bx(s, tmp);
7829 } else if (op1 == 3) {
7830 /* clz */
7831 ARCH(5);
7832 rd = (insn >> 12) & 0xf;
7833 tmp = load_reg(s, rm);
7834 gen_helper_clz(tmp, tmp);
7835 store_reg(s, rd, tmp);
7836 } else {
7837 goto illegal_op;
7839 break;
7840 case 0x2:
7841 if (op1 == 1) {
7842 ARCH(5J); /* bxj */
7843 /* Trivial implementation equivalent to bx. */
7844 tmp = load_reg(s, rm);
7845 gen_bx(s, tmp);
7846 } else {
7847 goto illegal_op;
7849 break;
7850 case 0x3:
7851 if (op1 != 1)
7852 goto illegal_op;
7854 ARCH(5);
7855 /* branch link/exchange thumb (blx) */
7856 tmp = load_reg(s, rm);
7857 tmp2 = tcg_temp_new_i32();
7858 tcg_gen_movi_i32(tmp2, s->pc);
7859 store_reg(s, 14, tmp2);
7860 gen_bx(s, tmp);
7861 break;
7862 case 0x4:
7864 /* crc32/crc32c */
7865 uint32_t c = extract32(insn, 8, 4);
7867 /* Check this CPU supports ARMv8 CRC instructions.
7868 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7869 * Bits 8, 10 and 11 should be zero.
7871 if (!arm_feature(env, ARM_FEATURE_CRC) || op1 == 0x3 ||
7872 (c & 0xd) != 0) {
7873 goto illegal_op;
7876 rn = extract32(insn, 16, 4);
7877 rd = extract32(insn, 12, 4);
7879 tmp = load_reg(s, rn);
7880 tmp2 = load_reg(s, rm);
7881 if (op1 == 0) {
7882 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
7883 } else if (op1 == 1) {
7884 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
7886 tmp3 = tcg_const_i32(1 << op1);
7887 if (c & 0x2) {
7888 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7889 } else {
7890 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7892 tcg_temp_free_i32(tmp2);
7893 tcg_temp_free_i32(tmp3);
7894 store_reg(s, rd, tmp);
7895 break;
7897 case 0x5: /* saturating add/subtract */
7898 ARCH(5TE);
7899 rd = (insn >> 12) & 0xf;
7900 rn = (insn >> 16) & 0xf;
7901 tmp = load_reg(s, rm);
7902 tmp2 = load_reg(s, rn);
7903 if (op1 & 2)
7904 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7905 if (op1 & 1)
7906 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7907 else
7908 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7909 tcg_temp_free_i32(tmp2);
7910 store_reg(s, rd, tmp);
7911 break;
7912 case 7:
7914 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
7915 switch (op1) {
7916 case 1:
7917 /* bkpt */
7918 ARCH(5);
7919 gen_exception_insn(s, 4, EXCP_BKPT,
7920 syn_aa32_bkpt(imm16, false));
7921 break;
7922 case 2:
7923 /* Hypervisor call (v7) */
7924 ARCH(7);
7925 if (IS_USER(s)) {
7926 goto illegal_op;
7928 gen_hvc(s, imm16);
7929 break;
7930 case 3:
7931 /* Secure monitor call (v6+) */
7932 ARCH(6K);
7933 if (IS_USER(s)) {
7934 goto illegal_op;
7936 gen_smc(s);
7937 break;
7938 default:
7939 goto illegal_op;
7941 break;
7943 case 0x8: /* signed multiply */
7944 case 0xa:
7945 case 0xc:
7946 case 0xe:
7947 ARCH(5TE);
7948 rs = (insn >> 8) & 0xf;
7949 rn = (insn >> 12) & 0xf;
7950 rd = (insn >> 16) & 0xf;
7951 if (op1 == 1) {
7952 /* (32 * 16) >> 16 */
7953 tmp = load_reg(s, rm);
7954 tmp2 = load_reg(s, rs);
7955 if (sh & 4)
7956 tcg_gen_sari_i32(tmp2, tmp2, 16);
7957 else
7958 gen_sxth(tmp2);
7959 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7960 tcg_gen_shri_i64(tmp64, tmp64, 16);
7961 tmp = tcg_temp_new_i32();
7962 tcg_gen_trunc_i64_i32(tmp, tmp64);
7963 tcg_temp_free_i64(tmp64);
7964 if ((sh & 2) == 0) {
7965 tmp2 = load_reg(s, rn);
7966 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7967 tcg_temp_free_i32(tmp2);
7969 store_reg(s, rd, tmp);
7970 } else {
7971 /* 16 * 16 */
7972 tmp = load_reg(s, rm);
7973 tmp2 = load_reg(s, rs);
7974 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7975 tcg_temp_free_i32(tmp2);
7976 if (op1 == 2) {
7977 tmp64 = tcg_temp_new_i64();
7978 tcg_gen_ext_i32_i64(tmp64, tmp);
7979 tcg_temp_free_i32(tmp);
7980 gen_addq(s, tmp64, rn, rd);
7981 gen_storeq_reg(s, rn, rd, tmp64);
7982 tcg_temp_free_i64(tmp64);
7983 } else {
7984 if (op1 == 0) {
7985 tmp2 = load_reg(s, rn);
7986 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7987 tcg_temp_free_i32(tmp2);
7989 store_reg(s, rd, tmp);
7992 break;
7993 default:
7994 goto illegal_op;
7996 } else if (((insn & 0x0e000000) == 0 &&
7997 (insn & 0x00000090) != 0x90) ||
7998 ((insn & 0x0e000000) == (1 << 25))) {
7999 int set_cc, logic_cc, shiftop;
8001 op1 = (insn >> 21) & 0xf;
8002 set_cc = (insn >> 20) & 1;
8003 logic_cc = table_logic_cc[op1] & set_cc;
8005 /* data processing instruction */
8006 if (insn & (1 << 25)) {
8007 /* immediate operand */
8008 val = insn & 0xff;
8009 shift = ((insn >> 8) & 0xf) * 2;
8010 if (shift) {
8011 val = (val >> shift) | (val << (32 - shift));
8013 tmp2 = tcg_temp_new_i32();
8014 tcg_gen_movi_i32(tmp2, val);
8015 if (logic_cc && shift) {
8016 gen_set_CF_bit31(tmp2);
8018 } else {
8019 /* register */
8020 rm = (insn) & 0xf;
8021 tmp2 = load_reg(s, rm);
8022 shiftop = (insn >> 5) & 3;
8023 if (!(insn & (1 << 4))) {
8024 shift = (insn >> 7) & 0x1f;
8025 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8026 } else {
8027 rs = (insn >> 8) & 0xf;
8028 tmp = load_reg(s, rs);
8029 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8032 if (op1 != 0x0f && op1 != 0x0d) {
8033 rn = (insn >> 16) & 0xf;
8034 tmp = load_reg(s, rn);
8035 } else {
8036 TCGV_UNUSED_I32(tmp);
8038 rd = (insn >> 12) & 0xf;
8039 switch(op1) {
8040 case 0x00:
8041 tcg_gen_and_i32(tmp, tmp, tmp2);
8042 if (logic_cc) {
8043 gen_logic_CC(tmp);
8045 store_reg_bx(env, s, rd, tmp);
8046 break;
8047 case 0x01:
8048 tcg_gen_xor_i32(tmp, tmp, tmp2);
8049 if (logic_cc) {
8050 gen_logic_CC(tmp);
8052 store_reg_bx(env, s, rd, tmp);
8053 break;
8054 case 0x02:
8055 if (set_cc && rd == 15) {
8056 /* SUBS r15, ... is used for exception return. */
8057 if (IS_USER(s)) {
8058 goto illegal_op;
8060 gen_sub_CC(tmp, tmp, tmp2);
8061 gen_exception_return(s, tmp);
8062 } else {
8063 if (set_cc) {
8064 gen_sub_CC(tmp, tmp, tmp2);
8065 } else {
8066 tcg_gen_sub_i32(tmp, tmp, tmp2);
8068 store_reg_bx(env, s, rd, tmp);
8070 break;
8071 case 0x03:
8072 if (set_cc) {
8073 gen_sub_CC(tmp, tmp2, tmp);
8074 } else {
8075 tcg_gen_sub_i32(tmp, tmp2, tmp);
8077 store_reg_bx(env, s, rd, tmp);
8078 break;
8079 case 0x04:
8080 if (set_cc) {
8081 gen_add_CC(tmp, tmp, tmp2);
8082 } else {
8083 tcg_gen_add_i32(tmp, tmp, tmp2);
8085 store_reg_bx(env, s, rd, tmp);
8086 break;
8087 case 0x05:
8088 if (set_cc) {
8089 gen_adc_CC(tmp, tmp, tmp2);
8090 } else {
8091 gen_add_carry(tmp, tmp, tmp2);
8093 store_reg_bx(env, s, rd, tmp);
8094 break;
8095 case 0x06:
8096 if (set_cc) {
8097 gen_sbc_CC(tmp, tmp, tmp2);
8098 } else {
8099 gen_sub_carry(tmp, tmp, tmp2);
8101 store_reg_bx(env, s, rd, tmp);
8102 break;
8103 case 0x07:
8104 if (set_cc) {
8105 gen_sbc_CC(tmp, tmp2, tmp);
8106 } else {
8107 gen_sub_carry(tmp, tmp2, tmp);
8109 store_reg_bx(env, s, rd, tmp);
8110 break;
8111 case 0x08:
8112 if (set_cc) {
8113 tcg_gen_and_i32(tmp, tmp, tmp2);
8114 gen_logic_CC(tmp);
8116 tcg_temp_free_i32(tmp);
8117 break;
8118 case 0x09:
8119 if (set_cc) {
8120 tcg_gen_xor_i32(tmp, tmp, tmp2);
8121 gen_logic_CC(tmp);
8123 tcg_temp_free_i32(tmp);
8124 break;
8125 case 0x0a:
8126 if (set_cc) {
8127 gen_sub_CC(tmp, tmp, tmp2);
8129 tcg_temp_free_i32(tmp);
8130 break;
8131 case 0x0b:
8132 if (set_cc) {
8133 gen_add_CC(tmp, tmp, tmp2);
8135 tcg_temp_free_i32(tmp);
8136 break;
8137 case 0x0c:
8138 tcg_gen_or_i32(tmp, tmp, tmp2);
8139 if (logic_cc) {
8140 gen_logic_CC(tmp);
8142 store_reg_bx(env, s, rd, tmp);
8143 break;
8144 case 0x0d:
8145 if (logic_cc && rd == 15) {
8146 /* MOVS r15, ... is used for exception return. */
8147 if (IS_USER(s)) {
8148 goto illegal_op;
8150 gen_exception_return(s, tmp2);
8151 } else {
8152 if (logic_cc) {
8153 gen_logic_CC(tmp2);
8155 store_reg_bx(env, s, rd, tmp2);
8157 break;
8158 case 0x0e:
8159 tcg_gen_andc_i32(tmp, tmp, tmp2);
8160 if (logic_cc) {
8161 gen_logic_CC(tmp);
8163 store_reg_bx(env, s, rd, tmp);
8164 break;
8165 default:
8166 case 0x0f:
8167 tcg_gen_not_i32(tmp2, tmp2);
8168 if (logic_cc) {
8169 gen_logic_CC(tmp2);
8171 store_reg_bx(env, s, rd, tmp2);
8172 break;
8174 if (op1 != 0x0f && op1 != 0x0d) {
8175 tcg_temp_free_i32(tmp2);
8177 } else {
8178 /* other instructions */
8179 op1 = (insn >> 24) & 0xf;
8180 switch(op1) {
8181 case 0x0:
8182 case 0x1:
8183 /* multiplies, extra load/stores */
8184 sh = (insn >> 5) & 3;
8185 if (sh == 0) {
8186 if (op1 == 0x0) {
8187 rd = (insn >> 16) & 0xf;
8188 rn = (insn >> 12) & 0xf;
8189 rs = (insn >> 8) & 0xf;
8190 rm = (insn) & 0xf;
8191 op1 = (insn >> 20) & 0xf;
8192 switch (op1) {
8193 case 0: case 1: case 2: case 3: case 6:
8194 /* 32 bit mul */
8195 tmp = load_reg(s, rs);
8196 tmp2 = load_reg(s, rm);
8197 tcg_gen_mul_i32(tmp, tmp, tmp2);
8198 tcg_temp_free_i32(tmp2);
8199 if (insn & (1 << 22)) {
8200 /* Subtract (mls) */
8201 ARCH(6T2);
8202 tmp2 = load_reg(s, rn);
8203 tcg_gen_sub_i32(tmp, tmp2, tmp);
8204 tcg_temp_free_i32(tmp2);
8205 } else if (insn & (1 << 21)) {
8206 /* Add */
8207 tmp2 = load_reg(s, rn);
8208 tcg_gen_add_i32(tmp, tmp, tmp2);
8209 tcg_temp_free_i32(tmp2);
8211 if (insn & (1 << 20))
8212 gen_logic_CC(tmp);
8213 store_reg(s, rd, tmp);
8214 break;
8215 case 4:
8216 /* 64 bit mul double accumulate (UMAAL) */
8217 ARCH(6);
8218 tmp = load_reg(s, rs);
8219 tmp2 = load_reg(s, rm);
8220 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8221 gen_addq_lo(s, tmp64, rn);
8222 gen_addq_lo(s, tmp64, rd);
8223 gen_storeq_reg(s, rn, rd, tmp64);
8224 tcg_temp_free_i64(tmp64);
8225 break;
8226 case 8: case 9: case 10: case 11:
8227 case 12: case 13: case 14: case 15:
8228 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8229 tmp = load_reg(s, rs);
8230 tmp2 = load_reg(s, rm);
8231 if (insn & (1 << 22)) {
8232 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8233 } else {
8234 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8236 if (insn & (1 << 21)) { /* mult accumulate */
8237 TCGv_i32 al = load_reg(s, rn);
8238 TCGv_i32 ah = load_reg(s, rd);
8239 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8240 tcg_temp_free_i32(al);
8241 tcg_temp_free_i32(ah);
8243 if (insn & (1 << 20)) {
8244 gen_logicq_cc(tmp, tmp2);
8246 store_reg(s, rn, tmp);
8247 store_reg(s, rd, tmp2);
8248 break;
8249 default:
8250 goto illegal_op;
8252 } else {
8253 rn = (insn >> 16) & 0xf;
8254 rd = (insn >> 12) & 0xf;
8255 if (insn & (1 << 23)) {
8256 /* load/store exclusive */
8257 int op2 = (insn >> 8) & 3;
8258 op1 = (insn >> 21) & 0x3;
8260 switch (op2) {
8261 case 0: /* lda/stl */
8262 if (op1 == 1) {
8263 goto illegal_op;
8265 ARCH(8);
8266 break;
8267 case 1: /* reserved */
8268 goto illegal_op;
8269 case 2: /* ldaex/stlex */
8270 ARCH(8);
8271 break;
8272 case 3: /* ldrex/strex */
8273 if (op1) {
8274 ARCH(6K);
8275 } else {
8276 ARCH(6);
8278 break;
8281 addr = tcg_temp_local_new_i32();
8282 load_reg_var(s, addr, rn);
8284 /* Since the emulation does not have barriers,
8285 the acquire/release semantics need no special
8286 handling */
8287 if (op2 == 0) {
8288 if (insn & (1 << 20)) {
8289 tmp = tcg_temp_new_i32();
8290 switch (op1) {
8291 case 0: /* lda */
8292 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8293 break;
8294 case 2: /* ldab */
8295 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
8296 break;
8297 case 3: /* ldah */
8298 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8299 break;
8300 default:
8301 abort();
8303 store_reg(s, rd, tmp);
8304 } else {
8305 rm = insn & 0xf;
8306 tmp = load_reg(s, rm);
8307 switch (op1) {
8308 case 0: /* stl */
8309 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8310 break;
8311 case 2: /* stlb */
8312 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8313 break;
8314 case 3: /* stlh */
8315 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8316 break;
8317 default:
8318 abort();
8320 tcg_temp_free_i32(tmp);
8322 } else if (insn & (1 << 20)) {
8323 switch (op1) {
8324 case 0: /* ldrex */
8325 gen_load_exclusive(s, rd, 15, addr, 2);
8326 break;
8327 case 1: /* ldrexd */
8328 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8329 break;
8330 case 2: /* ldrexb */
8331 gen_load_exclusive(s, rd, 15, addr, 0);
8332 break;
8333 case 3: /* ldrexh */
8334 gen_load_exclusive(s, rd, 15, addr, 1);
8335 break;
8336 default:
8337 abort();
8339 } else {
8340 rm = insn & 0xf;
8341 switch (op1) {
8342 case 0: /* strex */
8343 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8344 break;
8345 case 1: /* strexd */
8346 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8347 break;
8348 case 2: /* strexb */
8349 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8350 break;
8351 case 3: /* strexh */
8352 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8353 break;
8354 default:
8355 abort();
8358 tcg_temp_free_i32(addr);
8359 } else {
8360 /* SWP instruction */
8361 rm = (insn) & 0xf;
8363 /* ??? This is not really atomic. However we know
8364 we never have multiple CPUs running in parallel,
8365 so it is good enough. */
8366 addr = load_reg(s, rn);
8367 tmp = load_reg(s, rm);
8368 tmp2 = tcg_temp_new_i32();
8369 if (insn & (1 << 22)) {
8370 gen_aa32_ld8u(s, tmp2, addr, get_mem_index(s));
8371 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
8372 } else {
8373 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8374 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8376 tcg_temp_free_i32(tmp);
8377 tcg_temp_free_i32(addr);
8378 store_reg(s, rd, tmp2);
8381 } else {
8382 int address_offset;
8383 int load;
8384 /* Misc load/store */
8385 rn = (insn >> 16) & 0xf;
8386 rd = (insn >> 12) & 0xf;
8387 addr = load_reg(s, rn);
8388 if (insn & (1 << 24))
8389 gen_add_datah_offset(s, insn, 0, addr);
8390 address_offset = 0;
8391 if (insn & (1 << 20)) {
8392 /* load */
8393 tmp = tcg_temp_new_i32();
8394 switch(sh) {
8395 case 1:
8396 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8397 break;
8398 case 2:
8399 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
8400 break;
8401 default:
8402 case 3:
8403 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
8404 break;
8406 load = 1;
8407 } else if (sh & 2) {
8408 ARCH(5TE);
8409 /* doubleword */
8410 if (sh & 1) {
8411 /* store */
8412 tmp = load_reg(s, rd);
8413 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8414 tcg_temp_free_i32(tmp);
8415 tcg_gen_addi_i32(addr, addr, 4);
8416 tmp = load_reg(s, rd + 1);
8417 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8418 tcg_temp_free_i32(tmp);
8419 load = 0;
8420 } else {
8421 /* load */
8422 tmp = tcg_temp_new_i32();
8423 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8424 store_reg(s, rd, tmp);
8425 tcg_gen_addi_i32(addr, addr, 4);
8426 tmp = tcg_temp_new_i32();
8427 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8428 rd++;
8429 load = 1;
8431 address_offset = -4;
8432 } else {
8433 /* store */
8434 tmp = load_reg(s, rd);
8435 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8436 tcg_temp_free_i32(tmp);
8437 load = 0;
8439 /* Perform base writeback before the loaded value to
8440 ensure correct behavior with overlapping index registers.
8441 ldrd with base writeback is is undefined if the
8442 destination and index registers overlap. */
8443 if (!(insn & (1 << 24))) {
8444 gen_add_datah_offset(s, insn, address_offset, addr);
8445 store_reg(s, rn, addr);
8446 } else if (insn & (1 << 21)) {
8447 if (address_offset)
8448 tcg_gen_addi_i32(addr, addr, address_offset);
8449 store_reg(s, rn, addr);
8450 } else {
8451 tcg_temp_free_i32(addr);
8453 if (load) {
8454 /* Complete the load. */
8455 store_reg(s, rd, tmp);
8458 break;
8459 case 0x4:
8460 case 0x5:
8461 goto do_ldst;
8462 case 0x6:
8463 case 0x7:
8464 if (insn & (1 << 4)) {
8465 ARCH(6);
8466 /* Armv6 Media instructions. */
8467 rm = insn & 0xf;
8468 rn = (insn >> 16) & 0xf;
8469 rd = (insn >> 12) & 0xf;
8470 rs = (insn >> 8) & 0xf;
8471 switch ((insn >> 23) & 3) {
8472 case 0: /* Parallel add/subtract. */
8473 op1 = (insn >> 20) & 7;
8474 tmp = load_reg(s, rn);
8475 tmp2 = load_reg(s, rm);
8476 sh = (insn >> 5) & 7;
8477 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8478 goto illegal_op;
8479 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8480 tcg_temp_free_i32(tmp2);
8481 store_reg(s, rd, tmp);
8482 break;
8483 case 1:
8484 if ((insn & 0x00700020) == 0) {
8485 /* Halfword pack. */
8486 tmp = load_reg(s, rn);
8487 tmp2 = load_reg(s, rm);
8488 shift = (insn >> 7) & 0x1f;
8489 if (insn & (1 << 6)) {
8490 /* pkhtb */
8491 if (shift == 0)
8492 shift = 31;
8493 tcg_gen_sari_i32(tmp2, tmp2, shift);
8494 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8495 tcg_gen_ext16u_i32(tmp2, tmp2);
8496 } else {
8497 /* pkhbt */
8498 if (shift)
8499 tcg_gen_shli_i32(tmp2, tmp2, shift);
8500 tcg_gen_ext16u_i32(tmp, tmp);
8501 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8503 tcg_gen_or_i32(tmp, tmp, tmp2);
8504 tcg_temp_free_i32(tmp2);
8505 store_reg(s, rd, tmp);
8506 } else if ((insn & 0x00200020) == 0x00200000) {
8507 /* [us]sat */
8508 tmp = load_reg(s, rm);
8509 shift = (insn >> 7) & 0x1f;
8510 if (insn & (1 << 6)) {
8511 if (shift == 0)
8512 shift = 31;
8513 tcg_gen_sari_i32(tmp, tmp, shift);
8514 } else {
8515 tcg_gen_shli_i32(tmp, tmp, shift);
8517 sh = (insn >> 16) & 0x1f;
8518 tmp2 = tcg_const_i32(sh);
8519 if (insn & (1 << 22))
8520 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8521 else
8522 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8523 tcg_temp_free_i32(tmp2);
8524 store_reg(s, rd, tmp);
8525 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8526 /* [us]sat16 */
8527 tmp = load_reg(s, rm);
8528 sh = (insn >> 16) & 0x1f;
8529 tmp2 = tcg_const_i32(sh);
8530 if (insn & (1 << 22))
8531 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8532 else
8533 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8534 tcg_temp_free_i32(tmp2);
8535 store_reg(s, rd, tmp);
8536 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8537 /* Select bytes. */
8538 tmp = load_reg(s, rn);
8539 tmp2 = load_reg(s, rm);
8540 tmp3 = tcg_temp_new_i32();
8541 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8542 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8543 tcg_temp_free_i32(tmp3);
8544 tcg_temp_free_i32(tmp2);
8545 store_reg(s, rd, tmp);
8546 } else if ((insn & 0x000003e0) == 0x00000060) {
8547 tmp = load_reg(s, rm);
8548 shift = (insn >> 10) & 3;
8549 /* ??? In many cases it's not necessary to do a
8550 rotate, a shift is sufficient. */
8551 if (shift != 0)
8552 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8553 op1 = (insn >> 20) & 7;
8554 switch (op1) {
8555 case 0: gen_sxtb16(tmp); break;
8556 case 2: gen_sxtb(tmp); break;
8557 case 3: gen_sxth(tmp); break;
8558 case 4: gen_uxtb16(tmp); break;
8559 case 6: gen_uxtb(tmp); break;
8560 case 7: gen_uxth(tmp); break;
8561 default: goto illegal_op;
8563 if (rn != 15) {
8564 tmp2 = load_reg(s, rn);
8565 if ((op1 & 3) == 0) {
8566 gen_add16(tmp, tmp2);
8567 } else {
8568 tcg_gen_add_i32(tmp, tmp, tmp2);
8569 tcg_temp_free_i32(tmp2);
8572 store_reg(s, rd, tmp);
8573 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8574 /* rev */
8575 tmp = load_reg(s, rm);
8576 if (insn & (1 << 22)) {
8577 if (insn & (1 << 7)) {
8578 gen_revsh(tmp);
8579 } else {
8580 ARCH(6T2);
8581 gen_helper_rbit(tmp, tmp);
8583 } else {
8584 if (insn & (1 << 7))
8585 gen_rev16(tmp);
8586 else
8587 tcg_gen_bswap32_i32(tmp, tmp);
8589 store_reg(s, rd, tmp);
8590 } else {
8591 goto illegal_op;
8593 break;
8594 case 2: /* Multiplies (Type 3). */
8595 switch ((insn >> 20) & 0x7) {
8596 case 5:
8597 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8598 /* op2 not 00x or 11x : UNDEF */
8599 goto illegal_op;
8601 /* Signed multiply most significant [accumulate].
8602 (SMMUL, SMMLA, SMMLS) */
8603 tmp = load_reg(s, rm);
8604 tmp2 = load_reg(s, rs);
8605 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8607 if (rd != 15) {
8608 tmp = load_reg(s, rd);
8609 if (insn & (1 << 6)) {
8610 tmp64 = gen_subq_msw(tmp64, tmp);
8611 } else {
8612 tmp64 = gen_addq_msw(tmp64, tmp);
8615 if (insn & (1 << 5)) {
8616 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8618 tcg_gen_shri_i64(tmp64, tmp64, 32);
8619 tmp = tcg_temp_new_i32();
8620 tcg_gen_trunc_i64_i32(tmp, tmp64);
8621 tcg_temp_free_i64(tmp64);
8622 store_reg(s, rn, tmp);
8623 break;
8624 case 0:
8625 case 4:
8626 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8627 if (insn & (1 << 7)) {
8628 goto illegal_op;
8630 tmp = load_reg(s, rm);
8631 tmp2 = load_reg(s, rs);
8632 if (insn & (1 << 5))
8633 gen_swap_half(tmp2);
8634 gen_smul_dual(tmp, tmp2);
8635 if (insn & (1 << 22)) {
8636 /* smlald, smlsld */
8637 TCGv_i64 tmp64_2;
8639 tmp64 = tcg_temp_new_i64();
8640 tmp64_2 = tcg_temp_new_i64();
8641 tcg_gen_ext_i32_i64(tmp64, tmp);
8642 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8643 tcg_temp_free_i32(tmp);
8644 tcg_temp_free_i32(tmp2);
8645 if (insn & (1 << 6)) {
8646 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8647 } else {
8648 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8650 tcg_temp_free_i64(tmp64_2);
8651 gen_addq(s, tmp64, rd, rn);
8652 gen_storeq_reg(s, rd, rn, tmp64);
8653 tcg_temp_free_i64(tmp64);
8654 } else {
8655 /* smuad, smusd, smlad, smlsd */
8656 if (insn & (1 << 6)) {
8657 /* This subtraction cannot overflow. */
8658 tcg_gen_sub_i32(tmp, tmp, tmp2);
8659 } else {
8660 /* This addition cannot overflow 32 bits;
8661 * however it may overflow considered as a
8662 * signed operation, in which case we must set
8663 * the Q flag.
8665 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8667 tcg_temp_free_i32(tmp2);
8668 if (rd != 15)
8670 tmp2 = load_reg(s, rd);
8671 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8672 tcg_temp_free_i32(tmp2);
8674 store_reg(s, rn, tmp);
8676 break;
8677 case 1:
8678 case 3:
8679 /* SDIV, UDIV */
8680 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8681 goto illegal_op;
8683 if (((insn >> 5) & 7) || (rd != 15)) {
8684 goto illegal_op;
8686 tmp = load_reg(s, rm);
8687 tmp2 = load_reg(s, rs);
8688 if (insn & (1 << 21)) {
8689 gen_helper_udiv(tmp, tmp, tmp2);
8690 } else {
8691 gen_helper_sdiv(tmp, tmp, tmp2);
8693 tcg_temp_free_i32(tmp2);
8694 store_reg(s, rn, tmp);
8695 break;
8696 default:
8697 goto illegal_op;
8699 break;
8700 case 3:
8701 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8702 switch (op1) {
8703 case 0: /* Unsigned sum of absolute differences. */
8704 ARCH(6);
8705 tmp = load_reg(s, rm);
8706 tmp2 = load_reg(s, rs);
8707 gen_helper_usad8(tmp, tmp, tmp2);
8708 tcg_temp_free_i32(tmp2);
8709 if (rd != 15) {
8710 tmp2 = load_reg(s, rd);
8711 tcg_gen_add_i32(tmp, tmp, tmp2);
8712 tcg_temp_free_i32(tmp2);
8714 store_reg(s, rn, tmp);
8715 break;
8716 case 0x20: case 0x24: case 0x28: case 0x2c:
8717 /* Bitfield insert/clear. */
8718 ARCH(6T2);
8719 shift = (insn >> 7) & 0x1f;
8720 i = (insn >> 16) & 0x1f;
8721 i = i + 1 - shift;
8722 if (rm == 15) {
8723 tmp = tcg_temp_new_i32();
8724 tcg_gen_movi_i32(tmp, 0);
8725 } else {
8726 tmp = load_reg(s, rm);
8728 if (i != 32) {
8729 tmp2 = load_reg(s, rd);
8730 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8731 tcg_temp_free_i32(tmp2);
8733 store_reg(s, rd, tmp);
8734 break;
8735 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8736 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8737 ARCH(6T2);
8738 tmp = load_reg(s, rm);
8739 shift = (insn >> 7) & 0x1f;
8740 i = ((insn >> 16) & 0x1f) + 1;
8741 if (shift + i > 32)
8742 goto illegal_op;
8743 if (i < 32) {
8744 if (op1 & 0x20) {
8745 gen_ubfx(tmp, shift, (1u << i) - 1);
8746 } else {
8747 gen_sbfx(tmp, shift, i);
8750 store_reg(s, rd, tmp);
8751 break;
8752 default:
8753 goto illegal_op;
8755 break;
8757 break;
8759 do_ldst:
8760 /* Check for undefined extension instructions
8761 * per the ARM Bible IE:
8762 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8764 sh = (0xf << 20) | (0xf << 4);
8765 if (op1 == 0x7 && ((insn & sh) == sh))
8767 goto illegal_op;
8769 /* load/store byte/word */
8770 rn = (insn >> 16) & 0xf;
8771 rd = (insn >> 12) & 0xf;
8772 tmp2 = load_reg(s, rn);
8773 if ((insn & 0x01200000) == 0x00200000) {
8774 /* ldrt/strt */
8775 i = MMU_USER_IDX;
8776 } else {
8777 i = get_mem_index(s);
8779 if (insn & (1 << 24))
8780 gen_add_data_offset(s, insn, tmp2);
8781 if (insn & (1 << 20)) {
8782 /* load */
8783 tmp = tcg_temp_new_i32();
8784 if (insn & (1 << 22)) {
8785 gen_aa32_ld8u(s, tmp, tmp2, i);
8786 } else {
8787 gen_aa32_ld32u(s, tmp, tmp2, i);
8789 } else {
8790 /* store */
8791 tmp = load_reg(s, rd);
8792 if (insn & (1 << 22)) {
8793 gen_aa32_st8(s, tmp, tmp2, i);
8794 } else {
8795 gen_aa32_st32(s, tmp, tmp2, i);
8797 tcg_temp_free_i32(tmp);
8799 if (!(insn & (1 << 24))) {
8800 gen_add_data_offset(s, insn, tmp2);
8801 store_reg(s, rn, tmp2);
8802 } else if (insn & (1 << 21)) {
8803 store_reg(s, rn, tmp2);
8804 } else {
8805 tcg_temp_free_i32(tmp2);
8807 if (insn & (1 << 20)) {
8808 /* Complete the load. */
8809 store_reg_from_load(env, s, rd, tmp);
8811 break;
8812 case 0x08:
8813 case 0x09:
8815 int j, n, user, loaded_base;
8816 TCGv_i32 loaded_var;
8817 /* load/store multiple words */
8818 /* XXX: store correct base if write back */
8819 user = 0;
8820 if (insn & (1 << 22)) {
8821 if (IS_USER(s))
8822 goto illegal_op; /* only usable in supervisor mode */
8824 if ((insn & (1 << 15)) == 0)
8825 user = 1;
8827 rn = (insn >> 16) & 0xf;
8828 addr = load_reg(s, rn);
8830 /* compute total size */
8831 loaded_base = 0;
8832 TCGV_UNUSED_I32(loaded_var);
8833 n = 0;
8834 for(i=0;i<16;i++) {
8835 if (insn & (1 << i))
8836 n++;
8838 /* XXX: test invalid n == 0 case ? */
8839 if (insn & (1 << 23)) {
8840 if (insn & (1 << 24)) {
8841 /* pre increment */
8842 tcg_gen_addi_i32(addr, addr, 4);
8843 } else {
8844 /* post increment */
8846 } else {
8847 if (insn & (1 << 24)) {
8848 /* pre decrement */
8849 tcg_gen_addi_i32(addr, addr, -(n * 4));
8850 } else {
8851 /* post decrement */
8852 if (n != 1)
8853 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8856 j = 0;
8857 for(i=0;i<16;i++) {
8858 if (insn & (1 << i)) {
8859 if (insn & (1 << 20)) {
8860 /* load */
8861 tmp = tcg_temp_new_i32();
8862 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8863 if (user) {
8864 tmp2 = tcg_const_i32(i);
8865 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8866 tcg_temp_free_i32(tmp2);
8867 tcg_temp_free_i32(tmp);
8868 } else if (i == rn) {
8869 loaded_var = tmp;
8870 loaded_base = 1;
8871 } else {
8872 store_reg_from_load(env, s, i, tmp);
8874 } else {
8875 /* store */
8876 if (i == 15) {
8877 /* special case: r15 = PC + 8 */
8878 val = (long)s->pc + 4;
8879 tmp = tcg_temp_new_i32();
8880 tcg_gen_movi_i32(tmp, val);
8881 } else if (user) {
8882 tmp = tcg_temp_new_i32();
8883 tmp2 = tcg_const_i32(i);
8884 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8885 tcg_temp_free_i32(tmp2);
8886 } else {
8887 tmp = load_reg(s, i);
8889 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8890 tcg_temp_free_i32(tmp);
8892 j++;
8893 /* no need to add after the last transfer */
8894 if (j != n)
8895 tcg_gen_addi_i32(addr, addr, 4);
8898 if (insn & (1 << 21)) {
8899 /* write back */
8900 if (insn & (1 << 23)) {
8901 if (insn & (1 << 24)) {
8902 /* pre increment */
8903 } else {
8904 /* post increment */
8905 tcg_gen_addi_i32(addr, addr, 4);
8907 } else {
8908 if (insn & (1 << 24)) {
8909 /* pre decrement */
8910 if (n != 1)
8911 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8912 } else {
8913 /* post decrement */
8914 tcg_gen_addi_i32(addr, addr, -(n * 4));
8917 store_reg(s, rn, addr);
8918 } else {
8919 tcg_temp_free_i32(addr);
8921 if (loaded_base) {
8922 store_reg(s, rn, loaded_var);
8924 if ((insn & (1 << 22)) && !user) {
8925 /* Restore CPSR from SPSR. */
8926 tmp = load_cpu_field(spsr);
8927 gen_set_cpsr(tmp, CPSR_ERET_MASK);
8928 tcg_temp_free_i32(tmp);
8929 s->is_jmp = DISAS_UPDATE;
8932 break;
8933 case 0xa:
8934 case 0xb:
8936 int32_t offset;
8938 /* branch (and link) */
8939 val = (int32_t)s->pc;
8940 if (insn & (1 << 24)) {
8941 tmp = tcg_temp_new_i32();
8942 tcg_gen_movi_i32(tmp, val);
8943 store_reg(s, 14, tmp);
8945 offset = sextract32(insn << 2, 0, 26);
8946 val += offset + 4;
8947 gen_jmp(s, val);
8949 break;
8950 case 0xc:
8951 case 0xd:
8952 case 0xe:
8953 if (((insn >> 8) & 0xe) == 10) {
8954 /* VFP. */
8955 if (disas_vfp_insn(env, s, insn)) {
8956 goto illegal_op;
8958 } else if (disas_coproc_insn(env, s, insn)) {
8959 /* Coprocessor. */
8960 goto illegal_op;
8962 break;
8963 case 0xf:
8964 /* swi */
8965 gen_set_pc_im(s, s->pc);
8966 s->svc_imm = extract32(insn, 0, 24);
8967 s->is_jmp = DISAS_SWI;
8968 break;
8969 default:
8970 illegal_op:
8971 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
8972 break;
8977 /* Return true if this is a Thumb-2 logical op. */
8978 static int
8979 thumb2_logic_op(int op)
8981 return (op < 8);
8984 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8985 then set condition code flags based on the result of the operation.
8986 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8987 to the high bit of T1.
8988 Returns zero if the opcode is valid. */
8990 static int
8991 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8992 TCGv_i32 t0, TCGv_i32 t1)
8994 int logic_cc;
8996 logic_cc = 0;
8997 switch (op) {
8998 case 0: /* and */
8999 tcg_gen_and_i32(t0, t0, t1);
9000 logic_cc = conds;
9001 break;
9002 case 1: /* bic */
9003 tcg_gen_andc_i32(t0, t0, t1);
9004 logic_cc = conds;
9005 break;
9006 case 2: /* orr */
9007 tcg_gen_or_i32(t0, t0, t1);
9008 logic_cc = conds;
9009 break;
9010 case 3: /* orn */
9011 tcg_gen_orc_i32(t0, t0, t1);
9012 logic_cc = conds;
9013 break;
9014 case 4: /* eor */
9015 tcg_gen_xor_i32(t0, t0, t1);
9016 logic_cc = conds;
9017 break;
9018 case 8: /* add */
9019 if (conds)
9020 gen_add_CC(t0, t0, t1);
9021 else
9022 tcg_gen_add_i32(t0, t0, t1);
9023 break;
9024 case 10: /* adc */
9025 if (conds)
9026 gen_adc_CC(t0, t0, t1);
9027 else
9028 gen_adc(t0, t1);
9029 break;
9030 case 11: /* sbc */
9031 if (conds) {
9032 gen_sbc_CC(t0, t0, t1);
9033 } else {
9034 gen_sub_carry(t0, t0, t1);
9036 break;
9037 case 13: /* sub */
9038 if (conds)
9039 gen_sub_CC(t0, t0, t1);
9040 else
9041 tcg_gen_sub_i32(t0, t0, t1);
9042 break;
9043 case 14: /* rsb */
9044 if (conds)
9045 gen_sub_CC(t0, t1, t0);
9046 else
9047 tcg_gen_sub_i32(t0, t1, t0);
9048 break;
9049 default: /* 5, 6, 7, 9, 12, 15. */
9050 return 1;
9052 if (logic_cc) {
9053 gen_logic_CC(t0);
9054 if (shifter_out)
9055 gen_set_CF_bit31(t1);
9057 return 0;
9060 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9061 is not legal. */
9062 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9064 uint32_t insn, imm, shift, offset;
9065 uint32_t rd, rn, rm, rs;
9066 TCGv_i32 tmp;
9067 TCGv_i32 tmp2;
9068 TCGv_i32 tmp3;
9069 TCGv_i32 addr;
9070 TCGv_i64 tmp64;
9071 int op;
9072 int shiftop;
9073 int conds;
9074 int logic_cc;
9076 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
9077 || arm_feature (env, ARM_FEATURE_M))) {
9078 /* Thumb-1 cores may need to treat bl and blx as a pair of
9079 16-bit instructions to get correct prefetch abort behavior. */
9080 insn = insn_hw1;
9081 if ((insn & (1 << 12)) == 0) {
9082 ARCH(5);
9083 /* Second half of blx. */
9084 offset = ((insn & 0x7ff) << 1);
9085 tmp = load_reg(s, 14);
9086 tcg_gen_addi_i32(tmp, tmp, offset);
9087 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9089 tmp2 = tcg_temp_new_i32();
9090 tcg_gen_movi_i32(tmp2, s->pc | 1);
9091 store_reg(s, 14, tmp2);
9092 gen_bx(s, tmp);
9093 return 0;
9095 if (insn & (1 << 11)) {
9096 /* Second half of bl. */
9097 offset = ((insn & 0x7ff) << 1) | 1;
9098 tmp = load_reg(s, 14);
9099 tcg_gen_addi_i32(tmp, tmp, offset);
9101 tmp2 = tcg_temp_new_i32();
9102 tcg_gen_movi_i32(tmp2, s->pc | 1);
9103 store_reg(s, 14, tmp2);
9104 gen_bx(s, tmp);
9105 return 0;
9107 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9108 /* Instruction spans a page boundary. Implement it as two
9109 16-bit instructions in case the second half causes an
9110 prefetch abort. */
9111 offset = ((int32_t)insn << 21) >> 9;
9112 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9113 return 0;
9115 /* Fall through to 32-bit decode. */
9118 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9119 s->pc += 2;
9120 insn |= (uint32_t)insn_hw1 << 16;
9122 if ((insn & 0xf800e800) != 0xf000e800) {
9123 ARCH(6T2);
9126 rn = (insn >> 16) & 0xf;
9127 rs = (insn >> 12) & 0xf;
9128 rd = (insn >> 8) & 0xf;
9129 rm = insn & 0xf;
9130 switch ((insn >> 25) & 0xf) {
9131 case 0: case 1: case 2: case 3:
9132 /* 16-bit instructions. Should never happen. */
9133 abort();
9134 case 4:
9135 if (insn & (1 << 22)) {
9136 /* Other load/store, table branch. */
9137 if (insn & 0x01200000) {
9138 ARCH(5); /* Load/store doubleword. */
9139 if (rn == 15) {
9140 addr = tcg_temp_new_i32();
9141 tcg_gen_movi_i32(addr, s->pc & ~3);
9142 } else {
9143 addr = load_reg(s, rn);
9145 offset = (insn & 0xff) * 4;
9146 if ((insn & (1 << 23)) == 0)
9147 offset = -offset;
9148 if (insn & (1 << 24)) {
9149 tcg_gen_addi_i32(addr, addr, offset);
9150 offset = 0;
9152 if (insn & (1 << 20)) {
9153 /* ldrd */
9154 tmp = tcg_temp_new_i32();
9155 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9156 store_reg(s, rs, tmp);
9157 tcg_gen_addi_i32(addr, addr, 4);
9158 tmp = tcg_temp_new_i32();
9159 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9160 store_reg(s, rd, tmp);
9161 } else {
9162 /* strd */
9163 tmp = load_reg(s, rs);
9164 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9165 tcg_temp_free_i32(tmp);
9166 tcg_gen_addi_i32(addr, addr, 4);
9167 tmp = load_reg(s, rd);
9168 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9169 tcg_temp_free_i32(tmp);
9171 if (insn & (1 << 21)) {
9172 /* Base writeback. */
9173 if (rn == 15)
9174 goto illegal_op;
9175 tcg_gen_addi_i32(addr, addr, offset - 4);
9176 store_reg(s, rn, addr);
9177 } else {
9178 tcg_temp_free_i32(addr);
9180 } else if ((insn & (1 << 23)) == 0) {
9181 /* Load/store exclusive word. */
9182 addr = tcg_temp_local_new_i32();
9183 load_reg_var(s, addr, rn);
9184 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9185 if (insn & (1 << 20)) {
9186 gen_load_exclusive(s, rs, 15, addr, 2);
9187 } else {
9188 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9190 tcg_temp_free_i32(addr);
9191 } else if ((insn & (7 << 5)) == 0) {
9192 /* Table Branch. */
9193 if (rn == 15) {
9194 addr = tcg_temp_new_i32();
9195 tcg_gen_movi_i32(addr, s->pc);
9196 } else {
9197 addr = load_reg(s, rn);
9199 tmp = load_reg(s, rm);
9200 tcg_gen_add_i32(addr, addr, tmp);
9201 if (insn & (1 << 4)) {
9202 /* tbh */
9203 tcg_gen_add_i32(addr, addr, tmp);
9204 tcg_temp_free_i32(tmp);
9205 tmp = tcg_temp_new_i32();
9206 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9207 } else { /* tbb */
9208 tcg_temp_free_i32(tmp);
9209 tmp = tcg_temp_new_i32();
9210 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9212 tcg_temp_free_i32(addr);
9213 tcg_gen_shli_i32(tmp, tmp, 1);
9214 tcg_gen_addi_i32(tmp, tmp, s->pc);
9215 store_reg(s, 15, tmp);
9216 } else {
9217 int op2 = (insn >> 6) & 0x3;
9218 op = (insn >> 4) & 0x3;
9219 switch (op2) {
9220 case 0:
9221 goto illegal_op;
9222 case 1:
9223 /* Load/store exclusive byte/halfword/doubleword */
9224 if (op == 2) {
9225 goto illegal_op;
9227 ARCH(7);
9228 break;
9229 case 2:
9230 /* Load-acquire/store-release */
9231 if (op == 3) {
9232 goto illegal_op;
9234 /* Fall through */
9235 case 3:
9236 /* Load-acquire/store-release exclusive */
9237 ARCH(8);
9238 break;
9240 addr = tcg_temp_local_new_i32();
9241 load_reg_var(s, addr, rn);
9242 if (!(op2 & 1)) {
9243 if (insn & (1 << 20)) {
9244 tmp = tcg_temp_new_i32();
9245 switch (op) {
9246 case 0: /* ldab */
9247 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9248 break;
9249 case 1: /* ldah */
9250 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9251 break;
9252 case 2: /* lda */
9253 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9254 break;
9255 default:
9256 abort();
9258 store_reg(s, rs, tmp);
9259 } else {
9260 tmp = load_reg(s, rs);
9261 switch (op) {
9262 case 0: /* stlb */
9263 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
9264 break;
9265 case 1: /* stlh */
9266 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
9267 break;
9268 case 2: /* stl */
9269 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9270 break;
9271 default:
9272 abort();
9274 tcg_temp_free_i32(tmp);
9276 } else if (insn & (1 << 20)) {
9277 gen_load_exclusive(s, rs, rd, addr, op);
9278 } else {
9279 gen_store_exclusive(s, rm, rs, rd, addr, op);
9281 tcg_temp_free_i32(addr);
9283 } else {
9284 /* Load/store multiple, RFE, SRS. */
9285 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9286 /* RFE, SRS: not available in user mode or on M profile */
9287 if (IS_USER(s) || IS_M(env)) {
9288 goto illegal_op;
9290 if (insn & (1 << 20)) {
9291 /* rfe */
9292 addr = load_reg(s, rn);
9293 if ((insn & (1 << 24)) == 0)
9294 tcg_gen_addi_i32(addr, addr, -8);
9295 /* Load PC into tmp and CPSR into tmp2. */
9296 tmp = tcg_temp_new_i32();
9297 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9298 tcg_gen_addi_i32(addr, addr, 4);
9299 tmp2 = tcg_temp_new_i32();
9300 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9301 if (insn & (1 << 21)) {
9302 /* Base writeback. */
9303 if (insn & (1 << 24)) {
9304 tcg_gen_addi_i32(addr, addr, 4);
9305 } else {
9306 tcg_gen_addi_i32(addr, addr, -4);
9308 store_reg(s, rn, addr);
9309 } else {
9310 tcg_temp_free_i32(addr);
9312 gen_rfe(s, tmp, tmp2);
9313 } else {
9314 /* srs */
9315 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9316 insn & (1 << 21));
9318 } else {
9319 int i, loaded_base = 0;
9320 TCGv_i32 loaded_var;
9321 /* Load/store multiple. */
9322 addr = load_reg(s, rn);
9323 offset = 0;
9324 for (i = 0; i < 16; i++) {
9325 if (insn & (1 << i))
9326 offset += 4;
9328 if (insn & (1 << 24)) {
9329 tcg_gen_addi_i32(addr, addr, -offset);
9332 TCGV_UNUSED_I32(loaded_var);
9333 for (i = 0; i < 16; i++) {
9334 if ((insn & (1 << i)) == 0)
9335 continue;
9336 if (insn & (1 << 20)) {
9337 /* Load. */
9338 tmp = tcg_temp_new_i32();
9339 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9340 if (i == 15) {
9341 gen_bx(s, tmp);
9342 } else if (i == rn) {
9343 loaded_var = tmp;
9344 loaded_base = 1;
9345 } else {
9346 store_reg(s, i, tmp);
9348 } else {
9349 /* Store. */
9350 tmp = load_reg(s, i);
9351 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9352 tcg_temp_free_i32(tmp);
9354 tcg_gen_addi_i32(addr, addr, 4);
9356 if (loaded_base) {
9357 store_reg(s, rn, loaded_var);
9359 if (insn & (1 << 21)) {
9360 /* Base register writeback. */
9361 if (insn & (1 << 24)) {
9362 tcg_gen_addi_i32(addr, addr, -offset);
9364 /* Fault if writeback register is in register list. */
9365 if (insn & (1 << rn))
9366 goto illegal_op;
9367 store_reg(s, rn, addr);
9368 } else {
9369 tcg_temp_free_i32(addr);
9373 break;
9374 case 5:
9376 op = (insn >> 21) & 0xf;
9377 if (op == 6) {
9378 /* Halfword pack. */
9379 tmp = load_reg(s, rn);
9380 tmp2 = load_reg(s, rm);
9381 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9382 if (insn & (1 << 5)) {
9383 /* pkhtb */
9384 if (shift == 0)
9385 shift = 31;
9386 tcg_gen_sari_i32(tmp2, tmp2, shift);
9387 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9388 tcg_gen_ext16u_i32(tmp2, tmp2);
9389 } else {
9390 /* pkhbt */
9391 if (shift)
9392 tcg_gen_shli_i32(tmp2, tmp2, shift);
9393 tcg_gen_ext16u_i32(tmp, tmp);
9394 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9396 tcg_gen_or_i32(tmp, tmp, tmp2);
9397 tcg_temp_free_i32(tmp2);
9398 store_reg(s, rd, tmp);
9399 } else {
9400 /* Data processing register constant shift. */
9401 if (rn == 15) {
9402 tmp = tcg_temp_new_i32();
9403 tcg_gen_movi_i32(tmp, 0);
9404 } else {
9405 tmp = load_reg(s, rn);
9407 tmp2 = load_reg(s, rm);
9409 shiftop = (insn >> 4) & 3;
9410 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9411 conds = (insn & (1 << 20)) != 0;
9412 logic_cc = (conds && thumb2_logic_op(op));
9413 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9414 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9415 goto illegal_op;
9416 tcg_temp_free_i32(tmp2);
9417 if (rd != 15) {
9418 store_reg(s, rd, tmp);
9419 } else {
9420 tcg_temp_free_i32(tmp);
9423 break;
9424 case 13: /* Misc data processing. */
9425 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9426 if (op < 4 && (insn & 0xf000) != 0xf000)
9427 goto illegal_op;
9428 switch (op) {
9429 case 0: /* Register controlled shift. */
9430 tmp = load_reg(s, rn);
9431 tmp2 = load_reg(s, rm);
9432 if ((insn & 0x70) != 0)
9433 goto illegal_op;
9434 op = (insn >> 21) & 3;
9435 logic_cc = (insn & (1 << 20)) != 0;
9436 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9437 if (logic_cc)
9438 gen_logic_CC(tmp);
9439 store_reg_bx(env, s, rd, tmp);
9440 break;
9441 case 1: /* Sign/zero extend. */
9442 tmp = load_reg(s, rm);
9443 shift = (insn >> 4) & 3;
9444 /* ??? In many cases it's not necessary to do a
9445 rotate, a shift is sufficient. */
9446 if (shift != 0)
9447 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9448 op = (insn >> 20) & 7;
9449 switch (op) {
9450 case 0: gen_sxth(tmp); break;
9451 case 1: gen_uxth(tmp); break;
9452 case 2: gen_sxtb16(tmp); break;
9453 case 3: gen_uxtb16(tmp); break;
9454 case 4: gen_sxtb(tmp); break;
9455 case 5: gen_uxtb(tmp); break;
9456 default: goto illegal_op;
9458 if (rn != 15) {
9459 tmp2 = load_reg(s, rn);
9460 if ((op >> 1) == 1) {
9461 gen_add16(tmp, tmp2);
9462 } else {
9463 tcg_gen_add_i32(tmp, tmp, tmp2);
9464 tcg_temp_free_i32(tmp2);
9467 store_reg(s, rd, tmp);
9468 break;
9469 case 2: /* SIMD add/subtract. */
9470 op = (insn >> 20) & 7;
9471 shift = (insn >> 4) & 7;
9472 if ((op & 3) == 3 || (shift & 3) == 3)
9473 goto illegal_op;
9474 tmp = load_reg(s, rn);
9475 tmp2 = load_reg(s, rm);
9476 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9477 tcg_temp_free_i32(tmp2);
9478 store_reg(s, rd, tmp);
9479 break;
9480 case 3: /* Other data processing. */
9481 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9482 if (op < 4) {
9483 /* Saturating add/subtract. */
9484 tmp = load_reg(s, rn);
9485 tmp2 = load_reg(s, rm);
9486 if (op & 1)
9487 gen_helper_double_saturate(tmp, cpu_env, tmp);
9488 if (op & 2)
9489 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9490 else
9491 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9492 tcg_temp_free_i32(tmp2);
9493 } else {
9494 tmp = load_reg(s, rn);
9495 switch (op) {
9496 case 0x0a: /* rbit */
9497 gen_helper_rbit(tmp, tmp);
9498 break;
9499 case 0x08: /* rev */
9500 tcg_gen_bswap32_i32(tmp, tmp);
9501 break;
9502 case 0x09: /* rev16 */
9503 gen_rev16(tmp);
9504 break;
9505 case 0x0b: /* revsh */
9506 gen_revsh(tmp);
9507 break;
9508 case 0x10: /* sel */
9509 tmp2 = load_reg(s, rm);
9510 tmp3 = tcg_temp_new_i32();
9511 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9512 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9513 tcg_temp_free_i32(tmp3);
9514 tcg_temp_free_i32(tmp2);
9515 break;
9516 case 0x18: /* clz */
9517 gen_helper_clz(tmp, tmp);
9518 break;
9519 case 0x20:
9520 case 0x21:
9521 case 0x22:
9522 case 0x28:
9523 case 0x29:
9524 case 0x2a:
9526 /* crc32/crc32c */
9527 uint32_t sz = op & 0x3;
9528 uint32_t c = op & 0x8;
9530 if (!arm_feature(env, ARM_FEATURE_CRC)) {
9531 goto illegal_op;
9534 tmp2 = load_reg(s, rm);
9535 if (sz == 0) {
9536 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9537 } else if (sz == 1) {
9538 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9540 tmp3 = tcg_const_i32(1 << sz);
9541 if (c) {
9542 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9543 } else {
9544 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9546 tcg_temp_free_i32(tmp2);
9547 tcg_temp_free_i32(tmp3);
9548 break;
9550 default:
9551 goto illegal_op;
9554 store_reg(s, rd, tmp);
9555 break;
9556 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9557 op = (insn >> 4) & 0xf;
9558 tmp = load_reg(s, rn);
9559 tmp2 = load_reg(s, rm);
9560 switch ((insn >> 20) & 7) {
9561 case 0: /* 32 x 32 -> 32 */
9562 tcg_gen_mul_i32(tmp, tmp, tmp2);
9563 tcg_temp_free_i32(tmp2);
9564 if (rs != 15) {
9565 tmp2 = load_reg(s, rs);
9566 if (op)
9567 tcg_gen_sub_i32(tmp, tmp2, tmp);
9568 else
9569 tcg_gen_add_i32(tmp, tmp, tmp2);
9570 tcg_temp_free_i32(tmp2);
9572 break;
9573 case 1: /* 16 x 16 -> 32 */
9574 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9575 tcg_temp_free_i32(tmp2);
9576 if (rs != 15) {
9577 tmp2 = load_reg(s, rs);
9578 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9579 tcg_temp_free_i32(tmp2);
9581 break;
9582 case 2: /* Dual multiply add. */
9583 case 4: /* Dual multiply subtract. */
9584 if (op)
9585 gen_swap_half(tmp2);
9586 gen_smul_dual(tmp, tmp2);
9587 if (insn & (1 << 22)) {
9588 /* This subtraction cannot overflow. */
9589 tcg_gen_sub_i32(tmp, tmp, tmp2);
9590 } else {
9591 /* This addition cannot overflow 32 bits;
9592 * however it may overflow considered as a signed
9593 * operation, in which case we must set the Q flag.
9595 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9597 tcg_temp_free_i32(tmp2);
9598 if (rs != 15)
9600 tmp2 = load_reg(s, rs);
9601 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9602 tcg_temp_free_i32(tmp2);
9604 break;
9605 case 3: /* 32 * 16 -> 32msb */
9606 if (op)
9607 tcg_gen_sari_i32(tmp2, tmp2, 16);
9608 else
9609 gen_sxth(tmp2);
9610 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9611 tcg_gen_shri_i64(tmp64, tmp64, 16);
9612 tmp = tcg_temp_new_i32();
9613 tcg_gen_trunc_i64_i32(tmp, tmp64);
9614 tcg_temp_free_i64(tmp64);
9615 if (rs != 15)
9617 tmp2 = load_reg(s, rs);
9618 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9619 tcg_temp_free_i32(tmp2);
9621 break;
9622 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9623 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9624 if (rs != 15) {
9625 tmp = load_reg(s, rs);
9626 if (insn & (1 << 20)) {
9627 tmp64 = gen_addq_msw(tmp64, tmp);
9628 } else {
9629 tmp64 = gen_subq_msw(tmp64, tmp);
9632 if (insn & (1 << 4)) {
9633 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9635 tcg_gen_shri_i64(tmp64, tmp64, 32);
9636 tmp = tcg_temp_new_i32();
9637 tcg_gen_trunc_i64_i32(tmp, tmp64);
9638 tcg_temp_free_i64(tmp64);
9639 break;
9640 case 7: /* Unsigned sum of absolute differences. */
9641 gen_helper_usad8(tmp, tmp, tmp2);
9642 tcg_temp_free_i32(tmp2);
9643 if (rs != 15) {
9644 tmp2 = load_reg(s, rs);
9645 tcg_gen_add_i32(tmp, tmp, tmp2);
9646 tcg_temp_free_i32(tmp2);
9648 break;
9650 store_reg(s, rd, tmp);
9651 break;
9652 case 6: case 7: /* 64-bit multiply, Divide. */
9653 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9654 tmp = load_reg(s, rn);
9655 tmp2 = load_reg(s, rm);
9656 if ((op & 0x50) == 0x10) {
9657 /* sdiv, udiv */
9658 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9659 goto illegal_op;
9661 if (op & 0x20)
9662 gen_helper_udiv(tmp, tmp, tmp2);
9663 else
9664 gen_helper_sdiv(tmp, tmp, tmp2);
9665 tcg_temp_free_i32(tmp2);
9666 store_reg(s, rd, tmp);
9667 } else if ((op & 0xe) == 0xc) {
9668 /* Dual multiply accumulate long. */
9669 if (op & 1)
9670 gen_swap_half(tmp2);
9671 gen_smul_dual(tmp, tmp2);
9672 if (op & 0x10) {
9673 tcg_gen_sub_i32(tmp, tmp, tmp2);
9674 } else {
9675 tcg_gen_add_i32(tmp, tmp, tmp2);
9677 tcg_temp_free_i32(tmp2);
9678 /* BUGFIX */
9679 tmp64 = tcg_temp_new_i64();
9680 tcg_gen_ext_i32_i64(tmp64, tmp);
9681 tcg_temp_free_i32(tmp);
9682 gen_addq(s, tmp64, rs, rd);
9683 gen_storeq_reg(s, rs, rd, tmp64);
9684 tcg_temp_free_i64(tmp64);
9685 } else {
9686 if (op & 0x20) {
9687 /* Unsigned 64-bit multiply */
9688 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9689 } else {
9690 if (op & 8) {
9691 /* smlalxy */
9692 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9693 tcg_temp_free_i32(tmp2);
9694 tmp64 = tcg_temp_new_i64();
9695 tcg_gen_ext_i32_i64(tmp64, tmp);
9696 tcg_temp_free_i32(tmp);
9697 } else {
9698 /* Signed 64-bit multiply */
9699 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9702 if (op & 4) {
9703 /* umaal */
9704 gen_addq_lo(s, tmp64, rs);
9705 gen_addq_lo(s, tmp64, rd);
9706 } else if (op & 0x40) {
9707 /* 64-bit accumulate. */
9708 gen_addq(s, tmp64, rs, rd);
9710 gen_storeq_reg(s, rs, rd, tmp64);
9711 tcg_temp_free_i64(tmp64);
9713 break;
9715 break;
9716 case 6: case 7: case 14: case 15:
9717 /* Coprocessor. */
9718 if (((insn >> 24) & 3) == 3) {
9719 /* Translate into the equivalent ARM encoding. */
9720 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9721 if (disas_neon_data_insn(env, s, insn))
9722 goto illegal_op;
9723 } else if (((insn >> 8) & 0xe) == 10) {
9724 if (disas_vfp_insn(env, s, insn)) {
9725 goto illegal_op;
9727 } else {
9728 if (insn & (1 << 28))
9729 goto illegal_op;
9730 if (disas_coproc_insn (env, s, insn))
9731 goto illegal_op;
9733 break;
9734 case 8: case 9: case 10: case 11:
9735 if (insn & (1 << 15)) {
9736 /* Branches, misc control. */
9737 if (insn & 0x5000) {
9738 /* Unconditional branch. */
9739 /* signextend(hw1[10:0]) -> offset[:12]. */
9740 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9741 /* hw1[10:0] -> offset[11:1]. */
9742 offset |= (insn & 0x7ff) << 1;
9743 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9744 offset[24:22] already have the same value because of the
9745 sign extension above. */
9746 offset ^= ((~insn) & (1 << 13)) << 10;
9747 offset ^= ((~insn) & (1 << 11)) << 11;
9749 if (insn & (1 << 14)) {
9750 /* Branch and link. */
9751 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9754 offset += s->pc;
9755 if (insn & (1 << 12)) {
9756 /* b/bl */
9757 gen_jmp(s, offset);
9758 } else {
9759 /* blx */
9760 offset &= ~(uint32_t)2;
9761 /* thumb2 bx, no need to check */
9762 gen_bx_im(s, offset);
9764 } else if (((insn >> 23) & 7) == 7) {
9765 /* Misc control */
9766 if (insn & (1 << 13))
9767 goto illegal_op;
9769 if (insn & (1 << 26)) {
9770 if (!(insn & (1 << 20))) {
9771 /* Hypervisor call (v7) */
9772 int imm16 = extract32(insn, 16, 4) << 12
9773 | extract32(insn, 0, 12);
9774 ARCH(7);
9775 if (IS_USER(s)) {
9776 goto illegal_op;
9778 gen_hvc(s, imm16);
9779 } else {
9780 /* Secure monitor call (v6+) */
9781 ARCH(6K);
9782 if (IS_USER(s)) {
9783 goto illegal_op;
9785 gen_smc(s);
9787 } else {
9788 op = (insn >> 20) & 7;
9789 switch (op) {
9790 case 0: /* msr cpsr. */
9791 if (IS_M(env)) {
9792 tmp = load_reg(s, rn);
9793 addr = tcg_const_i32(insn & 0xff);
9794 gen_helper_v7m_msr(cpu_env, addr, tmp);
9795 tcg_temp_free_i32(addr);
9796 tcg_temp_free_i32(tmp);
9797 gen_lookup_tb(s);
9798 break;
9800 /* fall through */
9801 case 1: /* msr spsr. */
9802 if (IS_M(env))
9803 goto illegal_op;
9804 tmp = load_reg(s, rn);
9805 if (gen_set_psr(s,
9806 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9807 op == 1, tmp))
9808 goto illegal_op;
9809 break;
9810 case 2: /* cps, nop-hint. */
9811 if (((insn >> 8) & 7) == 0) {
9812 gen_nop_hint(s, insn & 0xff);
9814 /* Implemented as NOP in user mode. */
9815 if (IS_USER(s))
9816 break;
9817 offset = 0;
9818 imm = 0;
9819 if (insn & (1 << 10)) {
9820 if (insn & (1 << 7))
9821 offset |= CPSR_A;
9822 if (insn & (1 << 6))
9823 offset |= CPSR_I;
9824 if (insn & (1 << 5))
9825 offset |= CPSR_F;
9826 if (insn & (1 << 9))
9827 imm = CPSR_A | CPSR_I | CPSR_F;
9829 if (insn & (1 << 8)) {
9830 offset |= 0x1f;
9831 imm |= (insn & 0x1f);
9833 if (offset) {
9834 gen_set_psr_im(s, offset, 0, imm);
9836 break;
9837 case 3: /* Special control operations. */
9838 ARCH(7);
9839 op = (insn >> 4) & 0xf;
9840 switch (op) {
9841 case 2: /* clrex */
9842 gen_clrex(s);
9843 break;
9844 case 4: /* dsb */
9845 case 5: /* dmb */
9846 case 6: /* isb */
9847 /* These execute as NOPs. */
9848 break;
9849 default:
9850 goto illegal_op;
9852 break;
9853 case 4: /* bxj */
9854 /* Trivial implementation equivalent to bx. */
9855 tmp = load_reg(s, rn);
9856 gen_bx(s, tmp);
9857 break;
9858 case 5: /* Exception return. */
9859 if (IS_USER(s)) {
9860 goto illegal_op;
9862 if (rn != 14 || rd != 15) {
9863 goto illegal_op;
9865 tmp = load_reg(s, rn);
9866 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9867 gen_exception_return(s, tmp);
9868 break;
9869 case 6: /* mrs cpsr. */
9870 tmp = tcg_temp_new_i32();
9871 if (IS_M(env)) {
9872 addr = tcg_const_i32(insn & 0xff);
9873 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9874 tcg_temp_free_i32(addr);
9875 } else {
9876 gen_helper_cpsr_read(tmp, cpu_env);
9878 store_reg(s, rd, tmp);
9879 break;
9880 case 7: /* mrs spsr. */
9881 /* Not accessible in user mode. */
9882 if (IS_USER(s) || IS_M(env))
9883 goto illegal_op;
9884 tmp = load_cpu_field(spsr);
9885 store_reg(s, rd, tmp);
9886 break;
9889 } else {
9890 /* Conditional branch. */
9891 op = (insn >> 22) & 0xf;
9892 /* Generate a conditional jump to next instruction. */
9893 s->condlabel = gen_new_label();
9894 arm_gen_test_cc(op ^ 1, s->condlabel);
9895 s->condjmp = 1;
9897 /* offset[11:1] = insn[10:0] */
9898 offset = (insn & 0x7ff) << 1;
9899 /* offset[17:12] = insn[21:16]. */
9900 offset |= (insn & 0x003f0000) >> 4;
9901 /* offset[31:20] = insn[26]. */
9902 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9903 /* offset[18] = insn[13]. */
9904 offset |= (insn & (1 << 13)) << 5;
9905 /* offset[19] = insn[11]. */
9906 offset |= (insn & (1 << 11)) << 8;
9908 /* jump to the offset */
9909 gen_jmp(s, s->pc + offset);
9911 } else {
9912 /* Data processing immediate. */
9913 if (insn & (1 << 25)) {
9914 if (insn & (1 << 24)) {
9915 if (insn & (1 << 20))
9916 goto illegal_op;
9917 /* Bitfield/Saturate. */
9918 op = (insn >> 21) & 7;
9919 imm = insn & 0x1f;
9920 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9921 if (rn == 15) {
9922 tmp = tcg_temp_new_i32();
9923 tcg_gen_movi_i32(tmp, 0);
9924 } else {
9925 tmp = load_reg(s, rn);
9927 switch (op) {
9928 case 2: /* Signed bitfield extract. */
9929 imm++;
9930 if (shift + imm > 32)
9931 goto illegal_op;
9932 if (imm < 32)
9933 gen_sbfx(tmp, shift, imm);
9934 break;
9935 case 6: /* Unsigned bitfield extract. */
9936 imm++;
9937 if (shift + imm > 32)
9938 goto illegal_op;
9939 if (imm < 32)
9940 gen_ubfx(tmp, shift, (1u << imm) - 1);
9941 break;
9942 case 3: /* Bitfield insert/clear. */
9943 if (imm < shift)
9944 goto illegal_op;
9945 imm = imm + 1 - shift;
9946 if (imm != 32) {
9947 tmp2 = load_reg(s, rd);
9948 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9949 tcg_temp_free_i32(tmp2);
9951 break;
9952 case 7:
9953 goto illegal_op;
9954 default: /* Saturate. */
9955 if (shift) {
9956 if (op & 1)
9957 tcg_gen_sari_i32(tmp, tmp, shift);
9958 else
9959 tcg_gen_shli_i32(tmp, tmp, shift);
9961 tmp2 = tcg_const_i32(imm);
9962 if (op & 4) {
9963 /* Unsigned. */
9964 if ((op & 1) && shift == 0)
9965 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9966 else
9967 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9968 } else {
9969 /* Signed. */
9970 if ((op & 1) && shift == 0)
9971 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9972 else
9973 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9975 tcg_temp_free_i32(tmp2);
9976 break;
9978 store_reg(s, rd, tmp);
9979 } else {
9980 imm = ((insn & 0x04000000) >> 15)
9981 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9982 if (insn & (1 << 22)) {
9983 /* 16-bit immediate. */
9984 imm |= (insn >> 4) & 0xf000;
9985 if (insn & (1 << 23)) {
9986 /* movt */
9987 tmp = load_reg(s, rd);
9988 tcg_gen_ext16u_i32(tmp, tmp);
9989 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9990 } else {
9991 /* movw */
9992 tmp = tcg_temp_new_i32();
9993 tcg_gen_movi_i32(tmp, imm);
9995 } else {
9996 /* Add/sub 12-bit immediate. */
9997 if (rn == 15) {
9998 offset = s->pc & ~(uint32_t)3;
9999 if (insn & (1 << 23))
10000 offset -= imm;
10001 else
10002 offset += imm;
10003 tmp = tcg_temp_new_i32();
10004 tcg_gen_movi_i32(tmp, offset);
10005 } else {
10006 tmp = load_reg(s, rn);
10007 if (insn & (1 << 23))
10008 tcg_gen_subi_i32(tmp, tmp, imm);
10009 else
10010 tcg_gen_addi_i32(tmp, tmp, imm);
10013 store_reg(s, rd, tmp);
10015 } else {
10016 int shifter_out = 0;
10017 /* modified 12-bit immediate. */
10018 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10019 imm = (insn & 0xff);
10020 switch (shift) {
10021 case 0: /* XY */
10022 /* Nothing to do. */
10023 break;
10024 case 1: /* 00XY00XY */
10025 imm |= imm << 16;
10026 break;
10027 case 2: /* XY00XY00 */
10028 imm |= imm << 16;
10029 imm <<= 8;
10030 break;
10031 case 3: /* XYXYXYXY */
10032 imm |= imm << 16;
10033 imm |= imm << 8;
10034 break;
10035 default: /* Rotated constant. */
10036 shift = (shift << 1) | (imm >> 7);
10037 imm |= 0x80;
10038 imm = imm << (32 - shift);
10039 shifter_out = 1;
10040 break;
10042 tmp2 = tcg_temp_new_i32();
10043 tcg_gen_movi_i32(tmp2, imm);
10044 rn = (insn >> 16) & 0xf;
10045 if (rn == 15) {
10046 tmp = tcg_temp_new_i32();
10047 tcg_gen_movi_i32(tmp, 0);
10048 } else {
10049 tmp = load_reg(s, rn);
10051 op = (insn >> 21) & 0xf;
10052 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10053 shifter_out, tmp, tmp2))
10054 goto illegal_op;
10055 tcg_temp_free_i32(tmp2);
10056 rd = (insn >> 8) & 0xf;
10057 if (rd != 15) {
10058 store_reg(s, rd, tmp);
10059 } else {
10060 tcg_temp_free_i32(tmp);
10064 break;
10065 case 12: /* Load/store single data item. */
10067 int postinc = 0;
10068 int writeback = 0;
10069 int memidx;
10070 if ((insn & 0x01100000) == 0x01000000) {
10071 if (disas_neon_ls_insn(env, s, insn))
10072 goto illegal_op;
10073 break;
10075 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10076 if (rs == 15) {
10077 if (!(insn & (1 << 20))) {
10078 goto illegal_op;
10080 if (op != 2) {
10081 /* Byte or halfword load space with dest == r15 : memory hints.
10082 * Catch them early so we don't emit pointless addressing code.
10083 * This space is a mix of:
10084 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10085 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10086 * cores)
10087 * unallocated hints, which must be treated as NOPs
10088 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10089 * which is easiest for the decoding logic
10090 * Some space which must UNDEF
10092 int op1 = (insn >> 23) & 3;
10093 int op2 = (insn >> 6) & 0x3f;
10094 if (op & 2) {
10095 goto illegal_op;
10097 if (rn == 15) {
10098 /* UNPREDICTABLE, unallocated hint or
10099 * PLD/PLDW/PLI (literal)
10101 return 0;
10103 if (op1 & 1) {
10104 return 0; /* PLD/PLDW/PLI or unallocated hint */
10106 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10107 return 0; /* PLD/PLDW/PLI or unallocated hint */
10109 /* UNDEF space, or an UNPREDICTABLE */
10110 return 1;
10113 memidx = get_mem_index(s);
10114 if (rn == 15) {
10115 addr = tcg_temp_new_i32();
10116 /* PC relative. */
10117 /* s->pc has already been incremented by 4. */
10118 imm = s->pc & 0xfffffffc;
10119 if (insn & (1 << 23))
10120 imm += insn & 0xfff;
10121 else
10122 imm -= insn & 0xfff;
10123 tcg_gen_movi_i32(addr, imm);
10124 } else {
10125 addr = load_reg(s, rn);
10126 if (insn & (1 << 23)) {
10127 /* Positive offset. */
10128 imm = insn & 0xfff;
10129 tcg_gen_addi_i32(addr, addr, imm);
10130 } else {
10131 imm = insn & 0xff;
10132 switch ((insn >> 8) & 0xf) {
10133 case 0x0: /* Shifted Register. */
10134 shift = (insn >> 4) & 0xf;
10135 if (shift > 3) {
10136 tcg_temp_free_i32(addr);
10137 goto illegal_op;
10139 tmp = load_reg(s, rm);
10140 if (shift)
10141 tcg_gen_shli_i32(tmp, tmp, shift);
10142 tcg_gen_add_i32(addr, addr, tmp);
10143 tcg_temp_free_i32(tmp);
10144 break;
10145 case 0xc: /* Negative offset. */
10146 tcg_gen_addi_i32(addr, addr, -imm);
10147 break;
10148 case 0xe: /* User privilege. */
10149 tcg_gen_addi_i32(addr, addr, imm);
10150 memidx = MMU_USER_IDX;
10151 break;
10152 case 0x9: /* Post-decrement. */
10153 imm = -imm;
10154 /* Fall through. */
10155 case 0xb: /* Post-increment. */
10156 postinc = 1;
10157 writeback = 1;
10158 break;
10159 case 0xd: /* Pre-decrement. */
10160 imm = -imm;
10161 /* Fall through. */
10162 case 0xf: /* Pre-increment. */
10163 tcg_gen_addi_i32(addr, addr, imm);
10164 writeback = 1;
10165 break;
10166 default:
10167 tcg_temp_free_i32(addr);
10168 goto illegal_op;
10172 if (insn & (1 << 20)) {
10173 /* Load. */
10174 tmp = tcg_temp_new_i32();
10175 switch (op) {
10176 case 0:
10177 gen_aa32_ld8u(s, tmp, addr, memidx);
10178 break;
10179 case 4:
10180 gen_aa32_ld8s(s, tmp, addr, memidx);
10181 break;
10182 case 1:
10183 gen_aa32_ld16u(s, tmp, addr, memidx);
10184 break;
10185 case 5:
10186 gen_aa32_ld16s(s, tmp, addr, memidx);
10187 break;
10188 case 2:
10189 gen_aa32_ld32u(s, tmp, addr, memidx);
10190 break;
10191 default:
10192 tcg_temp_free_i32(tmp);
10193 tcg_temp_free_i32(addr);
10194 goto illegal_op;
10196 if (rs == 15) {
10197 gen_bx(s, tmp);
10198 } else {
10199 store_reg(s, rs, tmp);
10201 } else {
10202 /* Store. */
10203 tmp = load_reg(s, rs);
10204 switch (op) {
10205 case 0:
10206 gen_aa32_st8(s, tmp, addr, memidx);
10207 break;
10208 case 1:
10209 gen_aa32_st16(s, tmp, addr, memidx);
10210 break;
10211 case 2:
10212 gen_aa32_st32(s, tmp, addr, memidx);
10213 break;
10214 default:
10215 tcg_temp_free_i32(tmp);
10216 tcg_temp_free_i32(addr);
10217 goto illegal_op;
10219 tcg_temp_free_i32(tmp);
10221 if (postinc)
10222 tcg_gen_addi_i32(addr, addr, imm);
10223 if (writeback) {
10224 store_reg(s, rn, addr);
10225 } else {
10226 tcg_temp_free_i32(addr);
10229 break;
10230 default:
10231 goto illegal_op;
10233 return 0;
10234 illegal_op:
10235 return 1;
10238 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10240 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10241 int32_t offset;
10242 int i;
10243 TCGv_i32 tmp;
10244 TCGv_i32 tmp2;
10245 TCGv_i32 addr;
10247 if (s->condexec_mask) {
10248 cond = s->condexec_cond;
10249 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10250 s->condlabel = gen_new_label();
10251 arm_gen_test_cc(cond ^ 1, s->condlabel);
10252 s->condjmp = 1;
10256 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
10257 s->pc += 2;
10259 switch (insn >> 12) {
10260 case 0: case 1:
10262 rd = insn & 7;
10263 op = (insn >> 11) & 3;
10264 if (op == 3) {
10265 /* add/subtract */
10266 rn = (insn >> 3) & 7;
10267 tmp = load_reg(s, rn);
10268 if (insn & (1 << 10)) {
10269 /* immediate */
10270 tmp2 = tcg_temp_new_i32();
10271 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10272 } else {
10273 /* reg */
10274 rm = (insn >> 6) & 7;
10275 tmp2 = load_reg(s, rm);
10277 if (insn & (1 << 9)) {
10278 if (s->condexec_mask)
10279 tcg_gen_sub_i32(tmp, tmp, tmp2);
10280 else
10281 gen_sub_CC(tmp, tmp, tmp2);
10282 } else {
10283 if (s->condexec_mask)
10284 tcg_gen_add_i32(tmp, tmp, tmp2);
10285 else
10286 gen_add_CC(tmp, tmp, tmp2);
10288 tcg_temp_free_i32(tmp2);
10289 store_reg(s, rd, tmp);
10290 } else {
10291 /* shift immediate */
10292 rm = (insn >> 3) & 7;
10293 shift = (insn >> 6) & 0x1f;
10294 tmp = load_reg(s, rm);
10295 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10296 if (!s->condexec_mask)
10297 gen_logic_CC(tmp);
10298 store_reg(s, rd, tmp);
10300 break;
10301 case 2: case 3:
10302 /* arithmetic large immediate */
10303 op = (insn >> 11) & 3;
10304 rd = (insn >> 8) & 0x7;
10305 if (op == 0) { /* mov */
10306 tmp = tcg_temp_new_i32();
10307 tcg_gen_movi_i32(tmp, insn & 0xff);
10308 if (!s->condexec_mask)
10309 gen_logic_CC(tmp);
10310 store_reg(s, rd, tmp);
10311 } else {
10312 tmp = load_reg(s, rd);
10313 tmp2 = tcg_temp_new_i32();
10314 tcg_gen_movi_i32(tmp2, insn & 0xff);
10315 switch (op) {
10316 case 1: /* cmp */
10317 gen_sub_CC(tmp, tmp, tmp2);
10318 tcg_temp_free_i32(tmp);
10319 tcg_temp_free_i32(tmp2);
10320 break;
10321 case 2: /* add */
10322 if (s->condexec_mask)
10323 tcg_gen_add_i32(tmp, tmp, tmp2);
10324 else
10325 gen_add_CC(tmp, tmp, tmp2);
10326 tcg_temp_free_i32(tmp2);
10327 store_reg(s, rd, tmp);
10328 break;
10329 case 3: /* sub */
10330 if (s->condexec_mask)
10331 tcg_gen_sub_i32(tmp, tmp, tmp2);
10332 else
10333 gen_sub_CC(tmp, tmp, tmp2);
10334 tcg_temp_free_i32(tmp2);
10335 store_reg(s, rd, tmp);
10336 break;
10339 break;
10340 case 4:
10341 if (insn & (1 << 11)) {
10342 rd = (insn >> 8) & 7;
10343 /* load pc-relative. Bit 1 of PC is ignored. */
10344 val = s->pc + 2 + ((insn & 0xff) * 4);
10345 val &= ~(uint32_t)2;
10346 addr = tcg_temp_new_i32();
10347 tcg_gen_movi_i32(addr, val);
10348 tmp = tcg_temp_new_i32();
10349 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10350 tcg_temp_free_i32(addr);
10351 store_reg(s, rd, tmp);
10352 break;
10354 if (insn & (1 << 10)) {
10355 /* data processing extended or blx */
10356 rd = (insn & 7) | ((insn >> 4) & 8);
10357 rm = (insn >> 3) & 0xf;
10358 op = (insn >> 8) & 3;
10359 switch (op) {
10360 case 0: /* add */
10361 tmp = load_reg(s, rd);
10362 tmp2 = load_reg(s, rm);
10363 tcg_gen_add_i32(tmp, tmp, tmp2);
10364 tcg_temp_free_i32(tmp2);
10365 store_reg(s, rd, tmp);
10366 break;
10367 case 1: /* cmp */
10368 tmp = load_reg(s, rd);
10369 tmp2 = load_reg(s, rm);
10370 gen_sub_CC(tmp, tmp, tmp2);
10371 tcg_temp_free_i32(tmp2);
10372 tcg_temp_free_i32(tmp);
10373 break;
10374 case 2: /* mov/cpy */
10375 tmp = load_reg(s, rm);
10376 store_reg(s, rd, tmp);
10377 break;
10378 case 3:/* branch [and link] exchange thumb register */
10379 tmp = load_reg(s, rm);
10380 if (insn & (1 << 7)) {
10381 ARCH(5);
10382 val = (uint32_t)s->pc | 1;
10383 tmp2 = tcg_temp_new_i32();
10384 tcg_gen_movi_i32(tmp2, val);
10385 store_reg(s, 14, tmp2);
10387 /* already thumb, no need to check */
10388 gen_bx(s, tmp);
10389 break;
10391 break;
10394 /* data processing register */
10395 rd = insn & 7;
10396 rm = (insn >> 3) & 7;
10397 op = (insn >> 6) & 0xf;
10398 if (op == 2 || op == 3 || op == 4 || op == 7) {
10399 /* the shift/rotate ops want the operands backwards */
10400 val = rm;
10401 rm = rd;
10402 rd = val;
10403 val = 1;
10404 } else {
10405 val = 0;
10408 if (op == 9) { /* neg */
10409 tmp = tcg_temp_new_i32();
10410 tcg_gen_movi_i32(tmp, 0);
10411 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10412 tmp = load_reg(s, rd);
10413 } else {
10414 TCGV_UNUSED_I32(tmp);
10417 tmp2 = load_reg(s, rm);
10418 switch (op) {
10419 case 0x0: /* and */
10420 tcg_gen_and_i32(tmp, tmp, tmp2);
10421 if (!s->condexec_mask)
10422 gen_logic_CC(tmp);
10423 break;
10424 case 0x1: /* eor */
10425 tcg_gen_xor_i32(tmp, tmp, tmp2);
10426 if (!s->condexec_mask)
10427 gen_logic_CC(tmp);
10428 break;
10429 case 0x2: /* lsl */
10430 if (s->condexec_mask) {
10431 gen_shl(tmp2, tmp2, tmp);
10432 } else {
10433 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10434 gen_logic_CC(tmp2);
10436 break;
10437 case 0x3: /* lsr */
10438 if (s->condexec_mask) {
10439 gen_shr(tmp2, tmp2, tmp);
10440 } else {
10441 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10442 gen_logic_CC(tmp2);
10444 break;
10445 case 0x4: /* asr */
10446 if (s->condexec_mask) {
10447 gen_sar(tmp2, tmp2, tmp);
10448 } else {
10449 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10450 gen_logic_CC(tmp2);
10452 break;
10453 case 0x5: /* adc */
10454 if (s->condexec_mask) {
10455 gen_adc(tmp, tmp2);
10456 } else {
10457 gen_adc_CC(tmp, tmp, tmp2);
10459 break;
10460 case 0x6: /* sbc */
10461 if (s->condexec_mask) {
10462 gen_sub_carry(tmp, tmp, tmp2);
10463 } else {
10464 gen_sbc_CC(tmp, tmp, tmp2);
10466 break;
10467 case 0x7: /* ror */
10468 if (s->condexec_mask) {
10469 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10470 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10471 } else {
10472 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10473 gen_logic_CC(tmp2);
10475 break;
10476 case 0x8: /* tst */
10477 tcg_gen_and_i32(tmp, tmp, tmp2);
10478 gen_logic_CC(tmp);
10479 rd = 16;
10480 break;
10481 case 0x9: /* neg */
10482 if (s->condexec_mask)
10483 tcg_gen_neg_i32(tmp, tmp2);
10484 else
10485 gen_sub_CC(tmp, tmp, tmp2);
10486 break;
10487 case 0xa: /* cmp */
10488 gen_sub_CC(tmp, tmp, tmp2);
10489 rd = 16;
10490 break;
10491 case 0xb: /* cmn */
10492 gen_add_CC(tmp, tmp, tmp2);
10493 rd = 16;
10494 break;
10495 case 0xc: /* orr */
10496 tcg_gen_or_i32(tmp, tmp, tmp2);
10497 if (!s->condexec_mask)
10498 gen_logic_CC(tmp);
10499 break;
10500 case 0xd: /* mul */
10501 tcg_gen_mul_i32(tmp, tmp, tmp2);
10502 if (!s->condexec_mask)
10503 gen_logic_CC(tmp);
10504 break;
10505 case 0xe: /* bic */
10506 tcg_gen_andc_i32(tmp, tmp, tmp2);
10507 if (!s->condexec_mask)
10508 gen_logic_CC(tmp);
10509 break;
10510 case 0xf: /* mvn */
10511 tcg_gen_not_i32(tmp2, tmp2);
10512 if (!s->condexec_mask)
10513 gen_logic_CC(tmp2);
10514 val = 1;
10515 rm = rd;
10516 break;
10518 if (rd != 16) {
10519 if (val) {
10520 store_reg(s, rm, tmp2);
10521 if (op != 0xf)
10522 tcg_temp_free_i32(tmp);
10523 } else {
10524 store_reg(s, rd, tmp);
10525 tcg_temp_free_i32(tmp2);
10527 } else {
10528 tcg_temp_free_i32(tmp);
10529 tcg_temp_free_i32(tmp2);
10531 break;
10533 case 5:
10534 /* load/store register offset. */
10535 rd = insn & 7;
10536 rn = (insn >> 3) & 7;
10537 rm = (insn >> 6) & 7;
10538 op = (insn >> 9) & 7;
10539 addr = load_reg(s, rn);
10540 tmp = load_reg(s, rm);
10541 tcg_gen_add_i32(addr, addr, tmp);
10542 tcg_temp_free_i32(tmp);
10544 if (op < 3) { /* store */
10545 tmp = load_reg(s, rd);
10546 } else {
10547 tmp = tcg_temp_new_i32();
10550 switch (op) {
10551 case 0: /* str */
10552 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10553 break;
10554 case 1: /* strh */
10555 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10556 break;
10557 case 2: /* strb */
10558 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10559 break;
10560 case 3: /* ldrsb */
10561 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
10562 break;
10563 case 4: /* ldr */
10564 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10565 break;
10566 case 5: /* ldrh */
10567 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10568 break;
10569 case 6: /* ldrb */
10570 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10571 break;
10572 case 7: /* ldrsh */
10573 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
10574 break;
10576 if (op >= 3) { /* load */
10577 store_reg(s, rd, tmp);
10578 } else {
10579 tcg_temp_free_i32(tmp);
10581 tcg_temp_free_i32(addr);
10582 break;
10584 case 6:
10585 /* load/store word immediate offset */
10586 rd = insn & 7;
10587 rn = (insn >> 3) & 7;
10588 addr = load_reg(s, rn);
10589 val = (insn >> 4) & 0x7c;
10590 tcg_gen_addi_i32(addr, addr, val);
10592 if (insn & (1 << 11)) {
10593 /* load */
10594 tmp = tcg_temp_new_i32();
10595 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10596 store_reg(s, rd, tmp);
10597 } else {
10598 /* store */
10599 tmp = load_reg(s, rd);
10600 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10601 tcg_temp_free_i32(tmp);
10603 tcg_temp_free_i32(addr);
10604 break;
10606 case 7:
10607 /* load/store byte immediate offset */
10608 rd = insn & 7;
10609 rn = (insn >> 3) & 7;
10610 addr = load_reg(s, rn);
10611 val = (insn >> 6) & 0x1f;
10612 tcg_gen_addi_i32(addr, addr, val);
10614 if (insn & (1 << 11)) {
10615 /* load */
10616 tmp = tcg_temp_new_i32();
10617 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10618 store_reg(s, rd, tmp);
10619 } else {
10620 /* store */
10621 tmp = load_reg(s, rd);
10622 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
10623 tcg_temp_free_i32(tmp);
10625 tcg_temp_free_i32(addr);
10626 break;
10628 case 8:
10629 /* load/store halfword immediate offset */
10630 rd = insn & 7;
10631 rn = (insn >> 3) & 7;
10632 addr = load_reg(s, rn);
10633 val = (insn >> 5) & 0x3e;
10634 tcg_gen_addi_i32(addr, addr, val);
10636 if (insn & (1 << 11)) {
10637 /* load */
10638 tmp = tcg_temp_new_i32();
10639 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10640 store_reg(s, rd, tmp);
10641 } else {
10642 /* store */
10643 tmp = load_reg(s, rd);
10644 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
10645 tcg_temp_free_i32(tmp);
10647 tcg_temp_free_i32(addr);
10648 break;
10650 case 9:
10651 /* load/store from stack */
10652 rd = (insn >> 8) & 7;
10653 addr = load_reg(s, 13);
10654 val = (insn & 0xff) * 4;
10655 tcg_gen_addi_i32(addr, addr, val);
10657 if (insn & (1 << 11)) {
10658 /* load */
10659 tmp = tcg_temp_new_i32();
10660 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10661 store_reg(s, rd, tmp);
10662 } else {
10663 /* store */
10664 tmp = load_reg(s, rd);
10665 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10666 tcg_temp_free_i32(tmp);
10668 tcg_temp_free_i32(addr);
10669 break;
10671 case 10:
10672 /* add to high reg */
10673 rd = (insn >> 8) & 7;
10674 if (insn & (1 << 11)) {
10675 /* SP */
10676 tmp = load_reg(s, 13);
10677 } else {
10678 /* PC. bit 1 is ignored. */
10679 tmp = tcg_temp_new_i32();
10680 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10682 val = (insn & 0xff) * 4;
10683 tcg_gen_addi_i32(tmp, tmp, val);
10684 store_reg(s, rd, tmp);
10685 break;
10687 case 11:
10688 /* misc */
10689 op = (insn >> 8) & 0xf;
10690 switch (op) {
10691 case 0:
10692 /* adjust stack pointer */
10693 tmp = load_reg(s, 13);
10694 val = (insn & 0x7f) * 4;
10695 if (insn & (1 << 7))
10696 val = -(int32_t)val;
10697 tcg_gen_addi_i32(tmp, tmp, val);
10698 store_reg(s, 13, tmp);
10699 break;
10701 case 2: /* sign/zero extend. */
10702 ARCH(6);
10703 rd = insn & 7;
10704 rm = (insn >> 3) & 7;
10705 tmp = load_reg(s, rm);
10706 switch ((insn >> 6) & 3) {
10707 case 0: gen_sxth(tmp); break;
10708 case 1: gen_sxtb(tmp); break;
10709 case 2: gen_uxth(tmp); break;
10710 case 3: gen_uxtb(tmp); break;
10712 store_reg(s, rd, tmp);
10713 break;
10714 case 4: case 5: case 0xc: case 0xd:
10715 /* push/pop */
10716 addr = load_reg(s, 13);
10717 if (insn & (1 << 8))
10718 offset = 4;
10719 else
10720 offset = 0;
10721 for (i = 0; i < 8; i++) {
10722 if (insn & (1 << i))
10723 offset += 4;
10725 if ((insn & (1 << 11)) == 0) {
10726 tcg_gen_addi_i32(addr, addr, -offset);
10728 for (i = 0; i < 8; i++) {
10729 if (insn & (1 << i)) {
10730 if (insn & (1 << 11)) {
10731 /* pop */
10732 tmp = tcg_temp_new_i32();
10733 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10734 store_reg(s, i, tmp);
10735 } else {
10736 /* push */
10737 tmp = load_reg(s, i);
10738 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10739 tcg_temp_free_i32(tmp);
10741 /* advance to the next address. */
10742 tcg_gen_addi_i32(addr, addr, 4);
10745 TCGV_UNUSED_I32(tmp);
10746 if (insn & (1 << 8)) {
10747 if (insn & (1 << 11)) {
10748 /* pop pc */
10749 tmp = tcg_temp_new_i32();
10750 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10751 /* don't set the pc until the rest of the instruction
10752 has completed */
10753 } else {
10754 /* push lr */
10755 tmp = load_reg(s, 14);
10756 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10757 tcg_temp_free_i32(tmp);
10759 tcg_gen_addi_i32(addr, addr, 4);
10761 if ((insn & (1 << 11)) == 0) {
10762 tcg_gen_addi_i32(addr, addr, -offset);
10764 /* write back the new stack pointer */
10765 store_reg(s, 13, addr);
10766 /* set the new PC value */
10767 if ((insn & 0x0900) == 0x0900) {
10768 store_reg_from_load(env, s, 15, tmp);
10770 break;
10772 case 1: case 3: case 9: case 11: /* czb */
10773 rm = insn & 7;
10774 tmp = load_reg(s, rm);
10775 s->condlabel = gen_new_label();
10776 s->condjmp = 1;
10777 if (insn & (1 << 11))
10778 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10779 else
10780 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10781 tcg_temp_free_i32(tmp);
10782 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10783 val = (uint32_t)s->pc + 2;
10784 val += offset;
10785 gen_jmp(s, val);
10786 break;
10788 case 15: /* IT, nop-hint. */
10789 if ((insn & 0xf) == 0) {
10790 gen_nop_hint(s, (insn >> 4) & 0xf);
10791 break;
10793 /* If Then. */
10794 s->condexec_cond = (insn >> 4) & 0xe;
10795 s->condexec_mask = insn & 0x1f;
10796 /* No actual code generated for this insn, just setup state. */
10797 break;
10799 case 0xe: /* bkpt */
10801 int imm8 = extract32(insn, 0, 8);
10802 ARCH(5);
10803 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true));
10804 break;
10807 case 0xa: /* rev */
10808 ARCH(6);
10809 rn = (insn >> 3) & 0x7;
10810 rd = insn & 0x7;
10811 tmp = load_reg(s, rn);
10812 switch ((insn >> 6) & 3) {
10813 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10814 case 1: gen_rev16(tmp); break;
10815 case 3: gen_revsh(tmp); break;
10816 default: goto illegal_op;
10818 store_reg(s, rd, tmp);
10819 break;
10821 case 6:
10822 switch ((insn >> 5) & 7) {
10823 case 2:
10824 /* setend */
10825 ARCH(6);
10826 if (((insn >> 3) & 1) != s->cpsr_e) {
10827 /* Dynamic endianness switching not implemented. */
10828 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10829 goto illegal_op;
10831 break;
10832 case 3:
10833 /* cps */
10834 ARCH(6);
10835 if (IS_USER(s)) {
10836 break;
10838 if (IS_M(env)) {
10839 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10840 /* FAULTMASK */
10841 if (insn & 1) {
10842 addr = tcg_const_i32(19);
10843 gen_helper_v7m_msr(cpu_env, addr, tmp);
10844 tcg_temp_free_i32(addr);
10846 /* PRIMASK */
10847 if (insn & 2) {
10848 addr = tcg_const_i32(16);
10849 gen_helper_v7m_msr(cpu_env, addr, tmp);
10850 tcg_temp_free_i32(addr);
10852 tcg_temp_free_i32(tmp);
10853 gen_lookup_tb(s);
10854 } else {
10855 if (insn & (1 << 4)) {
10856 shift = CPSR_A | CPSR_I | CPSR_F;
10857 } else {
10858 shift = 0;
10860 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10862 break;
10863 default:
10864 goto undef;
10866 break;
10868 default:
10869 goto undef;
10871 break;
10873 case 12:
10875 /* load/store multiple */
10876 TCGv_i32 loaded_var;
10877 TCGV_UNUSED_I32(loaded_var);
10878 rn = (insn >> 8) & 0x7;
10879 addr = load_reg(s, rn);
10880 for (i = 0; i < 8; i++) {
10881 if (insn & (1 << i)) {
10882 if (insn & (1 << 11)) {
10883 /* load */
10884 tmp = tcg_temp_new_i32();
10885 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10886 if (i == rn) {
10887 loaded_var = tmp;
10888 } else {
10889 store_reg(s, i, tmp);
10891 } else {
10892 /* store */
10893 tmp = load_reg(s, i);
10894 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10895 tcg_temp_free_i32(tmp);
10897 /* advance to the next address */
10898 tcg_gen_addi_i32(addr, addr, 4);
10901 if ((insn & (1 << rn)) == 0) {
10902 /* base reg not in list: base register writeback */
10903 store_reg(s, rn, addr);
10904 } else {
10905 /* base reg in list: if load, complete it now */
10906 if (insn & (1 << 11)) {
10907 store_reg(s, rn, loaded_var);
10909 tcg_temp_free_i32(addr);
10911 break;
10913 case 13:
10914 /* conditional branch or swi */
10915 cond = (insn >> 8) & 0xf;
10916 if (cond == 0xe)
10917 goto undef;
10919 if (cond == 0xf) {
10920 /* swi */
10921 gen_set_pc_im(s, s->pc);
10922 s->svc_imm = extract32(insn, 0, 8);
10923 s->is_jmp = DISAS_SWI;
10924 break;
10926 /* generate a conditional jump to next instruction */
10927 s->condlabel = gen_new_label();
10928 arm_gen_test_cc(cond ^ 1, s->condlabel);
10929 s->condjmp = 1;
10931 /* jump to the offset */
10932 val = (uint32_t)s->pc + 2;
10933 offset = ((int32_t)insn << 24) >> 24;
10934 val += offset << 1;
10935 gen_jmp(s, val);
10936 break;
10938 case 14:
10939 if (insn & (1 << 11)) {
10940 if (disas_thumb2_insn(env, s, insn))
10941 goto undef32;
10942 break;
10944 /* unconditional branch */
10945 val = (uint32_t)s->pc;
10946 offset = ((int32_t)insn << 21) >> 21;
10947 val += (offset << 1) + 2;
10948 gen_jmp(s, val);
10949 break;
10951 case 15:
10952 if (disas_thumb2_insn(env, s, insn))
10953 goto undef32;
10954 break;
10956 return;
10957 undef32:
10958 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
10959 return;
10960 illegal_op:
10961 undef:
10962 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
10965 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10966 basic block 'tb'. If search_pc is TRUE, also generate PC
10967 information for each intermediate instruction. */
10968 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10969 TranslationBlock *tb,
10970 bool search_pc)
10972 CPUState *cs = CPU(cpu);
10973 CPUARMState *env = &cpu->env;
10974 DisasContext dc1, *dc = &dc1;
10975 CPUBreakpoint *bp;
10976 uint16_t *gen_opc_end;
10977 int j, lj;
10978 target_ulong pc_start;
10979 target_ulong next_page_start;
10980 int num_insns;
10981 int max_insns;
10983 /* generate intermediate code */
10985 /* The A64 decoder has its own top level loop, because it doesn't need
10986 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10988 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10989 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10990 return;
10993 pc_start = tb->pc;
10995 dc->tb = tb;
10997 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10999 dc->is_jmp = DISAS_NEXT;
11000 dc->pc = pc_start;
11001 dc->singlestep_enabled = cs->singlestep_enabled;
11002 dc->condjmp = 0;
11004 dc->aarch64 = 0;
11005 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11006 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11007 dc->cpsr_e = ARM_TBFLAG_CPSR_E(tb->flags);
11008 dc->mo_endianness = arm_tbflag_is_data_be(tb->flags) ? MO_BE : MO_LE;
11009 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11010 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11011 #if !defined(CONFIG_USER_ONLY)
11012 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
11013 #endif
11014 dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
11015 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11016 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11017 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11018 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11019 dc->cp_regs = cpu->cp_regs;
11020 dc->current_el = arm_current_el(env);
11021 dc->features = env->features;
11023 /* Single step state. The code-generation logic here is:
11024 * SS_ACTIVE == 0:
11025 * generate code with no special handling for single-stepping (except
11026 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11027 * this happens anyway because those changes are all system register or
11028 * PSTATE writes).
11029 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11030 * emit code for one insn
11031 * emit code to clear PSTATE.SS
11032 * emit code to generate software step exception for completed step
11033 * end TB (as usual for having generated an exception)
11034 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11035 * emit code to generate a software step exception
11036 * end the TB
11038 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11039 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11040 dc->is_ldex = false;
11041 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11043 cpu_F0s = tcg_temp_new_i32();
11044 cpu_F1s = tcg_temp_new_i32();
11045 cpu_F0d = tcg_temp_new_i64();
11046 cpu_F1d = tcg_temp_new_i64();
11047 cpu_V0 = cpu_F0d;
11048 cpu_V1 = cpu_F1d;
11049 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11050 cpu_M0 = tcg_temp_new_i64();
11051 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11052 lj = -1;
11053 num_insns = 0;
11054 max_insns = tb->cflags & CF_COUNT_MASK;
11055 if (max_insns == 0)
11056 max_insns = CF_COUNT_MASK;
11058 gen_tb_start();
11060 tcg_clear_temp_count();
11062 /* A note on handling of the condexec (IT) bits:
11064 * We want to avoid the overhead of having to write the updated condexec
11065 * bits back to the CPUARMState for every instruction in an IT block. So:
11066 * (1) if the condexec bits are not already zero then we write
11067 * zero back into the CPUARMState now. This avoids complications trying
11068 * to do it at the end of the block. (For example if we don't do this
11069 * it's hard to identify whether we can safely skip writing condexec
11070 * at the end of the TB, which we definitely want to do for the case
11071 * where a TB doesn't do anything with the IT state at all.)
11072 * (2) if we are going to leave the TB then we call gen_set_condexec()
11073 * which will write the correct value into CPUARMState if zero is wrong.
11074 * This is done both for leaving the TB at the end, and for leaving
11075 * it because of an exception we know will happen, which is done in
11076 * gen_exception_insn(). The latter is necessary because we need to
11077 * leave the TB with the PC/IT state just prior to execution of the
11078 * instruction which caused the exception.
11079 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11080 * then the CPUARMState will be wrong and we need to reset it.
11081 * This is handled in the same way as restoration of the
11082 * PC in these situations: we will be called again with search_pc=1
11083 * and generate a mapping of the condexec bits for each PC in
11084 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
11085 * this to restore the condexec bits.
11087 * Note that there are no instructions which can read the condexec
11088 * bits, and none which can write non-static values to them, so
11089 * we don't need to care about whether CPUARMState is correct in the
11090 * middle of a TB.
11093 /* Reset the conditional execution bits immediately. This avoids
11094 complications trying to do it at the end of the block. */
11095 if (dc->condexec_mask || dc->condexec_cond)
11097 TCGv_i32 tmp = tcg_temp_new_i32();
11098 tcg_gen_movi_i32(tmp, 0);
11099 store_cpu_field(tmp, condexec_bits);
11101 do {
11102 #ifdef CONFIG_USER_ONLY
11103 /* Intercept jump to the magic kernel page. */
11104 if (dc->pc >= 0xffff0000) {
11105 /* We always get here via a jump, so know we are not in a
11106 conditional execution block. */
11107 gen_exception_internal(EXCP_KERNEL_TRAP);
11108 dc->is_jmp = DISAS_UPDATE;
11109 break;
11111 #else
11112 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
11113 /* We always get here via a jump, so know we are not in a
11114 conditional execution block. */
11115 gen_exception_internal(EXCP_EXCEPTION_EXIT);
11116 dc->is_jmp = DISAS_UPDATE;
11117 break;
11119 #endif
11121 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11122 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11123 if (bp->pc == dc->pc) {
11124 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11125 /* Advance PC so that clearing the breakpoint will
11126 invalidate this TB. */
11127 dc->pc += 2;
11128 goto done_generating;
11132 if (search_pc) {
11133 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
11134 if (lj < j) {
11135 lj++;
11136 while (lj < j)
11137 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11139 tcg_ctx.gen_opc_pc[lj] = dc->pc;
11140 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
11141 tcg_ctx.gen_opc_instr_start[lj] = 1;
11142 tcg_ctx.gen_opc_icount[lj] = num_insns;
11145 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
11146 gen_io_start();
11148 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
11149 tcg_gen_debug_insn_start(dc->pc);
11152 if (dc->ss_active && !dc->pstate_ss) {
11153 /* Singlestep state is Active-pending.
11154 * If we're in this state at the start of a TB then either
11155 * a) we just took an exception to an EL which is being debugged
11156 * and this is the first insn in the exception handler
11157 * b) debug exceptions were masked and we just unmasked them
11158 * without changing EL (eg by clearing PSTATE.D)
11159 * In either case we're going to take a swstep exception in the
11160 * "did not step an insn" case, and so the syndrome ISV and EX
11161 * bits should be zero.
11163 assert(num_insns == 0);
11164 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0));
11165 goto done_generating;
11168 if (dc->thumb) {
11169 disas_thumb_insn(env, dc);
11170 if (dc->condexec_mask) {
11171 dc->condexec_cond = (dc->condexec_cond & 0xe)
11172 | ((dc->condexec_mask >> 4) & 1);
11173 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11174 if (dc->condexec_mask == 0) {
11175 dc->condexec_cond = 0;
11178 } else {
11179 disas_arm_insn(env, dc);
11182 if (dc->condjmp && !dc->is_jmp) {
11183 gen_set_label(dc->condlabel);
11184 dc->condjmp = 0;
11187 if (tcg_check_temp_count()) {
11188 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11189 dc->pc);
11192 /* Translation stops when a conditional branch is encountered.
11193 * Otherwise the subsequent code could get translated several times.
11194 * Also stop translation when a page boundary is reached. This
11195 * ensures prefetch aborts occur at the right place. */
11196 num_insns ++;
11197 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
11198 !cs->singlestep_enabled &&
11199 !singlestep &&
11200 !dc->ss_active &&
11201 dc->pc < next_page_start &&
11202 num_insns < max_insns);
11204 if (tb->cflags & CF_LAST_IO) {
11205 if (dc->condjmp) {
11206 /* FIXME: This can theoretically happen with self-modifying
11207 code. */
11208 cpu_abort(cs, "IO on conditional branch instruction");
11210 gen_io_end();
11213 /* At this stage dc->condjmp will only be set when the skipped
11214 instruction was a conditional branch or trap, and the PC has
11215 already been written. */
11216 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11217 /* Make sure the pc is updated, and raise a debug exception. */
11218 if (dc->condjmp) {
11219 gen_set_condexec(dc);
11220 if (dc->is_jmp == DISAS_SWI) {
11221 gen_ss_advance(dc);
11222 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11223 } else if (dc->is_jmp == DISAS_HVC) {
11224 gen_ss_advance(dc);
11225 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11226 } else if (dc->is_jmp == DISAS_SMC) {
11227 gen_ss_advance(dc);
11228 gen_exception(EXCP_SMC, syn_aa32_smc());
11229 } else if (dc->ss_active) {
11230 gen_step_complete_exception(dc);
11231 } else {
11232 gen_exception_internal(EXCP_DEBUG);
11234 gen_set_label(dc->condlabel);
11236 if (dc->condjmp || !dc->is_jmp) {
11237 gen_set_pc_im(dc, dc->pc);
11238 dc->condjmp = 0;
11240 gen_set_condexec(dc);
11241 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
11242 gen_ss_advance(dc);
11243 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11244 } else if (dc->is_jmp == DISAS_HVC && !dc->condjmp) {
11245 gen_ss_advance(dc);
11246 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11247 } else if (dc->is_jmp == DISAS_SMC && !dc->condjmp) {
11248 gen_ss_advance(dc);
11249 gen_exception(EXCP_SMC, syn_aa32_smc());
11250 } else if (dc->ss_active) {
11251 gen_step_complete_exception(dc);
11252 } else {
11253 /* FIXME: Single stepping a WFI insn will not halt
11254 the CPU. */
11255 gen_exception_internal(EXCP_DEBUG);
11257 } else {
11258 /* While branches must always occur at the end of an IT block,
11259 there are a few other things that can cause us to terminate
11260 the TB in the middle of an IT block:
11261 - Exception generating instructions (bkpt, swi, undefined).
11262 - Page boundaries.
11263 - Hardware watchpoints.
11264 Hardware breakpoints have already been handled and skip this code.
11266 gen_set_condexec(dc);
11267 switch(dc->is_jmp) {
11268 case DISAS_NEXT:
11269 gen_goto_tb(dc, 1, dc->pc);
11270 break;
11271 default:
11272 case DISAS_JUMP:
11273 case DISAS_UPDATE:
11274 /* indicate that the hash table must be used to find the next TB */
11275 tcg_gen_exit_tb(0);
11276 break;
11277 case DISAS_TB_JUMP:
11278 /* nothing more to generate */
11279 break;
11280 case DISAS_WFI:
11281 gen_helper_wfi(cpu_env);
11282 break;
11283 case DISAS_WFE:
11284 gen_helper_wfe(cpu_env);
11285 break;
11286 case DISAS_SWI:
11287 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11288 break;
11289 case DISAS_HVC:
11290 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm));
11291 break;
11292 case DISAS_SMC:
11293 gen_exception(EXCP_SMC, syn_aa32_smc());
11294 break;
11296 if (dc->condjmp) {
11297 gen_set_label(dc->condlabel);
11298 gen_set_condexec(dc);
11299 gen_goto_tb(dc, 1, dc->pc);
11300 dc->condjmp = 0;
11304 done_generating:
11305 gen_tb_end(tb, num_insns);
11306 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
11308 #ifdef DEBUG_DISAS
11309 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11310 qemu_log("----------------\n");
11311 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11312 log_target_disas(env, pc_start, dc->pc - pc_start,
11313 dc->thumb | (dc->sctlr_b << 1));
11314 qemu_log("\n");
11316 #endif
11317 if (search_pc) {
11318 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
11319 lj++;
11320 while (lj <= j)
11321 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11322 } else {
11323 tb->size = dc->pc - pc_start;
11324 tb->icount = num_insns;
11328 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11330 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
11333 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
11335 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
11338 static const char *cpu_mode_names[16] = {
11339 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11340 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11343 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11344 int flags)
11346 ARMCPU *cpu = ARM_CPU(cs);
11347 CPUARMState *env = &cpu->env;
11348 int i;
11349 uint32_t psr;
11351 if (is_a64(env)) {
11352 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11353 return;
11356 for(i=0;i<16;i++) {
11357 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11358 if ((i % 4) == 3)
11359 cpu_fprintf(f, "\n");
11360 else
11361 cpu_fprintf(f, " ");
11363 psr = cpsr_read(env);
11364 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11365 psr,
11366 psr & (1 << 31) ? 'N' : '-',
11367 psr & (1 << 30) ? 'Z' : '-',
11368 psr & (1 << 29) ? 'C' : '-',
11369 psr & (1 << 28) ? 'V' : '-',
11370 psr & CPSR_T ? 'T' : 'A',
11371 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11373 if (flags & CPU_DUMP_FPU) {
11374 int numvfpregs = 0;
11375 if (arm_feature(env, ARM_FEATURE_VFP)) {
11376 numvfpregs += 16;
11378 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11379 numvfpregs += 16;
11381 for (i = 0; i < numvfpregs; i++) {
11382 uint64_t v = float64_val(env->vfp.regs[i]);
11383 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11384 i * 2, (uint32_t)v,
11385 i * 2 + 1, (uint32_t)(v >> 32),
11386 i, v);
11388 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11392 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11394 if (is_a64(env)) {
11395 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
11396 env->condexec_bits = 0;
11397 } else {
11398 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
11399 env->condexec_bits = gen_opc_condexec_bits[pc_pos];