arm: Enforce should-be-1 bits in MRS decoding
[qemu/ar7.git] / target / arm / translate.c
blobc4acff5f994fd5f515f778180eefa90733179de4
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));
4408 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4409 * only call the helper when running single threaded TCG code to ensure
4410 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4411 * just skip this instruction. Currently the SEV/SEVL instructions
4412 * which are *one* of many ways to wake the CPU from WFE are not
4413 * implemented so we can't sleep like WFI does.
4415 static void gen_nop_hint(DisasContext *s, int val)
4417 switch (val) {
4418 case 1: /* yield */
4419 if (!parallel_cpus) {
4420 gen_set_pc_im(s, s->pc);
4421 s->is_jmp = DISAS_YIELD;
4423 break;
4424 case 3: /* wfi */
4425 gen_set_pc_im(s, s->pc);
4426 s->is_jmp = DISAS_WFI;
4427 break;
4428 case 2: /* wfe */
4429 if (!parallel_cpus) {
4430 gen_set_pc_im(s, s->pc);
4431 s->is_jmp = DISAS_WFE;
4433 break;
4434 case 4: /* sev */
4435 case 5: /* sevl */
4436 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4437 default: /* nop */
4438 break;
4442 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4444 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4446 switch (size) {
4447 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4448 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4449 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4450 default: abort();
4454 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4456 switch (size) {
4457 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4458 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4459 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4460 default: return;
4464 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4465 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4466 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4467 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4468 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4470 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4471 switch ((size << 1) | u) { \
4472 case 0: \
4473 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4474 break; \
4475 case 1: \
4476 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4477 break; \
4478 case 2: \
4479 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4480 break; \
4481 case 3: \
4482 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4483 break; \
4484 case 4: \
4485 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4486 break; \
4487 case 5: \
4488 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4489 break; \
4490 default: return 1; \
4491 }} while (0)
4493 #define GEN_NEON_INTEGER_OP(name) do { \
4494 switch ((size << 1) | u) { \
4495 case 0: \
4496 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4497 break; \
4498 case 1: \
4499 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4500 break; \
4501 case 2: \
4502 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4503 break; \
4504 case 3: \
4505 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4506 break; \
4507 case 4: \
4508 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4509 break; \
4510 case 5: \
4511 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4512 break; \
4513 default: return 1; \
4514 }} while (0)
4516 static TCGv_i32 neon_load_scratch(int scratch)
4518 TCGv_i32 tmp = tcg_temp_new_i32();
4519 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4520 return tmp;
4523 static void neon_store_scratch(int scratch, TCGv_i32 var)
4525 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4526 tcg_temp_free_i32(var);
4529 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4531 TCGv_i32 tmp;
4532 if (size == 1) {
4533 tmp = neon_load_reg(reg & 7, reg >> 4);
4534 if (reg & 8) {
4535 gen_neon_dup_high16(tmp);
4536 } else {
4537 gen_neon_dup_low16(tmp);
4539 } else {
4540 tmp = neon_load_reg(reg & 15, reg >> 4);
4542 return tmp;
4545 static int gen_neon_unzip(int rd, int rm, int size, int q)
4547 TCGv_i32 tmp, tmp2;
4548 if (!q && size == 2) {
4549 return 1;
4551 tmp = tcg_const_i32(rd);
4552 tmp2 = tcg_const_i32(rm);
4553 if (q) {
4554 switch (size) {
4555 case 0:
4556 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4557 break;
4558 case 1:
4559 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4560 break;
4561 case 2:
4562 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4563 break;
4564 default:
4565 abort();
4567 } else {
4568 switch (size) {
4569 case 0:
4570 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4571 break;
4572 case 1:
4573 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4574 break;
4575 default:
4576 abort();
4579 tcg_temp_free_i32(tmp);
4580 tcg_temp_free_i32(tmp2);
4581 return 0;
4584 static int gen_neon_zip(int rd, int rm, int size, int q)
4586 TCGv_i32 tmp, tmp2;
4587 if (!q && size == 2) {
4588 return 1;
4590 tmp = tcg_const_i32(rd);
4591 tmp2 = tcg_const_i32(rm);
4592 if (q) {
4593 switch (size) {
4594 case 0:
4595 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4596 break;
4597 case 1:
4598 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4599 break;
4600 case 2:
4601 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4602 break;
4603 default:
4604 abort();
4606 } else {
4607 switch (size) {
4608 case 0:
4609 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4610 break;
4611 case 1:
4612 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4613 break;
4614 default:
4615 abort();
4618 tcg_temp_free_i32(tmp);
4619 tcg_temp_free_i32(tmp2);
4620 return 0;
4623 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4625 TCGv_i32 rd, tmp;
4627 rd = tcg_temp_new_i32();
4628 tmp = tcg_temp_new_i32();
4630 tcg_gen_shli_i32(rd, t0, 8);
4631 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4632 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4633 tcg_gen_or_i32(rd, rd, tmp);
4635 tcg_gen_shri_i32(t1, t1, 8);
4636 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4637 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4638 tcg_gen_or_i32(t1, t1, tmp);
4639 tcg_gen_mov_i32(t0, rd);
4641 tcg_temp_free_i32(tmp);
4642 tcg_temp_free_i32(rd);
4645 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4647 TCGv_i32 rd, tmp;
4649 rd = tcg_temp_new_i32();
4650 tmp = tcg_temp_new_i32();
4652 tcg_gen_shli_i32(rd, t0, 16);
4653 tcg_gen_andi_i32(tmp, t1, 0xffff);
4654 tcg_gen_or_i32(rd, rd, tmp);
4655 tcg_gen_shri_i32(t1, t1, 16);
4656 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4657 tcg_gen_or_i32(t1, t1, tmp);
4658 tcg_gen_mov_i32(t0, rd);
4660 tcg_temp_free_i32(tmp);
4661 tcg_temp_free_i32(rd);
4665 static struct {
4666 int nregs;
4667 int interleave;
4668 int spacing;
4669 } neon_ls_element_type[11] = {
4670 {4, 4, 1},
4671 {4, 4, 2},
4672 {4, 1, 1},
4673 {4, 2, 1},
4674 {3, 3, 1},
4675 {3, 3, 2},
4676 {3, 1, 1},
4677 {1, 1, 1},
4678 {2, 2, 1},
4679 {2, 2, 2},
4680 {2, 1, 1}
4683 /* Translate a NEON load/store element instruction. Return nonzero if the
4684 instruction is invalid. */
4685 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4687 int rd, rn, rm;
4688 int op;
4689 int nregs;
4690 int interleave;
4691 int spacing;
4692 int stride;
4693 int size;
4694 int reg;
4695 int pass;
4696 int load;
4697 int shift;
4698 int n;
4699 TCGv_i32 addr;
4700 TCGv_i32 tmp;
4701 TCGv_i32 tmp2;
4702 TCGv_i64 tmp64;
4704 /* FIXME: this access check should not take precedence over UNDEF
4705 * for invalid encodings; we will generate incorrect syndrome information
4706 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4708 if (s->fp_excp_el) {
4709 gen_exception_insn(s, 4, EXCP_UDEF,
4710 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4711 return 0;
4714 if (!s->vfp_enabled)
4715 return 1;
4716 VFP_DREG_D(rd, insn);
4717 rn = (insn >> 16) & 0xf;
4718 rm = insn & 0xf;
4719 load = (insn & (1 << 21)) != 0;
4720 if ((insn & (1 << 23)) == 0) {
4721 /* Load store all elements. */
4722 op = (insn >> 8) & 0xf;
4723 size = (insn >> 6) & 3;
4724 if (op > 10)
4725 return 1;
4726 /* Catch UNDEF cases for bad values of align field */
4727 switch (op & 0xc) {
4728 case 4:
4729 if (((insn >> 5) & 1) == 1) {
4730 return 1;
4732 break;
4733 case 8:
4734 if (((insn >> 4) & 3) == 3) {
4735 return 1;
4737 break;
4738 default:
4739 break;
4741 nregs = neon_ls_element_type[op].nregs;
4742 interleave = neon_ls_element_type[op].interleave;
4743 spacing = neon_ls_element_type[op].spacing;
4744 if (size == 3 && (interleave | spacing) != 1)
4745 return 1;
4746 addr = tcg_temp_new_i32();
4747 load_reg_var(s, addr, rn);
4748 stride = (1 << size) * interleave;
4749 for (reg = 0; reg < nregs; reg++) {
4750 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4751 load_reg_var(s, addr, rn);
4752 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4753 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4754 load_reg_var(s, addr, rn);
4755 tcg_gen_addi_i32(addr, addr, 1 << size);
4757 if (size == 3) {
4758 tmp64 = tcg_temp_new_i64();
4759 if (load) {
4760 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4761 neon_store_reg64(tmp64, rd);
4762 } else {
4763 neon_load_reg64(tmp64, rd);
4764 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4766 tcg_temp_free_i64(tmp64);
4767 tcg_gen_addi_i32(addr, addr, stride);
4768 } else {
4769 for (pass = 0; pass < 2; pass++) {
4770 if (size == 2) {
4771 if (load) {
4772 tmp = tcg_temp_new_i32();
4773 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4774 neon_store_reg(rd, pass, tmp);
4775 } else {
4776 tmp = neon_load_reg(rd, pass);
4777 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4778 tcg_temp_free_i32(tmp);
4780 tcg_gen_addi_i32(addr, addr, stride);
4781 } else if (size == 1) {
4782 if (load) {
4783 tmp = tcg_temp_new_i32();
4784 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4785 tcg_gen_addi_i32(addr, addr, stride);
4786 tmp2 = tcg_temp_new_i32();
4787 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4788 tcg_gen_addi_i32(addr, addr, stride);
4789 tcg_gen_shli_i32(tmp2, tmp2, 16);
4790 tcg_gen_or_i32(tmp, tmp, tmp2);
4791 tcg_temp_free_i32(tmp2);
4792 neon_store_reg(rd, pass, tmp);
4793 } else {
4794 tmp = neon_load_reg(rd, pass);
4795 tmp2 = tcg_temp_new_i32();
4796 tcg_gen_shri_i32(tmp2, tmp, 16);
4797 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4798 tcg_temp_free_i32(tmp);
4799 tcg_gen_addi_i32(addr, addr, stride);
4800 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4801 tcg_temp_free_i32(tmp2);
4802 tcg_gen_addi_i32(addr, addr, stride);
4804 } else /* size == 0 */ {
4805 if (load) {
4806 TCGV_UNUSED_I32(tmp2);
4807 for (n = 0; n < 4; n++) {
4808 tmp = tcg_temp_new_i32();
4809 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4810 tcg_gen_addi_i32(addr, addr, stride);
4811 if (n == 0) {
4812 tmp2 = tmp;
4813 } else {
4814 tcg_gen_shli_i32(tmp, tmp, n * 8);
4815 tcg_gen_or_i32(tmp2, tmp2, tmp);
4816 tcg_temp_free_i32(tmp);
4819 neon_store_reg(rd, pass, tmp2);
4820 } else {
4821 tmp2 = neon_load_reg(rd, pass);
4822 for (n = 0; n < 4; n++) {
4823 tmp = tcg_temp_new_i32();
4824 if (n == 0) {
4825 tcg_gen_mov_i32(tmp, tmp2);
4826 } else {
4827 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4829 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4830 tcg_temp_free_i32(tmp);
4831 tcg_gen_addi_i32(addr, addr, stride);
4833 tcg_temp_free_i32(tmp2);
4838 rd += spacing;
4840 tcg_temp_free_i32(addr);
4841 stride = nregs * 8;
4842 } else {
4843 size = (insn >> 10) & 3;
4844 if (size == 3) {
4845 /* Load single element to all lanes. */
4846 int a = (insn >> 4) & 1;
4847 if (!load) {
4848 return 1;
4850 size = (insn >> 6) & 3;
4851 nregs = ((insn >> 8) & 3) + 1;
4853 if (size == 3) {
4854 if (nregs != 4 || a == 0) {
4855 return 1;
4857 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4858 size = 2;
4860 if (nregs == 1 && a == 1 && size == 0) {
4861 return 1;
4863 if (nregs == 3 && a == 1) {
4864 return 1;
4866 addr = tcg_temp_new_i32();
4867 load_reg_var(s, addr, rn);
4868 if (nregs == 1) {
4869 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
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 if (insn & (1 << 5)) {
4874 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4875 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4877 tcg_temp_free_i32(tmp);
4878 } else {
4879 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4880 stride = (insn & (1 << 5)) ? 2 : 1;
4881 for (reg = 0; reg < nregs; reg++) {
4882 tmp = gen_load_and_replicate(s, addr, size);
4883 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4884 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4885 tcg_temp_free_i32(tmp);
4886 tcg_gen_addi_i32(addr, addr, 1 << size);
4887 rd += stride;
4890 tcg_temp_free_i32(addr);
4891 stride = (1 << size) * nregs;
4892 } else {
4893 /* Single element. */
4894 int idx = (insn >> 4) & 0xf;
4895 pass = (insn >> 7) & 1;
4896 switch (size) {
4897 case 0:
4898 shift = ((insn >> 5) & 3) * 8;
4899 stride = 1;
4900 break;
4901 case 1:
4902 shift = ((insn >> 6) & 1) * 16;
4903 stride = (insn & (1 << 5)) ? 2 : 1;
4904 break;
4905 case 2:
4906 shift = 0;
4907 stride = (insn & (1 << 6)) ? 2 : 1;
4908 break;
4909 default:
4910 abort();
4912 nregs = ((insn >> 8) & 3) + 1;
4913 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4914 switch (nregs) {
4915 case 1:
4916 if (((idx & (1 << size)) != 0) ||
4917 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4918 return 1;
4920 break;
4921 case 3:
4922 if ((idx & 1) != 0) {
4923 return 1;
4925 /* fall through */
4926 case 2:
4927 if (size == 2 && (idx & 2) != 0) {
4928 return 1;
4930 break;
4931 case 4:
4932 if ((size == 2) && ((idx & 3) == 3)) {
4933 return 1;
4935 break;
4936 default:
4937 abort();
4939 if ((rd + stride * (nregs - 1)) > 31) {
4940 /* Attempts to write off the end of the register file
4941 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4942 * the neon_load_reg() would write off the end of the array.
4944 return 1;
4946 addr = tcg_temp_new_i32();
4947 load_reg_var(s, addr, rn);
4948 for (reg = 0; reg < nregs; reg++) {
4949 if (load) {
4950 tmp = tcg_temp_new_i32();
4951 switch (size) {
4952 case 0:
4953 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4954 break;
4955 case 1:
4956 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4957 break;
4958 case 2:
4959 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4960 break;
4961 default: /* Avoid compiler warnings. */
4962 abort();
4964 if (size != 2) {
4965 tmp2 = neon_load_reg(rd, pass);
4966 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4967 shift, size ? 16 : 8);
4968 tcg_temp_free_i32(tmp2);
4970 neon_store_reg(rd, pass, tmp);
4971 } else { /* Store */
4972 tmp = neon_load_reg(rd, pass);
4973 if (shift)
4974 tcg_gen_shri_i32(tmp, tmp, shift);
4975 switch (size) {
4976 case 0:
4977 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4978 break;
4979 case 1:
4980 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4981 break;
4982 case 2:
4983 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4984 break;
4986 tcg_temp_free_i32(tmp);
4988 rd += stride;
4989 tcg_gen_addi_i32(addr, addr, 1 << size);
4991 tcg_temp_free_i32(addr);
4992 stride = nregs * (1 << size);
4995 if (rm != 15) {
4996 TCGv_i32 base;
4998 base = load_reg(s, rn);
4999 if (rm == 13) {
5000 tcg_gen_addi_i32(base, base, stride);
5001 } else {
5002 TCGv_i32 index;
5003 index = load_reg(s, rm);
5004 tcg_gen_add_i32(base, base, index);
5005 tcg_temp_free_i32(index);
5007 store_reg(s, rn, base);
5009 return 0;
5012 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5013 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5015 tcg_gen_and_i32(t, t, c);
5016 tcg_gen_andc_i32(f, f, c);
5017 tcg_gen_or_i32(dest, t, f);
5020 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5022 switch (size) {
5023 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5024 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5025 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5026 default: abort();
5030 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5032 switch (size) {
5033 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5034 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5035 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5036 default: abort();
5040 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5042 switch (size) {
5043 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5044 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5045 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5046 default: abort();
5050 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5052 switch (size) {
5053 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5054 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5055 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5056 default: abort();
5060 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5061 int q, int u)
5063 if (q) {
5064 if (u) {
5065 switch (size) {
5066 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5067 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5068 default: abort();
5070 } else {
5071 switch (size) {
5072 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5073 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5074 default: abort();
5077 } else {
5078 if (u) {
5079 switch (size) {
5080 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5081 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5082 default: abort();
5084 } else {
5085 switch (size) {
5086 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5087 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5088 default: abort();
5094 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5096 if (u) {
5097 switch (size) {
5098 case 0: gen_helper_neon_widen_u8(dest, src); break;
5099 case 1: gen_helper_neon_widen_u16(dest, src); break;
5100 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5101 default: abort();
5103 } else {
5104 switch (size) {
5105 case 0: gen_helper_neon_widen_s8(dest, src); break;
5106 case 1: gen_helper_neon_widen_s16(dest, src); break;
5107 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5108 default: abort();
5111 tcg_temp_free_i32(src);
5114 static inline void gen_neon_addl(int size)
5116 switch (size) {
5117 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5118 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5119 case 2: tcg_gen_add_i64(CPU_V001); break;
5120 default: abort();
5124 static inline void gen_neon_subl(int size)
5126 switch (size) {
5127 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5128 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5129 case 2: tcg_gen_sub_i64(CPU_V001); break;
5130 default: abort();
5134 static inline void gen_neon_negl(TCGv_i64 var, int size)
5136 switch (size) {
5137 case 0: gen_helper_neon_negl_u16(var, var); break;
5138 case 1: gen_helper_neon_negl_u32(var, var); break;
5139 case 2:
5140 tcg_gen_neg_i64(var, var);
5141 break;
5142 default: abort();
5146 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5148 switch (size) {
5149 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5150 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5151 default: abort();
5155 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5156 int size, int u)
5158 TCGv_i64 tmp;
5160 switch ((size << 1) | u) {
5161 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5162 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5163 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5164 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5165 case 4:
5166 tmp = gen_muls_i64_i32(a, b);
5167 tcg_gen_mov_i64(dest, tmp);
5168 tcg_temp_free_i64(tmp);
5169 break;
5170 case 5:
5171 tmp = gen_mulu_i64_i32(a, b);
5172 tcg_gen_mov_i64(dest, tmp);
5173 tcg_temp_free_i64(tmp);
5174 break;
5175 default: abort();
5178 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5179 Don't forget to clean them now. */
5180 if (size < 2) {
5181 tcg_temp_free_i32(a);
5182 tcg_temp_free_i32(b);
5186 static void gen_neon_narrow_op(int op, int u, int size,
5187 TCGv_i32 dest, TCGv_i64 src)
5189 if (op) {
5190 if (u) {
5191 gen_neon_unarrow_sats(size, dest, src);
5192 } else {
5193 gen_neon_narrow(size, dest, src);
5195 } else {
5196 if (u) {
5197 gen_neon_narrow_satu(size, dest, src);
5198 } else {
5199 gen_neon_narrow_sats(size, dest, src);
5204 /* Symbolic constants for op fields for Neon 3-register same-length.
5205 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5206 * table A7-9.
5208 #define NEON_3R_VHADD 0
5209 #define NEON_3R_VQADD 1
5210 #define NEON_3R_VRHADD 2
5211 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5212 #define NEON_3R_VHSUB 4
5213 #define NEON_3R_VQSUB 5
5214 #define NEON_3R_VCGT 6
5215 #define NEON_3R_VCGE 7
5216 #define NEON_3R_VSHL 8
5217 #define NEON_3R_VQSHL 9
5218 #define NEON_3R_VRSHL 10
5219 #define NEON_3R_VQRSHL 11
5220 #define NEON_3R_VMAX 12
5221 #define NEON_3R_VMIN 13
5222 #define NEON_3R_VABD 14
5223 #define NEON_3R_VABA 15
5224 #define NEON_3R_VADD_VSUB 16
5225 #define NEON_3R_VTST_VCEQ 17
5226 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5227 #define NEON_3R_VMUL 19
5228 #define NEON_3R_VPMAX 20
5229 #define NEON_3R_VPMIN 21
5230 #define NEON_3R_VQDMULH_VQRDMULH 22
5231 #define NEON_3R_VPADD 23
5232 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5233 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5234 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5235 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5236 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5237 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5238 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5239 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5241 static const uint8_t neon_3r_sizes[] = {
5242 [NEON_3R_VHADD] = 0x7,
5243 [NEON_3R_VQADD] = 0xf,
5244 [NEON_3R_VRHADD] = 0x7,
5245 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5246 [NEON_3R_VHSUB] = 0x7,
5247 [NEON_3R_VQSUB] = 0xf,
5248 [NEON_3R_VCGT] = 0x7,
5249 [NEON_3R_VCGE] = 0x7,
5250 [NEON_3R_VSHL] = 0xf,
5251 [NEON_3R_VQSHL] = 0xf,
5252 [NEON_3R_VRSHL] = 0xf,
5253 [NEON_3R_VQRSHL] = 0xf,
5254 [NEON_3R_VMAX] = 0x7,
5255 [NEON_3R_VMIN] = 0x7,
5256 [NEON_3R_VABD] = 0x7,
5257 [NEON_3R_VABA] = 0x7,
5258 [NEON_3R_VADD_VSUB] = 0xf,
5259 [NEON_3R_VTST_VCEQ] = 0x7,
5260 [NEON_3R_VML] = 0x7,
5261 [NEON_3R_VMUL] = 0x7,
5262 [NEON_3R_VPMAX] = 0x7,
5263 [NEON_3R_VPMIN] = 0x7,
5264 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5265 [NEON_3R_VPADD] = 0x7,
5266 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5267 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5268 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5269 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5270 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5271 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5272 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5273 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5276 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5277 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5278 * table A7-13.
5280 #define NEON_2RM_VREV64 0
5281 #define NEON_2RM_VREV32 1
5282 #define NEON_2RM_VREV16 2
5283 #define NEON_2RM_VPADDL 4
5284 #define NEON_2RM_VPADDL_U 5
5285 #define NEON_2RM_AESE 6 /* Includes AESD */
5286 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5287 #define NEON_2RM_VCLS 8
5288 #define NEON_2RM_VCLZ 9
5289 #define NEON_2RM_VCNT 10
5290 #define NEON_2RM_VMVN 11
5291 #define NEON_2RM_VPADAL 12
5292 #define NEON_2RM_VPADAL_U 13
5293 #define NEON_2RM_VQABS 14
5294 #define NEON_2RM_VQNEG 15
5295 #define NEON_2RM_VCGT0 16
5296 #define NEON_2RM_VCGE0 17
5297 #define NEON_2RM_VCEQ0 18
5298 #define NEON_2RM_VCLE0 19
5299 #define NEON_2RM_VCLT0 20
5300 #define NEON_2RM_SHA1H 21
5301 #define NEON_2RM_VABS 22
5302 #define NEON_2RM_VNEG 23
5303 #define NEON_2RM_VCGT0_F 24
5304 #define NEON_2RM_VCGE0_F 25
5305 #define NEON_2RM_VCEQ0_F 26
5306 #define NEON_2RM_VCLE0_F 27
5307 #define NEON_2RM_VCLT0_F 28
5308 #define NEON_2RM_VABS_F 30
5309 #define NEON_2RM_VNEG_F 31
5310 #define NEON_2RM_VSWP 32
5311 #define NEON_2RM_VTRN 33
5312 #define NEON_2RM_VUZP 34
5313 #define NEON_2RM_VZIP 35
5314 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5315 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5316 #define NEON_2RM_VSHLL 38
5317 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5318 #define NEON_2RM_VRINTN 40
5319 #define NEON_2RM_VRINTX 41
5320 #define NEON_2RM_VRINTA 42
5321 #define NEON_2RM_VRINTZ 43
5322 #define NEON_2RM_VCVT_F16_F32 44
5323 #define NEON_2RM_VRINTM 45
5324 #define NEON_2RM_VCVT_F32_F16 46
5325 #define NEON_2RM_VRINTP 47
5326 #define NEON_2RM_VCVTAU 48
5327 #define NEON_2RM_VCVTAS 49
5328 #define NEON_2RM_VCVTNU 50
5329 #define NEON_2RM_VCVTNS 51
5330 #define NEON_2RM_VCVTPU 52
5331 #define NEON_2RM_VCVTPS 53
5332 #define NEON_2RM_VCVTMU 54
5333 #define NEON_2RM_VCVTMS 55
5334 #define NEON_2RM_VRECPE 56
5335 #define NEON_2RM_VRSQRTE 57
5336 #define NEON_2RM_VRECPE_F 58
5337 #define NEON_2RM_VRSQRTE_F 59
5338 #define NEON_2RM_VCVT_FS 60
5339 #define NEON_2RM_VCVT_FU 61
5340 #define NEON_2RM_VCVT_SF 62
5341 #define NEON_2RM_VCVT_UF 63
5343 static int neon_2rm_is_float_op(int op)
5345 /* Return true if this neon 2reg-misc op is float-to-float */
5346 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5347 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5348 op == NEON_2RM_VRINTM ||
5349 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5350 op >= NEON_2RM_VRECPE_F);
5353 static bool neon_2rm_is_v8_op(int op)
5355 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5356 switch (op) {
5357 case NEON_2RM_VRINTN:
5358 case NEON_2RM_VRINTA:
5359 case NEON_2RM_VRINTM:
5360 case NEON_2RM_VRINTP:
5361 case NEON_2RM_VRINTZ:
5362 case NEON_2RM_VRINTX:
5363 case NEON_2RM_VCVTAU:
5364 case NEON_2RM_VCVTAS:
5365 case NEON_2RM_VCVTNU:
5366 case NEON_2RM_VCVTNS:
5367 case NEON_2RM_VCVTPU:
5368 case NEON_2RM_VCVTPS:
5369 case NEON_2RM_VCVTMU:
5370 case NEON_2RM_VCVTMS:
5371 return true;
5372 default:
5373 return false;
5377 /* Each entry in this array has bit n set if the insn allows
5378 * size value n (otherwise it will UNDEF). Since unallocated
5379 * op values will have no bits set they always UNDEF.
5381 static const uint8_t neon_2rm_sizes[] = {
5382 [NEON_2RM_VREV64] = 0x7,
5383 [NEON_2RM_VREV32] = 0x3,
5384 [NEON_2RM_VREV16] = 0x1,
5385 [NEON_2RM_VPADDL] = 0x7,
5386 [NEON_2RM_VPADDL_U] = 0x7,
5387 [NEON_2RM_AESE] = 0x1,
5388 [NEON_2RM_AESMC] = 0x1,
5389 [NEON_2RM_VCLS] = 0x7,
5390 [NEON_2RM_VCLZ] = 0x7,
5391 [NEON_2RM_VCNT] = 0x1,
5392 [NEON_2RM_VMVN] = 0x1,
5393 [NEON_2RM_VPADAL] = 0x7,
5394 [NEON_2RM_VPADAL_U] = 0x7,
5395 [NEON_2RM_VQABS] = 0x7,
5396 [NEON_2RM_VQNEG] = 0x7,
5397 [NEON_2RM_VCGT0] = 0x7,
5398 [NEON_2RM_VCGE0] = 0x7,
5399 [NEON_2RM_VCEQ0] = 0x7,
5400 [NEON_2RM_VCLE0] = 0x7,
5401 [NEON_2RM_VCLT0] = 0x7,
5402 [NEON_2RM_SHA1H] = 0x4,
5403 [NEON_2RM_VABS] = 0x7,
5404 [NEON_2RM_VNEG] = 0x7,
5405 [NEON_2RM_VCGT0_F] = 0x4,
5406 [NEON_2RM_VCGE0_F] = 0x4,
5407 [NEON_2RM_VCEQ0_F] = 0x4,
5408 [NEON_2RM_VCLE0_F] = 0x4,
5409 [NEON_2RM_VCLT0_F] = 0x4,
5410 [NEON_2RM_VABS_F] = 0x4,
5411 [NEON_2RM_VNEG_F] = 0x4,
5412 [NEON_2RM_VSWP] = 0x1,
5413 [NEON_2RM_VTRN] = 0x7,
5414 [NEON_2RM_VUZP] = 0x7,
5415 [NEON_2RM_VZIP] = 0x7,
5416 [NEON_2RM_VMOVN] = 0x7,
5417 [NEON_2RM_VQMOVN] = 0x7,
5418 [NEON_2RM_VSHLL] = 0x7,
5419 [NEON_2RM_SHA1SU1] = 0x4,
5420 [NEON_2RM_VRINTN] = 0x4,
5421 [NEON_2RM_VRINTX] = 0x4,
5422 [NEON_2RM_VRINTA] = 0x4,
5423 [NEON_2RM_VRINTZ] = 0x4,
5424 [NEON_2RM_VCVT_F16_F32] = 0x2,
5425 [NEON_2RM_VRINTM] = 0x4,
5426 [NEON_2RM_VCVT_F32_F16] = 0x2,
5427 [NEON_2RM_VRINTP] = 0x4,
5428 [NEON_2RM_VCVTAU] = 0x4,
5429 [NEON_2RM_VCVTAS] = 0x4,
5430 [NEON_2RM_VCVTNU] = 0x4,
5431 [NEON_2RM_VCVTNS] = 0x4,
5432 [NEON_2RM_VCVTPU] = 0x4,
5433 [NEON_2RM_VCVTPS] = 0x4,
5434 [NEON_2RM_VCVTMU] = 0x4,
5435 [NEON_2RM_VCVTMS] = 0x4,
5436 [NEON_2RM_VRECPE] = 0x4,
5437 [NEON_2RM_VRSQRTE] = 0x4,
5438 [NEON_2RM_VRECPE_F] = 0x4,
5439 [NEON_2RM_VRSQRTE_F] = 0x4,
5440 [NEON_2RM_VCVT_FS] = 0x4,
5441 [NEON_2RM_VCVT_FU] = 0x4,
5442 [NEON_2RM_VCVT_SF] = 0x4,
5443 [NEON_2RM_VCVT_UF] = 0x4,
5446 /* Translate a NEON data processing instruction. Return nonzero if the
5447 instruction is invalid.
5448 We process data in a mixture of 32-bit and 64-bit chunks.
5449 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5451 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5453 int op;
5454 int q;
5455 int rd, rn, rm;
5456 int size;
5457 int shift;
5458 int pass;
5459 int count;
5460 int pairwise;
5461 int u;
5462 uint32_t imm, mask;
5463 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5464 TCGv_i64 tmp64;
5466 /* FIXME: this access check should not take precedence over UNDEF
5467 * for invalid encodings; we will generate incorrect syndrome information
5468 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5470 if (s->fp_excp_el) {
5471 gen_exception_insn(s, 4, EXCP_UDEF,
5472 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5473 return 0;
5476 if (!s->vfp_enabled)
5477 return 1;
5478 q = (insn & (1 << 6)) != 0;
5479 u = (insn >> 24) & 1;
5480 VFP_DREG_D(rd, insn);
5481 VFP_DREG_N(rn, insn);
5482 VFP_DREG_M(rm, insn);
5483 size = (insn >> 20) & 3;
5484 if ((insn & (1 << 23)) == 0) {
5485 /* Three register same length. */
5486 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5487 /* Catch invalid op and bad size combinations: UNDEF */
5488 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5489 return 1;
5491 /* All insns of this form UNDEF for either this condition or the
5492 * superset of cases "Q==1"; we catch the latter later.
5494 if (q && ((rd | rn | rm) & 1)) {
5495 return 1;
5498 * The SHA-1/SHA-256 3-register instructions require special treatment
5499 * here, as their size field is overloaded as an op type selector, and
5500 * they all consume their input in a single pass.
5502 if (op == NEON_3R_SHA) {
5503 if (!q) {
5504 return 1;
5506 if (!u) { /* SHA-1 */
5507 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5508 return 1;
5510 tmp = tcg_const_i32(rd);
5511 tmp2 = tcg_const_i32(rn);
5512 tmp3 = tcg_const_i32(rm);
5513 tmp4 = tcg_const_i32(size);
5514 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5515 tcg_temp_free_i32(tmp4);
5516 } else { /* SHA-256 */
5517 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5518 return 1;
5520 tmp = tcg_const_i32(rd);
5521 tmp2 = tcg_const_i32(rn);
5522 tmp3 = tcg_const_i32(rm);
5523 switch (size) {
5524 case 0:
5525 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5526 break;
5527 case 1:
5528 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5529 break;
5530 case 2:
5531 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5532 break;
5535 tcg_temp_free_i32(tmp);
5536 tcg_temp_free_i32(tmp2);
5537 tcg_temp_free_i32(tmp3);
5538 return 0;
5540 if (size == 3 && op != NEON_3R_LOGIC) {
5541 /* 64-bit element instructions. */
5542 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5543 neon_load_reg64(cpu_V0, rn + pass);
5544 neon_load_reg64(cpu_V1, rm + pass);
5545 switch (op) {
5546 case NEON_3R_VQADD:
5547 if (u) {
5548 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5549 cpu_V0, cpu_V1);
5550 } else {
5551 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5552 cpu_V0, cpu_V1);
5554 break;
5555 case NEON_3R_VQSUB:
5556 if (u) {
5557 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5558 cpu_V0, cpu_V1);
5559 } else {
5560 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5561 cpu_V0, cpu_V1);
5563 break;
5564 case NEON_3R_VSHL:
5565 if (u) {
5566 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5567 } else {
5568 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5570 break;
5571 case NEON_3R_VQSHL:
5572 if (u) {
5573 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5574 cpu_V1, cpu_V0);
5575 } else {
5576 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5577 cpu_V1, cpu_V0);
5579 break;
5580 case NEON_3R_VRSHL:
5581 if (u) {
5582 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5583 } else {
5584 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5586 break;
5587 case NEON_3R_VQRSHL:
5588 if (u) {
5589 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5590 cpu_V1, cpu_V0);
5591 } else {
5592 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5593 cpu_V1, cpu_V0);
5595 break;
5596 case NEON_3R_VADD_VSUB:
5597 if (u) {
5598 tcg_gen_sub_i64(CPU_V001);
5599 } else {
5600 tcg_gen_add_i64(CPU_V001);
5602 break;
5603 default:
5604 abort();
5606 neon_store_reg64(cpu_V0, rd + pass);
5608 return 0;
5610 pairwise = 0;
5611 switch (op) {
5612 case NEON_3R_VSHL:
5613 case NEON_3R_VQSHL:
5614 case NEON_3R_VRSHL:
5615 case NEON_3R_VQRSHL:
5617 int rtmp;
5618 /* Shift instruction operands are reversed. */
5619 rtmp = rn;
5620 rn = rm;
5621 rm = rtmp;
5623 break;
5624 case NEON_3R_VPADD:
5625 if (u) {
5626 return 1;
5628 /* Fall through */
5629 case NEON_3R_VPMAX:
5630 case NEON_3R_VPMIN:
5631 pairwise = 1;
5632 break;
5633 case NEON_3R_FLOAT_ARITH:
5634 pairwise = (u && size < 2); /* if VPADD (float) */
5635 break;
5636 case NEON_3R_FLOAT_MINMAX:
5637 pairwise = u; /* if VPMIN/VPMAX (float) */
5638 break;
5639 case NEON_3R_FLOAT_CMP:
5640 if (!u && size) {
5641 /* no encoding for U=0 C=1x */
5642 return 1;
5644 break;
5645 case NEON_3R_FLOAT_ACMP:
5646 if (!u) {
5647 return 1;
5649 break;
5650 case NEON_3R_FLOAT_MISC:
5651 /* VMAXNM/VMINNM in ARMv8 */
5652 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5653 return 1;
5655 break;
5656 case NEON_3R_VMUL:
5657 if (u && (size != 0)) {
5658 /* UNDEF on invalid size for polynomial subcase */
5659 return 1;
5661 break;
5662 case NEON_3R_VFM:
5663 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5664 return 1;
5666 break;
5667 default:
5668 break;
5671 if (pairwise && q) {
5672 /* All the pairwise insns UNDEF if Q is set */
5673 return 1;
5676 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5678 if (pairwise) {
5679 /* Pairwise. */
5680 if (pass < 1) {
5681 tmp = neon_load_reg(rn, 0);
5682 tmp2 = neon_load_reg(rn, 1);
5683 } else {
5684 tmp = neon_load_reg(rm, 0);
5685 tmp2 = neon_load_reg(rm, 1);
5687 } else {
5688 /* Elementwise. */
5689 tmp = neon_load_reg(rn, pass);
5690 tmp2 = neon_load_reg(rm, pass);
5692 switch (op) {
5693 case NEON_3R_VHADD:
5694 GEN_NEON_INTEGER_OP(hadd);
5695 break;
5696 case NEON_3R_VQADD:
5697 GEN_NEON_INTEGER_OP_ENV(qadd);
5698 break;
5699 case NEON_3R_VRHADD:
5700 GEN_NEON_INTEGER_OP(rhadd);
5701 break;
5702 case NEON_3R_LOGIC: /* Logic ops. */
5703 switch ((u << 2) | size) {
5704 case 0: /* VAND */
5705 tcg_gen_and_i32(tmp, tmp, tmp2);
5706 break;
5707 case 1: /* BIC */
5708 tcg_gen_andc_i32(tmp, tmp, tmp2);
5709 break;
5710 case 2: /* VORR */
5711 tcg_gen_or_i32(tmp, tmp, tmp2);
5712 break;
5713 case 3: /* VORN */
5714 tcg_gen_orc_i32(tmp, tmp, tmp2);
5715 break;
5716 case 4: /* VEOR */
5717 tcg_gen_xor_i32(tmp, tmp, tmp2);
5718 break;
5719 case 5: /* VBSL */
5720 tmp3 = neon_load_reg(rd, pass);
5721 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5722 tcg_temp_free_i32(tmp3);
5723 break;
5724 case 6: /* VBIT */
5725 tmp3 = neon_load_reg(rd, pass);
5726 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5727 tcg_temp_free_i32(tmp3);
5728 break;
5729 case 7: /* VBIF */
5730 tmp3 = neon_load_reg(rd, pass);
5731 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5732 tcg_temp_free_i32(tmp3);
5733 break;
5735 break;
5736 case NEON_3R_VHSUB:
5737 GEN_NEON_INTEGER_OP(hsub);
5738 break;
5739 case NEON_3R_VQSUB:
5740 GEN_NEON_INTEGER_OP_ENV(qsub);
5741 break;
5742 case NEON_3R_VCGT:
5743 GEN_NEON_INTEGER_OP(cgt);
5744 break;
5745 case NEON_3R_VCGE:
5746 GEN_NEON_INTEGER_OP(cge);
5747 break;
5748 case NEON_3R_VSHL:
5749 GEN_NEON_INTEGER_OP(shl);
5750 break;
5751 case NEON_3R_VQSHL:
5752 GEN_NEON_INTEGER_OP_ENV(qshl);
5753 break;
5754 case NEON_3R_VRSHL:
5755 GEN_NEON_INTEGER_OP(rshl);
5756 break;
5757 case NEON_3R_VQRSHL:
5758 GEN_NEON_INTEGER_OP_ENV(qrshl);
5759 break;
5760 case NEON_3R_VMAX:
5761 GEN_NEON_INTEGER_OP(max);
5762 break;
5763 case NEON_3R_VMIN:
5764 GEN_NEON_INTEGER_OP(min);
5765 break;
5766 case NEON_3R_VABD:
5767 GEN_NEON_INTEGER_OP(abd);
5768 break;
5769 case NEON_3R_VABA:
5770 GEN_NEON_INTEGER_OP(abd);
5771 tcg_temp_free_i32(tmp2);
5772 tmp2 = neon_load_reg(rd, pass);
5773 gen_neon_add(size, tmp, tmp2);
5774 break;
5775 case NEON_3R_VADD_VSUB:
5776 if (!u) { /* VADD */
5777 gen_neon_add(size, tmp, tmp2);
5778 } else { /* VSUB */
5779 switch (size) {
5780 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5781 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5782 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5783 default: abort();
5786 break;
5787 case NEON_3R_VTST_VCEQ:
5788 if (!u) { /* VTST */
5789 switch (size) {
5790 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5791 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5792 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5793 default: abort();
5795 } else { /* VCEQ */
5796 switch (size) {
5797 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5798 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5799 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5800 default: abort();
5803 break;
5804 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5805 switch (size) {
5806 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5807 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5808 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5809 default: abort();
5811 tcg_temp_free_i32(tmp2);
5812 tmp2 = neon_load_reg(rd, pass);
5813 if (u) { /* VMLS */
5814 gen_neon_rsb(size, tmp, tmp2);
5815 } else { /* VMLA */
5816 gen_neon_add(size, tmp, tmp2);
5818 break;
5819 case NEON_3R_VMUL:
5820 if (u) { /* polynomial */
5821 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5822 } else { /* Integer */
5823 switch (size) {
5824 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5825 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5826 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5827 default: abort();
5830 break;
5831 case NEON_3R_VPMAX:
5832 GEN_NEON_INTEGER_OP(pmax);
5833 break;
5834 case NEON_3R_VPMIN:
5835 GEN_NEON_INTEGER_OP(pmin);
5836 break;
5837 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5838 if (!u) { /* VQDMULH */
5839 switch (size) {
5840 case 1:
5841 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5842 break;
5843 case 2:
5844 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5845 break;
5846 default: abort();
5848 } else { /* VQRDMULH */
5849 switch (size) {
5850 case 1:
5851 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5852 break;
5853 case 2:
5854 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5855 break;
5856 default: abort();
5859 break;
5860 case NEON_3R_VPADD:
5861 switch (size) {
5862 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5863 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5864 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5865 default: abort();
5867 break;
5868 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5870 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5871 switch ((u << 2) | size) {
5872 case 0: /* VADD */
5873 case 4: /* VPADD */
5874 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5875 break;
5876 case 2: /* VSUB */
5877 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5878 break;
5879 case 6: /* VABD */
5880 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5881 break;
5882 default:
5883 abort();
5885 tcg_temp_free_ptr(fpstatus);
5886 break;
5888 case NEON_3R_FLOAT_MULTIPLY:
5890 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5891 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5892 if (!u) {
5893 tcg_temp_free_i32(tmp2);
5894 tmp2 = neon_load_reg(rd, pass);
5895 if (size == 0) {
5896 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5897 } else {
5898 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5901 tcg_temp_free_ptr(fpstatus);
5902 break;
5904 case NEON_3R_FLOAT_CMP:
5906 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5907 if (!u) {
5908 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5909 } else {
5910 if (size == 0) {
5911 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5912 } else {
5913 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5916 tcg_temp_free_ptr(fpstatus);
5917 break;
5919 case NEON_3R_FLOAT_ACMP:
5921 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5922 if (size == 0) {
5923 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5924 } else {
5925 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5927 tcg_temp_free_ptr(fpstatus);
5928 break;
5930 case NEON_3R_FLOAT_MINMAX:
5932 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5933 if (size == 0) {
5934 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5935 } else {
5936 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5938 tcg_temp_free_ptr(fpstatus);
5939 break;
5941 case NEON_3R_FLOAT_MISC:
5942 if (u) {
5943 /* VMAXNM/VMINNM */
5944 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5945 if (size == 0) {
5946 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5947 } else {
5948 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5950 tcg_temp_free_ptr(fpstatus);
5951 } else {
5952 if (size == 0) {
5953 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5954 } else {
5955 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5958 break;
5959 case NEON_3R_VFM:
5961 /* VFMA, VFMS: fused multiply-add */
5962 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5963 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5964 if (size) {
5965 /* VFMS */
5966 gen_helper_vfp_negs(tmp, tmp);
5968 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5969 tcg_temp_free_i32(tmp3);
5970 tcg_temp_free_ptr(fpstatus);
5971 break;
5973 default:
5974 abort();
5976 tcg_temp_free_i32(tmp2);
5978 /* Save the result. For elementwise operations we can put it
5979 straight into the destination register. For pairwise operations
5980 we have to be careful to avoid clobbering the source operands. */
5981 if (pairwise && rd == rm) {
5982 neon_store_scratch(pass, tmp);
5983 } else {
5984 neon_store_reg(rd, pass, tmp);
5987 } /* for pass */
5988 if (pairwise && rd == rm) {
5989 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5990 tmp = neon_load_scratch(pass);
5991 neon_store_reg(rd, pass, tmp);
5994 /* End of 3 register same size operations. */
5995 } else if (insn & (1 << 4)) {
5996 if ((insn & 0x00380080) != 0) {
5997 /* Two registers and shift. */
5998 op = (insn >> 8) & 0xf;
5999 if (insn & (1 << 7)) {
6000 /* 64-bit shift. */
6001 if (op > 7) {
6002 return 1;
6004 size = 3;
6005 } else {
6006 size = 2;
6007 while ((insn & (1 << (size + 19))) == 0)
6008 size--;
6010 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6011 /* To avoid excessive duplication of ops we implement shift
6012 by immediate using the variable shift operations. */
6013 if (op < 8) {
6014 /* Shift by immediate:
6015 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6016 if (q && ((rd | rm) & 1)) {
6017 return 1;
6019 if (!u && (op == 4 || op == 6)) {
6020 return 1;
6022 /* Right shifts are encoded as N - shift, where N is the
6023 element size in bits. */
6024 if (op <= 4)
6025 shift = shift - (1 << (size + 3));
6026 if (size == 3) {
6027 count = q + 1;
6028 } else {
6029 count = q ? 4: 2;
6031 switch (size) {
6032 case 0:
6033 imm = (uint8_t) shift;
6034 imm |= imm << 8;
6035 imm |= imm << 16;
6036 break;
6037 case 1:
6038 imm = (uint16_t) shift;
6039 imm |= imm << 16;
6040 break;
6041 case 2:
6042 case 3:
6043 imm = shift;
6044 break;
6045 default:
6046 abort();
6049 for (pass = 0; pass < count; pass++) {
6050 if (size == 3) {
6051 neon_load_reg64(cpu_V0, rm + pass);
6052 tcg_gen_movi_i64(cpu_V1, imm);
6053 switch (op) {
6054 case 0: /* VSHR */
6055 case 1: /* VSRA */
6056 if (u)
6057 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6058 else
6059 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6060 break;
6061 case 2: /* VRSHR */
6062 case 3: /* VRSRA */
6063 if (u)
6064 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6065 else
6066 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6067 break;
6068 case 4: /* VSRI */
6069 case 5: /* VSHL, VSLI */
6070 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6071 break;
6072 case 6: /* VQSHLU */
6073 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6074 cpu_V0, cpu_V1);
6075 break;
6076 case 7: /* VQSHL */
6077 if (u) {
6078 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6079 cpu_V0, cpu_V1);
6080 } else {
6081 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6082 cpu_V0, cpu_V1);
6084 break;
6086 if (op == 1 || op == 3) {
6087 /* Accumulate. */
6088 neon_load_reg64(cpu_V1, rd + pass);
6089 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6090 } else if (op == 4 || (op == 5 && u)) {
6091 /* Insert */
6092 neon_load_reg64(cpu_V1, rd + pass);
6093 uint64_t mask;
6094 if (shift < -63 || shift > 63) {
6095 mask = 0;
6096 } else {
6097 if (op == 4) {
6098 mask = 0xffffffffffffffffull >> -shift;
6099 } else {
6100 mask = 0xffffffffffffffffull << shift;
6103 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6104 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6106 neon_store_reg64(cpu_V0, rd + pass);
6107 } else { /* size < 3 */
6108 /* Operands in T0 and T1. */
6109 tmp = neon_load_reg(rm, pass);
6110 tmp2 = tcg_temp_new_i32();
6111 tcg_gen_movi_i32(tmp2, imm);
6112 switch (op) {
6113 case 0: /* VSHR */
6114 case 1: /* VSRA */
6115 GEN_NEON_INTEGER_OP(shl);
6116 break;
6117 case 2: /* VRSHR */
6118 case 3: /* VRSRA */
6119 GEN_NEON_INTEGER_OP(rshl);
6120 break;
6121 case 4: /* VSRI */
6122 case 5: /* VSHL, VSLI */
6123 switch (size) {
6124 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6125 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6126 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6127 default: abort();
6129 break;
6130 case 6: /* VQSHLU */
6131 switch (size) {
6132 case 0:
6133 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6134 tmp, tmp2);
6135 break;
6136 case 1:
6137 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6138 tmp, tmp2);
6139 break;
6140 case 2:
6141 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6142 tmp, tmp2);
6143 break;
6144 default:
6145 abort();
6147 break;
6148 case 7: /* VQSHL */
6149 GEN_NEON_INTEGER_OP_ENV(qshl);
6150 break;
6152 tcg_temp_free_i32(tmp2);
6154 if (op == 1 || op == 3) {
6155 /* Accumulate. */
6156 tmp2 = neon_load_reg(rd, pass);
6157 gen_neon_add(size, tmp, tmp2);
6158 tcg_temp_free_i32(tmp2);
6159 } else if (op == 4 || (op == 5 && u)) {
6160 /* Insert */
6161 switch (size) {
6162 case 0:
6163 if (op == 4)
6164 mask = 0xff >> -shift;
6165 else
6166 mask = (uint8_t)(0xff << shift);
6167 mask |= mask << 8;
6168 mask |= mask << 16;
6169 break;
6170 case 1:
6171 if (op == 4)
6172 mask = 0xffff >> -shift;
6173 else
6174 mask = (uint16_t)(0xffff << shift);
6175 mask |= mask << 16;
6176 break;
6177 case 2:
6178 if (shift < -31 || shift > 31) {
6179 mask = 0;
6180 } else {
6181 if (op == 4)
6182 mask = 0xffffffffu >> -shift;
6183 else
6184 mask = 0xffffffffu << shift;
6186 break;
6187 default:
6188 abort();
6190 tmp2 = neon_load_reg(rd, pass);
6191 tcg_gen_andi_i32(tmp, tmp, mask);
6192 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6193 tcg_gen_or_i32(tmp, tmp, tmp2);
6194 tcg_temp_free_i32(tmp2);
6196 neon_store_reg(rd, pass, tmp);
6198 } /* for pass */
6199 } else if (op < 10) {
6200 /* Shift by immediate and narrow:
6201 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6202 int input_unsigned = (op == 8) ? !u : u;
6203 if (rm & 1) {
6204 return 1;
6206 shift = shift - (1 << (size + 3));
6207 size++;
6208 if (size == 3) {
6209 tmp64 = tcg_const_i64(shift);
6210 neon_load_reg64(cpu_V0, rm);
6211 neon_load_reg64(cpu_V1, rm + 1);
6212 for (pass = 0; pass < 2; pass++) {
6213 TCGv_i64 in;
6214 if (pass == 0) {
6215 in = cpu_V0;
6216 } else {
6217 in = cpu_V1;
6219 if (q) {
6220 if (input_unsigned) {
6221 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6222 } else {
6223 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6225 } else {
6226 if (input_unsigned) {
6227 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6228 } else {
6229 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6232 tmp = tcg_temp_new_i32();
6233 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6234 neon_store_reg(rd, pass, tmp);
6235 } /* for pass */
6236 tcg_temp_free_i64(tmp64);
6237 } else {
6238 if (size == 1) {
6239 imm = (uint16_t)shift;
6240 imm |= imm << 16;
6241 } else {
6242 /* size == 2 */
6243 imm = (uint32_t)shift;
6245 tmp2 = tcg_const_i32(imm);
6246 tmp4 = neon_load_reg(rm + 1, 0);
6247 tmp5 = neon_load_reg(rm + 1, 1);
6248 for (pass = 0; pass < 2; pass++) {
6249 if (pass == 0) {
6250 tmp = neon_load_reg(rm, 0);
6251 } else {
6252 tmp = tmp4;
6254 gen_neon_shift_narrow(size, tmp, tmp2, q,
6255 input_unsigned);
6256 if (pass == 0) {
6257 tmp3 = neon_load_reg(rm, 1);
6258 } else {
6259 tmp3 = tmp5;
6261 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6262 input_unsigned);
6263 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6264 tcg_temp_free_i32(tmp);
6265 tcg_temp_free_i32(tmp3);
6266 tmp = tcg_temp_new_i32();
6267 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6268 neon_store_reg(rd, pass, tmp);
6269 } /* for pass */
6270 tcg_temp_free_i32(tmp2);
6272 } else if (op == 10) {
6273 /* VSHLL, VMOVL */
6274 if (q || (rd & 1)) {
6275 return 1;
6277 tmp = neon_load_reg(rm, 0);
6278 tmp2 = neon_load_reg(rm, 1);
6279 for (pass = 0; pass < 2; pass++) {
6280 if (pass == 1)
6281 tmp = tmp2;
6283 gen_neon_widen(cpu_V0, tmp, size, u);
6285 if (shift != 0) {
6286 /* The shift is less than the width of the source
6287 type, so we can just shift the whole register. */
6288 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6289 /* Widen the result of shift: we need to clear
6290 * the potential overflow bits resulting from
6291 * left bits of the narrow input appearing as
6292 * right bits of left the neighbour narrow
6293 * input. */
6294 if (size < 2 || !u) {
6295 uint64_t imm64;
6296 if (size == 0) {
6297 imm = (0xffu >> (8 - shift));
6298 imm |= imm << 16;
6299 } else if (size == 1) {
6300 imm = 0xffff >> (16 - shift);
6301 } else {
6302 /* size == 2 */
6303 imm = 0xffffffff >> (32 - shift);
6305 if (size < 2) {
6306 imm64 = imm | (((uint64_t)imm) << 32);
6307 } else {
6308 imm64 = imm;
6310 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6313 neon_store_reg64(cpu_V0, rd + pass);
6315 } else if (op >= 14) {
6316 /* VCVT fixed-point. */
6317 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6318 return 1;
6320 /* We have already masked out the must-be-1 top bit of imm6,
6321 * hence this 32-shift where the ARM ARM has 64-imm6.
6323 shift = 32 - shift;
6324 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6325 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6326 if (!(op & 1)) {
6327 if (u)
6328 gen_vfp_ulto(0, shift, 1);
6329 else
6330 gen_vfp_slto(0, shift, 1);
6331 } else {
6332 if (u)
6333 gen_vfp_toul(0, shift, 1);
6334 else
6335 gen_vfp_tosl(0, shift, 1);
6337 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6339 } else {
6340 return 1;
6342 } else { /* (insn & 0x00380080) == 0 */
6343 int invert;
6344 if (q && (rd & 1)) {
6345 return 1;
6348 op = (insn >> 8) & 0xf;
6349 /* One register and immediate. */
6350 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6351 invert = (insn & (1 << 5)) != 0;
6352 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6353 * We choose to not special-case this and will behave as if a
6354 * valid constant encoding of 0 had been given.
6356 switch (op) {
6357 case 0: case 1:
6358 /* no-op */
6359 break;
6360 case 2: case 3:
6361 imm <<= 8;
6362 break;
6363 case 4: case 5:
6364 imm <<= 16;
6365 break;
6366 case 6: case 7:
6367 imm <<= 24;
6368 break;
6369 case 8: case 9:
6370 imm |= imm << 16;
6371 break;
6372 case 10: case 11:
6373 imm = (imm << 8) | (imm << 24);
6374 break;
6375 case 12:
6376 imm = (imm << 8) | 0xff;
6377 break;
6378 case 13:
6379 imm = (imm << 16) | 0xffff;
6380 break;
6381 case 14:
6382 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6383 if (invert)
6384 imm = ~imm;
6385 break;
6386 case 15:
6387 if (invert) {
6388 return 1;
6390 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6391 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6392 break;
6394 if (invert)
6395 imm = ~imm;
6397 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6398 if (op & 1 && op < 12) {
6399 tmp = neon_load_reg(rd, pass);
6400 if (invert) {
6401 /* The immediate value has already been inverted, so
6402 BIC becomes AND. */
6403 tcg_gen_andi_i32(tmp, tmp, imm);
6404 } else {
6405 tcg_gen_ori_i32(tmp, tmp, imm);
6407 } else {
6408 /* VMOV, VMVN. */
6409 tmp = tcg_temp_new_i32();
6410 if (op == 14 && invert) {
6411 int n;
6412 uint32_t val;
6413 val = 0;
6414 for (n = 0; n < 4; n++) {
6415 if (imm & (1 << (n + (pass & 1) * 4)))
6416 val |= 0xff << (n * 8);
6418 tcg_gen_movi_i32(tmp, val);
6419 } else {
6420 tcg_gen_movi_i32(tmp, imm);
6423 neon_store_reg(rd, pass, tmp);
6426 } else { /* (insn & 0x00800010 == 0x00800000) */
6427 if (size != 3) {
6428 op = (insn >> 8) & 0xf;
6429 if ((insn & (1 << 6)) == 0) {
6430 /* Three registers of different lengths. */
6431 int src1_wide;
6432 int src2_wide;
6433 int prewiden;
6434 /* undefreq: bit 0 : UNDEF if size == 0
6435 * bit 1 : UNDEF if size == 1
6436 * bit 2 : UNDEF if size == 2
6437 * bit 3 : UNDEF if U == 1
6438 * Note that [2:0] set implies 'always UNDEF'
6440 int undefreq;
6441 /* prewiden, src1_wide, src2_wide, undefreq */
6442 static const int neon_3reg_wide[16][4] = {
6443 {1, 0, 0, 0}, /* VADDL */
6444 {1, 1, 0, 0}, /* VADDW */
6445 {1, 0, 0, 0}, /* VSUBL */
6446 {1, 1, 0, 0}, /* VSUBW */
6447 {0, 1, 1, 0}, /* VADDHN */
6448 {0, 0, 0, 0}, /* VABAL */
6449 {0, 1, 1, 0}, /* VSUBHN */
6450 {0, 0, 0, 0}, /* VABDL */
6451 {0, 0, 0, 0}, /* VMLAL */
6452 {0, 0, 0, 9}, /* VQDMLAL */
6453 {0, 0, 0, 0}, /* VMLSL */
6454 {0, 0, 0, 9}, /* VQDMLSL */
6455 {0, 0, 0, 0}, /* Integer VMULL */
6456 {0, 0, 0, 1}, /* VQDMULL */
6457 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6458 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6461 prewiden = neon_3reg_wide[op][0];
6462 src1_wide = neon_3reg_wide[op][1];
6463 src2_wide = neon_3reg_wide[op][2];
6464 undefreq = neon_3reg_wide[op][3];
6466 if ((undefreq & (1 << size)) ||
6467 ((undefreq & 8) && u)) {
6468 return 1;
6470 if ((src1_wide && (rn & 1)) ||
6471 (src2_wide && (rm & 1)) ||
6472 (!src2_wide && (rd & 1))) {
6473 return 1;
6476 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6477 * outside the loop below as it only performs a single pass.
6479 if (op == 14 && size == 2) {
6480 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6482 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6483 return 1;
6485 tcg_rn = tcg_temp_new_i64();
6486 tcg_rm = tcg_temp_new_i64();
6487 tcg_rd = tcg_temp_new_i64();
6488 neon_load_reg64(tcg_rn, rn);
6489 neon_load_reg64(tcg_rm, rm);
6490 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6491 neon_store_reg64(tcg_rd, rd);
6492 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6493 neon_store_reg64(tcg_rd, rd + 1);
6494 tcg_temp_free_i64(tcg_rn);
6495 tcg_temp_free_i64(tcg_rm);
6496 tcg_temp_free_i64(tcg_rd);
6497 return 0;
6500 /* Avoid overlapping operands. Wide source operands are
6501 always aligned so will never overlap with wide
6502 destinations in problematic ways. */
6503 if (rd == rm && !src2_wide) {
6504 tmp = neon_load_reg(rm, 1);
6505 neon_store_scratch(2, tmp);
6506 } else if (rd == rn && !src1_wide) {
6507 tmp = neon_load_reg(rn, 1);
6508 neon_store_scratch(2, tmp);
6510 TCGV_UNUSED_I32(tmp3);
6511 for (pass = 0; pass < 2; pass++) {
6512 if (src1_wide) {
6513 neon_load_reg64(cpu_V0, rn + pass);
6514 TCGV_UNUSED_I32(tmp);
6515 } else {
6516 if (pass == 1 && rd == rn) {
6517 tmp = neon_load_scratch(2);
6518 } else {
6519 tmp = neon_load_reg(rn, pass);
6521 if (prewiden) {
6522 gen_neon_widen(cpu_V0, tmp, size, u);
6525 if (src2_wide) {
6526 neon_load_reg64(cpu_V1, rm + pass);
6527 TCGV_UNUSED_I32(tmp2);
6528 } else {
6529 if (pass == 1 && rd == rm) {
6530 tmp2 = neon_load_scratch(2);
6531 } else {
6532 tmp2 = neon_load_reg(rm, pass);
6534 if (prewiden) {
6535 gen_neon_widen(cpu_V1, tmp2, size, u);
6538 switch (op) {
6539 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6540 gen_neon_addl(size);
6541 break;
6542 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6543 gen_neon_subl(size);
6544 break;
6545 case 5: case 7: /* VABAL, VABDL */
6546 switch ((size << 1) | u) {
6547 case 0:
6548 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6549 break;
6550 case 1:
6551 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6552 break;
6553 case 2:
6554 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6555 break;
6556 case 3:
6557 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6558 break;
6559 case 4:
6560 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6561 break;
6562 case 5:
6563 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6564 break;
6565 default: abort();
6567 tcg_temp_free_i32(tmp2);
6568 tcg_temp_free_i32(tmp);
6569 break;
6570 case 8: case 9: case 10: case 11: case 12: case 13:
6571 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6572 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6573 break;
6574 case 14: /* Polynomial VMULL */
6575 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6576 tcg_temp_free_i32(tmp2);
6577 tcg_temp_free_i32(tmp);
6578 break;
6579 default: /* 15 is RESERVED: caught earlier */
6580 abort();
6582 if (op == 13) {
6583 /* VQDMULL */
6584 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6585 neon_store_reg64(cpu_V0, rd + pass);
6586 } else if (op == 5 || (op >= 8 && op <= 11)) {
6587 /* Accumulate. */
6588 neon_load_reg64(cpu_V1, rd + pass);
6589 switch (op) {
6590 case 10: /* VMLSL */
6591 gen_neon_negl(cpu_V0, size);
6592 /* Fall through */
6593 case 5: case 8: /* VABAL, VMLAL */
6594 gen_neon_addl(size);
6595 break;
6596 case 9: case 11: /* VQDMLAL, VQDMLSL */
6597 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6598 if (op == 11) {
6599 gen_neon_negl(cpu_V0, size);
6601 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6602 break;
6603 default:
6604 abort();
6606 neon_store_reg64(cpu_V0, rd + pass);
6607 } else if (op == 4 || op == 6) {
6608 /* Narrowing operation. */
6609 tmp = tcg_temp_new_i32();
6610 if (!u) {
6611 switch (size) {
6612 case 0:
6613 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6614 break;
6615 case 1:
6616 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6617 break;
6618 case 2:
6619 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6620 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6621 break;
6622 default: abort();
6624 } else {
6625 switch (size) {
6626 case 0:
6627 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6628 break;
6629 case 1:
6630 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6631 break;
6632 case 2:
6633 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6634 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6635 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6636 break;
6637 default: abort();
6640 if (pass == 0) {
6641 tmp3 = tmp;
6642 } else {
6643 neon_store_reg(rd, 0, tmp3);
6644 neon_store_reg(rd, 1, tmp);
6646 } else {
6647 /* Write back the result. */
6648 neon_store_reg64(cpu_V0, rd + pass);
6651 } else {
6652 /* Two registers and a scalar. NB that for ops of this form
6653 * the ARM ARM labels bit 24 as Q, but it is in our variable
6654 * 'u', not 'q'.
6656 if (size == 0) {
6657 return 1;
6659 switch (op) {
6660 case 1: /* Float VMLA scalar */
6661 case 5: /* Floating point VMLS scalar */
6662 case 9: /* Floating point VMUL scalar */
6663 if (size == 1) {
6664 return 1;
6666 /* fall through */
6667 case 0: /* Integer VMLA scalar */
6668 case 4: /* Integer VMLS scalar */
6669 case 8: /* Integer VMUL scalar */
6670 case 12: /* VQDMULH scalar */
6671 case 13: /* VQRDMULH scalar */
6672 if (u && ((rd | rn) & 1)) {
6673 return 1;
6675 tmp = neon_get_scalar(size, rm);
6676 neon_store_scratch(0, tmp);
6677 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6678 tmp = neon_load_scratch(0);
6679 tmp2 = neon_load_reg(rn, pass);
6680 if (op == 12) {
6681 if (size == 1) {
6682 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6683 } else {
6684 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6686 } else if (op == 13) {
6687 if (size == 1) {
6688 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6689 } else {
6690 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6692 } else if (op & 1) {
6693 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6694 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6695 tcg_temp_free_ptr(fpstatus);
6696 } else {
6697 switch (size) {
6698 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6699 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6700 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6701 default: abort();
6704 tcg_temp_free_i32(tmp2);
6705 if (op < 8) {
6706 /* Accumulate. */
6707 tmp2 = neon_load_reg(rd, pass);
6708 switch (op) {
6709 case 0:
6710 gen_neon_add(size, tmp, tmp2);
6711 break;
6712 case 1:
6714 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6715 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6716 tcg_temp_free_ptr(fpstatus);
6717 break;
6719 case 4:
6720 gen_neon_rsb(size, tmp, tmp2);
6721 break;
6722 case 5:
6724 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6725 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6726 tcg_temp_free_ptr(fpstatus);
6727 break;
6729 default:
6730 abort();
6732 tcg_temp_free_i32(tmp2);
6734 neon_store_reg(rd, pass, tmp);
6736 break;
6737 case 3: /* VQDMLAL scalar */
6738 case 7: /* VQDMLSL scalar */
6739 case 11: /* VQDMULL scalar */
6740 if (u == 1) {
6741 return 1;
6743 /* fall through */
6744 case 2: /* VMLAL sclar */
6745 case 6: /* VMLSL scalar */
6746 case 10: /* VMULL scalar */
6747 if (rd & 1) {
6748 return 1;
6750 tmp2 = neon_get_scalar(size, rm);
6751 /* We need a copy of tmp2 because gen_neon_mull
6752 * deletes it during pass 0. */
6753 tmp4 = tcg_temp_new_i32();
6754 tcg_gen_mov_i32(tmp4, tmp2);
6755 tmp3 = neon_load_reg(rn, 1);
6757 for (pass = 0; pass < 2; pass++) {
6758 if (pass == 0) {
6759 tmp = neon_load_reg(rn, 0);
6760 } else {
6761 tmp = tmp3;
6762 tmp2 = tmp4;
6764 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6765 if (op != 11) {
6766 neon_load_reg64(cpu_V1, rd + pass);
6768 switch (op) {
6769 case 6:
6770 gen_neon_negl(cpu_V0, size);
6771 /* Fall through */
6772 case 2:
6773 gen_neon_addl(size);
6774 break;
6775 case 3: case 7:
6776 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6777 if (op == 7) {
6778 gen_neon_negl(cpu_V0, size);
6780 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6781 break;
6782 case 10:
6783 /* no-op */
6784 break;
6785 case 11:
6786 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6787 break;
6788 default:
6789 abort();
6791 neon_store_reg64(cpu_V0, rd + pass);
6795 break;
6796 default: /* 14 and 15 are RESERVED */
6797 return 1;
6800 } else { /* size == 3 */
6801 if (!u) {
6802 /* Extract. */
6803 imm = (insn >> 8) & 0xf;
6805 if (imm > 7 && !q)
6806 return 1;
6808 if (q && ((rd | rn | rm) & 1)) {
6809 return 1;
6812 if (imm == 0) {
6813 neon_load_reg64(cpu_V0, rn);
6814 if (q) {
6815 neon_load_reg64(cpu_V1, rn + 1);
6817 } else if (imm == 8) {
6818 neon_load_reg64(cpu_V0, rn + 1);
6819 if (q) {
6820 neon_load_reg64(cpu_V1, rm);
6822 } else if (q) {
6823 tmp64 = tcg_temp_new_i64();
6824 if (imm < 8) {
6825 neon_load_reg64(cpu_V0, rn);
6826 neon_load_reg64(tmp64, rn + 1);
6827 } else {
6828 neon_load_reg64(cpu_V0, rn + 1);
6829 neon_load_reg64(tmp64, rm);
6831 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6832 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6833 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6834 if (imm < 8) {
6835 neon_load_reg64(cpu_V1, rm);
6836 } else {
6837 neon_load_reg64(cpu_V1, rm + 1);
6838 imm -= 8;
6840 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6841 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6842 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6843 tcg_temp_free_i64(tmp64);
6844 } else {
6845 /* BUGFIX */
6846 neon_load_reg64(cpu_V0, rn);
6847 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6848 neon_load_reg64(cpu_V1, rm);
6849 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6850 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6852 neon_store_reg64(cpu_V0, rd);
6853 if (q) {
6854 neon_store_reg64(cpu_V1, rd + 1);
6856 } else if ((insn & (1 << 11)) == 0) {
6857 /* Two register misc. */
6858 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6859 size = (insn >> 18) & 3;
6860 /* UNDEF for unknown op values and bad op-size combinations */
6861 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6862 return 1;
6864 if (neon_2rm_is_v8_op(op) &&
6865 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6866 return 1;
6868 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6869 q && ((rm | rd) & 1)) {
6870 return 1;
6872 switch (op) {
6873 case NEON_2RM_VREV64:
6874 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6875 tmp = neon_load_reg(rm, pass * 2);
6876 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6877 switch (size) {
6878 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6879 case 1: gen_swap_half(tmp); break;
6880 case 2: /* no-op */ break;
6881 default: abort();
6883 neon_store_reg(rd, pass * 2 + 1, tmp);
6884 if (size == 2) {
6885 neon_store_reg(rd, pass * 2, tmp2);
6886 } else {
6887 switch (size) {
6888 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6889 case 1: gen_swap_half(tmp2); break;
6890 default: abort();
6892 neon_store_reg(rd, pass * 2, tmp2);
6895 break;
6896 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6897 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6898 for (pass = 0; pass < q + 1; pass++) {
6899 tmp = neon_load_reg(rm, pass * 2);
6900 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6901 tmp = neon_load_reg(rm, pass * 2 + 1);
6902 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6903 switch (size) {
6904 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6905 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6906 case 2: tcg_gen_add_i64(CPU_V001); break;
6907 default: abort();
6909 if (op >= NEON_2RM_VPADAL) {
6910 /* Accumulate. */
6911 neon_load_reg64(cpu_V1, rd + pass);
6912 gen_neon_addl(size);
6914 neon_store_reg64(cpu_V0, rd + pass);
6916 break;
6917 case NEON_2RM_VTRN:
6918 if (size == 2) {
6919 int n;
6920 for (n = 0; n < (q ? 4 : 2); n += 2) {
6921 tmp = neon_load_reg(rm, n);
6922 tmp2 = neon_load_reg(rd, n + 1);
6923 neon_store_reg(rm, n, tmp2);
6924 neon_store_reg(rd, n + 1, tmp);
6926 } else {
6927 goto elementwise;
6929 break;
6930 case NEON_2RM_VUZP:
6931 if (gen_neon_unzip(rd, rm, size, q)) {
6932 return 1;
6934 break;
6935 case NEON_2RM_VZIP:
6936 if (gen_neon_zip(rd, rm, size, q)) {
6937 return 1;
6939 break;
6940 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6941 /* also VQMOVUN; op field and mnemonics don't line up */
6942 if (rm & 1) {
6943 return 1;
6945 TCGV_UNUSED_I32(tmp2);
6946 for (pass = 0; pass < 2; pass++) {
6947 neon_load_reg64(cpu_V0, rm + pass);
6948 tmp = tcg_temp_new_i32();
6949 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6950 tmp, cpu_V0);
6951 if (pass == 0) {
6952 tmp2 = tmp;
6953 } else {
6954 neon_store_reg(rd, 0, tmp2);
6955 neon_store_reg(rd, 1, tmp);
6958 break;
6959 case NEON_2RM_VSHLL:
6960 if (q || (rd & 1)) {
6961 return 1;
6963 tmp = neon_load_reg(rm, 0);
6964 tmp2 = neon_load_reg(rm, 1);
6965 for (pass = 0; pass < 2; pass++) {
6966 if (pass == 1)
6967 tmp = tmp2;
6968 gen_neon_widen(cpu_V0, tmp, size, 1);
6969 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6970 neon_store_reg64(cpu_V0, rd + pass);
6972 break;
6973 case NEON_2RM_VCVT_F16_F32:
6974 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6975 q || (rm & 1)) {
6976 return 1;
6978 tmp = tcg_temp_new_i32();
6979 tmp2 = tcg_temp_new_i32();
6980 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6981 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6982 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6983 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6984 tcg_gen_shli_i32(tmp2, tmp2, 16);
6985 tcg_gen_or_i32(tmp2, tmp2, tmp);
6986 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6987 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6988 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6989 neon_store_reg(rd, 0, tmp2);
6990 tmp2 = tcg_temp_new_i32();
6991 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6992 tcg_gen_shli_i32(tmp2, tmp2, 16);
6993 tcg_gen_or_i32(tmp2, tmp2, tmp);
6994 neon_store_reg(rd, 1, tmp2);
6995 tcg_temp_free_i32(tmp);
6996 break;
6997 case NEON_2RM_VCVT_F32_F16:
6998 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6999 q || (rd & 1)) {
7000 return 1;
7002 tmp3 = tcg_temp_new_i32();
7003 tmp = neon_load_reg(rm, 0);
7004 tmp2 = neon_load_reg(rm, 1);
7005 tcg_gen_ext16u_i32(tmp3, tmp);
7006 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7007 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7008 tcg_gen_shri_i32(tmp3, tmp, 16);
7009 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7010 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7011 tcg_temp_free_i32(tmp);
7012 tcg_gen_ext16u_i32(tmp3, tmp2);
7013 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7014 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7015 tcg_gen_shri_i32(tmp3, tmp2, 16);
7016 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7017 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7018 tcg_temp_free_i32(tmp2);
7019 tcg_temp_free_i32(tmp3);
7020 break;
7021 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7022 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7023 || ((rm | rd) & 1)) {
7024 return 1;
7026 tmp = tcg_const_i32(rd);
7027 tmp2 = tcg_const_i32(rm);
7029 /* Bit 6 is the lowest opcode bit; it distinguishes between
7030 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7032 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7034 if (op == NEON_2RM_AESE) {
7035 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
7036 } else {
7037 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
7039 tcg_temp_free_i32(tmp);
7040 tcg_temp_free_i32(tmp2);
7041 tcg_temp_free_i32(tmp3);
7042 break;
7043 case NEON_2RM_SHA1H:
7044 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7045 || ((rm | rd) & 1)) {
7046 return 1;
7048 tmp = tcg_const_i32(rd);
7049 tmp2 = tcg_const_i32(rm);
7051 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
7053 tcg_temp_free_i32(tmp);
7054 tcg_temp_free_i32(tmp2);
7055 break;
7056 case NEON_2RM_SHA1SU1:
7057 if ((rm | rd) & 1) {
7058 return 1;
7060 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7061 if (q) {
7062 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7063 return 1;
7065 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7066 return 1;
7068 tmp = tcg_const_i32(rd);
7069 tmp2 = tcg_const_i32(rm);
7070 if (q) {
7071 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7072 } else {
7073 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7075 tcg_temp_free_i32(tmp);
7076 tcg_temp_free_i32(tmp2);
7077 break;
7078 default:
7079 elementwise:
7080 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7081 if (neon_2rm_is_float_op(op)) {
7082 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7083 neon_reg_offset(rm, pass));
7084 TCGV_UNUSED_I32(tmp);
7085 } else {
7086 tmp = neon_load_reg(rm, pass);
7088 switch (op) {
7089 case NEON_2RM_VREV32:
7090 switch (size) {
7091 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7092 case 1: gen_swap_half(tmp); break;
7093 default: abort();
7095 break;
7096 case NEON_2RM_VREV16:
7097 gen_rev16(tmp);
7098 break;
7099 case NEON_2RM_VCLS:
7100 switch (size) {
7101 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7102 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7103 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7104 default: abort();
7106 break;
7107 case NEON_2RM_VCLZ:
7108 switch (size) {
7109 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7110 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7111 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7112 default: abort();
7114 break;
7115 case NEON_2RM_VCNT:
7116 gen_helper_neon_cnt_u8(tmp, tmp);
7117 break;
7118 case NEON_2RM_VMVN:
7119 tcg_gen_not_i32(tmp, tmp);
7120 break;
7121 case NEON_2RM_VQABS:
7122 switch (size) {
7123 case 0:
7124 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7125 break;
7126 case 1:
7127 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7128 break;
7129 case 2:
7130 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7131 break;
7132 default: abort();
7134 break;
7135 case NEON_2RM_VQNEG:
7136 switch (size) {
7137 case 0:
7138 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7139 break;
7140 case 1:
7141 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7142 break;
7143 case 2:
7144 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7145 break;
7146 default: abort();
7148 break;
7149 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7150 tmp2 = tcg_const_i32(0);
7151 switch(size) {
7152 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7153 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7154 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7155 default: abort();
7157 tcg_temp_free_i32(tmp2);
7158 if (op == NEON_2RM_VCLE0) {
7159 tcg_gen_not_i32(tmp, tmp);
7161 break;
7162 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7163 tmp2 = tcg_const_i32(0);
7164 switch(size) {
7165 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7166 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7167 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7168 default: abort();
7170 tcg_temp_free_i32(tmp2);
7171 if (op == NEON_2RM_VCLT0) {
7172 tcg_gen_not_i32(tmp, tmp);
7174 break;
7175 case NEON_2RM_VCEQ0:
7176 tmp2 = tcg_const_i32(0);
7177 switch(size) {
7178 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7179 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7180 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7181 default: abort();
7183 tcg_temp_free_i32(tmp2);
7184 break;
7185 case NEON_2RM_VABS:
7186 switch(size) {
7187 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7188 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7189 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7190 default: abort();
7192 break;
7193 case NEON_2RM_VNEG:
7194 tmp2 = tcg_const_i32(0);
7195 gen_neon_rsb(size, tmp, tmp2);
7196 tcg_temp_free_i32(tmp2);
7197 break;
7198 case NEON_2RM_VCGT0_F:
7200 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7201 tmp2 = tcg_const_i32(0);
7202 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7203 tcg_temp_free_i32(tmp2);
7204 tcg_temp_free_ptr(fpstatus);
7205 break;
7207 case NEON_2RM_VCGE0_F:
7209 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7210 tmp2 = tcg_const_i32(0);
7211 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7212 tcg_temp_free_i32(tmp2);
7213 tcg_temp_free_ptr(fpstatus);
7214 break;
7216 case NEON_2RM_VCEQ0_F:
7218 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7219 tmp2 = tcg_const_i32(0);
7220 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7221 tcg_temp_free_i32(tmp2);
7222 tcg_temp_free_ptr(fpstatus);
7223 break;
7225 case NEON_2RM_VCLE0_F:
7227 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7228 tmp2 = tcg_const_i32(0);
7229 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7230 tcg_temp_free_i32(tmp2);
7231 tcg_temp_free_ptr(fpstatus);
7232 break;
7234 case NEON_2RM_VCLT0_F:
7236 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7237 tmp2 = tcg_const_i32(0);
7238 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7239 tcg_temp_free_i32(tmp2);
7240 tcg_temp_free_ptr(fpstatus);
7241 break;
7243 case NEON_2RM_VABS_F:
7244 gen_vfp_abs(0);
7245 break;
7246 case NEON_2RM_VNEG_F:
7247 gen_vfp_neg(0);
7248 break;
7249 case NEON_2RM_VSWP:
7250 tmp2 = neon_load_reg(rd, pass);
7251 neon_store_reg(rm, pass, tmp2);
7252 break;
7253 case NEON_2RM_VTRN:
7254 tmp2 = neon_load_reg(rd, pass);
7255 switch (size) {
7256 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7257 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7258 default: abort();
7260 neon_store_reg(rm, pass, tmp2);
7261 break;
7262 case NEON_2RM_VRINTN:
7263 case NEON_2RM_VRINTA:
7264 case NEON_2RM_VRINTM:
7265 case NEON_2RM_VRINTP:
7266 case NEON_2RM_VRINTZ:
7268 TCGv_i32 tcg_rmode;
7269 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7270 int rmode;
7272 if (op == NEON_2RM_VRINTZ) {
7273 rmode = FPROUNDING_ZERO;
7274 } else {
7275 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7278 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7279 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7280 cpu_env);
7281 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7282 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7283 cpu_env);
7284 tcg_temp_free_ptr(fpstatus);
7285 tcg_temp_free_i32(tcg_rmode);
7286 break;
7288 case NEON_2RM_VRINTX:
7290 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7291 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7292 tcg_temp_free_ptr(fpstatus);
7293 break;
7295 case NEON_2RM_VCVTAU:
7296 case NEON_2RM_VCVTAS:
7297 case NEON_2RM_VCVTNU:
7298 case NEON_2RM_VCVTNS:
7299 case NEON_2RM_VCVTPU:
7300 case NEON_2RM_VCVTPS:
7301 case NEON_2RM_VCVTMU:
7302 case NEON_2RM_VCVTMS:
7304 bool is_signed = !extract32(insn, 7, 1);
7305 TCGv_ptr fpst = get_fpstatus_ptr(1);
7306 TCGv_i32 tcg_rmode, tcg_shift;
7307 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7309 tcg_shift = tcg_const_i32(0);
7310 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7311 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7312 cpu_env);
7314 if (is_signed) {
7315 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7316 tcg_shift, fpst);
7317 } else {
7318 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7319 tcg_shift, fpst);
7322 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7323 cpu_env);
7324 tcg_temp_free_i32(tcg_rmode);
7325 tcg_temp_free_i32(tcg_shift);
7326 tcg_temp_free_ptr(fpst);
7327 break;
7329 case NEON_2RM_VRECPE:
7331 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7332 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7333 tcg_temp_free_ptr(fpstatus);
7334 break;
7336 case NEON_2RM_VRSQRTE:
7338 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7339 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7340 tcg_temp_free_ptr(fpstatus);
7341 break;
7343 case NEON_2RM_VRECPE_F:
7345 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7346 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7347 tcg_temp_free_ptr(fpstatus);
7348 break;
7350 case NEON_2RM_VRSQRTE_F:
7352 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7353 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7354 tcg_temp_free_ptr(fpstatus);
7355 break;
7357 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7358 gen_vfp_sito(0, 1);
7359 break;
7360 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7361 gen_vfp_uito(0, 1);
7362 break;
7363 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7364 gen_vfp_tosiz(0, 1);
7365 break;
7366 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7367 gen_vfp_touiz(0, 1);
7368 break;
7369 default:
7370 /* Reserved op values were caught by the
7371 * neon_2rm_sizes[] check earlier.
7373 abort();
7375 if (neon_2rm_is_float_op(op)) {
7376 tcg_gen_st_f32(cpu_F0s, cpu_env,
7377 neon_reg_offset(rd, pass));
7378 } else {
7379 neon_store_reg(rd, pass, tmp);
7382 break;
7384 } else if ((insn & (1 << 10)) == 0) {
7385 /* VTBL, VTBX. */
7386 int n = ((insn >> 8) & 3) + 1;
7387 if ((rn + n) > 32) {
7388 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7389 * helper function running off the end of the register file.
7391 return 1;
7393 n <<= 3;
7394 if (insn & (1 << 6)) {
7395 tmp = neon_load_reg(rd, 0);
7396 } else {
7397 tmp = tcg_temp_new_i32();
7398 tcg_gen_movi_i32(tmp, 0);
7400 tmp2 = neon_load_reg(rm, 0);
7401 tmp4 = tcg_const_i32(rn);
7402 tmp5 = tcg_const_i32(n);
7403 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7404 tcg_temp_free_i32(tmp);
7405 if (insn & (1 << 6)) {
7406 tmp = neon_load_reg(rd, 1);
7407 } else {
7408 tmp = tcg_temp_new_i32();
7409 tcg_gen_movi_i32(tmp, 0);
7411 tmp3 = neon_load_reg(rm, 1);
7412 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7413 tcg_temp_free_i32(tmp5);
7414 tcg_temp_free_i32(tmp4);
7415 neon_store_reg(rd, 0, tmp2);
7416 neon_store_reg(rd, 1, tmp3);
7417 tcg_temp_free_i32(tmp);
7418 } else if ((insn & 0x380) == 0) {
7419 /* VDUP */
7420 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7421 return 1;
7423 if (insn & (1 << 19)) {
7424 tmp = neon_load_reg(rm, 1);
7425 } else {
7426 tmp = neon_load_reg(rm, 0);
7428 if (insn & (1 << 16)) {
7429 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7430 } else if (insn & (1 << 17)) {
7431 if ((insn >> 18) & 1)
7432 gen_neon_dup_high16(tmp);
7433 else
7434 gen_neon_dup_low16(tmp);
7436 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7437 tmp2 = tcg_temp_new_i32();
7438 tcg_gen_mov_i32(tmp2, tmp);
7439 neon_store_reg(rd, pass, tmp2);
7441 tcg_temp_free_i32(tmp);
7442 } else {
7443 return 1;
7447 return 0;
7450 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7452 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7453 const ARMCPRegInfo *ri;
7455 cpnum = (insn >> 8) & 0xf;
7457 /* First check for coprocessor space used for XScale/iwMMXt insns */
7458 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7459 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7460 return 1;
7462 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7463 return disas_iwmmxt_insn(s, insn);
7464 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7465 return disas_dsp_insn(s, insn);
7467 return 1;
7470 /* Otherwise treat as a generic register access */
7471 is64 = (insn & (1 << 25)) == 0;
7472 if (!is64 && ((insn & (1 << 4)) == 0)) {
7473 /* cdp */
7474 return 1;
7477 crm = insn & 0xf;
7478 if (is64) {
7479 crn = 0;
7480 opc1 = (insn >> 4) & 0xf;
7481 opc2 = 0;
7482 rt2 = (insn >> 16) & 0xf;
7483 } else {
7484 crn = (insn >> 16) & 0xf;
7485 opc1 = (insn >> 21) & 7;
7486 opc2 = (insn >> 5) & 7;
7487 rt2 = 0;
7489 isread = (insn >> 20) & 1;
7490 rt = (insn >> 12) & 0xf;
7492 ri = get_arm_cp_reginfo(s->cp_regs,
7493 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7494 if (ri) {
7495 /* Check access permissions */
7496 if (!cp_access_ok(s->current_el, ri, isread)) {
7497 return 1;
7500 if (ri->accessfn ||
7501 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7502 /* Emit code to perform further access permissions checks at
7503 * runtime; this may result in an exception.
7504 * Note that on XScale all cp0..c13 registers do an access check
7505 * call in order to handle c15_cpar.
7507 TCGv_ptr tmpptr;
7508 TCGv_i32 tcg_syn, tcg_isread;
7509 uint32_t syndrome;
7511 /* Note that since we are an implementation which takes an
7512 * exception on a trapped conditional instruction only if the
7513 * instruction passes its condition code check, we can take
7514 * advantage of the clause in the ARM ARM that allows us to set
7515 * the COND field in the instruction to 0xE in all cases.
7516 * We could fish the actual condition out of the insn (ARM)
7517 * or the condexec bits (Thumb) but it isn't necessary.
7519 switch (cpnum) {
7520 case 14:
7521 if (is64) {
7522 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7523 isread, false);
7524 } else {
7525 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7526 rt, isread, false);
7528 break;
7529 case 15:
7530 if (is64) {
7531 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7532 isread, false);
7533 } else {
7534 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7535 rt, isread, false);
7537 break;
7538 default:
7539 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7540 * so this can only happen if this is an ARMv7 or earlier CPU,
7541 * in which case the syndrome information won't actually be
7542 * guest visible.
7544 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7545 syndrome = syn_uncategorized();
7546 break;
7549 gen_set_condexec(s);
7550 gen_set_pc_im(s, s->pc - 4);
7551 tmpptr = tcg_const_ptr(ri);
7552 tcg_syn = tcg_const_i32(syndrome);
7553 tcg_isread = tcg_const_i32(isread);
7554 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7555 tcg_isread);
7556 tcg_temp_free_ptr(tmpptr);
7557 tcg_temp_free_i32(tcg_syn);
7558 tcg_temp_free_i32(tcg_isread);
7561 /* Handle special cases first */
7562 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7563 case ARM_CP_NOP:
7564 return 0;
7565 case ARM_CP_WFI:
7566 if (isread) {
7567 return 1;
7569 gen_set_pc_im(s, s->pc);
7570 s->is_jmp = DISAS_WFI;
7571 return 0;
7572 default:
7573 break;
7576 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7577 gen_io_start();
7580 if (isread) {
7581 /* Read */
7582 if (is64) {
7583 TCGv_i64 tmp64;
7584 TCGv_i32 tmp;
7585 if (ri->type & ARM_CP_CONST) {
7586 tmp64 = tcg_const_i64(ri->resetvalue);
7587 } else if (ri->readfn) {
7588 TCGv_ptr tmpptr;
7589 tmp64 = tcg_temp_new_i64();
7590 tmpptr = tcg_const_ptr(ri);
7591 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7592 tcg_temp_free_ptr(tmpptr);
7593 } else {
7594 tmp64 = tcg_temp_new_i64();
7595 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7597 tmp = tcg_temp_new_i32();
7598 tcg_gen_extrl_i64_i32(tmp, tmp64);
7599 store_reg(s, rt, tmp);
7600 tcg_gen_shri_i64(tmp64, tmp64, 32);
7601 tmp = tcg_temp_new_i32();
7602 tcg_gen_extrl_i64_i32(tmp, tmp64);
7603 tcg_temp_free_i64(tmp64);
7604 store_reg(s, rt2, tmp);
7605 } else {
7606 TCGv_i32 tmp;
7607 if (ri->type & ARM_CP_CONST) {
7608 tmp = tcg_const_i32(ri->resetvalue);
7609 } else if (ri->readfn) {
7610 TCGv_ptr tmpptr;
7611 tmp = tcg_temp_new_i32();
7612 tmpptr = tcg_const_ptr(ri);
7613 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7614 tcg_temp_free_ptr(tmpptr);
7615 } else {
7616 tmp = load_cpu_offset(ri->fieldoffset);
7618 if (rt == 15) {
7619 /* Destination register of r15 for 32 bit loads sets
7620 * the condition codes from the high 4 bits of the value
7622 gen_set_nzcv(tmp);
7623 tcg_temp_free_i32(tmp);
7624 } else {
7625 store_reg(s, rt, tmp);
7628 } else {
7629 /* Write */
7630 if (ri->type & ARM_CP_CONST) {
7631 /* If not forbidden by access permissions, treat as WI */
7632 return 0;
7635 if (is64) {
7636 TCGv_i32 tmplo, tmphi;
7637 TCGv_i64 tmp64 = tcg_temp_new_i64();
7638 tmplo = load_reg(s, rt);
7639 tmphi = load_reg(s, rt2);
7640 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7641 tcg_temp_free_i32(tmplo);
7642 tcg_temp_free_i32(tmphi);
7643 if (ri->writefn) {
7644 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7645 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7646 tcg_temp_free_ptr(tmpptr);
7647 } else {
7648 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7650 tcg_temp_free_i64(tmp64);
7651 } else {
7652 if (ri->writefn) {
7653 TCGv_i32 tmp;
7654 TCGv_ptr tmpptr;
7655 tmp = load_reg(s, rt);
7656 tmpptr = tcg_const_ptr(ri);
7657 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7658 tcg_temp_free_ptr(tmpptr);
7659 tcg_temp_free_i32(tmp);
7660 } else {
7661 TCGv_i32 tmp = load_reg(s, rt);
7662 store_cpu_offset(tmp, ri->fieldoffset);
7667 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7668 /* I/O operations must end the TB here (whether read or write) */
7669 gen_io_end();
7670 gen_lookup_tb(s);
7671 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7672 /* We default to ending the TB on a coprocessor register write,
7673 * but allow this to be suppressed by the register definition
7674 * (usually only necessary to work around guest bugs).
7676 gen_lookup_tb(s);
7679 return 0;
7682 /* Unknown register; this might be a guest error or a QEMU
7683 * unimplemented feature.
7685 if (is64) {
7686 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7687 "64 bit system register cp:%d opc1: %d crm:%d "
7688 "(%s)\n",
7689 isread ? "read" : "write", cpnum, opc1, crm,
7690 s->ns ? "non-secure" : "secure");
7691 } else {
7692 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7693 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7694 "(%s)\n",
7695 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7696 s->ns ? "non-secure" : "secure");
7699 return 1;
7703 /* Store a 64-bit value to a register pair. Clobbers val. */
7704 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7706 TCGv_i32 tmp;
7707 tmp = tcg_temp_new_i32();
7708 tcg_gen_extrl_i64_i32(tmp, val);
7709 store_reg(s, rlow, tmp);
7710 tmp = tcg_temp_new_i32();
7711 tcg_gen_shri_i64(val, val, 32);
7712 tcg_gen_extrl_i64_i32(tmp, val);
7713 store_reg(s, rhigh, tmp);
7716 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7717 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7719 TCGv_i64 tmp;
7720 TCGv_i32 tmp2;
7722 /* Load value and extend to 64 bits. */
7723 tmp = tcg_temp_new_i64();
7724 tmp2 = load_reg(s, rlow);
7725 tcg_gen_extu_i32_i64(tmp, tmp2);
7726 tcg_temp_free_i32(tmp2);
7727 tcg_gen_add_i64(val, val, tmp);
7728 tcg_temp_free_i64(tmp);
7731 /* load and add a 64-bit value from a register pair. */
7732 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7734 TCGv_i64 tmp;
7735 TCGv_i32 tmpl;
7736 TCGv_i32 tmph;
7738 /* Load 64-bit value rd:rn. */
7739 tmpl = load_reg(s, rlow);
7740 tmph = load_reg(s, rhigh);
7741 tmp = tcg_temp_new_i64();
7742 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7743 tcg_temp_free_i32(tmpl);
7744 tcg_temp_free_i32(tmph);
7745 tcg_gen_add_i64(val, val, tmp);
7746 tcg_temp_free_i64(tmp);
7749 /* Set N and Z flags from hi|lo. */
7750 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7752 tcg_gen_mov_i32(cpu_NF, hi);
7753 tcg_gen_or_i32(cpu_ZF, lo, hi);
7756 /* Load/Store exclusive instructions are implemented by remembering
7757 the value/address loaded, and seeing if these are the same
7758 when the store is performed. This should be sufficient to implement
7759 the architecturally mandated semantics, and avoids having to monitor
7760 regular stores. The compare vs the remembered value is done during
7761 the cmpxchg operation, but we must compare the addresses manually. */
7762 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7763 TCGv_i32 addr, int size)
7765 TCGv_i32 tmp = tcg_temp_new_i32();
7766 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7768 s->is_ldex = true;
7770 if (size == 3) {
7771 TCGv_i32 tmp2 = tcg_temp_new_i32();
7772 TCGv_i64 t64 = tcg_temp_new_i64();
7774 gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
7775 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7776 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7777 tcg_temp_free_i64(t64);
7779 store_reg(s, rt2, tmp2);
7780 } else {
7781 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7782 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7785 store_reg(s, rt, tmp);
7786 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7789 static void gen_clrex(DisasContext *s)
7791 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7794 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7795 TCGv_i32 addr, int size)
7797 TCGv_i32 t0, t1, t2;
7798 TCGv_i64 extaddr;
7799 TCGv taddr;
7800 TCGLabel *done_label;
7801 TCGLabel *fail_label;
7802 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7804 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7805 [addr] = {Rt};
7806 {Rd} = 0;
7807 } else {
7808 {Rd} = 1;
7809 } */
7810 fail_label = gen_new_label();
7811 done_label = gen_new_label();
7812 extaddr = tcg_temp_new_i64();
7813 tcg_gen_extu_i32_i64(extaddr, addr);
7814 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7815 tcg_temp_free_i64(extaddr);
7817 taddr = gen_aa32_addr(s, addr, opc);
7818 t0 = tcg_temp_new_i32();
7819 t1 = load_reg(s, rt);
7820 if (size == 3) {
7821 TCGv_i64 o64 = tcg_temp_new_i64();
7822 TCGv_i64 n64 = tcg_temp_new_i64();
7824 t2 = load_reg(s, rt2);
7825 tcg_gen_concat_i32_i64(n64, t1, t2);
7826 tcg_temp_free_i32(t2);
7827 gen_aa32_frob64(s, n64);
7829 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7830 get_mem_index(s), opc);
7831 tcg_temp_free_i64(n64);
7833 gen_aa32_frob64(s, o64);
7834 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7835 tcg_gen_extrl_i64_i32(t0, o64);
7837 tcg_temp_free_i64(o64);
7838 } else {
7839 t2 = tcg_temp_new_i32();
7840 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7841 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7842 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7843 tcg_temp_free_i32(t2);
7845 tcg_temp_free_i32(t1);
7846 tcg_temp_free(taddr);
7847 tcg_gen_mov_i32(cpu_R[rd], t0);
7848 tcg_temp_free_i32(t0);
7849 tcg_gen_br(done_label);
7851 gen_set_label(fail_label);
7852 tcg_gen_movi_i32(cpu_R[rd], 1);
7853 gen_set_label(done_label);
7854 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7857 /* gen_srs:
7858 * @env: CPUARMState
7859 * @s: DisasContext
7860 * @mode: mode field from insn (which stack to store to)
7861 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7862 * @writeback: true if writeback bit set
7864 * Generate code for the SRS (Store Return State) insn.
7866 static void gen_srs(DisasContext *s,
7867 uint32_t mode, uint32_t amode, bool writeback)
7869 int32_t offset;
7870 TCGv_i32 addr, tmp;
7871 bool undef = false;
7873 /* SRS is:
7874 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7875 * and specified mode is monitor mode
7876 * - UNDEFINED in Hyp mode
7877 * - UNPREDICTABLE in User or System mode
7878 * - UNPREDICTABLE if the specified mode is:
7879 * -- not implemented
7880 * -- not a valid mode number
7881 * -- a mode that's at a higher exception level
7882 * -- Monitor, if we are Non-secure
7883 * For the UNPREDICTABLE cases we choose to UNDEF.
7885 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7886 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7887 return;
7890 if (s->current_el == 0 || s->current_el == 2) {
7891 undef = true;
7894 switch (mode) {
7895 case ARM_CPU_MODE_USR:
7896 case ARM_CPU_MODE_FIQ:
7897 case ARM_CPU_MODE_IRQ:
7898 case ARM_CPU_MODE_SVC:
7899 case ARM_CPU_MODE_ABT:
7900 case ARM_CPU_MODE_UND:
7901 case ARM_CPU_MODE_SYS:
7902 break;
7903 case ARM_CPU_MODE_HYP:
7904 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7905 undef = true;
7907 break;
7908 case ARM_CPU_MODE_MON:
7909 /* No need to check specifically for "are we non-secure" because
7910 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7911 * so if this isn't EL3 then we must be non-secure.
7913 if (s->current_el != 3) {
7914 undef = true;
7916 break;
7917 default:
7918 undef = true;
7921 if (undef) {
7922 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
7923 default_exception_el(s));
7924 return;
7927 addr = tcg_temp_new_i32();
7928 tmp = tcg_const_i32(mode);
7929 /* get_r13_banked() will raise an exception if called from System mode */
7930 gen_set_condexec(s);
7931 gen_set_pc_im(s, s->pc - 4);
7932 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7933 tcg_temp_free_i32(tmp);
7934 switch (amode) {
7935 case 0: /* DA */
7936 offset = -4;
7937 break;
7938 case 1: /* IA */
7939 offset = 0;
7940 break;
7941 case 2: /* DB */
7942 offset = -8;
7943 break;
7944 case 3: /* IB */
7945 offset = 4;
7946 break;
7947 default:
7948 abort();
7950 tcg_gen_addi_i32(addr, addr, offset);
7951 tmp = load_reg(s, 14);
7952 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7953 tcg_temp_free_i32(tmp);
7954 tmp = load_cpu_field(spsr);
7955 tcg_gen_addi_i32(addr, addr, 4);
7956 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7957 tcg_temp_free_i32(tmp);
7958 if (writeback) {
7959 switch (amode) {
7960 case 0:
7961 offset = -8;
7962 break;
7963 case 1:
7964 offset = 4;
7965 break;
7966 case 2:
7967 offset = -4;
7968 break;
7969 case 3:
7970 offset = 0;
7971 break;
7972 default:
7973 abort();
7975 tcg_gen_addi_i32(addr, addr, offset);
7976 tmp = tcg_const_i32(mode);
7977 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7978 tcg_temp_free_i32(tmp);
7980 tcg_temp_free_i32(addr);
7981 s->is_jmp = DISAS_UPDATE;
7984 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7986 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7987 TCGv_i32 tmp;
7988 TCGv_i32 tmp2;
7989 TCGv_i32 tmp3;
7990 TCGv_i32 addr;
7991 TCGv_i64 tmp64;
7993 /* M variants do not implement ARM mode; this must raise the INVSTATE
7994 * UsageFault exception.
7996 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7997 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
7998 default_exception_el(s));
7999 return;
8001 cond = insn >> 28;
8002 if (cond == 0xf){
8003 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8004 * choose to UNDEF. In ARMv5 and above the space is used
8005 * for miscellaneous unconditional instructions.
8007 ARCH(5);
8009 /* Unconditional instructions. */
8010 if (((insn >> 25) & 7) == 1) {
8011 /* NEON Data processing. */
8012 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8013 goto illegal_op;
8016 if (disas_neon_data_insn(s, insn)) {
8017 goto illegal_op;
8019 return;
8021 if ((insn & 0x0f100000) == 0x04000000) {
8022 /* NEON load/store. */
8023 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8024 goto illegal_op;
8027 if (disas_neon_ls_insn(s, insn)) {
8028 goto illegal_op;
8030 return;
8032 if ((insn & 0x0f000e10) == 0x0e000a00) {
8033 /* VFP. */
8034 if (disas_vfp_insn(s, insn)) {
8035 goto illegal_op;
8037 return;
8039 if (((insn & 0x0f30f000) == 0x0510f000) ||
8040 ((insn & 0x0f30f010) == 0x0710f000)) {
8041 if ((insn & (1 << 22)) == 0) {
8042 /* PLDW; v7MP */
8043 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8044 goto illegal_op;
8047 /* Otherwise PLD; v5TE+ */
8048 ARCH(5TE);
8049 return;
8051 if (((insn & 0x0f70f000) == 0x0450f000) ||
8052 ((insn & 0x0f70f010) == 0x0650f000)) {
8053 ARCH(7);
8054 return; /* PLI; V7 */
8056 if (((insn & 0x0f700000) == 0x04100000) ||
8057 ((insn & 0x0f700010) == 0x06100000)) {
8058 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8059 goto illegal_op;
8061 return; /* v7MP: Unallocated memory hint: must NOP */
8064 if ((insn & 0x0ffffdff) == 0x01010000) {
8065 ARCH(6);
8066 /* setend */
8067 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8068 gen_helper_setend(cpu_env);
8069 s->is_jmp = DISAS_UPDATE;
8071 return;
8072 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8073 switch ((insn >> 4) & 0xf) {
8074 case 1: /* clrex */
8075 ARCH(6K);
8076 gen_clrex(s);
8077 return;
8078 case 4: /* dsb */
8079 case 5: /* dmb */
8080 ARCH(7);
8081 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8082 return;
8083 case 6: /* isb */
8084 /* We need to break the TB after this insn to execute
8085 * self-modifying code correctly and also to take
8086 * any pending interrupts immediately.
8088 gen_lookup_tb(s);
8089 return;
8090 default:
8091 goto illegal_op;
8093 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8094 /* srs */
8095 ARCH(6);
8096 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8097 return;
8098 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8099 /* rfe */
8100 int32_t offset;
8101 if (IS_USER(s))
8102 goto illegal_op;
8103 ARCH(6);
8104 rn = (insn >> 16) & 0xf;
8105 addr = load_reg(s, rn);
8106 i = (insn >> 23) & 3;
8107 switch (i) {
8108 case 0: offset = -4; break; /* DA */
8109 case 1: offset = 0; break; /* IA */
8110 case 2: offset = -8; break; /* DB */
8111 case 3: offset = 4; break; /* IB */
8112 default: abort();
8114 if (offset)
8115 tcg_gen_addi_i32(addr, addr, offset);
8116 /* Load PC into tmp and CPSR into tmp2. */
8117 tmp = tcg_temp_new_i32();
8118 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8119 tcg_gen_addi_i32(addr, addr, 4);
8120 tmp2 = tcg_temp_new_i32();
8121 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8122 if (insn & (1 << 21)) {
8123 /* Base writeback. */
8124 switch (i) {
8125 case 0: offset = -8; break;
8126 case 1: offset = 4; break;
8127 case 2: offset = -4; break;
8128 case 3: offset = 0; break;
8129 default: abort();
8131 if (offset)
8132 tcg_gen_addi_i32(addr, addr, offset);
8133 store_reg(s, rn, addr);
8134 } else {
8135 tcg_temp_free_i32(addr);
8137 gen_rfe(s, tmp, tmp2);
8138 return;
8139 } else if ((insn & 0x0e000000) == 0x0a000000) {
8140 /* branch link and change to thumb (blx <offset>) */
8141 int32_t offset;
8143 val = (uint32_t)s->pc;
8144 tmp = tcg_temp_new_i32();
8145 tcg_gen_movi_i32(tmp, val);
8146 store_reg(s, 14, tmp);
8147 /* Sign-extend the 24-bit offset */
8148 offset = (((int32_t)insn) << 8) >> 8;
8149 /* offset * 4 + bit24 * 2 + (thumb bit) */
8150 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8151 /* pipeline offset */
8152 val += 4;
8153 /* protected by ARCH(5); above, near the start of uncond block */
8154 gen_bx_im(s, val);
8155 return;
8156 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8157 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8158 /* iWMMXt register transfer. */
8159 if (extract32(s->c15_cpar, 1, 1)) {
8160 if (!disas_iwmmxt_insn(s, insn)) {
8161 return;
8165 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8166 /* Coprocessor double register transfer. */
8167 ARCH(5TE);
8168 } else if ((insn & 0x0f000010) == 0x0e000010) {
8169 /* Additional coprocessor register transfer. */
8170 } else if ((insn & 0x0ff10020) == 0x01000000) {
8171 uint32_t mask;
8172 uint32_t val;
8173 /* cps (privileged) */
8174 if (IS_USER(s))
8175 return;
8176 mask = val = 0;
8177 if (insn & (1 << 19)) {
8178 if (insn & (1 << 8))
8179 mask |= CPSR_A;
8180 if (insn & (1 << 7))
8181 mask |= CPSR_I;
8182 if (insn & (1 << 6))
8183 mask |= CPSR_F;
8184 if (insn & (1 << 18))
8185 val |= mask;
8187 if (insn & (1 << 17)) {
8188 mask |= CPSR_M;
8189 val |= (insn & 0x1f);
8191 if (mask) {
8192 gen_set_psr_im(s, mask, 0, val);
8194 return;
8196 goto illegal_op;
8198 if (cond != 0xe) {
8199 /* if not always execute, we generate a conditional jump to
8200 next instruction */
8201 s->condlabel = gen_new_label();
8202 arm_gen_test_cc(cond ^ 1, s->condlabel);
8203 s->condjmp = 1;
8205 if ((insn & 0x0f900000) == 0x03000000) {
8206 if ((insn & (1 << 21)) == 0) {
8207 ARCH(6T2);
8208 rd = (insn >> 12) & 0xf;
8209 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8210 if ((insn & (1 << 22)) == 0) {
8211 /* MOVW */
8212 tmp = tcg_temp_new_i32();
8213 tcg_gen_movi_i32(tmp, val);
8214 } else {
8215 /* MOVT */
8216 tmp = load_reg(s, rd);
8217 tcg_gen_ext16u_i32(tmp, tmp);
8218 tcg_gen_ori_i32(tmp, tmp, val << 16);
8220 store_reg(s, rd, tmp);
8221 } else {
8222 if (((insn >> 12) & 0xf) != 0xf)
8223 goto illegal_op;
8224 if (((insn >> 16) & 0xf) == 0) {
8225 gen_nop_hint(s, insn & 0xff);
8226 } else {
8227 /* CPSR = immediate */
8228 val = insn & 0xff;
8229 shift = ((insn >> 8) & 0xf) * 2;
8230 if (shift)
8231 val = (val >> shift) | (val << (32 - shift));
8232 i = ((insn & (1 << 22)) != 0);
8233 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8234 i, val)) {
8235 goto illegal_op;
8239 } else if ((insn & 0x0f900000) == 0x01000000
8240 && (insn & 0x00000090) != 0x00000090) {
8241 /* miscellaneous instructions */
8242 op1 = (insn >> 21) & 3;
8243 sh = (insn >> 4) & 0xf;
8244 rm = insn & 0xf;
8245 switch (sh) {
8246 case 0x0: /* MSR, MRS */
8247 if (insn & (1 << 9)) {
8248 /* MSR (banked) and MRS (banked) */
8249 int sysm = extract32(insn, 16, 4) |
8250 (extract32(insn, 8, 1) << 4);
8251 int r = extract32(insn, 22, 1);
8253 if (op1 & 1) {
8254 /* MSR (banked) */
8255 gen_msr_banked(s, r, sysm, rm);
8256 } else {
8257 /* MRS (banked) */
8258 int rd = extract32(insn, 12, 4);
8260 gen_mrs_banked(s, r, sysm, rd);
8262 break;
8265 /* MSR, MRS (for PSRs) */
8266 if (op1 & 1) {
8267 /* PSR = reg */
8268 tmp = load_reg(s, rm);
8269 i = ((op1 & 2) != 0);
8270 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8271 goto illegal_op;
8272 } else {
8273 /* reg = PSR */
8274 rd = (insn >> 12) & 0xf;
8275 if (op1 & 2) {
8276 if (IS_USER(s))
8277 goto illegal_op;
8278 tmp = load_cpu_field(spsr);
8279 } else {
8280 tmp = tcg_temp_new_i32();
8281 gen_helper_cpsr_read(tmp, cpu_env);
8283 store_reg(s, rd, tmp);
8285 break;
8286 case 0x1:
8287 if (op1 == 1) {
8288 /* branch/exchange thumb (bx). */
8289 ARCH(4T);
8290 tmp = load_reg(s, rm);
8291 gen_bx(s, tmp);
8292 } else if (op1 == 3) {
8293 /* clz */
8294 ARCH(5);
8295 rd = (insn >> 12) & 0xf;
8296 tmp = load_reg(s, rm);
8297 tcg_gen_clzi_i32(tmp, tmp, 32);
8298 store_reg(s, rd, tmp);
8299 } else {
8300 goto illegal_op;
8302 break;
8303 case 0x2:
8304 if (op1 == 1) {
8305 ARCH(5J); /* bxj */
8306 /* Trivial implementation equivalent to bx. */
8307 tmp = load_reg(s, rm);
8308 gen_bx(s, tmp);
8309 } else {
8310 goto illegal_op;
8312 break;
8313 case 0x3:
8314 if (op1 != 1)
8315 goto illegal_op;
8317 ARCH(5);
8318 /* branch link/exchange thumb (blx) */
8319 tmp = load_reg(s, rm);
8320 tmp2 = tcg_temp_new_i32();
8321 tcg_gen_movi_i32(tmp2, s->pc);
8322 store_reg(s, 14, tmp2);
8323 gen_bx(s, tmp);
8324 break;
8325 case 0x4:
8327 /* crc32/crc32c */
8328 uint32_t c = extract32(insn, 8, 4);
8330 /* Check this CPU supports ARMv8 CRC instructions.
8331 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8332 * Bits 8, 10 and 11 should be zero.
8334 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8335 (c & 0xd) != 0) {
8336 goto illegal_op;
8339 rn = extract32(insn, 16, 4);
8340 rd = extract32(insn, 12, 4);
8342 tmp = load_reg(s, rn);
8343 tmp2 = load_reg(s, rm);
8344 if (op1 == 0) {
8345 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8346 } else if (op1 == 1) {
8347 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8349 tmp3 = tcg_const_i32(1 << op1);
8350 if (c & 0x2) {
8351 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8352 } else {
8353 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8355 tcg_temp_free_i32(tmp2);
8356 tcg_temp_free_i32(tmp3);
8357 store_reg(s, rd, tmp);
8358 break;
8360 case 0x5: /* saturating add/subtract */
8361 ARCH(5TE);
8362 rd = (insn >> 12) & 0xf;
8363 rn = (insn >> 16) & 0xf;
8364 tmp = load_reg(s, rm);
8365 tmp2 = load_reg(s, rn);
8366 if (op1 & 2)
8367 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8368 if (op1 & 1)
8369 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8370 else
8371 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8372 tcg_temp_free_i32(tmp2);
8373 store_reg(s, rd, tmp);
8374 break;
8375 case 7:
8377 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8378 switch (op1) {
8379 case 0:
8380 /* HLT */
8381 gen_hlt(s, imm16);
8382 break;
8383 case 1:
8384 /* bkpt */
8385 ARCH(5);
8386 gen_exception_insn(s, 4, EXCP_BKPT,
8387 syn_aa32_bkpt(imm16, false),
8388 default_exception_el(s));
8389 break;
8390 case 2:
8391 /* Hypervisor call (v7) */
8392 ARCH(7);
8393 if (IS_USER(s)) {
8394 goto illegal_op;
8396 gen_hvc(s, imm16);
8397 break;
8398 case 3:
8399 /* Secure monitor call (v6+) */
8400 ARCH(6K);
8401 if (IS_USER(s)) {
8402 goto illegal_op;
8404 gen_smc(s);
8405 break;
8406 default:
8407 g_assert_not_reached();
8409 break;
8411 case 0x8: /* signed multiply */
8412 case 0xa:
8413 case 0xc:
8414 case 0xe:
8415 ARCH(5TE);
8416 rs = (insn >> 8) & 0xf;
8417 rn = (insn >> 12) & 0xf;
8418 rd = (insn >> 16) & 0xf;
8419 if (op1 == 1) {
8420 /* (32 * 16) >> 16 */
8421 tmp = load_reg(s, rm);
8422 tmp2 = load_reg(s, rs);
8423 if (sh & 4)
8424 tcg_gen_sari_i32(tmp2, tmp2, 16);
8425 else
8426 gen_sxth(tmp2);
8427 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8428 tcg_gen_shri_i64(tmp64, tmp64, 16);
8429 tmp = tcg_temp_new_i32();
8430 tcg_gen_extrl_i64_i32(tmp, tmp64);
8431 tcg_temp_free_i64(tmp64);
8432 if ((sh & 2) == 0) {
8433 tmp2 = load_reg(s, rn);
8434 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8435 tcg_temp_free_i32(tmp2);
8437 store_reg(s, rd, tmp);
8438 } else {
8439 /* 16 * 16 */
8440 tmp = load_reg(s, rm);
8441 tmp2 = load_reg(s, rs);
8442 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8443 tcg_temp_free_i32(tmp2);
8444 if (op1 == 2) {
8445 tmp64 = tcg_temp_new_i64();
8446 tcg_gen_ext_i32_i64(tmp64, tmp);
8447 tcg_temp_free_i32(tmp);
8448 gen_addq(s, tmp64, rn, rd);
8449 gen_storeq_reg(s, rn, rd, tmp64);
8450 tcg_temp_free_i64(tmp64);
8451 } else {
8452 if (op1 == 0) {
8453 tmp2 = load_reg(s, rn);
8454 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8455 tcg_temp_free_i32(tmp2);
8457 store_reg(s, rd, tmp);
8460 break;
8461 default:
8462 goto illegal_op;
8464 } else if (((insn & 0x0e000000) == 0 &&
8465 (insn & 0x00000090) != 0x90) ||
8466 ((insn & 0x0e000000) == (1 << 25))) {
8467 int set_cc, logic_cc, shiftop;
8469 op1 = (insn >> 21) & 0xf;
8470 set_cc = (insn >> 20) & 1;
8471 logic_cc = table_logic_cc[op1] & set_cc;
8473 /* data processing instruction */
8474 if (insn & (1 << 25)) {
8475 /* immediate operand */
8476 val = insn & 0xff;
8477 shift = ((insn >> 8) & 0xf) * 2;
8478 if (shift) {
8479 val = (val >> shift) | (val << (32 - shift));
8481 tmp2 = tcg_temp_new_i32();
8482 tcg_gen_movi_i32(tmp2, val);
8483 if (logic_cc && shift) {
8484 gen_set_CF_bit31(tmp2);
8486 } else {
8487 /* register */
8488 rm = (insn) & 0xf;
8489 tmp2 = load_reg(s, rm);
8490 shiftop = (insn >> 5) & 3;
8491 if (!(insn & (1 << 4))) {
8492 shift = (insn >> 7) & 0x1f;
8493 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8494 } else {
8495 rs = (insn >> 8) & 0xf;
8496 tmp = load_reg(s, rs);
8497 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8500 if (op1 != 0x0f && op1 != 0x0d) {
8501 rn = (insn >> 16) & 0xf;
8502 tmp = load_reg(s, rn);
8503 } else {
8504 TCGV_UNUSED_I32(tmp);
8506 rd = (insn >> 12) & 0xf;
8507 switch(op1) {
8508 case 0x00:
8509 tcg_gen_and_i32(tmp, tmp, tmp2);
8510 if (logic_cc) {
8511 gen_logic_CC(tmp);
8513 store_reg_bx(s, rd, tmp);
8514 break;
8515 case 0x01:
8516 tcg_gen_xor_i32(tmp, tmp, tmp2);
8517 if (logic_cc) {
8518 gen_logic_CC(tmp);
8520 store_reg_bx(s, rd, tmp);
8521 break;
8522 case 0x02:
8523 if (set_cc && rd == 15) {
8524 /* SUBS r15, ... is used for exception return. */
8525 if (IS_USER(s)) {
8526 goto illegal_op;
8528 gen_sub_CC(tmp, tmp, tmp2);
8529 gen_exception_return(s, tmp);
8530 } else {
8531 if (set_cc) {
8532 gen_sub_CC(tmp, tmp, tmp2);
8533 } else {
8534 tcg_gen_sub_i32(tmp, tmp, tmp2);
8536 store_reg_bx(s, rd, tmp);
8538 break;
8539 case 0x03:
8540 if (set_cc) {
8541 gen_sub_CC(tmp, tmp2, tmp);
8542 } else {
8543 tcg_gen_sub_i32(tmp, tmp2, tmp);
8545 store_reg_bx(s, rd, tmp);
8546 break;
8547 case 0x04:
8548 if (set_cc) {
8549 gen_add_CC(tmp, tmp, tmp2);
8550 } else {
8551 tcg_gen_add_i32(tmp, tmp, tmp2);
8553 store_reg_bx(s, rd, tmp);
8554 break;
8555 case 0x05:
8556 if (set_cc) {
8557 gen_adc_CC(tmp, tmp, tmp2);
8558 } else {
8559 gen_add_carry(tmp, tmp, tmp2);
8561 store_reg_bx(s, rd, tmp);
8562 break;
8563 case 0x06:
8564 if (set_cc) {
8565 gen_sbc_CC(tmp, tmp, tmp2);
8566 } else {
8567 gen_sub_carry(tmp, tmp, tmp2);
8569 store_reg_bx(s, rd, tmp);
8570 break;
8571 case 0x07:
8572 if (set_cc) {
8573 gen_sbc_CC(tmp, tmp2, tmp);
8574 } else {
8575 gen_sub_carry(tmp, tmp2, tmp);
8577 store_reg_bx(s, rd, tmp);
8578 break;
8579 case 0x08:
8580 if (set_cc) {
8581 tcg_gen_and_i32(tmp, tmp, tmp2);
8582 gen_logic_CC(tmp);
8584 tcg_temp_free_i32(tmp);
8585 break;
8586 case 0x09:
8587 if (set_cc) {
8588 tcg_gen_xor_i32(tmp, tmp, tmp2);
8589 gen_logic_CC(tmp);
8591 tcg_temp_free_i32(tmp);
8592 break;
8593 case 0x0a:
8594 if (set_cc) {
8595 gen_sub_CC(tmp, tmp, tmp2);
8597 tcg_temp_free_i32(tmp);
8598 break;
8599 case 0x0b:
8600 if (set_cc) {
8601 gen_add_CC(tmp, tmp, tmp2);
8603 tcg_temp_free_i32(tmp);
8604 break;
8605 case 0x0c:
8606 tcg_gen_or_i32(tmp, tmp, tmp2);
8607 if (logic_cc) {
8608 gen_logic_CC(tmp);
8610 store_reg_bx(s, rd, tmp);
8611 break;
8612 case 0x0d:
8613 if (logic_cc && rd == 15) {
8614 /* MOVS r15, ... is used for exception return. */
8615 if (IS_USER(s)) {
8616 goto illegal_op;
8618 gen_exception_return(s, tmp2);
8619 } else {
8620 if (logic_cc) {
8621 gen_logic_CC(tmp2);
8623 store_reg_bx(s, rd, tmp2);
8625 break;
8626 case 0x0e:
8627 tcg_gen_andc_i32(tmp, tmp, tmp2);
8628 if (logic_cc) {
8629 gen_logic_CC(tmp);
8631 store_reg_bx(s, rd, tmp);
8632 break;
8633 default:
8634 case 0x0f:
8635 tcg_gen_not_i32(tmp2, tmp2);
8636 if (logic_cc) {
8637 gen_logic_CC(tmp2);
8639 store_reg_bx(s, rd, tmp2);
8640 break;
8642 if (op1 != 0x0f && op1 != 0x0d) {
8643 tcg_temp_free_i32(tmp2);
8645 } else {
8646 /* other instructions */
8647 op1 = (insn >> 24) & 0xf;
8648 switch(op1) {
8649 case 0x0:
8650 case 0x1:
8651 /* multiplies, extra load/stores */
8652 sh = (insn >> 5) & 3;
8653 if (sh == 0) {
8654 if (op1 == 0x0) {
8655 rd = (insn >> 16) & 0xf;
8656 rn = (insn >> 12) & 0xf;
8657 rs = (insn >> 8) & 0xf;
8658 rm = (insn) & 0xf;
8659 op1 = (insn >> 20) & 0xf;
8660 switch (op1) {
8661 case 0: case 1: case 2: case 3: case 6:
8662 /* 32 bit mul */
8663 tmp = load_reg(s, rs);
8664 tmp2 = load_reg(s, rm);
8665 tcg_gen_mul_i32(tmp, tmp, tmp2);
8666 tcg_temp_free_i32(tmp2);
8667 if (insn & (1 << 22)) {
8668 /* Subtract (mls) */
8669 ARCH(6T2);
8670 tmp2 = load_reg(s, rn);
8671 tcg_gen_sub_i32(tmp, tmp2, tmp);
8672 tcg_temp_free_i32(tmp2);
8673 } else if (insn & (1 << 21)) {
8674 /* Add */
8675 tmp2 = load_reg(s, rn);
8676 tcg_gen_add_i32(tmp, tmp, tmp2);
8677 tcg_temp_free_i32(tmp2);
8679 if (insn & (1 << 20))
8680 gen_logic_CC(tmp);
8681 store_reg(s, rd, tmp);
8682 break;
8683 case 4:
8684 /* 64 bit mul double accumulate (UMAAL) */
8685 ARCH(6);
8686 tmp = load_reg(s, rs);
8687 tmp2 = load_reg(s, rm);
8688 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8689 gen_addq_lo(s, tmp64, rn);
8690 gen_addq_lo(s, tmp64, rd);
8691 gen_storeq_reg(s, rn, rd, tmp64);
8692 tcg_temp_free_i64(tmp64);
8693 break;
8694 case 8: case 9: case 10: case 11:
8695 case 12: case 13: case 14: case 15:
8696 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8697 tmp = load_reg(s, rs);
8698 tmp2 = load_reg(s, rm);
8699 if (insn & (1 << 22)) {
8700 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8701 } else {
8702 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8704 if (insn & (1 << 21)) { /* mult accumulate */
8705 TCGv_i32 al = load_reg(s, rn);
8706 TCGv_i32 ah = load_reg(s, rd);
8707 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8708 tcg_temp_free_i32(al);
8709 tcg_temp_free_i32(ah);
8711 if (insn & (1 << 20)) {
8712 gen_logicq_cc(tmp, tmp2);
8714 store_reg(s, rn, tmp);
8715 store_reg(s, rd, tmp2);
8716 break;
8717 default:
8718 goto illegal_op;
8720 } else {
8721 rn = (insn >> 16) & 0xf;
8722 rd = (insn >> 12) & 0xf;
8723 if (insn & (1 << 23)) {
8724 /* load/store exclusive */
8725 int op2 = (insn >> 8) & 3;
8726 op1 = (insn >> 21) & 0x3;
8728 switch (op2) {
8729 case 0: /* lda/stl */
8730 if (op1 == 1) {
8731 goto illegal_op;
8733 ARCH(8);
8734 break;
8735 case 1: /* reserved */
8736 goto illegal_op;
8737 case 2: /* ldaex/stlex */
8738 ARCH(8);
8739 break;
8740 case 3: /* ldrex/strex */
8741 if (op1) {
8742 ARCH(6K);
8743 } else {
8744 ARCH(6);
8746 break;
8749 addr = tcg_temp_local_new_i32();
8750 load_reg_var(s, addr, rn);
8752 /* Since the emulation does not have barriers,
8753 the acquire/release semantics need no special
8754 handling */
8755 if (op2 == 0) {
8756 if (insn & (1 << 20)) {
8757 tmp = tcg_temp_new_i32();
8758 switch (op1) {
8759 case 0: /* lda */
8760 gen_aa32_ld32u_iss(s, tmp, addr,
8761 get_mem_index(s),
8762 rd | ISSIsAcqRel);
8763 break;
8764 case 2: /* ldab */
8765 gen_aa32_ld8u_iss(s, tmp, addr,
8766 get_mem_index(s),
8767 rd | ISSIsAcqRel);
8768 break;
8769 case 3: /* ldah */
8770 gen_aa32_ld16u_iss(s, tmp, addr,
8771 get_mem_index(s),
8772 rd | ISSIsAcqRel);
8773 break;
8774 default:
8775 abort();
8777 store_reg(s, rd, tmp);
8778 } else {
8779 rm = insn & 0xf;
8780 tmp = load_reg(s, rm);
8781 switch (op1) {
8782 case 0: /* stl */
8783 gen_aa32_st32_iss(s, tmp, addr,
8784 get_mem_index(s),
8785 rm | ISSIsAcqRel);
8786 break;
8787 case 2: /* stlb */
8788 gen_aa32_st8_iss(s, tmp, addr,
8789 get_mem_index(s),
8790 rm | ISSIsAcqRel);
8791 break;
8792 case 3: /* stlh */
8793 gen_aa32_st16_iss(s, tmp, addr,
8794 get_mem_index(s),
8795 rm | ISSIsAcqRel);
8796 break;
8797 default:
8798 abort();
8800 tcg_temp_free_i32(tmp);
8802 } else if (insn & (1 << 20)) {
8803 switch (op1) {
8804 case 0: /* ldrex */
8805 gen_load_exclusive(s, rd, 15, addr, 2);
8806 break;
8807 case 1: /* ldrexd */
8808 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8809 break;
8810 case 2: /* ldrexb */
8811 gen_load_exclusive(s, rd, 15, addr, 0);
8812 break;
8813 case 3: /* ldrexh */
8814 gen_load_exclusive(s, rd, 15, addr, 1);
8815 break;
8816 default:
8817 abort();
8819 } else {
8820 rm = insn & 0xf;
8821 switch (op1) {
8822 case 0: /* strex */
8823 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8824 break;
8825 case 1: /* strexd */
8826 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8827 break;
8828 case 2: /* strexb */
8829 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8830 break;
8831 case 3: /* strexh */
8832 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8833 break;
8834 default:
8835 abort();
8838 tcg_temp_free_i32(addr);
8839 } else {
8840 TCGv taddr;
8841 TCGMemOp opc = s->be_data;
8843 /* SWP instruction */
8844 rm = (insn) & 0xf;
8846 if (insn & (1 << 22)) {
8847 opc |= MO_UB;
8848 } else {
8849 opc |= MO_UL | MO_ALIGN;
8852 addr = load_reg(s, rn);
8853 taddr = gen_aa32_addr(s, addr, opc);
8854 tcg_temp_free_i32(addr);
8856 tmp = load_reg(s, rm);
8857 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8858 get_mem_index(s), opc);
8859 tcg_temp_free(taddr);
8860 store_reg(s, rd, tmp);
8863 } else {
8864 int address_offset;
8865 bool load = insn & (1 << 20);
8866 bool wbit = insn & (1 << 21);
8867 bool pbit = insn & (1 << 24);
8868 bool doubleword = false;
8869 ISSInfo issinfo;
8871 /* Misc load/store */
8872 rn = (insn >> 16) & 0xf;
8873 rd = (insn >> 12) & 0xf;
8875 /* ISS not valid if writeback */
8876 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8878 if (!load && (sh & 2)) {
8879 /* doubleword */
8880 ARCH(5TE);
8881 if (rd & 1) {
8882 /* UNPREDICTABLE; we choose to UNDEF */
8883 goto illegal_op;
8885 load = (sh & 1) == 0;
8886 doubleword = true;
8889 addr = load_reg(s, rn);
8890 if (pbit) {
8891 gen_add_datah_offset(s, insn, 0, addr);
8893 address_offset = 0;
8895 if (doubleword) {
8896 if (!load) {
8897 /* store */
8898 tmp = load_reg(s, rd);
8899 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8900 tcg_temp_free_i32(tmp);
8901 tcg_gen_addi_i32(addr, addr, 4);
8902 tmp = load_reg(s, rd + 1);
8903 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8904 tcg_temp_free_i32(tmp);
8905 } else {
8906 /* load */
8907 tmp = tcg_temp_new_i32();
8908 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8909 store_reg(s, rd, tmp);
8910 tcg_gen_addi_i32(addr, addr, 4);
8911 tmp = tcg_temp_new_i32();
8912 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8913 rd++;
8915 address_offset = -4;
8916 } else if (load) {
8917 /* load */
8918 tmp = tcg_temp_new_i32();
8919 switch (sh) {
8920 case 1:
8921 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8922 issinfo);
8923 break;
8924 case 2:
8925 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8926 issinfo);
8927 break;
8928 default:
8929 case 3:
8930 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8931 issinfo);
8932 break;
8934 } else {
8935 /* store */
8936 tmp = load_reg(s, rd);
8937 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8938 tcg_temp_free_i32(tmp);
8940 /* Perform base writeback before the loaded value to
8941 ensure correct behavior with overlapping index registers.
8942 ldrd with base writeback is undefined if the
8943 destination and index registers overlap. */
8944 if (!pbit) {
8945 gen_add_datah_offset(s, insn, address_offset, addr);
8946 store_reg(s, rn, addr);
8947 } else if (wbit) {
8948 if (address_offset)
8949 tcg_gen_addi_i32(addr, addr, address_offset);
8950 store_reg(s, rn, addr);
8951 } else {
8952 tcg_temp_free_i32(addr);
8954 if (load) {
8955 /* Complete the load. */
8956 store_reg(s, rd, tmp);
8959 break;
8960 case 0x4:
8961 case 0x5:
8962 goto do_ldst;
8963 case 0x6:
8964 case 0x7:
8965 if (insn & (1 << 4)) {
8966 ARCH(6);
8967 /* Armv6 Media instructions. */
8968 rm = insn & 0xf;
8969 rn = (insn >> 16) & 0xf;
8970 rd = (insn >> 12) & 0xf;
8971 rs = (insn >> 8) & 0xf;
8972 switch ((insn >> 23) & 3) {
8973 case 0: /* Parallel add/subtract. */
8974 op1 = (insn >> 20) & 7;
8975 tmp = load_reg(s, rn);
8976 tmp2 = load_reg(s, rm);
8977 sh = (insn >> 5) & 7;
8978 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8979 goto illegal_op;
8980 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8981 tcg_temp_free_i32(tmp2);
8982 store_reg(s, rd, tmp);
8983 break;
8984 case 1:
8985 if ((insn & 0x00700020) == 0) {
8986 /* Halfword pack. */
8987 tmp = load_reg(s, rn);
8988 tmp2 = load_reg(s, rm);
8989 shift = (insn >> 7) & 0x1f;
8990 if (insn & (1 << 6)) {
8991 /* pkhtb */
8992 if (shift == 0)
8993 shift = 31;
8994 tcg_gen_sari_i32(tmp2, tmp2, shift);
8995 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8996 tcg_gen_ext16u_i32(tmp2, tmp2);
8997 } else {
8998 /* pkhbt */
8999 if (shift)
9000 tcg_gen_shli_i32(tmp2, tmp2, shift);
9001 tcg_gen_ext16u_i32(tmp, tmp);
9002 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9004 tcg_gen_or_i32(tmp, tmp, tmp2);
9005 tcg_temp_free_i32(tmp2);
9006 store_reg(s, rd, tmp);
9007 } else if ((insn & 0x00200020) == 0x00200000) {
9008 /* [us]sat */
9009 tmp = load_reg(s, rm);
9010 shift = (insn >> 7) & 0x1f;
9011 if (insn & (1 << 6)) {
9012 if (shift == 0)
9013 shift = 31;
9014 tcg_gen_sari_i32(tmp, tmp, shift);
9015 } else {
9016 tcg_gen_shli_i32(tmp, tmp, shift);
9018 sh = (insn >> 16) & 0x1f;
9019 tmp2 = tcg_const_i32(sh);
9020 if (insn & (1 << 22))
9021 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9022 else
9023 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9024 tcg_temp_free_i32(tmp2);
9025 store_reg(s, rd, tmp);
9026 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9027 /* [us]sat16 */
9028 tmp = load_reg(s, rm);
9029 sh = (insn >> 16) & 0x1f;
9030 tmp2 = tcg_const_i32(sh);
9031 if (insn & (1 << 22))
9032 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9033 else
9034 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9035 tcg_temp_free_i32(tmp2);
9036 store_reg(s, rd, tmp);
9037 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9038 /* Select bytes. */
9039 tmp = load_reg(s, rn);
9040 tmp2 = load_reg(s, rm);
9041 tmp3 = tcg_temp_new_i32();
9042 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9043 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9044 tcg_temp_free_i32(tmp3);
9045 tcg_temp_free_i32(tmp2);
9046 store_reg(s, rd, tmp);
9047 } else if ((insn & 0x000003e0) == 0x00000060) {
9048 tmp = load_reg(s, rm);
9049 shift = (insn >> 10) & 3;
9050 /* ??? In many cases it's not necessary to do a
9051 rotate, a shift is sufficient. */
9052 if (shift != 0)
9053 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9054 op1 = (insn >> 20) & 7;
9055 switch (op1) {
9056 case 0: gen_sxtb16(tmp); break;
9057 case 2: gen_sxtb(tmp); break;
9058 case 3: gen_sxth(tmp); break;
9059 case 4: gen_uxtb16(tmp); break;
9060 case 6: gen_uxtb(tmp); break;
9061 case 7: gen_uxth(tmp); break;
9062 default: goto illegal_op;
9064 if (rn != 15) {
9065 tmp2 = load_reg(s, rn);
9066 if ((op1 & 3) == 0) {
9067 gen_add16(tmp, tmp2);
9068 } else {
9069 tcg_gen_add_i32(tmp, tmp, tmp2);
9070 tcg_temp_free_i32(tmp2);
9073 store_reg(s, rd, tmp);
9074 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9075 /* rev */
9076 tmp = load_reg(s, rm);
9077 if (insn & (1 << 22)) {
9078 if (insn & (1 << 7)) {
9079 gen_revsh(tmp);
9080 } else {
9081 ARCH(6T2);
9082 gen_helper_rbit(tmp, tmp);
9084 } else {
9085 if (insn & (1 << 7))
9086 gen_rev16(tmp);
9087 else
9088 tcg_gen_bswap32_i32(tmp, tmp);
9090 store_reg(s, rd, tmp);
9091 } else {
9092 goto illegal_op;
9094 break;
9095 case 2: /* Multiplies (Type 3). */
9096 switch ((insn >> 20) & 0x7) {
9097 case 5:
9098 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9099 /* op2 not 00x or 11x : UNDEF */
9100 goto illegal_op;
9102 /* Signed multiply most significant [accumulate].
9103 (SMMUL, SMMLA, SMMLS) */
9104 tmp = load_reg(s, rm);
9105 tmp2 = load_reg(s, rs);
9106 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9108 if (rd != 15) {
9109 tmp = load_reg(s, rd);
9110 if (insn & (1 << 6)) {
9111 tmp64 = gen_subq_msw(tmp64, tmp);
9112 } else {
9113 tmp64 = gen_addq_msw(tmp64, tmp);
9116 if (insn & (1 << 5)) {
9117 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9119 tcg_gen_shri_i64(tmp64, tmp64, 32);
9120 tmp = tcg_temp_new_i32();
9121 tcg_gen_extrl_i64_i32(tmp, tmp64);
9122 tcg_temp_free_i64(tmp64);
9123 store_reg(s, rn, tmp);
9124 break;
9125 case 0:
9126 case 4:
9127 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9128 if (insn & (1 << 7)) {
9129 goto illegal_op;
9131 tmp = load_reg(s, rm);
9132 tmp2 = load_reg(s, rs);
9133 if (insn & (1 << 5))
9134 gen_swap_half(tmp2);
9135 gen_smul_dual(tmp, tmp2);
9136 if (insn & (1 << 22)) {
9137 /* smlald, smlsld */
9138 TCGv_i64 tmp64_2;
9140 tmp64 = tcg_temp_new_i64();
9141 tmp64_2 = tcg_temp_new_i64();
9142 tcg_gen_ext_i32_i64(tmp64, tmp);
9143 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9144 tcg_temp_free_i32(tmp);
9145 tcg_temp_free_i32(tmp2);
9146 if (insn & (1 << 6)) {
9147 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9148 } else {
9149 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9151 tcg_temp_free_i64(tmp64_2);
9152 gen_addq(s, tmp64, rd, rn);
9153 gen_storeq_reg(s, rd, rn, tmp64);
9154 tcg_temp_free_i64(tmp64);
9155 } else {
9156 /* smuad, smusd, smlad, smlsd */
9157 if (insn & (1 << 6)) {
9158 /* This subtraction cannot overflow. */
9159 tcg_gen_sub_i32(tmp, tmp, tmp2);
9160 } else {
9161 /* This addition cannot overflow 32 bits;
9162 * however it may overflow considered as a
9163 * signed operation, in which case we must set
9164 * the Q flag.
9166 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9168 tcg_temp_free_i32(tmp2);
9169 if (rd != 15)
9171 tmp2 = load_reg(s, rd);
9172 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9173 tcg_temp_free_i32(tmp2);
9175 store_reg(s, rn, tmp);
9177 break;
9178 case 1:
9179 case 3:
9180 /* SDIV, UDIV */
9181 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9182 goto illegal_op;
9184 if (((insn >> 5) & 7) || (rd != 15)) {
9185 goto illegal_op;
9187 tmp = load_reg(s, rm);
9188 tmp2 = load_reg(s, rs);
9189 if (insn & (1 << 21)) {
9190 gen_helper_udiv(tmp, tmp, tmp2);
9191 } else {
9192 gen_helper_sdiv(tmp, tmp, tmp2);
9194 tcg_temp_free_i32(tmp2);
9195 store_reg(s, rn, tmp);
9196 break;
9197 default:
9198 goto illegal_op;
9200 break;
9201 case 3:
9202 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9203 switch (op1) {
9204 case 0: /* Unsigned sum of absolute differences. */
9205 ARCH(6);
9206 tmp = load_reg(s, rm);
9207 tmp2 = load_reg(s, rs);
9208 gen_helper_usad8(tmp, tmp, tmp2);
9209 tcg_temp_free_i32(tmp2);
9210 if (rd != 15) {
9211 tmp2 = load_reg(s, rd);
9212 tcg_gen_add_i32(tmp, tmp, tmp2);
9213 tcg_temp_free_i32(tmp2);
9215 store_reg(s, rn, tmp);
9216 break;
9217 case 0x20: case 0x24: case 0x28: case 0x2c:
9218 /* Bitfield insert/clear. */
9219 ARCH(6T2);
9220 shift = (insn >> 7) & 0x1f;
9221 i = (insn >> 16) & 0x1f;
9222 if (i < shift) {
9223 /* UNPREDICTABLE; we choose to UNDEF */
9224 goto illegal_op;
9226 i = i + 1 - shift;
9227 if (rm == 15) {
9228 tmp = tcg_temp_new_i32();
9229 tcg_gen_movi_i32(tmp, 0);
9230 } else {
9231 tmp = load_reg(s, rm);
9233 if (i != 32) {
9234 tmp2 = load_reg(s, rd);
9235 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9236 tcg_temp_free_i32(tmp2);
9238 store_reg(s, rd, tmp);
9239 break;
9240 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9241 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9242 ARCH(6T2);
9243 tmp = load_reg(s, rm);
9244 shift = (insn >> 7) & 0x1f;
9245 i = ((insn >> 16) & 0x1f) + 1;
9246 if (shift + i > 32)
9247 goto illegal_op;
9248 if (i < 32) {
9249 if (op1 & 0x20) {
9250 tcg_gen_extract_i32(tmp, tmp, shift, i);
9251 } else {
9252 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9255 store_reg(s, rd, tmp);
9256 break;
9257 default:
9258 goto illegal_op;
9260 break;
9262 break;
9264 do_ldst:
9265 /* Check for undefined extension instructions
9266 * per the ARM Bible IE:
9267 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9269 sh = (0xf << 20) | (0xf << 4);
9270 if (op1 == 0x7 && ((insn & sh) == sh))
9272 goto illegal_op;
9274 /* load/store byte/word */
9275 rn = (insn >> 16) & 0xf;
9276 rd = (insn >> 12) & 0xf;
9277 tmp2 = load_reg(s, rn);
9278 if ((insn & 0x01200000) == 0x00200000) {
9279 /* ldrt/strt */
9280 i = get_a32_user_mem_index(s);
9281 } else {
9282 i = get_mem_index(s);
9284 if (insn & (1 << 24))
9285 gen_add_data_offset(s, insn, tmp2);
9286 if (insn & (1 << 20)) {
9287 /* load */
9288 tmp = tcg_temp_new_i32();
9289 if (insn & (1 << 22)) {
9290 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9291 } else {
9292 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9294 } else {
9295 /* store */
9296 tmp = load_reg(s, rd);
9297 if (insn & (1 << 22)) {
9298 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9299 } else {
9300 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9302 tcg_temp_free_i32(tmp);
9304 if (!(insn & (1 << 24))) {
9305 gen_add_data_offset(s, insn, tmp2);
9306 store_reg(s, rn, tmp2);
9307 } else if (insn & (1 << 21)) {
9308 store_reg(s, rn, tmp2);
9309 } else {
9310 tcg_temp_free_i32(tmp2);
9312 if (insn & (1 << 20)) {
9313 /* Complete the load. */
9314 store_reg_from_load(s, rd, tmp);
9316 break;
9317 case 0x08:
9318 case 0x09:
9320 int j, n, loaded_base;
9321 bool exc_return = false;
9322 bool is_load = extract32(insn, 20, 1);
9323 bool user = false;
9324 TCGv_i32 loaded_var;
9325 /* load/store multiple words */
9326 /* XXX: store correct base if write back */
9327 if (insn & (1 << 22)) {
9328 /* LDM (user), LDM (exception return) and STM (user) */
9329 if (IS_USER(s))
9330 goto illegal_op; /* only usable in supervisor mode */
9332 if (is_load && extract32(insn, 15, 1)) {
9333 exc_return = true;
9334 } else {
9335 user = true;
9338 rn = (insn >> 16) & 0xf;
9339 addr = load_reg(s, rn);
9341 /* compute total size */
9342 loaded_base = 0;
9343 TCGV_UNUSED_I32(loaded_var);
9344 n = 0;
9345 for(i=0;i<16;i++) {
9346 if (insn & (1 << i))
9347 n++;
9349 /* XXX: test invalid n == 0 case ? */
9350 if (insn & (1 << 23)) {
9351 if (insn & (1 << 24)) {
9352 /* pre increment */
9353 tcg_gen_addi_i32(addr, addr, 4);
9354 } else {
9355 /* post increment */
9357 } else {
9358 if (insn & (1 << 24)) {
9359 /* pre decrement */
9360 tcg_gen_addi_i32(addr, addr, -(n * 4));
9361 } else {
9362 /* post decrement */
9363 if (n != 1)
9364 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9367 j = 0;
9368 for(i=0;i<16;i++) {
9369 if (insn & (1 << i)) {
9370 if (is_load) {
9371 /* load */
9372 tmp = tcg_temp_new_i32();
9373 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9374 if (user) {
9375 tmp2 = tcg_const_i32(i);
9376 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9377 tcg_temp_free_i32(tmp2);
9378 tcg_temp_free_i32(tmp);
9379 } else if (i == rn) {
9380 loaded_var = tmp;
9381 loaded_base = 1;
9382 } else if (rn == 15 && exc_return) {
9383 store_pc_exc_ret(s, tmp);
9384 } else {
9385 store_reg_from_load(s, i, tmp);
9387 } else {
9388 /* store */
9389 if (i == 15) {
9390 /* special case: r15 = PC + 8 */
9391 val = (long)s->pc + 4;
9392 tmp = tcg_temp_new_i32();
9393 tcg_gen_movi_i32(tmp, val);
9394 } else if (user) {
9395 tmp = tcg_temp_new_i32();
9396 tmp2 = tcg_const_i32(i);
9397 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9398 tcg_temp_free_i32(tmp2);
9399 } else {
9400 tmp = load_reg(s, i);
9402 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9403 tcg_temp_free_i32(tmp);
9405 j++;
9406 /* no need to add after the last transfer */
9407 if (j != n)
9408 tcg_gen_addi_i32(addr, addr, 4);
9411 if (insn & (1 << 21)) {
9412 /* write back */
9413 if (insn & (1 << 23)) {
9414 if (insn & (1 << 24)) {
9415 /* pre increment */
9416 } else {
9417 /* post increment */
9418 tcg_gen_addi_i32(addr, addr, 4);
9420 } else {
9421 if (insn & (1 << 24)) {
9422 /* pre decrement */
9423 if (n != 1)
9424 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9425 } else {
9426 /* post decrement */
9427 tcg_gen_addi_i32(addr, addr, -(n * 4));
9430 store_reg(s, rn, addr);
9431 } else {
9432 tcg_temp_free_i32(addr);
9434 if (loaded_base) {
9435 store_reg(s, rn, loaded_var);
9437 if (exc_return) {
9438 /* Restore CPSR from SPSR. */
9439 tmp = load_cpu_field(spsr);
9440 gen_helper_cpsr_write_eret(cpu_env, tmp);
9441 tcg_temp_free_i32(tmp);
9442 s->is_jmp = DISAS_JUMP;
9445 break;
9446 case 0xa:
9447 case 0xb:
9449 int32_t offset;
9451 /* branch (and link) */
9452 val = (int32_t)s->pc;
9453 if (insn & (1 << 24)) {
9454 tmp = tcg_temp_new_i32();
9455 tcg_gen_movi_i32(tmp, val);
9456 store_reg(s, 14, tmp);
9458 offset = sextract32(insn << 2, 0, 26);
9459 val += offset + 4;
9460 gen_jmp(s, val);
9462 break;
9463 case 0xc:
9464 case 0xd:
9465 case 0xe:
9466 if (((insn >> 8) & 0xe) == 10) {
9467 /* VFP. */
9468 if (disas_vfp_insn(s, insn)) {
9469 goto illegal_op;
9471 } else if (disas_coproc_insn(s, insn)) {
9472 /* Coprocessor. */
9473 goto illegal_op;
9475 break;
9476 case 0xf:
9477 /* swi */
9478 gen_set_pc_im(s, s->pc);
9479 s->svc_imm = extract32(insn, 0, 24);
9480 s->is_jmp = DISAS_SWI;
9481 break;
9482 default:
9483 illegal_op:
9484 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9485 default_exception_el(s));
9486 break;
9491 /* Return true if this is a Thumb-2 logical op. */
9492 static int
9493 thumb2_logic_op(int op)
9495 return (op < 8);
9498 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9499 then set condition code flags based on the result of the operation.
9500 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9501 to the high bit of T1.
9502 Returns zero if the opcode is valid. */
9504 static int
9505 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9506 TCGv_i32 t0, TCGv_i32 t1)
9508 int logic_cc;
9510 logic_cc = 0;
9511 switch (op) {
9512 case 0: /* and */
9513 tcg_gen_and_i32(t0, t0, t1);
9514 logic_cc = conds;
9515 break;
9516 case 1: /* bic */
9517 tcg_gen_andc_i32(t0, t0, t1);
9518 logic_cc = conds;
9519 break;
9520 case 2: /* orr */
9521 tcg_gen_or_i32(t0, t0, t1);
9522 logic_cc = conds;
9523 break;
9524 case 3: /* orn */
9525 tcg_gen_orc_i32(t0, t0, t1);
9526 logic_cc = conds;
9527 break;
9528 case 4: /* eor */
9529 tcg_gen_xor_i32(t0, t0, t1);
9530 logic_cc = conds;
9531 break;
9532 case 8: /* add */
9533 if (conds)
9534 gen_add_CC(t0, t0, t1);
9535 else
9536 tcg_gen_add_i32(t0, t0, t1);
9537 break;
9538 case 10: /* adc */
9539 if (conds)
9540 gen_adc_CC(t0, t0, t1);
9541 else
9542 gen_adc(t0, t1);
9543 break;
9544 case 11: /* sbc */
9545 if (conds) {
9546 gen_sbc_CC(t0, t0, t1);
9547 } else {
9548 gen_sub_carry(t0, t0, t1);
9550 break;
9551 case 13: /* sub */
9552 if (conds)
9553 gen_sub_CC(t0, t0, t1);
9554 else
9555 tcg_gen_sub_i32(t0, t0, t1);
9556 break;
9557 case 14: /* rsb */
9558 if (conds)
9559 gen_sub_CC(t0, t1, t0);
9560 else
9561 tcg_gen_sub_i32(t0, t1, t0);
9562 break;
9563 default: /* 5, 6, 7, 9, 12, 15. */
9564 return 1;
9566 if (logic_cc) {
9567 gen_logic_CC(t0);
9568 if (shifter_out)
9569 gen_set_CF_bit31(t1);
9571 return 0;
9574 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9575 is not legal. */
9576 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9578 uint32_t insn, imm, shift, offset;
9579 uint32_t rd, rn, rm, rs;
9580 TCGv_i32 tmp;
9581 TCGv_i32 tmp2;
9582 TCGv_i32 tmp3;
9583 TCGv_i32 addr;
9584 TCGv_i64 tmp64;
9585 int op;
9586 int shiftop;
9587 int conds;
9588 int logic_cc;
9590 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9591 || arm_dc_feature(s, ARM_FEATURE_M))) {
9592 /* Thumb-1 cores may need to treat bl and blx as a pair of
9593 16-bit instructions to get correct prefetch abort behavior. */
9594 insn = insn_hw1;
9595 if ((insn & (1 << 12)) == 0) {
9596 ARCH(5);
9597 /* Second half of blx. */
9598 offset = ((insn & 0x7ff) << 1);
9599 tmp = load_reg(s, 14);
9600 tcg_gen_addi_i32(tmp, tmp, offset);
9601 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9603 tmp2 = tcg_temp_new_i32();
9604 tcg_gen_movi_i32(tmp2, s->pc | 1);
9605 store_reg(s, 14, tmp2);
9606 gen_bx(s, tmp);
9607 return 0;
9609 if (insn & (1 << 11)) {
9610 /* Second half of bl. */
9611 offset = ((insn & 0x7ff) << 1) | 1;
9612 tmp = load_reg(s, 14);
9613 tcg_gen_addi_i32(tmp, tmp, offset);
9615 tmp2 = tcg_temp_new_i32();
9616 tcg_gen_movi_i32(tmp2, s->pc | 1);
9617 store_reg(s, 14, tmp2);
9618 gen_bx(s, tmp);
9619 return 0;
9621 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9622 /* Instruction spans a page boundary. Implement it as two
9623 16-bit instructions in case the second half causes an
9624 prefetch abort. */
9625 offset = ((int32_t)insn << 21) >> 9;
9626 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9627 return 0;
9629 /* Fall through to 32-bit decode. */
9632 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9633 s->pc += 2;
9634 insn |= (uint32_t)insn_hw1 << 16;
9636 if ((insn & 0xf800e800) != 0xf000e800) {
9637 ARCH(6T2);
9640 rn = (insn >> 16) & 0xf;
9641 rs = (insn >> 12) & 0xf;
9642 rd = (insn >> 8) & 0xf;
9643 rm = insn & 0xf;
9644 switch ((insn >> 25) & 0xf) {
9645 case 0: case 1: case 2: case 3:
9646 /* 16-bit instructions. Should never happen. */
9647 abort();
9648 case 4:
9649 if (insn & (1 << 22)) {
9650 /* Other load/store, table branch. */
9651 if (insn & 0x01200000) {
9652 /* Load/store doubleword. */
9653 if (rn == 15) {
9654 addr = tcg_temp_new_i32();
9655 tcg_gen_movi_i32(addr, s->pc & ~3);
9656 } else {
9657 addr = load_reg(s, rn);
9659 offset = (insn & 0xff) * 4;
9660 if ((insn & (1 << 23)) == 0)
9661 offset = -offset;
9662 if (insn & (1 << 24)) {
9663 tcg_gen_addi_i32(addr, addr, offset);
9664 offset = 0;
9666 if (insn & (1 << 20)) {
9667 /* ldrd */
9668 tmp = tcg_temp_new_i32();
9669 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9670 store_reg(s, rs, tmp);
9671 tcg_gen_addi_i32(addr, addr, 4);
9672 tmp = tcg_temp_new_i32();
9673 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9674 store_reg(s, rd, tmp);
9675 } else {
9676 /* strd */
9677 tmp = load_reg(s, rs);
9678 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9679 tcg_temp_free_i32(tmp);
9680 tcg_gen_addi_i32(addr, addr, 4);
9681 tmp = load_reg(s, rd);
9682 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9683 tcg_temp_free_i32(tmp);
9685 if (insn & (1 << 21)) {
9686 /* Base writeback. */
9687 if (rn == 15)
9688 goto illegal_op;
9689 tcg_gen_addi_i32(addr, addr, offset - 4);
9690 store_reg(s, rn, addr);
9691 } else {
9692 tcg_temp_free_i32(addr);
9694 } else if ((insn & (1 << 23)) == 0) {
9695 /* Load/store exclusive word. */
9696 addr = tcg_temp_local_new_i32();
9697 load_reg_var(s, addr, rn);
9698 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9699 if (insn & (1 << 20)) {
9700 gen_load_exclusive(s, rs, 15, addr, 2);
9701 } else {
9702 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9704 tcg_temp_free_i32(addr);
9705 } else if ((insn & (7 << 5)) == 0) {
9706 /* Table Branch. */
9707 if (rn == 15) {
9708 addr = tcg_temp_new_i32();
9709 tcg_gen_movi_i32(addr, s->pc);
9710 } else {
9711 addr = load_reg(s, rn);
9713 tmp = load_reg(s, rm);
9714 tcg_gen_add_i32(addr, addr, tmp);
9715 if (insn & (1 << 4)) {
9716 /* tbh */
9717 tcg_gen_add_i32(addr, addr, tmp);
9718 tcg_temp_free_i32(tmp);
9719 tmp = tcg_temp_new_i32();
9720 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9721 } else { /* tbb */
9722 tcg_temp_free_i32(tmp);
9723 tmp = tcg_temp_new_i32();
9724 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9726 tcg_temp_free_i32(addr);
9727 tcg_gen_shli_i32(tmp, tmp, 1);
9728 tcg_gen_addi_i32(tmp, tmp, s->pc);
9729 store_reg(s, 15, tmp);
9730 } else {
9731 int op2 = (insn >> 6) & 0x3;
9732 op = (insn >> 4) & 0x3;
9733 switch (op2) {
9734 case 0:
9735 goto illegal_op;
9736 case 1:
9737 /* Load/store exclusive byte/halfword/doubleword */
9738 if (op == 2) {
9739 goto illegal_op;
9741 ARCH(7);
9742 break;
9743 case 2:
9744 /* Load-acquire/store-release */
9745 if (op == 3) {
9746 goto illegal_op;
9748 /* Fall through */
9749 case 3:
9750 /* Load-acquire/store-release exclusive */
9751 ARCH(8);
9752 break;
9754 addr = tcg_temp_local_new_i32();
9755 load_reg_var(s, addr, rn);
9756 if (!(op2 & 1)) {
9757 if (insn & (1 << 20)) {
9758 tmp = tcg_temp_new_i32();
9759 switch (op) {
9760 case 0: /* ldab */
9761 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9762 rs | ISSIsAcqRel);
9763 break;
9764 case 1: /* ldah */
9765 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9766 rs | ISSIsAcqRel);
9767 break;
9768 case 2: /* lda */
9769 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9770 rs | ISSIsAcqRel);
9771 break;
9772 default:
9773 abort();
9775 store_reg(s, rs, tmp);
9776 } else {
9777 tmp = load_reg(s, rs);
9778 switch (op) {
9779 case 0: /* stlb */
9780 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9781 rs | ISSIsAcqRel);
9782 break;
9783 case 1: /* stlh */
9784 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9785 rs | ISSIsAcqRel);
9786 break;
9787 case 2: /* stl */
9788 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9789 rs | ISSIsAcqRel);
9790 break;
9791 default:
9792 abort();
9794 tcg_temp_free_i32(tmp);
9796 } else if (insn & (1 << 20)) {
9797 gen_load_exclusive(s, rs, rd, addr, op);
9798 } else {
9799 gen_store_exclusive(s, rm, rs, rd, addr, op);
9801 tcg_temp_free_i32(addr);
9803 } else {
9804 /* Load/store multiple, RFE, SRS. */
9805 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9806 /* RFE, SRS: not available in user mode or on M profile */
9807 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9808 goto illegal_op;
9810 if (insn & (1 << 20)) {
9811 /* rfe */
9812 addr = load_reg(s, rn);
9813 if ((insn & (1 << 24)) == 0)
9814 tcg_gen_addi_i32(addr, addr, -8);
9815 /* Load PC into tmp and CPSR into tmp2. */
9816 tmp = tcg_temp_new_i32();
9817 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9818 tcg_gen_addi_i32(addr, addr, 4);
9819 tmp2 = tcg_temp_new_i32();
9820 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9821 if (insn & (1 << 21)) {
9822 /* Base writeback. */
9823 if (insn & (1 << 24)) {
9824 tcg_gen_addi_i32(addr, addr, 4);
9825 } else {
9826 tcg_gen_addi_i32(addr, addr, -4);
9828 store_reg(s, rn, addr);
9829 } else {
9830 tcg_temp_free_i32(addr);
9832 gen_rfe(s, tmp, tmp2);
9833 } else {
9834 /* srs */
9835 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9836 insn & (1 << 21));
9838 } else {
9839 int i, loaded_base = 0;
9840 TCGv_i32 loaded_var;
9841 /* Load/store multiple. */
9842 addr = load_reg(s, rn);
9843 offset = 0;
9844 for (i = 0; i < 16; i++) {
9845 if (insn & (1 << i))
9846 offset += 4;
9848 if (insn & (1 << 24)) {
9849 tcg_gen_addi_i32(addr, addr, -offset);
9852 TCGV_UNUSED_I32(loaded_var);
9853 for (i = 0; i < 16; i++) {
9854 if ((insn & (1 << i)) == 0)
9855 continue;
9856 if (insn & (1 << 20)) {
9857 /* Load. */
9858 tmp = tcg_temp_new_i32();
9859 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9860 if (i == 15) {
9861 gen_bx(s, tmp);
9862 } else if (i == rn) {
9863 loaded_var = tmp;
9864 loaded_base = 1;
9865 } else {
9866 store_reg(s, i, tmp);
9868 } else {
9869 /* Store. */
9870 tmp = load_reg(s, i);
9871 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9872 tcg_temp_free_i32(tmp);
9874 tcg_gen_addi_i32(addr, addr, 4);
9876 if (loaded_base) {
9877 store_reg(s, rn, loaded_var);
9879 if (insn & (1 << 21)) {
9880 /* Base register writeback. */
9881 if (insn & (1 << 24)) {
9882 tcg_gen_addi_i32(addr, addr, -offset);
9884 /* Fault if writeback register is in register list. */
9885 if (insn & (1 << rn))
9886 goto illegal_op;
9887 store_reg(s, rn, addr);
9888 } else {
9889 tcg_temp_free_i32(addr);
9893 break;
9894 case 5:
9896 op = (insn >> 21) & 0xf;
9897 if (op == 6) {
9898 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9899 goto illegal_op;
9901 /* Halfword pack. */
9902 tmp = load_reg(s, rn);
9903 tmp2 = load_reg(s, rm);
9904 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9905 if (insn & (1 << 5)) {
9906 /* pkhtb */
9907 if (shift == 0)
9908 shift = 31;
9909 tcg_gen_sari_i32(tmp2, tmp2, shift);
9910 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9911 tcg_gen_ext16u_i32(tmp2, tmp2);
9912 } else {
9913 /* pkhbt */
9914 if (shift)
9915 tcg_gen_shli_i32(tmp2, tmp2, shift);
9916 tcg_gen_ext16u_i32(tmp, tmp);
9917 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9919 tcg_gen_or_i32(tmp, tmp, tmp2);
9920 tcg_temp_free_i32(tmp2);
9921 store_reg(s, rd, tmp);
9922 } else {
9923 /* Data processing register constant shift. */
9924 if (rn == 15) {
9925 tmp = tcg_temp_new_i32();
9926 tcg_gen_movi_i32(tmp, 0);
9927 } else {
9928 tmp = load_reg(s, rn);
9930 tmp2 = load_reg(s, rm);
9932 shiftop = (insn >> 4) & 3;
9933 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9934 conds = (insn & (1 << 20)) != 0;
9935 logic_cc = (conds && thumb2_logic_op(op));
9936 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9937 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9938 goto illegal_op;
9939 tcg_temp_free_i32(tmp2);
9940 if (rd != 15) {
9941 store_reg(s, rd, tmp);
9942 } else {
9943 tcg_temp_free_i32(tmp);
9946 break;
9947 case 13: /* Misc data processing. */
9948 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9949 if (op < 4 && (insn & 0xf000) != 0xf000)
9950 goto illegal_op;
9951 switch (op) {
9952 case 0: /* Register controlled shift. */
9953 tmp = load_reg(s, rn);
9954 tmp2 = load_reg(s, rm);
9955 if ((insn & 0x70) != 0)
9956 goto illegal_op;
9957 op = (insn >> 21) & 3;
9958 logic_cc = (insn & (1 << 20)) != 0;
9959 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9960 if (logic_cc)
9961 gen_logic_CC(tmp);
9962 store_reg_bx(s, rd, tmp);
9963 break;
9964 case 1: /* Sign/zero extend. */
9965 op = (insn >> 20) & 7;
9966 switch (op) {
9967 case 0: /* SXTAH, SXTH */
9968 case 1: /* UXTAH, UXTH */
9969 case 4: /* SXTAB, SXTB */
9970 case 5: /* UXTAB, UXTB */
9971 break;
9972 case 2: /* SXTAB16, SXTB16 */
9973 case 3: /* UXTAB16, UXTB16 */
9974 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9975 goto illegal_op;
9977 break;
9978 default:
9979 goto illegal_op;
9981 if (rn != 15) {
9982 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9983 goto illegal_op;
9986 tmp = load_reg(s, rm);
9987 shift = (insn >> 4) & 3;
9988 /* ??? In many cases it's not necessary to do a
9989 rotate, a shift is sufficient. */
9990 if (shift != 0)
9991 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9992 op = (insn >> 20) & 7;
9993 switch (op) {
9994 case 0: gen_sxth(tmp); break;
9995 case 1: gen_uxth(tmp); break;
9996 case 2: gen_sxtb16(tmp); break;
9997 case 3: gen_uxtb16(tmp); break;
9998 case 4: gen_sxtb(tmp); break;
9999 case 5: gen_uxtb(tmp); break;
10000 default:
10001 g_assert_not_reached();
10003 if (rn != 15) {
10004 tmp2 = load_reg(s, rn);
10005 if ((op >> 1) == 1) {
10006 gen_add16(tmp, tmp2);
10007 } else {
10008 tcg_gen_add_i32(tmp, tmp, tmp2);
10009 tcg_temp_free_i32(tmp2);
10012 store_reg(s, rd, tmp);
10013 break;
10014 case 2: /* SIMD add/subtract. */
10015 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10016 goto illegal_op;
10018 op = (insn >> 20) & 7;
10019 shift = (insn >> 4) & 7;
10020 if ((op & 3) == 3 || (shift & 3) == 3)
10021 goto illegal_op;
10022 tmp = load_reg(s, rn);
10023 tmp2 = load_reg(s, rm);
10024 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10025 tcg_temp_free_i32(tmp2);
10026 store_reg(s, rd, tmp);
10027 break;
10028 case 3: /* Other data processing. */
10029 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10030 if (op < 4) {
10031 /* Saturating add/subtract. */
10032 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10033 goto illegal_op;
10035 tmp = load_reg(s, rn);
10036 tmp2 = load_reg(s, rm);
10037 if (op & 1)
10038 gen_helper_double_saturate(tmp, cpu_env, tmp);
10039 if (op & 2)
10040 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10041 else
10042 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10043 tcg_temp_free_i32(tmp2);
10044 } else {
10045 switch (op) {
10046 case 0x0a: /* rbit */
10047 case 0x08: /* rev */
10048 case 0x09: /* rev16 */
10049 case 0x0b: /* revsh */
10050 case 0x18: /* clz */
10051 break;
10052 case 0x10: /* sel */
10053 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10054 goto illegal_op;
10056 break;
10057 case 0x20: /* crc32/crc32c */
10058 case 0x21:
10059 case 0x22:
10060 case 0x28:
10061 case 0x29:
10062 case 0x2a:
10063 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10064 goto illegal_op;
10066 break;
10067 default:
10068 goto illegal_op;
10070 tmp = load_reg(s, rn);
10071 switch (op) {
10072 case 0x0a: /* rbit */
10073 gen_helper_rbit(tmp, tmp);
10074 break;
10075 case 0x08: /* rev */
10076 tcg_gen_bswap32_i32(tmp, tmp);
10077 break;
10078 case 0x09: /* rev16 */
10079 gen_rev16(tmp);
10080 break;
10081 case 0x0b: /* revsh */
10082 gen_revsh(tmp);
10083 break;
10084 case 0x10: /* sel */
10085 tmp2 = load_reg(s, rm);
10086 tmp3 = tcg_temp_new_i32();
10087 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10088 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10089 tcg_temp_free_i32(tmp3);
10090 tcg_temp_free_i32(tmp2);
10091 break;
10092 case 0x18: /* clz */
10093 tcg_gen_clzi_i32(tmp, tmp, 32);
10094 break;
10095 case 0x20:
10096 case 0x21:
10097 case 0x22:
10098 case 0x28:
10099 case 0x29:
10100 case 0x2a:
10102 /* crc32/crc32c */
10103 uint32_t sz = op & 0x3;
10104 uint32_t c = op & 0x8;
10106 tmp2 = load_reg(s, rm);
10107 if (sz == 0) {
10108 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10109 } else if (sz == 1) {
10110 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10112 tmp3 = tcg_const_i32(1 << sz);
10113 if (c) {
10114 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10115 } else {
10116 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10118 tcg_temp_free_i32(tmp2);
10119 tcg_temp_free_i32(tmp3);
10120 break;
10122 default:
10123 g_assert_not_reached();
10126 store_reg(s, rd, tmp);
10127 break;
10128 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10129 switch ((insn >> 20) & 7) {
10130 case 0: /* 32 x 32 -> 32 */
10131 case 7: /* Unsigned sum of absolute differences. */
10132 break;
10133 case 1: /* 16 x 16 -> 32 */
10134 case 2: /* Dual multiply add. */
10135 case 3: /* 32 * 16 -> 32msb */
10136 case 4: /* Dual multiply subtract. */
10137 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10138 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10139 goto illegal_op;
10141 break;
10143 op = (insn >> 4) & 0xf;
10144 tmp = load_reg(s, rn);
10145 tmp2 = load_reg(s, rm);
10146 switch ((insn >> 20) & 7) {
10147 case 0: /* 32 x 32 -> 32 */
10148 tcg_gen_mul_i32(tmp, tmp, tmp2);
10149 tcg_temp_free_i32(tmp2);
10150 if (rs != 15) {
10151 tmp2 = load_reg(s, rs);
10152 if (op)
10153 tcg_gen_sub_i32(tmp, tmp2, tmp);
10154 else
10155 tcg_gen_add_i32(tmp, tmp, tmp2);
10156 tcg_temp_free_i32(tmp2);
10158 break;
10159 case 1: /* 16 x 16 -> 32 */
10160 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10161 tcg_temp_free_i32(tmp2);
10162 if (rs != 15) {
10163 tmp2 = load_reg(s, rs);
10164 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10165 tcg_temp_free_i32(tmp2);
10167 break;
10168 case 2: /* Dual multiply add. */
10169 case 4: /* Dual multiply subtract. */
10170 if (op)
10171 gen_swap_half(tmp2);
10172 gen_smul_dual(tmp, tmp2);
10173 if (insn & (1 << 22)) {
10174 /* This subtraction cannot overflow. */
10175 tcg_gen_sub_i32(tmp, tmp, tmp2);
10176 } else {
10177 /* This addition cannot overflow 32 bits;
10178 * however it may overflow considered as a signed
10179 * operation, in which case we must set the Q flag.
10181 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10183 tcg_temp_free_i32(tmp2);
10184 if (rs != 15)
10186 tmp2 = load_reg(s, rs);
10187 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10188 tcg_temp_free_i32(tmp2);
10190 break;
10191 case 3: /* 32 * 16 -> 32msb */
10192 if (op)
10193 tcg_gen_sari_i32(tmp2, tmp2, 16);
10194 else
10195 gen_sxth(tmp2);
10196 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10197 tcg_gen_shri_i64(tmp64, tmp64, 16);
10198 tmp = tcg_temp_new_i32();
10199 tcg_gen_extrl_i64_i32(tmp, tmp64);
10200 tcg_temp_free_i64(tmp64);
10201 if (rs != 15)
10203 tmp2 = load_reg(s, rs);
10204 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10205 tcg_temp_free_i32(tmp2);
10207 break;
10208 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10209 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10210 if (rs != 15) {
10211 tmp = load_reg(s, rs);
10212 if (insn & (1 << 20)) {
10213 tmp64 = gen_addq_msw(tmp64, tmp);
10214 } else {
10215 tmp64 = gen_subq_msw(tmp64, tmp);
10218 if (insn & (1 << 4)) {
10219 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10221 tcg_gen_shri_i64(tmp64, tmp64, 32);
10222 tmp = tcg_temp_new_i32();
10223 tcg_gen_extrl_i64_i32(tmp, tmp64);
10224 tcg_temp_free_i64(tmp64);
10225 break;
10226 case 7: /* Unsigned sum of absolute differences. */
10227 gen_helper_usad8(tmp, tmp, tmp2);
10228 tcg_temp_free_i32(tmp2);
10229 if (rs != 15) {
10230 tmp2 = load_reg(s, rs);
10231 tcg_gen_add_i32(tmp, tmp, tmp2);
10232 tcg_temp_free_i32(tmp2);
10234 break;
10236 store_reg(s, rd, tmp);
10237 break;
10238 case 6: case 7: /* 64-bit multiply, Divide. */
10239 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10240 tmp = load_reg(s, rn);
10241 tmp2 = load_reg(s, rm);
10242 if ((op & 0x50) == 0x10) {
10243 /* sdiv, udiv */
10244 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10245 goto illegal_op;
10247 if (op & 0x20)
10248 gen_helper_udiv(tmp, tmp, tmp2);
10249 else
10250 gen_helper_sdiv(tmp, tmp, tmp2);
10251 tcg_temp_free_i32(tmp2);
10252 store_reg(s, rd, tmp);
10253 } else if ((op & 0xe) == 0xc) {
10254 /* Dual multiply accumulate long. */
10255 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10256 tcg_temp_free_i32(tmp);
10257 tcg_temp_free_i32(tmp2);
10258 goto illegal_op;
10260 if (op & 1)
10261 gen_swap_half(tmp2);
10262 gen_smul_dual(tmp, tmp2);
10263 if (op & 0x10) {
10264 tcg_gen_sub_i32(tmp, tmp, tmp2);
10265 } else {
10266 tcg_gen_add_i32(tmp, tmp, tmp2);
10268 tcg_temp_free_i32(tmp2);
10269 /* BUGFIX */
10270 tmp64 = tcg_temp_new_i64();
10271 tcg_gen_ext_i32_i64(tmp64, tmp);
10272 tcg_temp_free_i32(tmp);
10273 gen_addq(s, tmp64, rs, rd);
10274 gen_storeq_reg(s, rs, rd, tmp64);
10275 tcg_temp_free_i64(tmp64);
10276 } else {
10277 if (op & 0x20) {
10278 /* Unsigned 64-bit multiply */
10279 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10280 } else {
10281 if (op & 8) {
10282 /* smlalxy */
10283 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10284 tcg_temp_free_i32(tmp2);
10285 tcg_temp_free_i32(tmp);
10286 goto illegal_op;
10288 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10289 tcg_temp_free_i32(tmp2);
10290 tmp64 = tcg_temp_new_i64();
10291 tcg_gen_ext_i32_i64(tmp64, tmp);
10292 tcg_temp_free_i32(tmp);
10293 } else {
10294 /* Signed 64-bit multiply */
10295 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10298 if (op & 4) {
10299 /* umaal */
10300 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10301 tcg_temp_free_i64(tmp64);
10302 goto illegal_op;
10304 gen_addq_lo(s, tmp64, rs);
10305 gen_addq_lo(s, tmp64, rd);
10306 } else if (op & 0x40) {
10307 /* 64-bit accumulate. */
10308 gen_addq(s, tmp64, rs, rd);
10310 gen_storeq_reg(s, rs, rd, tmp64);
10311 tcg_temp_free_i64(tmp64);
10313 break;
10315 break;
10316 case 6: case 7: case 14: case 15:
10317 /* Coprocessor. */
10318 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10319 /* We don't currently implement M profile FP support,
10320 * so this entire space should give a NOCP fault.
10322 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10323 default_exception_el(s));
10324 break;
10326 if (((insn >> 24) & 3) == 3) {
10327 /* Translate into the equivalent ARM encoding. */
10328 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10329 if (disas_neon_data_insn(s, insn)) {
10330 goto illegal_op;
10332 } else if (((insn >> 8) & 0xe) == 10) {
10333 if (disas_vfp_insn(s, insn)) {
10334 goto illegal_op;
10336 } else {
10337 if (insn & (1 << 28))
10338 goto illegal_op;
10339 if (disas_coproc_insn(s, insn)) {
10340 goto illegal_op;
10343 break;
10344 case 8: case 9: case 10: case 11:
10345 if (insn & (1 << 15)) {
10346 /* Branches, misc control. */
10347 if (insn & 0x5000) {
10348 /* Unconditional branch. */
10349 /* signextend(hw1[10:0]) -> offset[:12]. */
10350 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10351 /* hw1[10:0] -> offset[11:1]. */
10352 offset |= (insn & 0x7ff) << 1;
10353 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10354 offset[24:22] already have the same value because of the
10355 sign extension above. */
10356 offset ^= ((~insn) & (1 << 13)) << 10;
10357 offset ^= ((~insn) & (1 << 11)) << 11;
10359 if (insn & (1 << 14)) {
10360 /* Branch and link. */
10361 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10364 offset += s->pc;
10365 if (insn & (1 << 12)) {
10366 /* b/bl */
10367 gen_jmp(s, offset);
10368 } else {
10369 /* blx */
10370 offset &= ~(uint32_t)2;
10371 /* thumb2 bx, no need to check */
10372 gen_bx_im(s, offset);
10374 } else if (((insn >> 23) & 7) == 7) {
10375 /* Misc control */
10376 if (insn & (1 << 13))
10377 goto illegal_op;
10379 if (insn & (1 << 26)) {
10380 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10381 goto illegal_op;
10383 if (!(insn & (1 << 20))) {
10384 /* Hypervisor call (v7) */
10385 int imm16 = extract32(insn, 16, 4) << 12
10386 | extract32(insn, 0, 12);
10387 ARCH(7);
10388 if (IS_USER(s)) {
10389 goto illegal_op;
10391 gen_hvc(s, imm16);
10392 } else {
10393 /* Secure monitor call (v6+) */
10394 ARCH(6K);
10395 if (IS_USER(s)) {
10396 goto illegal_op;
10398 gen_smc(s);
10400 } else {
10401 op = (insn >> 20) & 7;
10402 switch (op) {
10403 case 0: /* msr cpsr. */
10404 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10405 tmp = load_reg(s, rn);
10406 addr = tcg_const_i32(insn & 0xff);
10407 gen_helper_v7m_msr(cpu_env, addr, tmp);
10408 tcg_temp_free_i32(addr);
10409 tcg_temp_free_i32(tmp);
10410 gen_lookup_tb(s);
10411 break;
10413 /* fall through */
10414 case 1: /* msr spsr. */
10415 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10416 goto illegal_op;
10419 if (extract32(insn, 5, 1)) {
10420 /* MSR (banked) */
10421 int sysm = extract32(insn, 8, 4) |
10422 (extract32(insn, 4, 1) << 4);
10423 int r = op & 1;
10425 gen_msr_banked(s, r, sysm, rm);
10426 break;
10429 /* MSR (for PSRs) */
10430 tmp = load_reg(s, rn);
10431 if (gen_set_psr(s,
10432 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10433 op == 1, tmp))
10434 goto illegal_op;
10435 break;
10436 case 2: /* cps, nop-hint. */
10437 if (((insn >> 8) & 7) == 0) {
10438 gen_nop_hint(s, insn & 0xff);
10440 /* Implemented as NOP in user mode. */
10441 if (IS_USER(s))
10442 break;
10443 offset = 0;
10444 imm = 0;
10445 if (insn & (1 << 10)) {
10446 if (insn & (1 << 7))
10447 offset |= CPSR_A;
10448 if (insn & (1 << 6))
10449 offset |= CPSR_I;
10450 if (insn & (1 << 5))
10451 offset |= CPSR_F;
10452 if (insn & (1 << 9))
10453 imm = CPSR_A | CPSR_I | CPSR_F;
10455 if (insn & (1 << 8)) {
10456 offset |= 0x1f;
10457 imm |= (insn & 0x1f);
10459 if (offset) {
10460 gen_set_psr_im(s, offset, 0, imm);
10462 break;
10463 case 3: /* Special control operations. */
10464 ARCH(7);
10465 op = (insn >> 4) & 0xf;
10466 switch (op) {
10467 case 2: /* clrex */
10468 gen_clrex(s);
10469 break;
10470 case 4: /* dsb */
10471 case 5: /* dmb */
10472 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10473 break;
10474 case 6: /* isb */
10475 /* We need to break the TB after this insn
10476 * to execute self-modifying code correctly
10477 * and also to take any pending interrupts
10478 * immediately.
10480 gen_lookup_tb(s);
10481 break;
10482 default:
10483 goto illegal_op;
10485 break;
10486 case 4: /* bxj */
10487 /* Trivial implementation equivalent to bx. */
10488 tmp = load_reg(s, rn);
10489 gen_bx(s, tmp);
10490 break;
10491 case 5: /* Exception return. */
10492 if (IS_USER(s)) {
10493 goto illegal_op;
10495 if (rn != 14 || rd != 15) {
10496 goto illegal_op;
10498 tmp = load_reg(s, rn);
10499 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10500 gen_exception_return(s, tmp);
10501 break;
10502 case 6: /* MRS */
10503 if (extract32(insn, 5, 1) &&
10504 !arm_dc_feature(s, ARM_FEATURE_M)) {
10505 /* MRS (banked) */
10506 int sysm = extract32(insn, 16, 4) |
10507 (extract32(insn, 4, 1) << 4);
10509 gen_mrs_banked(s, 0, sysm, rd);
10510 break;
10513 if (extract32(insn, 16, 4) != 0xf) {
10514 goto illegal_op;
10516 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10517 extract32(insn, 0, 8) != 0) {
10518 goto illegal_op;
10521 /* mrs cpsr */
10522 tmp = tcg_temp_new_i32();
10523 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10524 addr = tcg_const_i32(insn & 0xff);
10525 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10526 tcg_temp_free_i32(addr);
10527 } else {
10528 gen_helper_cpsr_read(tmp, cpu_env);
10530 store_reg(s, rd, tmp);
10531 break;
10532 case 7: /* MRS */
10533 if (extract32(insn, 5, 1) &&
10534 !arm_dc_feature(s, ARM_FEATURE_M)) {
10535 /* MRS (banked) */
10536 int sysm = extract32(insn, 16, 4) |
10537 (extract32(insn, 4, 1) << 4);
10539 gen_mrs_banked(s, 1, sysm, rd);
10540 break;
10543 /* mrs spsr. */
10544 /* Not accessible in user mode. */
10545 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10546 goto illegal_op;
10549 if (extract32(insn, 16, 4) != 0xf ||
10550 extract32(insn, 0, 8) != 0) {
10551 goto illegal_op;
10554 tmp = load_cpu_field(spsr);
10555 store_reg(s, rd, tmp);
10556 break;
10559 } else {
10560 /* Conditional branch. */
10561 op = (insn >> 22) & 0xf;
10562 /* Generate a conditional jump to next instruction. */
10563 s->condlabel = gen_new_label();
10564 arm_gen_test_cc(op ^ 1, s->condlabel);
10565 s->condjmp = 1;
10567 /* offset[11:1] = insn[10:0] */
10568 offset = (insn & 0x7ff) << 1;
10569 /* offset[17:12] = insn[21:16]. */
10570 offset |= (insn & 0x003f0000) >> 4;
10571 /* offset[31:20] = insn[26]. */
10572 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10573 /* offset[18] = insn[13]. */
10574 offset |= (insn & (1 << 13)) << 5;
10575 /* offset[19] = insn[11]. */
10576 offset |= (insn & (1 << 11)) << 8;
10578 /* jump to the offset */
10579 gen_jmp(s, s->pc + offset);
10581 } else {
10582 /* Data processing immediate. */
10583 if (insn & (1 << 25)) {
10584 if (insn & (1 << 24)) {
10585 if (insn & (1 << 20))
10586 goto illegal_op;
10587 /* Bitfield/Saturate. */
10588 op = (insn >> 21) & 7;
10589 imm = insn & 0x1f;
10590 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10591 if (rn == 15) {
10592 tmp = tcg_temp_new_i32();
10593 tcg_gen_movi_i32(tmp, 0);
10594 } else {
10595 tmp = load_reg(s, rn);
10597 switch (op) {
10598 case 2: /* Signed bitfield extract. */
10599 imm++;
10600 if (shift + imm > 32)
10601 goto illegal_op;
10602 if (imm < 32) {
10603 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10605 break;
10606 case 6: /* Unsigned bitfield extract. */
10607 imm++;
10608 if (shift + imm > 32)
10609 goto illegal_op;
10610 if (imm < 32) {
10611 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10613 break;
10614 case 3: /* Bitfield insert/clear. */
10615 if (imm < shift)
10616 goto illegal_op;
10617 imm = imm + 1 - shift;
10618 if (imm != 32) {
10619 tmp2 = load_reg(s, rd);
10620 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10621 tcg_temp_free_i32(tmp2);
10623 break;
10624 case 7:
10625 goto illegal_op;
10626 default: /* Saturate. */
10627 if (shift) {
10628 if (op & 1)
10629 tcg_gen_sari_i32(tmp, tmp, shift);
10630 else
10631 tcg_gen_shli_i32(tmp, tmp, shift);
10633 tmp2 = tcg_const_i32(imm);
10634 if (op & 4) {
10635 /* Unsigned. */
10636 if ((op & 1) && shift == 0) {
10637 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10638 tcg_temp_free_i32(tmp);
10639 tcg_temp_free_i32(tmp2);
10640 goto illegal_op;
10642 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10643 } else {
10644 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10646 } else {
10647 /* Signed. */
10648 if ((op & 1) && shift == 0) {
10649 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10650 tcg_temp_free_i32(tmp);
10651 tcg_temp_free_i32(tmp2);
10652 goto illegal_op;
10654 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10655 } else {
10656 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10659 tcg_temp_free_i32(tmp2);
10660 break;
10662 store_reg(s, rd, tmp);
10663 } else {
10664 imm = ((insn & 0x04000000) >> 15)
10665 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10666 if (insn & (1 << 22)) {
10667 /* 16-bit immediate. */
10668 imm |= (insn >> 4) & 0xf000;
10669 if (insn & (1 << 23)) {
10670 /* movt */
10671 tmp = load_reg(s, rd);
10672 tcg_gen_ext16u_i32(tmp, tmp);
10673 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10674 } else {
10675 /* movw */
10676 tmp = tcg_temp_new_i32();
10677 tcg_gen_movi_i32(tmp, imm);
10679 } else {
10680 /* Add/sub 12-bit immediate. */
10681 if (rn == 15) {
10682 offset = s->pc & ~(uint32_t)3;
10683 if (insn & (1 << 23))
10684 offset -= imm;
10685 else
10686 offset += imm;
10687 tmp = tcg_temp_new_i32();
10688 tcg_gen_movi_i32(tmp, offset);
10689 } else {
10690 tmp = load_reg(s, rn);
10691 if (insn & (1 << 23))
10692 tcg_gen_subi_i32(tmp, tmp, imm);
10693 else
10694 tcg_gen_addi_i32(tmp, tmp, imm);
10697 store_reg(s, rd, tmp);
10699 } else {
10700 int shifter_out = 0;
10701 /* modified 12-bit immediate. */
10702 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10703 imm = (insn & 0xff);
10704 switch (shift) {
10705 case 0: /* XY */
10706 /* Nothing to do. */
10707 break;
10708 case 1: /* 00XY00XY */
10709 imm |= imm << 16;
10710 break;
10711 case 2: /* XY00XY00 */
10712 imm |= imm << 16;
10713 imm <<= 8;
10714 break;
10715 case 3: /* XYXYXYXY */
10716 imm |= imm << 16;
10717 imm |= imm << 8;
10718 break;
10719 default: /* Rotated constant. */
10720 shift = (shift << 1) | (imm >> 7);
10721 imm |= 0x80;
10722 imm = imm << (32 - shift);
10723 shifter_out = 1;
10724 break;
10726 tmp2 = tcg_temp_new_i32();
10727 tcg_gen_movi_i32(tmp2, imm);
10728 rn = (insn >> 16) & 0xf;
10729 if (rn == 15) {
10730 tmp = tcg_temp_new_i32();
10731 tcg_gen_movi_i32(tmp, 0);
10732 } else {
10733 tmp = load_reg(s, rn);
10735 op = (insn >> 21) & 0xf;
10736 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10737 shifter_out, tmp, tmp2))
10738 goto illegal_op;
10739 tcg_temp_free_i32(tmp2);
10740 rd = (insn >> 8) & 0xf;
10741 if (rd != 15) {
10742 store_reg(s, rd, tmp);
10743 } else {
10744 tcg_temp_free_i32(tmp);
10748 break;
10749 case 12: /* Load/store single data item. */
10751 int postinc = 0;
10752 int writeback = 0;
10753 int memidx;
10754 ISSInfo issinfo;
10756 if ((insn & 0x01100000) == 0x01000000) {
10757 if (disas_neon_ls_insn(s, insn)) {
10758 goto illegal_op;
10760 break;
10762 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10763 if (rs == 15) {
10764 if (!(insn & (1 << 20))) {
10765 goto illegal_op;
10767 if (op != 2) {
10768 /* Byte or halfword load space with dest == r15 : memory hints.
10769 * Catch them early so we don't emit pointless addressing code.
10770 * This space is a mix of:
10771 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10772 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10773 * cores)
10774 * unallocated hints, which must be treated as NOPs
10775 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10776 * which is easiest for the decoding logic
10777 * Some space which must UNDEF
10779 int op1 = (insn >> 23) & 3;
10780 int op2 = (insn >> 6) & 0x3f;
10781 if (op & 2) {
10782 goto illegal_op;
10784 if (rn == 15) {
10785 /* UNPREDICTABLE, unallocated hint or
10786 * PLD/PLDW/PLI (literal)
10788 return 0;
10790 if (op1 & 1) {
10791 return 0; /* PLD/PLDW/PLI or unallocated hint */
10793 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10794 return 0; /* PLD/PLDW/PLI or unallocated hint */
10796 /* UNDEF space, or an UNPREDICTABLE */
10797 return 1;
10800 memidx = get_mem_index(s);
10801 if (rn == 15) {
10802 addr = tcg_temp_new_i32();
10803 /* PC relative. */
10804 /* s->pc has already been incremented by 4. */
10805 imm = s->pc & 0xfffffffc;
10806 if (insn & (1 << 23))
10807 imm += insn & 0xfff;
10808 else
10809 imm -= insn & 0xfff;
10810 tcg_gen_movi_i32(addr, imm);
10811 } else {
10812 addr = load_reg(s, rn);
10813 if (insn & (1 << 23)) {
10814 /* Positive offset. */
10815 imm = insn & 0xfff;
10816 tcg_gen_addi_i32(addr, addr, imm);
10817 } else {
10818 imm = insn & 0xff;
10819 switch ((insn >> 8) & 0xf) {
10820 case 0x0: /* Shifted Register. */
10821 shift = (insn >> 4) & 0xf;
10822 if (shift > 3) {
10823 tcg_temp_free_i32(addr);
10824 goto illegal_op;
10826 tmp = load_reg(s, rm);
10827 if (shift)
10828 tcg_gen_shli_i32(tmp, tmp, shift);
10829 tcg_gen_add_i32(addr, addr, tmp);
10830 tcg_temp_free_i32(tmp);
10831 break;
10832 case 0xc: /* Negative offset. */
10833 tcg_gen_addi_i32(addr, addr, -imm);
10834 break;
10835 case 0xe: /* User privilege. */
10836 tcg_gen_addi_i32(addr, addr, imm);
10837 memidx = get_a32_user_mem_index(s);
10838 break;
10839 case 0x9: /* Post-decrement. */
10840 imm = -imm;
10841 /* Fall through. */
10842 case 0xb: /* Post-increment. */
10843 postinc = 1;
10844 writeback = 1;
10845 break;
10846 case 0xd: /* Pre-decrement. */
10847 imm = -imm;
10848 /* Fall through. */
10849 case 0xf: /* Pre-increment. */
10850 tcg_gen_addi_i32(addr, addr, imm);
10851 writeback = 1;
10852 break;
10853 default:
10854 tcg_temp_free_i32(addr);
10855 goto illegal_op;
10860 issinfo = writeback ? ISSInvalid : rs;
10862 if (insn & (1 << 20)) {
10863 /* Load. */
10864 tmp = tcg_temp_new_i32();
10865 switch (op) {
10866 case 0:
10867 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10868 break;
10869 case 4:
10870 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10871 break;
10872 case 1:
10873 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10874 break;
10875 case 5:
10876 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10877 break;
10878 case 2:
10879 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10880 break;
10881 default:
10882 tcg_temp_free_i32(tmp);
10883 tcg_temp_free_i32(addr);
10884 goto illegal_op;
10886 if (rs == 15) {
10887 gen_bx(s, tmp);
10888 } else {
10889 store_reg(s, rs, tmp);
10891 } else {
10892 /* Store. */
10893 tmp = load_reg(s, rs);
10894 switch (op) {
10895 case 0:
10896 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10897 break;
10898 case 1:
10899 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10900 break;
10901 case 2:
10902 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10903 break;
10904 default:
10905 tcg_temp_free_i32(tmp);
10906 tcg_temp_free_i32(addr);
10907 goto illegal_op;
10909 tcg_temp_free_i32(tmp);
10911 if (postinc)
10912 tcg_gen_addi_i32(addr, addr, imm);
10913 if (writeback) {
10914 store_reg(s, rn, addr);
10915 } else {
10916 tcg_temp_free_i32(addr);
10919 break;
10920 default:
10921 goto illegal_op;
10923 return 0;
10924 illegal_op:
10925 return 1;
10928 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10930 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10931 int32_t offset;
10932 int i;
10933 TCGv_i32 tmp;
10934 TCGv_i32 tmp2;
10935 TCGv_i32 addr;
10937 if (s->condexec_mask) {
10938 cond = s->condexec_cond;
10939 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10940 s->condlabel = gen_new_label();
10941 arm_gen_test_cc(cond ^ 1, s->condlabel);
10942 s->condjmp = 1;
10946 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
10947 s->pc += 2;
10949 switch (insn >> 12) {
10950 case 0: case 1:
10952 rd = insn & 7;
10953 op = (insn >> 11) & 3;
10954 if (op == 3) {
10955 /* add/subtract */
10956 rn = (insn >> 3) & 7;
10957 tmp = load_reg(s, rn);
10958 if (insn & (1 << 10)) {
10959 /* immediate */
10960 tmp2 = tcg_temp_new_i32();
10961 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10962 } else {
10963 /* reg */
10964 rm = (insn >> 6) & 7;
10965 tmp2 = load_reg(s, rm);
10967 if (insn & (1 << 9)) {
10968 if (s->condexec_mask)
10969 tcg_gen_sub_i32(tmp, tmp, tmp2);
10970 else
10971 gen_sub_CC(tmp, tmp, tmp2);
10972 } else {
10973 if (s->condexec_mask)
10974 tcg_gen_add_i32(tmp, tmp, tmp2);
10975 else
10976 gen_add_CC(tmp, tmp, tmp2);
10978 tcg_temp_free_i32(tmp2);
10979 store_reg(s, rd, tmp);
10980 } else {
10981 /* shift immediate */
10982 rm = (insn >> 3) & 7;
10983 shift = (insn >> 6) & 0x1f;
10984 tmp = load_reg(s, rm);
10985 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10986 if (!s->condexec_mask)
10987 gen_logic_CC(tmp);
10988 store_reg(s, rd, tmp);
10990 break;
10991 case 2: case 3:
10992 /* arithmetic large immediate */
10993 op = (insn >> 11) & 3;
10994 rd = (insn >> 8) & 0x7;
10995 if (op == 0) { /* mov */
10996 tmp = tcg_temp_new_i32();
10997 tcg_gen_movi_i32(tmp, insn & 0xff);
10998 if (!s->condexec_mask)
10999 gen_logic_CC(tmp);
11000 store_reg(s, rd, tmp);
11001 } else {
11002 tmp = load_reg(s, rd);
11003 tmp2 = tcg_temp_new_i32();
11004 tcg_gen_movi_i32(tmp2, insn & 0xff);
11005 switch (op) {
11006 case 1: /* cmp */
11007 gen_sub_CC(tmp, tmp, tmp2);
11008 tcg_temp_free_i32(tmp);
11009 tcg_temp_free_i32(tmp2);
11010 break;
11011 case 2: /* add */
11012 if (s->condexec_mask)
11013 tcg_gen_add_i32(tmp, tmp, tmp2);
11014 else
11015 gen_add_CC(tmp, tmp, tmp2);
11016 tcg_temp_free_i32(tmp2);
11017 store_reg(s, rd, tmp);
11018 break;
11019 case 3: /* sub */
11020 if (s->condexec_mask)
11021 tcg_gen_sub_i32(tmp, tmp, tmp2);
11022 else
11023 gen_sub_CC(tmp, tmp, tmp2);
11024 tcg_temp_free_i32(tmp2);
11025 store_reg(s, rd, tmp);
11026 break;
11029 break;
11030 case 4:
11031 if (insn & (1 << 11)) {
11032 rd = (insn >> 8) & 7;
11033 /* load pc-relative. Bit 1 of PC is ignored. */
11034 val = s->pc + 2 + ((insn & 0xff) * 4);
11035 val &= ~(uint32_t)2;
11036 addr = tcg_temp_new_i32();
11037 tcg_gen_movi_i32(addr, val);
11038 tmp = tcg_temp_new_i32();
11039 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11040 rd | ISSIs16Bit);
11041 tcg_temp_free_i32(addr);
11042 store_reg(s, rd, tmp);
11043 break;
11045 if (insn & (1 << 10)) {
11046 /* data processing extended or blx */
11047 rd = (insn & 7) | ((insn >> 4) & 8);
11048 rm = (insn >> 3) & 0xf;
11049 op = (insn >> 8) & 3;
11050 switch (op) {
11051 case 0: /* add */
11052 tmp = load_reg(s, rd);
11053 tmp2 = load_reg(s, rm);
11054 tcg_gen_add_i32(tmp, tmp, tmp2);
11055 tcg_temp_free_i32(tmp2);
11056 store_reg(s, rd, tmp);
11057 break;
11058 case 1: /* cmp */
11059 tmp = load_reg(s, rd);
11060 tmp2 = load_reg(s, rm);
11061 gen_sub_CC(tmp, tmp, tmp2);
11062 tcg_temp_free_i32(tmp2);
11063 tcg_temp_free_i32(tmp);
11064 break;
11065 case 2: /* mov/cpy */
11066 tmp = load_reg(s, rm);
11067 store_reg(s, rd, tmp);
11068 break;
11069 case 3:/* branch [and link] exchange thumb register */
11070 tmp = load_reg(s, rm);
11071 if (insn & (1 << 7)) {
11072 ARCH(5);
11073 val = (uint32_t)s->pc | 1;
11074 tmp2 = tcg_temp_new_i32();
11075 tcg_gen_movi_i32(tmp2, val);
11076 store_reg(s, 14, tmp2);
11078 /* already thumb, no need to check */
11079 gen_bx(s, tmp);
11080 break;
11082 break;
11085 /* data processing register */
11086 rd = insn & 7;
11087 rm = (insn >> 3) & 7;
11088 op = (insn >> 6) & 0xf;
11089 if (op == 2 || op == 3 || op == 4 || op == 7) {
11090 /* the shift/rotate ops want the operands backwards */
11091 val = rm;
11092 rm = rd;
11093 rd = val;
11094 val = 1;
11095 } else {
11096 val = 0;
11099 if (op == 9) { /* neg */
11100 tmp = tcg_temp_new_i32();
11101 tcg_gen_movi_i32(tmp, 0);
11102 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11103 tmp = load_reg(s, rd);
11104 } else {
11105 TCGV_UNUSED_I32(tmp);
11108 tmp2 = load_reg(s, rm);
11109 switch (op) {
11110 case 0x0: /* and */
11111 tcg_gen_and_i32(tmp, tmp, tmp2);
11112 if (!s->condexec_mask)
11113 gen_logic_CC(tmp);
11114 break;
11115 case 0x1: /* eor */
11116 tcg_gen_xor_i32(tmp, tmp, tmp2);
11117 if (!s->condexec_mask)
11118 gen_logic_CC(tmp);
11119 break;
11120 case 0x2: /* lsl */
11121 if (s->condexec_mask) {
11122 gen_shl(tmp2, tmp2, tmp);
11123 } else {
11124 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11125 gen_logic_CC(tmp2);
11127 break;
11128 case 0x3: /* lsr */
11129 if (s->condexec_mask) {
11130 gen_shr(tmp2, tmp2, tmp);
11131 } else {
11132 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11133 gen_logic_CC(tmp2);
11135 break;
11136 case 0x4: /* asr */
11137 if (s->condexec_mask) {
11138 gen_sar(tmp2, tmp2, tmp);
11139 } else {
11140 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11141 gen_logic_CC(tmp2);
11143 break;
11144 case 0x5: /* adc */
11145 if (s->condexec_mask) {
11146 gen_adc(tmp, tmp2);
11147 } else {
11148 gen_adc_CC(tmp, tmp, tmp2);
11150 break;
11151 case 0x6: /* sbc */
11152 if (s->condexec_mask) {
11153 gen_sub_carry(tmp, tmp, tmp2);
11154 } else {
11155 gen_sbc_CC(tmp, tmp, tmp2);
11157 break;
11158 case 0x7: /* ror */
11159 if (s->condexec_mask) {
11160 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11161 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11162 } else {
11163 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11164 gen_logic_CC(tmp2);
11166 break;
11167 case 0x8: /* tst */
11168 tcg_gen_and_i32(tmp, tmp, tmp2);
11169 gen_logic_CC(tmp);
11170 rd = 16;
11171 break;
11172 case 0x9: /* neg */
11173 if (s->condexec_mask)
11174 tcg_gen_neg_i32(tmp, tmp2);
11175 else
11176 gen_sub_CC(tmp, tmp, tmp2);
11177 break;
11178 case 0xa: /* cmp */
11179 gen_sub_CC(tmp, tmp, tmp2);
11180 rd = 16;
11181 break;
11182 case 0xb: /* cmn */
11183 gen_add_CC(tmp, tmp, tmp2);
11184 rd = 16;
11185 break;
11186 case 0xc: /* orr */
11187 tcg_gen_or_i32(tmp, tmp, tmp2);
11188 if (!s->condexec_mask)
11189 gen_logic_CC(tmp);
11190 break;
11191 case 0xd: /* mul */
11192 tcg_gen_mul_i32(tmp, tmp, tmp2);
11193 if (!s->condexec_mask)
11194 gen_logic_CC(tmp);
11195 break;
11196 case 0xe: /* bic */
11197 tcg_gen_andc_i32(tmp, tmp, tmp2);
11198 if (!s->condexec_mask)
11199 gen_logic_CC(tmp);
11200 break;
11201 case 0xf: /* mvn */
11202 tcg_gen_not_i32(tmp2, tmp2);
11203 if (!s->condexec_mask)
11204 gen_logic_CC(tmp2);
11205 val = 1;
11206 rm = rd;
11207 break;
11209 if (rd != 16) {
11210 if (val) {
11211 store_reg(s, rm, tmp2);
11212 if (op != 0xf)
11213 tcg_temp_free_i32(tmp);
11214 } else {
11215 store_reg(s, rd, tmp);
11216 tcg_temp_free_i32(tmp2);
11218 } else {
11219 tcg_temp_free_i32(tmp);
11220 tcg_temp_free_i32(tmp2);
11222 break;
11224 case 5:
11225 /* load/store register offset. */
11226 rd = insn & 7;
11227 rn = (insn >> 3) & 7;
11228 rm = (insn >> 6) & 7;
11229 op = (insn >> 9) & 7;
11230 addr = load_reg(s, rn);
11231 tmp = load_reg(s, rm);
11232 tcg_gen_add_i32(addr, addr, tmp);
11233 tcg_temp_free_i32(tmp);
11235 if (op < 3) { /* store */
11236 tmp = load_reg(s, rd);
11237 } else {
11238 tmp = tcg_temp_new_i32();
11241 switch (op) {
11242 case 0: /* str */
11243 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11244 break;
11245 case 1: /* strh */
11246 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11247 break;
11248 case 2: /* strb */
11249 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11250 break;
11251 case 3: /* ldrsb */
11252 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11253 break;
11254 case 4: /* ldr */
11255 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11256 break;
11257 case 5: /* ldrh */
11258 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11259 break;
11260 case 6: /* ldrb */
11261 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11262 break;
11263 case 7: /* ldrsh */
11264 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11265 break;
11267 if (op >= 3) { /* load */
11268 store_reg(s, rd, tmp);
11269 } else {
11270 tcg_temp_free_i32(tmp);
11272 tcg_temp_free_i32(addr);
11273 break;
11275 case 6:
11276 /* load/store word immediate offset */
11277 rd = insn & 7;
11278 rn = (insn >> 3) & 7;
11279 addr = load_reg(s, rn);
11280 val = (insn >> 4) & 0x7c;
11281 tcg_gen_addi_i32(addr, addr, val);
11283 if (insn & (1 << 11)) {
11284 /* load */
11285 tmp = tcg_temp_new_i32();
11286 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11287 store_reg(s, rd, tmp);
11288 } else {
11289 /* store */
11290 tmp = load_reg(s, rd);
11291 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11292 tcg_temp_free_i32(tmp);
11294 tcg_temp_free_i32(addr);
11295 break;
11297 case 7:
11298 /* load/store byte immediate offset */
11299 rd = insn & 7;
11300 rn = (insn >> 3) & 7;
11301 addr = load_reg(s, rn);
11302 val = (insn >> 6) & 0x1f;
11303 tcg_gen_addi_i32(addr, addr, val);
11305 if (insn & (1 << 11)) {
11306 /* load */
11307 tmp = tcg_temp_new_i32();
11308 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11309 store_reg(s, rd, tmp);
11310 } else {
11311 /* store */
11312 tmp = load_reg(s, rd);
11313 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11314 tcg_temp_free_i32(tmp);
11316 tcg_temp_free_i32(addr);
11317 break;
11319 case 8:
11320 /* load/store halfword immediate offset */
11321 rd = insn & 7;
11322 rn = (insn >> 3) & 7;
11323 addr = load_reg(s, rn);
11324 val = (insn >> 5) & 0x3e;
11325 tcg_gen_addi_i32(addr, addr, val);
11327 if (insn & (1 << 11)) {
11328 /* load */
11329 tmp = tcg_temp_new_i32();
11330 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11331 store_reg(s, rd, tmp);
11332 } else {
11333 /* store */
11334 tmp = load_reg(s, rd);
11335 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11336 tcg_temp_free_i32(tmp);
11338 tcg_temp_free_i32(addr);
11339 break;
11341 case 9:
11342 /* load/store from stack */
11343 rd = (insn >> 8) & 7;
11344 addr = load_reg(s, 13);
11345 val = (insn & 0xff) * 4;
11346 tcg_gen_addi_i32(addr, addr, val);
11348 if (insn & (1 << 11)) {
11349 /* load */
11350 tmp = tcg_temp_new_i32();
11351 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11352 store_reg(s, rd, tmp);
11353 } else {
11354 /* store */
11355 tmp = load_reg(s, rd);
11356 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11357 tcg_temp_free_i32(tmp);
11359 tcg_temp_free_i32(addr);
11360 break;
11362 case 10:
11363 /* add to high reg */
11364 rd = (insn >> 8) & 7;
11365 if (insn & (1 << 11)) {
11366 /* SP */
11367 tmp = load_reg(s, 13);
11368 } else {
11369 /* PC. bit 1 is ignored. */
11370 tmp = tcg_temp_new_i32();
11371 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11373 val = (insn & 0xff) * 4;
11374 tcg_gen_addi_i32(tmp, tmp, val);
11375 store_reg(s, rd, tmp);
11376 break;
11378 case 11:
11379 /* misc */
11380 op = (insn >> 8) & 0xf;
11381 switch (op) {
11382 case 0:
11383 /* adjust stack pointer */
11384 tmp = load_reg(s, 13);
11385 val = (insn & 0x7f) * 4;
11386 if (insn & (1 << 7))
11387 val = -(int32_t)val;
11388 tcg_gen_addi_i32(tmp, tmp, val);
11389 store_reg(s, 13, tmp);
11390 break;
11392 case 2: /* sign/zero extend. */
11393 ARCH(6);
11394 rd = insn & 7;
11395 rm = (insn >> 3) & 7;
11396 tmp = load_reg(s, rm);
11397 switch ((insn >> 6) & 3) {
11398 case 0: gen_sxth(tmp); break;
11399 case 1: gen_sxtb(tmp); break;
11400 case 2: gen_uxth(tmp); break;
11401 case 3: gen_uxtb(tmp); break;
11403 store_reg(s, rd, tmp);
11404 break;
11405 case 4: case 5: case 0xc: case 0xd:
11406 /* push/pop */
11407 addr = load_reg(s, 13);
11408 if (insn & (1 << 8))
11409 offset = 4;
11410 else
11411 offset = 0;
11412 for (i = 0; i < 8; i++) {
11413 if (insn & (1 << i))
11414 offset += 4;
11416 if ((insn & (1 << 11)) == 0) {
11417 tcg_gen_addi_i32(addr, addr, -offset);
11419 for (i = 0; i < 8; i++) {
11420 if (insn & (1 << i)) {
11421 if (insn & (1 << 11)) {
11422 /* pop */
11423 tmp = tcg_temp_new_i32();
11424 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11425 store_reg(s, i, tmp);
11426 } else {
11427 /* push */
11428 tmp = load_reg(s, i);
11429 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11430 tcg_temp_free_i32(tmp);
11432 /* advance to the next address. */
11433 tcg_gen_addi_i32(addr, addr, 4);
11436 TCGV_UNUSED_I32(tmp);
11437 if (insn & (1 << 8)) {
11438 if (insn & (1 << 11)) {
11439 /* pop pc */
11440 tmp = tcg_temp_new_i32();
11441 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11442 /* don't set the pc until the rest of the instruction
11443 has completed */
11444 } else {
11445 /* push lr */
11446 tmp = load_reg(s, 14);
11447 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11448 tcg_temp_free_i32(tmp);
11450 tcg_gen_addi_i32(addr, addr, 4);
11452 if ((insn & (1 << 11)) == 0) {
11453 tcg_gen_addi_i32(addr, addr, -offset);
11455 /* write back the new stack pointer */
11456 store_reg(s, 13, addr);
11457 /* set the new PC value */
11458 if ((insn & 0x0900) == 0x0900) {
11459 store_reg_from_load(s, 15, tmp);
11461 break;
11463 case 1: case 3: case 9: case 11: /* czb */
11464 rm = insn & 7;
11465 tmp = load_reg(s, rm);
11466 s->condlabel = gen_new_label();
11467 s->condjmp = 1;
11468 if (insn & (1 << 11))
11469 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11470 else
11471 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11472 tcg_temp_free_i32(tmp);
11473 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11474 val = (uint32_t)s->pc + 2;
11475 val += offset;
11476 gen_jmp(s, val);
11477 break;
11479 case 15: /* IT, nop-hint. */
11480 if ((insn & 0xf) == 0) {
11481 gen_nop_hint(s, (insn >> 4) & 0xf);
11482 break;
11484 /* If Then. */
11485 s->condexec_cond = (insn >> 4) & 0xe;
11486 s->condexec_mask = insn & 0x1f;
11487 /* No actual code generated for this insn, just setup state. */
11488 break;
11490 case 0xe: /* bkpt */
11492 int imm8 = extract32(insn, 0, 8);
11493 ARCH(5);
11494 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11495 default_exception_el(s));
11496 break;
11499 case 0xa: /* rev, and hlt */
11501 int op1 = extract32(insn, 6, 2);
11503 if (op1 == 2) {
11504 /* HLT */
11505 int imm6 = extract32(insn, 0, 6);
11507 gen_hlt(s, imm6);
11508 break;
11511 /* Otherwise this is rev */
11512 ARCH(6);
11513 rn = (insn >> 3) & 0x7;
11514 rd = insn & 0x7;
11515 tmp = load_reg(s, rn);
11516 switch (op1) {
11517 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11518 case 1: gen_rev16(tmp); break;
11519 case 3: gen_revsh(tmp); break;
11520 default:
11521 g_assert_not_reached();
11523 store_reg(s, rd, tmp);
11524 break;
11527 case 6:
11528 switch ((insn >> 5) & 7) {
11529 case 2:
11530 /* setend */
11531 ARCH(6);
11532 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11533 gen_helper_setend(cpu_env);
11534 s->is_jmp = DISAS_UPDATE;
11536 break;
11537 case 3:
11538 /* cps */
11539 ARCH(6);
11540 if (IS_USER(s)) {
11541 break;
11543 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11544 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11545 /* FAULTMASK */
11546 if (insn & 1) {
11547 addr = tcg_const_i32(19);
11548 gen_helper_v7m_msr(cpu_env, addr, tmp);
11549 tcg_temp_free_i32(addr);
11551 /* PRIMASK */
11552 if (insn & 2) {
11553 addr = tcg_const_i32(16);
11554 gen_helper_v7m_msr(cpu_env, addr, tmp);
11555 tcg_temp_free_i32(addr);
11557 tcg_temp_free_i32(tmp);
11558 gen_lookup_tb(s);
11559 } else {
11560 if (insn & (1 << 4)) {
11561 shift = CPSR_A | CPSR_I | CPSR_F;
11562 } else {
11563 shift = 0;
11565 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11567 break;
11568 default:
11569 goto undef;
11571 break;
11573 default:
11574 goto undef;
11576 break;
11578 case 12:
11580 /* load/store multiple */
11581 TCGv_i32 loaded_var;
11582 TCGV_UNUSED_I32(loaded_var);
11583 rn = (insn >> 8) & 0x7;
11584 addr = load_reg(s, rn);
11585 for (i = 0; i < 8; i++) {
11586 if (insn & (1 << i)) {
11587 if (insn & (1 << 11)) {
11588 /* load */
11589 tmp = tcg_temp_new_i32();
11590 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11591 if (i == rn) {
11592 loaded_var = tmp;
11593 } else {
11594 store_reg(s, i, tmp);
11596 } else {
11597 /* store */
11598 tmp = load_reg(s, i);
11599 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11600 tcg_temp_free_i32(tmp);
11602 /* advance to the next address */
11603 tcg_gen_addi_i32(addr, addr, 4);
11606 if ((insn & (1 << rn)) == 0) {
11607 /* base reg not in list: base register writeback */
11608 store_reg(s, rn, addr);
11609 } else {
11610 /* base reg in list: if load, complete it now */
11611 if (insn & (1 << 11)) {
11612 store_reg(s, rn, loaded_var);
11614 tcg_temp_free_i32(addr);
11616 break;
11618 case 13:
11619 /* conditional branch or swi */
11620 cond = (insn >> 8) & 0xf;
11621 if (cond == 0xe)
11622 goto undef;
11624 if (cond == 0xf) {
11625 /* swi */
11626 gen_set_pc_im(s, s->pc);
11627 s->svc_imm = extract32(insn, 0, 8);
11628 s->is_jmp = DISAS_SWI;
11629 break;
11631 /* generate a conditional jump to next instruction */
11632 s->condlabel = gen_new_label();
11633 arm_gen_test_cc(cond ^ 1, s->condlabel);
11634 s->condjmp = 1;
11636 /* jump to the offset */
11637 val = (uint32_t)s->pc + 2;
11638 offset = ((int32_t)insn << 24) >> 24;
11639 val += offset << 1;
11640 gen_jmp(s, val);
11641 break;
11643 case 14:
11644 if (insn & (1 << 11)) {
11645 if (disas_thumb2_insn(env, s, insn))
11646 goto undef32;
11647 break;
11649 /* unconditional branch */
11650 val = (uint32_t)s->pc;
11651 offset = ((int32_t)insn << 21) >> 21;
11652 val += (offset << 1) + 2;
11653 gen_jmp(s, val);
11654 break;
11656 case 15:
11657 if (disas_thumb2_insn(env, s, insn))
11658 goto undef32;
11659 break;
11661 return;
11662 undef32:
11663 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11664 default_exception_el(s));
11665 return;
11666 illegal_op:
11667 undef:
11668 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11669 default_exception_el(s));
11672 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11674 /* Return true if the insn at dc->pc might cross a page boundary.
11675 * (False positives are OK, false negatives are not.)
11677 uint16_t insn;
11679 if ((s->pc & 3) == 0) {
11680 /* At a 4-aligned address we can't be crossing a page */
11681 return false;
11684 /* This must be a Thumb insn */
11685 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11687 if ((insn >> 11) >= 0x1d) {
11688 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11689 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11690 * end up actually treating this as two 16-bit insns (see the
11691 * code at the start of disas_thumb2_insn()) but we don't bother
11692 * to check for that as it is unlikely, and false positives here
11693 * are harmless.
11695 return true;
11697 /* Definitely a 16-bit insn, can't be crossing a page. */
11698 return false;
11701 /* generate intermediate code for basic block 'tb'. */
11702 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11704 ARMCPU *cpu = arm_env_get_cpu(env);
11705 CPUState *cs = CPU(cpu);
11706 DisasContext dc1, *dc = &dc1;
11707 target_ulong pc_start;
11708 target_ulong next_page_start;
11709 int num_insns;
11710 int max_insns;
11711 bool end_of_page;
11713 /* generate intermediate code */
11715 /* The A64 decoder has its own top level loop, because it doesn't need
11716 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11718 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11719 gen_intermediate_code_a64(cpu, tb);
11720 return;
11723 pc_start = tb->pc;
11725 dc->tb = tb;
11727 dc->is_jmp = DISAS_NEXT;
11728 dc->pc = pc_start;
11729 dc->singlestep_enabled = cs->singlestep_enabled;
11730 dc->condjmp = 0;
11732 dc->aarch64 = 0;
11733 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11734 * there is no secure EL1, so we route exceptions to EL3.
11736 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11737 !arm_el_is_aa64(env, 3);
11738 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11739 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11740 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11741 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11742 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11743 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11744 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11745 #if !defined(CONFIG_USER_ONLY)
11746 dc->user = (dc->current_el == 0);
11747 #endif
11748 dc->ns = ARM_TBFLAG_NS(tb->flags);
11749 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11750 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11751 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11752 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11753 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11754 dc->cp_regs = cpu->cp_regs;
11755 dc->features = env->features;
11757 /* Single step state. The code-generation logic here is:
11758 * SS_ACTIVE == 0:
11759 * generate code with no special handling for single-stepping (except
11760 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11761 * this happens anyway because those changes are all system register or
11762 * PSTATE writes).
11763 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11764 * emit code for one insn
11765 * emit code to clear PSTATE.SS
11766 * emit code to generate software step exception for completed step
11767 * end TB (as usual for having generated an exception)
11768 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11769 * emit code to generate a software step exception
11770 * end the TB
11772 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11773 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11774 dc->is_ldex = false;
11775 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11777 cpu_F0s = tcg_temp_new_i32();
11778 cpu_F1s = tcg_temp_new_i32();
11779 cpu_F0d = tcg_temp_new_i64();
11780 cpu_F1d = tcg_temp_new_i64();
11781 cpu_V0 = cpu_F0d;
11782 cpu_V1 = cpu_F1d;
11783 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11784 cpu_M0 = tcg_temp_new_i64();
11785 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11786 num_insns = 0;
11787 max_insns = tb->cflags & CF_COUNT_MASK;
11788 if (max_insns == 0) {
11789 max_insns = CF_COUNT_MASK;
11791 if (max_insns > TCG_MAX_INSNS) {
11792 max_insns = TCG_MAX_INSNS;
11795 gen_tb_start(tb);
11797 tcg_clear_temp_count();
11799 /* A note on handling of the condexec (IT) bits:
11801 * We want to avoid the overhead of having to write the updated condexec
11802 * bits back to the CPUARMState for every instruction in an IT block. So:
11803 * (1) if the condexec bits are not already zero then we write
11804 * zero back into the CPUARMState now. This avoids complications trying
11805 * to do it at the end of the block. (For example if we don't do this
11806 * it's hard to identify whether we can safely skip writing condexec
11807 * at the end of the TB, which we definitely want to do for the case
11808 * where a TB doesn't do anything with the IT state at all.)
11809 * (2) if we are going to leave the TB then we call gen_set_condexec()
11810 * which will write the correct value into CPUARMState if zero is wrong.
11811 * This is done both for leaving the TB at the end, and for leaving
11812 * it because of an exception we know will happen, which is done in
11813 * gen_exception_insn(). The latter is necessary because we need to
11814 * leave the TB with the PC/IT state just prior to execution of the
11815 * instruction which caused the exception.
11816 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11817 * then the CPUARMState will be wrong and we need to reset it.
11818 * This is handled in the same way as restoration of the
11819 * PC in these situations; we save the value of the condexec bits
11820 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11821 * then uses this to restore them after an exception.
11823 * Note that there are no instructions which can read the condexec
11824 * bits, and none which can write non-static values to them, so
11825 * we don't need to care about whether CPUARMState is correct in the
11826 * middle of a TB.
11829 /* Reset the conditional execution bits immediately. This avoids
11830 complications trying to do it at the end of the block. */
11831 if (dc->condexec_mask || dc->condexec_cond)
11833 TCGv_i32 tmp = tcg_temp_new_i32();
11834 tcg_gen_movi_i32(tmp, 0);
11835 store_cpu_field(tmp, condexec_bits);
11837 do {
11838 dc->insn_start_idx = tcg_op_buf_count();
11839 tcg_gen_insn_start(dc->pc,
11840 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11842 num_insns++;
11844 #ifdef CONFIG_USER_ONLY
11845 /* Intercept jump to the magic kernel page. */
11846 if (dc->pc >= 0xffff0000) {
11847 /* We always get here via a jump, so know we are not in a
11848 conditional execution block. */
11849 gen_exception_internal(EXCP_KERNEL_TRAP);
11850 dc->is_jmp = DISAS_EXC;
11851 break;
11853 #else
11854 if (arm_dc_feature(dc, ARM_FEATURE_M)) {
11855 /* Branches to the magic exception-return addresses should
11856 * already have been caught via the arm_v7m_unassigned_access hook,
11857 * and never get here.
11859 assert(dc->pc < 0xfffffff0);
11861 #endif
11863 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11864 CPUBreakpoint *bp;
11865 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11866 if (bp->pc == dc->pc) {
11867 if (bp->flags & BP_CPU) {
11868 gen_set_condexec(dc);
11869 gen_set_pc_im(dc, dc->pc);
11870 gen_helper_check_breakpoints(cpu_env);
11871 /* End the TB early; it's likely not going to be executed */
11872 dc->is_jmp = DISAS_UPDATE;
11873 } else {
11874 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11875 /* The address covered by the breakpoint must be
11876 included in [tb->pc, tb->pc + tb->size) in order
11877 to for it to be properly cleared -- thus we
11878 increment the PC here so that the logic setting
11879 tb->size below does the right thing. */
11880 /* TODO: Advance PC by correct instruction length to
11881 * avoid disassembler error messages */
11882 dc->pc += 2;
11883 goto done_generating;
11885 break;
11890 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11891 gen_io_start();
11894 if (dc->ss_active && !dc->pstate_ss) {
11895 /* Singlestep state is Active-pending.
11896 * If we're in this state at the start of a TB then either
11897 * a) we just took an exception to an EL which is being debugged
11898 * and this is the first insn in the exception handler
11899 * b) debug exceptions were masked and we just unmasked them
11900 * without changing EL (eg by clearing PSTATE.D)
11901 * In either case we're going to take a swstep exception in the
11902 * "did not step an insn" case, and so the syndrome ISV and EX
11903 * bits should be zero.
11905 assert(num_insns == 1);
11906 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11907 default_exception_el(dc));
11908 goto done_generating;
11911 if (dc->thumb) {
11912 disas_thumb_insn(env, dc);
11913 if (dc->condexec_mask) {
11914 dc->condexec_cond = (dc->condexec_cond & 0xe)
11915 | ((dc->condexec_mask >> 4) & 1);
11916 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11917 if (dc->condexec_mask == 0) {
11918 dc->condexec_cond = 0;
11921 } else {
11922 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
11923 dc->pc += 4;
11924 disas_arm_insn(dc, insn);
11927 if (dc->condjmp && !dc->is_jmp) {
11928 gen_set_label(dc->condlabel);
11929 dc->condjmp = 0;
11932 if (tcg_check_temp_count()) {
11933 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11934 dc->pc);
11937 /* Translation stops when a conditional branch is encountered.
11938 * Otherwise the subsequent code could get translated several times.
11939 * Also stop translation when a page boundary is reached. This
11940 * ensures prefetch aborts occur at the right place. */
11942 /* We want to stop the TB if the next insn starts in a new page,
11943 * or if it spans between this page and the next. This means that
11944 * if we're looking at the last halfword in the page we need to
11945 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11946 * or a 32-bit Thumb insn (which won't).
11947 * This is to avoid generating a silly TB with a single 16-bit insn
11948 * in it at the end of this page (which would execute correctly
11949 * but isn't very efficient).
11951 end_of_page = (dc->pc >= next_page_start) ||
11952 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
11954 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11955 !cs->singlestep_enabled &&
11956 !singlestep &&
11957 !dc->ss_active &&
11958 !end_of_page &&
11959 num_insns < max_insns);
11961 if (tb->cflags & CF_LAST_IO) {
11962 if (dc->condjmp) {
11963 /* FIXME: This can theoretically happen with self-modifying
11964 code. */
11965 cpu_abort(cs, "IO on conditional branch instruction");
11967 gen_io_end();
11970 /* At this stage dc->condjmp will only be set when the skipped
11971 instruction was a conditional branch or trap, and the PC has
11972 already been written. */
11973 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11974 /* Unconditional and "condition passed" instruction codepath. */
11975 gen_set_condexec(dc);
11976 switch (dc->is_jmp) {
11977 case DISAS_SWI:
11978 gen_ss_advance(dc);
11979 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11980 default_exception_el(dc));
11981 break;
11982 case DISAS_HVC:
11983 gen_ss_advance(dc);
11984 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11985 break;
11986 case DISAS_SMC:
11987 gen_ss_advance(dc);
11988 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11989 break;
11990 case DISAS_NEXT:
11991 case DISAS_UPDATE:
11992 gen_set_pc_im(dc, dc->pc);
11993 /* fall through */
11994 default:
11995 if (dc->ss_active) {
11996 gen_step_complete_exception(dc);
11997 } else {
11998 /* FIXME: Single stepping a WFI insn will not halt
11999 the CPU. */
12000 gen_exception_internal(EXCP_DEBUG);
12003 if (dc->condjmp) {
12004 /* "Condition failed" instruction codepath. */
12005 gen_set_label(dc->condlabel);
12006 gen_set_condexec(dc);
12007 gen_set_pc_im(dc, dc->pc);
12008 if (dc->ss_active) {
12009 gen_step_complete_exception(dc);
12010 } else {
12011 gen_exception_internal(EXCP_DEBUG);
12014 } else {
12015 /* While branches must always occur at the end of an IT block,
12016 there are a few other things that can cause us to terminate
12017 the TB in the middle of an IT block:
12018 - Exception generating instructions (bkpt, swi, undefined).
12019 - Page boundaries.
12020 - Hardware watchpoints.
12021 Hardware breakpoints have already been handled and skip this code.
12023 gen_set_condexec(dc);
12024 switch(dc->is_jmp) {
12025 case DISAS_NEXT:
12026 gen_goto_tb(dc, 1, dc->pc);
12027 break;
12028 case DISAS_UPDATE:
12029 gen_set_pc_im(dc, dc->pc);
12030 /* fall through */
12031 case DISAS_JUMP:
12032 default:
12033 /* indicate that the hash table must be used to find the next TB */
12034 tcg_gen_exit_tb(0);
12035 break;
12036 case DISAS_TB_JUMP:
12037 /* nothing more to generate */
12038 break;
12039 case DISAS_WFI:
12040 gen_helper_wfi(cpu_env);
12041 /* The helper doesn't necessarily throw an exception, but we
12042 * must go back to the main loop to check for interrupts anyway.
12044 tcg_gen_exit_tb(0);
12045 break;
12046 case DISAS_WFE:
12047 gen_helper_wfe(cpu_env);
12048 break;
12049 case DISAS_YIELD:
12050 gen_helper_yield(cpu_env);
12051 break;
12052 case DISAS_SWI:
12053 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12054 default_exception_el(dc));
12055 break;
12056 case DISAS_HVC:
12057 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12058 break;
12059 case DISAS_SMC:
12060 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12061 break;
12063 if (dc->condjmp) {
12064 gen_set_label(dc->condlabel);
12065 gen_set_condexec(dc);
12066 gen_goto_tb(dc, 1, dc->pc);
12067 dc->condjmp = 0;
12071 done_generating:
12072 gen_tb_end(tb, num_insns);
12074 #ifdef DEBUG_DISAS
12075 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
12076 qemu_log_in_addr_range(pc_start)) {
12077 qemu_log_lock();
12078 qemu_log("----------------\n");
12079 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12080 log_target_disas(cs, pc_start, dc->pc - pc_start,
12081 dc->thumb | (dc->sctlr_b << 1));
12082 qemu_log("\n");
12083 qemu_log_unlock();
12085 #endif
12086 tb->size = dc->pc - pc_start;
12087 tb->icount = num_insns;
12090 static const char *cpu_mode_names[16] = {
12091 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12092 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12095 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12096 int flags)
12098 ARMCPU *cpu = ARM_CPU(cs);
12099 CPUARMState *env = &cpu->env;
12100 int i;
12101 uint32_t psr;
12102 const char *ns_status;
12104 if (is_a64(env)) {
12105 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12106 return;
12109 for(i=0;i<16;i++) {
12110 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12111 if ((i % 4) == 3)
12112 cpu_fprintf(f, "\n");
12113 else
12114 cpu_fprintf(f, " ");
12116 psr = cpsr_read(env);
12118 if (arm_feature(env, ARM_FEATURE_EL3) &&
12119 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12120 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12121 } else {
12122 ns_status = "";
12125 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12126 psr,
12127 psr & (1 << 31) ? 'N' : '-',
12128 psr & (1 << 30) ? 'Z' : '-',
12129 psr & (1 << 29) ? 'C' : '-',
12130 psr & (1 << 28) ? 'V' : '-',
12131 psr & CPSR_T ? 'T' : 'A',
12132 ns_status,
12133 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12135 if (flags & CPU_DUMP_FPU) {
12136 int numvfpregs = 0;
12137 if (arm_feature(env, ARM_FEATURE_VFP)) {
12138 numvfpregs += 16;
12140 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12141 numvfpregs += 16;
12143 for (i = 0; i < numvfpregs; i++) {
12144 uint64_t v = float64_val(env->vfp.regs[i]);
12145 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12146 i * 2, (uint32_t)v,
12147 i * 2 + 1, (uint32_t)(v >> 32),
12148 i, v);
12150 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12154 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12155 target_ulong *data)
12157 if (is_a64(env)) {
12158 env->pc = data[0];
12159 env->condexec_bits = 0;
12160 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12161 } else {
12162 env->regs[15] = data[0];
12163 env->condexec_bits = data[1];
12164 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;