virtio-ccw: check flic->adapter_routes_max_batch
[qemu.git] / target / arm / translate.c
blob4436d8f3a218b9994d191f3cb61c5b38a682e472
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "qemu/log.h"
29 #include "qemu/bitops.h"
30 #include "arm_ldst.h"
31 #include "exec/semihost.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
36 #include "trace-tcg.h"
37 #include "exec/log.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J 0
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) 1
57 #else
58 #define IS_USER(s) (s->user)
59 #endif
61 TCGv_env cpu_env;
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s, cpu_F1s;
71 static TCGv_i64 cpu_F0d, cpu_F1d;
73 #include "exec/gen-icount.h"
75 static const char *regnames[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* initialize TCG globals. */
80 void arm_translate_init(void)
82 int i;
84 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
85 tcg_ctx.tcg_env = cpu_env;
87 for (i = 0; i < 16; i++) {
88 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
89 offsetof(CPUARMState, regs[i]),
90 regnames[i]);
92 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
93 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
94 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
95 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
97 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
98 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
99 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
100 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 a64_translate_init();
105 /* Flags for the disas_set_da_iss info argument:
106 * lower bits hold the Rt register number, higher bits are flags.
108 typedef enum ISSInfo {
109 ISSNone = 0,
110 ISSRegMask = 0x1f,
111 ISSInvalid = (1 << 5),
112 ISSIsAcqRel = (1 << 6),
113 ISSIsWrite = (1 << 7),
114 ISSIs16Bit = (1 << 8),
115 } ISSInfo;
117 /* Save the syndrome information for a Data Abort */
118 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
120 uint32_t syn;
121 int sas = memop & MO_SIZE;
122 bool sse = memop & MO_SIGN;
123 bool is_acqrel = issinfo & ISSIsAcqRel;
124 bool is_write = issinfo & ISSIsWrite;
125 bool is_16bit = issinfo & ISSIs16Bit;
126 int srt = issinfo & ISSRegMask;
128 if (issinfo & ISSInvalid) {
129 /* Some callsites want to conditionally provide ISS info,
130 * eg "only if this was not a writeback"
132 return;
135 if (srt == 15) {
136 /* For AArch32, insns where the src/dest is R15 never generate
137 * ISS information. Catching that here saves checking at all
138 * the call sites.
140 return;
143 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
144 0, 0, 0, is_write, 0, is_16bit);
145 disas_set_insn_syndrome(s, syn);
148 static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
150 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
151 * insns:
152 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
153 * otherwise, access as if at PL0.
155 switch (s->mmu_idx) {
156 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
157 case ARMMMUIdx_S12NSE0:
158 case ARMMMUIdx_S12NSE1:
159 return ARMMMUIdx_S12NSE0;
160 case ARMMMUIdx_S1E3:
161 case ARMMMUIdx_S1SE0:
162 case ARMMMUIdx_S1SE1:
163 return ARMMMUIdx_S1SE0;
164 case ARMMMUIdx_S2NS:
165 default:
166 g_assert_not_reached();
170 static inline TCGv_i32 load_cpu_offset(int offset)
172 TCGv_i32 tmp = tcg_temp_new_i32();
173 tcg_gen_ld_i32(tmp, cpu_env, offset);
174 return tmp;
177 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
179 static inline void store_cpu_offset(TCGv_i32 var, int offset)
181 tcg_gen_st_i32(var, cpu_env, offset);
182 tcg_temp_free_i32(var);
185 #define store_cpu_field(var, name) \
186 store_cpu_offset(var, offsetof(CPUARMState, name))
188 /* Set a variable to the value of a CPU register. */
189 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
191 if (reg == 15) {
192 uint32_t addr;
193 /* normally, since we updated PC, we need only to add one insn */
194 if (s->thumb)
195 addr = (long)s->pc + 2;
196 else
197 addr = (long)s->pc + 4;
198 tcg_gen_movi_i32(var, addr);
199 } else {
200 tcg_gen_mov_i32(var, cpu_R[reg]);
204 /* Create a new temporary and set it to the value of a CPU register. */
205 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
207 TCGv_i32 tmp = tcg_temp_new_i32();
208 load_reg_var(s, tmp, reg);
209 return tmp;
212 /* Set a CPU register. The source must be a temporary and will be
213 marked as dead. */
214 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
216 if (reg == 15) {
217 /* In Thumb mode, we must ignore bit 0.
218 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
219 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
220 * We choose to ignore [1:0] in ARM mode for all architecture versions.
222 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
223 s->is_jmp = DISAS_JUMP;
225 tcg_gen_mov_i32(cpu_R[reg], var);
226 tcg_temp_free_i32(var);
229 /* Value extensions. */
230 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
231 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
232 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
233 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
235 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
236 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
239 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
241 TCGv_i32 tmp_mask = tcg_const_i32(mask);
242 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
243 tcg_temp_free_i32(tmp_mask);
245 /* Set NZCV flags from the high 4 bits of var. */
246 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
248 static void gen_exception_internal(int excp)
250 TCGv_i32 tcg_excp = tcg_const_i32(excp);
252 assert(excp_is_internal(excp));
253 gen_helper_exception_internal(cpu_env, tcg_excp);
254 tcg_temp_free_i32(tcg_excp);
257 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
259 TCGv_i32 tcg_excp = tcg_const_i32(excp);
260 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
261 TCGv_i32 tcg_el = tcg_const_i32(target_el);
263 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
264 tcg_syn, tcg_el);
266 tcg_temp_free_i32(tcg_el);
267 tcg_temp_free_i32(tcg_syn);
268 tcg_temp_free_i32(tcg_excp);
271 static void gen_ss_advance(DisasContext *s)
273 /* If the singlestep state is Active-not-pending, advance to
274 * Active-pending.
276 if (s->ss_active) {
277 s->pstate_ss = 0;
278 gen_helper_clear_pstate_ss(cpu_env);
282 static void gen_step_complete_exception(DisasContext *s)
284 /* We just completed step of an insn. Move from Active-not-pending
285 * to Active-pending, and then also take the swstep exception.
286 * This corresponds to making the (IMPDEF) choice to prioritize
287 * swstep exceptions over asynchronous exceptions taken to an exception
288 * level where debug is disabled. This choice has the advantage that
289 * we do not need to maintain internal state corresponding to the
290 * ISV/EX syndrome bits between completion of the step and generation
291 * of the exception, and our syndrome information is always correct.
293 gen_ss_advance(s);
294 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
295 default_exception_el(s));
296 s->is_jmp = DISAS_EXC;
299 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
301 TCGv_i32 tmp1 = tcg_temp_new_i32();
302 TCGv_i32 tmp2 = tcg_temp_new_i32();
303 tcg_gen_ext16s_i32(tmp1, a);
304 tcg_gen_ext16s_i32(tmp2, b);
305 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
306 tcg_temp_free_i32(tmp2);
307 tcg_gen_sari_i32(a, a, 16);
308 tcg_gen_sari_i32(b, b, 16);
309 tcg_gen_mul_i32(b, b, a);
310 tcg_gen_mov_i32(a, tmp1);
311 tcg_temp_free_i32(tmp1);
314 /* Byteswap each halfword. */
315 static void gen_rev16(TCGv_i32 var)
317 TCGv_i32 tmp = tcg_temp_new_i32();
318 tcg_gen_shri_i32(tmp, var, 8);
319 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
320 tcg_gen_shli_i32(var, var, 8);
321 tcg_gen_andi_i32(var, var, 0xff00ff00);
322 tcg_gen_or_i32(var, var, tmp);
323 tcg_temp_free_i32(tmp);
326 /* Byteswap low halfword and sign extend. */
327 static void gen_revsh(TCGv_i32 var)
329 tcg_gen_ext16u_i32(var, var);
330 tcg_gen_bswap16_i32(var, var);
331 tcg_gen_ext16s_i32(var, var);
334 /* Return (b << 32) + a. Mark inputs as dead */
335 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
337 TCGv_i64 tmp64 = tcg_temp_new_i64();
339 tcg_gen_extu_i32_i64(tmp64, b);
340 tcg_temp_free_i32(b);
341 tcg_gen_shli_i64(tmp64, tmp64, 32);
342 tcg_gen_add_i64(a, tmp64, a);
344 tcg_temp_free_i64(tmp64);
345 return a;
348 /* Return (b << 32) - a. Mark inputs as dead. */
349 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
351 TCGv_i64 tmp64 = tcg_temp_new_i64();
353 tcg_gen_extu_i32_i64(tmp64, b);
354 tcg_temp_free_i32(b);
355 tcg_gen_shli_i64(tmp64, tmp64, 32);
356 tcg_gen_sub_i64(a, tmp64, a);
358 tcg_temp_free_i64(tmp64);
359 return a;
362 /* 32x32->64 multiply. Marks inputs as dead. */
363 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
365 TCGv_i32 lo = tcg_temp_new_i32();
366 TCGv_i32 hi = tcg_temp_new_i32();
367 TCGv_i64 ret;
369 tcg_gen_mulu2_i32(lo, hi, a, b);
370 tcg_temp_free_i32(a);
371 tcg_temp_free_i32(b);
373 ret = tcg_temp_new_i64();
374 tcg_gen_concat_i32_i64(ret, lo, hi);
375 tcg_temp_free_i32(lo);
376 tcg_temp_free_i32(hi);
378 return ret;
381 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
383 TCGv_i32 lo = tcg_temp_new_i32();
384 TCGv_i32 hi = tcg_temp_new_i32();
385 TCGv_i64 ret;
387 tcg_gen_muls2_i32(lo, hi, a, b);
388 tcg_temp_free_i32(a);
389 tcg_temp_free_i32(b);
391 ret = tcg_temp_new_i64();
392 tcg_gen_concat_i32_i64(ret, lo, hi);
393 tcg_temp_free_i32(lo);
394 tcg_temp_free_i32(hi);
396 return ret;
399 /* Swap low and high halfwords. */
400 static void gen_swap_half(TCGv_i32 var)
402 TCGv_i32 tmp = tcg_temp_new_i32();
403 tcg_gen_shri_i32(tmp, var, 16);
404 tcg_gen_shli_i32(var, var, 16);
405 tcg_gen_or_i32(var, var, tmp);
406 tcg_temp_free_i32(tmp);
409 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
410 tmp = (t0 ^ t1) & 0x8000;
411 t0 &= ~0x8000;
412 t1 &= ~0x8000;
413 t0 = (t0 + t1) ^ tmp;
416 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
418 TCGv_i32 tmp = tcg_temp_new_i32();
419 tcg_gen_xor_i32(tmp, t0, t1);
420 tcg_gen_andi_i32(tmp, tmp, 0x8000);
421 tcg_gen_andi_i32(t0, t0, ~0x8000);
422 tcg_gen_andi_i32(t1, t1, ~0x8000);
423 tcg_gen_add_i32(t0, t0, t1);
424 tcg_gen_xor_i32(t0, t0, tmp);
425 tcg_temp_free_i32(tmp);
426 tcg_temp_free_i32(t1);
429 /* Set CF to the top bit of var. */
430 static void gen_set_CF_bit31(TCGv_i32 var)
432 tcg_gen_shri_i32(cpu_CF, var, 31);
435 /* Set N and Z flags from var. */
436 static inline void gen_logic_CC(TCGv_i32 var)
438 tcg_gen_mov_i32(cpu_NF, var);
439 tcg_gen_mov_i32(cpu_ZF, var);
442 /* T0 += T1 + CF. */
443 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
445 tcg_gen_add_i32(t0, t0, t1);
446 tcg_gen_add_i32(t0, t0, cpu_CF);
449 /* dest = T0 + T1 + CF. */
450 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
452 tcg_gen_add_i32(dest, t0, t1);
453 tcg_gen_add_i32(dest, dest, cpu_CF);
456 /* dest = T0 - T1 + CF - 1. */
457 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
459 tcg_gen_sub_i32(dest, t0, t1);
460 tcg_gen_add_i32(dest, dest, cpu_CF);
461 tcg_gen_subi_i32(dest, dest, 1);
464 /* dest = T0 + T1. Compute C, N, V and Z flags */
465 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
467 TCGv_i32 tmp = tcg_temp_new_i32();
468 tcg_gen_movi_i32(tmp, 0);
469 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
470 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
471 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
472 tcg_gen_xor_i32(tmp, t0, t1);
473 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
474 tcg_temp_free_i32(tmp);
475 tcg_gen_mov_i32(dest, cpu_NF);
478 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
479 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
481 TCGv_i32 tmp = tcg_temp_new_i32();
482 if (TCG_TARGET_HAS_add2_i32) {
483 tcg_gen_movi_i32(tmp, 0);
484 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
485 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
486 } else {
487 TCGv_i64 q0 = tcg_temp_new_i64();
488 TCGv_i64 q1 = tcg_temp_new_i64();
489 tcg_gen_extu_i32_i64(q0, t0);
490 tcg_gen_extu_i32_i64(q1, t1);
491 tcg_gen_add_i64(q0, q0, q1);
492 tcg_gen_extu_i32_i64(q1, cpu_CF);
493 tcg_gen_add_i64(q0, q0, q1);
494 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
495 tcg_temp_free_i64(q0);
496 tcg_temp_free_i64(q1);
498 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
499 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
500 tcg_gen_xor_i32(tmp, t0, t1);
501 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
502 tcg_temp_free_i32(tmp);
503 tcg_gen_mov_i32(dest, cpu_NF);
506 /* dest = T0 - T1. Compute C, N, V and Z flags */
507 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
509 TCGv_i32 tmp;
510 tcg_gen_sub_i32(cpu_NF, t0, t1);
511 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
512 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
513 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
514 tmp = tcg_temp_new_i32();
515 tcg_gen_xor_i32(tmp, t0, t1);
516 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
517 tcg_temp_free_i32(tmp);
518 tcg_gen_mov_i32(dest, cpu_NF);
521 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
522 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
524 TCGv_i32 tmp = tcg_temp_new_i32();
525 tcg_gen_not_i32(tmp, t1);
526 gen_adc_CC(dest, t0, tmp);
527 tcg_temp_free_i32(tmp);
530 #define GEN_SHIFT(name) \
531 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
533 TCGv_i32 tmp1, tmp2, tmp3; \
534 tmp1 = tcg_temp_new_i32(); \
535 tcg_gen_andi_i32(tmp1, t1, 0xff); \
536 tmp2 = tcg_const_i32(0); \
537 tmp3 = tcg_const_i32(0x1f); \
538 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
539 tcg_temp_free_i32(tmp3); \
540 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
541 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
542 tcg_temp_free_i32(tmp2); \
543 tcg_temp_free_i32(tmp1); \
545 GEN_SHIFT(shl)
546 GEN_SHIFT(shr)
547 #undef GEN_SHIFT
549 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
551 TCGv_i32 tmp1, tmp2;
552 tmp1 = tcg_temp_new_i32();
553 tcg_gen_andi_i32(tmp1, t1, 0xff);
554 tmp2 = tcg_const_i32(0x1f);
555 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
556 tcg_temp_free_i32(tmp2);
557 tcg_gen_sar_i32(dest, t0, tmp1);
558 tcg_temp_free_i32(tmp1);
561 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
563 TCGv_i32 c0 = tcg_const_i32(0);
564 TCGv_i32 tmp = tcg_temp_new_i32();
565 tcg_gen_neg_i32(tmp, src);
566 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
567 tcg_temp_free_i32(c0);
568 tcg_temp_free_i32(tmp);
571 static void shifter_out_im(TCGv_i32 var, int shift)
573 if (shift == 0) {
574 tcg_gen_andi_i32(cpu_CF, var, 1);
575 } else {
576 tcg_gen_shri_i32(cpu_CF, var, shift);
577 if (shift != 31) {
578 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
583 /* Shift by immediate. Includes special handling for shift == 0. */
584 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
585 int shift, int flags)
587 switch (shiftop) {
588 case 0: /* LSL */
589 if (shift != 0) {
590 if (flags)
591 shifter_out_im(var, 32 - shift);
592 tcg_gen_shli_i32(var, var, shift);
594 break;
595 case 1: /* LSR */
596 if (shift == 0) {
597 if (flags) {
598 tcg_gen_shri_i32(cpu_CF, var, 31);
600 tcg_gen_movi_i32(var, 0);
601 } else {
602 if (flags)
603 shifter_out_im(var, shift - 1);
604 tcg_gen_shri_i32(var, var, shift);
606 break;
607 case 2: /* ASR */
608 if (shift == 0)
609 shift = 32;
610 if (flags)
611 shifter_out_im(var, shift - 1);
612 if (shift == 32)
613 shift = 31;
614 tcg_gen_sari_i32(var, var, shift);
615 break;
616 case 3: /* ROR/RRX */
617 if (shift != 0) {
618 if (flags)
619 shifter_out_im(var, shift - 1);
620 tcg_gen_rotri_i32(var, var, shift); break;
621 } else {
622 TCGv_i32 tmp = tcg_temp_new_i32();
623 tcg_gen_shli_i32(tmp, cpu_CF, 31);
624 if (flags)
625 shifter_out_im(var, 0);
626 tcg_gen_shri_i32(var, var, 1);
627 tcg_gen_or_i32(var, var, tmp);
628 tcg_temp_free_i32(tmp);
633 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
634 TCGv_i32 shift, int flags)
636 if (flags) {
637 switch (shiftop) {
638 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
639 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
640 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
641 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
643 } else {
644 switch (shiftop) {
645 case 0:
646 gen_shl(var, var, shift);
647 break;
648 case 1:
649 gen_shr(var, var, shift);
650 break;
651 case 2:
652 gen_sar(var, var, shift);
653 break;
654 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
655 tcg_gen_rotr_i32(var, var, shift); break;
658 tcg_temp_free_i32(shift);
661 #define PAS_OP(pfx) \
662 switch (op2) { \
663 case 0: gen_pas_helper(glue(pfx,add16)); break; \
664 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
665 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
666 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
667 case 4: gen_pas_helper(glue(pfx,add8)); break; \
668 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
670 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
672 TCGv_ptr tmp;
674 switch (op1) {
675 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
676 case 1:
677 tmp = tcg_temp_new_ptr();
678 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
679 PAS_OP(s)
680 tcg_temp_free_ptr(tmp);
681 break;
682 case 5:
683 tmp = tcg_temp_new_ptr();
684 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
685 PAS_OP(u)
686 tcg_temp_free_ptr(tmp);
687 break;
688 #undef gen_pas_helper
689 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
690 case 2:
691 PAS_OP(q);
692 break;
693 case 3:
694 PAS_OP(sh);
695 break;
696 case 6:
697 PAS_OP(uq);
698 break;
699 case 7:
700 PAS_OP(uh);
701 break;
702 #undef gen_pas_helper
705 #undef PAS_OP
707 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
708 #define PAS_OP(pfx) \
709 switch (op1) { \
710 case 0: gen_pas_helper(glue(pfx,add8)); break; \
711 case 1: gen_pas_helper(glue(pfx,add16)); break; \
712 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
713 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
714 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
715 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
717 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
719 TCGv_ptr tmp;
721 switch (op2) {
722 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
723 case 0:
724 tmp = tcg_temp_new_ptr();
725 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
726 PAS_OP(s)
727 tcg_temp_free_ptr(tmp);
728 break;
729 case 4:
730 tmp = tcg_temp_new_ptr();
731 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
732 PAS_OP(u)
733 tcg_temp_free_ptr(tmp);
734 break;
735 #undef gen_pas_helper
736 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
737 case 1:
738 PAS_OP(q);
739 break;
740 case 2:
741 PAS_OP(sh);
742 break;
743 case 5:
744 PAS_OP(uq);
745 break;
746 case 6:
747 PAS_OP(uh);
748 break;
749 #undef gen_pas_helper
752 #undef PAS_OP
755 * Generate a conditional based on ARM condition code cc.
756 * This is common between ARM and Aarch64 targets.
758 void arm_test_cc(DisasCompare *cmp, int cc)
760 TCGv_i32 value;
761 TCGCond cond;
762 bool global = true;
764 switch (cc) {
765 case 0: /* eq: Z */
766 case 1: /* ne: !Z */
767 cond = TCG_COND_EQ;
768 value = cpu_ZF;
769 break;
771 case 2: /* cs: C */
772 case 3: /* cc: !C */
773 cond = TCG_COND_NE;
774 value = cpu_CF;
775 break;
777 case 4: /* mi: N */
778 case 5: /* pl: !N */
779 cond = TCG_COND_LT;
780 value = cpu_NF;
781 break;
783 case 6: /* vs: V */
784 case 7: /* vc: !V */
785 cond = TCG_COND_LT;
786 value = cpu_VF;
787 break;
789 case 8: /* hi: C && !Z */
790 case 9: /* ls: !C || Z -> !(C && !Z) */
791 cond = TCG_COND_NE;
792 value = tcg_temp_new_i32();
793 global = false;
794 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
795 ZF is non-zero for !Z; so AND the two subexpressions. */
796 tcg_gen_neg_i32(value, cpu_CF);
797 tcg_gen_and_i32(value, value, cpu_ZF);
798 break;
800 case 10: /* ge: N == V -> N ^ V == 0 */
801 case 11: /* lt: N != V -> N ^ V != 0 */
802 /* Since we're only interested in the sign bit, == 0 is >= 0. */
803 cond = TCG_COND_GE;
804 value = tcg_temp_new_i32();
805 global = false;
806 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
807 break;
809 case 12: /* gt: !Z && N == V */
810 case 13: /* le: Z || N != V */
811 cond = TCG_COND_NE;
812 value = tcg_temp_new_i32();
813 global = false;
814 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
815 * the sign bit then AND with ZF to yield the result. */
816 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
817 tcg_gen_sari_i32(value, value, 31);
818 tcg_gen_andc_i32(value, cpu_ZF, value);
819 break;
821 case 14: /* always */
822 case 15: /* always */
823 /* Use the ALWAYS condition, which will fold early.
824 * It doesn't matter what we use for the value. */
825 cond = TCG_COND_ALWAYS;
826 value = cpu_ZF;
827 goto no_invert;
829 default:
830 fprintf(stderr, "Bad condition code 0x%x\n", cc);
831 abort();
834 if (cc & 1) {
835 cond = tcg_invert_cond(cond);
838 no_invert:
839 cmp->cond = cond;
840 cmp->value = value;
841 cmp->value_global = global;
844 void arm_free_cc(DisasCompare *cmp)
846 if (!cmp->value_global) {
847 tcg_temp_free_i32(cmp->value);
851 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
853 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
856 void arm_gen_test_cc(int cc, TCGLabel *label)
858 DisasCompare cmp;
859 arm_test_cc(&cmp, cc);
860 arm_jump_cc(&cmp, label);
861 arm_free_cc(&cmp);
864 static const uint8_t table_logic_cc[16] = {
865 1, /* and */
866 1, /* xor */
867 0, /* sub */
868 0, /* rsb */
869 0, /* add */
870 0, /* adc */
871 0, /* sbc */
872 0, /* rsc */
873 1, /* andl */
874 1, /* xorl */
875 0, /* cmp */
876 0, /* cmn */
877 1, /* orr */
878 1, /* mov */
879 1, /* bic */
880 1, /* mvn */
883 /* Set PC and Thumb state from an immediate address. */
884 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
886 TCGv_i32 tmp;
888 s->is_jmp = DISAS_JUMP;
889 if (s->thumb != (addr & 1)) {
890 tmp = tcg_temp_new_i32();
891 tcg_gen_movi_i32(tmp, addr & 1);
892 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
893 tcg_temp_free_i32(tmp);
895 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
898 /* Set PC and Thumb state from var. var is marked as dead. */
899 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
901 s->is_jmp = DISAS_JUMP;
902 tcg_gen_andi_i32(cpu_R[15], var, ~1);
903 tcg_gen_andi_i32(var, var, 1);
904 store_cpu_field(var, thumb);
907 /* Variant of store_reg which uses branch&exchange logic when storing
908 to r15 in ARM architecture v7 and above. The source must be a temporary
909 and will be marked as dead. */
910 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
912 if (reg == 15 && ENABLE_ARCH_7) {
913 gen_bx(s, var);
914 } else {
915 store_reg(s, reg, var);
919 /* Variant of store_reg which uses branch&exchange logic when storing
920 * to r15 in ARM architecture v5T and above. This is used for storing
921 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
922 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
923 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
925 if (reg == 15 && ENABLE_ARCH_5) {
926 gen_bx(s, var);
927 } else {
928 store_reg(s, reg, var);
932 #ifdef CONFIG_USER_ONLY
933 #define IS_USER_ONLY 1
934 #else
935 #define IS_USER_ONLY 0
936 #endif
938 /* Abstractions of "generate code to do a guest load/store for
939 * AArch32", where a vaddr is always 32 bits (and is zero
940 * extended if we're a 64 bit core) and data is also
941 * 32 bits unless specifically doing a 64 bit access.
942 * These functions work like tcg_gen_qemu_{ld,st}* except
943 * that the address argument is TCGv_i32 rather than TCGv.
946 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
948 TCGv addr = tcg_temp_new();
949 tcg_gen_extu_i32_tl(addr, a32);
951 /* Not needed for user-mode BE32, where we use MO_BE instead. */
952 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
953 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
955 return addr;
958 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
959 int index, TCGMemOp opc)
961 TCGv addr = gen_aa32_addr(s, a32, opc);
962 tcg_gen_qemu_ld_i32(val, addr, index, opc);
963 tcg_temp_free(addr);
966 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
967 int index, TCGMemOp opc)
969 TCGv addr = gen_aa32_addr(s, a32, opc);
970 tcg_gen_qemu_st_i32(val, addr, index, opc);
971 tcg_temp_free(addr);
974 #define DO_GEN_LD(SUFF, OPC) \
975 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
976 TCGv_i32 a32, int index) \
978 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
980 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
981 TCGv_i32 val, \
982 TCGv_i32 a32, int index, \
983 ISSInfo issinfo) \
985 gen_aa32_ld##SUFF(s, val, a32, index); \
986 disas_set_da_iss(s, OPC, issinfo); \
989 #define DO_GEN_ST(SUFF, OPC) \
990 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
991 TCGv_i32 a32, int index) \
993 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
995 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
996 TCGv_i32 val, \
997 TCGv_i32 a32, int index, \
998 ISSInfo issinfo) \
1000 gen_aa32_st##SUFF(s, val, a32, index); \
1001 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1004 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1006 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1007 if (!IS_USER_ONLY && s->sctlr_b) {
1008 tcg_gen_rotri_i64(val, val, 32);
1012 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1013 int index, TCGMemOp opc)
1015 TCGv addr = gen_aa32_addr(s, a32, opc);
1016 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1017 gen_aa32_frob64(s, val);
1018 tcg_temp_free(addr);
1021 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1022 TCGv_i32 a32, int index)
1024 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1027 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1028 int index, TCGMemOp opc)
1030 TCGv addr = gen_aa32_addr(s, a32, opc);
1032 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1033 if (!IS_USER_ONLY && s->sctlr_b) {
1034 TCGv_i64 tmp = tcg_temp_new_i64();
1035 tcg_gen_rotri_i64(tmp, val, 32);
1036 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1037 tcg_temp_free_i64(tmp);
1038 } else {
1039 tcg_gen_qemu_st_i64(val, addr, index, opc);
1041 tcg_temp_free(addr);
1044 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1045 TCGv_i32 a32, int index)
1047 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1050 DO_GEN_LD(8s, MO_SB)
1051 DO_GEN_LD(8u, MO_UB)
1052 DO_GEN_LD(16s, MO_SW)
1053 DO_GEN_LD(16u, MO_UW)
1054 DO_GEN_LD(32u, MO_UL)
1055 DO_GEN_ST(8, MO_UB)
1056 DO_GEN_ST(16, MO_UW)
1057 DO_GEN_ST(32, MO_UL)
1059 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
1061 tcg_gen_movi_i32(cpu_R[15], val);
1064 static inline void gen_hvc(DisasContext *s, int imm16)
1066 /* The pre HVC helper handles cases when HVC gets trapped
1067 * as an undefined insn by runtime configuration (ie before
1068 * the insn really executes).
1070 gen_set_pc_im(s, s->pc - 4);
1071 gen_helper_pre_hvc(cpu_env);
1072 /* Otherwise we will treat this as a real exception which
1073 * happens after execution of the insn. (The distinction matters
1074 * for the PC value reported to the exception handler and also
1075 * for single stepping.)
1077 s->svc_imm = imm16;
1078 gen_set_pc_im(s, s->pc);
1079 s->is_jmp = DISAS_HVC;
1082 static inline void gen_smc(DisasContext *s)
1084 /* As with HVC, we may take an exception either before or after
1085 * the insn executes.
1087 TCGv_i32 tmp;
1089 gen_set_pc_im(s, s->pc - 4);
1090 tmp = tcg_const_i32(syn_aa32_smc());
1091 gen_helper_pre_smc(cpu_env, tmp);
1092 tcg_temp_free_i32(tmp);
1093 gen_set_pc_im(s, s->pc);
1094 s->is_jmp = DISAS_SMC;
1097 static inline void
1098 gen_set_condexec (DisasContext *s)
1100 if (s->condexec_mask) {
1101 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1102 TCGv_i32 tmp = tcg_temp_new_i32();
1103 tcg_gen_movi_i32(tmp, val);
1104 store_cpu_field(tmp, condexec_bits);
1108 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1110 gen_set_condexec(s);
1111 gen_set_pc_im(s, s->pc - offset);
1112 gen_exception_internal(excp);
1113 s->is_jmp = DISAS_JUMP;
1116 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1117 int syn, uint32_t target_el)
1119 gen_set_condexec(s);
1120 gen_set_pc_im(s, s->pc - offset);
1121 gen_exception(excp, syn, target_el);
1122 s->is_jmp = DISAS_JUMP;
1125 /* Force a TB lookup after an instruction that changes the CPU state. */
1126 static inline void gen_lookup_tb(DisasContext *s)
1128 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1129 s->is_jmp = DISAS_JUMP;
1132 static inline void gen_hlt(DisasContext *s, int imm)
1134 /* HLT. This has two purposes.
1135 * Architecturally, it is an external halting debug instruction.
1136 * Since QEMU doesn't implement external debug, we treat this as
1137 * it is required for halting debug disabled: it will UNDEF.
1138 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1139 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1140 * must trigger semihosting even for ARMv7 and earlier, where
1141 * HLT was an undefined encoding.
1142 * In system mode, we don't allow userspace access to
1143 * semihosting, to provide some semblance of security
1144 * (and for consistency with our 32-bit semihosting).
1146 if (semihosting_enabled() &&
1147 #ifndef CONFIG_USER_ONLY
1148 s->current_el != 0 &&
1149 #endif
1150 (imm == (s->thumb ? 0x3c : 0xf000))) {
1151 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1152 return;
1155 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1156 default_exception_el(s));
1159 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1160 TCGv_i32 var)
1162 int val, rm, shift, shiftop;
1163 TCGv_i32 offset;
1165 if (!(insn & (1 << 25))) {
1166 /* immediate */
1167 val = insn & 0xfff;
1168 if (!(insn & (1 << 23)))
1169 val = -val;
1170 if (val != 0)
1171 tcg_gen_addi_i32(var, var, val);
1172 } else {
1173 /* shift/register */
1174 rm = (insn) & 0xf;
1175 shift = (insn >> 7) & 0x1f;
1176 shiftop = (insn >> 5) & 3;
1177 offset = load_reg(s, rm);
1178 gen_arm_shift_im(offset, shiftop, shift, 0);
1179 if (!(insn & (1 << 23)))
1180 tcg_gen_sub_i32(var, var, offset);
1181 else
1182 tcg_gen_add_i32(var, var, offset);
1183 tcg_temp_free_i32(offset);
1187 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1188 int extra, TCGv_i32 var)
1190 int val, rm;
1191 TCGv_i32 offset;
1193 if (insn & (1 << 22)) {
1194 /* immediate */
1195 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1196 if (!(insn & (1 << 23)))
1197 val = -val;
1198 val += extra;
1199 if (val != 0)
1200 tcg_gen_addi_i32(var, var, val);
1201 } else {
1202 /* register */
1203 if (extra)
1204 tcg_gen_addi_i32(var, var, extra);
1205 rm = (insn) & 0xf;
1206 offset = load_reg(s, rm);
1207 if (!(insn & (1 << 23)))
1208 tcg_gen_sub_i32(var, var, offset);
1209 else
1210 tcg_gen_add_i32(var, var, offset);
1211 tcg_temp_free_i32(offset);
1215 static TCGv_ptr get_fpstatus_ptr(int neon)
1217 TCGv_ptr statusptr = tcg_temp_new_ptr();
1218 int offset;
1219 if (neon) {
1220 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1221 } else {
1222 offset = offsetof(CPUARMState, vfp.fp_status);
1224 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1225 return statusptr;
1228 #define VFP_OP2(name) \
1229 static inline void gen_vfp_##name(int dp) \
1231 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1232 if (dp) { \
1233 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1234 } else { \
1235 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1237 tcg_temp_free_ptr(fpst); \
1240 VFP_OP2(add)
1241 VFP_OP2(sub)
1242 VFP_OP2(mul)
1243 VFP_OP2(div)
1245 #undef VFP_OP2
1247 static inline void gen_vfp_F1_mul(int dp)
1249 /* Like gen_vfp_mul() but put result in F1 */
1250 TCGv_ptr fpst = get_fpstatus_ptr(0);
1251 if (dp) {
1252 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1253 } else {
1254 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1256 tcg_temp_free_ptr(fpst);
1259 static inline void gen_vfp_F1_neg(int dp)
1261 /* Like gen_vfp_neg() but put result in F1 */
1262 if (dp) {
1263 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1264 } else {
1265 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1269 static inline void gen_vfp_abs(int dp)
1271 if (dp)
1272 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1273 else
1274 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1277 static inline void gen_vfp_neg(int dp)
1279 if (dp)
1280 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1281 else
1282 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1285 static inline void gen_vfp_sqrt(int dp)
1287 if (dp)
1288 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1289 else
1290 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1293 static inline void gen_vfp_cmp(int dp)
1295 if (dp)
1296 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1297 else
1298 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1301 static inline void gen_vfp_cmpe(int dp)
1303 if (dp)
1304 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1305 else
1306 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1309 static inline void gen_vfp_F1_ld0(int dp)
1311 if (dp)
1312 tcg_gen_movi_i64(cpu_F1d, 0);
1313 else
1314 tcg_gen_movi_i32(cpu_F1s, 0);
1317 #define VFP_GEN_ITOF(name) \
1318 static inline void gen_vfp_##name(int dp, int neon) \
1320 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1321 if (dp) { \
1322 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1323 } else { \
1324 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1326 tcg_temp_free_ptr(statusptr); \
1329 VFP_GEN_ITOF(uito)
1330 VFP_GEN_ITOF(sito)
1331 #undef VFP_GEN_ITOF
1333 #define VFP_GEN_FTOI(name) \
1334 static inline void gen_vfp_##name(int dp, int neon) \
1336 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1337 if (dp) { \
1338 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1339 } else { \
1340 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1342 tcg_temp_free_ptr(statusptr); \
1345 VFP_GEN_FTOI(toui)
1346 VFP_GEN_FTOI(touiz)
1347 VFP_GEN_FTOI(tosi)
1348 VFP_GEN_FTOI(tosiz)
1349 #undef VFP_GEN_FTOI
1351 #define VFP_GEN_FIX(name, round) \
1352 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1354 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1355 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1356 if (dp) { \
1357 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1358 statusptr); \
1359 } else { \
1360 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1361 statusptr); \
1363 tcg_temp_free_i32(tmp_shift); \
1364 tcg_temp_free_ptr(statusptr); \
1366 VFP_GEN_FIX(tosh, _round_to_zero)
1367 VFP_GEN_FIX(tosl, _round_to_zero)
1368 VFP_GEN_FIX(touh, _round_to_zero)
1369 VFP_GEN_FIX(toul, _round_to_zero)
1370 VFP_GEN_FIX(shto, )
1371 VFP_GEN_FIX(slto, )
1372 VFP_GEN_FIX(uhto, )
1373 VFP_GEN_FIX(ulto, )
1374 #undef VFP_GEN_FIX
1376 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1378 if (dp) {
1379 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1380 } else {
1381 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1385 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1387 if (dp) {
1388 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1389 } else {
1390 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1394 static inline long
1395 vfp_reg_offset (int dp, int reg)
1397 if (dp)
1398 return offsetof(CPUARMState, vfp.regs[reg]);
1399 else if (reg & 1) {
1400 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1401 + offsetof(CPU_DoubleU, l.upper);
1402 } else {
1403 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1404 + offsetof(CPU_DoubleU, l.lower);
1408 /* Return the offset of a 32-bit piece of a NEON register.
1409 zero is the least significant end of the register. */
1410 static inline long
1411 neon_reg_offset (int reg, int n)
1413 int sreg;
1414 sreg = reg * 2 + n;
1415 return vfp_reg_offset(0, sreg);
1418 static TCGv_i32 neon_load_reg(int reg, int pass)
1420 TCGv_i32 tmp = tcg_temp_new_i32();
1421 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1422 return tmp;
1425 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1427 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1428 tcg_temp_free_i32(var);
1431 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1433 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1436 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1438 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1441 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1442 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1443 #define tcg_gen_st_f32 tcg_gen_st_i32
1444 #define tcg_gen_st_f64 tcg_gen_st_i64
1446 static inline void gen_mov_F0_vreg(int dp, int reg)
1448 if (dp)
1449 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1450 else
1451 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1454 static inline void gen_mov_F1_vreg(int dp, int reg)
1456 if (dp)
1457 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1458 else
1459 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1462 static inline void gen_mov_vreg_F0(int dp, int reg)
1464 if (dp)
1465 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1466 else
1467 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1470 #define ARM_CP_RW_BIT (1 << 20)
1472 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1474 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1477 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1479 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1482 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1484 TCGv_i32 var = tcg_temp_new_i32();
1485 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1486 return var;
1489 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1491 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1492 tcg_temp_free_i32(var);
1495 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1497 iwmmxt_store_reg(cpu_M0, rn);
1500 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1502 iwmmxt_load_reg(cpu_M0, rn);
1505 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1507 iwmmxt_load_reg(cpu_V1, rn);
1508 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1511 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1513 iwmmxt_load_reg(cpu_V1, rn);
1514 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1517 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1519 iwmmxt_load_reg(cpu_V1, rn);
1520 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1523 #define IWMMXT_OP(name) \
1524 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1526 iwmmxt_load_reg(cpu_V1, rn); \
1527 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1530 #define IWMMXT_OP_ENV(name) \
1531 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1533 iwmmxt_load_reg(cpu_V1, rn); \
1534 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1537 #define IWMMXT_OP_ENV_SIZE(name) \
1538 IWMMXT_OP_ENV(name##b) \
1539 IWMMXT_OP_ENV(name##w) \
1540 IWMMXT_OP_ENV(name##l)
1542 #define IWMMXT_OP_ENV1(name) \
1543 static inline void gen_op_iwmmxt_##name##_M0(void) \
1545 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1548 IWMMXT_OP(maddsq)
1549 IWMMXT_OP(madduq)
1550 IWMMXT_OP(sadb)
1551 IWMMXT_OP(sadw)
1552 IWMMXT_OP(mulslw)
1553 IWMMXT_OP(mulshw)
1554 IWMMXT_OP(mululw)
1555 IWMMXT_OP(muluhw)
1556 IWMMXT_OP(macsw)
1557 IWMMXT_OP(macuw)
1559 IWMMXT_OP_ENV_SIZE(unpackl)
1560 IWMMXT_OP_ENV_SIZE(unpackh)
1562 IWMMXT_OP_ENV1(unpacklub)
1563 IWMMXT_OP_ENV1(unpackluw)
1564 IWMMXT_OP_ENV1(unpacklul)
1565 IWMMXT_OP_ENV1(unpackhub)
1566 IWMMXT_OP_ENV1(unpackhuw)
1567 IWMMXT_OP_ENV1(unpackhul)
1568 IWMMXT_OP_ENV1(unpacklsb)
1569 IWMMXT_OP_ENV1(unpacklsw)
1570 IWMMXT_OP_ENV1(unpacklsl)
1571 IWMMXT_OP_ENV1(unpackhsb)
1572 IWMMXT_OP_ENV1(unpackhsw)
1573 IWMMXT_OP_ENV1(unpackhsl)
1575 IWMMXT_OP_ENV_SIZE(cmpeq)
1576 IWMMXT_OP_ENV_SIZE(cmpgtu)
1577 IWMMXT_OP_ENV_SIZE(cmpgts)
1579 IWMMXT_OP_ENV_SIZE(mins)
1580 IWMMXT_OP_ENV_SIZE(minu)
1581 IWMMXT_OP_ENV_SIZE(maxs)
1582 IWMMXT_OP_ENV_SIZE(maxu)
1584 IWMMXT_OP_ENV_SIZE(subn)
1585 IWMMXT_OP_ENV_SIZE(addn)
1586 IWMMXT_OP_ENV_SIZE(subu)
1587 IWMMXT_OP_ENV_SIZE(addu)
1588 IWMMXT_OP_ENV_SIZE(subs)
1589 IWMMXT_OP_ENV_SIZE(adds)
1591 IWMMXT_OP_ENV(avgb0)
1592 IWMMXT_OP_ENV(avgb1)
1593 IWMMXT_OP_ENV(avgw0)
1594 IWMMXT_OP_ENV(avgw1)
1596 IWMMXT_OP_ENV(packuw)
1597 IWMMXT_OP_ENV(packul)
1598 IWMMXT_OP_ENV(packuq)
1599 IWMMXT_OP_ENV(packsw)
1600 IWMMXT_OP_ENV(packsl)
1601 IWMMXT_OP_ENV(packsq)
1603 static void gen_op_iwmmxt_set_mup(void)
1605 TCGv_i32 tmp;
1606 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1607 tcg_gen_ori_i32(tmp, tmp, 2);
1608 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1611 static void gen_op_iwmmxt_set_cup(void)
1613 TCGv_i32 tmp;
1614 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1615 tcg_gen_ori_i32(tmp, tmp, 1);
1616 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1619 static void gen_op_iwmmxt_setpsr_nz(void)
1621 TCGv_i32 tmp = tcg_temp_new_i32();
1622 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1623 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1626 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1628 iwmmxt_load_reg(cpu_V1, rn);
1629 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1630 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1633 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1634 TCGv_i32 dest)
1636 int rd;
1637 uint32_t offset;
1638 TCGv_i32 tmp;
1640 rd = (insn >> 16) & 0xf;
1641 tmp = load_reg(s, rd);
1643 offset = (insn & 0xff) << ((insn >> 7) & 2);
1644 if (insn & (1 << 24)) {
1645 /* Pre indexed */
1646 if (insn & (1 << 23))
1647 tcg_gen_addi_i32(tmp, tmp, offset);
1648 else
1649 tcg_gen_addi_i32(tmp, tmp, -offset);
1650 tcg_gen_mov_i32(dest, tmp);
1651 if (insn & (1 << 21))
1652 store_reg(s, rd, tmp);
1653 else
1654 tcg_temp_free_i32(tmp);
1655 } else if (insn & (1 << 21)) {
1656 /* Post indexed */
1657 tcg_gen_mov_i32(dest, tmp);
1658 if (insn & (1 << 23))
1659 tcg_gen_addi_i32(tmp, tmp, offset);
1660 else
1661 tcg_gen_addi_i32(tmp, tmp, -offset);
1662 store_reg(s, rd, tmp);
1663 } else if (!(insn & (1 << 23)))
1664 return 1;
1665 return 0;
1668 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1670 int rd = (insn >> 0) & 0xf;
1671 TCGv_i32 tmp;
1673 if (insn & (1 << 8)) {
1674 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1675 return 1;
1676 } else {
1677 tmp = iwmmxt_load_creg(rd);
1679 } else {
1680 tmp = tcg_temp_new_i32();
1681 iwmmxt_load_reg(cpu_V0, rd);
1682 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1684 tcg_gen_andi_i32(tmp, tmp, mask);
1685 tcg_gen_mov_i32(dest, tmp);
1686 tcg_temp_free_i32(tmp);
1687 return 0;
1690 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1691 (ie. an undefined instruction). */
1692 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1694 int rd, wrd;
1695 int rdhi, rdlo, rd0, rd1, i;
1696 TCGv_i32 addr;
1697 TCGv_i32 tmp, tmp2, tmp3;
1699 if ((insn & 0x0e000e00) == 0x0c000000) {
1700 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1701 wrd = insn & 0xf;
1702 rdlo = (insn >> 12) & 0xf;
1703 rdhi = (insn >> 16) & 0xf;
1704 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1705 iwmmxt_load_reg(cpu_V0, wrd);
1706 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1707 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1708 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1709 } else { /* TMCRR */
1710 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1711 iwmmxt_store_reg(cpu_V0, wrd);
1712 gen_op_iwmmxt_set_mup();
1714 return 0;
1717 wrd = (insn >> 12) & 0xf;
1718 addr = tcg_temp_new_i32();
1719 if (gen_iwmmxt_address(s, insn, addr)) {
1720 tcg_temp_free_i32(addr);
1721 return 1;
1723 if (insn & ARM_CP_RW_BIT) {
1724 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1725 tmp = tcg_temp_new_i32();
1726 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1727 iwmmxt_store_creg(wrd, tmp);
1728 } else {
1729 i = 1;
1730 if (insn & (1 << 8)) {
1731 if (insn & (1 << 22)) { /* WLDRD */
1732 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1733 i = 0;
1734 } else { /* WLDRW wRd */
1735 tmp = tcg_temp_new_i32();
1736 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1738 } else {
1739 tmp = tcg_temp_new_i32();
1740 if (insn & (1 << 22)) { /* WLDRH */
1741 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1742 } else { /* WLDRB */
1743 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1746 if (i) {
1747 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1748 tcg_temp_free_i32(tmp);
1750 gen_op_iwmmxt_movq_wRn_M0(wrd);
1752 } else {
1753 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1754 tmp = iwmmxt_load_creg(wrd);
1755 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1756 } else {
1757 gen_op_iwmmxt_movq_M0_wRn(wrd);
1758 tmp = tcg_temp_new_i32();
1759 if (insn & (1 << 8)) {
1760 if (insn & (1 << 22)) { /* WSTRD */
1761 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1762 } else { /* WSTRW wRd */
1763 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1764 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1766 } else {
1767 if (insn & (1 << 22)) { /* WSTRH */
1768 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1769 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1770 } else { /* WSTRB */
1771 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1772 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1776 tcg_temp_free_i32(tmp);
1778 tcg_temp_free_i32(addr);
1779 return 0;
1782 if ((insn & 0x0f000000) != 0x0e000000)
1783 return 1;
1785 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1786 case 0x000: /* WOR */
1787 wrd = (insn >> 12) & 0xf;
1788 rd0 = (insn >> 0) & 0xf;
1789 rd1 = (insn >> 16) & 0xf;
1790 gen_op_iwmmxt_movq_M0_wRn(rd0);
1791 gen_op_iwmmxt_orq_M0_wRn(rd1);
1792 gen_op_iwmmxt_setpsr_nz();
1793 gen_op_iwmmxt_movq_wRn_M0(wrd);
1794 gen_op_iwmmxt_set_mup();
1795 gen_op_iwmmxt_set_cup();
1796 break;
1797 case 0x011: /* TMCR */
1798 if (insn & 0xf)
1799 return 1;
1800 rd = (insn >> 12) & 0xf;
1801 wrd = (insn >> 16) & 0xf;
1802 switch (wrd) {
1803 case ARM_IWMMXT_wCID:
1804 case ARM_IWMMXT_wCASF:
1805 break;
1806 case ARM_IWMMXT_wCon:
1807 gen_op_iwmmxt_set_cup();
1808 /* Fall through. */
1809 case ARM_IWMMXT_wCSSF:
1810 tmp = iwmmxt_load_creg(wrd);
1811 tmp2 = load_reg(s, rd);
1812 tcg_gen_andc_i32(tmp, tmp, tmp2);
1813 tcg_temp_free_i32(tmp2);
1814 iwmmxt_store_creg(wrd, tmp);
1815 break;
1816 case ARM_IWMMXT_wCGR0:
1817 case ARM_IWMMXT_wCGR1:
1818 case ARM_IWMMXT_wCGR2:
1819 case ARM_IWMMXT_wCGR3:
1820 gen_op_iwmmxt_set_cup();
1821 tmp = load_reg(s, rd);
1822 iwmmxt_store_creg(wrd, tmp);
1823 break;
1824 default:
1825 return 1;
1827 break;
1828 case 0x100: /* WXOR */
1829 wrd = (insn >> 12) & 0xf;
1830 rd0 = (insn >> 0) & 0xf;
1831 rd1 = (insn >> 16) & 0xf;
1832 gen_op_iwmmxt_movq_M0_wRn(rd0);
1833 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1834 gen_op_iwmmxt_setpsr_nz();
1835 gen_op_iwmmxt_movq_wRn_M0(wrd);
1836 gen_op_iwmmxt_set_mup();
1837 gen_op_iwmmxt_set_cup();
1838 break;
1839 case 0x111: /* TMRC */
1840 if (insn & 0xf)
1841 return 1;
1842 rd = (insn >> 12) & 0xf;
1843 wrd = (insn >> 16) & 0xf;
1844 tmp = iwmmxt_load_creg(wrd);
1845 store_reg(s, rd, tmp);
1846 break;
1847 case 0x300: /* WANDN */
1848 wrd = (insn >> 12) & 0xf;
1849 rd0 = (insn >> 0) & 0xf;
1850 rd1 = (insn >> 16) & 0xf;
1851 gen_op_iwmmxt_movq_M0_wRn(rd0);
1852 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1853 gen_op_iwmmxt_andq_M0_wRn(rd1);
1854 gen_op_iwmmxt_setpsr_nz();
1855 gen_op_iwmmxt_movq_wRn_M0(wrd);
1856 gen_op_iwmmxt_set_mup();
1857 gen_op_iwmmxt_set_cup();
1858 break;
1859 case 0x200: /* WAND */
1860 wrd = (insn >> 12) & 0xf;
1861 rd0 = (insn >> 0) & 0xf;
1862 rd1 = (insn >> 16) & 0xf;
1863 gen_op_iwmmxt_movq_M0_wRn(rd0);
1864 gen_op_iwmmxt_andq_M0_wRn(rd1);
1865 gen_op_iwmmxt_setpsr_nz();
1866 gen_op_iwmmxt_movq_wRn_M0(wrd);
1867 gen_op_iwmmxt_set_mup();
1868 gen_op_iwmmxt_set_cup();
1869 break;
1870 case 0x810: case 0xa10: /* WMADD */
1871 wrd = (insn >> 12) & 0xf;
1872 rd0 = (insn >> 0) & 0xf;
1873 rd1 = (insn >> 16) & 0xf;
1874 gen_op_iwmmxt_movq_M0_wRn(rd0);
1875 if (insn & (1 << 21))
1876 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1877 else
1878 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1879 gen_op_iwmmxt_movq_wRn_M0(wrd);
1880 gen_op_iwmmxt_set_mup();
1881 break;
1882 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1883 wrd = (insn >> 12) & 0xf;
1884 rd0 = (insn >> 16) & 0xf;
1885 rd1 = (insn >> 0) & 0xf;
1886 gen_op_iwmmxt_movq_M0_wRn(rd0);
1887 switch ((insn >> 22) & 3) {
1888 case 0:
1889 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1890 break;
1891 case 1:
1892 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1893 break;
1894 case 2:
1895 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1896 break;
1897 case 3:
1898 return 1;
1900 gen_op_iwmmxt_movq_wRn_M0(wrd);
1901 gen_op_iwmmxt_set_mup();
1902 gen_op_iwmmxt_set_cup();
1903 break;
1904 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1905 wrd = (insn >> 12) & 0xf;
1906 rd0 = (insn >> 16) & 0xf;
1907 rd1 = (insn >> 0) & 0xf;
1908 gen_op_iwmmxt_movq_M0_wRn(rd0);
1909 switch ((insn >> 22) & 3) {
1910 case 0:
1911 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1912 break;
1913 case 1:
1914 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1915 break;
1916 case 2:
1917 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1918 break;
1919 case 3:
1920 return 1;
1922 gen_op_iwmmxt_movq_wRn_M0(wrd);
1923 gen_op_iwmmxt_set_mup();
1924 gen_op_iwmmxt_set_cup();
1925 break;
1926 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1927 wrd = (insn >> 12) & 0xf;
1928 rd0 = (insn >> 16) & 0xf;
1929 rd1 = (insn >> 0) & 0xf;
1930 gen_op_iwmmxt_movq_M0_wRn(rd0);
1931 if (insn & (1 << 22))
1932 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1933 else
1934 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1935 if (!(insn & (1 << 20)))
1936 gen_op_iwmmxt_addl_M0_wRn(wrd);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd);
1938 gen_op_iwmmxt_set_mup();
1939 break;
1940 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1941 wrd = (insn >> 12) & 0xf;
1942 rd0 = (insn >> 16) & 0xf;
1943 rd1 = (insn >> 0) & 0xf;
1944 gen_op_iwmmxt_movq_M0_wRn(rd0);
1945 if (insn & (1 << 21)) {
1946 if (insn & (1 << 20))
1947 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1948 else
1949 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1950 } else {
1951 if (insn & (1 << 20))
1952 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1953 else
1954 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1956 gen_op_iwmmxt_movq_wRn_M0(wrd);
1957 gen_op_iwmmxt_set_mup();
1958 break;
1959 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1960 wrd = (insn >> 12) & 0xf;
1961 rd0 = (insn >> 16) & 0xf;
1962 rd1 = (insn >> 0) & 0xf;
1963 gen_op_iwmmxt_movq_M0_wRn(rd0);
1964 if (insn & (1 << 21))
1965 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1966 else
1967 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1968 if (!(insn & (1 << 20))) {
1969 iwmmxt_load_reg(cpu_V1, wrd);
1970 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1972 gen_op_iwmmxt_movq_wRn_M0(wrd);
1973 gen_op_iwmmxt_set_mup();
1974 break;
1975 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1976 wrd = (insn >> 12) & 0xf;
1977 rd0 = (insn >> 16) & 0xf;
1978 rd1 = (insn >> 0) & 0xf;
1979 gen_op_iwmmxt_movq_M0_wRn(rd0);
1980 switch ((insn >> 22) & 3) {
1981 case 0:
1982 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1983 break;
1984 case 1:
1985 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1986 break;
1987 case 2:
1988 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1989 break;
1990 case 3:
1991 return 1;
1993 gen_op_iwmmxt_movq_wRn_M0(wrd);
1994 gen_op_iwmmxt_set_mup();
1995 gen_op_iwmmxt_set_cup();
1996 break;
1997 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1998 wrd = (insn >> 12) & 0xf;
1999 rd0 = (insn >> 16) & 0xf;
2000 rd1 = (insn >> 0) & 0xf;
2001 gen_op_iwmmxt_movq_M0_wRn(rd0);
2002 if (insn & (1 << 22)) {
2003 if (insn & (1 << 20))
2004 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2005 else
2006 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2007 } else {
2008 if (insn & (1 << 20))
2009 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2010 else
2011 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2013 gen_op_iwmmxt_movq_wRn_M0(wrd);
2014 gen_op_iwmmxt_set_mup();
2015 gen_op_iwmmxt_set_cup();
2016 break;
2017 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2018 wrd = (insn >> 12) & 0xf;
2019 rd0 = (insn >> 16) & 0xf;
2020 rd1 = (insn >> 0) & 0xf;
2021 gen_op_iwmmxt_movq_M0_wRn(rd0);
2022 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2023 tcg_gen_andi_i32(tmp, tmp, 7);
2024 iwmmxt_load_reg(cpu_V1, rd1);
2025 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2026 tcg_temp_free_i32(tmp);
2027 gen_op_iwmmxt_movq_wRn_M0(wrd);
2028 gen_op_iwmmxt_set_mup();
2029 break;
2030 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2031 if (((insn >> 6) & 3) == 3)
2032 return 1;
2033 rd = (insn >> 12) & 0xf;
2034 wrd = (insn >> 16) & 0xf;
2035 tmp = load_reg(s, rd);
2036 gen_op_iwmmxt_movq_M0_wRn(wrd);
2037 switch ((insn >> 6) & 3) {
2038 case 0:
2039 tmp2 = tcg_const_i32(0xff);
2040 tmp3 = tcg_const_i32((insn & 7) << 3);
2041 break;
2042 case 1:
2043 tmp2 = tcg_const_i32(0xffff);
2044 tmp3 = tcg_const_i32((insn & 3) << 4);
2045 break;
2046 case 2:
2047 tmp2 = tcg_const_i32(0xffffffff);
2048 tmp3 = tcg_const_i32((insn & 1) << 5);
2049 break;
2050 default:
2051 TCGV_UNUSED_I32(tmp2);
2052 TCGV_UNUSED_I32(tmp3);
2054 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2055 tcg_temp_free_i32(tmp3);
2056 tcg_temp_free_i32(tmp2);
2057 tcg_temp_free_i32(tmp);
2058 gen_op_iwmmxt_movq_wRn_M0(wrd);
2059 gen_op_iwmmxt_set_mup();
2060 break;
2061 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2062 rd = (insn >> 12) & 0xf;
2063 wrd = (insn >> 16) & 0xf;
2064 if (rd == 15 || ((insn >> 22) & 3) == 3)
2065 return 1;
2066 gen_op_iwmmxt_movq_M0_wRn(wrd);
2067 tmp = tcg_temp_new_i32();
2068 switch ((insn >> 22) & 3) {
2069 case 0:
2070 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2071 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2072 if (insn & 8) {
2073 tcg_gen_ext8s_i32(tmp, tmp);
2074 } else {
2075 tcg_gen_andi_i32(tmp, tmp, 0xff);
2077 break;
2078 case 1:
2079 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2080 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2081 if (insn & 8) {
2082 tcg_gen_ext16s_i32(tmp, tmp);
2083 } else {
2084 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2086 break;
2087 case 2:
2088 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2089 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2090 break;
2092 store_reg(s, rd, tmp);
2093 break;
2094 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2095 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2096 return 1;
2097 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2098 switch ((insn >> 22) & 3) {
2099 case 0:
2100 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2101 break;
2102 case 1:
2103 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2104 break;
2105 case 2:
2106 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2107 break;
2109 tcg_gen_shli_i32(tmp, tmp, 28);
2110 gen_set_nzcv(tmp);
2111 tcg_temp_free_i32(tmp);
2112 break;
2113 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2114 if (((insn >> 6) & 3) == 3)
2115 return 1;
2116 rd = (insn >> 12) & 0xf;
2117 wrd = (insn >> 16) & 0xf;
2118 tmp = load_reg(s, rd);
2119 switch ((insn >> 6) & 3) {
2120 case 0:
2121 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2122 break;
2123 case 1:
2124 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2125 break;
2126 case 2:
2127 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2128 break;
2130 tcg_temp_free_i32(tmp);
2131 gen_op_iwmmxt_movq_wRn_M0(wrd);
2132 gen_op_iwmmxt_set_mup();
2133 break;
2134 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2135 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2136 return 1;
2137 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2138 tmp2 = tcg_temp_new_i32();
2139 tcg_gen_mov_i32(tmp2, tmp);
2140 switch ((insn >> 22) & 3) {
2141 case 0:
2142 for (i = 0; i < 7; i ++) {
2143 tcg_gen_shli_i32(tmp2, tmp2, 4);
2144 tcg_gen_and_i32(tmp, tmp, tmp2);
2146 break;
2147 case 1:
2148 for (i = 0; i < 3; i ++) {
2149 tcg_gen_shli_i32(tmp2, tmp2, 8);
2150 tcg_gen_and_i32(tmp, tmp, tmp2);
2152 break;
2153 case 2:
2154 tcg_gen_shli_i32(tmp2, tmp2, 16);
2155 tcg_gen_and_i32(tmp, tmp, tmp2);
2156 break;
2158 gen_set_nzcv(tmp);
2159 tcg_temp_free_i32(tmp2);
2160 tcg_temp_free_i32(tmp);
2161 break;
2162 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2163 wrd = (insn >> 12) & 0xf;
2164 rd0 = (insn >> 16) & 0xf;
2165 gen_op_iwmmxt_movq_M0_wRn(rd0);
2166 switch ((insn >> 22) & 3) {
2167 case 0:
2168 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2169 break;
2170 case 1:
2171 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2172 break;
2173 case 2:
2174 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2175 break;
2176 case 3:
2177 return 1;
2179 gen_op_iwmmxt_movq_wRn_M0(wrd);
2180 gen_op_iwmmxt_set_mup();
2181 break;
2182 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2183 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2184 return 1;
2185 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2186 tmp2 = tcg_temp_new_i32();
2187 tcg_gen_mov_i32(tmp2, tmp);
2188 switch ((insn >> 22) & 3) {
2189 case 0:
2190 for (i = 0; i < 7; i ++) {
2191 tcg_gen_shli_i32(tmp2, tmp2, 4);
2192 tcg_gen_or_i32(tmp, tmp, tmp2);
2194 break;
2195 case 1:
2196 for (i = 0; i < 3; i ++) {
2197 tcg_gen_shli_i32(tmp2, tmp2, 8);
2198 tcg_gen_or_i32(tmp, tmp, tmp2);
2200 break;
2201 case 2:
2202 tcg_gen_shli_i32(tmp2, tmp2, 16);
2203 tcg_gen_or_i32(tmp, tmp, tmp2);
2204 break;
2206 gen_set_nzcv(tmp);
2207 tcg_temp_free_i32(tmp2);
2208 tcg_temp_free_i32(tmp);
2209 break;
2210 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2211 rd = (insn >> 12) & 0xf;
2212 rd0 = (insn >> 16) & 0xf;
2213 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2214 return 1;
2215 gen_op_iwmmxt_movq_M0_wRn(rd0);
2216 tmp = tcg_temp_new_i32();
2217 switch ((insn >> 22) & 3) {
2218 case 0:
2219 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2220 break;
2221 case 1:
2222 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2223 break;
2224 case 2:
2225 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2226 break;
2228 store_reg(s, rd, tmp);
2229 break;
2230 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2231 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2232 wrd = (insn >> 12) & 0xf;
2233 rd0 = (insn >> 16) & 0xf;
2234 rd1 = (insn >> 0) & 0xf;
2235 gen_op_iwmmxt_movq_M0_wRn(rd0);
2236 switch ((insn >> 22) & 3) {
2237 case 0:
2238 if (insn & (1 << 21))
2239 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2240 else
2241 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2242 break;
2243 case 1:
2244 if (insn & (1 << 21))
2245 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2246 else
2247 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2248 break;
2249 case 2:
2250 if (insn & (1 << 21))
2251 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2252 else
2253 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2254 break;
2255 case 3:
2256 return 1;
2258 gen_op_iwmmxt_movq_wRn_M0(wrd);
2259 gen_op_iwmmxt_set_mup();
2260 gen_op_iwmmxt_set_cup();
2261 break;
2262 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2263 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2264 wrd = (insn >> 12) & 0xf;
2265 rd0 = (insn >> 16) & 0xf;
2266 gen_op_iwmmxt_movq_M0_wRn(rd0);
2267 switch ((insn >> 22) & 3) {
2268 case 0:
2269 if (insn & (1 << 21))
2270 gen_op_iwmmxt_unpacklsb_M0();
2271 else
2272 gen_op_iwmmxt_unpacklub_M0();
2273 break;
2274 case 1:
2275 if (insn & (1 << 21))
2276 gen_op_iwmmxt_unpacklsw_M0();
2277 else
2278 gen_op_iwmmxt_unpackluw_M0();
2279 break;
2280 case 2:
2281 if (insn & (1 << 21))
2282 gen_op_iwmmxt_unpacklsl_M0();
2283 else
2284 gen_op_iwmmxt_unpacklul_M0();
2285 break;
2286 case 3:
2287 return 1;
2289 gen_op_iwmmxt_movq_wRn_M0(wrd);
2290 gen_op_iwmmxt_set_mup();
2291 gen_op_iwmmxt_set_cup();
2292 break;
2293 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2294 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2295 wrd = (insn >> 12) & 0xf;
2296 rd0 = (insn >> 16) & 0xf;
2297 gen_op_iwmmxt_movq_M0_wRn(rd0);
2298 switch ((insn >> 22) & 3) {
2299 case 0:
2300 if (insn & (1 << 21))
2301 gen_op_iwmmxt_unpackhsb_M0();
2302 else
2303 gen_op_iwmmxt_unpackhub_M0();
2304 break;
2305 case 1:
2306 if (insn & (1 << 21))
2307 gen_op_iwmmxt_unpackhsw_M0();
2308 else
2309 gen_op_iwmmxt_unpackhuw_M0();
2310 break;
2311 case 2:
2312 if (insn & (1 << 21))
2313 gen_op_iwmmxt_unpackhsl_M0();
2314 else
2315 gen_op_iwmmxt_unpackhul_M0();
2316 break;
2317 case 3:
2318 return 1;
2320 gen_op_iwmmxt_movq_wRn_M0(wrd);
2321 gen_op_iwmmxt_set_mup();
2322 gen_op_iwmmxt_set_cup();
2323 break;
2324 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2325 case 0x214: case 0x614: case 0xa14: case 0xe14:
2326 if (((insn >> 22) & 3) == 0)
2327 return 1;
2328 wrd = (insn >> 12) & 0xf;
2329 rd0 = (insn >> 16) & 0xf;
2330 gen_op_iwmmxt_movq_M0_wRn(rd0);
2331 tmp = tcg_temp_new_i32();
2332 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2333 tcg_temp_free_i32(tmp);
2334 return 1;
2336 switch ((insn >> 22) & 3) {
2337 case 1:
2338 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2339 break;
2340 case 2:
2341 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2342 break;
2343 case 3:
2344 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2345 break;
2347 tcg_temp_free_i32(tmp);
2348 gen_op_iwmmxt_movq_wRn_M0(wrd);
2349 gen_op_iwmmxt_set_mup();
2350 gen_op_iwmmxt_set_cup();
2351 break;
2352 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2353 case 0x014: case 0x414: case 0x814: case 0xc14:
2354 if (((insn >> 22) & 3) == 0)
2355 return 1;
2356 wrd = (insn >> 12) & 0xf;
2357 rd0 = (insn >> 16) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0);
2359 tmp = tcg_temp_new_i32();
2360 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2361 tcg_temp_free_i32(tmp);
2362 return 1;
2364 switch ((insn >> 22) & 3) {
2365 case 1:
2366 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2367 break;
2368 case 2:
2369 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2370 break;
2371 case 3:
2372 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2373 break;
2375 tcg_temp_free_i32(tmp);
2376 gen_op_iwmmxt_movq_wRn_M0(wrd);
2377 gen_op_iwmmxt_set_mup();
2378 gen_op_iwmmxt_set_cup();
2379 break;
2380 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2381 case 0x114: case 0x514: case 0x914: case 0xd14:
2382 if (((insn >> 22) & 3) == 0)
2383 return 1;
2384 wrd = (insn >> 12) & 0xf;
2385 rd0 = (insn >> 16) & 0xf;
2386 gen_op_iwmmxt_movq_M0_wRn(rd0);
2387 tmp = tcg_temp_new_i32();
2388 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2389 tcg_temp_free_i32(tmp);
2390 return 1;
2392 switch ((insn >> 22) & 3) {
2393 case 1:
2394 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2395 break;
2396 case 2:
2397 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2398 break;
2399 case 3:
2400 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2401 break;
2403 tcg_temp_free_i32(tmp);
2404 gen_op_iwmmxt_movq_wRn_M0(wrd);
2405 gen_op_iwmmxt_set_mup();
2406 gen_op_iwmmxt_set_cup();
2407 break;
2408 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2409 case 0x314: case 0x714: case 0xb14: case 0xf14:
2410 if (((insn >> 22) & 3) == 0)
2411 return 1;
2412 wrd = (insn >> 12) & 0xf;
2413 rd0 = (insn >> 16) & 0xf;
2414 gen_op_iwmmxt_movq_M0_wRn(rd0);
2415 tmp = tcg_temp_new_i32();
2416 switch ((insn >> 22) & 3) {
2417 case 1:
2418 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2419 tcg_temp_free_i32(tmp);
2420 return 1;
2422 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2423 break;
2424 case 2:
2425 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2426 tcg_temp_free_i32(tmp);
2427 return 1;
2429 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2430 break;
2431 case 3:
2432 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2433 tcg_temp_free_i32(tmp);
2434 return 1;
2436 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2437 break;
2439 tcg_temp_free_i32(tmp);
2440 gen_op_iwmmxt_movq_wRn_M0(wrd);
2441 gen_op_iwmmxt_set_mup();
2442 gen_op_iwmmxt_set_cup();
2443 break;
2444 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2445 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2446 wrd = (insn >> 12) & 0xf;
2447 rd0 = (insn >> 16) & 0xf;
2448 rd1 = (insn >> 0) & 0xf;
2449 gen_op_iwmmxt_movq_M0_wRn(rd0);
2450 switch ((insn >> 22) & 3) {
2451 case 0:
2452 if (insn & (1 << 21))
2453 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2454 else
2455 gen_op_iwmmxt_minub_M0_wRn(rd1);
2456 break;
2457 case 1:
2458 if (insn & (1 << 21))
2459 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2460 else
2461 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2462 break;
2463 case 2:
2464 if (insn & (1 << 21))
2465 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2466 else
2467 gen_op_iwmmxt_minul_M0_wRn(rd1);
2468 break;
2469 case 3:
2470 return 1;
2472 gen_op_iwmmxt_movq_wRn_M0(wrd);
2473 gen_op_iwmmxt_set_mup();
2474 break;
2475 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2476 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2477 wrd = (insn >> 12) & 0xf;
2478 rd0 = (insn >> 16) & 0xf;
2479 rd1 = (insn >> 0) & 0xf;
2480 gen_op_iwmmxt_movq_M0_wRn(rd0);
2481 switch ((insn >> 22) & 3) {
2482 case 0:
2483 if (insn & (1 << 21))
2484 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2485 else
2486 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2487 break;
2488 case 1:
2489 if (insn & (1 << 21))
2490 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2491 else
2492 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2493 break;
2494 case 2:
2495 if (insn & (1 << 21))
2496 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2497 else
2498 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2499 break;
2500 case 3:
2501 return 1;
2503 gen_op_iwmmxt_movq_wRn_M0(wrd);
2504 gen_op_iwmmxt_set_mup();
2505 break;
2506 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2507 case 0x402: case 0x502: case 0x602: case 0x702:
2508 wrd = (insn >> 12) & 0xf;
2509 rd0 = (insn >> 16) & 0xf;
2510 rd1 = (insn >> 0) & 0xf;
2511 gen_op_iwmmxt_movq_M0_wRn(rd0);
2512 tmp = tcg_const_i32((insn >> 20) & 3);
2513 iwmmxt_load_reg(cpu_V1, rd1);
2514 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2515 tcg_temp_free_i32(tmp);
2516 gen_op_iwmmxt_movq_wRn_M0(wrd);
2517 gen_op_iwmmxt_set_mup();
2518 break;
2519 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2520 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2521 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2522 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2523 wrd = (insn >> 12) & 0xf;
2524 rd0 = (insn >> 16) & 0xf;
2525 rd1 = (insn >> 0) & 0xf;
2526 gen_op_iwmmxt_movq_M0_wRn(rd0);
2527 switch ((insn >> 20) & 0xf) {
2528 case 0x0:
2529 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2530 break;
2531 case 0x1:
2532 gen_op_iwmmxt_subub_M0_wRn(rd1);
2533 break;
2534 case 0x3:
2535 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2536 break;
2537 case 0x4:
2538 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2539 break;
2540 case 0x5:
2541 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2542 break;
2543 case 0x7:
2544 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2545 break;
2546 case 0x8:
2547 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2548 break;
2549 case 0x9:
2550 gen_op_iwmmxt_subul_M0_wRn(rd1);
2551 break;
2552 case 0xb:
2553 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2554 break;
2555 default:
2556 return 1;
2558 gen_op_iwmmxt_movq_wRn_M0(wrd);
2559 gen_op_iwmmxt_set_mup();
2560 gen_op_iwmmxt_set_cup();
2561 break;
2562 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2563 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2564 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2565 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2566 wrd = (insn >> 12) & 0xf;
2567 rd0 = (insn >> 16) & 0xf;
2568 gen_op_iwmmxt_movq_M0_wRn(rd0);
2569 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2570 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2571 tcg_temp_free_i32(tmp);
2572 gen_op_iwmmxt_movq_wRn_M0(wrd);
2573 gen_op_iwmmxt_set_mup();
2574 gen_op_iwmmxt_set_cup();
2575 break;
2576 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2577 case 0x418: case 0x518: case 0x618: case 0x718:
2578 case 0x818: case 0x918: case 0xa18: case 0xb18:
2579 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2580 wrd = (insn >> 12) & 0xf;
2581 rd0 = (insn >> 16) & 0xf;
2582 rd1 = (insn >> 0) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0);
2584 switch ((insn >> 20) & 0xf) {
2585 case 0x0:
2586 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2587 break;
2588 case 0x1:
2589 gen_op_iwmmxt_addub_M0_wRn(rd1);
2590 break;
2591 case 0x3:
2592 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2593 break;
2594 case 0x4:
2595 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2596 break;
2597 case 0x5:
2598 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2599 break;
2600 case 0x7:
2601 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2602 break;
2603 case 0x8:
2604 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2605 break;
2606 case 0x9:
2607 gen_op_iwmmxt_addul_M0_wRn(rd1);
2608 break;
2609 case 0xb:
2610 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2611 break;
2612 default:
2613 return 1;
2615 gen_op_iwmmxt_movq_wRn_M0(wrd);
2616 gen_op_iwmmxt_set_mup();
2617 gen_op_iwmmxt_set_cup();
2618 break;
2619 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2620 case 0x408: case 0x508: case 0x608: case 0x708:
2621 case 0x808: case 0x908: case 0xa08: case 0xb08:
2622 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2623 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2624 return 1;
2625 wrd = (insn >> 12) & 0xf;
2626 rd0 = (insn >> 16) & 0xf;
2627 rd1 = (insn >> 0) & 0xf;
2628 gen_op_iwmmxt_movq_M0_wRn(rd0);
2629 switch ((insn >> 22) & 3) {
2630 case 1:
2631 if (insn & (1 << 21))
2632 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2633 else
2634 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2635 break;
2636 case 2:
2637 if (insn & (1 << 21))
2638 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2639 else
2640 gen_op_iwmmxt_packul_M0_wRn(rd1);
2641 break;
2642 case 3:
2643 if (insn & (1 << 21))
2644 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2645 else
2646 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2647 break;
2649 gen_op_iwmmxt_movq_wRn_M0(wrd);
2650 gen_op_iwmmxt_set_mup();
2651 gen_op_iwmmxt_set_cup();
2652 break;
2653 case 0x201: case 0x203: case 0x205: case 0x207:
2654 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2655 case 0x211: case 0x213: case 0x215: case 0x217:
2656 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2657 wrd = (insn >> 5) & 0xf;
2658 rd0 = (insn >> 12) & 0xf;
2659 rd1 = (insn >> 0) & 0xf;
2660 if (rd0 == 0xf || rd1 == 0xf)
2661 return 1;
2662 gen_op_iwmmxt_movq_M0_wRn(wrd);
2663 tmp = load_reg(s, rd0);
2664 tmp2 = load_reg(s, rd1);
2665 switch ((insn >> 16) & 0xf) {
2666 case 0x0: /* TMIA */
2667 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2668 break;
2669 case 0x8: /* TMIAPH */
2670 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2671 break;
2672 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2673 if (insn & (1 << 16))
2674 tcg_gen_shri_i32(tmp, tmp, 16);
2675 if (insn & (1 << 17))
2676 tcg_gen_shri_i32(tmp2, tmp2, 16);
2677 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2678 break;
2679 default:
2680 tcg_temp_free_i32(tmp2);
2681 tcg_temp_free_i32(tmp);
2682 return 1;
2684 tcg_temp_free_i32(tmp2);
2685 tcg_temp_free_i32(tmp);
2686 gen_op_iwmmxt_movq_wRn_M0(wrd);
2687 gen_op_iwmmxt_set_mup();
2688 break;
2689 default:
2690 return 1;
2693 return 0;
2696 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2697 (ie. an undefined instruction). */
2698 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2700 int acc, rd0, rd1, rdhi, rdlo;
2701 TCGv_i32 tmp, tmp2;
2703 if ((insn & 0x0ff00f10) == 0x0e200010) {
2704 /* Multiply with Internal Accumulate Format */
2705 rd0 = (insn >> 12) & 0xf;
2706 rd1 = insn & 0xf;
2707 acc = (insn >> 5) & 7;
2709 if (acc != 0)
2710 return 1;
2712 tmp = load_reg(s, rd0);
2713 tmp2 = load_reg(s, rd1);
2714 switch ((insn >> 16) & 0xf) {
2715 case 0x0: /* MIA */
2716 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2717 break;
2718 case 0x8: /* MIAPH */
2719 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2720 break;
2721 case 0xc: /* MIABB */
2722 case 0xd: /* MIABT */
2723 case 0xe: /* MIATB */
2724 case 0xf: /* MIATT */
2725 if (insn & (1 << 16))
2726 tcg_gen_shri_i32(tmp, tmp, 16);
2727 if (insn & (1 << 17))
2728 tcg_gen_shri_i32(tmp2, tmp2, 16);
2729 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2730 break;
2731 default:
2732 return 1;
2734 tcg_temp_free_i32(tmp2);
2735 tcg_temp_free_i32(tmp);
2737 gen_op_iwmmxt_movq_wRn_M0(acc);
2738 return 0;
2741 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2742 /* Internal Accumulator Access Format */
2743 rdhi = (insn >> 16) & 0xf;
2744 rdlo = (insn >> 12) & 0xf;
2745 acc = insn & 7;
2747 if (acc != 0)
2748 return 1;
2750 if (insn & ARM_CP_RW_BIT) { /* MRA */
2751 iwmmxt_load_reg(cpu_V0, acc);
2752 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2753 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2754 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2755 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2756 } else { /* MAR */
2757 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2758 iwmmxt_store_reg(cpu_V0, acc);
2760 return 0;
2763 return 1;
2766 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2767 #define VFP_SREG(insn, bigbit, smallbit) \
2768 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2769 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2770 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2771 reg = (((insn) >> (bigbit)) & 0x0f) \
2772 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2773 } else { \
2774 if (insn & (1 << (smallbit))) \
2775 return 1; \
2776 reg = ((insn) >> (bigbit)) & 0x0f; \
2777 }} while (0)
2779 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2780 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2781 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2782 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2783 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2784 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2786 /* Move between integer and VFP cores. */
2787 static TCGv_i32 gen_vfp_mrs(void)
2789 TCGv_i32 tmp = tcg_temp_new_i32();
2790 tcg_gen_mov_i32(tmp, cpu_F0s);
2791 return tmp;
2794 static void gen_vfp_msr(TCGv_i32 tmp)
2796 tcg_gen_mov_i32(cpu_F0s, tmp);
2797 tcg_temp_free_i32(tmp);
2800 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2802 TCGv_i32 tmp = tcg_temp_new_i32();
2803 if (shift)
2804 tcg_gen_shri_i32(var, var, shift);
2805 tcg_gen_ext8u_i32(var, var);
2806 tcg_gen_shli_i32(tmp, var, 8);
2807 tcg_gen_or_i32(var, var, tmp);
2808 tcg_gen_shli_i32(tmp, var, 16);
2809 tcg_gen_or_i32(var, var, tmp);
2810 tcg_temp_free_i32(tmp);
2813 static void gen_neon_dup_low16(TCGv_i32 var)
2815 TCGv_i32 tmp = tcg_temp_new_i32();
2816 tcg_gen_ext16u_i32(var, var);
2817 tcg_gen_shli_i32(tmp, var, 16);
2818 tcg_gen_or_i32(var, var, tmp);
2819 tcg_temp_free_i32(tmp);
2822 static void gen_neon_dup_high16(TCGv_i32 var)
2824 TCGv_i32 tmp = tcg_temp_new_i32();
2825 tcg_gen_andi_i32(var, var, 0xffff0000);
2826 tcg_gen_shri_i32(tmp, var, 16);
2827 tcg_gen_or_i32(var, var, tmp);
2828 tcg_temp_free_i32(tmp);
2831 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2833 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2834 TCGv_i32 tmp = tcg_temp_new_i32();
2835 switch (size) {
2836 case 0:
2837 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2838 gen_neon_dup_u8(tmp, 0);
2839 break;
2840 case 1:
2841 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2842 gen_neon_dup_low16(tmp);
2843 break;
2844 case 2:
2845 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2846 break;
2847 default: /* Avoid compiler warnings. */
2848 abort();
2850 return tmp;
2853 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2854 uint32_t dp)
2856 uint32_t cc = extract32(insn, 20, 2);
2858 if (dp) {
2859 TCGv_i64 frn, frm, dest;
2860 TCGv_i64 tmp, zero, zf, nf, vf;
2862 zero = tcg_const_i64(0);
2864 frn = tcg_temp_new_i64();
2865 frm = tcg_temp_new_i64();
2866 dest = tcg_temp_new_i64();
2868 zf = tcg_temp_new_i64();
2869 nf = tcg_temp_new_i64();
2870 vf = tcg_temp_new_i64();
2872 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2873 tcg_gen_ext_i32_i64(nf, cpu_NF);
2874 tcg_gen_ext_i32_i64(vf, cpu_VF);
2876 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2877 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2878 switch (cc) {
2879 case 0: /* eq: Z */
2880 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2881 frn, frm);
2882 break;
2883 case 1: /* vs: V */
2884 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2885 frn, frm);
2886 break;
2887 case 2: /* ge: N == V -> N ^ V == 0 */
2888 tmp = tcg_temp_new_i64();
2889 tcg_gen_xor_i64(tmp, vf, nf);
2890 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2891 frn, frm);
2892 tcg_temp_free_i64(tmp);
2893 break;
2894 case 3: /* gt: !Z && N == V */
2895 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2896 frn, frm);
2897 tmp = tcg_temp_new_i64();
2898 tcg_gen_xor_i64(tmp, vf, nf);
2899 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2900 dest, frm);
2901 tcg_temp_free_i64(tmp);
2902 break;
2904 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2905 tcg_temp_free_i64(frn);
2906 tcg_temp_free_i64(frm);
2907 tcg_temp_free_i64(dest);
2909 tcg_temp_free_i64(zf);
2910 tcg_temp_free_i64(nf);
2911 tcg_temp_free_i64(vf);
2913 tcg_temp_free_i64(zero);
2914 } else {
2915 TCGv_i32 frn, frm, dest;
2916 TCGv_i32 tmp, zero;
2918 zero = tcg_const_i32(0);
2920 frn = tcg_temp_new_i32();
2921 frm = tcg_temp_new_i32();
2922 dest = tcg_temp_new_i32();
2923 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2924 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2925 switch (cc) {
2926 case 0: /* eq: Z */
2927 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2928 frn, frm);
2929 break;
2930 case 1: /* vs: V */
2931 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2932 frn, frm);
2933 break;
2934 case 2: /* ge: N == V -> N ^ V == 0 */
2935 tmp = tcg_temp_new_i32();
2936 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2937 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2938 frn, frm);
2939 tcg_temp_free_i32(tmp);
2940 break;
2941 case 3: /* gt: !Z && N == V */
2942 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2943 frn, frm);
2944 tmp = tcg_temp_new_i32();
2945 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2946 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2947 dest, frm);
2948 tcg_temp_free_i32(tmp);
2949 break;
2951 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2952 tcg_temp_free_i32(frn);
2953 tcg_temp_free_i32(frm);
2954 tcg_temp_free_i32(dest);
2956 tcg_temp_free_i32(zero);
2959 return 0;
2962 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2963 uint32_t rm, uint32_t dp)
2965 uint32_t vmin = extract32(insn, 6, 1);
2966 TCGv_ptr fpst = get_fpstatus_ptr(0);
2968 if (dp) {
2969 TCGv_i64 frn, frm, dest;
2971 frn = tcg_temp_new_i64();
2972 frm = tcg_temp_new_i64();
2973 dest = tcg_temp_new_i64();
2975 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2976 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2977 if (vmin) {
2978 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2979 } else {
2980 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2982 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2983 tcg_temp_free_i64(frn);
2984 tcg_temp_free_i64(frm);
2985 tcg_temp_free_i64(dest);
2986 } else {
2987 TCGv_i32 frn, frm, dest;
2989 frn = tcg_temp_new_i32();
2990 frm = tcg_temp_new_i32();
2991 dest = tcg_temp_new_i32();
2993 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2994 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2995 if (vmin) {
2996 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2997 } else {
2998 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3000 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3001 tcg_temp_free_i32(frn);
3002 tcg_temp_free_i32(frm);
3003 tcg_temp_free_i32(dest);
3006 tcg_temp_free_ptr(fpst);
3007 return 0;
3010 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3011 int rounding)
3013 TCGv_ptr fpst = get_fpstatus_ptr(0);
3014 TCGv_i32 tcg_rmode;
3016 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3017 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3019 if (dp) {
3020 TCGv_i64 tcg_op;
3021 TCGv_i64 tcg_res;
3022 tcg_op = tcg_temp_new_i64();
3023 tcg_res = tcg_temp_new_i64();
3024 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3025 gen_helper_rintd(tcg_res, tcg_op, fpst);
3026 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3027 tcg_temp_free_i64(tcg_op);
3028 tcg_temp_free_i64(tcg_res);
3029 } else {
3030 TCGv_i32 tcg_op;
3031 TCGv_i32 tcg_res;
3032 tcg_op = tcg_temp_new_i32();
3033 tcg_res = tcg_temp_new_i32();
3034 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3035 gen_helper_rints(tcg_res, tcg_op, fpst);
3036 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3037 tcg_temp_free_i32(tcg_op);
3038 tcg_temp_free_i32(tcg_res);
3041 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3042 tcg_temp_free_i32(tcg_rmode);
3044 tcg_temp_free_ptr(fpst);
3045 return 0;
3048 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3049 int rounding)
3051 bool is_signed = extract32(insn, 7, 1);
3052 TCGv_ptr fpst = get_fpstatus_ptr(0);
3053 TCGv_i32 tcg_rmode, tcg_shift;
3055 tcg_shift = tcg_const_i32(0);
3057 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3058 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3060 if (dp) {
3061 TCGv_i64 tcg_double, tcg_res;
3062 TCGv_i32 tcg_tmp;
3063 /* Rd is encoded as a single precision register even when the source
3064 * is double precision.
3066 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3067 tcg_double = tcg_temp_new_i64();
3068 tcg_res = tcg_temp_new_i64();
3069 tcg_tmp = tcg_temp_new_i32();
3070 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3071 if (is_signed) {
3072 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3073 } else {
3074 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3076 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3077 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3078 tcg_temp_free_i32(tcg_tmp);
3079 tcg_temp_free_i64(tcg_res);
3080 tcg_temp_free_i64(tcg_double);
3081 } else {
3082 TCGv_i32 tcg_single, tcg_res;
3083 tcg_single = tcg_temp_new_i32();
3084 tcg_res = tcg_temp_new_i32();
3085 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3086 if (is_signed) {
3087 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3088 } else {
3089 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3091 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3092 tcg_temp_free_i32(tcg_res);
3093 tcg_temp_free_i32(tcg_single);
3096 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3097 tcg_temp_free_i32(tcg_rmode);
3099 tcg_temp_free_i32(tcg_shift);
3101 tcg_temp_free_ptr(fpst);
3103 return 0;
3106 /* Table for converting the most common AArch32 encoding of
3107 * rounding mode to arm_fprounding order (which matches the
3108 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3110 static const uint8_t fp_decode_rm[] = {
3111 FPROUNDING_TIEAWAY,
3112 FPROUNDING_TIEEVEN,
3113 FPROUNDING_POSINF,
3114 FPROUNDING_NEGINF,
3117 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3119 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3121 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3122 return 1;
3125 if (dp) {
3126 VFP_DREG_D(rd, insn);
3127 VFP_DREG_N(rn, insn);
3128 VFP_DREG_M(rm, insn);
3129 } else {
3130 rd = VFP_SREG_D(insn);
3131 rn = VFP_SREG_N(insn);
3132 rm = VFP_SREG_M(insn);
3135 if ((insn & 0x0f800e50) == 0x0e000a00) {
3136 return handle_vsel(insn, rd, rn, rm, dp);
3137 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3138 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3139 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3140 /* VRINTA, VRINTN, VRINTP, VRINTM */
3141 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3142 return handle_vrint(insn, rd, rm, dp, rounding);
3143 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3144 /* VCVTA, VCVTN, VCVTP, VCVTM */
3145 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3146 return handle_vcvt(insn, rd, rm, dp, rounding);
3148 return 1;
3151 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3152 (ie. an undefined instruction). */
3153 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3155 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3156 int dp, veclen;
3157 TCGv_i32 addr;
3158 TCGv_i32 tmp;
3159 TCGv_i32 tmp2;
3161 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3162 return 1;
3165 /* FIXME: this access check should not take precedence over UNDEF
3166 * for invalid encodings; we will generate incorrect syndrome information
3167 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3169 if (s->fp_excp_el) {
3170 gen_exception_insn(s, 4, EXCP_UDEF,
3171 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3172 return 0;
3175 if (!s->vfp_enabled) {
3176 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3177 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3178 return 1;
3179 rn = (insn >> 16) & 0xf;
3180 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3181 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3182 return 1;
3186 if (extract32(insn, 28, 4) == 0xf) {
3187 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3188 * only used in v8 and above.
3190 return disas_vfp_v8_insn(s, insn);
3193 dp = ((insn & 0xf00) == 0xb00);
3194 switch ((insn >> 24) & 0xf) {
3195 case 0xe:
3196 if (insn & (1 << 4)) {
3197 /* single register transfer */
3198 rd = (insn >> 12) & 0xf;
3199 if (dp) {
3200 int size;
3201 int pass;
3203 VFP_DREG_N(rn, insn);
3204 if (insn & 0xf)
3205 return 1;
3206 if (insn & 0x00c00060
3207 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3208 return 1;
3211 pass = (insn >> 21) & 1;
3212 if (insn & (1 << 22)) {
3213 size = 0;
3214 offset = ((insn >> 5) & 3) * 8;
3215 } else if (insn & (1 << 5)) {
3216 size = 1;
3217 offset = (insn & (1 << 6)) ? 16 : 0;
3218 } else {
3219 size = 2;
3220 offset = 0;
3222 if (insn & ARM_CP_RW_BIT) {
3223 /* vfp->arm */
3224 tmp = neon_load_reg(rn, pass);
3225 switch (size) {
3226 case 0:
3227 if (offset)
3228 tcg_gen_shri_i32(tmp, tmp, offset);
3229 if (insn & (1 << 23))
3230 gen_uxtb(tmp);
3231 else
3232 gen_sxtb(tmp);
3233 break;
3234 case 1:
3235 if (insn & (1 << 23)) {
3236 if (offset) {
3237 tcg_gen_shri_i32(tmp, tmp, 16);
3238 } else {
3239 gen_uxth(tmp);
3241 } else {
3242 if (offset) {
3243 tcg_gen_sari_i32(tmp, tmp, 16);
3244 } else {
3245 gen_sxth(tmp);
3248 break;
3249 case 2:
3250 break;
3252 store_reg(s, rd, tmp);
3253 } else {
3254 /* arm->vfp */
3255 tmp = load_reg(s, rd);
3256 if (insn & (1 << 23)) {
3257 /* VDUP */
3258 if (size == 0) {
3259 gen_neon_dup_u8(tmp, 0);
3260 } else if (size == 1) {
3261 gen_neon_dup_low16(tmp);
3263 for (n = 0; n <= pass * 2; n++) {
3264 tmp2 = tcg_temp_new_i32();
3265 tcg_gen_mov_i32(tmp2, tmp);
3266 neon_store_reg(rn, n, tmp2);
3268 neon_store_reg(rn, n, tmp);
3269 } else {
3270 /* VMOV */
3271 switch (size) {
3272 case 0:
3273 tmp2 = neon_load_reg(rn, pass);
3274 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3275 tcg_temp_free_i32(tmp2);
3276 break;
3277 case 1:
3278 tmp2 = neon_load_reg(rn, pass);
3279 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3280 tcg_temp_free_i32(tmp2);
3281 break;
3282 case 2:
3283 break;
3285 neon_store_reg(rn, pass, tmp);
3288 } else { /* !dp */
3289 if ((insn & 0x6f) != 0x00)
3290 return 1;
3291 rn = VFP_SREG_N(insn);
3292 if (insn & ARM_CP_RW_BIT) {
3293 /* vfp->arm */
3294 if (insn & (1 << 21)) {
3295 /* system register */
3296 rn >>= 1;
3298 switch (rn) {
3299 case ARM_VFP_FPSID:
3300 /* VFP2 allows access to FSID from userspace.
3301 VFP3 restricts all id registers to privileged
3302 accesses. */
3303 if (IS_USER(s)
3304 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3305 return 1;
3307 tmp = load_cpu_field(vfp.xregs[rn]);
3308 break;
3309 case ARM_VFP_FPEXC:
3310 if (IS_USER(s))
3311 return 1;
3312 tmp = load_cpu_field(vfp.xregs[rn]);
3313 break;
3314 case ARM_VFP_FPINST:
3315 case ARM_VFP_FPINST2:
3316 /* Not present in VFP3. */
3317 if (IS_USER(s)
3318 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3319 return 1;
3321 tmp = load_cpu_field(vfp.xregs[rn]);
3322 break;
3323 case ARM_VFP_FPSCR:
3324 if (rd == 15) {
3325 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3326 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3327 } else {
3328 tmp = tcg_temp_new_i32();
3329 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3331 break;
3332 case ARM_VFP_MVFR2:
3333 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3334 return 1;
3336 /* fall through */
3337 case ARM_VFP_MVFR0:
3338 case ARM_VFP_MVFR1:
3339 if (IS_USER(s)
3340 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3341 return 1;
3343 tmp = load_cpu_field(vfp.xregs[rn]);
3344 break;
3345 default:
3346 return 1;
3348 } else {
3349 gen_mov_F0_vreg(0, rn);
3350 tmp = gen_vfp_mrs();
3352 if (rd == 15) {
3353 /* Set the 4 flag bits in the CPSR. */
3354 gen_set_nzcv(tmp);
3355 tcg_temp_free_i32(tmp);
3356 } else {
3357 store_reg(s, rd, tmp);
3359 } else {
3360 /* arm->vfp */
3361 if (insn & (1 << 21)) {
3362 rn >>= 1;
3363 /* system register */
3364 switch (rn) {
3365 case ARM_VFP_FPSID:
3366 case ARM_VFP_MVFR0:
3367 case ARM_VFP_MVFR1:
3368 /* Writes are ignored. */
3369 break;
3370 case ARM_VFP_FPSCR:
3371 tmp = load_reg(s, rd);
3372 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3373 tcg_temp_free_i32(tmp);
3374 gen_lookup_tb(s);
3375 break;
3376 case ARM_VFP_FPEXC:
3377 if (IS_USER(s))
3378 return 1;
3379 /* TODO: VFP subarchitecture support.
3380 * For now, keep the EN bit only */
3381 tmp = load_reg(s, rd);
3382 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3383 store_cpu_field(tmp, vfp.xregs[rn]);
3384 gen_lookup_tb(s);
3385 break;
3386 case ARM_VFP_FPINST:
3387 case ARM_VFP_FPINST2:
3388 if (IS_USER(s)) {
3389 return 1;
3391 tmp = load_reg(s, rd);
3392 store_cpu_field(tmp, vfp.xregs[rn]);
3393 break;
3394 default:
3395 return 1;
3397 } else {
3398 tmp = load_reg(s, rd);
3399 gen_vfp_msr(tmp);
3400 gen_mov_vreg_F0(0, rn);
3404 } else {
3405 /* data processing */
3406 /* The opcode is in bits 23, 21, 20 and 6. */
3407 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3408 if (dp) {
3409 if (op == 15) {
3410 /* rn is opcode */
3411 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3412 } else {
3413 /* rn is register number */
3414 VFP_DREG_N(rn, insn);
3417 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3418 ((rn & 0x1e) == 0x6))) {
3419 /* Integer or single/half precision destination. */
3420 rd = VFP_SREG_D(insn);
3421 } else {
3422 VFP_DREG_D(rd, insn);
3424 if (op == 15 &&
3425 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3426 ((rn & 0x1e) == 0x4))) {
3427 /* VCVT from int or half precision is always from S reg
3428 * regardless of dp bit. VCVT with immediate frac_bits
3429 * has same format as SREG_M.
3431 rm = VFP_SREG_M(insn);
3432 } else {
3433 VFP_DREG_M(rm, insn);
3435 } else {
3436 rn = VFP_SREG_N(insn);
3437 if (op == 15 && rn == 15) {
3438 /* Double precision destination. */
3439 VFP_DREG_D(rd, insn);
3440 } else {
3441 rd = VFP_SREG_D(insn);
3443 /* NB that we implicitly rely on the encoding for the frac_bits
3444 * in VCVT of fixed to float being the same as that of an SREG_M
3446 rm = VFP_SREG_M(insn);
3449 veclen = s->vec_len;
3450 if (op == 15 && rn > 3)
3451 veclen = 0;
3453 /* Shut up compiler warnings. */
3454 delta_m = 0;
3455 delta_d = 0;
3456 bank_mask = 0;
3458 if (veclen > 0) {
3459 if (dp)
3460 bank_mask = 0xc;
3461 else
3462 bank_mask = 0x18;
3464 /* Figure out what type of vector operation this is. */
3465 if ((rd & bank_mask) == 0) {
3466 /* scalar */
3467 veclen = 0;
3468 } else {
3469 if (dp)
3470 delta_d = (s->vec_stride >> 1) + 1;
3471 else
3472 delta_d = s->vec_stride + 1;
3474 if ((rm & bank_mask) == 0) {
3475 /* mixed scalar/vector */
3476 delta_m = 0;
3477 } else {
3478 /* vector */
3479 delta_m = delta_d;
3484 /* Load the initial operands. */
3485 if (op == 15) {
3486 switch (rn) {
3487 case 16:
3488 case 17:
3489 /* Integer source */
3490 gen_mov_F0_vreg(0, rm);
3491 break;
3492 case 8:
3493 case 9:
3494 /* Compare */
3495 gen_mov_F0_vreg(dp, rd);
3496 gen_mov_F1_vreg(dp, rm);
3497 break;
3498 case 10:
3499 case 11:
3500 /* Compare with zero */
3501 gen_mov_F0_vreg(dp, rd);
3502 gen_vfp_F1_ld0(dp);
3503 break;
3504 case 20:
3505 case 21:
3506 case 22:
3507 case 23:
3508 case 28:
3509 case 29:
3510 case 30:
3511 case 31:
3512 /* Source and destination the same. */
3513 gen_mov_F0_vreg(dp, rd);
3514 break;
3515 case 4:
3516 case 5:
3517 case 6:
3518 case 7:
3519 /* VCVTB, VCVTT: only present with the halfprec extension
3520 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3521 * (we choose to UNDEF)
3523 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3524 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3525 return 1;
3527 if (!extract32(rn, 1, 1)) {
3528 /* Half precision source. */
3529 gen_mov_F0_vreg(0, rm);
3530 break;
3532 /* Otherwise fall through */
3533 default:
3534 /* One source operand. */
3535 gen_mov_F0_vreg(dp, rm);
3536 break;
3538 } else {
3539 /* Two source operands. */
3540 gen_mov_F0_vreg(dp, rn);
3541 gen_mov_F1_vreg(dp, rm);
3544 for (;;) {
3545 /* Perform the calculation. */
3546 switch (op) {
3547 case 0: /* VMLA: fd + (fn * fm) */
3548 /* Note that order of inputs to the add matters for NaNs */
3549 gen_vfp_F1_mul(dp);
3550 gen_mov_F0_vreg(dp, rd);
3551 gen_vfp_add(dp);
3552 break;
3553 case 1: /* VMLS: fd + -(fn * fm) */
3554 gen_vfp_mul(dp);
3555 gen_vfp_F1_neg(dp);
3556 gen_mov_F0_vreg(dp, rd);
3557 gen_vfp_add(dp);
3558 break;
3559 case 2: /* VNMLS: -fd + (fn * fm) */
3560 /* Note that it isn't valid to replace (-A + B) with (B - A)
3561 * or similar plausible looking simplifications
3562 * because this will give wrong results for NaNs.
3564 gen_vfp_F1_mul(dp);
3565 gen_mov_F0_vreg(dp, rd);
3566 gen_vfp_neg(dp);
3567 gen_vfp_add(dp);
3568 break;
3569 case 3: /* VNMLA: -fd + -(fn * fm) */
3570 gen_vfp_mul(dp);
3571 gen_vfp_F1_neg(dp);
3572 gen_mov_F0_vreg(dp, rd);
3573 gen_vfp_neg(dp);
3574 gen_vfp_add(dp);
3575 break;
3576 case 4: /* mul: fn * fm */
3577 gen_vfp_mul(dp);
3578 break;
3579 case 5: /* nmul: -(fn * fm) */
3580 gen_vfp_mul(dp);
3581 gen_vfp_neg(dp);
3582 break;
3583 case 6: /* add: fn + fm */
3584 gen_vfp_add(dp);
3585 break;
3586 case 7: /* sub: fn - fm */
3587 gen_vfp_sub(dp);
3588 break;
3589 case 8: /* div: fn / fm */
3590 gen_vfp_div(dp);
3591 break;
3592 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3593 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3594 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3595 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3596 /* These are fused multiply-add, and must be done as one
3597 * floating point operation with no rounding between the
3598 * multiplication and addition steps.
3599 * NB that doing the negations here as separate steps is
3600 * correct : an input NaN should come out with its sign bit
3601 * flipped if it is a negated-input.
3603 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3604 return 1;
3606 if (dp) {
3607 TCGv_ptr fpst;
3608 TCGv_i64 frd;
3609 if (op & 1) {
3610 /* VFNMS, VFMS */
3611 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3613 frd = tcg_temp_new_i64();
3614 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3615 if (op & 2) {
3616 /* VFNMA, VFNMS */
3617 gen_helper_vfp_negd(frd, frd);
3619 fpst = get_fpstatus_ptr(0);
3620 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3621 cpu_F1d, frd, fpst);
3622 tcg_temp_free_ptr(fpst);
3623 tcg_temp_free_i64(frd);
3624 } else {
3625 TCGv_ptr fpst;
3626 TCGv_i32 frd;
3627 if (op & 1) {
3628 /* VFNMS, VFMS */
3629 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3631 frd = tcg_temp_new_i32();
3632 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3633 if (op & 2) {
3634 gen_helper_vfp_negs(frd, frd);
3636 fpst = get_fpstatus_ptr(0);
3637 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3638 cpu_F1s, frd, fpst);
3639 tcg_temp_free_ptr(fpst);
3640 tcg_temp_free_i32(frd);
3642 break;
3643 case 14: /* fconst */
3644 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3645 return 1;
3648 n = (insn << 12) & 0x80000000;
3649 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3650 if (dp) {
3651 if (i & 0x40)
3652 i |= 0x3f80;
3653 else
3654 i |= 0x4000;
3655 n |= i << 16;
3656 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3657 } else {
3658 if (i & 0x40)
3659 i |= 0x780;
3660 else
3661 i |= 0x800;
3662 n |= i << 19;
3663 tcg_gen_movi_i32(cpu_F0s, n);
3665 break;
3666 case 15: /* extension space */
3667 switch (rn) {
3668 case 0: /* cpy */
3669 /* no-op */
3670 break;
3671 case 1: /* abs */
3672 gen_vfp_abs(dp);
3673 break;
3674 case 2: /* neg */
3675 gen_vfp_neg(dp);
3676 break;
3677 case 3: /* sqrt */
3678 gen_vfp_sqrt(dp);
3679 break;
3680 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3681 tmp = gen_vfp_mrs();
3682 tcg_gen_ext16u_i32(tmp, tmp);
3683 if (dp) {
3684 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3685 cpu_env);
3686 } else {
3687 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3688 cpu_env);
3690 tcg_temp_free_i32(tmp);
3691 break;
3692 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3693 tmp = gen_vfp_mrs();
3694 tcg_gen_shri_i32(tmp, tmp, 16);
3695 if (dp) {
3696 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3697 cpu_env);
3698 } else {
3699 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3700 cpu_env);
3702 tcg_temp_free_i32(tmp);
3703 break;
3704 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3705 tmp = tcg_temp_new_i32();
3706 if (dp) {
3707 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3708 cpu_env);
3709 } else {
3710 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3711 cpu_env);
3713 gen_mov_F0_vreg(0, rd);
3714 tmp2 = gen_vfp_mrs();
3715 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3716 tcg_gen_or_i32(tmp, tmp, tmp2);
3717 tcg_temp_free_i32(tmp2);
3718 gen_vfp_msr(tmp);
3719 break;
3720 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3721 tmp = tcg_temp_new_i32();
3722 if (dp) {
3723 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3724 cpu_env);
3725 } else {
3726 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3727 cpu_env);
3729 tcg_gen_shli_i32(tmp, tmp, 16);
3730 gen_mov_F0_vreg(0, rd);
3731 tmp2 = gen_vfp_mrs();
3732 tcg_gen_ext16u_i32(tmp2, tmp2);
3733 tcg_gen_or_i32(tmp, tmp, tmp2);
3734 tcg_temp_free_i32(tmp2);
3735 gen_vfp_msr(tmp);
3736 break;
3737 case 8: /* cmp */
3738 gen_vfp_cmp(dp);
3739 break;
3740 case 9: /* cmpe */
3741 gen_vfp_cmpe(dp);
3742 break;
3743 case 10: /* cmpz */
3744 gen_vfp_cmp(dp);
3745 break;
3746 case 11: /* cmpez */
3747 gen_vfp_F1_ld0(dp);
3748 gen_vfp_cmpe(dp);
3749 break;
3750 case 12: /* vrintr */
3752 TCGv_ptr fpst = get_fpstatus_ptr(0);
3753 if (dp) {
3754 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3755 } else {
3756 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3758 tcg_temp_free_ptr(fpst);
3759 break;
3761 case 13: /* vrintz */
3763 TCGv_ptr fpst = get_fpstatus_ptr(0);
3764 TCGv_i32 tcg_rmode;
3765 tcg_rmode = tcg_const_i32(float_round_to_zero);
3766 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3767 if (dp) {
3768 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3769 } else {
3770 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3772 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3773 tcg_temp_free_i32(tcg_rmode);
3774 tcg_temp_free_ptr(fpst);
3775 break;
3777 case 14: /* vrintx */
3779 TCGv_ptr fpst = get_fpstatus_ptr(0);
3780 if (dp) {
3781 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3782 } else {
3783 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3785 tcg_temp_free_ptr(fpst);
3786 break;
3788 case 15: /* single<->double conversion */
3789 if (dp)
3790 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3791 else
3792 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3793 break;
3794 case 16: /* fuito */
3795 gen_vfp_uito(dp, 0);
3796 break;
3797 case 17: /* fsito */
3798 gen_vfp_sito(dp, 0);
3799 break;
3800 case 20: /* fshto */
3801 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3802 return 1;
3804 gen_vfp_shto(dp, 16 - rm, 0);
3805 break;
3806 case 21: /* fslto */
3807 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3808 return 1;
3810 gen_vfp_slto(dp, 32 - rm, 0);
3811 break;
3812 case 22: /* fuhto */
3813 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3814 return 1;
3816 gen_vfp_uhto(dp, 16 - rm, 0);
3817 break;
3818 case 23: /* fulto */
3819 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3820 return 1;
3822 gen_vfp_ulto(dp, 32 - rm, 0);
3823 break;
3824 case 24: /* ftoui */
3825 gen_vfp_toui(dp, 0);
3826 break;
3827 case 25: /* ftouiz */
3828 gen_vfp_touiz(dp, 0);
3829 break;
3830 case 26: /* ftosi */
3831 gen_vfp_tosi(dp, 0);
3832 break;
3833 case 27: /* ftosiz */
3834 gen_vfp_tosiz(dp, 0);
3835 break;
3836 case 28: /* ftosh */
3837 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3838 return 1;
3840 gen_vfp_tosh(dp, 16 - rm, 0);
3841 break;
3842 case 29: /* ftosl */
3843 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3844 return 1;
3846 gen_vfp_tosl(dp, 32 - rm, 0);
3847 break;
3848 case 30: /* ftouh */
3849 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3850 return 1;
3852 gen_vfp_touh(dp, 16 - rm, 0);
3853 break;
3854 case 31: /* ftoul */
3855 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3856 return 1;
3858 gen_vfp_toul(dp, 32 - rm, 0);
3859 break;
3860 default: /* undefined */
3861 return 1;
3863 break;
3864 default: /* undefined */
3865 return 1;
3868 /* Write back the result. */
3869 if (op == 15 && (rn >= 8 && rn <= 11)) {
3870 /* Comparison, do nothing. */
3871 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3872 (rn & 0x1e) == 0x6)) {
3873 /* VCVT double to int: always integer result.
3874 * VCVT double to half precision is always a single
3875 * precision result.
3877 gen_mov_vreg_F0(0, rd);
3878 } else if (op == 15 && rn == 15) {
3879 /* conversion */
3880 gen_mov_vreg_F0(!dp, rd);
3881 } else {
3882 gen_mov_vreg_F0(dp, rd);
3885 /* break out of the loop if we have finished */
3886 if (veclen == 0)
3887 break;
3889 if (op == 15 && delta_m == 0) {
3890 /* single source one-many */
3891 while (veclen--) {
3892 rd = ((rd + delta_d) & (bank_mask - 1))
3893 | (rd & bank_mask);
3894 gen_mov_vreg_F0(dp, rd);
3896 break;
3898 /* Setup the next operands. */
3899 veclen--;
3900 rd = ((rd + delta_d) & (bank_mask - 1))
3901 | (rd & bank_mask);
3903 if (op == 15) {
3904 /* One source operand. */
3905 rm = ((rm + delta_m) & (bank_mask - 1))
3906 | (rm & bank_mask);
3907 gen_mov_F0_vreg(dp, rm);
3908 } else {
3909 /* Two source operands. */
3910 rn = ((rn + delta_d) & (bank_mask - 1))
3911 | (rn & bank_mask);
3912 gen_mov_F0_vreg(dp, rn);
3913 if (delta_m) {
3914 rm = ((rm + delta_m) & (bank_mask - 1))
3915 | (rm & bank_mask);
3916 gen_mov_F1_vreg(dp, rm);
3921 break;
3922 case 0xc:
3923 case 0xd:
3924 if ((insn & 0x03e00000) == 0x00400000) {
3925 /* two-register transfer */
3926 rn = (insn >> 16) & 0xf;
3927 rd = (insn >> 12) & 0xf;
3928 if (dp) {
3929 VFP_DREG_M(rm, insn);
3930 } else {
3931 rm = VFP_SREG_M(insn);
3934 if (insn & ARM_CP_RW_BIT) {
3935 /* vfp->arm */
3936 if (dp) {
3937 gen_mov_F0_vreg(0, rm * 2);
3938 tmp = gen_vfp_mrs();
3939 store_reg(s, rd, tmp);
3940 gen_mov_F0_vreg(0, rm * 2 + 1);
3941 tmp = gen_vfp_mrs();
3942 store_reg(s, rn, tmp);
3943 } else {
3944 gen_mov_F0_vreg(0, rm);
3945 tmp = gen_vfp_mrs();
3946 store_reg(s, rd, tmp);
3947 gen_mov_F0_vreg(0, rm + 1);
3948 tmp = gen_vfp_mrs();
3949 store_reg(s, rn, tmp);
3951 } else {
3952 /* arm->vfp */
3953 if (dp) {
3954 tmp = load_reg(s, rd);
3955 gen_vfp_msr(tmp);
3956 gen_mov_vreg_F0(0, rm * 2);
3957 tmp = load_reg(s, rn);
3958 gen_vfp_msr(tmp);
3959 gen_mov_vreg_F0(0, rm * 2 + 1);
3960 } else {
3961 tmp = load_reg(s, rd);
3962 gen_vfp_msr(tmp);
3963 gen_mov_vreg_F0(0, rm);
3964 tmp = load_reg(s, rn);
3965 gen_vfp_msr(tmp);
3966 gen_mov_vreg_F0(0, rm + 1);
3969 } else {
3970 /* Load/store */
3971 rn = (insn >> 16) & 0xf;
3972 if (dp)
3973 VFP_DREG_D(rd, insn);
3974 else
3975 rd = VFP_SREG_D(insn);
3976 if ((insn & 0x01200000) == 0x01000000) {
3977 /* Single load/store */
3978 offset = (insn & 0xff) << 2;
3979 if ((insn & (1 << 23)) == 0)
3980 offset = -offset;
3981 if (s->thumb && rn == 15) {
3982 /* This is actually UNPREDICTABLE */
3983 addr = tcg_temp_new_i32();
3984 tcg_gen_movi_i32(addr, s->pc & ~2);
3985 } else {
3986 addr = load_reg(s, rn);
3988 tcg_gen_addi_i32(addr, addr, offset);
3989 if (insn & (1 << 20)) {
3990 gen_vfp_ld(s, dp, addr);
3991 gen_mov_vreg_F0(dp, rd);
3992 } else {
3993 gen_mov_F0_vreg(dp, rd);
3994 gen_vfp_st(s, dp, addr);
3996 tcg_temp_free_i32(addr);
3997 } else {
3998 /* load/store multiple */
3999 int w = insn & (1 << 21);
4000 if (dp)
4001 n = (insn >> 1) & 0x7f;
4002 else
4003 n = insn & 0xff;
4005 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4006 /* P == U , W == 1 => UNDEF */
4007 return 1;
4009 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4010 /* UNPREDICTABLE cases for bad immediates: we choose to
4011 * UNDEF to avoid generating huge numbers of TCG ops
4013 return 1;
4015 if (rn == 15 && w) {
4016 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4017 return 1;
4020 if (s->thumb && rn == 15) {
4021 /* This is actually UNPREDICTABLE */
4022 addr = tcg_temp_new_i32();
4023 tcg_gen_movi_i32(addr, s->pc & ~2);
4024 } else {
4025 addr = load_reg(s, rn);
4027 if (insn & (1 << 24)) /* pre-decrement */
4028 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4030 if (dp)
4031 offset = 8;
4032 else
4033 offset = 4;
4034 for (i = 0; i < n; i++) {
4035 if (insn & ARM_CP_RW_BIT) {
4036 /* load */
4037 gen_vfp_ld(s, dp, addr);
4038 gen_mov_vreg_F0(dp, rd + i);
4039 } else {
4040 /* store */
4041 gen_mov_F0_vreg(dp, rd + i);
4042 gen_vfp_st(s, dp, addr);
4044 tcg_gen_addi_i32(addr, addr, offset);
4046 if (w) {
4047 /* writeback */
4048 if (insn & (1 << 24))
4049 offset = -offset * n;
4050 else if (dp && (insn & 1))
4051 offset = 4;
4052 else
4053 offset = 0;
4055 if (offset != 0)
4056 tcg_gen_addi_i32(addr, addr, offset);
4057 store_reg(s, rn, addr);
4058 } else {
4059 tcg_temp_free_i32(addr);
4063 break;
4064 default:
4065 /* Should never happen. */
4066 return 1;
4068 return 0;
4071 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4073 #ifndef CONFIG_USER_ONLY
4074 return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4075 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4076 #else
4077 return true;
4078 #endif
4081 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4083 if (use_goto_tb(s, dest)) {
4084 tcg_gen_goto_tb(n);
4085 gen_set_pc_im(s, dest);
4086 tcg_gen_exit_tb((uintptr_t)s->tb + n);
4087 } else {
4088 gen_set_pc_im(s, dest);
4089 tcg_gen_exit_tb(0);
4093 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4095 if (unlikely(s->singlestep_enabled || s->ss_active)) {
4096 /* An indirect jump so that we still trigger the debug exception. */
4097 if (s->thumb)
4098 dest |= 1;
4099 gen_bx_im(s, dest);
4100 } else {
4101 gen_goto_tb(s, 0, dest);
4102 s->is_jmp = DISAS_TB_JUMP;
4106 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4108 if (x)
4109 tcg_gen_sari_i32(t0, t0, 16);
4110 else
4111 gen_sxth(t0);
4112 if (y)
4113 tcg_gen_sari_i32(t1, t1, 16);
4114 else
4115 gen_sxth(t1);
4116 tcg_gen_mul_i32(t0, t0, t1);
4119 /* Return the mask of PSR bits set by a MSR instruction. */
4120 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4122 uint32_t mask;
4124 mask = 0;
4125 if (flags & (1 << 0))
4126 mask |= 0xff;
4127 if (flags & (1 << 1))
4128 mask |= 0xff00;
4129 if (flags & (1 << 2))
4130 mask |= 0xff0000;
4131 if (flags & (1 << 3))
4132 mask |= 0xff000000;
4134 /* Mask out undefined bits. */
4135 mask &= ~CPSR_RESERVED;
4136 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4137 mask &= ~CPSR_T;
4139 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4140 mask &= ~CPSR_Q; /* V5TE in reality*/
4142 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4143 mask &= ~(CPSR_E | CPSR_GE);
4145 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4146 mask &= ~CPSR_IT;
4148 /* Mask out execution state and reserved bits. */
4149 if (!spsr) {
4150 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4152 /* Mask out privileged bits. */
4153 if (IS_USER(s))
4154 mask &= CPSR_USER;
4155 return mask;
4158 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4159 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4161 TCGv_i32 tmp;
4162 if (spsr) {
4163 /* ??? This is also undefined in system mode. */
4164 if (IS_USER(s))
4165 return 1;
4167 tmp = load_cpu_field(spsr);
4168 tcg_gen_andi_i32(tmp, tmp, ~mask);
4169 tcg_gen_andi_i32(t0, t0, mask);
4170 tcg_gen_or_i32(tmp, tmp, t0);
4171 store_cpu_field(tmp, spsr);
4172 } else {
4173 gen_set_cpsr(t0, mask);
4175 tcg_temp_free_i32(t0);
4176 gen_lookup_tb(s);
4177 return 0;
4180 /* Returns nonzero if access to the PSR is not permitted. */
4181 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4183 TCGv_i32 tmp;
4184 tmp = tcg_temp_new_i32();
4185 tcg_gen_movi_i32(tmp, val);
4186 return gen_set_psr(s, mask, spsr, tmp);
4189 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4190 int *tgtmode, int *regno)
4192 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4193 * the target mode and register number, and identify the various
4194 * unpredictable cases.
4195 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4196 * + executed in user mode
4197 * + using R15 as the src/dest register
4198 * + accessing an unimplemented register
4199 * + accessing a register that's inaccessible at current PL/security state*
4200 * + accessing a register that you could access with a different insn
4201 * We choose to UNDEF in all these cases.
4202 * Since we don't know which of the various AArch32 modes we are in
4203 * we have to defer some checks to runtime.
4204 * Accesses to Monitor mode registers from Secure EL1 (which implies
4205 * that EL3 is AArch64) must trap to EL3.
4207 * If the access checks fail this function will emit code to take
4208 * an exception and return false. Otherwise it will return true,
4209 * and set *tgtmode and *regno appropriately.
4211 int exc_target = default_exception_el(s);
4213 /* These instructions are present only in ARMv8, or in ARMv7 with the
4214 * Virtualization Extensions.
4216 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4217 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4218 goto undef;
4221 if (IS_USER(s) || rn == 15) {
4222 goto undef;
4225 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4226 * of registers into (r, sysm).
4228 if (r) {
4229 /* SPSRs for other modes */
4230 switch (sysm) {
4231 case 0xe: /* SPSR_fiq */
4232 *tgtmode = ARM_CPU_MODE_FIQ;
4233 break;
4234 case 0x10: /* SPSR_irq */
4235 *tgtmode = ARM_CPU_MODE_IRQ;
4236 break;
4237 case 0x12: /* SPSR_svc */
4238 *tgtmode = ARM_CPU_MODE_SVC;
4239 break;
4240 case 0x14: /* SPSR_abt */
4241 *tgtmode = ARM_CPU_MODE_ABT;
4242 break;
4243 case 0x16: /* SPSR_und */
4244 *tgtmode = ARM_CPU_MODE_UND;
4245 break;
4246 case 0x1c: /* SPSR_mon */
4247 *tgtmode = ARM_CPU_MODE_MON;
4248 break;
4249 case 0x1e: /* SPSR_hyp */
4250 *tgtmode = ARM_CPU_MODE_HYP;
4251 break;
4252 default: /* unallocated */
4253 goto undef;
4255 /* We arbitrarily assign SPSR a register number of 16. */
4256 *regno = 16;
4257 } else {
4258 /* general purpose registers for other modes */
4259 switch (sysm) {
4260 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4261 *tgtmode = ARM_CPU_MODE_USR;
4262 *regno = sysm + 8;
4263 break;
4264 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4265 *tgtmode = ARM_CPU_MODE_FIQ;
4266 *regno = sysm;
4267 break;
4268 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4269 *tgtmode = ARM_CPU_MODE_IRQ;
4270 *regno = sysm & 1 ? 13 : 14;
4271 break;
4272 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4273 *tgtmode = ARM_CPU_MODE_SVC;
4274 *regno = sysm & 1 ? 13 : 14;
4275 break;
4276 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4277 *tgtmode = ARM_CPU_MODE_ABT;
4278 *regno = sysm & 1 ? 13 : 14;
4279 break;
4280 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4281 *tgtmode = ARM_CPU_MODE_UND;
4282 *regno = sysm & 1 ? 13 : 14;
4283 break;
4284 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4285 *tgtmode = ARM_CPU_MODE_MON;
4286 *regno = sysm & 1 ? 13 : 14;
4287 break;
4288 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4289 *tgtmode = ARM_CPU_MODE_HYP;
4290 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4291 *regno = sysm & 1 ? 13 : 17;
4292 break;
4293 default: /* unallocated */
4294 goto undef;
4298 /* Catch the 'accessing inaccessible register' cases we can detect
4299 * at translate time.
4301 switch (*tgtmode) {
4302 case ARM_CPU_MODE_MON:
4303 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4304 goto undef;
4306 if (s->current_el == 1) {
4307 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4308 * then accesses to Mon registers trap to EL3
4310 exc_target = 3;
4311 goto undef;
4313 break;
4314 case ARM_CPU_MODE_HYP:
4315 /* Note that we can forbid accesses from EL2 here because they
4316 * must be from Hyp mode itself
4318 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4319 goto undef;
4321 break;
4322 default:
4323 break;
4326 return true;
4328 undef:
4329 /* If we get here then some access check did not pass */
4330 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4331 return false;
4334 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4336 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4337 int tgtmode = 0, regno = 0;
4339 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4340 return;
4343 /* Sync state because msr_banked() can raise exceptions */
4344 gen_set_condexec(s);
4345 gen_set_pc_im(s, s->pc - 4);
4346 tcg_reg = load_reg(s, rn);
4347 tcg_tgtmode = tcg_const_i32(tgtmode);
4348 tcg_regno = tcg_const_i32(regno);
4349 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4350 tcg_temp_free_i32(tcg_tgtmode);
4351 tcg_temp_free_i32(tcg_regno);
4352 tcg_temp_free_i32(tcg_reg);
4353 s->is_jmp = DISAS_UPDATE;
4356 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4358 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4359 int tgtmode = 0, regno = 0;
4361 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4362 return;
4365 /* Sync state because mrs_banked() can raise exceptions */
4366 gen_set_condexec(s);
4367 gen_set_pc_im(s, s->pc - 4);
4368 tcg_reg = tcg_temp_new_i32();
4369 tcg_tgtmode = tcg_const_i32(tgtmode);
4370 tcg_regno = tcg_const_i32(regno);
4371 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4372 tcg_temp_free_i32(tcg_tgtmode);
4373 tcg_temp_free_i32(tcg_regno);
4374 store_reg(s, rn, tcg_reg);
4375 s->is_jmp = DISAS_UPDATE;
4378 /* Store value to PC as for an exception return (ie don't
4379 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4380 * will do the masking based on the new value of the Thumb bit.
4382 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4384 tcg_gen_mov_i32(cpu_R[15], pc);
4385 tcg_temp_free_i32(pc);
4388 /* Generate a v6 exception return. Marks both values as dead. */
4389 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4391 store_pc_exc_ret(s, pc);
4392 /* The cpsr_write_eret helper will mask the low bits of PC
4393 * appropriately depending on the new Thumb bit, so it must
4394 * be called after storing the new PC.
4396 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4397 tcg_temp_free_i32(cpsr);
4398 s->is_jmp = DISAS_JUMP;
4401 /* Generate an old-style exception return. Marks pc as dead. */
4402 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4404 gen_rfe(s, pc, load_cpu_field(spsr));
4407 static void gen_nop_hint(DisasContext *s, int val)
4409 switch (val) {
4410 case 1: /* yield */
4411 gen_set_pc_im(s, s->pc);
4412 s->is_jmp = DISAS_YIELD;
4413 break;
4414 case 3: /* wfi */
4415 gen_set_pc_im(s, s->pc);
4416 s->is_jmp = DISAS_WFI;
4417 break;
4418 case 2: /* wfe */
4419 gen_set_pc_im(s, s->pc);
4420 s->is_jmp = DISAS_WFE;
4421 break;
4422 case 4: /* sev */
4423 case 5: /* sevl */
4424 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4425 default: /* nop */
4426 break;
4430 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4432 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4434 switch (size) {
4435 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4436 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4437 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4438 default: abort();
4442 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4444 switch (size) {
4445 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4446 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4447 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4448 default: return;
4452 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4453 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4454 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4455 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4456 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4458 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4459 switch ((size << 1) | u) { \
4460 case 0: \
4461 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4462 break; \
4463 case 1: \
4464 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4465 break; \
4466 case 2: \
4467 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4468 break; \
4469 case 3: \
4470 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4471 break; \
4472 case 4: \
4473 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4474 break; \
4475 case 5: \
4476 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4477 break; \
4478 default: return 1; \
4479 }} while (0)
4481 #define GEN_NEON_INTEGER_OP(name) do { \
4482 switch ((size << 1) | u) { \
4483 case 0: \
4484 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4485 break; \
4486 case 1: \
4487 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4488 break; \
4489 case 2: \
4490 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4491 break; \
4492 case 3: \
4493 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4494 break; \
4495 case 4: \
4496 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4497 break; \
4498 case 5: \
4499 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4500 break; \
4501 default: return 1; \
4502 }} while (0)
4504 static TCGv_i32 neon_load_scratch(int scratch)
4506 TCGv_i32 tmp = tcg_temp_new_i32();
4507 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4508 return tmp;
4511 static void neon_store_scratch(int scratch, TCGv_i32 var)
4513 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4514 tcg_temp_free_i32(var);
4517 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4519 TCGv_i32 tmp;
4520 if (size == 1) {
4521 tmp = neon_load_reg(reg & 7, reg >> 4);
4522 if (reg & 8) {
4523 gen_neon_dup_high16(tmp);
4524 } else {
4525 gen_neon_dup_low16(tmp);
4527 } else {
4528 tmp = neon_load_reg(reg & 15, reg >> 4);
4530 return tmp;
4533 static int gen_neon_unzip(int rd, int rm, int size, int q)
4535 TCGv_i32 tmp, tmp2;
4536 if (!q && size == 2) {
4537 return 1;
4539 tmp = tcg_const_i32(rd);
4540 tmp2 = tcg_const_i32(rm);
4541 if (q) {
4542 switch (size) {
4543 case 0:
4544 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4545 break;
4546 case 1:
4547 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4548 break;
4549 case 2:
4550 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4551 break;
4552 default:
4553 abort();
4555 } else {
4556 switch (size) {
4557 case 0:
4558 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4559 break;
4560 case 1:
4561 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4562 break;
4563 default:
4564 abort();
4567 tcg_temp_free_i32(tmp);
4568 tcg_temp_free_i32(tmp2);
4569 return 0;
4572 static int gen_neon_zip(int rd, int rm, int size, int q)
4574 TCGv_i32 tmp, tmp2;
4575 if (!q && size == 2) {
4576 return 1;
4578 tmp = tcg_const_i32(rd);
4579 tmp2 = tcg_const_i32(rm);
4580 if (q) {
4581 switch (size) {
4582 case 0:
4583 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4584 break;
4585 case 1:
4586 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4587 break;
4588 case 2:
4589 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4590 break;
4591 default:
4592 abort();
4594 } else {
4595 switch (size) {
4596 case 0:
4597 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4598 break;
4599 case 1:
4600 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4601 break;
4602 default:
4603 abort();
4606 tcg_temp_free_i32(tmp);
4607 tcg_temp_free_i32(tmp2);
4608 return 0;
4611 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4613 TCGv_i32 rd, tmp;
4615 rd = tcg_temp_new_i32();
4616 tmp = tcg_temp_new_i32();
4618 tcg_gen_shli_i32(rd, t0, 8);
4619 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4620 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4621 tcg_gen_or_i32(rd, rd, tmp);
4623 tcg_gen_shri_i32(t1, t1, 8);
4624 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4625 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4626 tcg_gen_or_i32(t1, t1, tmp);
4627 tcg_gen_mov_i32(t0, rd);
4629 tcg_temp_free_i32(tmp);
4630 tcg_temp_free_i32(rd);
4633 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4635 TCGv_i32 rd, tmp;
4637 rd = tcg_temp_new_i32();
4638 tmp = tcg_temp_new_i32();
4640 tcg_gen_shli_i32(rd, t0, 16);
4641 tcg_gen_andi_i32(tmp, t1, 0xffff);
4642 tcg_gen_or_i32(rd, rd, tmp);
4643 tcg_gen_shri_i32(t1, t1, 16);
4644 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4645 tcg_gen_or_i32(t1, t1, tmp);
4646 tcg_gen_mov_i32(t0, rd);
4648 tcg_temp_free_i32(tmp);
4649 tcg_temp_free_i32(rd);
4653 static struct {
4654 int nregs;
4655 int interleave;
4656 int spacing;
4657 } neon_ls_element_type[11] = {
4658 {4, 4, 1},
4659 {4, 4, 2},
4660 {4, 1, 1},
4661 {4, 2, 1},
4662 {3, 3, 1},
4663 {3, 3, 2},
4664 {3, 1, 1},
4665 {1, 1, 1},
4666 {2, 2, 1},
4667 {2, 2, 2},
4668 {2, 1, 1}
4671 /* Translate a NEON load/store element instruction. Return nonzero if the
4672 instruction is invalid. */
4673 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4675 int rd, rn, rm;
4676 int op;
4677 int nregs;
4678 int interleave;
4679 int spacing;
4680 int stride;
4681 int size;
4682 int reg;
4683 int pass;
4684 int load;
4685 int shift;
4686 int n;
4687 TCGv_i32 addr;
4688 TCGv_i32 tmp;
4689 TCGv_i32 tmp2;
4690 TCGv_i64 tmp64;
4692 /* FIXME: this access check should not take precedence over UNDEF
4693 * for invalid encodings; we will generate incorrect syndrome information
4694 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4696 if (s->fp_excp_el) {
4697 gen_exception_insn(s, 4, EXCP_UDEF,
4698 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4699 return 0;
4702 if (!s->vfp_enabled)
4703 return 1;
4704 VFP_DREG_D(rd, insn);
4705 rn = (insn >> 16) & 0xf;
4706 rm = insn & 0xf;
4707 load = (insn & (1 << 21)) != 0;
4708 if ((insn & (1 << 23)) == 0) {
4709 /* Load store all elements. */
4710 op = (insn >> 8) & 0xf;
4711 size = (insn >> 6) & 3;
4712 if (op > 10)
4713 return 1;
4714 /* Catch UNDEF cases for bad values of align field */
4715 switch (op & 0xc) {
4716 case 4:
4717 if (((insn >> 5) & 1) == 1) {
4718 return 1;
4720 break;
4721 case 8:
4722 if (((insn >> 4) & 3) == 3) {
4723 return 1;
4725 break;
4726 default:
4727 break;
4729 nregs = neon_ls_element_type[op].nregs;
4730 interleave = neon_ls_element_type[op].interleave;
4731 spacing = neon_ls_element_type[op].spacing;
4732 if (size == 3 && (interleave | spacing) != 1)
4733 return 1;
4734 addr = tcg_temp_new_i32();
4735 load_reg_var(s, addr, rn);
4736 stride = (1 << size) * interleave;
4737 for (reg = 0; reg < nregs; reg++) {
4738 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4739 load_reg_var(s, addr, rn);
4740 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4741 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4742 load_reg_var(s, addr, rn);
4743 tcg_gen_addi_i32(addr, addr, 1 << size);
4745 if (size == 3) {
4746 tmp64 = tcg_temp_new_i64();
4747 if (load) {
4748 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4749 neon_store_reg64(tmp64, rd);
4750 } else {
4751 neon_load_reg64(tmp64, rd);
4752 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4754 tcg_temp_free_i64(tmp64);
4755 tcg_gen_addi_i32(addr, addr, stride);
4756 } else {
4757 for (pass = 0; pass < 2; pass++) {
4758 if (size == 2) {
4759 if (load) {
4760 tmp = tcg_temp_new_i32();
4761 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4762 neon_store_reg(rd, pass, tmp);
4763 } else {
4764 tmp = neon_load_reg(rd, pass);
4765 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4766 tcg_temp_free_i32(tmp);
4768 tcg_gen_addi_i32(addr, addr, stride);
4769 } else if (size == 1) {
4770 if (load) {
4771 tmp = tcg_temp_new_i32();
4772 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4773 tcg_gen_addi_i32(addr, addr, stride);
4774 tmp2 = tcg_temp_new_i32();
4775 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4776 tcg_gen_addi_i32(addr, addr, stride);
4777 tcg_gen_shli_i32(tmp2, tmp2, 16);
4778 tcg_gen_or_i32(tmp, tmp, tmp2);
4779 tcg_temp_free_i32(tmp2);
4780 neon_store_reg(rd, pass, tmp);
4781 } else {
4782 tmp = neon_load_reg(rd, pass);
4783 tmp2 = tcg_temp_new_i32();
4784 tcg_gen_shri_i32(tmp2, tmp, 16);
4785 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4786 tcg_temp_free_i32(tmp);
4787 tcg_gen_addi_i32(addr, addr, stride);
4788 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4789 tcg_temp_free_i32(tmp2);
4790 tcg_gen_addi_i32(addr, addr, stride);
4792 } else /* size == 0 */ {
4793 if (load) {
4794 TCGV_UNUSED_I32(tmp2);
4795 for (n = 0; n < 4; n++) {
4796 tmp = tcg_temp_new_i32();
4797 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4798 tcg_gen_addi_i32(addr, addr, stride);
4799 if (n == 0) {
4800 tmp2 = tmp;
4801 } else {
4802 tcg_gen_shli_i32(tmp, tmp, n * 8);
4803 tcg_gen_or_i32(tmp2, tmp2, tmp);
4804 tcg_temp_free_i32(tmp);
4807 neon_store_reg(rd, pass, tmp2);
4808 } else {
4809 tmp2 = neon_load_reg(rd, pass);
4810 for (n = 0; n < 4; n++) {
4811 tmp = tcg_temp_new_i32();
4812 if (n == 0) {
4813 tcg_gen_mov_i32(tmp, tmp2);
4814 } else {
4815 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4817 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4818 tcg_temp_free_i32(tmp);
4819 tcg_gen_addi_i32(addr, addr, stride);
4821 tcg_temp_free_i32(tmp2);
4826 rd += spacing;
4828 tcg_temp_free_i32(addr);
4829 stride = nregs * 8;
4830 } else {
4831 size = (insn >> 10) & 3;
4832 if (size == 3) {
4833 /* Load single element to all lanes. */
4834 int a = (insn >> 4) & 1;
4835 if (!load) {
4836 return 1;
4838 size = (insn >> 6) & 3;
4839 nregs = ((insn >> 8) & 3) + 1;
4841 if (size == 3) {
4842 if (nregs != 4 || a == 0) {
4843 return 1;
4845 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4846 size = 2;
4848 if (nregs == 1 && a == 1 && size == 0) {
4849 return 1;
4851 if (nregs == 3 && a == 1) {
4852 return 1;
4854 addr = tcg_temp_new_i32();
4855 load_reg_var(s, addr, rn);
4856 if (nregs == 1) {
4857 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4858 tmp = gen_load_and_replicate(s, addr, size);
4859 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4860 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4861 if (insn & (1 << 5)) {
4862 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4863 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4865 tcg_temp_free_i32(tmp);
4866 } else {
4867 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4868 stride = (insn & (1 << 5)) ? 2 : 1;
4869 for (reg = 0; reg < nregs; reg++) {
4870 tmp = gen_load_and_replicate(s, addr, size);
4871 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4872 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4873 tcg_temp_free_i32(tmp);
4874 tcg_gen_addi_i32(addr, addr, 1 << size);
4875 rd += stride;
4878 tcg_temp_free_i32(addr);
4879 stride = (1 << size) * nregs;
4880 } else {
4881 /* Single element. */
4882 int idx = (insn >> 4) & 0xf;
4883 pass = (insn >> 7) & 1;
4884 switch (size) {
4885 case 0:
4886 shift = ((insn >> 5) & 3) * 8;
4887 stride = 1;
4888 break;
4889 case 1:
4890 shift = ((insn >> 6) & 1) * 16;
4891 stride = (insn & (1 << 5)) ? 2 : 1;
4892 break;
4893 case 2:
4894 shift = 0;
4895 stride = (insn & (1 << 6)) ? 2 : 1;
4896 break;
4897 default:
4898 abort();
4900 nregs = ((insn >> 8) & 3) + 1;
4901 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4902 switch (nregs) {
4903 case 1:
4904 if (((idx & (1 << size)) != 0) ||
4905 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4906 return 1;
4908 break;
4909 case 3:
4910 if ((idx & 1) != 0) {
4911 return 1;
4913 /* fall through */
4914 case 2:
4915 if (size == 2 && (idx & 2) != 0) {
4916 return 1;
4918 break;
4919 case 4:
4920 if ((size == 2) && ((idx & 3) == 3)) {
4921 return 1;
4923 break;
4924 default:
4925 abort();
4927 if ((rd + stride * (nregs - 1)) > 31) {
4928 /* Attempts to write off the end of the register file
4929 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4930 * the neon_load_reg() would write off the end of the array.
4932 return 1;
4934 addr = tcg_temp_new_i32();
4935 load_reg_var(s, addr, rn);
4936 for (reg = 0; reg < nregs; reg++) {
4937 if (load) {
4938 tmp = tcg_temp_new_i32();
4939 switch (size) {
4940 case 0:
4941 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4942 break;
4943 case 1:
4944 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4945 break;
4946 case 2:
4947 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4948 break;
4949 default: /* Avoid compiler warnings. */
4950 abort();
4952 if (size != 2) {
4953 tmp2 = neon_load_reg(rd, pass);
4954 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4955 shift, size ? 16 : 8);
4956 tcg_temp_free_i32(tmp2);
4958 neon_store_reg(rd, pass, tmp);
4959 } else { /* Store */
4960 tmp = neon_load_reg(rd, pass);
4961 if (shift)
4962 tcg_gen_shri_i32(tmp, tmp, shift);
4963 switch (size) {
4964 case 0:
4965 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4966 break;
4967 case 1:
4968 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4969 break;
4970 case 2:
4971 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4972 break;
4974 tcg_temp_free_i32(tmp);
4976 rd += stride;
4977 tcg_gen_addi_i32(addr, addr, 1 << size);
4979 tcg_temp_free_i32(addr);
4980 stride = nregs * (1 << size);
4983 if (rm != 15) {
4984 TCGv_i32 base;
4986 base = load_reg(s, rn);
4987 if (rm == 13) {
4988 tcg_gen_addi_i32(base, base, stride);
4989 } else {
4990 TCGv_i32 index;
4991 index = load_reg(s, rm);
4992 tcg_gen_add_i32(base, base, index);
4993 tcg_temp_free_i32(index);
4995 store_reg(s, rn, base);
4997 return 0;
5000 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5001 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5003 tcg_gen_and_i32(t, t, c);
5004 tcg_gen_andc_i32(f, f, c);
5005 tcg_gen_or_i32(dest, t, f);
5008 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5010 switch (size) {
5011 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5012 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5013 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5014 default: abort();
5018 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5020 switch (size) {
5021 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5022 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5023 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5024 default: abort();
5028 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5030 switch (size) {
5031 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5032 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5033 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5034 default: abort();
5038 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5040 switch (size) {
5041 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5042 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5043 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5044 default: abort();
5048 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5049 int q, int u)
5051 if (q) {
5052 if (u) {
5053 switch (size) {
5054 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5055 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5056 default: abort();
5058 } else {
5059 switch (size) {
5060 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5061 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5062 default: abort();
5065 } else {
5066 if (u) {
5067 switch (size) {
5068 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5069 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5070 default: abort();
5072 } else {
5073 switch (size) {
5074 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5075 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5076 default: abort();
5082 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5084 if (u) {
5085 switch (size) {
5086 case 0: gen_helper_neon_widen_u8(dest, src); break;
5087 case 1: gen_helper_neon_widen_u16(dest, src); break;
5088 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5089 default: abort();
5091 } else {
5092 switch (size) {
5093 case 0: gen_helper_neon_widen_s8(dest, src); break;
5094 case 1: gen_helper_neon_widen_s16(dest, src); break;
5095 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5096 default: abort();
5099 tcg_temp_free_i32(src);
5102 static inline void gen_neon_addl(int size)
5104 switch (size) {
5105 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5106 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5107 case 2: tcg_gen_add_i64(CPU_V001); break;
5108 default: abort();
5112 static inline void gen_neon_subl(int size)
5114 switch (size) {
5115 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5116 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5117 case 2: tcg_gen_sub_i64(CPU_V001); break;
5118 default: abort();
5122 static inline void gen_neon_negl(TCGv_i64 var, int size)
5124 switch (size) {
5125 case 0: gen_helper_neon_negl_u16(var, var); break;
5126 case 1: gen_helper_neon_negl_u32(var, var); break;
5127 case 2:
5128 tcg_gen_neg_i64(var, var);
5129 break;
5130 default: abort();
5134 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5136 switch (size) {
5137 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5138 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5139 default: abort();
5143 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5144 int size, int u)
5146 TCGv_i64 tmp;
5148 switch ((size << 1) | u) {
5149 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5150 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5151 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5152 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5153 case 4:
5154 tmp = gen_muls_i64_i32(a, b);
5155 tcg_gen_mov_i64(dest, tmp);
5156 tcg_temp_free_i64(tmp);
5157 break;
5158 case 5:
5159 tmp = gen_mulu_i64_i32(a, b);
5160 tcg_gen_mov_i64(dest, tmp);
5161 tcg_temp_free_i64(tmp);
5162 break;
5163 default: abort();
5166 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5167 Don't forget to clean them now. */
5168 if (size < 2) {
5169 tcg_temp_free_i32(a);
5170 tcg_temp_free_i32(b);
5174 static void gen_neon_narrow_op(int op, int u, int size,
5175 TCGv_i32 dest, TCGv_i64 src)
5177 if (op) {
5178 if (u) {
5179 gen_neon_unarrow_sats(size, dest, src);
5180 } else {
5181 gen_neon_narrow(size, dest, src);
5183 } else {
5184 if (u) {
5185 gen_neon_narrow_satu(size, dest, src);
5186 } else {
5187 gen_neon_narrow_sats(size, dest, src);
5192 /* Symbolic constants for op fields for Neon 3-register same-length.
5193 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5194 * table A7-9.
5196 #define NEON_3R_VHADD 0
5197 #define NEON_3R_VQADD 1
5198 #define NEON_3R_VRHADD 2
5199 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5200 #define NEON_3R_VHSUB 4
5201 #define NEON_3R_VQSUB 5
5202 #define NEON_3R_VCGT 6
5203 #define NEON_3R_VCGE 7
5204 #define NEON_3R_VSHL 8
5205 #define NEON_3R_VQSHL 9
5206 #define NEON_3R_VRSHL 10
5207 #define NEON_3R_VQRSHL 11
5208 #define NEON_3R_VMAX 12
5209 #define NEON_3R_VMIN 13
5210 #define NEON_3R_VABD 14
5211 #define NEON_3R_VABA 15
5212 #define NEON_3R_VADD_VSUB 16
5213 #define NEON_3R_VTST_VCEQ 17
5214 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5215 #define NEON_3R_VMUL 19
5216 #define NEON_3R_VPMAX 20
5217 #define NEON_3R_VPMIN 21
5218 #define NEON_3R_VQDMULH_VQRDMULH 22
5219 #define NEON_3R_VPADD 23
5220 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5221 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5222 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5223 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5224 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5225 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5226 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5227 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5229 static const uint8_t neon_3r_sizes[] = {
5230 [NEON_3R_VHADD] = 0x7,
5231 [NEON_3R_VQADD] = 0xf,
5232 [NEON_3R_VRHADD] = 0x7,
5233 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5234 [NEON_3R_VHSUB] = 0x7,
5235 [NEON_3R_VQSUB] = 0xf,
5236 [NEON_3R_VCGT] = 0x7,
5237 [NEON_3R_VCGE] = 0x7,
5238 [NEON_3R_VSHL] = 0xf,
5239 [NEON_3R_VQSHL] = 0xf,
5240 [NEON_3R_VRSHL] = 0xf,
5241 [NEON_3R_VQRSHL] = 0xf,
5242 [NEON_3R_VMAX] = 0x7,
5243 [NEON_3R_VMIN] = 0x7,
5244 [NEON_3R_VABD] = 0x7,
5245 [NEON_3R_VABA] = 0x7,
5246 [NEON_3R_VADD_VSUB] = 0xf,
5247 [NEON_3R_VTST_VCEQ] = 0x7,
5248 [NEON_3R_VML] = 0x7,
5249 [NEON_3R_VMUL] = 0x7,
5250 [NEON_3R_VPMAX] = 0x7,
5251 [NEON_3R_VPMIN] = 0x7,
5252 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5253 [NEON_3R_VPADD] = 0x7,
5254 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5255 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5256 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5257 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5258 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5259 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5260 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5261 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5264 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5265 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5266 * table A7-13.
5268 #define NEON_2RM_VREV64 0
5269 #define NEON_2RM_VREV32 1
5270 #define NEON_2RM_VREV16 2
5271 #define NEON_2RM_VPADDL 4
5272 #define NEON_2RM_VPADDL_U 5
5273 #define NEON_2RM_AESE 6 /* Includes AESD */
5274 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5275 #define NEON_2RM_VCLS 8
5276 #define NEON_2RM_VCLZ 9
5277 #define NEON_2RM_VCNT 10
5278 #define NEON_2RM_VMVN 11
5279 #define NEON_2RM_VPADAL 12
5280 #define NEON_2RM_VPADAL_U 13
5281 #define NEON_2RM_VQABS 14
5282 #define NEON_2RM_VQNEG 15
5283 #define NEON_2RM_VCGT0 16
5284 #define NEON_2RM_VCGE0 17
5285 #define NEON_2RM_VCEQ0 18
5286 #define NEON_2RM_VCLE0 19
5287 #define NEON_2RM_VCLT0 20
5288 #define NEON_2RM_SHA1H 21
5289 #define NEON_2RM_VABS 22
5290 #define NEON_2RM_VNEG 23
5291 #define NEON_2RM_VCGT0_F 24
5292 #define NEON_2RM_VCGE0_F 25
5293 #define NEON_2RM_VCEQ0_F 26
5294 #define NEON_2RM_VCLE0_F 27
5295 #define NEON_2RM_VCLT0_F 28
5296 #define NEON_2RM_VABS_F 30
5297 #define NEON_2RM_VNEG_F 31
5298 #define NEON_2RM_VSWP 32
5299 #define NEON_2RM_VTRN 33
5300 #define NEON_2RM_VUZP 34
5301 #define NEON_2RM_VZIP 35
5302 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5303 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5304 #define NEON_2RM_VSHLL 38
5305 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5306 #define NEON_2RM_VRINTN 40
5307 #define NEON_2RM_VRINTX 41
5308 #define NEON_2RM_VRINTA 42
5309 #define NEON_2RM_VRINTZ 43
5310 #define NEON_2RM_VCVT_F16_F32 44
5311 #define NEON_2RM_VRINTM 45
5312 #define NEON_2RM_VCVT_F32_F16 46
5313 #define NEON_2RM_VRINTP 47
5314 #define NEON_2RM_VCVTAU 48
5315 #define NEON_2RM_VCVTAS 49
5316 #define NEON_2RM_VCVTNU 50
5317 #define NEON_2RM_VCVTNS 51
5318 #define NEON_2RM_VCVTPU 52
5319 #define NEON_2RM_VCVTPS 53
5320 #define NEON_2RM_VCVTMU 54
5321 #define NEON_2RM_VCVTMS 55
5322 #define NEON_2RM_VRECPE 56
5323 #define NEON_2RM_VRSQRTE 57
5324 #define NEON_2RM_VRECPE_F 58
5325 #define NEON_2RM_VRSQRTE_F 59
5326 #define NEON_2RM_VCVT_FS 60
5327 #define NEON_2RM_VCVT_FU 61
5328 #define NEON_2RM_VCVT_SF 62
5329 #define NEON_2RM_VCVT_UF 63
5331 static int neon_2rm_is_float_op(int op)
5333 /* Return true if this neon 2reg-misc op is float-to-float */
5334 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5335 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5336 op == NEON_2RM_VRINTM ||
5337 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5338 op >= NEON_2RM_VRECPE_F);
5341 static bool neon_2rm_is_v8_op(int op)
5343 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5344 switch (op) {
5345 case NEON_2RM_VRINTN:
5346 case NEON_2RM_VRINTA:
5347 case NEON_2RM_VRINTM:
5348 case NEON_2RM_VRINTP:
5349 case NEON_2RM_VRINTZ:
5350 case NEON_2RM_VRINTX:
5351 case NEON_2RM_VCVTAU:
5352 case NEON_2RM_VCVTAS:
5353 case NEON_2RM_VCVTNU:
5354 case NEON_2RM_VCVTNS:
5355 case NEON_2RM_VCVTPU:
5356 case NEON_2RM_VCVTPS:
5357 case NEON_2RM_VCVTMU:
5358 case NEON_2RM_VCVTMS:
5359 return true;
5360 default:
5361 return false;
5365 /* Each entry in this array has bit n set if the insn allows
5366 * size value n (otherwise it will UNDEF). Since unallocated
5367 * op values will have no bits set they always UNDEF.
5369 static const uint8_t neon_2rm_sizes[] = {
5370 [NEON_2RM_VREV64] = 0x7,
5371 [NEON_2RM_VREV32] = 0x3,
5372 [NEON_2RM_VREV16] = 0x1,
5373 [NEON_2RM_VPADDL] = 0x7,
5374 [NEON_2RM_VPADDL_U] = 0x7,
5375 [NEON_2RM_AESE] = 0x1,
5376 [NEON_2RM_AESMC] = 0x1,
5377 [NEON_2RM_VCLS] = 0x7,
5378 [NEON_2RM_VCLZ] = 0x7,
5379 [NEON_2RM_VCNT] = 0x1,
5380 [NEON_2RM_VMVN] = 0x1,
5381 [NEON_2RM_VPADAL] = 0x7,
5382 [NEON_2RM_VPADAL_U] = 0x7,
5383 [NEON_2RM_VQABS] = 0x7,
5384 [NEON_2RM_VQNEG] = 0x7,
5385 [NEON_2RM_VCGT0] = 0x7,
5386 [NEON_2RM_VCGE0] = 0x7,
5387 [NEON_2RM_VCEQ0] = 0x7,
5388 [NEON_2RM_VCLE0] = 0x7,
5389 [NEON_2RM_VCLT0] = 0x7,
5390 [NEON_2RM_SHA1H] = 0x4,
5391 [NEON_2RM_VABS] = 0x7,
5392 [NEON_2RM_VNEG] = 0x7,
5393 [NEON_2RM_VCGT0_F] = 0x4,
5394 [NEON_2RM_VCGE0_F] = 0x4,
5395 [NEON_2RM_VCEQ0_F] = 0x4,
5396 [NEON_2RM_VCLE0_F] = 0x4,
5397 [NEON_2RM_VCLT0_F] = 0x4,
5398 [NEON_2RM_VABS_F] = 0x4,
5399 [NEON_2RM_VNEG_F] = 0x4,
5400 [NEON_2RM_VSWP] = 0x1,
5401 [NEON_2RM_VTRN] = 0x7,
5402 [NEON_2RM_VUZP] = 0x7,
5403 [NEON_2RM_VZIP] = 0x7,
5404 [NEON_2RM_VMOVN] = 0x7,
5405 [NEON_2RM_VQMOVN] = 0x7,
5406 [NEON_2RM_VSHLL] = 0x7,
5407 [NEON_2RM_SHA1SU1] = 0x4,
5408 [NEON_2RM_VRINTN] = 0x4,
5409 [NEON_2RM_VRINTX] = 0x4,
5410 [NEON_2RM_VRINTA] = 0x4,
5411 [NEON_2RM_VRINTZ] = 0x4,
5412 [NEON_2RM_VCVT_F16_F32] = 0x2,
5413 [NEON_2RM_VRINTM] = 0x4,
5414 [NEON_2RM_VCVT_F32_F16] = 0x2,
5415 [NEON_2RM_VRINTP] = 0x4,
5416 [NEON_2RM_VCVTAU] = 0x4,
5417 [NEON_2RM_VCVTAS] = 0x4,
5418 [NEON_2RM_VCVTNU] = 0x4,
5419 [NEON_2RM_VCVTNS] = 0x4,
5420 [NEON_2RM_VCVTPU] = 0x4,
5421 [NEON_2RM_VCVTPS] = 0x4,
5422 [NEON_2RM_VCVTMU] = 0x4,
5423 [NEON_2RM_VCVTMS] = 0x4,
5424 [NEON_2RM_VRECPE] = 0x4,
5425 [NEON_2RM_VRSQRTE] = 0x4,
5426 [NEON_2RM_VRECPE_F] = 0x4,
5427 [NEON_2RM_VRSQRTE_F] = 0x4,
5428 [NEON_2RM_VCVT_FS] = 0x4,
5429 [NEON_2RM_VCVT_FU] = 0x4,
5430 [NEON_2RM_VCVT_SF] = 0x4,
5431 [NEON_2RM_VCVT_UF] = 0x4,
5434 /* Translate a NEON data processing instruction. Return nonzero if the
5435 instruction is invalid.
5436 We process data in a mixture of 32-bit and 64-bit chunks.
5437 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5439 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5441 int op;
5442 int q;
5443 int rd, rn, rm;
5444 int size;
5445 int shift;
5446 int pass;
5447 int count;
5448 int pairwise;
5449 int u;
5450 uint32_t imm, mask;
5451 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5452 TCGv_i64 tmp64;
5454 /* FIXME: this access check should not take precedence over UNDEF
5455 * for invalid encodings; we will generate incorrect syndrome information
5456 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5458 if (s->fp_excp_el) {
5459 gen_exception_insn(s, 4, EXCP_UDEF,
5460 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5461 return 0;
5464 if (!s->vfp_enabled)
5465 return 1;
5466 q = (insn & (1 << 6)) != 0;
5467 u = (insn >> 24) & 1;
5468 VFP_DREG_D(rd, insn);
5469 VFP_DREG_N(rn, insn);
5470 VFP_DREG_M(rm, insn);
5471 size = (insn >> 20) & 3;
5472 if ((insn & (1 << 23)) == 0) {
5473 /* Three register same length. */
5474 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5475 /* Catch invalid op and bad size combinations: UNDEF */
5476 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5477 return 1;
5479 /* All insns of this form UNDEF for either this condition or the
5480 * superset of cases "Q==1"; we catch the latter later.
5482 if (q && ((rd | rn | rm) & 1)) {
5483 return 1;
5486 * The SHA-1/SHA-256 3-register instructions require special treatment
5487 * here, as their size field is overloaded as an op type selector, and
5488 * they all consume their input in a single pass.
5490 if (op == NEON_3R_SHA) {
5491 if (!q) {
5492 return 1;
5494 if (!u) { /* SHA-1 */
5495 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5496 return 1;
5498 tmp = tcg_const_i32(rd);
5499 tmp2 = tcg_const_i32(rn);
5500 tmp3 = tcg_const_i32(rm);
5501 tmp4 = tcg_const_i32(size);
5502 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5503 tcg_temp_free_i32(tmp4);
5504 } else { /* SHA-256 */
5505 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5506 return 1;
5508 tmp = tcg_const_i32(rd);
5509 tmp2 = tcg_const_i32(rn);
5510 tmp3 = tcg_const_i32(rm);
5511 switch (size) {
5512 case 0:
5513 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5514 break;
5515 case 1:
5516 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5517 break;
5518 case 2:
5519 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5520 break;
5523 tcg_temp_free_i32(tmp);
5524 tcg_temp_free_i32(tmp2);
5525 tcg_temp_free_i32(tmp3);
5526 return 0;
5528 if (size == 3 && op != NEON_3R_LOGIC) {
5529 /* 64-bit element instructions. */
5530 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5531 neon_load_reg64(cpu_V0, rn + pass);
5532 neon_load_reg64(cpu_V1, rm + pass);
5533 switch (op) {
5534 case NEON_3R_VQADD:
5535 if (u) {
5536 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5537 cpu_V0, cpu_V1);
5538 } else {
5539 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5540 cpu_V0, cpu_V1);
5542 break;
5543 case NEON_3R_VQSUB:
5544 if (u) {
5545 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5546 cpu_V0, cpu_V1);
5547 } else {
5548 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5549 cpu_V0, cpu_V1);
5551 break;
5552 case NEON_3R_VSHL:
5553 if (u) {
5554 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5555 } else {
5556 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5558 break;
5559 case NEON_3R_VQSHL:
5560 if (u) {
5561 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5562 cpu_V1, cpu_V0);
5563 } else {
5564 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5565 cpu_V1, cpu_V0);
5567 break;
5568 case NEON_3R_VRSHL:
5569 if (u) {
5570 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5571 } else {
5572 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5574 break;
5575 case NEON_3R_VQRSHL:
5576 if (u) {
5577 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5578 cpu_V1, cpu_V0);
5579 } else {
5580 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5581 cpu_V1, cpu_V0);
5583 break;
5584 case NEON_3R_VADD_VSUB:
5585 if (u) {
5586 tcg_gen_sub_i64(CPU_V001);
5587 } else {
5588 tcg_gen_add_i64(CPU_V001);
5590 break;
5591 default:
5592 abort();
5594 neon_store_reg64(cpu_V0, rd + pass);
5596 return 0;
5598 pairwise = 0;
5599 switch (op) {
5600 case NEON_3R_VSHL:
5601 case NEON_3R_VQSHL:
5602 case NEON_3R_VRSHL:
5603 case NEON_3R_VQRSHL:
5605 int rtmp;
5606 /* Shift instruction operands are reversed. */
5607 rtmp = rn;
5608 rn = rm;
5609 rm = rtmp;
5611 break;
5612 case NEON_3R_VPADD:
5613 if (u) {
5614 return 1;
5616 /* Fall through */
5617 case NEON_3R_VPMAX:
5618 case NEON_3R_VPMIN:
5619 pairwise = 1;
5620 break;
5621 case NEON_3R_FLOAT_ARITH:
5622 pairwise = (u && size < 2); /* if VPADD (float) */
5623 break;
5624 case NEON_3R_FLOAT_MINMAX:
5625 pairwise = u; /* if VPMIN/VPMAX (float) */
5626 break;
5627 case NEON_3R_FLOAT_CMP:
5628 if (!u && size) {
5629 /* no encoding for U=0 C=1x */
5630 return 1;
5632 break;
5633 case NEON_3R_FLOAT_ACMP:
5634 if (!u) {
5635 return 1;
5637 break;
5638 case NEON_3R_FLOAT_MISC:
5639 /* VMAXNM/VMINNM in ARMv8 */
5640 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5641 return 1;
5643 break;
5644 case NEON_3R_VMUL:
5645 if (u && (size != 0)) {
5646 /* UNDEF on invalid size for polynomial subcase */
5647 return 1;
5649 break;
5650 case NEON_3R_VFM:
5651 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5652 return 1;
5654 break;
5655 default:
5656 break;
5659 if (pairwise && q) {
5660 /* All the pairwise insns UNDEF if Q is set */
5661 return 1;
5664 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5666 if (pairwise) {
5667 /* Pairwise. */
5668 if (pass < 1) {
5669 tmp = neon_load_reg(rn, 0);
5670 tmp2 = neon_load_reg(rn, 1);
5671 } else {
5672 tmp = neon_load_reg(rm, 0);
5673 tmp2 = neon_load_reg(rm, 1);
5675 } else {
5676 /* Elementwise. */
5677 tmp = neon_load_reg(rn, pass);
5678 tmp2 = neon_load_reg(rm, pass);
5680 switch (op) {
5681 case NEON_3R_VHADD:
5682 GEN_NEON_INTEGER_OP(hadd);
5683 break;
5684 case NEON_3R_VQADD:
5685 GEN_NEON_INTEGER_OP_ENV(qadd);
5686 break;
5687 case NEON_3R_VRHADD:
5688 GEN_NEON_INTEGER_OP(rhadd);
5689 break;
5690 case NEON_3R_LOGIC: /* Logic ops. */
5691 switch ((u << 2) | size) {
5692 case 0: /* VAND */
5693 tcg_gen_and_i32(tmp, tmp, tmp2);
5694 break;
5695 case 1: /* BIC */
5696 tcg_gen_andc_i32(tmp, tmp, tmp2);
5697 break;
5698 case 2: /* VORR */
5699 tcg_gen_or_i32(tmp, tmp, tmp2);
5700 break;
5701 case 3: /* VORN */
5702 tcg_gen_orc_i32(tmp, tmp, tmp2);
5703 break;
5704 case 4: /* VEOR */
5705 tcg_gen_xor_i32(tmp, tmp, tmp2);
5706 break;
5707 case 5: /* VBSL */
5708 tmp3 = neon_load_reg(rd, pass);
5709 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5710 tcg_temp_free_i32(tmp3);
5711 break;
5712 case 6: /* VBIT */
5713 tmp3 = neon_load_reg(rd, pass);
5714 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5715 tcg_temp_free_i32(tmp3);
5716 break;
5717 case 7: /* VBIF */
5718 tmp3 = neon_load_reg(rd, pass);
5719 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5720 tcg_temp_free_i32(tmp3);
5721 break;
5723 break;
5724 case NEON_3R_VHSUB:
5725 GEN_NEON_INTEGER_OP(hsub);
5726 break;
5727 case NEON_3R_VQSUB:
5728 GEN_NEON_INTEGER_OP_ENV(qsub);
5729 break;
5730 case NEON_3R_VCGT:
5731 GEN_NEON_INTEGER_OP(cgt);
5732 break;
5733 case NEON_3R_VCGE:
5734 GEN_NEON_INTEGER_OP(cge);
5735 break;
5736 case NEON_3R_VSHL:
5737 GEN_NEON_INTEGER_OP(shl);
5738 break;
5739 case NEON_3R_VQSHL:
5740 GEN_NEON_INTEGER_OP_ENV(qshl);
5741 break;
5742 case NEON_3R_VRSHL:
5743 GEN_NEON_INTEGER_OP(rshl);
5744 break;
5745 case NEON_3R_VQRSHL:
5746 GEN_NEON_INTEGER_OP_ENV(qrshl);
5747 break;
5748 case NEON_3R_VMAX:
5749 GEN_NEON_INTEGER_OP(max);
5750 break;
5751 case NEON_3R_VMIN:
5752 GEN_NEON_INTEGER_OP(min);
5753 break;
5754 case NEON_3R_VABD:
5755 GEN_NEON_INTEGER_OP(abd);
5756 break;
5757 case NEON_3R_VABA:
5758 GEN_NEON_INTEGER_OP(abd);
5759 tcg_temp_free_i32(tmp2);
5760 tmp2 = neon_load_reg(rd, pass);
5761 gen_neon_add(size, tmp, tmp2);
5762 break;
5763 case NEON_3R_VADD_VSUB:
5764 if (!u) { /* VADD */
5765 gen_neon_add(size, tmp, tmp2);
5766 } else { /* VSUB */
5767 switch (size) {
5768 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5769 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5770 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5771 default: abort();
5774 break;
5775 case NEON_3R_VTST_VCEQ:
5776 if (!u) { /* VTST */
5777 switch (size) {
5778 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5779 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5780 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5781 default: abort();
5783 } else { /* VCEQ */
5784 switch (size) {
5785 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5786 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5787 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5788 default: abort();
5791 break;
5792 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5793 switch (size) {
5794 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5795 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5796 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5797 default: abort();
5799 tcg_temp_free_i32(tmp2);
5800 tmp2 = neon_load_reg(rd, pass);
5801 if (u) { /* VMLS */
5802 gen_neon_rsb(size, tmp, tmp2);
5803 } else { /* VMLA */
5804 gen_neon_add(size, tmp, tmp2);
5806 break;
5807 case NEON_3R_VMUL:
5808 if (u) { /* polynomial */
5809 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5810 } else { /* Integer */
5811 switch (size) {
5812 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5813 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5814 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5815 default: abort();
5818 break;
5819 case NEON_3R_VPMAX:
5820 GEN_NEON_INTEGER_OP(pmax);
5821 break;
5822 case NEON_3R_VPMIN:
5823 GEN_NEON_INTEGER_OP(pmin);
5824 break;
5825 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5826 if (!u) { /* VQDMULH */
5827 switch (size) {
5828 case 1:
5829 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5830 break;
5831 case 2:
5832 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5833 break;
5834 default: abort();
5836 } else { /* VQRDMULH */
5837 switch (size) {
5838 case 1:
5839 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5840 break;
5841 case 2:
5842 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5843 break;
5844 default: abort();
5847 break;
5848 case NEON_3R_VPADD:
5849 switch (size) {
5850 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5851 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5852 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5853 default: abort();
5855 break;
5856 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5858 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5859 switch ((u << 2) | size) {
5860 case 0: /* VADD */
5861 case 4: /* VPADD */
5862 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5863 break;
5864 case 2: /* VSUB */
5865 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5866 break;
5867 case 6: /* VABD */
5868 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5869 break;
5870 default:
5871 abort();
5873 tcg_temp_free_ptr(fpstatus);
5874 break;
5876 case NEON_3R_FLOAT_MULTIPLY:
5878 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5879 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5880 if (!u) {
5881 tcg_temp_free_i32(tmp2);
5882 tmp2 = neon_load_reg(rd, pass);
5883 if (size == 0) {
5884 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5885 } else {
5886 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5889 tcg_temp_free_ptr(fpstatus);
5890 break;
5892 case NEON_3R_FLOAT_CMP:
5894 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5895 if (!u) {
5896 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5897 } else {
5898 if (size == 0) {
5899 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5900 } else {
5901 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5904 tcg_temp_free_ptr(fpstatus);
5905 break;
5907 case NEON_3R_FLOAT_ACMP:
5909 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5910 if (size == 0) {
5911 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5912 } else {
5913 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5915 tcg_temp_free_ptr(fpstatus);
5916 break;
5918 case NEON_3R_FLOAT_MINMAX:
5920 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5921 if (size == 0) {
5922 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5923 } else {
5924 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5926 tcg_temp_free_ptr(fpstatus);
5927 break;
5929 case NEON_3R_FLOAT_MISC:
5930 if (u) {
5931 /* VMAXNM/VMINNM */
5932 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5933 if (size == 0) {
5934 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5935 } else {
5936 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5938 tcg_temp_free_ptr(fpstatus);
5939 } else {
5940 if (size == 0) {
5941 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5942 } else {
5943 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5946 break;
5947 case NEON_3R_VFM:
5949 /* VFMA, VFMS: fused multiply-add */
5950 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5951 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5952 if (size) {
5953 /* VFMS */
5954 gen_helper_vfp_negs(tmp, tmp);
5956 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5957 tcg_temp_free_i32(tmp3);
5958 tcg_temp_free_ptr(fpstatus);
5959 break;
5961 default:
5962 abort();
5964 tcg_temp_free_i32(tmp2);
5966 /* Save the result. For elementwise operations we can put it
5967 straight into the destination register. For pairwise operations
5968 we have to be careful to avoid clobbering the source operands. */
5969 if (pairwise && rd == rm) {
5970 neon_store_scratch(pass, tmp);
5971 } else {
5972 neon_store_reg(rd, pass, tmp);
5975 } /* for pass */
5976 if (pairwise && rd == rm) {
5977 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5978 tmp = neon_load_scratch(pass);
5979 neon_store_reg(rd, pass, tmp);
5982 /* End of 3 register same size operations. */
5983 } else if (insn & (1 << 4)) {
5984 if ((insn & 0x00380080) != 0) {
5985 /* Two registers and shift. */
5986 op = (insn >> 8) & 0xf;
5987 if (insn & (1 << 7)) {
5988 /* 64-bit shift. */
5989 if (op > 7) {
5990 return 1;
5992 size = 3;
5993 } else {
5994 size = 2;
5995 while ((insn & (1 << (size + 19))) == 0)
5996 size--;
5998 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5999 /* To avoid excessive duplication of ops we implement shift
6000 by immediate using the variable shift operations. */
6001 if (op < 8) {
6002 /* Shift by immediate:
6003 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6004 if (q && ((rd | rm) & 1)) {
6005 return 1;
6007 if (!u && (op == 4 || op == 6)) {
6008 return 1;
6010 /* Right shifts are encoded as N - shift, where N is the
6011 element size in bits. */
6012 if (op <= 4)
6013 shift = shift - (1 << (size + 3));
6014 if (size == 3) {
6015 count = q + 1;
6016 } else {
6017 count = q ? 4: 2;
6019 switch (size) {
6020 case 0:
6021 imm = (uint8_t) shift;
6022 imm |= imm << 8;
6023 imm |= imm << 16;
6024 break;
6025 case 1:
6026 imm = (uint16_t) shift;
6027 imm |= imm << 16;
6028 break;
6029 case 2:
6030 case 3:
6031 imm = shift;
6032 break;
6033 default:
6034 abort();
6037 for (pass = 0; pass < count; pass++) {
6038 if (size == 3) {
6039 neon_load_reg64(cpu_V0, rm + pass);
6040 tcg_gen_movi_i64(cpu_V1, imm);
6041 switch (op) {
6042 case 0: /* VSHR */
6043 case 1: /* VSRA */
6044 if (u)
6045 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6046 else
6047 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6048 break;
6049 case 2: /* VRSHR */
6050 case 3: /* VRSRA */
6051 if (u)
6052 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6053 else
6054 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6055 break;
6056 case 4: /* VSRI */
6057 case 5: /* VSHL, VSLI */
6058 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6059 break;
6060 case 6: /* VQSHLU */
6061 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6062 cpu_V0, cpu_V1);
6063 break;
6064 case 7: /* VQSHL */
6065 if (u) {
6066 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6067 cpu_V0, cpu_V1);
6068 } else {
6069 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6070 cpu_V0, cpu_V1);
6072 break;
6074 if (op == 1 || op == 3) {
6075 /* Accumulate. */
6076 neon_load_reg64(cpu_V1, rd + pass);
6077 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6078 } else if (op == 4 || (op == 5 && u)) {
6079 /* Insert */
6080 neon_load_reg64(cpu_V1, rd + pass);
6081 uint64_t mask;
6082 if (shift < -63 || shift > 63) {
6083 mask = 0;
6084 } else {
6085 if (op == 4) {
6086 mask = 0xffffffffffffffffull >> -shift;
6087 } else {
6088 mask = 0xffffffffffffffffull << shift;
6091 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6092 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6094 neon_store_reg64(cpu_V0, rd + pass);
6095 } else { /* size < 3 */
6096 /* Operands in T0 and T1. */
6097 tmp = neon_load_reg(rm, pass);
6098 tmp2 = tcg_temp_new_i32();
6099 tcg_gen_movi_i32(tmp2, imm);
6100 switch (op) {
6101 case 0: /* VSHR */
6102 case 1: /* VSRA */
6103 GEN_NEON_INTEGER_OP(shl);
6104 break;
6105 case 2: /* VRSHR */
6106 case 3: /* VRSRA */
6107 GEN_NEON_INTEGER_OP(rshl);
6108 break;
6109 case 4: /* VSRI */
6110 case 5: /* VSHL, VSLI */
6111 switch (size) {
6112 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6113 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6114 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6115 default: abort();
6117 break;
6118 case 6: /* VQSHLU */
6119 switch (size) {
6120 case 0:
6121 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6122 tmp, tmp2);
6123 break;
6124 case 1:
6125 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6126 tmp, tmp2);
6127 break;
6128 case 2:
6129 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6130 tmp, tmp2);
6131 break;
6132 default:
6133 abort();
6135 break;
6136 case 7: /* VQSHL */
6137 GEN_NEON_INTEGER_OP_ENV(qshl);
6138 break;
6140 tcg_temp_free_i32(tmp2);
6142 if (op == 1 || op == 3) {
6143 /* Accumulate. */
6144 tmp2 = neon_load_reg(rd, pass);
6145 gen_neon_add(size, tmp, tmp2);
6146 tcg_temp_free_i32(tmp2);
6147 } else if (op == 4 || (op == 5 && u)) {
6148 /* Insert */
6149 switch (size) {
6150 case 0:
6151 if (op == 4)
6152 mask = 0xff >> -shift;
6153 else
6154 mask = (uint8_t)(0xff << shift);
6155 mask |= mask << 8;
6156 mask |= mask << 16;
6157 break;
6158 case 1:
6159 if (op == 4)
6160 mask = 0xffff >> -shift;
6161 else
6162 mask = (uint16_t)(0xffff << shift);
6163 mask |= mask << 16;
6164 break;
6165 case 2:
6166 if (shift < -31 || shift > 31) {
6167 mask = 0;
6168 } else {
6169 if (op == 4)
6170 mask = 0xffffffffu >> -shift;
6171 else
6172 mask = 0xffffffffu << shift;
6174 break;
6175 default:
6176 abort();
6178 tmp2 = neon_load_reg(rd, pass);
6179 tcg_gen_andi_i32(tmp, tmp, mask);
6180 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6181 tcg_gen_or_i32(tmp, tmp, tmp2);
6182 tcg_temp_free_i32(tmp2);
6184 neon_store_reg(rd, pass, tmp);
6186 } /* for pass */
6187 } else if (op < 10) {
6188 /* Shift by immediate and narrow:
6189 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6190 int input_unsigned = (op == 8) ? !u : u;
6191 if (rm & 1) {
6192 return 1;
6194 shift = shift - (1 << (size + 3));
6195 size++;
6196 if (size == 3) {
6197 tmp64 = tcg_const_i64(shift);
6198 neon_load_reg64(cpu_V0, rm);
6199 neon_load_reg64(cpu_V1, rm + 1);
6200 for (pass = 0; pass < 2; pass++) {
6201 TCGv_i64 in;
6202 if (pass == 0) {
6203 in = cpu_V0;
6204 } else {
6205 in = cpu_V1;
6207 if (q) {
6208 if (input_unsigned) {
6209 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6210 } else {
6211 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6213 } else {
6214 if (input_unsigned) {
6215 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6216 } else {
6217 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6220 tmp = tcg_temp_new_i32();
6221 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6222 neon_store_reg(rd, pass, tmp);
6223 } /* for pass */
6224 tcg_temp_free_i64(tmp64);
6225 } else {
6226 if (size == 1) {
6227 imm = (uint16_t)shift;
6228 imm |= imm << 16;
6229 } else {
6230 /* size == 2 */
6231 imm = (uint32_t)shift;
6233 tmp2 = tcg_const_i32(imm);
6234 tmp4 = neon_load_reg(rm + 1, 0);
6235 tmp5 = neon_load_reg(rm + 1, 1);
6236 for (pass = 0; pass < 2; pass++) {
6237 if (pass == 0) {
6238 tmp = neon_load_reg(rm, 0);
6239 } else {
6240 tmp = tmp4;
6242 gen_neon_shift_narrow(size, tmp, tmp2, q,
6243 input_unsigned);
6244 if (pass == 0) {
6245 tmp3 = neon_load_reg(rm, 1);
6246 } else {
6247 tmp3 = tmp5;
6249 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6250 input_unsigned);
6251 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6252 tcg_temp_free_i32(tmp);
6253 tcg_temp_free_i32(tmp3);
6254 tmp = tcg_temp_new_i32();
6255 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6256 neon_store_reg(rd, pass, tmp);
6257 } /* for pass */
6258 tcg_temp_free_i32(tmp2);
6260 } else if (op == 10) {
6261 /* VSHLL, VMOVL */
6262 if (q || (rd & 1)) {
6263 return 1;
6265 tmp = neon_load_reg(rm, 0);
6266 tmp2 = neon_load_reg(rm, 1);
6267 for (pass = 0; pass < 2; pass++) {
6268 if (pass == 1)
6269 tmp = tmp2;
6271 gen_neon_widen(cpu_V0, tmp, size, u);
6273 if (shift != 0) {
6274 /* The shift is less than the width of the source
6275 type, so we can just shift the whole register. */
6276 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6277 /* Widen the result of shift: we need to clear
6278 * the potential overflow bits resulting from
6279 * left bits of the narrow input appearing as
6280 * right bits of left the neighbour narrow
6281 * input. */
6282 if (size < 2 || !u) {
6283 uint64_t imm64;
6284 if (size == 0) {
6285 imm = (0xffu >> (8 - shift));
6286 imm |= imm << 16;
6287 } else if (size == 1) {
6288 imm = 0xffff >> (16 - shift);
6289 } else {
6290 /* size == 2 */
6291 imm = 0xffffffff >> (32 - shift);
6293 if (size < 2) {
6294 imm64 = imm | (((uint64_t)imm) << 32);
6295 } else {
6296 imm64 = imm;
6298 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6301 neon_store_reg64(cpu_V0, rd + pass);
6303 } else if (op >= 14) {
6304 /* VCVT fixed-point. */
6305 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6306 return 1;
6308 /* We have already masked out the must-be-1 top bit of imm6,
6309 * hence this 32-shift where the ARM ARM has 64-imm6.
6311 shift = 32 - shift;
6312 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6313 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6314 if (!(op & 1)) {
6315 if (u)
6316 gen_vfp_ulto(0, shift, 1);
6317 else
6318 gen_vfp_slto(0, shift, 1);
6319 } else {
6320 if (u)
6321 gen_vfp_toul(0, shift, 1);
6322 else
6323 gen_vfp_tosl(0, shift, 1);
6325 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6327 } else {
6328 return 1;
6330 } else { /* (insn & 0x00380080) == 0 */
6331 int invert;
6332 if (q && (rd & 1)) {
6333 return 1;
6336 op = (insn >> 8) & 0xf;
6337 /* One register and immediate. */
6338 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6339 invert = (insn & (1 << 5)) != 0;
6340 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6341 * We choose to not special-case this and will behave as if a
6342 * valid constant encoding of 0 had been given.
6344 switch (op) {
6345 case 0: case 1:
6346 /* no-op */
6347 break;
6348 case 2: case 3:
6349 imm <<= 8;
6350 break;
6351 case 4: case 5:
6352 imm <<= 16;
6353 break;
6354 case 6: case 7:
6355 imm <<= 24;
6356 break;
6357 case 8: case 9:
6358 imm |= imm << 16;
6359 break;
6360 case 10: case 11:
6361 imm = (imm << 8) | (imm << 24);
6362 break;
6363 case 12:
6364 imm = (imm << 8) | 0xff;
6365 break;
6366 case 13:
6367 imm = (imm << 16) | 0xffff;
6368 break;
6369 case 14:
6370 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6371 if (invert)
6372 imm = ~imm;
6373 break;
6374 case 15:
6375 if (invert) {
6376 return 1;
6378 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6379 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6380 break;
6382 if (invert)
6383 imm = ~imm;
6385 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6386 if (op & 1 && op < 12) {
6387 tmp = neon_load_reg(rd, pass);
6388 if (invert) {
6389 /* The immediate value has already been inverted, so
6390 BIC becomes AND. */
6391 tcg_gen_andi_i32(tmp, tmp, imm);
6392 } else {
6393 tcg_gen_ori_i32(tmp, tmp, imm);
6395 } else {
6396 /* VMOV, VMVN. */
6397 tmp = tcg_temp_new_i32();
6398 if (op == 14 && invert) {
6399 int n;
6400 uint32_t val;
6401 val = 0;
6402 for (n = 0; n < 4; n++) {
6403 if (imm & (1 << (n + (pass & 1) * 4)))
6404 val |= 0xff << (n * 8);
6406 tcg_gen_movi_i32(tmp, val);
6407 } else {
6408 tcg_gen_movi_i32(tmp, imm);
6411 neon_store_reg(rd, pass, tmp);
6414 } else { /* (insn & 0x00800010 == 0x00800000) */
6415 if (size != 3) {
6416 op = (insn >> 8) & 0xf;
6417 if ((insn & (1 << 6)) == 0) {
6418 /* Three registers of different lengths. */
6419 int src1_wide;
6420 int src2_wide;
6421 int prewiden;
6422 /* undefreq: bit 0 : UNDEF if size == 0
6423 * bit 1 : UNDEF if size == 1
6424 * bit 2 : UNDEF if size == 2
6425 * bit 3 : UNDEF if U == 1
6426 * Note that [2:0] set implies 'always UNDEF'
6428 int undefreq;
6429 /* prewiden, src1_wide, src2_wide, undefreq */
6430 static const int neon_3reg_wide[16][4] = {
6431 {1, 0, 0, 0}, /* VADDL */
6432 {1, 1, 0, 0}, /* VADDW */
6433 {1, 0, 0, 0}, /* VSUBL */
6434 {1, 1, 0, 0}, /* VSUBW */
6435 {0, 1, 1, 0}, /* VADDHN */
6436 {0, 0, 0, 0}, /* VABAL */
6437 {0, 1, 1, 0}, /* VSUBHN */
6438 {0, 0, 0, 0}, /* VABDL */
6439 {0, 0, 0, 0}, /* VMLAL */
6440 {0, 0, 0, 9}, /* VQDMLAL */
6441 {0, 0, 0, 0}, /* VMLSL */
6442 {0, 0, 0, 9}, /* VQDMLSL */
6443 {0, 0, 0, 0}, /* Integer VMULL */
6444 {0, 0, 0, 1}, /* VQDMULL */
6445 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6446 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6449 prewiden = neon_3reg_wide[op][0];
6450 src1_wide = neon_3reg_wide[op][1];
6451 src2_wide = neon_3reg_wide[op][2];
6452 undefreq = neon_3reg_wide[op][3];
6454 if ((undefreq & (1 << size)) ||
6455 ((undefreq & 8) && u)) {
6456 return 1;
6458 if ((src1_wide && (rn & 1)) ||
6459 (src2_wide && (rm & 1)) ||
6460 (!src2_wide && (rd & 1))) {
6461 return 1;
6464 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6465 * outside the loop below as it only performs a single pass.
6467 if (op == 14 && size == 2) {
6468 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6470 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6471 return 1;
6473 tcg_rn = tcg_temp_new_i64();
6474 tcg_rm = tcg_temp_new_i64();
6475 tcg_rd = tcg_temp_new_i64();
6476 neon_load_reg64(tcg_rn, rn);
6477 neon_load_reg64(tcg_rm, rm);
6478 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6479 neon_store_reg64(tcg_rd, rd);
6480 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6481 neon_store_reg64(tcg_rd, rd + 1);
6482 tcg_temp_free_i64(tcg_rn);
6483 tcg_temp_free_i64(tcg_rm);
6484 tcg_temp_free_i64(tcg_rd);
6485 return 0;
6488 /* Avoid overlapping operands. Wide source operands are
6489 always aligned so will never overlap with wide
6490 destinations in problematic ways. */
6491 if (rd == rm && !src2_wide) {
6492 tmp = neon_load_reg(rm, 1);
6493 neon_store_scratch(2, tmp);
6494 } else if (rd == rn && !src1_wide) {
6495 tmp = neon_load_reg(rn, 1);
6496 neon_store_scratch(2, tmp);
6498 TCGV_UNUSED_I32(tmp3);
6499 for (pass = 0; pass < 2; pass++) {
6500 if (src1_wide) {
6501 neon_load_reg64(cpu_V0, rn + pass);
6502 TCGV_UNUSED_I32(tmp);
6503 } else {
6504 if (pass == 1 && rd == rn) {
6505 tmp = neon_load_scratch(2);
6506 } else {
6507 tmp = neon_load_reg(rn, pass);
6509 if (prewiden) {
6510 gen_neon_widen(cpu_V0, tmp, size, u);
6513 if (src2_wide) {
6514 neon_load_reg64(cpu_V1, rm + pass);
6515 TCGV_UNUSED_I32(tmp2);
6516 } else {
6517 if (pass == 1 && rd == rm) {
6518 tmp2 = neon_load_scratch(2);
6519 } else {
6520 tmp2 = neon_load_reg(rm, pass);
6522 if (prewiden) {
6523 gen_neon_widen(cpu_V1, tmp2, size, u);
6526 switch (op) {
6527 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6528 gen_neon_addl(size);
6529 break;
6530 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6531 gen_neon_subl(size);
6532 break;
6533 case 5: case 7: /* VABAL, VABDL */
6534 switch ((size << 1) | u) {
6535 case 0:
6536 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6537 break;
6538 case 1:
6539 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6540 break;
6541 case 2:
6542 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6543 break;
6544 case 3:
6545 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6546 break;
6547 case 4:
6548 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6549 break;
6550 case 5:
6551 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6552 break;
6553 default: abort();
6555 tcg_temp_free_i32(tmp2);
6556 tcg_temp_free_i32(tmp);
6557 break;
6558 case 8: case 9: case 10: case 11: case 12: case 13:
6559 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6560 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6561 break;
6562 case 14: /* Polynomial VMULL */
6563 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6564 tcg_temp_free_i32(tmp2);
6565 tcg_temp_free_i32(tmp);
6566 break;
6567 default: /* 15 is RESERVED: caught earlier */
6568 abort();
6570 if (op == 13) {
6571 /* VQDMULL */
6572 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6573 neon_store_reg64(cpu_V0, rd + pass);
6574 } else if (op == 5 || (op >= 8 && op <= 11)) {
6575 /* Accumulate. */
6576 neon_load_reg64(cpu_V1, rd + pass);
6577 switch (op) {
6578 case 10: /* VMLSL */
6579 gen_neon_negl(cpu_V0, size);
6580 /* Fall through */
6581 case 5: case 8: /* VABAL, VMLAL */
6582 gen_neon_addl(size);
6583 break;
6584 case 9: case 11: /* VQDMLAL, VQDMLSL */
6585 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6586 if (op == 11) {
6587 gen_neon_negl(cpu_V0, size);
6589 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6590 break;
6591 default:
6592 abort();
6594 neon_store_reg64(cpu_V0, rd + pass);
6595 } else if (op == 4 || op == 6) {
6596 /* Narrowing operation. */
6597 tmp = tcg_temp_new_i32();
6598 if (!u) {
6599 switch (size) {
6600 case 0:
6601 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6602 break;
6603 case 1:
6604 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6605 break;
6606 case 2:
6607 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6608 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6609 break;
6610 default: abort();
6612 } else {
6613 switch (size) {
6614 case 0:
6615 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6616 break;
6617 case 1:
6618 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6619 break;
6620 case 2:
6621 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6622 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6623 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6624 break;
6625 default: abort();
6628 if (pass == 0) {
6629 tmp3 = tmp;
6630 } else {
6631 neon_store_reg(rd, 0, tmp3);
6632 neon_store_reg(rd, 1, tmp);
6634 } else {
6635 /* Write back the result. */
6636 neon_store_reg64(cpu_V0, rd + pass);
6639 } else {
6640 /* Two registers and a scalar. NB that for ops of this form
6641 * the ARM ARM labels bit 24 as Q, but it is in our variable
6642 * 'u', not 'q'.
6644 if (size == 0) {
6645 return 1;
6647 switch (op) {
6648 case 1: /* Float VMLA scalar */
6649 case 5: /* Floating point VMLS scalar */
6650 case 9: /* Floating point VMUL scalar */
6651 if (size == 1) {
6652 return 1;
6654 /* fall through */
6655 case 0: /* Integer VMLA scalar */
6656 case 4: /* Integer VMLS scalar */
6657 case 8: /* Integer VMUL scalar */
6658 case 12: /* VQDMULH scalar */
6659 case 13: /* VQRDMULH scalar */
6660 if (u && ((rd | rn) & 1)) {
6661 return 1;
6663 tmp = neon_get_scalar(size, rm);
6664 neon_store_scratch(0, tmp);
6665 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6666 tmp = neon_load_scratch(0);
6667 tmp2 = neon_load_reg(rn, pass);
6668 if (op == 12) {
6669 if (size == 1) {
6670 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6671 } else {
6672 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6674 } else if (op == 13) {
6675 if (size == 1) {
6676 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6677 } else {
6678 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6680 } else if (op & 1) {
6681 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6682 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6683 tcg_temp_free_ptr(fpstatus);
6684 } else {
6685 switch (size) {
6686 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6687 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6688 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6689 default: abort();
6692 tcg_temp_free_i32(tmp2);
6693 if (op < 8) {
6694 /* Accumulate. */
6695 tmp2 = neon_load_reg(rd, pass);
6696 switch (op) {
6697 case 0:
6698 gen_neon_add(size, tmp, tmp2);
6699 break;
6700 case 1:
6702 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6703 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6704 tcg_temp_free_ptr(fpstatus);
6705 break;
6707 case 4:
6708 gen_neon_rsb(size, tmp, tmp2);
6709 break;
6710 case 5:
6712 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6713 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6714 tcg_temp_free_ptr(fpstatus);
6715 break;
6717 default:
6718 abort();
6720 tcg_temp_free_i32(tmp2);
6722 neon_store_reg(rd, pass, tmp);
6724 break;
6725 case 3: /* VQDMLAL scalar */
6726 case 7: /* VQDMLSL scalar */
6727 case 11: /* VQDMULL scalar */
6728 if (u == 1) {
6729 return 1;
6731 /* fall through */
6732 case 2: /* VMLAL sclar */
6733 case 6: /* VMLSL scalar */
6734 case 10: /* VMULL scalar */
6735 if (rd & 1) {
6736 return 1;
6738 tmp2 = neon_get_scalar(size, rm);
6739 /* We need a copy of tmp2 because gen_neon_mull
6740 * deletes it during pass 0. */
6741 tmp4 = tcg_temp_new_i32();
6742 tcg_gen_mov_i32(tmp4, tmp2);
6743 tmp3 = neon_load_reg(rn, 1);
6745 for (pass = 0; pass < 2; pass++) {
6746 if (pass == 0) {
6747 tmp = neon_load_reg(rn, 0);
6748 } else {
6749 tmp = tmp3;
6750 tmp2 = tmp4;
6752 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6753 if (op != 11) {
6754 neon_load_reg64(cpu_V1, rd + pass);
6756 switch (op) {
6757 case 6:
6758 gen_neon_negl(cpu_V0, size);
6759 /* Fall through */
6760 case 2:
6761 gen_neon_addl(size);
6762 break;
6763 case 3: case 7:
6764 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6765 if (op == 7) {
6766 gen_neon_negl(cpu_V0, size);
6768 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6769 break;
6770 case 10:
6771 /* no-op */
6772 break;
6773 case 11:
6774 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6775 break;
6776 default:
6777 abort();
6779 neon_store_reg64(cpu_V0, rd + pass);
6783 break;
6784 default: /* 14 and 15 are RESERVED */
6785 return 1;
6788 } else { /* size == 3 */
6789 if (!u) {
6790 /* Extract. */
6791 imm = (insn >> 8) & 0xf;
6793 if (imm > 7 && !q)
6794 return 1;
6796 if (q && ((rd | rn | rm) & 1)) {
6797 return 1;
6800 if (imm == 0) {
6801 neon_load_reg64(cpu_V0, rn);
6802 if (q) {
6803 neon_load_reg64(cpu_V1, rn + 1);
6805 } else if (imm == 8) {
6806 neon_load_reg64(cpu_V0, rn + 1);
6807 if (q) {
6808 neon_load_reg64(cpu_V1, rm);
6810 } else if (q) {
6811 tmp64 = tcg_temp_new_i64();
6812 if (imm < 8) {
6813 neon_load_reg64(cpu_V0, rn);
6814 neon_load_reg64(tmp64, rn + 1);
6815 } else {
6816 neon_load_reg64(cpu_V0, rn + 1);
6817 neon_load_reg64(tmp64, rm);
6819 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6820 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6821 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6822 if (imm < 8) {
6823 neon_load_reg64(cpu_V1, rm);
6824 } else {
6825 neon_load_reg64(cpu_V1, rm + 1);
6826 imm -= 8;
6828 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6829 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6830 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6831 tcg_temp_free_i64(tmp64);
6832 } else {
6833 /* BUGFIX */
6834 neon_load_reg64(cpu_V0, rn);
6835 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6836 neon_load_reg64(cpu_V1, rm);
6837 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6838 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6840 neon_store_reg64(cpu_V0, rd);
6841 if (q) {
6842 neon_store_reg64(cpu_V1, rd + 1);
6844 } else if ((insn & (1 << 11)) == 0) {
6845 /* Two register misc. */
6846 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6847 size = (insn >> 18) & 3;
6848 /* UNDEF for unknown op values and bad op-size combinations */
6849 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6850 return 1;
6852 if (neon_2rm_is_v8_op(op) &&
6853 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6854 return 1;
6856 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6857 q && ((rm | rd) & 1)) {
6858 return 1;
6860 switch (op) {
6861 case NEON_2RM_VREV64:
6862 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6863 tmp = neon_load_reg(rm, pass * 2);
6864 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6865 switch (size) {
6866 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6867 case 1: gen_swap_half(tmp); break;
6868 case 2: /* no-op */ break;
6869 default: abort();
6871 neon_store_reg(rd, pass * 2 + 1, tmp);
6872 if (size == 2) {
6873 neon_store_reg(rd, pass * 2, tmp2);
6874 } else {
6875 switch (size) {
6876 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6877 case 1: gen_swap_half(tmp2); break;
6878 default: abort();
6880 neon_store_reg(rd, pass * 2, tmp2);
6883 break;
6884 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6885 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6886 for (pass = 0; pass < q + 1; pass++) {
6887 tmp = neon_load_reg(rm, pass * 2);
6888 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6889 tmp = neon_load_reg(rm, pass * 2 + 1);
6890 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6891 switch (size) {
6892 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6893 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6894 case 2: tcg_gen_add_i64(CPU_V001); break;
6895 default: abort();
6897 if (op >= NEON_2RM_VPADAL) {
6898 /* Accumulate. */
6899 neon_load_reg64(cpu_V1, rd + pass);
6900 gen_neon_addl(size);
6902 neon_store_reg64(cpu_V0, rd + pass);
6904 break;
6905 case NEON_2RM_VTRN:
6906 if (size == 2) {
6907 int n;
6908 for (n = 0; n < (q ? 4 : 2); n += 2) {
6909 tmp = neon_load_reg(rm, n);
6910 tmp2 = neon_load_reg(rd, n + 1);
6911 neon_store_reg(rm, n, tmp2);
6912 neon_store_reg(rd, n + 1, tmp);
6914 } else {
6915 goto elementwise;
6917 break;
6918 case NEON_2RM_VUZP:
6919 if (gen_neon_unzip(rd, rm, size, q)) {
6920 return 1;
6922 break;
6923 case NEON_2RM_VZIP:
6924 if (gen_neon_zip(rd, rm, size, q)) {
6925 return 1;
6927 break;
6928 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6929 /* also VQMOVUN; op field and mnemonics don't line up */
6930 if (rm & 1) {
6931 return 1;
6933 TCGV_UNUSED_I32(tmp2);
6934 for (pass = 0; pass < 2; pass++) {
6935 neon_load_reg64(cpu_V0, rm + pass);
6936 tmp = tcg_temp_new_i32();
6937 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6938 tmp, cpu_V0);
6939 if (pass == 0) {
6940 tmp2 = tmp;
6941 } else {
6942 neon_store_reg(rd, 0, tmp2);
6943 neon_store_reg(rd, 1, tmp);
6946 break;
6947 case NEON_2RM_VSHLL:
6948 if (q || (rd & 1)) {
6949 return 1;
6951 tmp = neon_load_reg(rm, 0);
6952 tmp2 = neon_load_reg(rm, 1);
6953 for (pass = 0; pass < 2; pass++) {
6954 if (pass == 1)
6955 tmp = tmp2;
6956 gen_neon_widen(cpu_V0, tmp, size, 1);
6957 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6958 neon_store_reg64(cpu_V0, rd + pass);
6960 break;
6961 case NEON_2RM_VCVT_F16_F32:
6962 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6963 q || (rm & 1)) {
6964 return 1;
6966 tmp = tcg_temp_new_i32();
6967 tmp2 = tcg_temp_new_i32();
6968 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6969 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6970 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6971 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6972 tcg_gen_shli_i32(tmp2, tmp2, 16);
6973 tcg_gen_or_i32(tmp2, tmp2, tmp);
6974 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6975 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6976 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6977 neon_store_reg(rd, 0, tmp2);
6978 tmp2 = tcg_temp_new_i32();
6979 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6980 tcg_gen_shli_i32(tmp2, tmp2, 16);
6981 tcg_gen_or_i32(tmp2, tmp2, tmp);
6982 neon_store_reg(rd, 1, tmp2);
6983 tcg_temp_free_i32(tmp);
6984 break;
6985 case NEON_2RM_VCVT_F32_F16:
6986 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6987 q || (rd & 1)) {
6988 return 1;
6990 tmp3 = tcg_temp_new_i32();
6991 tmp = neon_load_reg(rm, 0);
6992 tmp2 = neon_load_reg(rm, 1);
6993 tcg_gen_ext16u_i32(tmp3, tmp);
6994 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6995 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6996 tcg_gen_shri_i32(tmp3, tmp, 16);
6997 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6998 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6999 tcg_temp_free_i32(tmp);
7000 tcg_gen_ext16u_i32(tmp3, tmp2);
7001 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7002 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7003 tcg_gen_shri_i32(tmp3, tmp2, 16);
7004 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7005 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7006 tcg_temp_free_i32(tmp2);
7007 tcg_temp_free_i32(tmp3);
7008 break;
7009 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7010 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7011 || ((rm | rd) & 1)) {
7012 return 1;
7014 tmp = tcg_const_i32(rd);
7015 tmp2 = tcg_const_i32(rm);
7017 /* Bit 6 is the lowest opcode bit; it distinguishes between
7018 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7020 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7022 if (op == NEON_2RM_AESE) {
7023 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
7024 } else {
7025 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
7027 tcg_temp_free_i32(tmp);
7028 tcg_temp_free_i32(tmp2);
7029 tcg_temp_free_i32(tmp3);
7030 break;
7031 case NEON_2RM_SHA1H:
7032 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7033 || ((rm | rd) & 1)) {
7034 return 1;
7036 tmp = tcg_const_i32(rd);
7037 tmp2 = tcg_const_i32(rm);
7039 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
7041 tcg_temp_free_i32(tmp);
7042 tcg_temp_free_i32(tmp2);
7043 break;
7044 case NEON_2RM_SHA1SU1:
7045 if ((rm | rd) & 1) {
7046 return 1;
7048 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7049 if (q) {
7050 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7051 return 1;
7053 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7054 return 1;
7056 tmp = tcg_const_i32(rd);
7057 tmp2 = tcg_const_i32(rm);
7058 if (q) {
7059 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7060 } else {
7061 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7063 tcg_temp_free_i32(tmp);
7064 tcg_temp_free_i32(tmp2);
7065 break;
7066 default:
7067 elementwise:
7068 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7069 if (neon_2rm_is_float_op(op)) {
7070 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7071 neon_reg_offset(rm, pass));
7072 TCGV_UNUSED_I32(tmp);
7073 } else {
7074 tmp = neon_load_reg(rm, pass);
7076 switch (op) {
7077 case NEON_2RM_VREV32:
7078 switch (size) {
7079 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7080 case 1: gen_swap_half(tmp); break;
7081 default: abort();
7083 break;
7084 case NEON_2RM_VREV16:
7085 gen_rev16(tmp);
7086 break;
7087 case NEON_2RM_VCLS:
7088 switch (size) {
7089 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7090 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7091 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7092 default: abort();
7094 break;
7095 case NEON_2RM_VCLZ:
7096 switch (size) {
7097 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7098 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7099 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7100 default: abort();
7102 break;
7103 case NEON_2RM_VCNT:
7104 gen_helper_neon_cnt_u8(tmp, tmp);
7105 break;
7106 case NEON_2RM_VMVN:
7107 tcg_gen_not_i32(tmp, tmp);
7108 break;
7109 case NEON_2RM_VQABS:
7110 switch (size) {
7111 case 0:
7112 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7113 break;
7114 case 1:
7115 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7116 break;
7117 case 2:
7118 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7119 break;
7120 default: abort();
7122 break;
7123 case NEON_2RM_VQNEG:
7124 switch (size) {
7125 case 0:
7126 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7127 break;
7128 case 1:
7129 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7130 break;
7131 case 2:
7132 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7133 break;
7134 default: abort();
7136 break;
7137 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7138 tmp2 = tcg_const_i32(0);
7139 switch(size) {
7140 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7141 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7142 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7143 default: abort();
7145 tcg_temp_free_i32(tmp2);
7146 if (op == NEON_2RM_VCLE0) {
7147 tcg_gen_not_i32(tmp, tmp);
7149 break;
7150 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7151 tmp2 = tcg_const_i32(0);
7152 switch(size) {
7153 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7154 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7155 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7156 default: abort();
7158 tcg_temp_free_i32(tmp2);
7159 if (op == NEON_2RM_VCLT0) {
7160 tcg_gen_not_i32(tmp, tmp);
7162 break;
7163 case NEON_2RM_VCEQ0:
7164 tmp2 = tcg_const_i32(0);
7165 switch(size) {
7166 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7167 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7168 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7169 default: abort();
7171 tcg_temp_free_i32(tmp2);
7172 break;
7173 case NEON_2RM_VABS:
7174 switch(size) {
7175 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7176 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7177 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7178 default: abort();
7180 break;
7181 case NEON_2RM_VNEG:
7182 tmp2 = tcg_const_i32(0);
7183 gen_neon_rsb(size, tmp, tmp2);
7184 tcg_temp_free_i32(tmp2);
7185 break;
7186 case NEON_2RM_VCGT0_F:
7188 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7189 tmp2 = tcg_const_i32(0);
7190 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7191 tcg_temp_free_i32(tmp2);
7192 tcg_temp_free_ptr(fpstatus);
7193 break;
7195 case NEON_2RM_VCGE0_F:
7197 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7198 tmp2 = tcg_const_i32(0);
7199 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7200 tcg_temp_free_i32(tmp2);
7201 tcg_temp_free_ptr(fpstatus);
7202 break;
7204 case NEON_2RM_VCEQ0_F:
7206 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7207 tmp2 = tcg_const_i32(0);
7208 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7209 tcg_temp_free_i32(tmp2);
7210 tcg_temp_free_ptr(fpstatus);
7211 break;
7213 case NEON_2RM_VCLE0_F:
7215 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7216 tmp2 = tcg_const_i32(0);
7217 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7218 tcg_temp_free_i32(tmp2);
7219 tcg_temp_free_ptr(fpstatus);
7220 break;
7222 case NEON_2RM_VCLT0_F:
7224 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7225 tmp2 = tcg_const_i32(0);
7226 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7227 tcg_temp_free_i32(tmp2);
7228 tcg_temp_free_ptr(fpstatus);
7229 break;
7231 case NEON_2RM_VABS_F:
7232 gen_vfp_abs(0);
7233 break;
7234 case NEON_2RM_VNEG_F:
7235 gen_vfp_neg(0);
7236 break;
7237 case NEON_2RM_VSWP:
7238 tmp2 = neon_load_reg(rd, pass);
7239 neon_store_reg(rm, pass, tmp2);
7240 break;
7241 case NEON_2RM_VTRN:
7242 tmp2 = neon_load_reg(rd, pass);
7243 switch (size) {
7244 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7245 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7246 default: abort();
7248 neon_store_reg(rm, pass, tmp2);
7249 break;
7250 case NEON_2RM_VRINTN:
7251 case NEON_2RM_VRINTA:
7252 case NEON_2RM_VRINTM:
7253 case NEON_2RM_VRINTP:
7254 case NEON_2RM_VRINTZ:
7256 TCGv_i32 tcg_rmode;
7257 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7258 int rmode;
7260 if (op == NEON_2RM_VRINTZ) {
7261 rmode = FPROUNDING_ZERO;
7262 } else {
7263 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7266 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7267 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7268 cpu_env);
7269 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7270 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7271 cpu_env);
7272 tcg_temp_free_ptr(fpstatus);
7273 tcg_temp_free_i32(tcg_rmode);
7274 break;
7276 case NEON_2RM_VRINTX:
7278 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7279 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7280 tcg_temp_free_ptr(fpstatus);
7281 break;
7283 case NEON_2RM_VCVTAU:
7284 case NEON_2RM_VCVTAS:
7285 case NEON_2RM_VCVTNU:
7286 case NEON_2RM_VCVTNS:
7287 case NEON_2RM_VCVTPU:
7288 case NEON_2RM_VCVTPS:
7289 case NEON_2RM_VCVTMU:
7290 case NEON_2RM_VCVTMS:
7292 bool is_signed = !extract32(insn, 7, 1);
7293 TCGv_ptr fpst = get_fpstatus_ptr(1);
7294 TCGv_i32 tcg_rmode, tcg_shift;
7295 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7297 tcg_shift = tcg_const_i32(0);
7298 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7299 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7300 cpu_env);
7302 if (is_signed) {
7303 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7304 tcg_shift, fpst);
7305 } else {
7306 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7307 tcg_shift, fpst);
7310 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7311 cpu_env);
7312 tcg_temp_free_i32(tcg_rmode);
7313 tcg_temp_free_i32(tcg_shift);
7314 tcg_temp_free_ptr(fpst);
7315 break;
7317 case NEON_2RM_VRECPE:
7319 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7320 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7321 tcg_temp_free_ptr(fpstatus);
7322 break;
7324 case NEON_2RM_VRSQRTE:
7326 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7327 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7328 tcg_temp_free_ptr(fpstatus);
7329 break;
7331 case NEON_2RM_VRECPE_F:
7333 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7334 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7335 tcg_temp_free_ptr(fpstatus);
7336 break;
7338 case NEON_2RM_VRSQRTE_F:
7340 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7341 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7342 tcg_temp_free_ptr(fpstatus);
7343 break;
7345 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7346 gen_vfp_sito(0, 1);
7347 break;
7348 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7349 gen_vfp_uito(0, 1);
7350 break;
7351 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7352 gen_vfp_tosiz(0, 1);
7353 break;
7354 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7355 gen_vfp_touiz(0, 1);
7356 break;
7357 default:
7358 /* Reserved op values were caught by the
7359 * neon_2rm_sizes[] check earlier.
7361 abort();
7363 if (neon_2rm_is_float_op(op)) {
7364 tcg_gen_st_f32(cpu_F0s, cpu_env,
7365 neon_reg_offset(rd, pass));
7366 } else {
7367 neon_store_reg(rd, pass, tmp);
7370 break;
7372 } else if ((insn & (1 << 10)) == 0) {
7373 /* VTBL, VTBX. */
7374 int n = ((insn >> 8) & 3) + 1;
7375 if ((rn + n) > 32) {
7376 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7377 * helper function running off the end of the register file.
7379 return 1;
7381 n <<= 3;
7382 if (insn & (1 << 6)) {
7383 tmp = neon_load_reg(rd, 0);
7384 } else {
7385 tmp = tcg_temp_new_i32();
7386 tcg_gen_movi_i32(tmp, 0);
7388 tmp2 = neon_load_reg(rm, 0);
7389 tmp4 = tcg_const_i32(rn);
7390 tmp5 = tcg_const_i32(n);
7391 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7392 tcg_temp_free_i32(tmp);
7393 if (insn & (1 << 6)) {
7394 tmp = neon_load_reg(rd, 1);
7395 } else {
7396 tmp = tcg_temp_new_i32();
7397 tcg_gen_movi_i32(tmp, 0);
7399 tmp3 = neon_load_reg(rm, 1);
7400 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7401 tcg_temp_free_i32(tmp5);
7402 tcg_temp_free_i32(tmp4);
7403 neon_store_reg(rd, 0, tmp2);
7404 neon_store_reg(rd, 1, tmp3);
7405 tcg_temp_free_i32(tmp);
7406 } else if ((insn & 0x380) == 0) {
7407 /* VDUP */
7408 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7409 return 1;
7411 if (insn & (1 << 19)) {
7412 tmp = neon_load_reg(rm, 1);
7413 } else {
7414 tmp = neon_load_reg(rm, 0);
7416 if (insn & (1 << 16)) {
7417 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7418 } else if (insn & (1 << 17)) {
7419 if ((insn >> 18) & 1)
7420 gen_neon_dup_high16(tmp);
7421 else
7422 gen_neon_dup_low16(tmp);
7424 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7425 tmp2 = tcg_temp_new_i32();
7426 tcg_gen_mov_i32(tmp2, tmp);
7427 neon_store_reg(rd, pass, tmp2);
7429 tcg_temp_free_i32(tmp);
7430 } else {
7431 return 1;
7435 return 0;
7438 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7440 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7441 const ARMCPRegInfo *ri;
7443 cpnum = (insn >> 8) & 0xf;
7445 /* First check for coprocessor space used for XScale/iwMMXt insns */
7446 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7447 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7448 return 1;
7450 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7451 return disas_iwmmxt_insn(s, insn);
7452 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7453 return disas_dsp_insn(s, insn);
7455 return 1;
7458 /* Otherwise treat as a generic register access */
7459 is64 = (insn & (1 << 25)) == 0;
7460 if (!is64 && ((insn & (1 << 4)) == 0)) {
7461 /* cdp */
7462 return 1;
7465 crm = insn & 0xf;
7466 if (is64) {
7467 crn = 0;
7468 opc1 = (insn >> 4) & 0xf;
7469 opc2 = 0;
7470 rt2 = (insn >> 16) & 0xf;
7471 } else {
7472 crn = (insn >> 16) & 0xf;
7473 opc1 = (insn >> 21) & 7;
7474 opc2 = (insn >> 5) & 7;
7475 rt2 = 0;
7477 isread = (insn >> 20) & 1;
7478 rt = (insn >> 12) & 0xf;
7480 ri = get_arm_cp_reginfo(s->cp_regs,
7481 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7482 if (ri) {
7483 /* Check access permissions */
7484 if (!cp_access_ok(s->current_el, ri, isread)) {
7485 return 1;
7488 if (ri->accessfn ||
7489 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7490 /* Emit code to perform further access permissions checks at
7491 * runtime; this may result in an exception.
7492 * Note that on XScale all cp0..c13 registers do an access check
7493 * call in order to handle c15_cpar.
7495 TCGv_ptr tmpptr;
7496 TCGv_i32 tcg_syn, tcg_isread;
7497 uint32_t syndrome;
7499 /* Note that since we are an implementation which takes an
7500 * exception on a trapped conditional instruction only if the
7501 * instruction passes its condition code check, we can take
7502 * advantage of the clause in the ARM ARM that allows us to set
7503 * the COND field in the instruction to 0xE in all cases.
7504 * We could fish the actual condition out of the insn (ARM)
7505 * or the condexec bits (Thumb) but it isn't necessary.
7507 switch (cpnum) {
7508 case 14:
7509 if (is64) {
7510 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7511 isread, false);
7512 } else {
7513 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7514 rt, isread, false);
7516 break;
7517 case 15:
7518 if (is64) {
7519 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7520 isread, false);
7521 } else {
7522 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7523 rt, isread, false);
7525 break;
7526 default:
7527 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7528 * so this can only happen if this is an ARMv7 or earlier CPU,
7529 * in which case the syndrome information won't actually be
7530 * guest visible.
7532 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7533 syndrome = syn_uncategorized();
7534 break;
7537 gen_set_condexec(s);
7538 gen_set_pc_im(s, s->pc - 4);
7539 tmpptr = tcg_const_ptr(ri);
7540 tcg_syn = tcg_const_i32(syndrome);
7541 tcg_isread = tcg_const_i32(isread);
7542 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7543 tcg_isread);
7544 tcg_temp_free_ptr(tmpptr);
7545 tcg_temp_free_i32(tcg_syn);
7546 tcg_temp_free_i32(tcg_isread);
7549 /* Handle special cases first */
7550 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7551 case ARM_CP_NOP:
7552 return 0;
7553 case ARM_CP_WFI:
7554 if (isread) {
7555 return 1;
7557 gen_set_pc_im(s, s->pc);
7558 s->is_jmp = DISAS_WFI;
7559 return 0;
7560 default:
7561 break;
7564 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7565 gen_io_start();
7568 if (isread) {
7569 /* Read */
7570 if (is64) {
7571 TCGv_i64 tmp64;
7572 TCGv_i32 tmp;
7573 if (ri->type & ARM_CP_CONST) {
7574 tmp64 = tcg_const_i64(ri->resetvalue);
7575 } else if (ri->readfn) {
7576 TCGv_ptr tmpptr;
7577 tmp64 = tcg_temp_new_i64();
7578 tmpptr = tcg_const_ptr(ri);
7579 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7580 tcg_temp_free_ptr(tmpptr);
7581 } else {
7582 tmp64 = tcg_temp_new_i64();
7583 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7585 tmp = tcg_temp_new_i32();
7586 tcg_gen_extrl_i64_i32(tmp, tmp64);
7587 store_reg(s, rt, tmp);
7588 tcg_gen_shri_i64(tmp64, tmp64, 32);
7589 tmp = tcg_temp_new_i32();
7590 tcg_gen_extrl_i64_i32(tmp, tmp64);
7591 tcg_temp_free_i64(tmp64);
7592 store_reg(s, rt2, tmp);
7593 } else {
7594 TCGv_i32 tmp;
7595 if (ri->type & ARM_CP_CONST) {
7596 tmp = tcg_const_i32(ri->resetvalue);
7597 } else if (ri->readfn) {
7598 TCGv_ptr tmpptr;
7599 tmp = tcg_temp_new_i32();
7600 tmpptr = tcg_const_ptr(ri);
7601 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7602 tcg_temp_free_ptr(tmpptr);
7603 } else {
7604 tmp = load_cpu_offset(ri->fieldoffset);
7606 if (rt == 15) {
7607 /* Destination register of r15 for 32 bit loads sets
7608 * the condition codes from the high 4 bits of the value
7610 gen_set_nzcv(tmp);
7611 tcg_temp_free_i32(tmp);
7612 } else {
7613 store_reg(s, rt, tmp);
7616 } else {
7617 /* Write */
7618 if (ri->type & ARM_CP_CONST) {
7619 /* If not forbidden by access permissions, treat as WI */
7620 return 0;
7623 if (is64) {
7624 TCGv_i32 tmplo, tmphi;
7625 TCGv_i64 tmp64 = tcg_temp_new_i64();
7626 tmplo = load_reg(s, rt);
7627 tmphi = load_reg(s, rt2);
7628 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7629 tcg_temp_free_i32(tmplo);
7630 tcg_temp_free_i32(tmphi);
7631 if (ri->writefn) {
7632 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7633 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7634 tcg_temp_free_ptr(tmpptr);
7635 } else {
7636 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7638 tcg_temp_free_i64(tmp64);
7639 } else {
7640 if (ri->writefn) {
7641 TCGv_i32 tmp;
7642 TCGv_ptr tmpptr;
7643 tmp = load_reg(s, rt);
7644 tmpptr = tcg_const_ptr(ri);
7645 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7646 tcg_temp_free_ptr(tmpptr);
7647 tcg_temp_free_i32(tmp);
7648 } else {
7649 TCGv_i32 tmp = load_reg(s, rt);
7650 store_cpu_offset(tmp, ri->fieldoffset);
7655 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7656 /* I/O operations must end the TB here (whether read or write) */
7657 gen_io_end();
7658 gen_lookup_tb(s);
7659 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7660 /* We default to ending the TB on a coprocessor register write,
7661 * but allow this to be suppressed by the register definition
7662 * (usually only necessary to work around guest bugs).
7664 gen_lookup_tb(s);
7667 return 0;
7670 /* Unknown register; this might be a guest error or a QEMU
7671 * unimplemented feature.
7673 if (is64) {
7674 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7675 "64 bit system register cp:%d opc1: %d crm:%d "
7676 "(%s)\n",
7677 isread ? "read" : "write", cpnum, opc1, crm,
7678 s->ns ? "non-secure" : "secure");
7679 } else {
7680 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7681 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7682 "(%s)\n",
7683 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7684 s->ns ? "non-secure" : "secure");
7687 return 1;
7691 /* Store a 64-bit value to a register pair. Clobbers val. */
7692 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7694 TCGv_i32 tmp;
7695 tmp = tcg_temp_new_i32();
7696 tcg_gen_extrl_i64_i32(tmp, val);
7697 store_reg(s, rlow, tmp);
7698 tmp = tcg_temp_new_i32();
7699 tcg_gen_shri_i64(val, val, 32);
7700 tcg_gen_extrl_i64_i32(tmp, val);
7701 store_reg(s, rhigh, tmp);
7704 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7705 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7707 TCGv_i64 tmp;
7708 TCGv_i32 tmp2;
7710 /* Load value and extend to 64 bits. */
7711 tmp = tcg_temp_new_i64();
7712 tmp2 = load_reg(s, rlow);
7713 tcg_gen_extu_i32_i64(tmp, tmp2);
7714 tcg_temp_free_i32(tmp2);
7715 tcg_gen_add_i64(val, val, tmp);
7716 tcg_temp_free_i64(tmp);
7719 /* load and add a 64-bit value from a register pair. */
7720 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7722 TCGv_i64 tmp;
7723 TCGv_i32 tmpl;
7724 TCGv_i32 tmph;
7726 /* Load 64-bit value rd:rn. */
7727 tmpl = load_reg(s, rlow);
7728 tmph = load_reg(s, rhigh);
7729 tmp = tcg_temp_new_i64();
7730 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7731 tcg_temp_free_i32(tmpl);
7732 tcg_temp_free_i32(tmph);
7733 tcg_gen_add_i64(val, val, tmp);
7734 tcg_temp_free_i64(tmp);
7737 /* Set N and Z flags from hi|lo. */
7738 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7740 tcg_gen_mov_i32(cpu_NF, hi);
7741 tcg_gen_or_i32(cpu_ZF, lo, hi);
7744 /* Load/Store exclusive instructions are implemented by remembering
7745 the value/address loaded, and seeing if these are the same
7746 when the store is performed. This should be sufficient to implement
7747 the architecturally mandated semantics, and avoids having to monitor
7748 regular stores. The compare vs the remembered value is done during
7749 the cmpxchg operation, but we must compare the addresses manually. */
7750 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7751 TCGv_i32 addr, int size)
7753 TCGv_i32 tmp = tcg_temp_new_i32();
7754 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7756 s->is_ldex = true;
7758 if (size == 3) {
7759 TCGv_i32 tmp2 = tcg_temp_new_i32();
7760 TCGv_i64 t64 = tcg_temp_new_i64();
7762 gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
7763 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7764 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7765 tcg_temp_free_i64(t64);
7767 store_reg(s, rt2, tmp2);
7768 } else {
7769 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7770 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7773 store_reg(s, rt, tmp);
7774 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7777 static void gen_clrex(DisasContext *s)
7779 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7782 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7783 TCGv_i32 addr, int size)
7785 TCGv_i32 t0, t1, t2;
7786 TCGv_i64 extaddr;
7787 TCGv taddr;
7788 TCGLabel *done_label;
7789 TCGLabel *fail_label;
7790 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7792 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7793 [addr] = {Rt};
7794 {Rd} = 0;
7795 } else {
7796 {Rd} = 1;
7797 } */
7798 fail_label = gen_new_label();
7799 done_label = gen_new_label();
7800 extaddr = tcg_temp_new_i64();
7801 tcg_gen_extu_i32_i64(extaddr, addr);
7802 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7803 tcg_temp_free_i64(extaddr);
7805 taddr = gen_aa32_addr(s, addr, opc);
7806 t0 = tcg_temp_new_i32();
7807 t1 = load_reg(s, rt);
7808 if (size == 3) {
7809 TCGv_i64 o64 = tcg_temp_new_i64();
7810 TCGv_i64 n64 = tcg_temp_new_i64();
7812 t2 = load_reg(s, rt2);
7813 tcg_gen_concat_i32_i64(n64, t1, t2);
7814 tcg_temp_free_i32(t2);
7815 gen_aa32_frob64(s, n64);
7817 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7818 get_mem_index(s), opc);
7819 tcg_temp_free_i64(n64);
7821 gen_aa32_frob64(s, o64);
7822 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7823 tcg_gen_extrl_i64_i32(t0, o64);
7825 tcg_temp_free_i64(o64);
7826 } else {
7827 t2 = tcg_temp_new_i32();
7828 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7829 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7830 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7831 tcg_temp_free_i32(t2);
7833 tcg_temp_free_i32(t1);
7834 tcg_temp_free(taddr);
7835 tcg_gen_mov_i32(cpu_R[rd], t0);
7836 tcg_temp_free_i32(t0);
7837 tcg_gen_br(done_label);
7839 gen_set_label(fail_label);
7840 tcg_gen_movi_i32(cpu_R[rd], 1);
7841 gen_set_label(done_label);
7842 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7845 /* gen_srs:
7846 * @env: CPUARMState
7847 * @s: DisasContext
7848 * @mode: mode field from insn (which stack to store to)
7849 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7850 * @writeback: true if writeback bit set
7852 * Generate code for the SRS (Store Return State) insn.
7854 static void gen_srs(DisasContext *s,
7855 uint32_t mode, uint32_t amode, bool writeback)
7857 int32_t offset;
7858 TCGv_i32 addr, tmp;
7859 bool undef = false;
7861 /* SRS is:
7862 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7863 * and specified mode is monitor mode
7864 * - UNDEFINED in Hyp mode
7865 * - UNPREDICTABLE in User or System mode
7866 * - UNPREDICTABLE if the specified mode is:
7867 * -- not implemented
7868 * -- not a valid mode number
7869 * -- a mode that's at a higher exception level
7870 * -- Monitor, if we are Non-secure
7871 * For the UNPREDICTABLE cases we choose to UNDEF.
7873 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7874 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7875 return;
7878 if (s->current_el == 0 || s->current_el == 2) {
7879 undef = true;
7882 switch (mode) {
7883 case ARM_CPU_MODE_USR:
7884 case ARM_CPU_MODE_FIQ:
7885 case ARM_CPU_MODE_IRQ:
7886 case ARM_CPU_MODE_SVC:
7887 case ARM_CPU_MODE_ABT:
7888 case ARM_CPU_MODE_UND:
7889 case ARM_CPU_MODE_SYS:
7890 break;
7891 case ARM_CPU_MODE_HYP:
7892 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7893 undef = true;
7895 break;
7896 case ARM_CPU_MODE_MON:
7897 /* No need to check specifically for "are we non-secure" because
7898 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7899 * so if this isn't EL3 then we must be non-secure.
7901 if (s->current_el != 3) {
7902 undef = true;
7904 break;
7905 default:
7906 undef = true;
7909 if (undef) {
7910 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
7911 default_exception_el(s));
7912 return;
7915 addr = tcg_temp_new_i32();
7916 tmp = tcg_const_i32(mode);
7917 /* get_r13_banked() will raise an exception if called from System mode */
7918 gen_set_condexec(s);
7919 gen_set_pc_im(s, s->pc - 4);
7920 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7921 tcg_temp_free_i32(tmp);
7922 switch (amode) {
7923 case 0: /* DA */
7924 offset = -4;
7925 break;
7926 case 1: /* IA */
7927 offset = 0;
7928 break;
7929 case 2: /* DB */
7930 offset = -8;
7931 break;
7932 case 3: /* IB */
7933 offset = 4;
7934 break;
7935 default:
7936 abort();
7938 tcg_gen_addi_i32(addr, addr, offset);
7939 tmp = load_reg(s, 14);
7940 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7941 tcg_temp_free_i32(tmp);
7942 tmp = load_cpu_field(spsr);
7943 tcg_gen_addi_i32(addr, addr, 4);
7944 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7945 tcg_temp_free_i32(tmp);
7946 if (writeback) {
7947 switch (amode) {
7948 case 0:
7949 offset = -8;
7950 break;
7951 case 1:
7952 offset = 4;
7953 break;
7954 case 2:
7955 offset = -4;
7956 break;
7957 case 3:
7958 offset = 0;
7959 break;
7960 default:
7961 abort();
7963 tcg_gen_addi_i32(addr, addr, offset);
7964 tmp = tcg_const_i32(mode);
7965 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7966 tcg_temp_free_i32(tmp);
7968 tcg_temp_free_i32(addr);
7969 s->is_jmp = DISAS_UPDATE;
7972 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7974 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7975 TCGv_i32 tmp;
7976 TCGv_i32 tmp2;
7977 TCGv_i32 tmp3;
7978 TCGv_i32 addr;
7979 TCGv_i64 tmp64;
7981 /* M variants do not implement ARM mode. */
7982 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7983 goto illegal_op;
7985 cond = insn >> 28;
7986 if (cond == 0xf){
7987 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7988 * choose to UNDEF. In ARMv5 and above the space is used
7989 * for miscellaneous unconditional instructions.
7991 ARCH(5);
7993 /* Unconditional instructions. */
7994 if (((insn >> 25) & 7) == 1) {
7995 /* NEON Data processing. */
7996 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7997 goto illegal_op;
8000 if (disas_neon_data_insn(s, insn)) {
8001 goto illegal_op;
8003 return;
8005 if ((insn & 0x0f100000) == 0x04000000) {
8006 /* NEON load/store. */
8007 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8008 goto illegal_op;
8011 if (disas_neon_ls_insn(s, insn)) {
8012 goto illegal_op;
8014 return;
8016 if ((insn & 0x0f000e10) == 0x0e000a00) {
8017 /* VFP. */
8018 if (disas_vfp_insn(s, insn)) {
8019 goto illegal_op;
8021 return;
8023 if (((insn & 0x0f30f000) == 0x0510f000) ||
8024 ((insn & 0x0f30f010) == 0x0710f000)) {
8025 if ((insn & (1 << 22)) == 0) {
8026 /* PLDW; v7MP */
8027 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8028 goto illegal_op;
8031 /* Otherwise PLD; v5TE+ */
8032 ARCH(5TE);
8033 return;
8035 if (((insn & 0x0f70f000) == 0x0450f000) ||
8036 ((insn & 0x0f70f010) == 0x0650f000)) {
8037 ARCH(7);
8038 return; /* PLI; V7 */
8040 if (((insn & 0x0f700000) == 0x04100000) ||
8041 ((insn & 0x0f700010) == 0x06100000)) {
8042 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8043 goto illegal_op;
8045 return; /* v7MP: Unallocated memory hint: must NOP */
8048 if ((insn & 0x0ffffdff) == 0x01010000) {
8049 ARCH(6);
8050 /* setend */
8051 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8052 gen_helper_setend(cpu_env);
8053 s->is_jmp = DISAS_UPDATE;
8055 return;
8056 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8057 switch ((insn >> 4) & 0xf) {
8058 case 1: /* clrex */
8059 ARCH(6K);
8060 gen_clrex(s);
8061 return;
8062 case 4: /* dsb */
8063 case 5: /* dmb */
8064 ARCH(7);
8065 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8066 return;
8067 case 6: /* isb */
8068 /* We need to break the TB after this insn to execute
8069 * self-modifying code correctly and also to take
8070 * any pending interrupts immediately.
8072 gen_lookup_tb(s);
8073 return;
8074 default:
8075 goto illegal_op;
8077 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8078 /* srs */
8079 ARCH(6);
8080 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8081 return;
8082 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8083 /* rfe */
8084 int32_t offset;
8085 if (IS_USER(s))
8086 goto illegal_op;
8087 ARCH(6);
8088 rn = (insn >> 16) & 0xf;
8089 addr = load_reg(s, rn);
8090 i = (insn >> 23) & 3;
8091 switch (i) {
8092 case 0: offset = -4; break; /* DA */
8093 case 1: offset = 0; break; /* IA */
8094 case 2: offset = -8; break; /* DB */
8095 case 3: offset = 4; break; /* IB */
8096 default: abort();
8098 if (offset)
8099 tcg_gen_addi_i32(addr, addr, offset);
8100 /* Load PC into tmp and CPSR into tmp2. */
8101 tmp = tcg_temp_new_i32();
8102 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8103 tcg_gen_addi_i32(addr, addr, 4);
8104 tmp2 = tcg_temp_new_i32();
8105 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8106 if (insn & (1 << 21)) {
8107 /* Base writeback. */
8108 switch (i) {
8109 case 0: offset = -8; break;
8110 case 1: offset = 4; break;
8111 case 2: offset = -4; break;
8112 case 3: offset = 0; break;
8113 default: abort();
8115 if (offset)
8116 tcg_gen_addi_i32(addr, addr, offset);
8117 store_reg(s, rn, addr);
8118 } else {
8119 tcg_temp_free_i32(addr);
8121 gen_rfe(s, tmp, tmp2);
8122 return;
8123 } else if ((insn & 0x0e000000) == 0x0a000000) {
8124 /* branch link and change to thumb (blx <offset>) */
8125 int32_t offset;
8127 val = (uint32_t)s->pc;
8128 tmp = tcg_temp_new_i32();
8129 tcg_gen_movi_i32(tmp, val);
8130 store_reg(s, 14, tmp);
8131 /* Sign-extend the 24-bit offset */
8132 offset = (((int32_t)insn) << 8) >> 8;
8133 /* offset * 4 + bit24 * 2 + (thumb bit) */
8134 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8135 /* pipeline offset */
8136 val += 4;
8137 /* protected by ARCH(5); above, near the start of uncond block */
8138 gen_bx_im(s, val);
8139 return;
8140 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8141 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8142 /* iWMMXt register transfer. */
8143 if (extract32(s->c15_cpar, 1, 1)) {
8144 if (!disas_iwmmxt_insn(s, insn)) {
8145 return;
8149 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8150 /* Coprocessor double register transfer. */
8151 ARCH(5TE);
8152 } else if ((insn & 0x0f000010) == 0x0e000010) {
8153 /* Additional coprocessor register transfer. */
8154 } else if ((insn & 0x0ff10020) == 0x01000000) {
8155 uint32_t mask;
8156 uint32_t val;
8157 /* cps (privileged) */
8158 if (IS_USER(s))
8159 return;
8160 mask = val = 0;
8161 if (insn & (1 << 19)) {
8162 if (insn & (1 << 8))
8163 mask |= CPSR_A;
8164 if (insn & (1 << 7))
8165 mask |= CPSR_I;
8166 if (insn & (1 << 6))
8167 mask |= CPSR_F;
8168 if (insn & (1 << 18))
8169 val |= mask;
8171 if (insn & (1 << 17)) {
8172 mask |= CPSR_M;
8173 val |= (insn & 0x1f);
8175 if (mask) {
8176 gen_set_psr_im(s, mask, 0, val);
8178 return;
8180 goto illegal_op;
8182 if (cond != 0xe) {
8183 /* if not always execute, we generate a conditional jump to
8184 next instruction */
8185 s->condlabel = gen_new_label();
8186 arm_gen_test_cc(cond ^ 1, s->condlabel);
8187 s->condjmp = 1;
8189 if ((insn & 0x0f900000) == 0x03000000) {
8190 if ((insn & (1 << 21)) == 0) {
8191 ARCH(6T2);
8192 rd = (insn >> 12) & 0xf;
8193 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8194 if ((insn & (1 << 22)) == 0) {
8195 /* MOVW */
8196 tmp = tcg_temp_new_i32();
8197 tcg_gen_movi_i32(tmp, val);
8198 } else {
8199 /* MOVT */
8200 tmp = load_reg(s, rd);
8201 tcg_gen_ext16u_i32(tmp, tmp);
8202 tcg_gen_ori_i32(tmp, tmp, val << 16);
8204 store_reg(s, rd, tmp);
8205 } else {
8206 if (((insn >> 12) & 0xf) != 0xf)
8207 goto illegal_op;
8208 if (((insn >> 16) & 0xf) == 0) {
8209 gen_nop_hint(s, insn & 0xff);
8210 } else {
8211 /* CPSR = immediate */
8212 val = insn & 0xff;
8213 shift = ((insn >> 8) & 0xf) * 2;
8214 if (shift)
8215 val = (val >> shift) | (val << (32 - shift));
8216 i = ((insn & (1 << 22)) != 0);
8217 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8218 i, val)) {
8219 goto illegal_op;
8223 } else if ((insn & 0x0f900000) == 0x01000000
8224 && (insn & 0x00000090) != 0x00000090) {
8225 /* miscellaneous instructions */
8226 op1 = (insn >> 21) & 3;
8227 sh = (insn >> 4) & 0xf;
8228 rm = insn & 0xf;
8229 switch (sh) {
8230 case 0x0: /* MSR, MRS */
8231 if (insn & (1 << 9)) {
8232 /* MSR (banked) and MRS (banked) */
8233 int sysm = extract32(insn, 16, 4) |
8234 (extract32(insn, 8, 1) << 4);
8235 int r = extract32(insn, 22, 1);
8237 if (op1 & 1) {
8238 /* MSR (banked) */
8239 gen_msr_banked(s, r, sysm, rm);
8240 } else {
8241 /* MRS (banked) */
8242 int rd = extract32(insn, 12, 4);
8244 gen_mrs_banked(s, r, sysm, rd);
8246 break;
8249 /* MSR, MRS (for PSRs) */
8250 if (op1 & 1) {
8251 /* PSR = reg */
8252 tmp = load_reg(s, rm);
8253 i = ((op1 & 2) != 0);
8254 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8255 goto illegal_op;
8256 } else {
8257 /* reg = PSR */
8258 rd = (insn >> 12) & 0xf;
8259 if (op1 & 2) {
8260 if (IS_USER(s))
8261 goto illegal_op;
8262 tmp = load_cpu_field(spsr);
8263 } else {
8264 tmp = tcg_temp_new_i32();
8265 gen_helper_cpsr_read(tmp, cpu_env);
8267 store_reg(s, rd, tmp);
8269 break;
8270 case 0x1:
8271 if (op1 == 1) {
8272 /* branch/exchange thumb (bx). */
8273 ARCH(4T);
8274 tmp = load_reg(s, rm);
8275 gen_bx(s, tmp);
8276 } else if (op1 == 3) {
8277 /* clz */
8278 ARCH(5);
8279 rd = (insn >> 12) & 0xf;
8280 tmp = load_reg(s, rm);
8281 tcg_gen_clzi_i32(tmp, tmp, 32);
8282 store_reg(s, rd, tmp);
8283 } else {
8284 goto illegal_op;
8286 break;
8287 case 0x2:
8288 if (op1 == 1) {
8289 ARCH(5J); /* bxj */
8290 /* Trivial implementation equivalent to bx. */
8291 tmp = load_reg(s, rm);
8292 gen_bx(s, tmp);
8293 } else {
8294 goto illegal_op;
8296 break;
8297 case 0x3:
8298 if (op1 != 1)
8299 goto illegal_op;
8301 ARCH(5);
8302 /* branch link/exchange thumb (blx) */
8303 tmp = load_reg(s, rm);
8304 tmp2 = tcg_temp_new_i32();
8305 tcg_gen_movi_i32(tmp2, s->pc);
8306 store_reg(s, 14, tmp2);
8307 gen_bx(s, tmp);
8308 break;
8309 case 0x4:
8311 /* crc32/crc32c */
8312 uint32_t c = extract32(insn, 8, 4);
8314 /* Check this CPU supports ARMv8 CRC instructions.
8315 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8316 * Bits 8, 10 and 11 should be zero.
8318 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8319 (c & 0xd) != 0) {
8320 goto illegal_op;
8323 rn = extract32(insn, 16, 4);
8324 rd = extract32(insn, 12, 4);
8326 tmp = load_reg(s, rn);
8327 tmp2 = load_reg(s, rm);
8328 if (op1 == 0) {
8329 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8330 } else if (op1 == 1) {
8331 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8333 tmp3 = tcg_const_i32(1 << op1);
8334 if (c & 0x2) {
8335 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8336 } else {
8337 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8339 tcg_temp_free_i32(tmp2);
8340 tcg_temp_free_i32(tmp3);
8341 store_reg(s, rd, tmp);
8342 break;
8344 case 0x5: /* saturating add/subtract */
8345 ARCH(5TE);
8346 rd = (insn >> 12) & 0xf;
8347 rn = (insn >> 16) & 0xf;
8348 tmp = load_reg(s, rm);
8349 tmp2 = load_reg(s, rn);
8350 if (op1 & 2)
8351 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8352 if (op1 & 1)
8353 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8354 else
8355 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8356 tcg_temp_free_i32(tmp2);
8357 store_reg(s, rd, tmp);
8358 break;
8359 case 7:
8361 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8362 switch (op1) {
8363 case 0:
8364 /* HLT */
8365 gen_hlt(s, imm16);
8366 break;
8367 case 1:
8368 /* bkpt */
8369 ARCH(5);
8370 gen_exception_insn(s, 4, EXCP_BKPT,
8371 syn_aa32_bkpt(imm16, false),
8372 default_exception_el(s));
8373 break;
8374 case 2:
8375 /* Hypervisor call (v7) */
8376 ARCH(7);
8377 if (IS_USER(s)) {
8378 goto illegal_op;
8380 gen_hvc(s, imm16);
8381 break;
8382 case 3:
8383 /* Secure monitor call (v6+) */
8384 ARCH(6K);
8385 if (IS_USER(s)) {
8386 goto illegal_op;
8388 gen_smc(s);
8389 break;
8390 default:
8391 g_assert_not_reached();
8393 break;
8395 case 0x8: /* signed multiply */
8396 case 0xa:
8397 case 0xc:
8398 case 0xe:
8399 ARCH(5TE);
8400 rs = (insn >> 8) & 0xf;
8401 rn = (insn >> 12) & 0xf;
8402 rd = (insn >> 16) & 0xf;
8403 if (op1 == 1) {
8404 /* (32 * 16) >> 16 */
8405 tmp = load_reg(s, rm);
8406 tmp2 = load_reg(s, rs);
8407 if (sh & 4)
8408 tcg_gen_sari_i32(tmp2, tmp2, 16);
8409 else
8410 gen_sxth(tmp2);
8411 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8412 tcg_gen_shri_i64(tmp64, tmp64, 16);
8413 tmp = tcg_temp_new_i32();
8414 tcg_gen_extrl_i64_i32(tmp, tmp64);
8415 tcg_temp_free_i64(tmp64);
8416 if ((sh & 2) == 0) {
8417 tmp2 = load_reg(s, rn);
8418 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8419 tcg_temp_free_i32(tmp2);
8421 store_reg(s, rd, tmp);
8422 } else {
8423 /* 16 * 16 */
8424 tmp = load_reg(s, rm);
8425 tmp2 = load_reg(s, rs);
8426 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8427 tcg_temp_free_i32(tmp2);
8428 if (op1 == 2) {
8429 tmp64 = tcg_temp_new_i64();
8430 tcg_gen_ext_i32_i64(tmp64, tmp);
8431 tcg_temp_free_i32(tmp);
8432 gen_addq(s, tmp64, rn, rd);
8433 gen_storeq_reg(s, rn, rd, tmp64);
8434 tcg_temp_free_i64(tmp64);
8435 } else {
8436 if (op1 == 0) {
8437 tmp2 = load_reg(s, rn);
8438 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8439 tcg_temp_free_i32(tmp2);
8441 store_reg(s, rd, tmp);
8444 break;
8445 default:
8446 goto illegal_op;
8448 } else if (((insn & 0x0e000000) == 0 &&
8449 (insn & 0x00000090) != 0x90) ||
8450 ((insn & 0x0e000000) == (1 << 25))) {
8451 int set_cc, logic_cc, shiftop;
8453 op1 = (insn >> 21) & 0xf;
8454 set_cc = (insn >> 20) & 1;
8455 logic_cc = table_logic_cc[op1] & set_cc;
8457 /* data processing instruction */
8458 if (insn & (1 << 25)) {
8459 /* immediate operand */
8460 val = insn & 0xff;
8461 shift = ((insn >> 8) & 0xf) * 2;
8462 if (shift) {
8463 val = (val >> shift) | (val << (32 - shift));
8465 tmp2 = tcg_temp_new_i32();
8466 tcg_gen_movi_i32(tmp2, val);
8467 if (logic_cc && shift) {
8468 gen_set_CF_bit31(tmp2);
8470 } else {
8471 /* register */
8472 rm = (insn) & 0xf;
8473 tmp2 = load_reg(s, rm);
8474 shiftop = (insn >> 5) & 3;
8475 if (!(insn & (1 << 4))) {
8476 shift = (insn >> 7) & 0x1f;
8477 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8478 } else {
8479 rs = (insn >> 8) & 0xf;
8480 tmp = load_reg(s, rs);
8481 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8484 if (op1 != 0x0f && op1 != 0x0d) {
8485 rn = (insn >> 16) & 0xf;
8486 tmp = load_reg(s, rn);
8487 } else {
8488 TCGV_UNUSED_I32(tmp);
8490 rd = (insn >> 12) & 0xf;
8491 switch(op1) {
8492 case 0x00:
8493 tcg_gen_and_i32(tmp, tmp, tmp2);
8494 if (logic_cc) {
8495 gen_logic_CC(tmp);
8497 store_reg_bx(s, rd, tmp);
8498 break;
8499 case 0x01:
8500 tcg_gen_xor_i32(tmp, tmp, tmp2);
8501 if (logic_cc) {
8502 gen_logic_CC(tmp);
8504 store_reg_bx(s, rd, tmp);
8505 break;
8506 case 0x02:
8507 if (set_cc && rd == 15) {
8508 /* SUBS r15, ... is used for exception return. */
8509 if (IS_USER(s)) {
8510 goto illegal_op;
8512 gen_sub_CC(tmp, tmp, tmp2);
8513 gen_exception_return(s, tmp);
8514 } else {
8515 if (set_cc) {
8516 gen_sub_CC(tmp, tmp, tmp2);
8517 } else {
8518 tcg_gen_sub_i32(tmp, tmp, tmp2);
8520 store_reg_bx(s, rd, tmp);
8522 break;
8523 case 0x03:
8524 if (set_cc) {
8525 gen_sub_CC(tmp, tmp2, tmp);
8526 } else {
8527 tcg_gen_sub_i32(tmp, tmp2, tmp);
8529 store_reg_bx(s, rd, tmp);
8530 break;
8531 case 0x04:
8532 if (set_cc) {
8533 gen_add_CC(tmp, tmp, tmp2);
8534 } else {
8535 tcg_gen_add_i32(tmp, tmp, tmp2);
8537 store_reg_bx(s, rd, tmp);
8538 break;
8539 case 0x05:
8540 if (set_cc) {
8541 gen_adc_CC(tmp, tmp, tmp2);
8542 } else {
8543 gen_add_carry(tmp, tmp, tmp2);
8545 store_reg_bx(s, rd, tmp);
8546 break;
8547 case 0x06:
8548 if (set_cc) {
8549 gen_sbc_CC(tmp, tmp, tmp2);
8550 } else {
8551 gen_sub_carry(tmp, tmp, tmp2);
8553 store_reg_bx(s, rd, tmp);
8554 break;
8555 case 0x07:
8556 if (set_cc) {
8557 gen_sbc_CC(tmp, tmp2, tmp);
8558 } else {
8559 gen_sub_carry(tmp, tmp2, tmp);
8561 store_reg_bx(s, rd, tmp);
8562 break;
8563 case 0x08:
8564 if (set_cc) {
8565 tcg_gen_and_i32(tmp, tmp, tmp2);
8566 gen_logic_CC(tmp);
8568 tcg_temp_free_i32(tmp);
8569 break;
8570 case 0x09:
8571 if (set_cc) {
8572 tcg_gen_xor_i32(tmp, tmp, tmp2);
8573 gen_logic_CC(tmp);
8575 tcg_temp_free_i32(tmp);
8576 break;
8577 case 0x0a:
8578 if (set_cc) {
8579 gen_sub_CC(tmp, tmp, tmp2);
8581 tcg_temp_free_i32(tmp);
8582 break;
8583 case 0x0b:
8584 if (set_cc) {
8585 gen_add_CC(tmp, tmp, tmp2);
8587 tcg_temp_free_i32(tmp);
8588 break;
8589 case 0x0c:
8590 tcg_gen_or_i32(tmp, tmp, tmp2);
8591 if (logic_cc) {
8592 gen_logic_CC(tmp);
8594 store_reg_bx(s, rd, tmp);
8595 break;
8596 case 0x0d:
8597 if (logic_cc && rd == 15) {
8598 /* MOVS r15, ... is used for exception return. */
8599 if (IS_USER(s)) {
8600 goto illegal_op;
8602 gen_exception_return(s, tmp2);
8603 } else {
8604 if (logic_cc) {
8605 gen_logic_CC(tmp2);
8607 store_reg_bx(s, rd, tmp2);
8609 break;
8610 case 0x0e:
8611 tcg_gen_andc_i32(tmp, tmp, tmp2);
8612 if (logic_cc) {
8613 gen_logic_CC(tmp);
8615 store_reg_bx(s, rd, tmp);
8616 break;
8617 default:
8618 case 0x0f:
8619 tcg_gen_not_i32(tmp2, tmp2);
8620 if (logic_cc) {
8621 gen_logic_CC(tmp2);
8623 store_reg_bx(s, rd, tmp2);
8624 break;
8626 if (op1 != 0x0f && op1 != 0x0d) {
8627 tcg_temp_free_i32(tmp2);
8629 } else {
8630 /* other instructions */
8631 op1 = (insn >> 24) & 0xf;
8632 switch(op1) {
8633 case 0x0:
8634 case 0x1:
8635 /* multiplies, extra load/stores */
8636 sh = (insn >> 5) & 3;
8637 if (sh == 0) {
8638 if (op1 == 0x0) {
8639 rd = (insn >> 16) & 0xf;
8640 rn = (insn >> 12) & 0xf;
8641 rs = (insn >> 8) & 0xf;
8642 rm = (insn) & 0xf;
8643 op1 = (insn >> 20) & 0xf;
8644 switch (op1) {
8645 case 0: case 1: case 2: case 3: case 6:
8646 /* 32 bit mul */
8647 tmp = load_reg(s, rs);
8648 tmp2 = load_reg(s, rm);
8649 tcg_gen_mul_i32(tmp, tmp, tmp2);
8650 tcg_temp_free_i32(tmp2);
8651 if (insn & (1 << 22)) {
8652 /* Subtract (mls) */
8653 ARCH(6T2);
8654 tmp2 = load_reg(s, rn);
8655 tcg_gen_sub_i32(tmp, tmp2, tmp);
8656 tcg_temp_free_i32(tmp2);
8657 } else if (insn & (1 << 21)) {
8658 /* Add */
8659 tmp2 = load_reg(s, rn);
8660 tcg_gen_add_i32(tmp, tmp, tmp2);
8661 tcg_temp_free_i32(tmp2);
8663 if (insn & (1 << 20))
8664 gen_logic_CC(tmp);
8665 store_reg(s, rd, tmp);
8666 break;
8667 case 4:
8668 /* 64 bit mul double accumulate (UMAAL) */
8669 ARCH(6);
8670 tmp = load_reg(s, rs);
8671 tmp2 = load_reg(s, rm);
8672 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8673 gen_addq_lo(s, tmp64, rn);
8674 gen_addq_lo(s, tmp64, rd);
8675 gen_storeq_reg(s, rn, rd, tmp64);
8676 tcg_temp_free_i64(tmp64);
8677 break;
8678 case 8: case 9: case 10: case 11:
8679 case 12: case 13: case 14: case 15:
8680 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8681 tmp = load_reg(s, rs);
8682 tmp2 = load_reg(s, rm);
8683 if (insn & (1 << 22)) {
8684 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8685 } else {
8686 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8688 if (insn & (1 << 21)) { /* mult accumulate */
8689 TCGv_i32 al = load_reg(s, rn);
8690 TCGv_i32 ah = load_reg(s, rd);
8691 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8692 tcg_temp_free_i32(al);
8693 tcg_temp_free_i32(ah);
8695 if (insn & (1 << 20)) {
8696 gen_logicq_cc(tmp, tmp2);
8698 store_reg(s, rn, tmp);
8699 store_reg(s, rd, tmp2);
8700 break;
8701 default:
8702 goto illegal_op;
8704 } else {
8705 rn = (insn >> 16) & 0xf;
8706 rd = (insn >> 12) & 0xf;
8707 if (insn & (1 << 23)) {
8708 /* load/store exclusive */
8709 int op2 = (insn >> 8) & 3;
8710 op1 = (insn >> 21) & 0x3;
8712 switch (op2) {
8713 case 0: /* lda/stl */
8714 if (op1 == 1) {
8715 goto illegal_op;
8717 ARCH(8);
8718 break;
8719 case 1: /* reserved */
8720 goto illegal_op;
8721 case 2: /* ldaex/stlex */
8722 ARCH(8);
8723 break;
8724 case 3: /* ldrex/strex */
8725 if (op1) {
8726 ARCH(6K);
8727 } else {
8728 ARCH(6);
8730 break;
8733 addr = tcg_temp_local_new_i32();
8734 load_reg_var(s, addr, rn);
8736 /* Since the emulation does not have barriers,
8737 the acquire/release semantics need no special
8738 handling */
8739 if (op2 == 0) {
8740 if (insn & (1 << 20)) {
8741 tmp = tcg_temp_new_i32();
8742 switch (op1) {
8743 case 0: /* lda */
8744 gen_aa32_ld32u_iss(s, tmp, addr,
8745 get_mem_index(s),
8746 rd | ISSIsAcqRel);
8747 break;
8748 case 2: /* ldab */
8749 gen_aa32_ld8u_iss(s, tmp, addr,
8750 get_mem_index(s),
8751 rd | ISSIsAcqRel);
8752 break;
8753 case 3: /* ldah */
8754 gen_aa32_ld16u_iss(s, tmp, addr,
8755 get_mem_index(s),
8756 rd | ISSIsAcqRel);
8757 break;
8758 default:
8759 abort();
8761 store_reg(s, rd, tmp);
8762 } else {
8763 rm = insn & 0xf;
8764 tmp = load_reg(s, rm);
8765 switch (op1) {
8766 case 0: /* stl */
8767 gen_aa32_st32_iss(s, tmp, addr,
8768 get_mem_index(s),
8769 rm | ISSIsAcqRel);
8770 break;
8771 case 2: /* stlb */
8772 gen_aa32_st8_iss(s, tmp, addr,
8773 get_mem_index(s),
8774 rm | ISSIsAcqRel);
8775 break;
8776 case 3: /* stlh */
8777 gen_aa32_st16_iss(s, tmp, addr,
8778 get_mem_index(s),
8779 rm | ISSIsAcqRel);
8780 break;
8781 default:
8782 abort();
8784 tcg_temp_free_i32(tmp);
8786 } else if (insn & (1 << 20)) {
8787 switch (op1) {
8788 case 0: /* ldrex */
8789 gen_load_exclusive(s, rd, 15, addr, 2);
8790 break;
8791 case 1: /* ldrexd */
8792 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8793 break;
8794 case 2: /* ldrexb */
8795 gen_load_exclusive(s, rd, 15, addr, 0);
8796 break;
8797 case 3: /* ldrexh */
8798 gen_load_exclusive(s, rd, 15, addr, 1);
8799 break;
8800 default:
8801 abort();
8803 } else {
8804 rm = insn & 0xf;
8805 switch (op1) {
8806 case 0: /* strex */
8807 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8808 break;
8809 case 1: /* strexd */
8810 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8811 break;
8812 case 2: /* strexb */
8813 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8814 break;
8815 case 3: /* strexh */
8816 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8817 break;
8818 default:
8819 abort();
8822 tcg_temp_free_i32(addr);
8823 } else {
8824 TCGv taddr;
8825 TCGMemOp opc = s->be_data;
8827 /* SWP instruction */
8828 rm = (insn) & 0xf;
8830 if (insn & (1 << 22)) {
8831 opc |= MO_UB;
8832 } else {
8833 opc |= MO_UL | MO_ALIGN;
8836 addr = load_reg(s, rn);
8837 taddr = gen_aa32_addr(s, addr, opc);
8838 tcg_temp_free_i32(addr);
8840 tmp = load_reg(s, rm);
8841 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8842 get_mem_index(s), opc);
8843 tcg_temp_free(taddr);
8844 store_reg(s, rd, tmp);
8847 } else {
8848 int address_offset;
8849 bool load = insn & (1 << 20);
8850 bool wbit = insn & (1 << 21);
8851 bool pbit = insn & (1 << 24);
8852 bool doubleword = false;
8853 ISSInfo issinfo;
8855 /* Misc load/store */
8856 rn = (insn >> 16) & 0xf;
8857 rd = (insn >> 12) & 0xf;
8859 /* ISS not valid if writeback */
8860 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8862 if (!load && (sh & 2)) {
8863 /* doubleword */
8864 ARCH(5TE);
8865 if (rd & 1) {
8866 /* UNPREDICTABLE; we choose to UNDEF */
8867 goto illegal_op;
8869 load = (sh & 1) == 0;
8870 doubleword = true;
8873 addr = load_reg(s, rn);
8874 if (pbit) {
8875 gen_add_datah_offset(s, insn, 0, addr);
8877 address_offset = 0;
8879 if (doubleword) {
8880 if (!load) {
8881 /* store */
8882 tmp = load_reg(s, rd);
8883 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8884 tcg_temp_free_i32(tmp);
8885 tcg_gen_addi_i32(addr, addr, 4);
8886 tmp = load_reg(s, rd + 1);
8887 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8888 tcg_temp_free_i32(tmp);
8889 } else {
8890 /* load */
8891 tmp = tcg_temp_new_i32();
8892 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8893 store_reg(s, rd, tmp);
8894 tcg_gen_addi_i32(addr, addr, 4);
8895 tmp = tcg_temp_new_i32();
8896 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8897 rd++;
8899 address_offset = -4;
8900 } else if (load) {
8901 /* load */
8902 tmp = tcg_temp_new_i32();
8903 switch (sh) {
8904 case 1:
8905 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8906 issinfo);
8907 break;
8908 case 2:
8909 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8910 issinfo);
8911 break;
8912 default:
8913 case 3:
8914 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8915 issinfo);
8916 break;
8918 } else {
8919 /* store */
8920 tmp = load_reg(s, rd);
8921 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8922 tcg_temp_free_i32(tmp);
8924 /* Perform base writeback before the loaded value to
8925 ensure correct behavior with overlapping index registers.
8926 ldrd with base writeback is undefined if the
8927 destination and index registers overlap. */
8928 if (!pbit) {
8929 gen_add_datah_offset(s, insn, address_offset, addr);
8930 store_reg(s, rn, addr);
8931 } else if (wbit) {
8932 if (address_offset)
8933 tcg_gen_addi_i32(addr, addr, address_offset);
8934 store_reg(s, rn, addr);
8935 } else {
8936 tcg_temp_free_i32(addr);
8938 if (load) {
8939 /* Complete the load. */
8940 store_reg(s, rd, tmp);
8943 break;
8944 case 0x4:
8945 case 0x5:
8946 goto do_ldst;
8947 case 0x6:
8948 case 0x7:
8949 if (insn & (1 << 4)) {
8950 ARCH(6);
8951 /* Armv6 Media instructions. */
8952 rm = insn & 0xf;
8953 rn = (insn >> 16) & 0xf;
8954 rd = (insn >> 12) & 0xf;
8955 rs = (insn >> 8) & 0xf;
8956 switch ((insn >> 23) & 3) {
8957 case 0: /* Parallel add/subtract. */
8958 op1 = (insn >> 20) & 7;
8959 tmp = load_reg(s, rn);
8960 tmp2 = load_reg(s, rm);
8961 sh = (insn >> 5) & 7;
8962 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8963 goto illegal_op;
8964 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8965 tcg_temp_free_i32(tmp2);
8966 store_reg(s, rd, tmp);
8967 break;
8968 case 1:
8969 if ((insn & 0x00700020) == 0) {
8970 /* Halfword pack. */
8971 tmp = load_reg(s, rn);
8972 tmp2 = load_reg(s, rm);
8973 shift = (insn >> 7) & 0x1f;
8974 if (insn & (1 << 6)) {
8975 /* pkhtb */
8976 if (shift == 0)
8977 shift = 31;
8978 tcg_gen_sari_i32(tmp2, tmp2, shift);
8979 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8980 tcg_gen_ext16u_i32(tmp2, tmp2);
8981 } else {
8982 /* pkhbt */
8983 if (shift)
8984 tcg_gen_shli_i32(tmp2, tmp2, shift);
8985 tcg_gen_ext16u_i32(tmp, tmp);
8986 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8988 tcg_gen_or_i32(tmp, tmp, tmp2);
8989 tcg_temp_free_i32(tmp2);
8990 store_reg(s, rd, tmp);
8991 } else if ((insn & 0x00200020) == 0x00200000) {
8992 /* [us]sat */
8993 tmp = load_reg(s, rm);
8994 shift = (insn >> 7) & 0x1f;
8995 if (insn & (1 << 6)) {
8996 if (shift == 0)
8997 shift = 31;
8998 tcg_gen_sari_i32(tmp, tmp, shift);
8999 } else {
9000 tcg_gen_shli_i32(tmp, tmp, shift);
9002 sh = (insn >> 16) & 0x1f;
9003 tmp2 = tcg_const_i32(sh);
9004 if (insn & (1 << 22))
9005 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9006 else
9007 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9008 tcg_temp_free_i32(tmp2);
9009 store_reg(s, rd, tmp);
9010 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9011 /* [us]sat16 */
9012 tmp = load_reg(s, rm);
9013 sh = (insn >> 16) & 0x1f;
9014 tmp2 = tcg_const_i32(sh);
9015 if (insn & (1 << 22))
9016 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9017 else
9018 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9019 tcg_temp_free_i32(tmp2);
9020 store_reg(s, rd, tmp);
9021 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9022 /* Select bytes. */
9023 tmp = load_reg(s, rn);
9024 tmp2 = load_reg(s, rm);
9025 tmp3 = tcg_temp_new_i32();
9026 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9027 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9028 tcg_temp_free_i32(tmp3);
9029 tcg_temp_free_i32(tmp2);
9030 store_reg(s, rd, tmp);
9031 } else if ((insn & 0x000003e0) == 0x00000060) {
9032 tmp = load_reg(s, rm);
9033 shift = (insn >> 10) & 3;
9034 /* ??? In many cases it's not necessary to do a
9035 rotate, a shift is sufficient. */
9036 if (shift != 0)
9037 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9038 op1 = (insn >> 20) & 7;
9039 switch (op1) {
9040 case 0: gen_sxtb16(tmp); break;
9041 case 2: gen_sxtb(tmp); break;
9042 case 3: gen_sxth(tmp); break;
9043 case 4: gen_uxtb16(tmp); break;
9044 case 6: gen_uxtb(tmp); break;
9045 case 7: gen_uxth(tmp); break;
9046 default: goto illegal_op;
9048 if (rn != 15) {
9049 tmp2 = load_reg(s, rn);
9050 if ((op1 & 3) == 0) {
9051 gen_add16(tmp, tmp2);
9052 } else {
9053 tcg_gen_add_i32(tmp, tmp, tmp2);
9054 tcg_temp_free_i32(tmp2);
9057 store_reg(s, rd, tmp);
9058 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9059 /* rev */
9060 tmp = load_reg(s, rm);
9061 if (insn & (1 << 22)) {
9062 if (insn & (1 << 7)) {
9063 gen_revsh(tmp);
9064 } else {
9065 ARCH(6T2);
9066 gen_helper_rbit(tmp, tmp);
9068 } else {
9069 if (insn & (1 << 7))
9070 gen_rev16(tmp);
9071 else
9072 tcg_gen_bswap32_i32(tmp, tmp);
9074 store_reg(s, rd, tmp);
9075 } else {
9076 goto illegal_op;
9078 break;
9079 case 2: /* Multiplies (Type 3). */
9080 switch ((insn >> 20) & 0x7) {
9081 case 5:
9082 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9083 /* op2 not 00x or 11x : UNDEF */
9084 goto illegal_op;
9086 /* Signed multiply most significant [accumulate].
9087 (SMMUL, SMMLA, SMMLS) */
9088 tmp = load_reg(s, rm);
9089 tmp2 = load_reg(s, rs);
9090 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9092 if (rd != 15) {
9093 tmp = load_reg(s, rd);
9094 if (insn & (1 << 6)) {
9095 tmp64 = gen_subq_msw(tmp64, tmp);
9096 } else {
9097 tmp64 = gen_addq_msw(tmp64, tmp);
9100 if (insn & (1 << 5)) {
9101 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9103 tcg_gen_shri_i64(tmp64, tmp64, 32);
9104 tmp = tcg_temp_new_i32();
9105 tcg_gen_extrl_i64_i32(tmp, tmp64);
9106 tcg_temp_free_i64(tmp64);
9107 store_reg(s, rn, tmp);
9108 break;
9109 case 0:
9110 case 4:
9111 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9112 if (insn & (1 << 7)) {
9113 goto illegal_op;
9115 tmp = load_reg(s, rm);
9116 tmp2 = load_reg(s, rs);
9117 if (insn & (1 << 5))
9118 gen_swap_half(tmp2);
9119 gen_smul_dual(tmp, tmp2);
9120 if (insn & (1 << 22)) {
9121 /* smlald, smlsld */
9122 TCGv_i64 tmp64_2;
9124 tmp64 = tcg_temp_new_i64();
9125 tmp64_2 = tcg_temp_new_i64();
9126 tcg_gen_ext_i32_i64(tmp64, tmp);
9127 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9128 tcg_temp_free_i32(tmp);
9129 tcg_temp_free_i32(tmp2);
9130 if (insn & (1 << 6)) {
9131 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9132 } else {
9133 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9135 tcg_temp_free_i64(tmp64_2);
9136 gen_addq(s, tmp64, rd, rn);
9137 gen_storeq_reg(s, rd, rn, tmp64);
9138 tcg_temp_free_i64(tmp64);
9139 } else {
9140 /* smuad, smusd, smlad, smlsd */
9141 if (insn & (1 << 6)) {
9142 /* This subtraction cannot overflow. */
9143 tcg_gen_sub_i32(tmp, tmp, tmp2);
9144 } else {
9145 /* This addition cannot overflow 32 bits;
9146 * however it may overflow considered as a
9147 * signed operation, in which case we must set
9148 * the Q flag.
9150 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9152 tcg_temp_free_i32(tmp2);
9153 if (rd != 15)
9155 tmp2 = load_reg(s, rd);
9156 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9157 tcg_temp_free_i32(tmp2);
9159 store_reg(s, rn, tmp);
9161 break;
9162 case 1:
9163 case 3:
9164 /* SDIV, UDIV */
9165 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9166 goto illegal_op;
9168 if (((insn >> 5) & 7) || (rd != 15)) {
9169 goto illegal_op;
9171 tmp = load_reg(s, rm);
9172 tmp2 = load_reg(s, rs);
9173 if (insn & (1 << 21)) {
9174 gen_helper_udiv(tmp, tmp, tmp2);
9175 } else {
9176 gen_helper_sdiv(tmp, tmp, tmp2);
9178 tcg_temp_free_i32(tmp2);
9179 store_reg(s, rn, tmp);
9180 break;
9181 default:
9182 goto illegal_op;
9184 break;
9185 case 3:
9186 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9187 switch (op1) {
9188 case 0: /* Unsigned sum of absolute differences. */
9189 ARCH(6);
9190 tmp = load_reg(s, rm);
9191 tmp2 = load_reg(s, rs);
9192 gen_helper_usad8(tmp, tmp, tmp2);
9193 tcg_temp_free_i32(tmp2);
9194 if (rd != 15) {
9195 tmp2 = load_reg(s, rd);
9196 tcg_gen_add_i32(tmp, tmp, tmp2);
9197 tcg_temp_free_i32(tmp2);
9199 store_reg(s, rn, tmp);
9200 break;
9201 case 0x20: case 0x24: case 0x28: case 0x2c:
9202 /* Bitfield insert/clear. */
9203 ARCH(6T2);
9204 shift = (insn >> 7) & 0x1f;
9205 i = (insn >> 16) & 0x1f;
9206 if (i < shift) {
9207 /* UNPREDICTABLE; we choose to UNDEF */
9208 goto illegal_op;
9210 i = i + 1 - shift;
9211 if (rm == 15) {
9212 tmp = tcg_temp_new_i32();
9213 tcg_gen_movi_i32(tmp, 0);
9214 } else {
9215 tmp = load_reg(s, rm);
9217 if (i != 32) {
9218 tmp2 = load_reg(s, rd);
9219 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9220 tcg_temp_free_i32(tmp2);
9222 store_reg(s, rd, tmp);
9223 break;
9224 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9225 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9226 ARCH(6T2);
9227 tmp = load_reg(s, rm);
9228 shift = (insn >> 7) & 0x1f;
9229 i = ((insn >> 16) & 0x1f) + 1;
9230 if (shift + i > 32)
9231 goto illegal_op;
9232 if (i < 32) {
9233 if (op1 & 0x20) {
9234 tcg_gen_extract_i32(tmp, tmp, shift, i);
9235 } else {
9236 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9239 store_reg(s, rd, tmp);
9240 break;
9241 default:
9242 goto illegal_op;
9244 break;
9246 break;
9248 do_ldst:
9249 /* Check for undefined extension instructions
9250 * per the ARM Bible IE:
9251 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9253 sh = (0xf << 20) | (0xf << 4);
9254 if (op1 == 0x7 && ((insn & sh) == sh))
9256 goto illegal_op;
9258 /* load/store byte/word */
9259 rn = (insn >> 16) & 0xf;
9260 rd = (insn >> 12) & 0xf;
9261 tmp2 = load_reg(s, rn);
9262 if ((insn & 0x01200000) == 0x00200000) {
9263 /* ldrt/strt */
9264 i = get_a32_user_mem_index(s);
9265 } else {
9266 i = get_mem_index(s);
9268 if (insn & (1 << 24))
9269 gen_add_data_offset(s, insn, tmp2);
9270 if (insn & (1 << 20)) {
9271 /* load */
9272 tmp = tcg_temp_new_i32();
9273 if (insn & (1 << 22)) {
9274 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9275 } else {
9276 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9278 } else {
9279 /* store */
9280 tmp = load_reg(s, rd);
9281 if (insn & (1 << 22)) {
9282 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9283 } else {
9284 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9286 tcg_temp_free_i32(tmp);
9288 if (!(insn & (1 << 24))) {
9289 gen_add_data_offset(s, insn, tmp2);
9290 store_reg(s, rn, tmp2);
9291 } else if (insn & (1 << 21)) {
9292 store_reg(s, rn, tmp2);
9293 } else {
9294 tcg_temp_free_i32(tmp2);
9296 if (insn & (1 << 20)) {
9297 /* Complete the load. */
9298 store_reg_from_load(s, rd, tmp);
9300 break;
9301 case 0x08:
9302 case 0x09:
9304 int j, n, loaded_base;
9305 bool exc_return = false;
9306 bool is_load = extract32(insn, 20, 1);
9307 bool user = false;
9308 TCGv_i32 loaded_var;
9309 /* load/store multiple words */
9310 /* XXX: store correct base if write back */
9311 if (insn & (1 << 22)) {
9312 /* LDM (user), LDM (exception return) and STM (user) */
9313 if (IS_USER(s))
9314 goto illegal_op; /* only usable in supervisor mode */
9316 if (is_load && extract32(insn, 15, 1)) {
9317 exc_return = true;
9318 } else {
9319 user = true;
9322 rn = (insn >> 16) & 0xf;
9323 addr = load_reg(s, rn);
9325 /* compute total size */
9326 loaded_base = 0;
9327 TCGV_UNUSED_I32(loaded_var);
9328 n = 0;
9329 for(i=0;i<16;i++) {
9330 if (insn & (1 << i))
9331 n++;
9333 /* XXX: test invalid n == 0 case ? */
9334 if (insn & (1 << 23)) {
9335 if (insn & (1 << 24)) {
9336 /* pre increment */
9337 tcg_gen_addi_i32(addr, addr, 4);
9338 } else {
9339 /* post increment */
9341 } else {
9342 if (insn & (1 << 24)) {
9343 /* pre decrement */
9344 tcg_gen_addi_i32(addr, addr, -(n * 4));
9345 } else {
9346 /* post decrement */
9347 if (n != 1)
9348 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9351 j = 0;
9352 for(i=0;i<16;i++) {
9353 if (insn & (1 << i)) {
9354 if (is_load) {
9355 /* load */
9356 tmp = tcg_temp_new_i32();
9357 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9358 if (user) {
9359 tmp2 = tcg_const_i32(i);
9360 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9361 tcg_temp_free_i32(tmp2);
9362 tcg_temp_free_i32(tmp);
9363 } else if (i == rn) {
9364 loaded_var = tmp;
9365 loaded_base = 1;
9366 } else if (rn == 15 && exc_return) {
9367 store_pc_exc_ret(s, tmp);
9368 } else {
9369 store_reg_from_load(s, i, tmp);
9371 } else {
9372 /* store */
9373 if (i == 15) {
9374 /* special case: r15 = PC + 8 */
9375 val = (long)s->pc + 4;
9376 tmp = tcg_temp_new_i32();
9377 tcg_gen_movi_i32(tmp, val);
9378 } else if (user) {
9379 tmp = tcg_temp_new_i32();
9380 tmp2 = tcg_const_i32(i);
9381 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9382 tcg_temp_free_i32(tmp2);
9383 } else {
9384 tmp = load_reg(s, i);
9386 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9387 tcg_temp_free_i32(tmp);
9389 j++;
9390 /* no need to add after the last transfer */
9391 if (j != n)
9392 tcg_gen_addi_i32(addr, addr, 4);
9395 if (insn & (1 << 21)) {
9396 /* write back */
9397 if (insn & (1 << 23)) {
9398 if (insn & (1 << 24)) {
9399 /* pre increment */
9400 } else {
9401 /* post increment */
9402 tcg_gen_addi_i32(addr, addr, 4);
9404 } else {
9405 if (insn & (1 << 24)) {
9406 /* pre decrement */
9407 if (n != 1)
9408 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9409 } else {
9410 /* post decrement */
9411 tcg_gen_addi_i32(addr, addr, -(n * 4));
9414 store_reg(s, rn, addr);
9415 } else {
9416 tcg_temp_free_i32(addr);
9418 if (loaded_base) {
9419 store_reg(s, rn, loaded_var);
9421 if (exc_return) {
9422 /* Restore CPSR from SPSR. */
9423 tmp = load_cpu_field(spsr);
9424 gen_helper_cpsr_write_eret(cpu_env, tmp);
9425 tcg_temp_free_i32(tmp);
9426 s->is_jmp = DISAS_JUMP;
9429 break;
9430 case 0xa:
9431 case 0xb:
9433 int32_t offset;
9435 /* branch (and link) */
9436 val = (int32_t)s->pc;
9437 if (insn & (1 << 24)) {
9438 tmp = tcg_temp_new_i32();
9439 tcg_gen_movi_i32(tmp, val);
9440 store_reg(s, 14, tmp);
9442 offset = sextract32(insn << 2, 0, 26);
9443 val += offset + 4;
9444 gen_jmp(s, val);
9446 break;
9447 case 0xc:
9448 case 0xd:
9449 case 0xe:
9450 if (((insn >> 8) & 0xe) == 10) {
9451 /* VFP. */
9452 if (disas_vfp_insn(s, insn)) {
9453 goto illegal_op;
9455 } else if (disas_coproc_insn(s, insn)) {
9456 /* Coprocessor. */
9457 goto illegal_op;
9459 break;
9460 case 0xf:
9461 /* swi */
9462 gen_set_pc_im(s, s->pc);
9463 s->svc_imm = extract32(insn, 0, 24);
9464 s->is_jmp = DISAS_SWI;
9465 break;
9466 default:
9467 illegal_op:
9468 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9469 default_exception_el(s));
9470 break;
9475 /* Return true if this is a Thumb-2 logical op. */
9476 static int
9477 thumb2_logic_op(int op)
9479 return (op < 8);
9482 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9483 then set condition code flags based on the result of the operation.
9484 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9485 to the high bit of T1.
9486 Returns zero if the opcode is valid. */
9488 static int
9489 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9490 TCGv_i32 t0, TCGv_i32 t1)
9492 int logic_cc;
9494 logic_cc = 0;
9495 switch (op) {
9496 case 0: /* and */
9497 tcg_gen_and_i32(t0, t0, t1);
9498 logic_cc = conds;
9499 break;
9500 case 1: /* bic */
9501 tcg_gen_andc_i32(t0, t0, t1);
9502 logic_cc = conds;
9503 break;
9504 case 2: /* orr */
9505 tcg_gen_or_i32(t0, t0, t1);
9506 logic_cc = conds;
9507 break;
9508 case 3: /* orn */
9509 tcg_gen_orc_i32(t0, t0, t1);
9510 logic_cc = conds;
9511 break;
9512 case 4: /* eor */
9513 tcg_gen_xor_i32(t0, t0, t1);
9514 logic_cc = conds;
9515 break;
9516 case 8: /* add */
9517 if (conds)
9518 gen_add_CC(t0, t0, t1);
9519 else
9520 tcg_gen_add_i32(t0, t0, t1);
9521 break;
9522 case 10: /* adc */
9523 if (conds)
9524 gen_adc_CC(t0, t0, t1);
9525 else
9526 gen_adc(t0, t1);
9527 break;
9528 case 11: /* sbc */
9529 if (conds) {
9530 gen_sbc_CC(t0, t0, t1);
9531 } else {
9532 gen_sub_carry(t0, t0, t1);
9534 break;
9535 case 13: /* sub */
9536 if (conds)
9537 gen_sub_CC(t0, t0, t1);
9538 else
9539 tcg_gen_sub_i32(t0, t0, t1);
9540 break;
9541 case 14: /* rsb */
9542 if (conds)
9543 gen_sub_CC(t0, t1, t0);
9544 else
9545 tcg_gen_sub_i32(t0, t1, t0);
9546 break;
9547 default: /* 5, 6, 7, 9, 12, 15. */
9548 return 1;
9550 if (logic_cc) {
9551 gen_logic_CC(t0);
9552 if (shifter_out)
9553 gen_set_CF_bit31(t1);
9555 return 0;
9558 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9559 is not legal. */
9560 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9562 uint32_t insn, imm, shift, offset;
9563 uint32_t rd, rn, rm, rs;
9564 TCGv_i32 tmp;
9565 TCGv_i32 tmp2;
9566 TCGv_i32 tmp3;
9567 TCGv_i32 addr;
9568 TCGv_i64 tmp64;
9569 int op;
9570 int shiftop;
9571 int conds;
9572 int logic_cc;
9574 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9575 || arm_dc_feature(s, ARM_FEATURE_M))) {
9576 /* Thumb-1 cores may need to treat bl and blx as a pair of
9577 16-bit instructions to get correct prefetch abort behavior. */
9578 insn = insn_hw1;
9579 if ((insn & (1 << 12)) == 0) {
9580 ARCH(5);
9581 /* Second half of blx. */
9582 offset = ((insn & 0x7ff) << 1);
9583 tmp = load_reg(s, 14);
9584 tcg_gen_addi_i32(tmp, tmp, offset);
9585 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9587 tmp2 = tcg_temp_new_i32();
9588 tcg_gen_movi_i32(tmp2, s->pc | 1);
9589 store_reg(s, 14, tmp2);
9590 gen_bx(s, tmp);
9591 return 0;
9593 if (insn & (1 << 11)) {
9594 /* Second half of bl. */
9595 offset = ((insn & 0x7ff) << 1) | 1;
9596 tmp = load_reg(s, 14);
9597 tcg_gen_addi_i32(tmp, tmp, offset);
9599 tmp2 = tcg_temp_new_i32();
9600 tcg_gen_movi_i32(tmp2, s->pc | 1);
9601 store_reg(s, 14, tmp2);
9602 gen_bx(s, tmp);
9603 return 0;
9605 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9606 /* Instruction spans a page boundary. Implement it as two
9607 16-bit instructions in case the second half causes an
9608 prefetch abort. */
9609 offset = ((int32_t)insn << 21) >> 9;
9610 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9611 return 0;
9613 /* Fall through to 32-bit decode. */
9616 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9617 s->pc += 2;
9618 insn |= (uint32_t)insn_hw1 << 16;
9620 if ((insn & 0xf800e800) != 0xf000e800) {
9621 ARCH(6T2);
9624 rn = (insn >> 16) & 0xf;
9625 rs = (insn >> 12) & 0xf;
9626 rd = (insn >> 8) & 0xf;
9627 rm = insn & 0xf;
9628 switch ((insn >> 25) & 0xf) {
9629 case 0: case 1: case 2: case 3:
9630 /* 16-bit instructions. Should never happen. */
9631 abort();
9632 case 4:
9633 if (insn & (1 << 22)) {
9634 /* Other load/store, table branch. */
9635 if (insn & 0x01200000) {
9636 /* Load/store doubleword. */
9637 if (rn == 15) {
9638 addr = tcg_temp_new_i32();
9639 tcg_gen_movi_i32(addr, s->pc & ~3);
9640 } else {
9641 addr = load_reg(s, rn);
9643 offset = (insn & 0xff) * 4;
9644 if ((insn & (1 << 23)) == 0)
9645 offset = -offset;
9646 if (insn & (1 << 24)) {
9647 tcg_gen_addi_i32(addr, addr, offset);
9648 offset = 0;
9650 if (insn & (1 << 20)) {
9651 /* ldrd */
9652 tmp = tcg_temp_new_i32();
9653 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9654 store_reg(s, rs, tmp);
9655 tcg_gen_addi_i32(addr, addr, 4);
9656 tmp = tcg_temp_new_i32();
9657 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9658 store_reg(s, rd, tmp);
9659 } else {
9660 /* strd */
9661 tmp = load_reg(s, rs);
9662 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9663 tcg_temp_free_i32(tmp);
9664 tcg_gen_addi_i32(addr, addr, 4);
9665 tmp = load_reg(s, rd);
9666 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9667 tcg_temp_free_i32(tmp);
9669 if (insn & (1 << 21)) {
9670 /* Base writeback. */
9671 if (rn == 15)
9672 goto illegal_op;
9673 tcg_gen_addi_i32(addr, addr, offset - 4);
9674 store_reg(s, rn, addr);
9675 } else {
9676 tcg_temp_free_i32(addr);
9678 } else if ((insn & (1 << 23)) == 0) {
9679 /* Load/store exclusive word. */
9680 addr = tcg_temp_local_new_i32();
9681 load_reg_var(s, addr, rn);
9682 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9683 if (insn & (1 << 20)) {
9684 gen_load_exclusive(s, rs, 15, addr, 2);
9685 } else {
9686 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9688 tcg_temp_free_i32(addr);
9689 } else if ((insn & (7 << 5)) == 0) {
9690 /* Table Branch. */
9691 if (rn == 15) {
9692 addr = tcg_temp_new_i32();
9693 tcg_gen_movi_i32(addr, s->pc);
9694 } else {
9695 addr = load_reg(s, rn);
9697 tmp = load_reg(s, rm);
9698 tcg_gen_add_i32(addr, addr, tmp);
9699 if (insn & (1 << 4)) {
9700 /* tbh */
9701 tcg_gen_add_i32(addr, addr, tmp);
9702 tcg_temp_free_i32(tmp);
9703 tmp = tcg_temp_new_i32();
9704 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9705 } else { /* tbb */
9706 tcg_temp_free_i32(tmp);
9707 tmp = tcg_temp_new_i32();
9708 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9710 tcg_temp_free_i32(addr);
9711 tcg_gen_shli_i32(tmp, tmp, 1);
9712 tcg_gen_addi_i32(tmp, tmp, s->pc);
9713 store_reg(s, 15, tmp);
9714 } else {
9715 int op2 = (insn >> 6) & 0x3;
9716 op = (insn >> 4) & 0x3;
9717 switch (op2) {
9718 case 0:
9719 goto illegal_op;
9720 case 1:
9721 /* Load/store exclusive byte/halfword/doubleword */
9722 if (op == 2) {
9723 goto illegal_op;
9725 ARCH(7);
9726 break;
9727 case 2:
9728 /* Load-acquire/store-release */
9729 if (op == 3) {
9730 goto illegal_op;
9732 /* Fall through */
9733 case 3:
9734 /* Load-acquire/store-release exclusive */
9735 ARCH(8);
9736 break;
9738 addr = tcg_temp_local_new_i32();
9739 load_reg_var(s, addr, rn);
9740 if (!(op2 & 1)) {
9741 if (insn & (1 << 20)) {
9742 tmp = tcg_temp_new_i32();
9743 switch (op) {
9744 case 0: /* ldab */
9745 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9746 rs | ISSIsAcqRel);
9747 break;
9748 case 1: /* ldah */
9749 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9750 rs | ISSIsAcqRel);
9751 break;
9752 case 2: /* lda */
9753 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9754 rs | ISSIsAcqRel);
9755 break;
9756 default:
9757 abort();
9759 store_reg(s, rs, tmp);
9760 } else {
9761 tmp = load_reg(s, rs);
9762 switch (op) {
9763 case 0: /* stlb */
9764 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9765 rs | ISSIsAcqRel);
9766 break;
9767 case 1: /* stlh */
9768 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9769 rs | ISSIsAcqRel);
9770 break;
9771 case 2: /* stl */
9772 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9773 rs | ISSIsAcqRel);
9774 break;
9775 default:
9776 abort();
9778 tcg_temp_free_i32(tmp);
9780 } else if (insn & (1 << 20)) {
9781 gen_load_exclusive(s, rs, rd, addr, op);
9782 } else {
9783 gen_store_exclusive(s, rm, rs, rd, addr, op);
9785 tcg_temp_free_i32(addr);
9787 } else {
9788 /* Load/store multiple, RFE, SRS. */
9789 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9790 /* RFE, SRS: not available in user mode or on M profile */
9791 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9792 goto illegal_op;
9794 if (insn & (1 << 20)) {
9795 /* rfe */
9796 addr = load_reg(s, rn);
9797 if ((insn & (1 << 24)) == 0)
9798 tcg_gen_addi_i32(addr, addr, -8);
9799 /* Load PC into tmp and CPSR into tmp2. */
9800 tmp = tcg_temp_new_i32();
9801 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9802 tcg_gen_addi_i32(addr, addr, 4);
9803 tmp2 = tcg_temp_new_i32();
9804 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9805 if (insn & (1 << 21)) {
9806 /* Base writeback. */
9807 if (insn & (1 << 24)) {
9808 tcg_gen_addi_i32(addr, addr, 4);
9809 } else {
9810 tcg_gen_addi_i32(addr, addr, -4);
9812 store_reg(s, rn, addr);
9813 } else {
9814 tcg_temp_free_i32(addr);
9816 gen_rfe(s, tmp, tmp2);
9817 } else {
9818 /* srs */
9819 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9820 insn & (1 << 21));
9822 } else {
9823 int i, loaded_base = 0;
9824 TCGv_i32 loaded_var;
9825 /* Load/store multiple. */
9826 addr = load_reg(s, rn);
9827 offset = 0;
9828 for (i = 0; i < 16; i++) {
9829 if (insn & (1 << i))
9830 offset += 4;
9832 if (insn & (1 << 24)) {
9833 tcg_gen_addi_i32(addr, addr, -offset);
9836 TCGV_UNUSED_I32(loaded_var);
9837 for (i = 0; i < 16; i++) {
9838 if ((insn & (1 << i)) == 0)
9839 continue;
9840 if (insn & (1 << 20)) {
9841 /* Load. */
9842 tmp = tcg_temp_new_i32();
9843 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9844 if (i == 15) {
9845 gen_bx(s, tmp);
9846 } else if (i == rn) {
9847 loaded_var = tmp;
9848 loaded_base = 1;
9849 } else {
9850 store_reg(s, i, tmp);
9852 } else {
9853 /* Store. */
9854 tmp = load_reg(s, i);
9855 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9856 tcg_temp_free_i32(tmp);
9858 tcg_gen_addi_i32(addr, addr, 4);
9860 if (loaded_base) {
9861 store_reg(s, rn, loaded_var);
9863 if (insn & (1 << 21)) {
9864 /* Base register writeback. */
9865 if (insn & (1 << 24)) {
9866 tcg_gen_addi_i32(addr, addr, -offset);
9868 /* Fault if writeback register is in register list. */
9869 if (insn & (1 << rn))
9870 goto illegal_op;
9871 store_reg(s, rn, addr);
9872 } else {
9873 tcg_temp_free_i32(addr);
9877 break;
9878 case 5:
9880 op = (insn >> 21) & 0xf;
9881 if (op == 6) {
9882 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9883 goto illegal_op;
9885 /* Halfword pack. */
9886 tmp = load_reg(s, rn);
9887 tmp2 = load_reg(s, rm);
9888 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9889 if (insn & (1 << 5)) {
9890 /* pkhtb */
9891 if (shift == 0)
9892 shift = 31;
9893 tcg_gen_sari_i32(tmp2, tmp2, shift);
9894 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9895 tcg_gen_ext16u_i32(tmp2, tmp2);
9896 } else {
9897 /* pkhbt */
9898 if (shift)
9899 tcg_gen_shli_i32(tmp2, tmp2, shift);
9900 tcg_gen_ext16u_i32(tmp, tmp);
9901 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9903 tcg_gen_or_i32(tmp, tmp, tmp2);
9904 tcg_temp_free_i32(tmp2);
9905 store_reg(s, rd, tmp);
9906 } else {
9907 /* Data processing register constant shift. */
9908 if (rn == 15) {
9909 tmp = tcg_temp_new_i32();
9910 tcg_gen_movi_i32(tmp, 0);
9911 } else {
9912 tmp = load_reg(s, rn);
9914 tmp2 = load_reg(s, rm);
9916 shiftop = (insn >> 4) & 3;
9917 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9918 conds = (insn & (1 << 20)) != 0;
9919 logic_cc = (conds && thumb2_logic_op(op));
9920 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9921 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9922 goto illegal_op;
9923 tcg_temp_free_i32(tmp2);
9924 if (rd != 15) {
9925 store_reg(s, rd, tmp);
9926 } else {
9927 tcg_temp_free_i32(tmp);
9930 break;
9931 case 13: /* Misc data processing. */
9932 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9933 if (op < 4 && (insn & 0xf000) != 0xf000)
9934 goto illegal_op;
9935 switch (op) {
9936 case 0: /* Register controlled shift. */
9937 tmp = load_reg(s, rn);
9938 tmp2 = load_reg(s, rm);
9939 if ((insn & 0x70) != 0)
9940 goto illegal_op;
9941 op = (insn >> 21) & 3;
9942 logic_cc = (insn & (1 << 20)) != 0;
9943 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9944 if (logic_cc)
9945 gen_logic_CC(tmp);
9946 store_reg_bx(s, rd, tmp);
9947 break;
9948 case 1: /* Sign/zero extend. */
9949 op = (insn >> 20) & 7;
9950 switch (op) {
9951 case 0: /* SXTAH, SXTH */
9952 case 1: /* UXTAH, UXTH */
9953 case 4: /* SXTAB, SXTB */
9954 case 5: /* UXTAB, UXTB */
9955 break;
9956 case 2: /* SXTAB16, SXTB16 */
9957 case 3: /* UXTAB16, UXTB16 */
9958 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9959 goto illegal_op;
9961 break;
9962 default:
9963 goto illegal_op;
9965 if (rn != 15) {
9966 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9967 goto illegal_op;
9970 tmp = load_reg(s, rm);
9971 shift = (insn >> 4) & 3;
9972 /* ??? In many cases it's not necessary to do a
9973 rotate, a shift is sufficient. */
9974 if (shift != 0)
9975 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9976 op = (insn >> 20) & 7;
9977 switch (op) {
9978 case 0: gen_sxth(tmp); break;
9979 case 1: gen_uxth(tmp); break;
9980 case 2: gen_sxtb16(tmp); break;
9981 case 3: gen_uxtb16(tmp); break;
9982 case 4: gen_sxtb(tmp); break;
9983 case 5: gen_uxtb(tmp); break;
9984 default:
9985 g_assert_not_reached();
9987 if (rn != 15) {
9988 tmp2 = load_reg(s, rn);
9989 if ((op >> 1) == 1) {
9990 gen_add16(tmp, tmp2);
9991 } else {
9992 tcg_gen_add_i32(tmp, tmp, tmp2);
9993 tcg_temp_free_i32(tmp2);
9996 store_reg(s, rd, tmp);
9997 break;
9998 case 2: /* SIMD add/subtract. */
9999 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10000 goto illegal_op;
10002 op = (insn >> 20) & 7;
10003 shift = (insn >> 4) & 7;
10004 if ((op & 3) == 3 || (shift & 3) == 3)
10005 goto illegal_op;
10006 tmp = load_reg(s, rn);
10007 tmp2 = load_reg(s, rm);
10008 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10009 tcg_temp_free_i32(tmp2);
10010 store_reg(s, rd, tmp);
10011 break;
10012 case 3: /* Other data processing. */
10013 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10014 if (op < 4) {
10015 /* Saturating add/subtract. */
10016 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10017 goto illegal_op;
10019 tmp = load_reg(s, rn);
10020 tmp2 = load_reg(s, rm);
10021 if (op & 1)
10022 gen_helper_double_saturate(tmp, cpu_env, tmp);
10023 if (op & 2)
10024 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10025 else
10026 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10027 tcg_temp_free_i32(tmp2);
10028 } else {
10029 switch (op) {
10030 case 0x0a: /* rbit */
10031 case 0x08: /* rev */
10032 case 0x09: /* rev16 */
10033 case 0x0b: /* revsh */
10034 case 0x18: /* clz */
10035 break;
10036 case 0x10: /* sel */
10037 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10038 goto illegal_op;
10040 break;
10041 case 0x20: /* crc32/crc32c */
10042 case 0x21:
10043 case 0x22:
10044 case 0x28:
10045 case 0x29:
10046 case 0x2a:
10047 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10048 goto illegal_op;
10050 break;
10051 default:
10052 goto illegal_op;
10054 tmp = load_reg(s, rn);
10055 switch (op) {
10056 case 0x0a: /* rbit */
10057 gen_helper_rbit(tmp, tmp);
10058 break;
10059 case 0x08: /* rev */
10060 tcg_gen_bswap32_i32(tmp, tmp);
10061 break;
10062 case 0x09: /* rev16 */
10063 gen_rev16(tmp);
10064 break;
10065 case 0x0b: /* revsh */
10066 gen_revsh(tmp);
10067 break;
10068 case 0x10: /* sel */
10069 tmp2 = load_reg(s, rm);
10070 tmp3 = tcg_temp_new_i32();
10071 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10072 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10073 tcg_temp_free_i32(tmp3);
10074 tcg_temp_free_i32(tmp2);
10075 break;
10076 case 0x18: /* clz */
10077 tcg_gen_clzi_i32(tmp, tmp, 32);
10078 break;
10079 case 0x20:
10080 case 0x21:
10081 case 0x22:
10082 case 0x28:
10083 case 0x29:
10084 case 0x2a:
10086 /* crc32/crc32c */
10087 uint32_t sz = op & 0x3;
10088 uint32_t c = op & 0x8;
10090 tmp2 = load_reg(s, rm);
10091 if (sz == 0) {
10092 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10093 } else if (sz == 1) {
10094 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10096 tmp3 = tcg_const_i32(1 << sz);
10097 if (c) {
10098 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10099 } else {
10100 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10102 tcg_temp_free_i32(tmp2);
10103 tcg_temp_free_i32(tmp3);
10104 break;
10106 default:
10107 g_assert_not_reached();
10110 store_reg(s, rd, tmp);
10111 break;
10112 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10113 switch ((insn >> 20) & 7) {
10114 case 0: /* 32 x 32 -> 32 */
10115 case 7: /* Unsigned sum of absolute differences. */
10116 break;
10117 case 1: /* 16 x 16 -> 32 */
10118 case 2: /* Dual multiply add. */
10119 case 3: /* 32 * 16 -> 32msb */
10120 case 4: /* Dual multiply subtract. */
10121 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10122 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10123 goto illegal_op;
10125 break;
10127 op = (insn >> 4) & 0xf;
10128 tmp = load_reg(s, rn);
10129 tmp2 = load_reg(s, rm);
10130 switch ((insn >> 20) & 7) {
10131 case 0: /* 32 x 32 -> 32 */
10132 tcg_gen_mul_i32(tmp, tmp, tmp2);
10133 tcg_temp_free_i32(tmp2);
10134 if (rs != 15) {
10135 tmp2 = load_reg(s, rs);
10136 if (op)
10137 tcg_gen_sub_i32(tmp, tmp2, tmp);
10138 else
10139 tcg_gen_add_i32(tmp, tmp, tmp2);
10140 tcg_temp_free_i32(tmp2);
10142 break;
10143 case 1: /* 16 x 16 -> 32 */
10144 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10145 tcg_temp_free_i32(tmp2);
10146 if (rs != 15) {
10147 tmp2 = load_reg(s, rs);
10148 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10149 tcg_temp_free_i32(tmp2);
10151 break;
10152 case 2: /* Dual multiply add. */
10153 case 4: /* Dual multiply subtract. */
10154 if (op)
10155 gen_swap_half(tmp2);
10156 gen_smul_dual(tmp, tmp2);
10157 if (insn & (1 << 22)) {
10158 /* This subtraction cannot overflow. */
10159 tcg_gen_sub_i32(tmp, tmp, tmp2);
10160 } else {
10161 /* This addition cannot overflow 32 bits;
10162 * however it may overflow considered as a signed
10163 * operation, in which case we must set the Q flag.
10165 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10167 tcg_temp_free_i32(tmp2);
10168 if (rs != 15)
10170 tmp2 = load_reg(s, rs);
10171 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10172 tcg_temp_free_i32(tmp2);
10174 break;
10175 case 3: /* 32 * 16 -> 32msb */
10176 if (op)
10177 tcg_gen_sari_i32(tmp2, tmp2, 16);
10178 else
10179 gen_sxth(tmp2);
10180 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10181 tcg_gen_shri_i64(tmp64, tmp64, 16);
10182 tmp = tcg_temp_new_i32();
10183 tcg_gen_extrl_i64_i32(tmp, tmp64);
10184 tcg_temp_free_i64(tmp64);
10185 if (rs != 15)
10187 tmp2 = load_reg(s, rs);
10188 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10189 tcg_temp_free_i32(tmp2);
10191 break;
10192 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10193 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10194 if (rs != 15) {
10195 tmp = load_reg(s, rs);
10196 if (insn & (1 << 20)) {
10197 tmp64 = gen_addq_msw(tmp64, tmp);
10198 } else {
10199 tmp64 = gen_subq_msw(tmp64, tmp);
10202 if (insn & (1 << 4)) {
10203 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10205 tcg_gen_shri_i64(tmp64, tmp64, 32);
10206 tmp = tcg_temp_new_i32();
10207 tcg_gen_extrl_i64_i32(tmp, tmp64);
10208 tcg_temp_free_i64(tmp64);
10209 break;
10210 case 7: /* Unsigned sum of absolute differences. */
10211 gen_helper_usad8(tmp, tmp, tmp2);
10212 tcg_temp_free_i32(tmp2);
10213 if (rs != 15) {
10214 tmp2 = load_reg(s, rs);
10215 tcg_gen_add_i32(tmp, tmp, tmp2);
10216 tcg_temp_free_i32(tmp2);
10218 break;
10220 store_reg(s, rd, tmp);
10221 break;
10222 case 6: case 7: /* 64-bit multiply, Divide. */
10223 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10224 tmp = load_reg(s, rn);
10225 tmp2 = load_reg(s, rm);
10226 if ((op & 0x50) == 0x10) {
10227 /* sdiv, udiv */
10228 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10229 goto illegal_op;
10231 if (op & 0x20)
10232 gen_helper_udiv(tmp, tmp, tmp2);
10233 else
10234 gen_helper_sdiv(tmp, tmp, tmp2);
10235 tcg_temp_free_i32(tmp2);
10236 store_reg(s, rd, tmp);
10237 } else if ((op & 0xe) == 0xc) {
10238 /* Dual multiply accumulate long. */
10239 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10240 tcg_temp_free_i32(tmp);
10241 tcg_temp_free_i32(tmp2);
10242 goto illegal_op;
10244 if (op & 1)
10245 gen_swap_half(tmp2);
10246 gen_smul_dual(tmp, tmp2);
10247 if (op & 0x10) {
10248 tcg_gen_sub_i32(tmp, tmp, tmp2);
10249 } else {
10250 tcg_gen_add_i32(tmp, tmp, tmp2);
10252 tcg_temp_free_i32(tmp2);
10253 /* BUGFIX */
10254 tmp64 = tcg_temp_new_i64();
10255 tcg_gen_ext_i32_i64(tmp64, tmp);
10256 tcg_temp_free_i32(tmp);
10257 gen_addq(s, tmp64, rs, rd);
10258 gen_storeq_reg(s, rs, rd, tmp64);
10259 tcg_temp_free_i64(tmp64);
10260 } else {
10261 if (op & 0x20) {
10262 /* Unsigned 64-bit multiply */
10263 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10264 } else {
10265 if (op & 8) {
10266 /* smlalxy */
10267 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10268 tcg_temp_free_i32(tmp2);
10269 tcg_temp_free_i32(tmp);
10270 goto illegal_op;
10272 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10273 tcg_temp_free_i32(tmp2);
10274 tmp64 = tcg_temp_new_i64();
10275 tcg_gen_ext_i32_i64(tmp64, tmp);
10276 tcg_temp_free_i32(tmp);
10277 } else {
10278 /* Signed 64-bit multiply */
10279 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10282 if (op & 4) {
10283 /* umaal */
10284 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10285 tcg_temp_free_i64(tmp64);
10286 goto illegal_op;
10288 gen_addq_lo(s, tmp64, rs);
10289 gen_addq_lo(s, tmp64, rd);
10290 } else if (op & 0x40) {
10291 /* 64-bit accumulate. */
10292 gen_addq(s, tmp64, rs, rd);
10294 gen_storeq_reg(s, rs, rd, tmp64);
10295 tcg_temp_free_i64(tmp64);
10297 break;
10299 break;
10300 case 6: case 7: case 14: case 15:
10301 /* Coprocessor. */
10302 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10303 /* We don't currently implement M profile FP support,
10304 * so this entire space should give a NOCP fault.
10306 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10307 default_exception_el(s));
10308 break;
10310 if (((insn >> 24) & 3) == 3) {
10311 /* Translate into the equivalent ARM encoding. */
10312 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10313 if (disas_neon_data_insn(s, insn)) {
10314 goto illegal_op;
10316 } else if (((insn >> 8) & 0xe) == 10) {
10317 if (disas_vfp_insn(s, insn)) {
10318 goto illegal_op;
10320 } else {
10321 if (insn & (1 << 28))
10322 goto illegal_op;
10323 if (disas_coproc_insn(s, insn)) {
10324 goto illegal_op;
10327 break;
10328 case 8: case 9: case 10: case 11:
10329 if (insn & (1 << 15)) {
10330 /* Branches, misc control. */
10331 if (insn & 0x5000) {
10332 /* Unconditional branch. */
10333 /* signextend(hw1[10:0]) -> offset[:12]. */
10334 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10335 /* hw1[10:0] -> offset[11:1]. */
10336 offset |= (insn & 0x7ff) << 1;
10337 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10338 offset[24:22] already have the same value because of the
10339 sign extension above. */
10340 offset ^= ((~insn) & (1 << 13)) << 10;
10341 offset ^= ((~insn) & (1 << 11)) << 11;
10343 if (insn & (1 << 14)) {
10344 /* Branch and link. */
10345 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10348 offset += s->pc;
10349 if (insn & (1 << 12)) {
10350 /* b/bl */
10351 gen_jmp(s, offset);
10352 } else {
10353 /* blx */
10354 offset &= ~(uint32_t)2;
10355 /* thumb2 bx, no need to check */
10356 gen_bx_im(s, offset);
10358 } else if (((insn >> 23) & 7) == 7) {
10359 /* Misc control */
10360 if (insn & (1 << 13))
10361 goto illegal_op;
10363 if (insn & (1 << 26)) {
10364 if (!(insn & (1 << 20))) {
10365 /* Hypervisor call (v7) */
10366 int imm16 = extract32(insn, 16, 4) << 12
10367 | extract32(insn, 0, 12);
10368 ARCH(7);
10369 if (IS_USER(s)) {
10370 goto illegal_op;
10372 gen_hvc(s, imm16);
10373 } else {
10374 /* Secure monitor call (v6+) */
10375 ARCH(6K);
10376 if (IS_USER(s)) {
10377 goto illegal_op;
10379 gen_smc(s);
10381 } else {
10382 op = (insn >> 20) & 7;
10383 switch (op) {
10384 case 0: /* msr cpsr. */
10385 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10386 tmp = load_reg(s, rn);
10387 addr = tcg_const_i32(insn & 0xff);
10388 gen_helper_v7m_msr(cpu_env, addr, tmp);
10389 tcg_temp_free_i32(addr);
10390 tcg_temp_free_i32(tmp);
10391 gen_lookup_tb(s);
10392 break;
10394 /* fall through */
10395 case 1: /* msr spsr. */
10396 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10397 goto illegal_op;
10400 if (extract32(insn, 5, 1)) {
10401 /* MSR (banked) */
10402 int sysm = extract32(insn, 8, 4) |
10403 (extract32(insn, 4, 1) << 4);
10404 int r = op & 1;
10406 gen_msr_banked(s, r, sysm, rm);
10407 break;
10410 /* MSR (for PSRs) */
10411 tmp = load_reg(s, rn);
10412 if (gen_set_psr(s,
10413 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10414 op == 1, tmp))
10415 goto illegal_op;
10416 break;
10417 case 2: /* cps, nop-hint. */
10418 if (((insn >> 8) & 7) == 0) {
10419 gen_nop_hint(s, insn & 0xff);
10421 /* Implemented as NOP in user mode. */
10422 if (IS_USER(s))
10423 break;
10424 offset = 0;
10425 imm = 0;
10426 if (insn & (1 << 10)) {
10427 if (insn & (1 << 7))
10428 offset |= CPSR_A;
10429 if (insn & (1 << 6))
10430 offset |= CPSR_I;
10431 if (insn & (1 << 5))
10432 offset |= CPSR_F;
10433 if (insn & (1 << 9))
10434 imm = CPSR_A | CPSR_I | CPSR_F;
10436 if (insn & (1 << 8)) {
10437 offset |= 0x1f;
10438 imm |= (insn & 0x1f);
10440 if (offset) {
10441 gen_set_psr_im(s, offset, 0, imm);
10443 break;
10444 case 3: /* Special control operations. */
10445 ARCH(7);
10446 op = (insn >> 4) & 0xf;
10447 switch (op) {
10448 case 2: /* clrex */
10449 gen_clrex(s);
10450 break;
10451 case 4: /* dsb */
10452 case 5: /* dmb */
10453 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10454 break;
10455 case 6: /* isb */
10456 /* We need to break the TB after this insn
10457 * to execute self-modifying code correctly
10458 * and also to take any pending interrupts
10459 * immediately.
10461 gen_lookup_tb(s);
10462 break;
10463 default:
10464 goto illegal_op;
10466 break;
10467 case 4: /* bxj */
10468 /* Trivial implementation equivalent to bx. */
10469 tmp = load_reg(s, rn);
10470 gen_bx(s, tmp);
10471 break;
10472 case 5: /* Exception return. */
10473 if (IS_USER(s)) {
10474 goto illegal_op;
10476 if (rn != 14 || rd != 15) {
10477 goto illegal_op;
10479 tmp = load_reg(s, rn);
10480 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10481 gen_exception_return(s, tmp);
10482 break;
10483 case 6: /* MRS */
10484 if (extract32(insn, 5, 1)) {
10485 /* MRS (banked) */
10486 int sysm = extract32(insn, 16, 4) |
10487 (extract32(insn, 4, 1) << 4);
10489 gen_mrs_banked(s, 0, sysm, rd);
10490 break;
10493 /* mrs cpsr */
10494 tmp = tcg_temp_new_i32();
10495 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10496 addr = tcg_const_i32(insn & 0xff);
10497 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10498 tcg_temp_free_i32(addr);
10499 } else {
10500 gen_helper_cpsr_read(tmp, cpu_env);
10502 store_reg(s, rd, tmp);
10503 break;
10504 case 7: /* MRS */
10505 if (extract32(insn, 5, 1)) {
10506 /* MRS (banked) */
10507 int sysm = extract32(insn, 16, 4) |
10508 (extract32(insn, 4, 1) << 4);
10510 gen_mrs_banked(s, 1, sysm, rd);
10511 break;
10514 /* mrs spsr. */
10515 /* Not accessible in user mode. */
10516 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10517 goto illegal_op;
10519 tmp = load_cpu_field(spsr);
10520 store_reg(s, rd, tmp);
10521 break;
10524 } else {
10525 /* Conditional branch. */
10526 op = (insn >> 22) & 0xf;
10527 /* Generate a conditional jump to next instruction. */
10528 s->condlabel = gen_new_label();
10529 arm_gen_test_cc(op ^ 1, s->condlabel);
10530 s->condjmp = 1;
10532 /* offset[11:1] = insn[10:0] */
10533 offset = (insn & 0x7ff) << 1;
10534 /* offset[17:12] = insn[21:16]. */
10535 offset |= (insn & 0x003f0000) >> 4;
10536 /* offset[31:20] = insn[26]. */
10537 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10538 /* offset[18] = insn[13]. */
10539 offset |= (insn & (1 << 13)) << 5;
10540 /* offset[19] = insn[11]. */
10541 offset |= (insn & (1 << 11)) << 8;
10543 /* jump to the offset */
10544 gen_jmp(s, s->pc + offset);
10546 } else {
10547 /* Data processing immediate. */
10548 if (insn & (1 << 25)) {
10549 if (insn & (1 << 24)) {
10550 if (insn & (1 << 20))
10551 goto illegal_op;
10552 /* Bitfield/Saturate. */
10553 op = (insn >> 21) & 7;
10554 imm = insn & 0x1f;
10555 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10556 if (rn == 15) {
10557 tmp = tcg_temp_new_i32();
10558 tcg_gen_movi_i32(tmp, 0);
10559 } else {
10560 tmp = load_reg(s, rn);
10562 switch (op) {
10563 case 2: /* Signed bitfield extract. */
10564 imm++;
10565 if (shift + imm > 32)
10566 goto illegal_op;
10567 if (imm < 32) {
10568 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10570 break;
10571 case 6: /* Unsigned bitfield extract. */
10572 imm++;
10573 if (shift + imm > 32)
10574 goto illegal_op;
10575 if (imm < 32) {
10576 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10578 break;
10579 case 3: /* Bitfield insert/clear. */
10580 if (imm < shift)
10581 goto illegal_op;
10582 imm = imm + 1 - shift;
10583 if (imm != 32) {
10584 tmp2 = load_reg(s, rd);
10585 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10586 tcg_temp_free_i32(tmp2);
10588 break;
10589 case 7:
10590 goto illegal_op;
10591 default: /* Saturate. */
10592 if (shift) {
10593 if (op & 1)
10594 tcg_gen_sari_i32(tmp, tmp, shift);
10595 else
10596 tcg_gen_shli_i32(tmp, tmp, shift);
10598 tmp2 = tcg_const_i32(imm);
10599 if (op & 4) {
10600 /* Unsigned. */
10601 if ((op & 1) && shift == 0) {
10602 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10603 tcg_temp_free_i32(tmp);
10604 tcg_temp_free_i32(tmp2);
10605 goto illegal_op;
10607 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10608 } else {
10609 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10611 } else {
10612 /* Signed. */
10613 if ((op & 1) && shift == 0) {
10614 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10615 tcg_temp_free_i32(tmp);
10616 tcg_temp_free_i32(tmp2);
10617 goto illegal_op;
10619 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10620 } else {
10621 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10624 tcg_temp_free_i32(tmp2);
10625 break;
10627 store_reg(s, rd, tmp);
10628 } else {
10629 imm = ((insn & 0x04000000) >> 15)
10630 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10631 if (insn & (1 << 22)) {
10632 /* 16-bit immediate. */
10633 imm |= (insn >> 4) & 0xf000;
10634 if (insn & (1 << 23)) {
10635 /* movt */
10636 tmp = load_reg(s, rd);
10637 tcg_gen_ext16u_i32(tmp, tmp);
10638 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10639 } else {
10640 /* movw */
10641 tmp = tcg_temp_new_i32();
10642 tcg_gen_movi_i32(tmp, imm);
10644 } else {
10645 /* Add/sub 12-bit immediate. */
10646 if (rn == 15) {
10647 offset = s->pc & ~(uint32_t)3;
10648 if (insn & (1 << 23))
10649 offset -= imm;
10650 else
10651 offset += imm;
10652 tmp = tcg_temp_new_i32();
10653 tcg_gen_movi_i32(tmp, offset);
10654 } else {
10655 tmp = load_reg(s, rn);
10656 if (insn & (1 << 23))
10657 tcg_gen_subi_i32(tmp, tmp, imm);
10658 else
10659 tcg_gen_addi_i32(tmp, tmp, imm);
10662 store_reg(s, rd, tmp);
10664 } else {
10665 int shifter_out = 0;
10666 /* modified 12-bit immediate. */
10667 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10668 imm = (insn & 0xff);
10669 switch (shift) {
10670 case 0: /* XY */
10671 /* Nothing to do. */
10672 break;
10673 case 1: /* 00XY00XY */
10674 imm |= imm << 16;
10675 break;
10676 case 2: /* XY00XY00 */
10677 imm |= imm << 16;
10678 imm <<= 8;
10679 break;
10680 case 3: /* XYXYXYXY */
10681 imm |= imm << 16;
10682 imm |= imm << 8;
10683 break;
10684 default: /* Rotated constant. */
10685 shift = (shift << 1) | (imm >> 7);
10686 imm |= 0x80;
10687 imm = imm << (32 - shift);
10688 shifter_out = 1;
10689 break;
10691 tmp2 = tcg_temp_new_i32();
10692 tcg_gen_movi_i32(tmp2, imm);
10693 rn = (insn >> 16) & 0xf;
10694 if (rn == 15) {
10695 tmp = tcg_temp_new_i32();
10696 tcg_gen_movi_i32(tmp, 0);
10697 } else {
10698 tmp = load_reg(s, rn);
10700 op = (insn >> 21) & 0xf;
10701 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10702 shifter_out, tmp, tmp2))
10703 goto illegal_op;
10704 tcg_temp_free_i32(tmp2);
10705 rd = (insn >> 8) & 0xf;
10706 if (rd != 15) {
10707 store_reg(s, rd, tmp);
10708 } else {
10709 tcg_temp_free_i32(tmp);
10713 break;
10714 case 12: /* Load/store single data item. */
10716 int postinc = 0;
10717 int writeback = 0;
10718 int memidx;
10719 ISSInfo issinfo;
10721 if ((insn & 0x01100000) == 0x01000000) {
10722 if (disas_neon_ls_insn(s, insn)) {
10723 goto illegal_op;
10725 break;
10727 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10728 if (rs == 15) {
10729 if (!(insn & (1 << 20))) {
10730 goto illegal_op;
10732 if (op != 2) {
10733 /* Byte or halfword load space with dest == r15 : memory hints.
10734 * Catch them early so we don't emit pointless addressing code.
10735 * This space is a mix of:
10736 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10737 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10738 * cores)
10739 * unallocated hints, which must be treated as NOPs
10740 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10741 * which is easiest for the decoding logic
10742 * Some space which must UNDEF
10744 int op1 = (insn >> 23) & 3;
10745 int op2 = (insn >> 6) & 0x3f;
10746 if (op & 2) {
10747 goto illegal_op;
10749 if (rn == 15) {
10750 /* UNPREDICTABLE, unallocated hint or
10751 * PLD/PLDW/PLI (literal)
10753 return 0;
10755 if (op1 & 1) {
10756 return 0; /* PLD/PLDW/PLI or unallocated hint */
10758 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10759 return 0; /* PLD/PLDW/PLI or unallocated hint */
10761 /* UNDEF space, or an UNPREDICTABLE */
10762 return 1;
10765 memidx = get_mem_index(s);
10766 if (rn == 15) {
10767 addr = tcg_temp_new_i32();
10768 /* PC relative. */
10769 /* s->pc has already been incremented by 4. */
10770 imm = s->pc & 0xfffffffc;
10771 if (insn & (1 << 23))
10772 imm += insn & 0xfff;
10773 else
10774 imm -= insn & 0xfff;
10775 tcg_gen_movi_i32(addr, imm);
10776 } else {
10777 addr = load_reg(s, rn);
10778 if (insn & (1 << 23)) {
10779 /* Positive offset. */
10780 imm = insn & 0xfff;
10781 tcg_gen_addi_i32(addr, addr, imm);
10782 } else {
10783 imm = insn & 0xff;
10784 switch ((insn >> 8) & 0xf) {
10785 case 0x0: /* Shifted Register. */
10786 shift = (insn >> 4) & 0xf;
10787 if (shift > 3) {
10788 tcg_temp_free_i32(addr);
10789 goto illegal_op;
10791 tmp = load_reg(s, rm);
10792 if (shift)
10793 tcg_gen_shli_i32(tmp, tmp, shift);
10794 tcg_gen_add_i32(addr, addr, tmp);
10795 tcg_temp_free_i32(tmp);
10796 break;
10797 case 0xc: /* Negative offset. */
10798 tcg_gen_addi_i32(addr, addr, -imm);
10799 break;
10800 case 0xe: /* User privilege. */
10801 tcg_gen_addi_i32(addr, addr, imm);
10802 memidx = get_a32_user_mem_index(s);
10803 break;
10804 case 0x9: /* Post-decrement. */
10805 imm = -imm;
10806 /* Fall through. */
10807 case 0xb: /* Post-increment. */
10808 postinc = 1;
10809 writeback = 1;
10810 break;
10811 case 0xd: /* Pre-decrement. */
10812 imm = -imm;
10813 /* Fall through. */
10814 case 0xf: /* Pre-increment. */
10815 tcg_gen_addi_i32(addr, addr, imm);
10816 writeback = 1;
10817 break;
10818 default:
10819 tcg_temp_free_i32(addr);
10820 goto illegal_op;
10825 issinfo = writeback ? ISSInvalid : rs;
10827 if (insn & (1 << 20)) {
10828 /* Load. */
10829 tmp = tcg_temp_new_i32();
10830 switch (op) {
10831 case 0:
10832 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10833 break;
10834 case 4:
10835 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10836 break;
10837 case 1:
10838 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10839 break;
10840 case 5:
10841 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10842 break;
10843 case 2:
10844 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10845 break;
10846 default:
10847 tcg_temp_free_i32(tmp);
10848 tcg_temp_free_i32(addr);
10849 goto illegal_op;
10851 if (rs == 15) {
10852 gen_bx(s, tmp);
10853 } else {
10854 store_reg(s, rs, tmp);
10856 } else {
10857 /* Store. */
10858 tmp = load_reg(s, rs);
10859 switch (op) {
10860 case 0:
10861 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10862 break;
10863 case 1:
10864 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10865 break;
10866 case 2:
10867 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10868 break;
10869 default:
10870 tcg_temp_free_i32(tmp);
10871 tcg_temp_free_i32(addr);
10872 goto illegal_op;
10874 tcg_temp_free_i32(tmp);
10876 if (postinc)
10877 tcg_gen_addi_i32(addr, addr, imm);
10878 if (writeback) {
10879 store_reg(s, rn, addr);
10880 } else {
10881 tcg_temp_free_i32(addr);
10884 break;
10885 default:
10886 goto illegal_op;
10888 return 0;
10889 illegal_op:
10890 return 1;
10893 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10895 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10896 int32_t offset;
10897 int i;
10898 TCGv_i32 tmp;
10899 TCGv_i32 tmp2;
10900 TCGv_i32 addr;
10902 if (s->condexec_mask) {
10903 cond = s->condexec_cond;
10904 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10905 s->condlabel = gen_new_label();
10906 arm_gen_test_cc(cond ^ 1, s->condlabel);
10907 s->condjmp = 1;
10911 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
10912 s->pc += 2;
10914 switch (insn >> 12) {
10915 case 0: case 1:
10917 rd = insn & 7;
10918 op = (insn >> 11) & 3;
10919 if (op == 3) {
10920 /* add/subtract */
10921 rn = (insn >> 3) & 7;
10922 tmp = load_reg(s, rn);
10923 if (insn & (1 << 10)) {
10924 /* immediate */
10925 tmp2 = tcg_temp_new_i32();
10926 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10927 } else {
10928 /* reg */
10929 rm = (insn >> 6) & 7;
10930 tmp2 = load_reg(s, rm);
10932 if (insn & (1 << 9)) {
10933 if (s->condexec_mask)
10934 tcg_gen_sub_i32(tmp, tmp, tmp2);
10935 else
10936 gen_sub_CC(tmp, tmp, tmp2);
10937 } else {
10938 if (s->condexec_mask)
10939 tcg_gen_add_i32(tmp, tmp, tmp2);
10940 else
10941 gen_add_CC(tmp, tmp, tmp2);
10943 tcg_temp_free_i32(tmp2);
10944 store_reg(s, rd, tmp);
10945 } else {
10946 /* shift immediate */
10947 rm = (insn >> 3) & 7;
10948 shift = (insn >> 6) & 0x1f;
10949 tmp = load_reg(s, rm);
10950 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10951 if (!s->condexec_mask)
10952 gen_logic_CC(tmp);
10953 store_reg(s, rd, tmp);
10955 break;
10956 case 2: case 3:
10957 /* arithmetic large immediate */
10958 op = (insn >> 11) & 3;
10959 rd = (insn >> 8) & 0x7;
10960 if (op == 0) { /* mov */
10961 tmp = tcg_temp_new_i32();
10962 tcg_gen_movi_i32(tmp, insn & 0xff);
10963 if (!s->condexec_mask)
10964 gen_logic_CC(tmp);
10965 store_reg(s, rd, tmp);
10966 } else {
10967 tmp = load_reg(s, rd);
10968 tmp2 = tcg_temp_new_i32();
10969 tcg_gen_movi_i32(tmp2, insn & 0xff);
10970 switch (op) {
10971 case 1: /* cmp */
10972 gen_sub_CC(tmp, tmp, tmp2);
10973 tcg_temp_free_i32(tmp);
10974 tcg_temp_free_i32(tmp2);
10975 break;
10976 case 2: /* add */
10977 if (s->condexec_mask)
10978 tcg_gen_add_i32(tmp, tmp, tmp2);
10979 else
10980 gen_add_CC(tmp, tmp, tmp2);
10981 tcg_temp_free_i32(tmp2);
10982 store_reg(s, rd, tmp);
10983 break;
10984 case 3: /* sub */
10985 if (s->condexec_mask)
10986 tcg_gen_sub_i32(tmp, tmp, tmp2);
10987 else
10988 gen_sub_CC(tmp, tmp, tmp2);
10989 tcg_temp_free_i32(tmp2);
10990 store_reg(s, rd, tmp);
10991 break;
10994 break;
10995 case 4:
10996 if (insn & (1 << 11)) {
10997 rd = (insn >> 8) & 7;
10998 /* load pc-relative. Bit 1 of PC is ignored. */
10999 val = s->pc + 2 + ((insn & 0xff) * 4);
11000 val &= ~(uint32_t)2;
11001 addr = tcg_temp_new_i32();
11002 tcg_gen_movi_i32(addr, val);
11003 tmp = tcg_temp_new_i32();
11004 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11005 rd | ISSIs16Bit);
11006 tcg_temp_free_i32(addr);
11007 store_reg(s, rd, tmp);
11008 break;
11010 if (insn & (1 << 10)) {
11011 /* data processing extended or blx */
11012 rd = (insn & 7) | ((insn >> 4) & 8);
11013 rm = (insn >> 3) & 0xf;
11014 op = (insn >> 8) & 3;
11015 switch (op) {
11016 case 0: /* add */
11017 tmp = load_reg(s, rd);
11018 tmp2 = load_reg(s, rm);
11019 tcg_gen_add_i32(tmp, tmp, tmp2);
11020 tcg_temp_free_i32(tmp2);
11021 store_reg(s, rd, tmp);
11022 break;
11023 case 1: /* cmp */
11024 tmp = load_reg(s, rd);
11025 tmp2 = load_reg(s, rm);
11026 gen_sub_CC(tmp, tmp, tmp2);
11027 tcg_temp_free_i32(tmp2);
11028 tcg_temp_free_i32(tmp);
11029 break;
11030 case 2: /* mov/cpy */
11031 tmp = load_reg(s, rm);
11032 store_reg(s, rd, tmp);
11033 break;
11034 case 3:/* branch [and link] exchange thumb register */
11035 tmp = load_reg(s, rm);
11036 if (insn & (1 << 7)) {
11037 ARCH(5);
11038 val = (uint32_t)s->pc | 1;
11039 tmp2 = tcg_temp_new_i32();
11040 tcg_gen_movi_i32(tmp2, val);
11041 store_reg(s, 14, tmp2);
11043 /* already thumb, no need to check */
11044 gen_bx(s, tmp);
11045 break;
11047 break;
11050 /* data processing register */
11051 rd = insn & 7;
11052 rm = (insn >> 3) & 7;
11053 op = (insn >> 6) & 0xf;
11054 if (op == 2 || op == 3 || op == 4 || op == 7) {
11055 /* the shift/rotate ops want the operands backwards */
11056 val = rm;
11057 rm = rd;
11058 rd = val;
11059 val = 1;
11060 } else {
11061 val = 0;
11064 if (op == 9) { /* neg */
11065 tmp = tcg_temp_new_i32();
11066 tcg_gen_movi_i32(tmp, 0);
11067 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11068 tmp = load_reg(s, rd);
11069 } else {
11070 TCGV_UNUSED_I32(tmp);
11073 tmp2 = load_reg(s, rm);
11074 switch (op) {
11075 case 0x0: /* and */
11076 tcg_gen_and_i32(tmp, tmp, tmp2);
11077 if (!s->condexec_mask)
11078 gen_logic_CC(tmp);
11079 break;
11080 case 0x1: /* eor */
11081 tcg_gen_xor_i32(tmp, tmp, tmp2);
11082 if (!s->condexec_mask)
11083 gen_logic_CC(tmp);
11084 break;
11085 case 0x2: /* lsl */
11086 if (s->condexec_mask) {
11087 gen_shl(tmp2, tmp2, tmp);
11088 } else {
11089 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11090 gen_logic_CC(tmp2);
11092 break;
11093 case 0x3: /* lsr */
11094 if (s->condexec_mask) {
11095 gen_shr(tmp2, tmp2, tmp);
11096 } else {
11097 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11098 gen_logic_CC(tmp2);
11100 break;
11101 case 0x4: /* asr */
11102 if (s->condexec_mask) {
11103 gen_sar(tmp2, tmp2, tmp);
11104 } else {
11105 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11106 gen_logic_CC(tmp2);
11108 break;
11109 case 0x5: /* adc */
11110 if (s->condexec_mask) {
11111 gen_adc(tmp, tmp2);
11112 } else {
11113 gen_adc_CC(tmp, tmp, tmp2);
11115 break;
11116 case 0x6: /* sbc */
11117 if (s->condexec_mask) {
11118 gen_sub_carry(tmp, tmp, tmp2);
11119 } else {
11120 gen_sbc_CC(tmp, tmp, tmp2);
11122 break;
11123 case 0x7: /* ror */
11124 if (s->condexec_mask) {
11125 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11126 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11127 } else {
11128 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11129 gen_logic_CC(tmp2);
11131 break;
11132 case 0x8: /* tst */
11133 tcg_gen_and_i32(tmp, tmp, tmp2);
11134 gen_logic_CC(tmp);
11135 rd = 16;
11136 break;
11137 case 0x9: /* neg */
11138 if (s->condexec_mask)
11139 tcg_gen_neg_i32(tmp, tmp2);
11140 else
11141 gen_sub_CC(tmp, tmp, tmp2);
11142 break;
11143 case 0xa: /* cmp */
11144 gen_sub_CC(tmp, tmp, tmp2);
11145 rd = 16;
11146 break;
11147 case 0xb: /* cmn */
11148 gen_add_CC(tmp, tmp, tmp2);
11149 rd = 16;
11150 break;
11151 case 0xc: /* orr */
11152 tcg_gen_or_i32(tmp, tmp, tmp2);
11153 if (!s->condexec_mask)
11154 gen_logic_CC(tmp);
11155 break;
11156 case 0xd: /* mul */
11157 tcg_gen_mul_i32(tmp, tmp, tmp2);
11158 if (!s->condexec_mask)
11159 gen_logic_CC(tmp);
11160 break;
11161 case 0xe: /* bic */
11162 tcg_gen_andc_i32(tmp, tmp, tmp2);
11163 if (!s->condexec_mask)
11164 gen_logic_CC(tmp);
11165 break;
11166 case 0xf: /* mvn */
11167 tcg_gen_not_i32(tmp2, tmp2);
11168 if (!s->condexec_mask)
11169 gen_logic_CC(tmp2);
11170 val = 1;
11171 rm = rd;
11172 break;
11174 if (rd != 16) {
11175 if (val) {
11176 store_reg(s, rm, tmp2);
11177 if (op != 0xf)
11178 tcg_temp_free_i32(tmp);
11179 } else {
11180 store_reg(s, rd, tmp);
11181 tcg_temp_free_i32(tmp2);
11183 } else {
11184 tcg_temp_free_i32(tmp);
11185 tcg_temp_free_i32(tmp2);
11187 break;
11189 case 5:
11190 /* load/store register offset. */
11191 rd = insn & 7;
11192 rn = (insn >> 3) & 7;
11193 rm = (insn >> 6) & 7;
11194 op = (insn >> 9) & 7;
11195 addr = load_reg(s, rn);
11196 tmp = load_reg(s, rm);
11197 tcg_gen_add_i32(addr, addr, tmp);
11198 tcg_temp_free_i32(tmp);
11200 if (op < 3) { /* store */
11201 tmp = load_reg(s, rd);
11202 } else {
11203 tmp = tcg_temp_new_i32();
11206 switch (op) {
11207 case 0: /* str */
11208 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11209 break;
11210 case 1: /* strh */
11211 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11212 break;
11213 case 2: /* strb */
11214 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11215 break;
11216 case 3: /* ldrsb */
11217 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11218 break;
11219 case 4: /* ldr */
11220 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11221 break;
11222 case 5: /* ldrh */
11223 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11224 break;
11225 case 6: /* ldrb */
11226 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11227 break;
11228 case 7: /* ldrsh */
11229 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11230 break;
11232 if (op >= 3) { /* load */
11233 store_reg(s, rd, tmp);
11234 } else {
11235 tcg_temp_free_i32(tmp);
11237 tcg_temp_free_i32(addr);
11238 break;
11240 case 6:
11241 /* load/store word immediate offset */
11242 rd = insn & 7;
11243 rn = (insn >> 3) & 7;
11244 addr = load_reg(s, rn);
11245 val = (insn >> 4) & 0x7c;
11246 tcg_gen_addi_i32(addr, addr, val);
11248 if (insn & (1 << 11)) {
11249 /* load */
11250 tmp = tcg_temp_new_i32();
11251 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11252 store_reg(s, rd, tmp);
11253 } else {
11254 /* store */
11255 tmp = load_reg(s, rd);
11256 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11257 tcg_temp_free_i32(tmp);
11259 tcg_temp_free_i32(addr);
11260 break;
11262 case 7:
11263 /* load/store byte immediate offset */
11264 rd = insn & 7;
11265 rn = (insn >> 3) & 7;
11266 addr = load_reg(s, rn);
11267 val = (insn >> 6) & 0x1f;
11268 tcg_gen_addi_i32(addr, addr, val);
11270 if (insn & (1 << 11)) {
11271 /* load */
11272 tmp = tcg_temp_new_i32();
11273 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11274 store_reg(s, rd, tmp);
11275 } else {
11276 /* store */
11277 tmp = load_reg(s, rd);
11278 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11279 tcg_temp_free_i32(tmp);
11281 tcg_temp_free_i32(addr);
11282 break;
11284 case 8:
11285 /* load/store halfword immediate offset */
11286 rd = insn & 7;
11287 rn = (insn >> 3) & 7;
11288 addr = load_reg(s, rn);
11289 val = (insn >> 5) & 0x3e;
11290 tcg_gen_addi_i32(addr, addr, val);
11292 if (insn & (1 << 11)) {
11293 /* load */
11294 tmp = tcg_temp_new_i32();
11295 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11296 store_reg(s, rd, tmp);
11297 } else {
11298 /* store */
11299 tmp = load_reg(s, rd);
11300 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11301 tcg_temp_free_i32(tmp);
11303 tcg_temp_free_i32(addr);
11304 break;
11306 case 9:
11307 /* load/store from stack */
11308 rd = (insn >> 8) & 7;
11309 addr = load_reg(s, 13);
11310 val = (insn & 0xff) * 4;
11311 tcg_gen_addi_i32(addr, addr, val);
11313 if (insn & (1 << 11)) {
11314 /* load */
11315 tmp = tcg_temp_new_i32();
11316 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11317 store_reg(s, rd, tmp);
11318 } else {
11319 /* store */
11320 tmp = load_reg(s, rd);
11321 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11322 tcg_temp_free_i32(tmp);
11324 tcg_temp_free_i32(addr);
11325 break;
11327 case 10:
11328 /* add to high reg */
11329 rd = (insn >> 8) & 7;
11330 if (insn & (1 << 11)) {
11331 /* SP */
11332 tmp = load_reg(s, 13);
11333 } else {
11334 /* PC. bit 1 is ignored. */
11335 tmp = tcg_temp_new_i32();
11336 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11338 val = (insn & 0xff) * 4;
11339 tcg_gen_addi_i32(tmp, tmp, val);
11340 store_reg(s, rd, tmp);
11341 break;
11343 case 11:
11344 /* misc */
11345 op = (insn >> 8) & 0xf;
11346 switch (op) {
11347 case 0:
11348 /* adjust stack pointer */
11349 tmp = load_reg(s, 13);
11350 val = (insn & 0x7f) * 4;
11351 if (insn & (1 << 7))
11352 val = -(int32_t)val;
11353 tcg_gen_addi_i32(tmp, tmp, val);
11354 store_reg(s, 13, tmp);
11355 break;
11357 case 2: /* sign/zero extend. */
11358 ARCH(6);
11359 rd = insn & 7;
11360 rm = (insn >> 3) & 7;
11361 tmp = load_reg(s, rm);
11362 switch ((insn >> 6) & 3) {
11363 case 0: gen_sxth(tmp); break;
11364 case 1: gen_sxtb(tmp); break;
11365 case 2: gen_uxth(tmp); break;
11366 case 3: gen_uxtb(tmp); break;
11368 store_reg(s, rd, tmp);
11369 break;
11370 case 4: case 5: case 0xc: case 0xd:
11371 /* push/pop */
11372 addr = load_reg(s, 13);
11373 if (insn & (1 << 8))
11374 offset = 4;
11375 else
11376 offset = 0;
11377 for (i = 0; i < 8; i++) {
11378 if (insn & (1 << i))
11379 offset += 4;
11381 if ((insn & (1 << 11)) == 0) {
11382 tcg_gen_addi_i32(addr, addr, -offset);
11384 for (i = 0; i < 8; i++) {
11385 if (insn & (1 << i)) {
11386 if (insn & (1 << 11)) {
11387 /* pop */
11388 tmp = tcg_temp_new_i32();
11389 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11390 store_reg(s, i, tmp);
11391 } else {
11392 /* push */
11393 tmp = load_reg(s, i);
11394 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11395 tcg_temp_free_i32(tmp);
11397 /* advance to the next address. */
11398 tcg_gen_addi_i32(addr, addr, 4);
11401 TCGV_UNUSED_I32(tmp);
11402 if (insn & (1 << 8)) {
11403 if (insn & (1 << 11)) {
11404 /* pop pc */
11405 tmp = tcg_temp_new_i32();
11406 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11407 /* don't set the pc until the rest of the instruction
11408 has completed */
11409 } else {
11410 /* push lr */
11411 tmp = load_reg(s, 14);
11412 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11413 tcg_temp_free_i32(tmp);
11415 tcg_gen_addi_i32(addr, addr, 4);
11417 if ((insn & (1 << 11)) == 0) {
11418 tcg_gen_addi_i32(addr, addr, -offset);
11420 /* write back the new stack pointer */
11421 store_reg(s, 13, addr);
11422 /* set the new PC value */
11423 if ((insn & 0x0900) == 0x0900) {
11424 store_reg_from_load(s, 15, tmp);
11426 break;
11428 case 1: case 3: case 9: case 11: /* czb */
11429 rm = insn & 7;
11430 tmp = load_reg(s, rm);
11431 s->condlabel = gen_new_label();
11432 s->condjmp = 1;
11433 if (insn & (1 << 11))
11434 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11435 else
11436 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11437 tcg_temp_free_i32(tmp);
11438 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11439 val = (uint32_t)s->pc + 2;
11440 val += offset;
11441 gen_jmp(s, val);
11442 break;
11444 case 15: /* IT, nop-hint. */
11445 if ((insn & 0xf) == 0) {
11446 gen_nop_hint(s, (insn >> 4) & 0xf);
11447 break;
11449 /* If Then. */
11450 s->condexec_cond = (insn >> 4) & 0xe;
11451 s->condexec_mask = insn & 0x1f;
11452 /* No actual code generated for this insn, just setup state. */
11453 break;
11455 case 0xe: /* bkpt */
11457 int imm8 = extract32(insn, 0, 8);
11458 ARCH(5);
11459 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11460 default_exception_el(s));
11461 break;
11464 case 0xa: /* rev, and hlt */
11466 int op1 = extract32(insn, 6, 2);
11468 if (op1 == 2) {
11469 /* HLT */
11470 int imm6 = extract32(insn, 0, 6);
11472 gen_hlt(s, imm6);
11473 break;
11476 /* Otherwise this is rev */
11477 ARCH(6);
11478 rn = (insn >> 3) & 0x7;
11479 rd = insn & 0x7;
11480 tmp = load_reg(s, rn);
11481 switch (op1) {
11482 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11483 case 1: gen_rev16(tmp); break;
11484 case 3: gen_revsh(tmp); break;
11485 default:
11486 g_assert_not_reached();
11488 store_reg(s, rd, tmp);
11489 break;
11492 case 6:
11493 switch ((insn >> 5) & 7) {
11494 case 2:
11495 /* setend */
11496 ARCH(6);
11497 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11498 gen_helper_setend(cpu_env);
11499 s->is_jmp = DISAS_UPDATE;
11501 break;
11502 case 3:
11503 /* cps */
11504 ARCH(6);
11505 if (IS_USER(s)) {
11506 break;
11508 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11509 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11510 /* FAULTMASK */
11511 if (insn & 1) {
11512 addr = tcg_const_i32(19);
11513 gen_helper_v7m_msr(cpu_env, addr, tmp);
11514 tcg_temp_free_i32(addr);
11516 /* PRIMASK */
11517 if (insn & 2) {
11518 addr = tcg_const_i32(16);
11519 gen_helper_v7m_msr(cpu_env, addr, tmp);
11520 tcg_temp_free_i32(addr);
11522 tcg_temp_free_i32(tmp);
11523 gen_lookup_tb(s);
11524 } else {
11525 if (insn & (1 << 4)) {
11526 shift = CPSR_A | CPSR_I | CPSR_F;
11527 } else {
11528 shift = 0;
11530 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11532 break;
11533 default:
11534 goto undef;
11536 break;
11538 default:
11539 goto undef;
11541 break;
11543 case 12:
11545 /* load/store multiple */
11546 TCGv_i32 loaded_var;
11547 TCGV_UNUSED_I32(loaded_var);
11548 rn = (insn >> 8) & 0x7;
11549 addr = load_reg(s, rn);
11550 for (i = 0; i < 8; i++) {
11551 if (insn & (1 << i)) {
11552 if (insn & (1 << 11)) {
11553 /* load */
11554 tmp = tcg_temp_new_i32();
11555 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11556 if (i == rn) {
11557 loaded_var = tmp;
11558 } else {
11559 store_reg(s, i, tmp);
11561 } else {
11562 /* store */
11563 tmp = load_reg(s, i);
11564 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11565 tcg_temp_free_i32(tmp);
11567 /* advance to the next address */
11568 tcg_gen_addi_i32(addr, addr, 4);
11571 if ((insn & (1 << rn)) == 0) {
11572 /* base reg not in list: base register writeback */
11573 store_reg(s, rn, addr);
11574 } else {
11575 /* base reg in list: if load, complete it now */
11576 if (insn & (1 << 11)) {
11577 store_reg(s, rn, loaded_var);
11579 tcg_temp_free_i32(addr);
11581 break;
11583 case 13:
11584 /* conditional branch or swi */
11585 cond = (insn >> 8) & 0xf;
11586 if (cond == 0xe)
11587 goto undef;
11589 if (cond == 0xf) {
11590 /* swi */
11591 gen_set_pc_im(s, s->pc);
11592 s->svc_imm = extract32(insn, 0, 8);
11593 s->is_jmp = DISAS_SWI;
11594 break;
11596 /* generate a conditional jump to next instruction */
11597 s->condlabel = gen_new_label();
11598 arm_gen_test_cc(cond ^ 1, s->condlabel);
11599 s->condjmp = 1;
11601 /* jump to the offset */
11602 val = (uint32_t)s->pc + 2;
11603 offset = ((int32_t)insn << 24) >> 24;
11604 val += offset << 1;
11605 gen_jmp(s, val);
11606 break;
11608 case 14:
11609 if (insn & (1 << 11)) {
11610 if (disas_thumb2_insn(env, s, insn))
11611 goto undef32;
11612 break;
11614 /* unconditional branch */
11615 val = (uint32_t)s->pc;
11616 offset = ((int32_t)insn << 21) >> 21;
11617 val += (offset << 1) + 2;
11618 gen_jmp(s, val);
11619 break;
11621 case 15:
11622 if (disas_thumb2_insn(env, s, insn))
11623 goto undef32;
11624 break;
11626 return;
11627 undef32:
11628 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11629 default_exception_el(s));
11630 return;
11631 illegal_op:
11632 undef:
11633 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11634 default_exception_el(s));
11637 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11639 /* Return true if the insn at dc->pc might cross a page boundary.
11640 * (False positives are OK, false negatives are not.)
11642 uint16_t insn;
11644 if ((s->pc & 3) == 0) {
11645 /* At a 4-aligned address we can't be crossing a page */
11646 return false;
11649 /* This must be a Thumb insn */
11650 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11652 if ((insn >> 11) >= 0x1d) {
11653 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11654 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11655 * end up actually treating this as two 16-bit insns (see the
11656 * code at the start of disas_thumb2_insn()) but we don't bother
11657 * to check for that as it is unlikely, and false positives here
11658 * are harmless.
11660 return true;
11662 /* Definitely a 16-bit insn, can't be crossing a page. */
11663 return false;
11666 /* generate intermediate code for basic block 'tb'. */
11667 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11669 ARMCPU *cpu = arm_env_get_cpu(env);
11670 CPUState *cs = CPU(cpu);
11671 DisasContext dc1, *dc = &dc1;
11672 target_ulong pc_start;
11673 target_ulong next_page_start;
11674 int num_insns;
11675 int max_insns;
11676 bool end_of_page;
11678 /* generate intermediate code */
11680 /* The A64 decoder has its own top level loop, because it doesn't need
11681 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11683 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11684 gen_intermediate_code_a64(cpu, tb);
11685 return;
11688 pc_start = tb->pc;
11690 dc->tb = tb;
11692 dc->is_jmp = DISAS_NEXT;
11693 dc->pc = pc_start;
11694 dc->singlestep_enabled = cs->singlestep_enabled;
11695 dc->condjmp = 0;
11697 dc->aarch64 = 0;
11698 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11699 * there is no secure EL1, so we route exceptions to EL3.
11701 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11702 !arm_el_is_aa64(env, 3);
11703 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11704 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11705 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11706 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11707 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11708 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11709 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11710 #if !defined(CONFIG_USER_ONLY)
11711 dc->user = (dc->current_el == 0);
11712 #endif
11713 dc->ns = ARM_TBFLAG_NS(tb->flags);
11714 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11715 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11716 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11717 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11718 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11719 dc->cp_regs = cpu->cp_regs;
11720 dc->features = env->features;
11722 /* Single step state. The code-generation logic here is:
11723 * SS_ACTIVE == 0:
11724 * generate code with no special handling for single-stepping (except
11725 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11726 * this happens anyway because those changes are all system register or
11727 * PSTATE writes).
11728 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11729 * emit code for one insn
11730 * emit code to clear PSTATE.SS
11731 * emit code to generate software step exception for completed step
11732 * end TB (as usual for having generated an exception)
11733 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11734 * emit code to generate a software step exception
11735 * end the TB
11737 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11738 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11739 dc->is_ldex = false;
11740 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11742 cpu_F0s = tcg_temp_new_i32();
11743 cpu_F1s = tcg_temp_new_i32();
11744 cpu_F0d = tcg_temp_new_i64();
11745 cpu_F1d = tcg_temp_new_i64();
11746 cpu_V0 = cpu_F0d;
11747 cpu_V1 = cpu_F1d;
11748 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11749 cpu_M0 = tcg_temp_new_i64();
11750 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11751 num_insns = 0;
11752 max_insns = tb->cflags & CF_COUNT_MASK;
11753 if (max_insns == 0) {
11754 max_insns = CF_COUNT_MASK;
11756 if (max_insns > TCG_MAX_INSNS) {
11757 max_insns = TCG_MAX_INSNS;
11760 gen_tb_start(tb);
11762 tcg_clear_temp_count();
11764 /* A note on handling of the condexec (IT) bits:
11766 * We want to avoid the overhead of having to write the updated condexec
11767 * bits back to the CPUARMState for every instruction in an IT block. So:
11768 * (1) if the condexec bits are not already zero then we write
11769 * zero back into the CPUARMState now. This avoids complications trying
11770 * to do it at the end of the block. (For example if we don't do this
11771 * it's hard to identify whether we can safely skip writing condexec
11772 * at the end of the TB, which we definitely want to do for the case
11773 * where a TB doesn't do anything with the IT state at all.)
11774 * (2) if we are going to leave the TB then we call gen_set_condexec()
11775 * which will write the correct value into CPUARMState if zero is wrong.
11776 * This is done both for leaving the TB at the end, and for leaving
11777 * it because of an exception we know will happen, which is done in
11778 * gen_exception_insn(). The latter is necessary because we need to
11779 * leave the TB with the PC/IT state just prior to execution of the
11780 * instruction which caused the exception.
11781 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11782 * then the CPUARMState will be wrong and we need to reset it.
11783 * This is handled in the same way as restoration of the
11784 * PC in these situations; we save the value of the condexec bits
11785 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11786 * then uses this to restore them after an exception.
11788 * Note that there are no instructions which can read the condexec
11789 * bits, and none which can write non-static values to them, so
11790 * we don't need to care about whether CPUARMState is correct in the
11791 * middle of a TB.
11794 /* Reset the conditional execution bits immediately. This avoids
11795 complications trying to do it at the end of the block. */
11796 if (dc->condexec_mask || dc->condexec_cond)
11798 TCGv_i32 tmp = tcg_temp_new_i32();
11799 tcg_gen_movi_i32(tmp, 0);
11800 store_cpu_field(tmp, condexec_bits);
11802 do {
11803 dc->insn_start_idx = tcg_op_buf_count();
11804 tcg_gen_insn_start(dc->pc,
11805 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11807 num_insns++;
11809 #ifdef CONFIG_USER_ONLY
11810 /* Intercept jump to the magic kernel page. */
11811 if (dc->pc >= 0xffff0000) {
11812 /* We always get here via a jump, so know we are not in a
11813 conditional execution block. */
11814 gen_exception_internal(EXCP_KERNEL_TRAP);
11815 dc->is_jmp = DISAS_EXC;
11816 break;
11818 #else
11819 if (arm_dc_feature(dc, ARM_FEATURE_M)) {
11820 /* Branches to the magic exception-return addresses should
11821 * already have been caught via the arm_v7m_unassigned_access hook,
11822 * and never get here.
11824 assert(dc->pc < 0xfffffff0);
11826 #endif
11828 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11829 CPUBreakpoint *bp;
11830 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11831 if (bp->pc == dc->pc) {
11832 if (bp->flags & BP_CPU) {
11833 gen_set_condexec(dc);
11834 gen_set_pc_im(dc, dc->pc);
11835 gen_helper_check_breakpoints(cpu_env);
11836 /* End the TB early; it's likely not going to be executed */
11837 dc->is_jmp = DISAS_UPDATE;
11838 } else {
11839 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11840 /* The address covered by the breakpoint must be
11841 included in [tb->pc, tb->pc + tb->size) in order
11842 to for it to be properly cleared -- thus we
11843 increment the PC here so that the logic setting
11844 tb->size below does the right thing. */
11845 /* TODO: Advance PC by correct instruction length to
11846 * avoid disassembler error messages */
11847 dc->pc += 2;
11848 goto done_generating;
11850 break;
11855 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11856 gen_io_start();
11859 if (dc->ss_active && !dc->pstate_ss) {
11860 /* Singlestep state is Active-pending.
11861 * If we're in this state at the start of a TB then either
11862 * a) we just took an exception to an EL which is being debugged
11863 * and this is the first insn in the exception handler
11864 * b) debug exceptions were masked and we just unmasked them
11865 * without changing EL (eg by clearing PSTATE.D)
11866 * In either case we're going to take a swstep exception in the
11867 * "did not step an insn" case, and so the syndrome ISV and EX
11868 * bits should be zero.
11870 assert(num_insns == 1);
11871 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11872 default_exception_el(dc));
11873 goto done_generating;
11876 if (dc->thumb) {
11877 disas_thumb_insn(env, dc);
11878 if (dc->condexec_mask) {
11879 dc->condexec_cond = (dc->condexec_cond & 0xe)
11880 | ((dc->condexec_mask >> 4) & 1);
11881 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11882 if (dc->condexec_mask == 0) {
11883 dc->condexec_cond = 0;
11886 } else {
11887 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
11888 dc->pc += 4;
11889 disas_arm_insn(dc, insn);
11892 if (dc->condjmp && !dc->is_jmp) {
11893 gen_set_label(dc->condlabel);
11894 dc->condjmp = 0;
11897 if (tcg_check_temp_count()) {
11898 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11899 dc->pc);
11902 /* Translation stops when a conditional branch is encountered.
11903 * Otherwise the subsequent code could get translated several times.
11904 * Also stop translation when a page boundary is reached. This
11905 * ensures prefetch aborts occur at the right place. */
11907 /* We want to stop the TB if the next insn starts in a new page,
11908 * or if it spans between this page and the next. This means that
11909 * if we're looking at the last halfword in the page we need to
11910 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11911 * or a 32-bit Thumb insn (which won't).
11912 * This is to avoid generating a silly TB with a single 16-bit insn
11913 * in it at the end of this page (which would execute correctly
11914 * but isn't very efficient).
11916 end_of_page = (dc->pc >= next_page_start) ||
11917 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
11919 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11920 !cs->singlestep_enabled &&
11921 !singlestep &&
11922 !dc->ss_active &&
11923 !end_of_page &&
11924 num_insns < max_insns);
11926 if (tb->cflags & CF_LAST_IO) {
11927 if (dc->condjmp) {
11928 /* FIXME: This can theoretically happen with self-modifying
11929 code. */
11930 cpu_abort(cs, "IO on conditional branch instruction");
11932 gen_io_end();
11935 /* At this stage dc->condjmp will only be set when the skipped
11936 instruction was a conditional branch or trap, and the PC has
11937 already been written. */
11938 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11939 /* Unconditional and "condition passed" instruction codepath. */
11940 gen_set_condexec(dc);
11941 switch (dc->is_jmp) {
11942 case DISAS_SWI:
11943 gen_ss_advance(dc);
11944 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11945 default_exception_el(dc));
11946 break;
11947 case DISAS_HVC:
11948 gen_ss_advance(dc);
11949 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11950 break;
11951 case DISAS_SMC:
11952 gen_ss_advance(dc);
11953 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11954 break;
11955 case DISAS_NEXT:
11956 case DISAS_UPDATE:
11957 gen_set_pc_im(dc, dc->pc);
11958 /* fall through */
11959 default:
11960 if (dc->ss_active) {
11961 gen_step_complete_exception(dc);
11962 } else {
11963 /* FIXME: Single stepping a WFI insn will not halt
11964 the CPU. */
11965 gen_exception_internal(EXCP_DEBUG);
11968 if (dc->condjmp) {
11969 /* "Condition failed" instruction codepath. */
11970 gen_set_label(dc->condlabel);
11971 gen_set_condexec(dc);
11972 gen_set_pc_im(dc, dc->pc);
11973 if (dc->ss_active) {
11974 gen_step_complete_exception(dc);
11975 } else {
11976 gen_exception_internal(EXCP_DEBUG);
11979 } else {
11980 /* While branches must always occur at the end of an IT block,
11981 there are a few other things that can cause us to terminate
11982 the TB in the middle of an IT block:
11983 - Exception generating instructions (bkpt, swi, undefined).
11984 - Page boundaries.
11985 - Hardware watchpoints.
11986 Hardware breakpoints have already been handled and skip this code.
11988 gen_set_condexec(dc);
11989 switch(dc->is_jmp) {
11990 case DISAS_NEXT:
11991 gen_goto_tb(dc, 1, dc->pc);
11992 break;
11993 case DISAS_UPDATE:
11994 gen_set_pc_im(dc, dc->pc);
11995 /* fall through */
11996 case DISAS_JUMP:
11997 default:
11998 /* indicate that the hash table must be used to find the next TB */
11999 tcg_gen_exit_tb(0);
12000 break;
12001 case DISAS_TB_JUMP:
12002 /* nothing more to generate */
12003 break;
12004 case DISAS_WFI:
12005 gen_helper_wfi(cpu_env);
12006 /* The helper doesn't necessarily throw an exception, but we
12007 * must go back to the main loop to check for interrupts anyway.
12009 tcg_gen_exit_tb(0);
12010 break;
12011 case DISAS_WFE:
12012 gen_helper_wfe(cpu_env);
12013 break;
12014 case DISAS_YIELD:
12015 gen_helper_yield(cpu_env);
12016 break;
12017 case DISAS_SWI:
12018 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12019 default_exception_el(dc));
12020 break;
12021 case DISAS_HVC:
12022 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12023 break;
12024 case DISAS_SMC:
12025 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12026 break;
12028 if (dc->condjmp) {
12029 gen_set_label(dc->condlabel);
12030 gen_set_condexec(dc);
12031 gen_goto_tb(dc, 1, dc->pc);
12032 dc->condjmp = 0;
12036 done_generating:
12037 gen_tb_end(tb, num_insns);
12039 #ifdef DEBUG_DISAS
12040 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
12041 qemu_log_in_addr_range(pc_start)) {
12042 qemu_log_lock();
12043 qemu_log("----------------\n");
12044 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12045 log_target_disas(cs, pc_start, dc->pc - pc_start,
12046 dc->thumb | (dc->sctlr_b << 1));
12047 qemu_log("\n");
12048 qemu_log_unlock();
12050 #endif
12051 tb->size = dc->pc - pc_start;
12052 tb->icount = num_insns;
12055 static const char *cpu_mode_names[16] = {
12056 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12057 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12060 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12061 int flags)
12063 ARMCPU *cpu = ARM_CPU(cs);
12064 CPUARMState *env = &cpu->env;
12065 int i;
12066 uint32_t psr;
12067 const char *ns_status;
12069 if (is_a64(env)) {
12070 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12071 return;
12074 for(i=0;i<16;i++) {
12075 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12076 if ((i % 4) == 3)
12077 cpu_fprintf(f, "\n");
12078 else
12079 cpu_fprintf(f, " ");
12081 psr = cpsr_read(env);
12083 if (arm_feature(env, ARM_FEATURE_EL3) &&
12084 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12085 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12086 } else {
12087 ns_status = "";
12090 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12091 psr,
12092 psr & (1 << 31) ? 'N' : '-',
12093 psr & (1 << 30) ? 'Z' : '-',
12094 psr & (1 << 29) ? 'C' : '-',
12095 psr & (1 << 28) ? 'V' : '-',
12096 psr & CPSR_T ? 'T' : 'A',
12097 ns_status,
12098 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12100 if (flags & CPU_DUMP_FPU) {
12101 int numvfpregs = 0;
12102 if (arm_feature(env, ARM_FEATURE_VFP)) {
12103 numvfpregs += 16;
12105 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12106 numvfpregs += 16;
12108 for (i = 0; i < numvfpregs; i++) {
12109 uint64_t v = float64_val(env->vfp.regs[i]);
12110 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12111 i * 2, (uint32_t)v,
12112 i * 2 + 1, (uint32_t)(v >> 32),
12113 i, v);
12115 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12119 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12120 target_ulong *data)
12122 if (is_a64(env)) {
12123 env->pc = data[0];
12124 env->condexec_bits = 0;
12125 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12126 } else {
12127 env->regs[15] = data[0];
12128 env->condexec_bits = data[1];
12129 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;