target/arm: use gen_goto_tb for ISB handling
[qemu/kevin.git] / target / arm / translate.c
blob75cdecacd76e901dc2dadeb91924f3726faee68c
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 int get_a32_user_mem_index(DisasContext *s)
150 /* Return the core 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 arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
160 case ARMMMUIdx_S1E3:
161 case ARMMMUIdx_S1SE0:
162 case ARMMMUIdx_S1SE1:
163 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
164 case ARMMMUIdx_MUser:
165 case ARMMMUIdx_MPriv:
166 case ARMMMUIdx_MNegPri:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_S2NS:
169 default:
170 g_assert_not_reached();
174 static inline TCGv_i32 load_cpu_offset(int offset)
176 TCGv_i32 tmp = tcg_temp_new_i32();
177 tcg_gen_ld_i32(tmp, cpu_env, offset);
178 return tmp;
181 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
183 static inline void store_cpu_offset(TCGv_i32 var, int offset)
185 tcg_gen_st_i32(var, cpu_env, offset);
186 tcg_temp_free_i32(var);
189 #define store_cpu_field(var, name) \
190 store_cpu_offset(var, offsetof(CPUARMState, name))
192 /* Set a variable to the value of a CPU register. */
193 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
195 if (reg == 15) {
196 uint32_t addr;
197 /* normally, since we updated PC, we need only to add one insn */
198 if (s->thumb)
199 addr = (long)s->pc + 2;
200 else
201 addr = (long)s->pc + 4;
202 tcg_gen_movi_i32(var, addr);
203 } else {
204 tcg_gen_mov_i32(var, cpu_R[reg]);
208 /* Create a new temporary and set it to the value of a CPU register. */
209 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
211 TCGv_i32 tmp = tcg_temp_new_i32();
212 load_reg_var(s, tmp, reg);
213 return tmp;
216 /* Set a CPU register. The source must be a temporary and will be
217 marked as dead. */
218 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
220 if (reg == 15) {
221 /* In Thumb mode, we must ignore bit 0.
222 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
223 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
224 * We choose to ignore [1:0] in ARM mode for all architecture versions.
226 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
227 s->is_jmp = DISAS_JUMP;
229 tcg_gen_mov_i32(cpu_R[reg], var);
230 tcg_temp_free_i32(var);
233 /* Value extensions. */
234 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
235 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
236 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
237 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
239 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
240 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
243 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
245 TCGv_i32 tmp_mask = tcg_const_i32(mask);
246 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
247 tcg_temp_free_i32(tmp_mask);
249 /* Set NZCV flags from the high 4 bits of var. */
250 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
252 static void gen_exception_internal(int excp)
254 TCGv_i32 tcg_excp = tcg_const_i32(excp);
256 assert(excp_is_internal(excp));
257 gen_helper_exception_internal(cpu_env, tcg_excp);
258 tcg_temp_free_i32(tcg_excp);
261 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
263 TCGv_i32 tcg_excp = tcg_const_i32(excp);
264 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
265 TCGv_i32 tcg_el = tcg_const_i32(target_el);
267 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
268 tcg_syn, tcg_el);
270 tcg_temp_free_i32(tcg_el);
271 tcg_temp_free_i32(tcg_syn);
272 tcg_temp_free_i32(tcg_excp);
275 static void gen_ss_advance(DisasContext *s)
277 /* If the singlestep state is Active-not-pending, advance to
278 * Active-pending.
280 if (s->ss_active) {
281 s->pstate_ss = 0;
282 gen_helper_clear_pstate_ss(cpu_env);
286 static void gen_step_complete_exception(DisasContext *s)
288 /* We just completed step of an insn. Move from Active-not-pending
289 * to Active-pending, and then also take the swstep exception.
290 * This corresponds to making the (IMPDEF) choice to prioritize
291 * swstep exceptions over asynchronous exceptions taken to an exception
292 * level where debug is disabled. This choice has the advantage that
293 * we do not need to maintain internal state corresponding to the
294 * ISV/EX syndrome bits between completion of the step and generation
295 * of the exception, and our syndrome information is always correct.
297 gen_ss_advance(s);
298 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
299 default_exception_el(s));
300 s->is_jmp = DISAS_EXC;
303 static void gen_singlestep_exception(DisasContext *s)
305 /* Generate the right kind of exception for singlestep, which is
306 * either the architectural singlestep or EXCP_DEBUG for QEMU's
307 * gdb singlestepping.
309 if (s->ss_active) {
310 gen_step_complete_exception(s);
311 } else {
312 gen_exception_internal(EXCP_DEBUG);
316 static inline bool is_singlestepping(DisasContext *s)
318 /* Return true if we are singlestepping either because of
319 * architectural singlestep or QEMU gdbstub singlestep. This does
320 * not include the command line '-singlestep' mode which is rather
321 * misnamed as it only means "one instruction per TB" and doesn't
322 * affect the code we generate.
324 return s->singlestep_enabled || s->ss_active;
327 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
329 TCGv_i32 tmp1 = tcg_temp_new_i32();
330 TCGv_i32 tmp2 = tcg_temp_new_i32();
331 tcg_gen_ext16s_i32(tmp1, a);
332 tcg_gen_ext16s_i32(tmp2, b);
333 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
334 tcg_temp_free_i32(tmp2);
335 tcg_gen_sari_i32(a, a, 16);
336 tcg_gen_sari_i32(b, b, 16);
337 tcg_gen_mul_i32(b, b, a);
338 tcg_gen_mov_i32(a, tmp1);
339 tcg_temp_free_i32(tmp1);
342 /* Byteswap each halfword. */
343 static void gen_rev16(TCGv_i32 var)
345 TCGv_i32 tmp = tcg_temp_new_i32();
346 tcg_gen_shri_i32(tmp, var, 8);
347 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
348 tcg_gen_shli_i32(var, var, 8);
349 tcg_gen_andi_i32(var, var, 0xff00ff00);
350 tcg_gen_or_i32(var, var, tmp);
351 tcg_temp_free_i32(tmp);
354 /* Byteswap low halfword and sign extend. */
355 static void gen_revsh(TCGv_i32 var)
357 tcg_gen_ext16u_i32(var, var);
358 tcg_gen_bswap16_i32(var, var);
359 tcg_gen_ext16s_i32(var, var);
362 /* Return (b << 32) + a. Mark inputs as dead */
363 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
365 TCGv_i64 tmp64 = tcg_temp_new_i64();
367 tcg_gen_extu_i32_i64(tmp64, b);
368 tcg_temp_free_i32(b);
369 tcg_gen_shli_i64(tmp64, tmp64, 32);
370 tcg_gen_add_i64(a, tmp64, a);
372 tcg_temp_free_i64(tmp64);
373 return a;
376 /* Return (b << 32) - a. Mark inputs as dead. */
377 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
379 TCGv_i64 tmp64 = tcg_temp_new_i64();
381 tcg_gen_extu_i32_i64(tmp64, b);
382 tcg_temp_free_i32(b);
383 tcg_gen_shli_i64(tmp64, tmp64, 32);
384 tcg_gen_sub_i64(a, tmp64, a);
386 tcg_temp_free_i64(tmp64);
387 return a;
390 /* 32x32->64 multiply. Marks inputs as dead. */
391 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
393 TCGv_i32 lo = tcg_temp_new_i32();
394 TCGv_i32 hi = tcg_temp_new_i32();
395 TCGv_i64 ret;
397 tcg_gen_mulu2_i32(lo, hi, a, b);
398 tcg_temp_free_i32(a);
399 tcg_temp_free_i32(b);
401 ret = tcg_temp_new_i64();
402 tcg_gen_concat_i32_i64(ret, lo, hi);
403 tcg_temp_free_i32(lo);
404 tcg_temp_free_i32(hi);
406 return ret;
409 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
411 TCGv_i32 lo = tcg_temp_new_i32();
412 TCGv_i32 hi = tcg_temp_new_i32();
413 TCGv_i64 ret;
415 tcg_gen_muls2_i32(lo, hi, a, b);
416 tcg_temp_free_i32(a);
417 tcg_temp_free_i32(b);
419 ret = tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret, lo, hi);
421 tcg_temp_free_i32(lo);
422 tcg_temp_free_i32(hi);
424 return ret;
427 /* Swap low and high halfwords. */
428 static void gen_swap_half(TCGv_i32 var)
430 TCGv_i32 tmp = tcg_temp_new_i32();
431 tcg_gen_shri_i32(tmp, var, 16);
432 tcg_gen_shli_i32(var, var, 16);
433 tcg_gen_or_i32(var, var, tmp);
434 tcg_temp_free_i32(tmp);
437 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
438 tmp = (t0 ^ t1) & 0x8000;
439 t0 &= ~0x8000;
440 t1 &= ~0x8000;
441 t0 = (t0 + t1) ^ tmp;
444 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
446 TCGv_i32 tmp = tcg_temp_new_i32();
447 tcg_gen_xor_i32(tmp, t0, t1);
448 tcg_gen_andi_i32(tmp, tmp, 0x8000);
449 tcg_gen_andi_i32(t0, t0, ~0x8000);
450 tcg_gen_andi_i32(t1, t1, ~0x8000);
451 tcg_gen_add_i32(t0, t0, t1);
452 tcg_gen_xor_i32(t0, t0, tmp);
453 tcg_temp_free_i32(tmp);
454 tcg_temp_free_i32(t1);
457 /* Set CF to the top bit of var. */
458 static void gen_set_CF_bit31(TCGv_i32 var)
460 tcg_gen_shri_i32(cpu_CF, var, 31);
463 /* Set N and Z flags from var. */
464 static inline void gen_logic_CC(TCGv_i32 var)
466 tcg_gen_mov_i32(cpu_NF, var);
467 tcg_gen_mov_i32(cpu_ZF, var);
470 /* T0 += T1 + CF. */
471 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
473 tcg_gen_add_i32(t0, t0, t1);
474 tcg_gen_add_i32(t0, t0, cpu_CF);
477 /* dest = T0 + T1 + CF. */
478 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
480 tcg_gen_add_i32(dest, t0, t1);
481 tcg_gen_add_i32(dest, dest, cpu_CF);
484 /* dest = T0 - T1 + CF - 1. */
485 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
487 tcg_gen_sub_i32(dest, t0, t1);
488 tcg_gen_add_i32(dest, dest, cpu_CF);
489 tcg_gen_subi_i32(dest, dest, 1);
492 /* dest = T0 + T1. Compute C, N, V and Z flags */
493 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
495 TCGv_i32 tmp = tcg_temp_new_i32();
496 tcg_gen_movi_i32(tmp, 0);
497 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
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 + CF. Compute C, N, V and Z flags */
507 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
509 TCGv_i32 tmp = tcg_temp_new_i32();
510 if (TCG_TARGET_HAS_add2_i32) {
511 tcg_gen_movi_i32(tmp, 0);
512 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
513 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
514 } else {
515 TCGv_i64 q0 = tcg_temp_new_i64();
516 TCGv_i64 q1 = tcg_temp_new_i64();
517 tcg_gen_extu_i32_i64(q0, t0);
518 tcg_gen_extu_i32_i64(q1, t1);
519 tcg_gen_add_i64(q0, q0, q1);
520 tcg_gen_extu_i32_i64(q1, cpu_CF);
521 tcg_gen_add_i64(q0, q0, q1);
522 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
523 tcg_temp_free_i64(q0);
524 tcg_temp_free_i64(q1);
526 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
527 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
528 tcg_gen_xor_i32(tmp, t0, t1);
529 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
530 tcg_temp_free_i32(tmp);
531 tcg_gen_mov_i32(dest, cpu_NF);
534 /* dest = T0 - T1. Compute C, N, V and Z flags */
535 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
537 TCGv_i32 tmp;
538 tcg_gen_sub_i32(cpu_NF, t0, t1);
539 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
540 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
541 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
542 tmp = tcg_temp_new_i32();
543 tcg_gen_xor_i32(tmp, t0, t1);
544 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
545 tcg_temp_free_i32(tmp);
546 tcg_gen_mov_i32(dest, cpu_NF);
549 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
550 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
552 TCGv_i32 tmp = tcg_temp_new_i32();
553 tcg_gen_not_i32(tmp, t1);
554 gen_adc_CC(dest, t0, tmp);
555 tcg_temp_free_i32(tmp);
558 #define GEN_SHIFT(name) \
559 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
561 TCGv_i32 tmp1, tmp2, tmp3; \
562 tmp1 = tcg_temp_new_i32(); \
563 tcg_gen_andi_i32(tmp1, t1, 0xff); \
564 tmp2 = tcg_const_i32(0); \
565 tmp3 = tcg_const_i32(0x1f); \
566 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
567 tcg_temp_free_i32(tmp3); \
568 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
569 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
570 tcg_temp_free_i32(tmp2); \
571 tcg_temp_free_i32(tmp1); \
573 GEN_SHIFT(shl)
574 GEN_SHIFT(shr)
575 #undef GEN_SHIFT
577 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
579 TCGv_i32 tmp1, tmp2;
580 tmp1 = tcg_temp_new_i32();
581 tcg_gen_andi_i32(tmp1, t1, 0xff);
582 tmp2 = tcg_const_i32(0x1f);
583 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
584 tcg_temp_free_i32(tmp2);
585 tcg_gen_sar_i32(dest, t0, tmp1);
586 tcg_temp_free_i32(tmp1);
589 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
591 TCGv_i32 c0 = tcg_const_i32(0);
592 TCGv_i32 tmp = tcg_temp_new_i32();
593 tcg_gen_neg_i32(tmp, src);
594 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
595 tcg_temp_free_i32(c0);
596 tcg_temp_free_i32(tmp);
599 static void shifter_out_im(TCGv_i32 var, int shift)
601 if (shift == 0) {
602 tcg_gen_andi_i32(cpu_CF, var, 1);
603 } else {
604 tcg_gen_shri_i32(cpu_CF, var, shift);
605 if (shift != 31) {
606 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
611 /* Shift by immediate. Includes special handling for shift == 0. */
612 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
613 int shift, int flags)
615 switch (shiftop) {
616 case 0: /* LSL */
617 if (shift != 0) {
618 if (flags)
619 shifter_out_im(var, 32 - shift);
620 tcg_gen_shli_i32(var, var, shift);
622 break;
623 case 1: /* LSR */
624 if (shift == 0) {
625 if (flags) {
626 tcg_gen_shri_i32(cpu_CF, var, 31);
628 tcg_gen_movi_i32(var, 0);
629 } else {
630 if (flags)
631 shifter_out_im(var, shift - 1);
632 tcg_gen_shri_i32(var, var, shift);
634 break;
635 case 2: /* ASR */
636 if (shift == 0)
637 shift = 32;
638 if (flags)
639 shifter_out_im(var, shift - 1);
640 if (shift == 32)
641 shift = 31;
642 tcg_gen_sari_i32(var, var, shift);
643 break;
644 case 3: /* ROR/RRX */
645 if (shift != 0) {
646 if (flags)
647 shifter_out_im(var, shift - 1);
648 tcg_gen_rotri_i32(var, var, shift); break;
649 } else {
650 TCGv_i32 tmp = tcg_temp_new_i32();
651 tcg_gen_shli_i32(tmp, cpu_CF, 31);
652 if (flags)
653 shifter_out_im(var, 0);
654 tcg_gen_shri_i32(var, var, 1);
655 tcg_gen_or_i32(var, var, tmp);
656 tcg_temp_free_i32(tmp);
661 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
662 TCGv_i32 shift, int flags)
664 if (flags) {
665 switch (shiftop) {
666 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
667 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
668 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
669 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
671 } else {
672 switch (shiftop) {
673 case 0:
674 gen_shl(var, var, shift);
675 break;
676 case 1:
677 gen_shr(var, var, shift);
678 break;
679 case 2:
680 gen_sar(var, var, shift);
681 break;
682 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
683 tcg_gen_rotr_i32(var, var, shift); break;
686 tcg_temp_free_i32(shift);
689 #define PAS_OP(pfx) \
690 switch (op2) { \
691 case 0: gen_pas_helper(glue(pfx,add16)); break; \
692 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
693 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
694 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
695 case 4: gen_pas_helper(glue(pfx,add8)); break; \
696 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
698 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
700 TCGv_ptr tmp;
702 switch (op1) {
703 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
704 case 1:
705 tmp = tcg_temp_new_ptr();
706 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
707 PAS_OP(s)
708 tcg_temp_free_ptr(tmp);
709 break;
710 case 5:
711 tmp = tcg_temp_new_ptr();
712 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
713 PAS_OP(u)
714 tcg_temp_free_ptr(tmp);
715 break;
716 #undef gen_pas_helper
717 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
718 case 2:
719 PAS_OP(q);
720 break;
721 case 3:
722 PAS_OP(sh);
723 break;
724 case 6:
725 PAS_OP(uq);
726 break;
727 case 7:
728 PAS_OP(uh);
729 break;
730 #undef gen_pas_helper
733 #undef PAS_OP
735 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
736 #define PAS_OP(pfx) \
737 switch (op1) { \
738 case 0: gen_pas_helper(glue(pfx,add8)); break; \
739 case 1: gen_pas_helper(glue(pfx,add16)); break; \
740 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
741 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
742 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
743 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
745 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
747 TCGv_ptr tmp;
749 switch (op2) {
750 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
751 case 0:
752 tmp = tcg_temp_new_ptr();
753 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
754 PAS_OP(s)
755 tcg_temp_free_ptr(tmp);
756 break;
757 case 4:
758 tmp = tcg_temp_new_ptr();
759 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
760 PAS_OP(u)
761 tcg_temp_free_ptr(tmp);
762 break;
763 #undef gen_pas_helper
764 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
765 case 1:
766 PAS_OP(q);
767 break;
768 case 2:
769 PAS_OP(sh);
770 break;
771 case 5:
772 PAS_OP(uq);
773 break;
774 case 6:
775 PAS_OP(uh);
776 break;
777 #undef gen_pas_helper
780 #undef PAS_OP
783 * Generate a conditional based on ARM condition code cc.
784 * This is common between ARM and Aarch64 targets.
786 void arm_test_cc(DisasCompare *cmp, int cc)
788 TCGv_i32 value;
789 TCGCond cond;
790 bool global = true;
792 switch (cc) {
793 case 0: /* eq: Z */
794 case 1: /* ne: !Z */
795 cond = TCG_COND_EQ;
796 value = cpu_ZF;
797 break;
799 case 2: /* cs: C */
800 case 3: /* cc: !C */
801 cond = TCG_COND_NE;
802 value = cpu_CF;
803 break;
805 case 4: /* mi: N */
806 case 5: /* pl: !N */
807 cond = TCG_COND_LT;
808 value = cpu_NF;
809 break;
811 case 6: /* vs: V */
812 case 7: /* vc: !V */
813 cond = TCG_COND_LT;
814 value = cpu_VF;
815 break;
817 case 8: /* hi: C && !Z */
818 case 9: /* ls: !C || Z -> !(C && !Z) */
819 cond = TCG_COND_NE;
820 value = tcg_temp_new_i32();
821 global = false;
822 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
823 ZF is non-zero for !Z; so AND the two subexpressions. */
824 tcg_gen_neg_i32(value, cpu_CF);
825 tcg_gen_and_i32(value, value, cpu_ZF);
826 break;
828 case 10: /* ge: N == V -> N ^ V == 0 */
829 case 11: /* lt: N != V -> N ^ V != 0 */
830 /* Since we're only interested in the sign bit, == 0 is >= 0. */
831 cond = TCG_COND_GE;
832 value = tcg_temp_new_i32();
833 global = false;
834 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
835 break;
837 case 12: /* gt: !Z && N == V */
838 case 13: /* le: Z || N != V */
839 cond = TCG_COND_NE;
840 value = tcg_temp_new_i32();
841 global = false;
842 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
843 * the sign bit then AND with ZF to yield the result. */
844 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
845 tcg_gen_sari_i32(value, value, 31);
846 tcg_gen_andc_i32(value, cpu_ZF, value);
847 break;
849 case 14: /* always */
850 case 15: /* always */
851 /* Use the ALWAYS condition, which will fold early.
852 * It doesn't matter what we use for the value. */
853 cond = TCG_COND_ALWAYS;
854 value = cpu_ZF;
855 goto no_invert;
857 default:
858 fprintf(stderr, "Bad condition code 0x%x\n", cc);
859 abort();
862 if (cc & 1) {
863 cond = tcg_invert_cond(cond);
866 no_invert:
867 cmp->cond = cond;
868 cmp->value = value;
869 cmp->value_global = global;
872 void arm_free_cc(DisasCompare *cmp)
874 if (!cmp->value_global) {
875 tcg_temp_free_i32(cmp->value);
879 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
881 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
884 void arm_gen_test_cc(int cc, TCGLabel *label)
886 DisasCompare cmp;
887 arm_test_cc(&cmp, cc);
888 arm_jump_cc(&cmp, label);
889 arm_free_cc(&cmp);
892 static const uint8_t table_logic_cc[16] = {
893 1, /* and */
894 1, /* xor */
895 0, /* sub */
896 0, /* rsb */
897 0, /* add */
898 0, /* adc */
899 0, /* sbc */
900 0, /* rsc */
901 1, /* andl */
902 1, /* xorl */
903 0, /* cmp */
904 0, /* cmn */
905 1, /* orr */
906 1, /* mov */
907 1, /* bic */
908 1, /* mvn */
911 static inline void gen_set_condexec(DisasContext *s)
913 if (s->condexec_mask) {
914 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
915 TCGv_i32 tmp = tcg_temp_new_i32();
916 tcg_gen_movi_i32(tmp, val);
917 store_cpu_field(tmp, condexec_bits);
921 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
923 tcg_gen_movi_i32(cpu_R[15], val);
926 /* Set PC and Thumb state from an immediate address. */
927 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
929 TCGv_i32 tmp;
931 s->is_jmp = DISAS_JUMP;
932 if (s->thumb != (addr & 1)) {
933 tmp = tcg_temp_new_i32();
934 tcg_gen_movi_i32(tmp, addr & 1);
935 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
936 tcg_temp_free_i32(tmp);
938 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
941 /* Set PC and Thumb state from var. var is marked as dead. */
942 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
944 s->is_jmp = DISAS_JUMP;
945 tcg_gen_andi_i32(cpu_R[15], var, ~1);
946 tcg_gen_andi_i32(var, var, 1);
947 store_cpu_field(var, thumb);
950 /* Set PC and Thumb state from var. var is marked as dead.
951 * For M-profile CPUs, include logic to detect exception-return
952 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
953 * and BX reg, and no others, and happens only for code in Handler mode.
955 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
957 /* Generate the same code here as for a simple bx, but flag via
958 * s->is_jmp that we need to do the rest of the work later.
960 gen_bx(s, var);
961 if (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M)) {
962 s->is_jmp = DISAS_BX_EXCRET;
966 static inline void gen_bx_excret_final_code(DisasContext *s)
968 /* Generate the code to finish possible exception return and end the TB */
969 TCGLabel *excret_label = gen_new_label();
971 /* Is the new PC value in the magic range indicating exception return? */
972 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], 0xff000000, excret_label);
973 /* No: end the TB as we would for a DISAS_JMP */
974 if (is_singlestepping(s)) {
975 gen_singlestep_exception(s);
976 } else {
977 tcg_gen_exit_tb(0);
979 gen_set_label(excret_label);
980 /* Yes: this is an exception return.
981 * At this point in runtime env->regs[15] and env->thumb will hold
982 * the exception-return magic number, which do_v7m_exception_exit()
983 * will read. Nothing else will be able to see those values because
984 * the cpu-exec main loop guarantees that we will always go straight
985 * from raising the exception to the exception-handling code.
987 * gen_ss_advance(s) does nothing on M profile currently but
988 * calling it is conceptually the right thing as we have executed
989 * this instruction (compare SWI, HVC, SMC handling).
991 gen_ss_advance(s);
992 gen_exception_internal(EXCP_EXCEPTION_EXIT);
995 /* Variant of store_reg which uses branch&exchange logic when storing
996 to r15 in ARM architecture v7 and above. The source must be a temporary
997 and will be marked as dead. */
998 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1000 if (reg == 15 && ENABLE_ARCH_7) {
1001 gen_bx(s, var);
1002 } else {
1003 store_reg(s, reg, var);
1007 /* Variant of store_reg which uses branch&exchange logic when storing
1008 * to r15 in ARM architecture v5T and above. This is used for storing
1009 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1010 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1011 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1013 if (reg == 15 && ENABLE_ARCH_5) {
1014 gen_bx_excret(s, var);
1015 } else {
1016 store_reg(s, reg, var);
1020 #ifdef CONFIG_USER_ONLY
1021 #define IS_USER_ONLY 1
1022 #else
1023 #define IS_USER_ONLY 0
1024 #endif
1026 /* Abstractions of "generate code to do a guest load/store for
1027 * AArch32", where a vaddr is always 32 bits (and is zero
1028 * extended if we're a 64 bit core) and data is also
1029 * 32 bits unless specifically doing a 64 bit access.
1030 * These functions work like tcg_gen_qemu_{ld,st}* except
1031 * that the address argument is TCGv_i32 rather than TCGv.
1034 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1036 TCGv addr = tcg_temp_new();
1037 tcg_gen_extu_i32_tl(addr, a32);
1039 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1040 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1041 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1043 return addr;
1046 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1047 int index, TCGMemOp opc)
1049 TCGv addr = gen_aa32_addr(s, a32, opc);
1050 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1051 tcg_temp_free(addr);
1054 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1055 int index, TCGMemOp opc)
1057 TCGv addr = gen_aa32_addr(s, a32, opc);
1058 tcg_gen_qemu_st_i32(val, addr, index, opc);
1059 tcg_temp_free(addr);
1062 #define DO_GEN_LD(SUFF, OPC) \
1063 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1064 TCGv_i32 a32, int index) \
1066 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1068 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1069 TCGv_i32 val, \
1070 TCGv_i32 a32, int index, \
1071 ISSInfo issinfo) \
1073 gen_aa32_ld##SUFF(s, val, a32, index); \
1074 disas_set_da_iss(s, OPC, issinfo); \
1077 #define DO_GEN_ST(SUFF, OPC) \
1078 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1079 TCGv_i32 a32, int index) \
1081 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1083 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1084 TCGv_i32 val, \
1085 TCGv_i32 a32, int index, \
1086 ISSInfo issinfo) \
1088 gen_aa32_st##SUFF(s, val, a32, index); \
1089 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1092 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1094 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1095 if (!IS_USER_ONLY && s->sctlr_b) {
1096 tcg_gen_rotri_i64(val, val, 32);
1100 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1101 int index, TCGMemOp opc)
1103 TCGv addr = gen_aa32_addr(s, a32, opc);
1104 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1105 gen_aa32_frob64(s, val);
1106 tcg_temp_free(addr);
1109 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1110 TCGv_i32 a32, int index)
1112 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1115 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1116 int index, TCGMemOp opc)
1118 TCGv addr = gen_aa32_addr(s, a32, opc);
1120 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1121 if (!IS_USER_ONLY && s->sctlr_b) {
1122 TCGv_i64 tmp = tcg_temp_new_i64();
1123 tcg_gen_rotri_i64(tmp, val, 32);
1124 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1125 tcg_temp_free_i64(tmp);
1126 } else {
1127 tcg_gen_qemu_st_i64(val, addr, index, opc);
1129 tcg_temp_free(addr);
1132 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1133 TCGv_i32 a32, int index)
1135 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1138 DO_GEN_LD(8s, MO_SB)
1139 DO_GEN_LD(8u, MO_UB)
1140 DO_GEN_LD(16s, MO_SW)
1141 DO_GEN_LD(16u, MO_UW)
1142 DO_GEN_LD(32u, MO_UL)
1143 DO_GEN_ST(8, MO_UB)
1144 DO_GEN_ST(16, MO_UW)
1145 DO_GEN_ST(32, MO_UL)
1147 static inline void gen_hvc(DisasContext *s, int imm16)
1149 /* The pre HVC helper handles cases when HVC gets trapped
1150 * as an undefined insn by runtime configuration (ie before
1151 * the insn really executes).
1153 gen_set_pc_im(s, s->pc - 4);
1154 gen_helper_pre_hvc(cpu_env);
1155 /* Otherwise we will treat this as a real exception which
1156 * happens after execution of the insn. (The distinction matters
1157 * for the PC value reported to the exception handler and also
1158 * for single stepping.)
1160 s->svc_imm = imm16;
1161 gen_set_pc_im(s, s->pc);
1162 s->is_jmp = DISAS_HVC;
1165 static inline void gen_smc(DisasContext *s)
1167 /* As with HVC, we may take an exception either before or after
1168 * the insn executes.
1170 TCGv_i32 tmp;
1172 gen_set_pc_im(s, s->pc - 4);
1173 tmp = tcg_const_i32(syn_aa32_smc());
1174 gen_helper_pre_smc(cpu_env, tmp);
1175 tcg_temp_free_i32(tmp);
1176 gen_set_pc_im(s, s->pc);
1177 s->is_jmp = DISAS_SMC;
1180 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1182 gen_set_condexec(s);
1183 gen_set_pc_im(s, s->pc - offset);
1184 gen_exception_internal(excp);
1185 s->is_jmp = DISAS_EXC;
1188 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1189 int syn, uint32_t target_el)
1191 gen_set_condexec(s);
1192 gen_set_pc_im(s, s->pc - offset);
1193 gen_exception(excp, syn, target_el);
1194 s->is_jmp = DISAS_EXC;
1197 /* Force a TB lookup after an instruction that changes the CPU state. */
1198 static inline void gen_lookup_tb(DisasContext *s)
1200 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1201 s->is_jmp = DISAS_EXIT;
1204 static inline void gen_hlt(DisasContext *s, int imm)
1206 /* HLT. This has two purposes.
1207 * Architecturally, it is an external halting debug instruction.
1208 * Since QEMU doesn't implement external debug, we treat this as
1209 * it is required for halting debug disabled: it will UNDEF.
1210 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1211 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1212 * must trigger semihosting even for ARMv7 and earlier, where
1213 * HLT was an undefined encoding.
1214 * In system mode, we don't allow userspace access to
1215 * semihosting, to provide some semblance of security
1216 * (and for consistency with our 32-bit semihosting).
1218 if (semihosting_enabled() &&
1219 #ifndef CONFIG_USER_ONLY
1220 s->current_el != 0 &&
1221 #endif
1222 (imm == (s->thumb ? 0x3c : 0xf000))) {
1223 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1224 return;
1227 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1228 default_exception_el(s));
1231 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1232 TCGv_i32 var)
1234 int val, rm, shift, shiftop;
1235 TCGv_i32 offset;
1237 if (!(insn & (1 << 25))) {
1238 /* immediate */
1239 val = insn & 0xfff;
1240 if (!(insn & (1 << 23)))
1241 val = -val;
1242 if (val != 0)
1243 tcg_gen_addi_i32(var, var, val);
1244 } else {
1245 /* shift/register */
1246 rm = (insn) & 0xf;
1247 shift = (insn >> 7) & 0x1f;
1248 shiftop = (insn >> 5) & 3;
1249 offset = load_reg(s, rm);
1250 gen_arm_shift_im(offset, shiftop, shift, 0);
1251 if (!(insn & (1 << 23)))
1252 tcg_gen_sub_i32(var, var, offset);
1253 else
1254 tcg_gen_add_i32(var, var, offset);
1255 tcg_temp_free_i32(offset);
1259 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1260 int extra, TCGv_i32 var)
1262 int val, rm;
1263 TCGv_i32 offset;
1265 if (insn & (1 << 22)) {
1266 /* immediate */
1267 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1268 if (!(insn & (1 << 23)))
1269 val = -val;
1270 val += extra;
1271 if (val != 0)
1272 tcg_gen_addi_i32(var, var, val);
1273 } else {
1274 /* register */
1275 if (extra)
1276 tcg_gen_addi_i32(var, var, extra);
1277 rm = (insn) & 0xf;
1278 offset = load_reg(s, rm);
1279 if (!(insn & (1 << 23)))
1280 tcg_gen_sub_i32(var, var, offset);
1281 else
1282 tcg_gen_add_i32(var, var, offset);
1283 tcg_temp_free_i32(offset);
1287 static TCGv_ptr get_fpstatus_ptr(int neon)
1289 TCGv_ptr statusptr = tcg_temp_new_ptr();
1290 int offset;
1291 if (neon) {
1292 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1293 } else {
1294 offset = offsetof(CPUARMState, vfp.fp_status);
1296 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1297 return statusptr;
1300 #define VFP_OP2(name) \
1301 static inline void gen_vfp_##name(int dp) \
1303 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1304 if (dp) { \
1305 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1306 } else { \
1307 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1309 tcg_temp_free_ptr(fpst); \
1312 VFP_OP2(add)
1313 VFP_OP2(sub)
1314 VFP_OP2(mul)
1315 VFP_OP2(div)
1317 #undef VFP_OP2
1319 static inline void gen_vfp_F1_mul(int dp)
1321 /* Like gen_vfp_mul() but put result in F1 */
1322 TCGv_ptr fpst = get_fpstatus_ptr(0);
1323 if (dp) {
1324 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1325 } else {
1326 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1328 tcg_temp_free_ptr(fpst);
1331 static inline void gen_vfp_F1_neg(int dp)
1333 /* Like gen_vfp_neg() but put result in F1 */
1334 if (dp) {
1335 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1336 } else {
1337 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1341 static inline void gen_vfp_abs(int dp)
1343 if (dp)
1344 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1345 else
1346 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1349 static inline void gen_vfp_neg(int dp)
1351 if (dp)
1352 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1353 else
1354 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1357 static inline void gen_vfp_sqrt(int dp)
1359 if (dp)
1360 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1361 else
1362 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1365 static inline void gen_vfp_cmp(int dp)
1367 if (dp)
1368 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1369 else
1370 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1373 static inline void gen_vfp_cmpe(int dp)
1375 if (dp)
1376 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1377 else
1378 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1381 static inline void gen_vfp_F1_ld0(int dp)
1383 if (dp)
1384 tcg_gen_movi_i64(cpu_F1d, 0);
1385 else
1386 tcg_gen_movi_i32(cpu_F1s, 0);
1389 #define VFP_GEN_ITOF(name) \
1390 static inline void gen_vfp_##name(int dp, int neon) \
1392 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1393 if (dp) { \
1394 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1395 } else { \
1396 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1398 tcg_temp_free_ptr(statusptr); \
1401 VFP_GEN_ITOF(uito)
1402 VFP_GEN_ITOF(sito)
1403 #undef VFP_GEN_ITOF
1405 #define VFP_GEN_FTOI(name) \
1406 static inline void gen_vfp_##name(int dp, int neon) \
1408 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1409 if (dp) { \
1410 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1411 } else { \
1412 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1414 tcg_temp_free_ptr(statusptr); \
1417 VFP_GEN_FTOI(toui)
1418 VFP_GEN_FTOI(touiz)
1419 VFP_GEN_FTOI(tosi)
1420 VFP_GEN_FTOI(tosiz)
1421 #undef VFP_GEN_FTOI
1423 #define VFP_GEN_FIX(name, round) \
1424 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1426 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1427 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1428 if (dp) { \
1429 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1430 statusptr); \
1431 } else { \
1432 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1433 statusptr); \
1435 tcg_temp_free_i32(tmp_shift); \
1436 tcg_temp_free_ptr(statusptr); \
1438 VFP_GEN_FIX(tosh, _round_to_zero)
1439 VFP_GEN_FIX(tosl, _round_to_zero)
1440 VFP_GEN_FIX(touh, _round_to_zero)
1441 VFP_GEN_FIX(toul, _round_to_zero)
1442 VFP_GEN_FIX(shto, )
1443 VFP_GEN_FIX(slto, )
1444 VFP_GEN_FIX(uhto, )
1445 VFP_GEN_FIX(ulto, )
1446 #undef VFP_GEN_FIX
1448 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1450 if (dp) {
1451 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1452 } else {
1453 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1457 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1459 if (dp) {
1460 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1461 } else {
1462 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1466 static inline long
1467 vfp_reg_offset (int dp, int reg)
1469 if (dp)
1470 return offsetof(CPUARMState, vfp.regs[reg]);
1471 else if (reg & 1) {
1472 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1473 + offsetof(CPU_DoubleU, l.upper);
1474 } else {
1475 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1476 + offsetof(CPU_DoubleU, l.lower);
1480 /* Return the offset of a 32-bit piece of a NEON register.
1481 zero is the least significant end of the register. */
1482 static inline long
1483 neon_reg_offset (int reg, int n)
1485 int sreg;
1486 sreg = reg * 2 + n;
1487 return vfp_reg_offset(0, sreg);
1490 static TCGv_i32 neon_load_reg(int reg, int pass)
1492 TCGv_i32 tmp = tcg_temp_new_i32();
1493 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1494 return tmp;
1497 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1499 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1500 tcg_temp_free_i32(var);
1503 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1505 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1508 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1510 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1513 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1514 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1515 #define tcg_gen_st_f32 tcg_gen_st_i32
1516 #define tcg_gen_st_f64 tcg_gen_st_i64
1518 static inline void gen_mov_F0_vreg(int dp, int reg)
1520 if (dp)
1521 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1522 else
1523 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1526 static inline void gen_mov_F1_vreg(int dp, int reg)
1528 if (dp)
1529 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1530 else
1531 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1534 static inline void gen_mov_vreg_F0(int dp, int reg)
1536 if (dp)
1537 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1538 else
1539 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1542 #define ARM_CP_RW_BIT (1 << 20)
1544 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1546 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1549 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1551 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1554 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1556 TCGv_i32 var = tcg_temp_new_i32();
1557 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1558 return var;
1561 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1563 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1564 tcg_temp_free_i32(var);
1567 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1569 iwmmxt_store_reg(cpu_M0, rn);
1572 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1574 iwmmxt_load_reg(cpu_M0, rn);
1577 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1579 iwmmxt_load_reg(cpu_V1, rn);
1580 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1583 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1585 iwmmxt_load_reg(cpu_V1, rn);
1586 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1589 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1591 iwmmxt_load_reg(cpu_V1, rn);
1592 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1595 #define IWMMXT_OP(name) \
1596 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1598 iwmmxt_load_reg(cpu_V1, rn); \
1599 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1602 #define IWMMXT_OP_ENV(name) \
1603 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1605 iwmmxt_load_reg(cpu_V1, rn); \
1606 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1609 #define IWMMXT_OP_ENV_SIZE(name) \
1610 IWMMXT_OP_ENV(name##b) \
1611 IWMMXT_OP_ENV(name##w) \
1612 IWMMXT_OP_ENV(name##l)
1614 #define IWMMXT_OP_ENV1(name) \
1615 static inline void gen_op_iwmmxt_##name##_M0(void) \
1617 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1620 IWMMXT_OP(maddsq)
1621 IWMMXT_OP(madduq)
1622 IWMMXT_OP(sadb)
1623 IWMMXT_OP(sadw)
1624 IWMMXT_OP(mulslw)
1625 IWMMXT_OP(mulshw)
1626 IWMMXT_OP(mululw)
1627 IWMMXT_OP(muluhw)
1628 IWMMXT_OP(macsw)
1629 IWMMXT_OP(macuw)
1631 IWMMXT_OP_ENV_SIZE(unpackl)
1632 IWMMXT_OP_ENV_SIZE(unpackh)
1634 IWMMXT_OP_ENV1(unpacklub)
1635 IWMMXT_OP_ENV1(unpackluw)
1636 IWMMXT_OP_ENV1(unpacklul)
1637 IWMMXT_OP_ENV1(unpackhub)
1638 IWMMXT_OP_ENV1(unpackhuw)
1639 IWMMXT_OP_ENV1(unpackhul)
1640 IWMMXT_OP_ENV1(unpacklsb)
1641 IWMMXT_OP_ENV1(unpacklsw)
1642 IWMMXT_OP_ENV1(unpacklsl)
1643 IWMMXT_OP_ENV1(unpackhsb)
1644 IWMMXT_OP_ENV1(unpackhsw)
1645 IWMMXT_OP_ENV1(unpackhsl)
1647 IWMMXT_OP_ENV_SIZE(cmpeq)
1648 IWMMXT_OP_ENV_SIZE(cmpgtu)
1649 IWMMXT_OP_ENV_SIZE(cmpgts)
1651 IWMMXT_OP_ENV_SIZE(mins)
1652 IWMMXT_OP_ENV_SIZE(minu)
1653 IWMMXT_OP_ENV_SIZE(maxs)
1654 IWMMXT_OP_ENV_SIZE(maxu)
1656 IWMMXT_OP_ENV_SIZE(subn)
1657 IWMMXT_OP_ENV_SIZE(addn)
1658 IWMMXT_OP_ENV_SIZE(subu)
1659 IWMMXT_OP_ENV_SIZE(addu)
1660 IWMMXT_OP_ENV_SIZE(subs)
1661 IWMMXT_OP_ENV_SIZE(adds)
1663 IWMMXT_OP_ENV(avgb0)
1664 IWMMXT_OP_ENV(avgb1)
1665 IWMMXT_OP_ENV(avgw0)
1666 IWMMXT_OP_ENV(avgw1)
1668 IWMMXT_OP_ENV(packuw)
1669 IWMMXT_OP_ENV(packul)
1670 IWMMXT_OP_ENV(packuq)
1671 IWMMXT_OP_ENV(packsw)
1672 IWMMXT_OP_ENV(packsl)
1673 IWMMXT_OP_ENV(packsq)
1675 static void gen_op_iwmmxt_set_mup(void)
1677 TCGv_i32 tmp;
1678 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1679 tcg_gen_ori_i32(tmp, tmp, 2);
1680 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1683 static void gen_op_iwmmxt_set_cup(void)
1685 TCGv_i32 tmp;
1686 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1687 tcg_gen_ori_i32(tmp, tmp, 1);
1688 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1691 static void gen_op_iwmmxt_setpsr_nz(void)
1693 TCGv_i32 tmp = tcg_temp_new_i32();
1694 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1695 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1698 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1700 iwmmxt_load_reg(cpu_V1, rn);
1701 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1702 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1705 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1706 TCGv_i32 dest)
1708 int rd;
1709 uint32_t offset;
1710 TCGv_i32 tmp;
1712 rd = (insn >> 16) & 0xf;
1713 tmp = load_reg(s, rd);
1715 offset = (insn & 0xff) << ((insn >> 7) & 2);
1716 if (insn & (1 << 24)) {
1717 /* Pre indexed */
1718 if (insn & (1 << 23))
1719 tcg_gen_addi_i32(tmp, tmp, offset);
1720 else
1721 tcg_gen_addi_i32(tmp, tmp, -offset);
1722 tcg_gen_mov_i32(dest, tmp);
1723 if (insn & (1 << 21))
1724 store_reg(s, rd, tmp);
1725 else
1726 tcg_temp_free_i32(tmp);
1727 } else if (insn & (1 << 21)) {
1728 /* Post indexed */
1729 tcg_gen_mov_i32(dest, tmp);
1730 if (insn & (1 << 23))
1731 tcg_gen_addi_i32(tmp, tmp, offset);
1732 else
1733 tcg_gen_addi_i32(tmp, tmp, -offset);
1734 store_reg(s, rd, tmp);
1735 } else if (!(insn & (1 << 23)))
1736 return 1;
1737 return 0;
1740 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1742 int rd = (insn >> 0) & 0xf;
1743 TCGv_i32 tmp;
1745 if (insn & (1 << 8)) {
1746 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1747 return 1;
1748 } else {
1749 tmp = iwmmxt_load_creg(rd);
1751 } else {
1752 tmp = tcg_temp_new_i32();
1753 iwmmxt_load_reg(cpu_V0, rd);
1754 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1756 tcg_gen_andi_i32(tmp, tmp, mask);
1757 tcg_gen_mov_i32(dest, tmp);
1758 tcg_temp_free_i32(tmp);
1759 return 0;
1762 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1763 (ie. an undefined instruction). */
1764 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1766 int rd, wrd;
1767 int rdhi, rdlo, rd0, rd1, i;
1768 TCGv_i32 addr;
1769 TCGv_i32 tmp, tmp2, tmp3;
1771 if ((insn & 0x0e000e00) == 0x0c000000) {
1772 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1773 wrd = insn & 0xf;
1774 rdlo = (insn >> 12) & 0xf;
1775 rdhi = (insn >> 16) & 0xf;
1776 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1777 iwmmxt_load_reg(cpu_V0, wrd);
1778 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1779 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1780 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1781 } else { /* TMCRR */
1782 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1783 iwmmxt_store_reg(cpu_V0, wrd);
1784 gen_op_iwmmxt_set_mup();
1786 return 0;
1789 wrd = (insn >> 12) & 0xf;
1790 addr = tcg_temp_new_i32();
1791 if (gen_iwmmxt_address(s, insn, addr)) {
1792 tcg_temp_free_i32(addr);
1793 return 1;
1795 if (insn & ARM_CP_RW_BIT) {
1796 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1797 tmp = tcg_temp_new_i32();
1798 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1799 iwmmxt_store_creg(wrd, tmp);
1800 } else {
1801 i = 1;
1802 if (insn & (1 << 8)) {
1803 if (insn & (1 << 22)) { /* WLDRD */
1804 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1805 i = 0;
1806 } else { /* WLDRW wRd */
1807 tmp = tcg_temp_new_i32();
1808 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1810 } else {
1811 tmp = tcg_temp_new_i32();
1812 if (insn & (1 << 22)) { /* WLDRH */
1813 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1814 } else { /* WLDRB */
1815 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1818 if (i) {
1819 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1820 tcg_temp_free_i32(tmp);
1822 gen_op_iwmmxt_movq_wRn_M0(wrd);
1824 } else {
1825 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1826 tmp = iwmmxt_load_creg(wrd);
1827 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1828 } else {
1829 gen_op_iwmmxt_movq_M0_wRn(wrd);
1830 tmp = tcg_temp_new_i32();
1831 if (insn & (1 << 8)) {
1832 if (insn & (1 << 22)) { /* WSTRD */
1833 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1834 } else { /* WSTRW wRd */
1835 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1836 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1838 } else {
1839 if (insn & (1 << 22)) { /* WSTRH */
1840 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1841 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1842 } else { /* WSTRB */
1843 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1844 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1848 tcg_temp_free_i32(tmp);
1850 tcg_temp_free_i32(addr);
1851 return 0;
1854 if ((insn & 0x0f000000) != 0x0e000000)
1855 return 1;
1857 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1858 case 0x000: /* WOR */
1859 wrd = (insn >> 12) & 0xf;
1860 rd0 = (insn >> 0) & 0xf;
1861 rd1 = (insn >> 16) & 0xf;
1862 gen_op_iwmmxt_movq_M0_wRn(rd0);
1863 gen_op_iwmmxt_orq_M0_wRn(rd1);
1864 gen_op_iwmmxt_setpsr_nz();
1865 gen_op_iwmmxt_movq_wRn_M0(wrd);
1866 gen_op_iwmmxt_set_mup();
1867 gen_op_iwmmxt_set_cup();
1868 break;
1869 case 0x011: /* TMCR */
1870 if (insn & 0xf)
1871 return 1;
1872 rd = (insn >> 12) & 0xf;
1873 wrd = (insn >> 16) & 0xf;
1874 switch (wrd) {
1875 case ARM_IWMMXT_wCID:
1876 case ARM_IWMMXT_wCASF:
1877 break;
1878 case ARM_IWMMXT_wCon:
1879 gen_op_iwmmxt_set_cup();
1880 /* Fall through. */
1881 case ARM_IWMMXT_wCSSF:
1882 tmp = iwmmxt_load_creg(wrd);
1883 tmp2 = load_reg(s, rd);
1884 tcg_gen_andc_i32(tmp, tmp, tmp2);
1885 tcg_temp_free_i32(tmp2);
1886 iwmmxt_store_creg(wrd, tmp);
1887 break;
1888 case ARM_IWMMXT_wCGR0:
1889 case ARM_IWMMXT_wCGR1:
1890 case ARM_IWMMXT_wCGR2:
1891 case ARM_IWMMXT_wCGR3:
1892 gen_op_iwmmxt_set_cup();
1893 tmp = load_reg(s, rd);
1894 iwmmxt_store_creg(wrd, tmp);
1895 break;
1896 default:
1897 return 1;
1899 break;
1900 case 0x100: /* WXOR */
1901 wrd = (insn >> 12) & 0xf;
1902 rd0 = (insn >> 0) & 0xf;
1903 rd1 = (insn >> 16) & 0xf;
1904 gen_op_iwmmxt_movq_M0_wRn(rd0);
1905 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1906 gen_op_iwmmxt_setpsr_nz();
1907 gen_op_iwmmxt_movq_wRn_M0(wrd);
1908 gen_op_iwmmxt_set_mup();
1909 gen_op_iwmmxt_set_cup();
1910 break;
1911 case 0x111: /* TMRC */
1912 if (insn & 0xf)
1913 return 1;
1914 rd = (insn >> 12) & 0xf;
1915 wrd = (insn >> 16) & 0xf;
1916 tmp = iwmmxt_load_creg(wrd);
1917 store_reg(s, rd, tmp);
1918 break;
1919 case 0x300: /* WANDN */
1920 wrd = (insn >> 12) & 0xf;
1921 rd0 = (insn >> 0) & 0xf;
1922 rd1 = (insn >> 16) & 0xf;
1923 gen_op_iwmmxt_movq_M0_wRn(rd0);
1924 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1925 gen_op_iwmmxt_andq_M0_wRn(rd1);
1926 gen_op_iwmmxt_setpsr_nz();
1927 gen_op_iwmmxt_movq_wRn_M0(wrd);
1928 gen_op_iwmmxt_set_mup();
1929 gen_op_iwmmxt_set_cup();
1930 break;
1931 case 0x200: /* WAND */
1932 wrd = (insn >> 12) & 0xf;
1933 rd0 = (insn >> 0) & 0xf;
1934 rd1 = (insn >> 16) & 0xf;
1935 gen_op_iwmmxt_movq_M0_wRn(rd0);
1936 gen_op_iwmmxt_andq_M0_wRn(rd1);
1937 gen_op_iwmmxt_setpsr_nz();
1938 gen_op_iwmmxt_movq_wRn_M0(wrd);
1939 gen_op_iwmmxt_set_mup();
1940 gen_op_iwmmxt_set_cup();
1941 break;
1942 case 0x810: case 0xa10: /* WMADD */
1943 wrd = (insn >> 12) & 0xf;
1944 rd0 = (insn >> 0) & 0xf;
1945 rd1 = (insn >> 16) & 0xf;
1946 gen_op_iwmmxt_movq_M0_wRn(rd0);
1947 if (insn & (1 << 21))
1948 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1949 else
1950 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1951 gen_op_iwmmxt_movq_wRn_M0(wrd);
1952 gen_op_iwmmxt_set_mup();
1953 break;
1954 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1955 wrd = (insn >> 12) & 0xf;
1956 rd0 = (insn >> 16) & 0xf;
1957 rd1 = (insn >> 0) & 0xf;
1958 gen_op_iwmmxt_movq_M0_wRn(rd0);
1959 switch ((insn >> 22) & 3) {
1960 case 0:
1961 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1962 break;
1963 case 1:
1964 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1965 break;
1966 case 2:
1967 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1968 break;
1969 case 3:
1970 return 1;
1972 gen_op_iwmmxt_movq_wRn_M0(wrd);
1973 gen_op_iwmmxt_set_mup();
1974 gen_op_iwmmxt_set_cup();
1975 break;
1976 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1977 wrd = (insn >> 12) & 0xf;
1978 rd0 = (insn >> 16) & 0xf;
1979 rd1 = (insn >> 0) & 0xf;
1980 gen_op_iwmmxt_movq_M0_wRn(rd0);
1981 switch ((insn >> 22) & 3) {
1982 case 0:
1983 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1984 break;
1985 case 1:
1986 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1987 break;
1988 case 2:
1989 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1990 break;
1991 case 3:
1992 return 1;
1994 gen_op_iwmmxt_movq_wRn_M0(wrd);
1995 gen_op_iwmmxt_set_mup();
1996 gen_op_iwmmxt_set_cup();
1997 break;
1998 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1999 wrd = (insn >> 12) & 0xf;
2000 rd0 = (insn >> 16) & 0xf;
2001 rd1 = (insn >> 0) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0);
2003 if (insn & (1 << 22))
2004 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2005 else
2006 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2007 if (!(insn & (1 << 20)))
2008 gen_op_iwmmxt_addl_M0_wRn(wrd);
2009 gen_op_iwmmxt_movq_wRn_M0(wrd);
2010 gen_op_iwmmxt_set_mup();
2011 break;
2012 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2013 wrd = (insn >> 12) & 0xf;
2014 rd0 = (insn >> 16) & 0xf;
2015 rd1 = (insn >> 0) & 0xf;
2016 gen_op_iwmmxt_movq_M0_wRn(rd0);
2017 if (insn & (1 << 21)) {
2018 if (insn & (1 << 20))
2019 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2020 else
2021 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2022 } else {
2023 if (insn & (1 << 20))
2024 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2025 else
2026 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2028 gen_op_iwmmxt_movq_wRn_M0(wrd);
2029 gen_op_iwmmxt_set_mup();
2030 break;
2031 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2032 wrd = (insn >> 12) & 0xf;
2033 rd0 = (insn >> 16) & 0xf;
2034 rd1 = (insn >> 0) & 0xf;
2035 gen_op_iwmmxt_movq_M0_wRn(rd0);
2036 if (insn & (1 << 21))
2037 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2038 else
2039 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2040 if (!(insn & (1 << 20))) {
2041 iwmmxt_load_reg(cpu_V1, wrd);
2042 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2044 gen_op_iwmmxt_movq_wRn_M0(wrd);
2045 gen_op_iwmmxt_set_mup();
2046 break;
2047 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2048 wrd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 16) & 0xf;
2050 rd1 = (insn >> 0) & 0xf;
2051 gen_op_iwmmxt_movq_M0_wRn(rd0);
2052 switch ((insn >> 22) & 3) {
2053 case 0:
2054 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2055 break;
2056 case 1:
2057 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2058 break;
2059 case 2:
2060 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2061 break;
2062 case 3:
2063 return 1;
2065 gen_op_iwmmxt_movq_wRn_M0(wrd);
2066 gen_op_iwmmxt_set_mup();
2067 gen_op_iwmmxt_set_cup();
2068 break;
2069 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2070 wrd = (insn >> 12) & 0xf;
2071 rd0 = (insn >> 16) & 0xf;
2072 rd1 = (insn >> 0) & 0xf;
2073 gen_op_iwmmxt_movq_M0_wRn(rd0);
2074 if (insn & (1 << 22)) {
2075 if (insn & (1 << 20))
2076 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2077 else
2078 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2079 } else {
2080 if (insn & (1 << 20))
2081 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2082 else
2083 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2085 gen_op_iwmmxt_movq_wRn_M0(wrd);
2086 gen_op_iwmmxt_set_mup();
2087 gen_op_iwmmxt_set_cup();
2088 break;
2089 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2090 wrd = (insn >> 12) & 0xf;
2091 rd0 = (insn >> 16) & 0xf;
2092 rd1 = (insn >> 0) & 0xf;
2093 gen_op_iwmmxt_movq_M0_wRn(rd0);
2094 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2095 tcg_gen_andi_i32(tmp, tmp, 7);
2096 iwmmxt_load_reg(cpu_V1, rd1);
2097 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2098 tcg_temp_free_i32(tmp);
2099 gen_op_iwmmxt_movq_wRn_M0(wrd);
2100 gen_op_iwmmxt_set_mup();
2101 break;
2102 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2103 if (((insn >> 6) & 3) == 3)
2104 return 1;
2105 rd = (insn >> 12) & 0xf;
2106 wrd = (insn >> 16) & 0xf;
2107 tmp = load_reg(s, rd);
2108 gen_op_iwmmxt_movq_M0_wRn(wrd);
2109 switch ((insn >> 6) & 3) {
2110 case 0:
2111 tmp2 = tcg_const_i32(0xff);
2112 tmp3 = tcg_const_i32((insn & 7) << 3);
2113 break;
2114 case 1:
2115 tmp2 = tcg_const_i32(0xffff);
2116 tmp3 = tcg_const_i32((insn & 3) << 4);
2117 break;
2118 case 2:
2119 tmp2 = tcg_const_i32(0xffffffff);
2120 tmp3 = tcg_const_i32((insn & 1) << 5);
2121 break;
2122 default:
2123 TCGV_UNUSED_I32(tmp2);
2124 TCGV_UNUSED_I32(tmp3);
2126 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2127 tcg_temp_free_i32(tmp3);
2128 tcg_temp_free_i32(tmp2);
2129 tcg_temp_free_i32(tmp);
2130 gen_op_iwmmxt_movq_wRn_M0(wrd);
2131 gen_op_iwmmxt_set_mup();
2132 break;
2133 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2134 rd = (insn >> 12) & 0xf;
2135 wrd = (insn >> 16) & 0xf;
2136 if (rd == 15 || ((insn >> 22) & 3) == 3)
2137 return 1;
2138 gen_op_iwmmxt_movq_M0_wRn(wrd);
2139 tmp = tcg_temp_new_i32();
2140 switch ((insn >> 22) & 3) {
2141 case 0:
2142 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2143 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2144 if (insn & 8) {
2145 tcg_gen_ext8s_i32(tmp, tmp);
2146 } else {
2147 tcg_gen_andi_i32(tmp, tmp, 0xff);
2149 break;
2150 case 1:
2151 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2152 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2153 if (insn & 8) {
2154 tcg_gen_ext16s_i32(tmp, tmp);
2155 } else {
2156 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2158 break;
2159 case 2:
2160 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2161 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2162 break;
2164 store_reg(s, rd, tmp);
2165 break;
2166 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2167 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2168 return 1;
2169 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2170 switch ((insn >> 22) & 3) {
2171 case 0:
2172 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2173 break;
2174 case 1:
2175 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2176 break;
2177 case 2:
2178 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2179 break;
2181 tcg_gen_shli_i32(tmp, tmp, 28);
2182 gen_set_nzcv(tmp);
2183 tcg_temp_free_i32(tmp);
2184 break;
2185 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2186 if (((insn >> 6) & 3) == 3)
2187 return 1;
2188 rd = (insn >> 12) & 0xf;
2189 wrd = (insn >> 16) & 0xf;
2190 tmp = load_reg(s, rd);
2191 switch ((insn >> 6) & 3) {
2192 case 0:
2193 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2194 break;
2195 case 1:
2196 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2197 break;
2198 case 2:
2199 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2200 break;
2202 tcg_temp_free_i32(tmp);
2203 gen_op_iwmmxt_movq_wRn_M0(wrd);
2204 gen_op_iwmmxt_set_mup();
2205 break;
2206 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2207 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2208 return 1;
2209 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2210 tmp2 = tcg_temp_new_i32();
2211 tcg_gen_mov_i32(tmp2, tmp);
2212 switch ((insn >> 22) & 3) {
2213 case 0:
2214 for (i = 0; i < 7; i ++) {
2215 tcg_gen_shli_i32(tmp2, tmp2, 4);
2216 tcg_gen_and_i32(tmp, tmp, tmp2);
2218 break;
2219 case 1:
2220 for (i = 0; i < 3; i ++) {
2221 tcg_gen_shli_i32(tmp2, tmp2, 8);
2222 tcg_gen_and_i32(tmp, tmp, tmp2);
2224 break;
2225 case 2:
2226 tcg_gen_shli_i32(tmp2, tmp2, 16);
2227 tcg_gen_and_i32(tmp, tmp, tmp2);
2228 break;
2230 gen_set_nzcv(tmp);
2231 tcg_temp_free_i32(tmp2);
2232 tcg_temp_free_i32(tmp);
2233 break;
2234 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2235 wrd = (insn >> 12) & 0xf;
2236 rd0 = (insn >> 16) & 0xf;
2237 gen_op_iwmmxt_movq_M0_wRn(rd0);
2238 switch ((insn >> 22) & 3) {
2239 case 0:
2240 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2241 break;
2242 case 1:
2243 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2244 break;
2245 case 2:
2246 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2247 break;
2248 case 3:
2249 return 1;
2251 gen_op_iwmmxt_movq_wRn_M0(wrd);
2252 gen_op_iwmmxt_set_mup();
2253 break;
2254 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2255 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2256 return 1;
2257 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2258 tmp2 = tcg_temp_new_i32();
2259 tcg_gen_mov_i32(tmp2, tmp);
2260 switch ((insn >> 22) & 3) {
2261 case 0:
2262 for (i = 0; i < 7; i ++) {
2263 tcg_gen_shli_i32(tmp2, tmp2, 4);
2264 tcg_gen_or_i32(tmp, tmp, tmp2);
2266 break;
2267 case 1:
2268 for (i = 0; i < 3; i ++) {
2269 tcg_gen_shli_i32(tmp2, tmp2, 8);
2270 tcg_gen_or_i32(tmp, tmp, tmp2);
2272 break;
2273 case 2:
2274 tcg_gen_shli_i32(tmp2, tmp2, 16);
2275 tcg_gen_or_i32(tmp, tmp, tmp2);
2276 break;
2278 gen_set_nzcv(tmp);
2279 tcg_temp_free_i32(tmp2);
2280 tcg_temp_free_i32(tmp);
2281 break;
2282 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2283 rd = (insn >> 12) & 0xf;
2284 rd0 = (insn >> 16) & 0xf;
2285 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2286 return 1;
2287 gen_op_iwmmxt_movq_M0_wRn(rd0);
2288 tmp = tcg_temp_new_i32();
2289 switch ((insn >> 22) & 3) {
2290 case 0:
2291 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2292 break;
2293 case 1:
2294 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2295 break;
2296 case 2:
2297 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2298 break;
2300 store_reg(s, rd, tmp);
2301 break;
2302 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2303 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2304 wrd = (insn >> 12) & 0xf;
2305 rd0 = (insn >> 16) & 0xf;
2306 rd1 = (insn >> 0) & 0xf;
2307 gen_op_iwmmxt_movq_M0_wRn(rd0);
2308 switch ((insn >> 22) & 3) {
2309 case 0:
2310 if (insn & (1 << 21))
2311 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2312 else
2313 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2314 break;
2315 case 1:
2316 if (insn & (1 << 21))
2317 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2318 else
2319 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2320 break;
2321 case 2:
2322 if (insn & (1 << 21))
2323 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2324 else
2325 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2326 break;
2327 case 3:
2328 return 1;
2330 gen_op_iwmmxt_movq_wRn_M0(wrd);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2333 break;
2334 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2335 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2336 wrd = (insn >> 12) & 0xf;
2337 rd0 = (insn >> 16) & 0xf;
2338 gen_op_iwmmxt_movq_M0_wRn(rd0);
2339 switch ((insn >> 22) & 3) {
2340 case 0:
2341 if (insn & (1 << 21))
2342 gen_op_iwmmxt_unpacklsb_M0();
2343 else
2344 gen_op_iwmmxt_unpacklub_M0();
2345 break;
2346 case 1:
2347 if (insn & (1 << 21))
2348 gen_op_iwmmxt_unpacklsw_M0();
2349 else
2350 gen_op_iwmmxt_unpackluw_M0();
2351 break;
2352 case 2:
2353 if (insn & (1 << 21))
2354 gen_op_iwmmxt_unpacklsl_M0();
2355 else
2356 gen_op_iwmmxt_unpacklul_M0();
2357 break;
2358 case 3:
2359 return 1;
2361 gen_op_iwmmxt_movq_wRn_M0(wrd);
2362 gen_op_iwmmxt_set_mup();
2363 gen_op_iwmmxt_set_cup();
2364 break;
2365 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2366 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2367 wrd = (insn >> 12) & 0xf;
2368 rd0 = (insn >> 16) & 0xf;
2369 gen_op_iwmmxt_movq_M0_wRn(rd0);
2370 switch ((insn >> 22) & 3) {
2371 case 0:
2372 if (insn & (1 << 21))
2373 gen_op_iwmmxt_unpackhsb_M0();
2374 else
2375 gen_op_iwmmxt_unpackhub_M0();
2376 break;
2377 case 1:
2378 if (insn & (1 << 21))
2379 gen_op_iwmmxt_unpackhsw_M0();
2380 else
2381 gen_op_iwmmxt_unpackhuw_M0();
2382 break;
2383 case 2:
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_unpackhsl_M0();
2386 else
2387 gen_op_iwmmxt_unpackhul_M0();
2388 break;
2389 case 3:
2390 return 1;
2392 gen_op_iwmmxt_movq_wRn_M0(wrd);
2393 gen_op_iwmmxt_set_mup();
2394 gen_op_iwmmxt_set_cup();
2395 break;
2396 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2397 case 0x214: case 0x614: case 0xa14: case 0xe14:
2398 if (((insn >> 22) & 3) == 0)
2399 return 1;
2400 wrd = (insn >> 12) & 0xf;
2401 rd0 = (insn >> 16) & 0xf;
2402 gen_op_iwmmxt_movq_M0_wRn(rd0);
2403 tmp = tcg_temp_new_i32();
2404 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2405 tcg_temp_free_i32(tmp);
2406 return 1;
2408 switch ((insn >> 22) & 3) {
2409 case 1:
2410 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2411 break;
2412 case 2:
2413 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2414 break;
2415 case 3:
2416 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2417 break;
2419 tcg_temp_free_i32(tmp);
2420 gen_op_iwmmxt_movq_wRn_M0(wrd);
2421 gen_op_iwmmxt_set_mup();
2422 gen_op_iwmmxt_set_cup();
2423 break;
2424 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2425 case 0x014: case 0x414: case 0x814: case 0xc14:
2426 if (((insn >> 22) & 3) == 0)
2427 return 1;
2428 wrd = (insn >> 12) & 0xf;
2429 rd0 = (insn >> 16) & 0xf;
2430 gen_op_iwmmxt_movq_M0_wRn(rd0);
2431 tmp = tcg_temp_new_i32();
2432 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2433 tcg_temp_free_i32(tmp);
2434 return 1;
2436 switch ((insn >> 22) & 3) {
2437 case 1:
2438 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2439 break;
2440 case 2:
2441 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2442 break;
2443 case 3:
2444 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2445 break;
2447 tcg_temp_free_i32(tmp);
2448 gen_op_iwmmxt_movq_wRn_M0(wrd);
2449 gen_op_iwmmxt_set_mup();
2450 gen_op_iwmmxt_set_cup();
2451 break;
2452 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2453 case 0x114: case 0x514: case 0x914: case 0xd14:
2454 if (((insn >> 22) & 3) == 0)
2455 return 1;
2456 wrd = (insn >> 12) & 0xf;
2457 rd0 = (insn >> 16) & 0xf;
2458 gen_op_iwmmxt_movq_M0_wRn(rd0);
2459 tmp = tcg_temp_new_i32();
2460 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2461 tcg_temp_free_i32(tmp);
2462 return 1;
2464 switch ((insn >> 22) & 3) {
2465 case 1:
2466 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2467 break;
2468 case 2:
2469 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2470 break;
2471 case 3:
2472 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2473 break;
2475 tcg_temp_free_i32(tmp);
2476 gen_op_iwmmxt_movq_wRn_M0(wrd);
2477 gen_op_iwmmxt_set_mup();
2478 gen_op_iwmmxt_set_cup();
2479 break;
2480 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2481 case 0x314: case 0x714: case 0xb14: case 0xf14:
2482 if (((insn >> 22) & 3) == 0)
2483 return 1;
2484 wrd = (insn >> 12) & 0xf;
2485 rd0 = (insn >> 16) & 0xf;
2486 gen_op_iwmmxt_movq_M0_wRn(rd0);
2487 tmp = tcg_temp_new_i32();
2488 switch ((insn >> 22) & 3) {
2489 case 1:
2490 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2491 tcg_temp_free_i32(tmp);
2492 return 1;
2494 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2495 break;
2496 case 2:
2497 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2498 tcg_temp_free_i32(tmp);
2499 return 1;
2501 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2502 break;
2503 case 3:
2504 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2505 tcg_temp_free_i32(tmp);
2506 return 1;
2508 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2509 break;
2511 tcg_temp_free_i32(tmp);
2512 gen_op_iwmmxt_movq_wRn_M0(wrd);
2513 gen_op_iwmmxt_set_mup();
2514 gen_op_iwmmxt_set_cup();
2515 break;
2516 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2517 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2518 wrd = (insn >> 12) & 0xf;
2519 rd0 = (insn >> 16) & 0xf;
2520 rd1 = (insn >> 0) & 0xf;
2521 gen_op_iwmmxt_movq_M0_wRn(rd0);
2522 switch ((insn >> 22) & 3) {
2523 case 0:
2524 if (insn & (1 << 21))
2525 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2526 else
2527 gen_op_iwmmxt_minub_M0_wRn(rd1);
2528 break;
2529 case 1:
2530 if (insn & (1 << 21))
2531 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2532 else
2533 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2534 break;
2535 case 2:
2536 if (insn & (1 << 21))
2537 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2538 else
2539 gen_op_iwmmxt_minul_M0_wRn(rd1);
2540 break;
2541 case 3:
2542 return 1;
2544 gen_op_iwmmxt_movq_wRn_M0(wrd);
2545 gen_op_iwmmxt_set_mup();
2546 break;
2547 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2548 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2549 wrd = (insn >> 12) & 0xf;
2550 rd0 = (insn >> 16) & 0xf;
2551 rd1 = (insn >> 0) & 0xf;
2552 gen_op_iwmmxt_movq_M0_wRn(rd0);
2553 switch ((insn >> 22) & 3) {
2554 case 0:
2555 if (insn & (1 << 21))
2556 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2557 else
2558 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2559 break;
2560 case 1:
2561 if (insn & (1 << 21))
2562 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2563 else
2564 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2565 break;
2566 case 2:
2567 if (insn & (1 << 21))
2568 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2569 else
2570 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2571 break;
2572 case 3:
2573 return 1;
2575 gen_op_iwmmxt_movq_wRn_M0(wrd);
2576 gen_op_iwmmxt_set_mup();
2577 break;
2578 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2579 case 0x402: case 0x502: case 0x602: case 0x702:
2580 wrd = (insn >> 12) & 0xf;
2581 rd0 = (insn >> 16) & 0xf;
2582 rd1 = (insn >> 0) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0);
2584 tmp = tcg_const_i32((insn >> 20) & 3);
2585 iwmmxt_load_reg(cpu_V1, rd1);
2586 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2587 tcg_temp_free_i32(tmp);
2588 gen_op_iwmmxt_movq_wRn_M0(wrd);
2589 gen_op_iwmmxt_set_mup();
2590 break;
2591 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2592 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2593 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2594 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2595 wrd = (insn >> 12) & 0xf;
2596 rd0 = (insn >> 16) & 0xf;
2597 rd1 = (insn >> 0) & 0xf;
2598 gen_op_iwmmxt_movq_M0_wRn(rd0);
2599 switch ((insn >> 20) & 0xf) {
2600 case 0x0:
2601 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2602 break;
2603 case 0x1:
2604 gen_op_iwmmxt_subub_M0_wRn(rd1);
2605 break;
2606 case 0x3:
2607 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2608 break;
2609 case 0x4:
2610 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2611 break;
2612 case 0x5:
2613 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2614 break;
2615 case 0x7:
2616 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2617 break;
2618 case 0x8:
2619 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2620 break;
2621 case 0x9:
2622 gen_op_iwmmxt_subul_M0_wRn(rd1);
2623 break;
2624 case 0xb:
2625 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2626 break;
2627 default:
2628 return 1;
2630 gen_op_iwmmxt_movq_wRn_M0(wrd);
2631 gen_op_iwmmxt_set_mup();
2632 gen_op_iwmmxt_set_cup();
2633 break;
2634 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2635 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2636 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2637 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2638 wrd = (insn >> 12) & 0xf;
2639 rd0 = (insn >> 16) & 0xf;
2640 gen_op_iwmmxt_movq_M0_wRn(rd0);
2641 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2642 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2643 tcg_temp_free_i32(tmp);
2644 gen_op_iwmmxt_movq_wRn_M0(wrd);
2645 gen_op_iwmmxt_set_mup();
2646 gen_op_iwmmxt_set_cup();
2647 break;
2648 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2649 case 0x418: case 0x518: case 0x618: case 0x718:
2650 case 0x818: case 0x918: case 0xa18: case 0xb18:
2651 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2652 wrd = (insn >> 12) & 0xf;
2653 rd0 = (insn >> 16) & 0xf;
2654 rd1 = (insn >> 0) & 0xf;
2655 gen_op_iwmmxt_movq_M0_wRn(rd0);
2656 switch ((insn >> 20) & 0xf) {
2657 case 0x0:
2658 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2659 break;
2660 case 0x1:
2661 gen_op_iwmmxt_addub_M0_wRn(rd1);
2662 break;
2663 case 0x3:
2664 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2665 break;
2666 case 0x4:
2667 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2668 break;
2669 case 0x5:
2670 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2671 break;
2672 case 0x7:
2673 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2674 break;
2675 case 0x8:
2676 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2677 break;
2678 case 0x9:
2679 gen_op_iwmmxt_addul_M0_wRn(rd1);
2680 break;
2681 case 0xb:
2682 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2683 break;
2684 default:
2685 return 1;
2687 gen_op_iwmmxt_movq_wRn_M0(wrd);
2688 gen_op_iwmmxt_set_mup();
2689 gen_op_iwmmxt_set_cup();
2690 break;
2691 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2692 case 0x408: case 0x508: case 0x608: case 0x708:
2693 case 0x808: case 0x908: case 0xa08: case 0xb08:
2694 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2695 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2696 return 1;
2697 wrd = (insn >> 12) & 0xf;
2698 rd0 = (insn >> 16) & 0xf;
2699 rd1 = (insn >> 0) & 0xf;
2700 gen_op_iwmmxt_movq_M0_wRn(rd0);
2701 switch ((insn >> 22) & 3) {
2702 case 1:
2703 if (insn & (1 << 21))
2704 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2705 else
2706 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2707 break;
2708 case 2:
2709 if (insn & (1 << 21))
2710 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2711 else
2712 gen_op_iwmmxt_packul_M0_wRn(rd1);
2713 break;
2714 case 3:
2715 if (insn & (1 << 21))
2716 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2717 else
2718 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2719 break;
2721 gen_op_iwmmxt_movq_wRn_M0(wrd);
2722 gen_op_iwmmxt_set_mup();
2723 gen_op_iwmmxt_set_cup();
2724 break;
2725 case 0x201: case 0x203: case 0x205: case 0x207:
2726 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2727 case 0x211: case 0x213: case 0x215: case 0x217:
2728 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2729 wrd = (insn >> 5) & 0xf;
2730 rd0 = (insn >> 12) & 0xf;
2731 rd1 = (insn >> 0) & 0xf;
2732 if (rd0 == 0xf || rd1 == 0xf)
2733 return 1;
2734 gen_op_iwmmxt_movq_M0_wRn(wrd);
2735 tmp = load_reg(s, rd0);
2736 tmp2 = load_reg(s, rd1);
2737 switch ((insn >> 16) & 0xf) {
2738 case 0x0: /* TMIA */
2739 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2740 break;
2741 case 0x8: /* TMIAPH */
2742 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2743 break;
2744 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2745 if (insn & (1 << 16))
2746 tcg_gen_shri_i32(tmp, tmp, 16);
2747 if (insn & (1 << 17))
2748 tcg_gen_shri_i32(tmp2, tmp2, 16);
2749 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2750 break;
2751 default:
2752 tcg_temp_free_i32(tmp2);
2753 tcg_temp_free_i32(tmp);
2754 return 1;
2756 tcg_temp_free_i32(tmp2);
2757 tcg_temp_free_i32(tmp);
2758 gen_op_iwmmxt_movq_wRn_M0(wrd);
2759 gen_op_iwmmxt_set_mup();
2760 break;
2761 default:
2762 return 1;
2765 return 0;
2768 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2769 (ie. an undefined instruction). */
2770 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2772 int acc, rd0, rd1, rdhi, rdlo;
2773 TCGv_i32 tmp, tmp2;
2775 if ((insn & 0x0ff00f10) == 0x0e200010) {
2776 /* Multiply with Internal Accumulate Format */
2777 rd0 = (insn >> 12) & 0xf;
2778 rd1 = insn & 0xf;
2779 acc = (insn >> 5) & 7;
2781 if (acc != 0)
2782 return 1;
2784 tmp = load_reg(s, rd0);
2785 tmp2 = load_reg(s, rd1);
2786 switch ((insn >> 16) & 0xf) {
2787 case 0x0: /* MIA */
2788 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2789 break;
2790 case 0x8: /* MIAPH */
2791 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2792 break;
2793 case 0xc: /* MIABB */
2794 case 0xd: /* MIABT */
2795 case 0xe: /* MIATB */
2796 case 0xf: /* MIATT */
2797 if (insn & (1 << 16))
2798 tcg_gen_shri_i32(tmp, tmp, 16);
2799 if (insn & (1 << 17))
2800 tcg_gen_shri_i32(tmp2, tmp2, 16);
2801 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2802 break;
2803 default:
2804 return 1;
2806 tcg_temp_free_i32(tmp2);
2807 tcg_temp_free_i32(tmp);
2809 gen_op_iwmmxt_movq_wRn_M0(acc);
2810 return 0;
2813 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2814 /* Internal Accumulator Access Format */
2815 rdhi = (insn >> 16) & 0xf;
2816 rdlo = (insn >> 12) & 0xf;
2817 acc = insn & 7;
2819 if (acc != 0)
2820 return 1;
2822 if (insn & ARM_CP_RW_BIT) { /* MRA */
2823 iwmmxt_load_reg(cpu_V0, acc);
2824 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2825 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2826 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2827 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2828 } else { /* MAR */
2829 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2830 iwmmxt_store_reg(cpu_V0, acc);
2832 return 0;
2835 return 1;
2838 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2839 #define VFP_SREG(insn, bigbit, smallbit) \
2840 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2841 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2842 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2843 reg = (((insn) >> (bigbit)) & 0x0f) \
2844 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2845 } else { \
2846 if (insn & (1 << (smallbit))) \
2847 return 1; \
2848 reg = ((insn) >> (bigbit)) & 0x0f; \
2849 }} while (0)
2851 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2852 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2853 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2854 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2855 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2856 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2858 /* Move between integer and VFP cores. */
2859 static TCGv_i32 gen_vfp_mrs(void)
2861 TCGv_i32 tmp = tcg_temp_new_i32();
2862 tcg_gen_mov_i32(tmp, cpu_F0s);
2863 return tmp;
2866 static void gen_vfp_msr(TCGv_i32 tmp)
2868 tcg_gen_mov_i32(cpu_F0s, tmp);
2869 tcg_temp_free_i32(tmp);
2872 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2874 TCGv_i32 tmp = tcg_temp_new_i32();
2875 if (shift)
2876 tcg_gen_shri_i32(var, var, shift);
2877 tcg_gen_ext8u_i32(var, var);
2878 tcg_gen_shli_i32(tmp, var, 8);
2879 tcg_gen_or_i32(var, var, tmp);
2880 tcg_gen_shli_i32(tmp, var, 16);
2881 tcg_gen_or_i32(var, var, tmp);
2882 tcg_temp_free_i32(tmp);
2885 static void gen_neon_dup_low16(TCGv_i32 var)
2887 TCGv_i32 tmp = tcg_temp_new_i32();
2888 tcg_gen_ext16u_i32(var, var);
2889 tcg_gen_shli_i32(tmp, var, 16);
2890 tcg_gen_or_i32(var, var, tmp);
2891 tcg_temp_free_i32(tmp);
2894 static void gen_neon_dup_high16(TCGv_i32 var)
2896 TCGv_i32 tmp = tcg_temp_new_i32();
2897 tcg_gen_andi_i32(var, var, 0xffff0000);
2898 tcg_gen_shri_i32(tmp, var, 16);
2899 tcg_gen_or_i32(var, var, tmp);
2900 tcg_temp_free_i32(tmp);
2903 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2905 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2906 TCGv_i32 tmp = tcg_temp_new_i32();
2907 switch (size) {
2908 case 0:
2909 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2910 gen_neon_dup_u8(tmp, 0);
2911 break;
2912 case 1:
2913 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2914 gen_neon_dup_low16(tmp);
2915 break;
2916 case 2:
2917 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2918 break;
2919 default: /* Avoid compiler warnings. */
2920 abort();
2922 return tmp;
2925 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2926 uint32_t dp)
2928 uint32_t cc = extract32(insn, 20, 2);
2930 if (dp) {
2931 TCGv_i64 frn, frm, dest;
2932 TCGv_i64 tmp, zero, zf, nf, vf;
2934 zero = tcg_const_i64(0);
2936 frn = tcg_temp_new_i64();
2937 frm = tcg_temp_new_i64();
2938 dest = tcg_temp_new_i64();
2940 zf = tcg_temp_new_i64();
2941 nf = tcg_temp_new_i64();
2942 vf = tcg_temp_new_i64();
2944 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2945 tcg_gen_ext_i32_i64(nf, cpu_NF);
2946 tcg_gen_ext_i32_i64(vf, cpu_VF);
2948 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2949 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2950 switch (cc) {
2951 case 0: /* eq: Z */
2952 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2953 frn, frm);
2954 break;
2955 case 1: /* vs: V */
2956 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2957 frn, frm);
2958 break;
2959 case 2: /* ge: N == V -> N ^ V == 0 */
2960 tmp = tcg_temp_new_i64();
2961 tcg_gen_xor_i64(tmp, vf, nf);
2962 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2963 frn, frm);
2964 tcg_temp_free_i64(tmp);
2965 break;
2966 case 3: /* gt: !Z && N == V */
2967 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2968 frn, frm);
2969 tmp = tcg_temp_new_i64();
2970 tcg_gen_xor_i64(tmp, vf, nf);
2971 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2972 dest, frm);
2973 tcg_temp_free_i64(tmp);
2974 break;
2976 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2977 tcg_temp_free_i64(frn);
2978 tcg_temp_free_i64(frm);
2979 tcg_temp_free_i64(dest);
2981 tcg_temp_free_i64(zf);
2982 tcg_temp_free_i64(nf);
2983 tcg_temp_free_i64(vf);
2985 tcg_temp_free_i64(zero);
2986 } else {
2987 TCGv_i32 frn, frm, dest;
2988 TCGv_i32 tmp, zero;
2990 zero = tcg_const_i32(0);
2992 frn = tcg_temp_new_i32();
2993 frm = tcg_temp_new_i32();
2994 dest = tcg_temp_new_i32();
2995 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2996 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2997 switch (cc) {
2998 case 0: /* eq: Z */
2999 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3000 frn, frm);
3001 break;
3002 case 1: /* vs: V */
3003 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3004 frn, frm);
3005 break;
3006 case 2: /* ge: N == V -> N ^ V == 0 */
3007 tmp = tcg_temp_new_i32();
3008 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3009 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3010 frn, frm);
3011 tcg_temp_free_i32(tmp);
3012 break;
3013 case 3: /* gt: !Z && N == V */
3014 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3015 frn, frm);
3016 tmp = tcg_temp_new_i32();
3017 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3018 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3019 dest, frm);
3020 tcg_temp_free_i32(tmp);
3021 break;
3023 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3024 tcg_temp_free_i32(frn);
3025 tcg_temp_free_i32(frm);
3026 tcg_temp_free_i32(dest);
3028 tcg_temp_free_i32(zero);
3031 return 0;
3034 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3035 uint32_t rm, uint32_t dp)
3037 uint32_t vmin = extract32(insn, 6, 1);
3038 TCGv_ptr fpst = get_fpstatus_ptr(0);
3040 if (dp) {
3041 TCGv_i64 frn, frm, dest;
3043 frn = tcg_temp_new_i64();
3044 frm = tcg_temp_new_i64();
3045 dest = tcg_temp_new_i64();
3047 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3048 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3049 if (vmin) {
3050 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3051 } else {
3052 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3054 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3055 tcg_temp_free_i64(frn);
3056 tcg_temp_free_i64(frm);
3057 tcg_temp_free_i64(dest);
3058 } else {
3059 TCGv_i32 frn, frm, dest;
3061 frn = tcg_temp_new_i32();
3062 frm = tcg_temp_new_i32();
3063 dest = tcg_temp_new_i32();
3065 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3066 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3067 if (vmin) {
3068 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3069 } else {
3070 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3072 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3073 tcg_temp_free_i32(frn);
3074 tcg_temp_free_i32(frm);
3075 tcg_temp_free_i32(dest);
3078 tcg_temp_free_ptr(fpst);
3079 return 0;
3082 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3083 int rounding)
3085 TCGv_ptr fpst = get_fpstatus_ptr(0);
3086 TCGv_i32 tcg_rmode;
3088 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3089 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3091 if (dp) {
3092 TCGv_i64 tcg_op;
3093 TCGv_i64 tcg_res;
3094 tcg_op = tcg_temp_new_i64();
3095 tcg_res = tcg_temp_new_i64();
3096 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3097 gen_helper_rintd(tcg_res, tcg_op, fpst);
3098 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3099 tcg_temp_free_i64(tcg_op);
3100 tcg_temp_free_i64(tcg_res);
3101 } else {
3102 TCGv_i32 tcg_op;
3103 TCGv_i32 tcg_res;
3104 tcg_op = tcg_temp_new_i32();
3105 tcg_res = tcg_temp_new_i32();
3106 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3107 gen_helper_rints(tcg_res, tcg_op, fpst);
3108 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3109 tcg_temp_free_i32(tcg_op);
3110 tcg_temp_free_i32(tcg_res);
3113 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3114 tcg_temp_free_i32(tcg_rmode);
3116 tcg_temp_free_ptr(fpst);
3117 return 0;
3120 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3121 int rounding)
3123 bool is_signed = extract32(insn, 7, 1);
3124 TCGv_ptr fpst = get_fpstatus_ptr(0);
3125 TCGv_i32 tcg_rmode, tcg_shift;
3127 tcg_shift = tcg_const_i32(0);
3129 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3130 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3132 if (dp) {
3133 TCGv_i64 tcg_double, tcg_res;
3134 TCGv_i32 tcg_tmp;
3135 /* Rd is encoded as a single precision register even when the source
3136 * is double precision.
3138 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3139 tcg_double = tcg_temp_new_i64();
3140 tcg_res = tcg_temp_new_i64();
3141 tcg_tmp = tcg_temp_new_i32();
3142 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3143 if (is_signed) {
3144 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3145 } else {
3146 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3148 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3149 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3150 tcg_temp_free_i32(tcg_tmp);
3151 tcg_temp_free_i64(tcg_res);
3152 tcg_temp_free_i64(tcg_double);
3153 } else {
3154 TCGv_i32 tcg_single, tcg_res;
3155 tcg_single = tcg_temp_new_i32();
3156 tcg_res = tcg_temp_new_i32();
3157 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3158 if (is_signed) {
3159 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3160 } else {
3161 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3163 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3164 tcg_temp_free_i32(tcg_res);
3165 tcg_temp_free_i32(tcg_single);
3168 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3169 tcg_temp_free_i32(tcg_rmode);
3171 tcg_temp_free_i32(tcg_shift);
3173 tcg_temp_free_ptr(fpst);
3175 return 0;
3178 /* Table for converting the most common AArch32 encoding of
3179 * rounding mode to arm_fprounding order (which matches the
3180 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3182 static const uint8_t fp_decode_rm[] = {
3183 FPROUNDING_TIEAWAY,
3184 FPROUNDING_TIEEVEN,
3185 FPROUNDING_POSINF,
3186 FPROUNDING_NEGINF,
3189 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3191 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3193 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3194 return 1;
3197 if (dp) {
3198 VFP_DREG_D(rd, insn);
3199 VFP_DREG_N(rn, insn);
3200 VFP_DREG_M(rm, insn);
3201 } else {
3202 rd = VFP_SREG_D(insn);
3203 rn = VFP_SREG_N(insn);
3204 rm = VFP_SREG_M(insn);
3207 if ((insn & 0x0f800e50) == 0x0e000a00) {
3208 return handle_vsel(insn, rd, rn, rm, dp);
3209 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3210 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3211 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3212 /* VRINTA, VRINTN, VRINTP, VRINTM */
3213 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3214 return handle_vrint(insn, rd, rm, dp, rounding);
3215 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3216 /* VCVTA, VCVTN, VCVTP, VCVTM */
3217 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3218 return handle_vcvt(insn, rd, rm, dp, rounding);
3220 return 1;
3223 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3224 (ie. an undefined instruction). */
3225 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3227 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3228 int dp, veclen;
3229 TCGv_i32 addr;
3230 TCGv_i32 tmp;
3231 TCGv_i32 tmp2;
3233 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3234 return 1;
3237 /* FIXME: this access check should not take precedence over UNDEF
3238 * for invalid encodings; we will generate incorrect syndrome information
3239 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3241 if (s->fp_excp_el) {
3242 gen_exception_insn(s, 4, EXCP_UDEF,
3243 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3244 return 0;
3247 if (!s->vfp_enabled) {
3248 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3249 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3250 return 1;
3251 rn = (insn >> 16) & 0xf;
3252 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3253 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3254 return 1;
3258 if (extract32(insn, 28, 4) == 0xf) {
3259 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3260 * only used in v8 and above.
3262 return disas_vfp_v8_insn(s, insn);
3265 dp = ((insn & 0xf00) == 0xb00);
3266 switch ((insn >> 24) & 0xf) {
3267 case 0xe:
3268 if (insn & (1 << 4)) {
3269 /* single register transfer */
3270 rd = (insn >> 12) & 0xf;
3271 if (dp) {
3272 int size;
3273 int pass;
3275 VFP_DREG_N(rn, insn);
3276 if (insn & 0xf)
3277 return 1;
3278 if (insn & 0x00c00060
3279 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3280 return 1;
3283 pass = (insn >> 21) & 1;
3284 if (insn & (1 << 22)) {
3285 size = 0;
3286 offset = ((insn >> 5) & 3) * 8;
3287 } else if (insn & (1 << 5)) {
3288 size = 1;
3289 offset = (insn & (1 << 6)) ? 16 : 0;
3290 } else {
3291 size = 2;
3292 offset = 0;
3294 if (insn & ARM_CP_RW_BIT) {
3295 /* vfp->arm */
3296 tmp = neon_load_reg(rn, pass);
3297 switch (size) {
3298 case 0:
3299 if (offset)
3300 tcg_gen_shri_i32(tmp, tmp, offset);
3301 if (insn & (1 << 23))
3302 gen_uxtb(tmp);
3303 else
3304 gen_sxtb(tmp);
3305 break;
3306 case 1:
3307 if (insn & (1 << 23)) {
3308 if (offset) {
3309 tcg_gen_shri_i32(tmp, tmp, 16);
3310 } else {
3311 gen_uxth(tmp);
3313 } else {
3314 if (offset) {
3315 tcg_gen_sari_i32(tmp, tmp, 16);
3316 } else {
3317 gen_sxth(tmp);
3320 break;
3321 case 2:
3322 break;
3324 store_reg(s, rd, tmp);
3325 } else {
3326 /* arm->vfp */
3327 tmp = load_reg(s, rd);
3328 if (insn & (1 << 23)) {
3329 /* VDUP */
3330 if (size == 0) {
3331 gen_neon_dup_u8(tmp, 0);
3332 } else if (size == 1) {
3333 gen_neon_dup_low16(tmp);
3335 for (n = 0; n <= pass * 2; n++) {
3336 tmp2 = tcg_temp_new_i32();
3337 tcg_gen_mov_i32(tmp2, tmp);
3338 neon_store_reg(rn, n, tmp2);
3340 neon_store_reg(rn, n, tmp);
3341 } else {
3342 /* VMOV */
3343 switch (size) {
3344 case 0:
3345 tmp2 = neon_load_reg(rn, pass);
3346 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3347 tcg_temp_free_i32(tmp2);
3348 break;
3349 case 1:
3350 tmp2 = neon_load_reg(rn, pass);
3351 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3352 tcg_temp_free_i32(tmp2);
3353 break;
3354 case 2:
3355 break;
3357 neon_store_reg(rn, pass, tmp);
3360 } else { /* !dp */
3361 if ((insn & 0x6f) != 0x00)
3362 return 1;
3363 rn = VFP_SREG_N(insn);
3364 if (insn & ARM_CP_RW_BIT) {
3365 /* vfp->arm */
3366 if (insn & (1 << 21)) {
3367 /* system register */
3368 rn >>= 1;
3370 switch (rn) {
3371 case ARM_VFP_FPSID:
3372 /* VFP2 allows access to FSID from userspace.
3373 VFP3 restricts all id registers to privileged
3374 accesses. */
3375 if (IS_USER(s)
3376 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3377 return 1;
3379 tmp = load_cpu_field(vfp.xregs[rn]);
3380 break;
3381 case ARM_VFP_FPEXC:
3382 if (IS_USER(s))
3383 return 1;
3384 tmp = load_cpu_field(vfp.xregs[rn]);
3385 break;
3386 case ARM_VFP_FPINST:
3387 case ARM_VFP_FPINST2:
3388 /* Not present in VFP3. */
3389 if (IS_USER(s)
3390 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3391 return 1;
3393 tmp = load_cpu_field(vfp.xregs[rn]);
3394 break;
3395 case ARM_VFP_FPSCR:
3396 if (rd == 15) {
3397 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3398 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3399 } else {
3400 tmp = tcg_temp_new_i32();
3401 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3403 break;
3404 case ARM_VFP_MVFR2:
3405 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3406 return 1;
3408 /* fall through */
3409 case ARM_VFP_MVFR0:
3410 case ARM_VFP_MVFR1:
3411 if (IS_USER(s)
3412 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3413 return 1;
3415 tmp = load_cpu_field(vfp.xregs[rn]);
3416 break;
3417 default:
3418 return 1;
3420 } else {
3421 gen_mov_F0_vreg(0, rn);
3422 tmp = gen_vfp_mrs();
3424 if (rd == 15) {
3425 /* Set the 4 flag bits in the CPSR. */
3426 gen_set_nzcv(tmp);
3427 tcg_temp_free_i32(tmp);
3428 } else {
3429 store_reg(s, rd, tmp);
3431 } else {
3432 /* arm->vfp */
3433 if (insn & (1 << 21)) {
3434 rn >>= 1;
3435 /* system register */
3436 switch (rn) {
3437 case ARM_VFP_FPSID:
3438 case ARM_VFP_MVFR0:
3439 case ARM_VFP_MVFR1:
3440 /* Writes are ignored. */
3441 break;
3442 case ARM_VFP_FPSCR:
3443 tmp = load_reg(s, rd);
3444 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3445 tcg_temp_free_i32(tmp);
3446 gen_lookup_tb(s);
3447 break;
3448 case ARM_VFP_FPEXC:
3449 if (IS_USER(s))
3450 return 1;
3451 /* TODO: VFP subarchitecture support.
3452 * For now, keep the EN bit only */
3453 tmp = load_reg(s, rd);
3454 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3455 store_cpu_field(tmp, vfp.xregs[rn]);
3456 gen_lookup_tb(s);
3457 break;
3458 case ARM_VFP_FPINST:
3459 case ARM_VFP_FPINST2:
3460 if (IS_USER(s)) {
3461 return 1;
3463 tmp = load_reg(s, rd);
3464 store_cpu_field(tmp, vfp.xregs[rn]);
3465 break;
3466 default:
3467 return 1;
3469 } else {
3470 tmp = load_reg(s, rd);
3471 gen_vfp_msr(tmp);
3472 gen_mov_vreg_F0(0, rn);
3476 } else {
3477 /* data processing */
3478 /* The opcode is in bits 23, 21, 20 and 6. */
3479 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3480 if (dp) {
3481 if (op == 15) {
3482 /* rn is opcode */
3483 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3484 } else {
3485 /* rn is register number */
3486 VFP_DREG_N(rn, insn);
3489 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3490 ((rn & 0x1e) == 0x6))) {
3491 /* Integer or single/half precision destination. */
3492 rd = VFP_SREG_D(insn);
3493 } else {
3494 VFP_DREG_D(rd, insn);
3496 if (op == 15 &&
3497 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3498 ((rn & 0x1e) == 0x4))) {
3499 /* VCVT from int or half precision is always from S reg
3500 * regardless of dp bit. VCVT with immediate frac_bits
3501 * has same format as SREG_M.
3503 rm = VFP_SREG_M(insn);
3504 } else {
3505 VFP_DREG_M(rm, insn);
3507 } else {
3508 rn = VFP_SREG_N(insn);
3509 if (op == 15 && rn == 15) {
3510 /* Double precision destination. */
3511 VFP_DREG_D(rd, insn);
3512 } else {
3513 rd = VFP_SREG_D(insn);
3515 /* NB that we implicitly rely on the encoding for the frac_bits
3516 * in VCVT of fixed to float being the same as that of an SREG_M
3518 rm = VFP_SREG_M(insn);
3521 veclen = s->vec_len;
3522 if (op == 15 && rn > 3)
3523 veclen = 0;
3525 /* Shut up compiler warnings. */
3526 delta_m = 0;
3527 delta_d = 0;
3528 bank_mask = 0;
3530 if (veclen > 0) {
3531 if (dp)
3532 bank_mask = 0xc;
3533 else
3534 bank_mask = 0x18;
3536 /* Figure out what type of vector operation this is. */
3537 if ((rd & bank_mask) == 0) {
3538 /* scalar */
3539 veclen = 0;
3540 } else {
3541 if (dp)
3542 delta_d = (s->vec_stride >> 1) + 1;
3543 else
3544 delta_d = s->vec_stride + 1;
3546 if ((rm & bank_mask) == 0) {
3547 /* mixed scalar/vector */
3548 delta_m = 0;
3549 } else {
3550 /* vector */
3551 delta_m = delta_d;
3556 /* Load the initial operands. */
3557 if (op == 15) {
3558 switch (rn) {
3559 case 16:
3560 case 17:
3561 /* Integer source */
3562 gen_mov_F0_vreg(0, rm);
3563 break;
3564 case 8:
3565 case 9:
3566 /* Compare */
3567 gen_mov_F0_vreg(dp, rd);
3568 gen_mov_F1_vreg(dp, rm);
3569 break;
3570 case 10:
3571 case 11:
3572 /* Compare with zero */
3573 gen_mov_F0_vreg(dp, rd);
3574 gen_vfp_F1_ld0(dp);
3575 break;
3576 case 20:
3577 case 21:
3578 case 22:
3579 case 23:
3580 case 28:
3581 case 29:
3582 case 30:
3583 case 31:
3584 /* Source and destination the same. */
3585 gen_mov_F0_vreg(dp, rd);
3586 break;
3587 case 4:
3588 case 5:
3589 case 6:
3590 case 7:
3591 /* VCVTB, VCVTT: only present with the halfprec extension
3592 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3593 * (we choose to UNDEF)
3595 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3596 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3597 return 1;
3599 if (!extract32(rn, 1, 1)) {
3600 /* Half precision source. */
3601 gen_mov_F0_vreg(0, rm);
3602 break;
3604 /* Otherwise fall through */
3605 default:
3606 /* One source operand. */
3607 gen_mov_F0_vreg(dp, rm);
3608 break;
3610 } else {
3611 /* Two source operands. */
3612 gen_mov_F0_vreg(dp, rn);
3613 gen_mov_F1_vreg(dp, rm);
3616 for (;;) {
3617 /* Perform the calculation. */
3618 switch (op) {
3619 case 0: /* VMLA: fd + (fn * fm) */
3620 /* Note that order of inputs to the add matters for NaNs */
3621 gen_vfp_F1_mul(dp);
3622 gen_mov_F0_vreg(dp, rd);
3623 gen_vfp_add(dp);
3624 break;
3625 case 1: /* VMLS: fd + -(fn * fm) */
3626 gen_vfp_mul(dp);
3627 gen_vfp_F1_neg(dp);
3628 gen_mov_F0_vreg(dp, rd);
3629 gen_vfp_add(dp);
3630 break;
3631 case 2: /* VNMLS: -fd + (fn * fm) */
3632 /* Note that it isn't valid to replace (-A + B) with (B - A)
3633 * or similar plausible looking simplifications
3634 * because this will give wrong results for NaNs.
3636 gen_vfp_F1_mul(dp);
3637 gen_mov_F0_vreg(dp, rd);
3638 gen_vfp_neg(dp);
3639 gen_vfp_add(dp);
3640 break;
3641 case 3: /* VNMLA: -fd + -(fn * fm) */
3642 gen_vfp_mul(dp);
3643 gen_vfp_F1_neg(dp);
3644 gen_mov_F0_vreg(dp, rd);
3645 gen_vfp_neg(dp);
3646 gen_vfp_add(dp);
3647 break;
3648 case 4: /* mul: fn * fm */
3649 gen_vfp_mul(dp);
3650 break;
3651 case 5: /* nmul: -(fn * fm) */
3652 gen_vfp_mul(dp);
3653 gen_vfp_neg(dp);
3654 break;
3655 case 6: /* add: fn + fm */
3656 gen_vfp_add(dp);
3657 break;
3658 case 7: /* sub: fn - fm */
3659 gen_vfp_sub(dp);
3660 break;
3661 case 8: /* div: fn / fm */
3662 gen_vfp_div(dp);
3663 break;
3664 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3665 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3666 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3667 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3668 /* These are fused multiply-add, and must be done as one
3669 * floating point operation with no rounding between the
3670 * multiplication and addition steps.
3671 * NB that doing the negations here as separate steps is
3672 * correct : an input NaN should come out with its sign bit
3673 * flipped if it is a negated-input.
3675 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3676 return 1;
3678 if (dp) {
3679 TCGv_ptr fpst;
3680 TCGv_i64 frd;
3681 if (op & 1) {
3682 /* VFNMS, VFMS */
3683 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3685 frd = tcg_temp_new_i64();
3686 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3687 if (op & 2) {
3688 /* VFNMA, VFNMS */
3689 gen_helper_vfp_negd(frd, frd);
3691 fpst = get_fpstatus_ptr(0);
3692 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3693 cpu_F1d, frd, fpst);
3694 tcg_temp_free_ptr(fpst);
3695 tcg_temp_free_i64(frd);
3696 } else {
3697 TCGv_ptr fpst;
3698 TCGv_i32 frd;
3699 if (op & 1) {
3700 /* VFNMS, VFMS */
3701 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3703 frd = tcg_temp_new_i32();
3704 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3705 if (op & 2) {
3706 gen_helper_vfp_negs(frd, frd);
3708 fpst = get_fpstatus_ptr(0);
3709 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3710 cpu_F1s, frd, fpst);
3711 tcg_temp_free_ptr(fpst);
3712 tcg_temp_free_i32(frd);
3714 break;
3715 case 14: /* fconst */
3716 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3717 return 1;
3720 n = (insn << 12) & 0x80000000;
3721 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3722 if (dp) {
3723 if (i & 0x40)
3724 i |= 0x3f80;
3725 else
3726 i |= 0x4000;
3727 n |= i << 16;
3728 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3729 } else {
3730 if (i & 0x40)
3731 i |= 0x780;
3732 else
3733 i |= 0x800;
3734 n |= i << 19;
3735 tcg_gen_movi_i32(cpu_F0s, n);
3737 break;
3738 case 15: /* extension space */
3739 switch (rn) {
3740 case 0: /* cpy */
3741 /* no-op */
3742 break;
3743 case 1: /* abs */
3744 gen_vfp_abs(dp);
3745 break;
3746 case 2: /* neg */
3747 gen_vfp_neg(dp);
3748 break;
3749 case 3: /* sqrt */
3750 gen_vfp_sqrt(dp);
3751 break;
3752 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3753 tmp = gen_vfp_mrs();
3754 tcg_gen_ext16u_i32(tmp, tmp);
3755 if (dp) {
3756 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3757 cpu_env);
3758 } else {
3759 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3760 cpu_env);
3762 tcg_temp_free_i32(tmp);
3763 break;
3764 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3765 tmp = gen_vfp_mrs();
3766 tcg_gen_shri_i32(tmp, tmp, 16);
3767 if (dp) {
3768 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3769 cpu_env);
3770 } else {
3771 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3772 cpu_env);
3774 tcg_temp_free_i32(tmp);
3775 break;
3776 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3777 tmp = tcg_temp_new_i32();
3778 if (dp) {
3779 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3780 cpu_env);
3781 } else {
3782 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3783 cpu_env);
3785 gen_mov_F0_vreg(0, rd);
3786 tmp2 = gen_vfp_mrs();
3787 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3788 tcg_gen_or_i32(tmp, tmp, tmp2);
3789 tcg_temp_free_i32(tmp2);
3790 gen_vfp_msr(tmp);
3791 break;
3792 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3793 tmp = tcg_temp_new_i32();
3794 if (dp) {
3795 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3796 cpu_env);
3797 } else {
3798 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3799 cpu_env);
3801 tcg_gen_shli_i32(tmp, tmp, 16);
3802 gen_mov_F0_vreg(0, rd);
3803 tmp2 = gen_vfp_mrs();
3804 tcg_gen_ext16u_i32(tmp2, tmp2);
3805 tcg_gen_or_i32(tmp, tmp, tmp2);
3806 tcg_temp_free_i32(tmp2);
3807 gen_vfp_msr(tmp);
3808 break;
3809 case 8: /* cmp */
3810 gen_vfp_cmp(dp);
3811 break;
3812 case 9: /* cmpe */
3813 gen_vfp_cmpe(dp);
3814 break;
3815 case 10: /* cmpz */
3816 gen_vfp_cmp(dp);
3817 break;
3818 case 11: /* cmpez */
3819 gen_vfp_F1_ld0(dp);
3820 gen_vfp_cmpe(dp);
3821 break;
3822 case 12: /* vrintr */
3824 TCGv_ptr fpst = get_fpstatus_ptr(0);
3825 if (dp) {
3826 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3827 } else {
3828 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3830 tcg_temp_free_ptr(fpst);
3831 break;
3833 case 13: /* vrintz */
3835 TCGv_ptr fpst = get_fpstatus_ptr(0);
3836 TCGv_i32 tcg_rmode;
3837 tcg_rmode = tcg_const_i32(float_round_to_zero);
3838 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3839 if (dp) {
3840 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3841 } else {
3842 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3844 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3845 tcg_temp_free_i32(tcg_rmode);
3846 tcg_temp_free_ptr(fpst);
3847 break;
3849 case 14: /* vrintx */
3851 TCGv_ptr fpst = get_fpstatus_ptr(0);
3852 if (dp) {
3853 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3854 } else {
3855 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3857 tcg_temp_free_ptr(fpst);
3858 break;
3860 case 15: /* single<->double conversion */
3861 if (dp)
3862 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3863 else
3864 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3865 break;
3866 case 16: /* fuito */
3867 gen_vfp_uito(dp, 0);
3868 break;
3869 case 17: /* fsito */
3870 gen_vfp_sito(dp, 0);
3871 break;
3872 case 20: /* fshto */
3873 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3874 return 1;
3876 gen_vfp_shto(dp, 16 - rm, 0);
3877 break;
3878 case 21: /* fslto */
3879 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3880 return 1;
3882 gen_vfp_slto(dp, 32 - rm, 0);
3883 break;
3884 case 22: /* fuhto */
3885 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3886 return 1;
3888 gen_vfp_uhto(dp, 16 - rm, 0);
3889 break;
3890 case 23: /* fulto */
3891 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3892 return 1;
3894 gen_vfp_ulto(dp, 32 - rm, 0);
3895 break;
3896 case 24: /* ftoui */
3897 gen_vfp_toui(dp, 0);
3898 break;
3899 case 25: /* ftouiz */
3900 gen_vfp_touiz(dp, 0);
3901 break;
3902 case 26: /* ftosi */
3903 gen_vfp_tosi(dp, 0);
3904 break;
3905 case 27: /* ftosiz */
3906 gen_vfp_tosiz(dp, 0);
3907 break;
3908 case 28: /* ftosh */
3909 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3910 return 1;
3912 gen_vfp_tosh(dp, 16 - rm, 0);
3913 break;
3914 case 29: /* ftosl */
3915 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3916 return 1;
3918 gen_vfp_tosl(dp, 32 - rm, 0);
3919 break;
3920 case 30: /* ftouh */
3921 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3922 return 1;
3924 gen_vfp_touh(dp, 16 - rm, 0);
3925 break;
3926 case 31: /* ftoul */
3927 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3928 return 1;
3930 gen_vfp_toul(dp, 32 - rm, 0);
3931 break;
3932 default: /* undefined */
3933 return 1;
3935 break;
3936 default: /* undefined */
3937 return 1;
3940 /* Write back the result. */
3941 if (op == 15 && (rn >= 8 && rn <= 11)) {
3942 /* Comparison, do nothing. */
3943 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3944 (rn & 0x1e) == 0x6)) {
3945 /* VCVT double to int: always integer result.
3946 * VCVT double to half precision is always a single
3947 * precision result.
3949 gen_mov_vreg_F0(0, rd);
3950 } else if (op == 15 && rn == 15) {
3951 /* conversion */
3952 gen_mov_vreg_F0(!dp, rd);
3953 } else {
3954 gen_mov_vreg_F0(dp, rd);
3957 /* break out of the loop if we have finished */
3958 if (veclen == 0)
3959 break;
3961 if (op == 15 && delta_m == 0) {
3962 /* single source one-many */
3963 while (veclen--) {
3964 rd = ((rd + delta_d) & (bank_mask - 1))
3965 | (rd & bank_mask);
3966 gen_mov_vreg_F0(dp, rd);
3968 break;
3970 /* Setup the next operands. */
3971 veclen--;
3972 rd = ((rd + delta_d) & (bank_mask - 1))
3973 | (rd & bank_mask);
3975 if (op == 15) {
3976 /* One source operand. */
3977 rm = ((rm + delta_m) & (bank_mask - 1))
3978 | (rm & bank_mask);
3979 gen_mov_F0_vreg(dp, rm);
3980 } else {
3981 /* Two source operands. */
3982 rn = ((rn + delta_d) & (bank_mask - 1))
3983 | (rn & bank_mask);
3984 gen_mov_F0_vreg(dp, rn);
3985 if (delta_m) {
3986 rm = ((rm + delta_m) & (bank_mask - 1))
3987 | (rm & bank_mask);
3988 gen_mov_F1_vreg(dp, rm);
3993 break;
3994 case 0xc:
3995 case 0xd:
3996 if ((insn & 0x03e00000) == 0x00400000) {
3997 /* two-register transfer */
3998 rn = (insn >> 16) & 0xf;
3999 rd = (insn >> 12) & 0xf;
4000 if (dp) {
4001 VFP_DREG_M(rm, insn);
4002 } else {
4003 rm = VFP_SREG_M(insn);
4006 if (insn & ARM_CP_RW_BIT) {
4007 /* vfp->arm */
4008 if (dp) {
4009 gen_mov_F0_vreg(0, rm * 2);
4010 tmp = gen_vfp_mrs();
4011 store_reg(s, rd, tmp);
4012 gen_mov_F0_vreg(0, rm * 2 + 1);
4013 tmp = gen_vfp_mrs();
4014 store_reg(s, rn, tmp);
4015 } else {
4016 gen_mov_F0_vreg(0, rm);
4017 tmp = gen_vfp_mrs();
4018 store_reg(s, rd, tmp);
4019 gen_mov_F0_vreg(0, rm + 1);
4020 tmp = gen_vfp_mrs();
4021 store_reg(s, rn, tmp);
4023 } else {
4024 /* arm->vfp */
4025 if (dp) {
4026 tmp = load_reg(s, rd);
4027 gen_vfp_msr(tmp);
4028 gen_mov_vreg_F0(0, rm * 2);
4029 tmp = load_reg(s, rn);
4030 gen_vfp_msr(tmp);
4031 gen_mov_vreg_F0(0, rm * 2 + 1);
4032 } else {
4033 tmp = load_reg(s, rd);
4034 gen_vfp_msr(tmp);
4035 gen_mov_vreg_F0(0, rm);
4036 tmp = load_reg(s, rn);
4037 gen_vfp_msr(tmp);
4038 gen_mov_vreg_F0(0, rm + 1);
4041 } else {
4042 /* Load/store */
4043 rn = (insn >> 16) & 0xf;
4044 if (dp)
4045 VFP_DREG_D(rd, insn);
4046 else
4047 rd = VFP_SREG_D(insn);
4048 if ((insn & 0x01200000) == 0x01000000) {
4049 /* Single load/store */
4050 offset = (insn & 0xff) << 2;
4051 if ((insn & (1 << 23)) == 0)
4052 offset = -offset;
4053 if (s->thumb && rn == 15) {
4054 /* This is actually UNPREDICTABLE */
4055 addr = tcg_temp_new_i32();
4056 tcg_gen_movi_i32(addr, s->pc & ~2);
4057 } else {
4058 addr = load_reg(s, rn);
4060 tcg_gen_addi_i32(addr, addr, offset);
4061 if (insn & (1 << 20)) {
4062 gen_vfp_ld(s, dp, addr);
4063 gen_mov_vreg_F0(dp, rd);
4064 } else {
4065 gen_mov_F0_vreg(dp, rd);
4066 gen_vfp_st(s, dp, addr);
4068 tcg_temp_free_i32(addr);
4069 } else {
4070 /* load/store multiple */
4071 int w = insn & (1 << 21);
4072 if (dp)
4073 n = (insn >> 1) & 0x7f;
4074 else
4075 n = insn & 0xff;
4077 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4078 /* P == U , W == 1 => UNDEF */
4079 return 1;
4081 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4082 /* UNPREDICTABLE cases for bad immediates: we choose to
4083 * UNDEF to avoid generating huge numbers of TCG ops
4085 return 1;
4087 if (rn == 15 && w) {
4088 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4089 return 1;
4092 if (s->thumb && rn == 15) {
4093 /* This is actually UNPREDICTABLE */
4094 addr = tcg_temp_new_i32();
4095 tcg_gen_movi_i32(addr, s->pc & ~2);
4096 } else {
4097 addr = load_reg(s, rn);
4099 if (insn & (1 << 24)) /* pre-decrement */
4100 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4102 if (dp)
4103 offset = 8;
4104 else
4105 offset = 4;
4106 for (i = 0; i < n; i++) {
4107 if (insn & ARM_CP_RW_BIT) {
4108 /* load */
4109 gen_vfp_ld(s, dp, addr);
4110 gen_mov_vreg_F0(dp, rd + i);
4111 } else {
4112 /* store */
4113 gen_mov_F0_vreg(dp, rd + i);
4114 gen_vfp_st(s, dp, addr);
4116 tcg_gen_addi_i32(addr, addr, offset);
4118 if (w) {
4119 /* writeback */
4120 if (insn & (1 << 24))
4121 offset = -offset * n;
4122 else if (dp && (insn & 1))
4123 offset = 4;
4124 else
4125 offset = 0;
4127 if (offset != 0)
4128 tcg_gen_addi_i32(addr, addr, offset);
4129 store_reg(s, rn, addr);
4130 } else {
4131 tcg_temp_free_i32(addr);
4135 break;
4136 default:
4137 /* Should never happen. */
4138 return 1;
4140 return 0;
4143 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4145 #ifndef CONFIG_USER_ONLY
4146 return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4147 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4148 #else
4149 return true;
4150 #endif
4153 static void gen_goto_ptr(void)
4155 TCGv addr = tcg_temp_new();
4156 tcg_gen_extu_i32_tl(addr, cpu_R[15]);
4157 tcg_gen_lookup_and_goto_ptr(addr);
4158 tcg_temp_free(addr);
4161 /* This will end the TB but doesn't guarantee we'll return to
4162 * cpu_loop_exec. Any live exit_requests will be processed as we
4163 * enter the next TB.
4165 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4167 if (use_goto_tb(s, dest)) {
4168 tcg_gen_goto_tb(n);
4169 gen_set_pc_im(s, dest);
4170 tcg_gen_exit_tb((uintptr_t)s->tb + n);
4171 } else {
4172 gen_set_pc_im(s, dest);
4173 gen_goto_ptr();
4175 s->is_jmp = DISAS_TB_JUMP;
4178 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4180 if (unlikely(is_singlestepping(s))) {
4181 /* An indirect jump so that we still trigger the debug exception. */
4182 if (s->thumb)
4183 dest |= 1;
4184 gen_bx_im(s, dest);
4185 } else {
4186 gen_goto_tb(s, 0, dest);
4190 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4192 if (x)
4193 tcg_gen_sari_i32(t0, t0, 16);
4194 else
4195 gen_sxth(t0);
4196 if (y)
4197 tcg_gen_sari_i32(t1, t1, 16);
4198 else
4199 gen_sxth(t1);
4200 tcg_gen_mul_i32(t0, t0, t1);
4203 /* Return the mask of PSR bits set by a MSR instruction. */
4204 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4206 uint32_t mask;
4208 mask = 0;
4209 if (flags & (1 << 0))
4210 mask |= 0xff;
4211 if (flags & (1 << 1))
4212 mask |= 0xff00;
4213 if (flags & (1 << 2))
4214 mask |= 0xff0000;
4215 if (flags & (1 << 3))
4216 mask |= 0xff000000;
4218 /* Mask out undefined bits. */
4219 mask &= ~CPSR_RESERVED;
4220 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4221 mask &= ~CPSR_T;
4223 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4224 mask &= ~CPSR_Q; /* V5TE in reality*/
4226 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4227 mask &= ~(CPSR_E | CPSR_GE);
4229 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4230 mask &= ~CPSR_IT;
4232 /* Mask out execution state and reserved bits. */
4233 if (!spsr) {
4234 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4236 /* Mask out privileged bits. */
4237 if (IS_USER(s))
4238 mask &= CPSR_USER;
4239 return mask;
4242 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4243 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4245 TCGv_i32 tmp;
4246 if (spsr) {
4247 /* ??? This is also undefined in system mode. */
4248 if (IS_USER(s))
4249 return 1;
4251 tmp = load_cpu_field(spsr);
4252 tcg_gen_andi_i32(tmp, tmp, ~mask);
4253 tcg_gen_andi_i32(t0, t0, mask);
4254 tcg_gen_or_i32(tmp, tmp, t0);
4255 store_cpu_field(tmp, spsr);
4256 } else {
4257 gen_set_cpsr(t0, mask);
4259 tcg_temp_free_i32(t0);
4260 gen_lookup_tb(s);
4261 return 0;
4264 /* Returns nonzero if access to the PSR is not permitted. */
4265 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4267 TCGv_i32 tmp;
4268 tmp = tcg_temp_new_i32();
4269 tcg_gen_movi_i32(tmp, val);
4270 return gen_set_psr(s, mask, spsr, tmp);
4273 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4274 int *tgtmode, int *regno)
4276 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4277 * the target mode and register number, and identify the various
4278 * unpredictable cases.
4279 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4280 * + executed in user mode
4281 * + using R15 as the src/dest register
4282 * + accessing an unimplemented register
4283 * + accessing a register that's inaccessible at current PL/security state*
4284 * + accessing a register that you could access with a different insn
4285 * We choose to UNDEF in all these cases.
4286 * Since we don't know which of the various AArch32 modes we are in
4287 * we have to defer some checks to runtime.
4288 * Accesses to Monitor mode registers from Secure EL1 (which implies
4289 * that EL3 is AArch64) must trap to EL3.
4291 * If the access checks fail this function will emit code to take
4292 * an exception and return false. Otherwise it will return true,
4293 * and set *tgtmode and *regno appropriately.
4295 int exc_target = default_exception_el(s);
4297 /* These instructions are present only in ARMv8, or in ARMv7 with the
4298 * Virtualization Extensions.
4300 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4301 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4302 goto undef;
4305 if (IS_USER(s) || rn == 15) {
4306 goto undef;
4309 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4310 * of registers into (r, sysm).
4312 if (r) {
4313 /* SPSRs for other modes */
4314 switch (sysm) {
4315 case 0xe: /* SPSR_fiq */
4316 *tgtmode = ARM_CPU_MODE_FIQ;
4317 break;
4318 case 0x10: /* SPSR_irq */
4319 *tgtmode = ARM_CPU_MODE_IRQ;
4320 break;
4321 case 0x12: /* SPSR_svc */
4322 *tgtmode = ARM_CPU_MODE_SVC;
4323 break;
4324 case 0x14: /* SPSR_abt */
4325 *tgtmode = ARM_CPU_MODE_ABT;
4326 break;
4327 case 0x16: /* SPSR_und */
4328 *tgtmode = ARM_CPU_MODE_UND;
4329 break;
4330 case 0x1c: /* SPSR_mon */
4331 *tgtmode = ARM_CPU_MODE_MON;
4332 break;
4333 case 0x1e: /* SPSR_hyp */
4334 *tgtmode = ARM_CPU_MODE_HYP;
4335 break;
4336 default: /* unallocated */
4337 goto undef;
4339 /* We arbitrarily assign SPSR a register number of 16. */
4340 *regno = 16;
4341 } else {
4342 /* general purpose registers for other modes */
4343 switch (sysm) {
4344 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4345 *tgtmode = ARM_CPU_MODE_USR;
4346 *regno = sysm + 8;
4347 break;
4348 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4349 *tgtmode = ARM_CPU_MODE_FIQ;
4350 *regno = sysm;
4351 break;
4352 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4353 *tgtmode = ARM_CPU_MODE_IRQ;
4354 *regno = sysm & 1 ? 13 : 14;
4355 break;
4356 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4357 *tgtmode = ARM_CPU_MODE_SVC;
4358 *regno = sysm & 1 ? 13 : 14;
4359 break;
4360 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4361 *tgtmode = ARM_CPU_MODE_ABT;
4362 *regno = sysm & 1 ? 13 : 14;
4363 break;
4364 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4365 *tgtmode = ARM_CPU_MODE_UND;
4366 *regno = sysm & 1 ? 13 : 14;
4367 break;
4368 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4369 *tgtmode = ARM_CPU_MODE_MON;
4370 *regno = sysm & 1 ? 13 : 14;
4371 break;
4372 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4373 *tgtmode = ARM_CPU_MODE_HYP;
4374 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4375 *regno = sysm & 1 ? 13 : 17;
4376 break;
4377 default: /* unallocated */
4378 goto undef;
4382 /* Catch the 'accessing inaccessible register' cases we can detect
4383 * at translate time.
4385 switch (*tgtmode) {
4386 case ARM_CPU_MODE_MON:
4387 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4388 goto undef;
4390 if (s->current_el == 1) {
4391 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4392 * then accesses to Mon registers trap to EL3
4394 exc_target = 3;
4395 goto undef;
4397 break;
4398 case ARM_CPU_MODE_HYP:
4399 /* Note that we can forbid accesses from EL2 here because they
4400 * must be from Hyp mode itself
4402 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4403 goto undef;
4405 break;
4406 default:
4407 break;
4410 return true;
4412 undef:
4413 /* If we get here then some access check did not pass */
4414 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4415 return false;
4418 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4420 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4421 int tgtmode = 0, regno = 0;
4423 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4424 return;
4427 /* Sync state because msr_banked() can raise exceptions */
4428 gen_set_condexec(s);
4429 gen_set_pc_im(s, s->pc - 4);
4430 tcg_reg = load_reg(s, rn);
4431 tcg_tgtmode = tcg_const_i32(tgtmode);
4432 tcg_regno = tcg_const_i32(regno);
4433 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4434 tcg_temp_free_i32(tcg_tgtmode);
4435 tcg_temp_free_i32(tcg_regno);
4436 tcg_temp_free_i32(tcg_reg);
4437 s->is_jmp = DISAS_UPDATE;
4440 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4442 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4443 int tgtmode = 0, regno = 0;
4445 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4446 return;
4449 /* Sync state because mrs_banked() can raise exceptions */
4450 gen_set_condexec(s);
4451 gen_set_pc_im(s, s->pc - 4);
4452 tcg_reg = tcg_temp_new_i32();
4453 tcg_tgtmode = tcg_const_i32(tgtmode);
4454 tcg_regno = tcg_const_i32(regno);
4455 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4456 tcg_temp_free_i32(tcg_tgtmode);
4457 tcg_temp_free_i32(tcg_regno);
4458 store_reg(s, rn, tcg_reg);
4459 s->is_jmp = DISAS_UPDATE;
4462 /* Store value to PC as for an exception return (ie don't
4463 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4464 * will do the masking based on the new value of the Thumb bit.
4466 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4468 tcg_gen_mov_i32(cpu_R[15], pc);
4469 tcg_temp_free_i32(pc);
4472 /* Generate a v6 exception return. Marks both values as dead. */
4473 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4475 store_pc_exc_ret(s, pc);
4476 /* The cpsr_write_eret helper will mask the low bits of PC
4477 * appropriately depending on the new Thumb bit, so it must
4478 * be called after storing the new PC.
4480 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4481 tcg_temp_free_i32(cpsr);
4482 s->is_jmp = DISAS_JUMP;
4485 /* Generate an old-style exception return. Marks pc as dead. */
4486 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4488 gen_rfe(s, pc, load_cpu_field(spsr));
4492 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4493 * only call the helper when running single threaded TCG code to ensure
4494 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4495 * just skip this instruction. Currently the SEV/SEVL instructions
4496 * which are *one* of many ways to wake the CPU from WFE are not
4497 * implemented so we can't sleep like WFI does.
4499 static void gen_nop_hint(DisasContext *s, int val)
4501 switch (val) {
4502 case 1: /* yield */
4503 if (!parallel_cpus) {
4504 gen_set_pc_im(s, s->pc);
4505 s->is_jmp = DISAS_YIELD;
4507 break;
4508 case 3: /* wfi */
4509 gen_set_pc_im(s, s->pc);
4510 s->is_jmp = DISAS_WFI;
4511 break;
4512 case 2: /* wfe */
4513 if (!parallel_cpus) {
4514 gen_set_pc_im(s, s->pc);
4515 s->is_jmp = DISAS_WFE;
4517 break;
4518 case 4: /* sev */
4519 case 5: /* sevl */
4520 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4521 default: /* nop */
4522 break;
4526 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4528 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4530 switch (size) {
4531 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4532 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4533 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4534 default: abort();
4538 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4540 switch (size) {
4541 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4542 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4543 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4544 default: return;
4548 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4549 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4550 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4551 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4552 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4554 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4555 switch ((size << 1) | u) { \
4556 case 0: \
4557 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4558 break; \
4559 case 1: \
4560 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4561 break; \
4562 case 2: \
4563 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4564 break; \
4565 case 3: \
4566 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4567 break; \
4568 case 4: \
4569 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4570 break; \
4571 case 5: \
4572 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4573 break; \
4574 default: return 1; \
4575 }} while (0)
4577 #define GEN_NEON_INTEGER_OP(name) do { \
4578 switch ((size << 1) | u) { \
4579 case 0: \
4580 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4581 break; \
4582 case 1: \
4583 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4584 break; \
4585 case 2: \
4586 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4587 break; \
4588 case 3: \
4589 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4590 break; \
4591 case 4: \
4592 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4593 break; \
4594 case 5: \
4595 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4596 break; \
4597 default: return 1; \
4598 }} while (0)
4600 static TCGv_i32 neon_load_scratch(int scratch)
4602 TCGv_i32 tmp = tcg_temp_new_i32();
4603 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4604 return tmp;
4607 static void neon_store_scratch(int scratch, TCGv_i32 var)
4609 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4610 tcg_temp_free_i32(var);
4613 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4615 TCGv_i32 tmp;
4616 if (size == 1) {
4617 tmp = neon_load_reg(reg & 7, reg >> 4);
4618 if (reg & 8) {
4619 gen_neon_dup_high16(tmp);
4620 } else {
4621 gen_neon_dup_low16(tmp);
4623 } else {
4624 tmp = neon_load_reg(reg & 15, reg >> 4);
4626 return tmp;
4629 static int gen_neon_unzip(int rd, int rm, int size, int q)
4631 TCGv_i32 tmp, tmp2;
4632 if (!q && size == 2) {
4633 return 1;
4635 tmp = tcg_const_i32(rd);
4636 tmp2 = tcg_const_i32(rm);
4637 if (q) {
4638 switch (size) {
4639 case 0:
4640 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4641 break;
4642 case 1:
4643 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4644 break;
4645 case 2:
4646 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4647 break;
4648 default:
4649 abort();
4651 } else {
4652 switch (size) {
4653 case 0:
4654 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4655 break;
4656 case 1:
4657 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4658 break;
4659 default:
4660 abort();
4663 tcg_temp_free_i32(tmp);
4664 tcg_temp_free_i32(tmp2);
4665 return 0;
4668 static int gen_neon_zip(int rd, int rm, int size, int q)
4670 TCGv_i32 tmp, tmp2;
4671 if (!q && size == 2) {
4672 return 1;
4674 tmp = tcg_const_i32(rd);
4675 tmp2 = tcg_const_i32(rm);
4676 if (q) {
4677 switch (size) {
4678 case 0:
4679 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4680 break;
4681 case 1:
4682 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4683 break;
4684 case 2:
4685 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4686 break;
4687 default:
4688 abort();
4690 } else {
4691 switch (size) {
4692 case 0:
4693 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4694 break;
4695 case 1:
4696 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4697 break;
4698 default:
4699 abort();
4702 tcg_temp_free_i32(tmp);
4703 tcg_temp_free_i32(tmp2);
4704 return 0;
4707 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4709 TCGv_i32 rd, tmp;
4711 rd = tcg_temp_new_i32();
4712 tmp = tcg_temp_new_i32();
4714 tcg_gen_shli_i32(rd, t0, 8);
4715 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4716 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4717 tcg_gen_or_i32(rd, rd, tmp);
4719 tcg_gen_shri_i32(t1, t1, 8);
4720 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4721 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4722 tcg_gen_or_i32(t1, t1, tmp);
4723 tcg_gen_mov_i32(t0, rd);
4725 tcg_temp_free_i32(tmp);
4726 tcg_temp_free_i32(rd);
4729 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4731 TCGv_i32 rd, tmp;
4733 rd = tcg_temp_new_i32();
4734 tmp = tcg_temp_new_i32();
4736 tcg_gen_shli_i32(rd, t0, 16);
4737 tcg_gen_andi_i32(tmp, t1, 0xffff);
4738 tcg_gen_or_i32(rd, rd, tmp);
4739 tcg_gen_shri_i32(t1, t1, 16);
4740 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4741 tcg_gen_or_i32(t1, t1, tmp);
4742 tcg_gen_mov_i32(t0, rd);
4744 tcg_temp_free_i32(tmp);
4745 tcg_temp_free_i32(rd);
4749 static struct {
4750 int nregs;
4751 int interleave;
4752 int spacing;
4753 } neon_ls_element_type[11] = {
4754 {4, 4, 1},
4755 {4, 4, 2},
4756 {4, 1, 1},
4757 {4, 2, 1},
4758 {3, 3, 1},
4759 {3, 3, 2},
4760 {3, 1, 1},
4761 {1, 1, 1},
4762 {2, 2, 1},
4763 {2, 2, 2},
4764 {2, 1, 1}
4767 /* Translate a NEON load/store element instruction. Return nonzero if the
4768 instruction is invalid. */
4769 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4771 int rd, rn, rm;
4772 int op;
4773 int nregs;
4774 int interleave;
4775 int spacing;
4776 int stride;
4777 int size;
4778 int reg;
4779 int pass;
4780 int load;
4781 int shift;
4782 int n;
4783 TCGv_i32 addr;
4784 TCGv_i32 tmp;
4785 TCGv_i32 tmp2;
4786 TCGv_i64 tmp64;
4788 /* FIXME: this access check should not take precedence over UNDEF
4789 * for invalid encodings; we will generate incorrect syndrome information
4790 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4792 if (s->fp_excp_el) {
4793 gen_exception_insn(s, 4, EXCP_UDEF,
4794 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4795 return 0;
4798 if (!s->vfp_enabled)
4799 return 1;
4800 VFP_DREG_D(rd, insn);
4801 rn = (insn >> 16) & 0xf;
4802 rm = insn & 0xf;
4803 load = (insn & (1 << 21)) != 0;
4804 if ((insn & (1 << 23)) == 0) {
4805 /* Load store all elements. */
4806 op = (insn >> 8) & 0xf;
4807 size = (insn >> 6) & 3;
4808 if (op > 10)
4809 return 1;
4810 /* Catch UNDEF cases for bad values of align field */
4811 switch (op & 0xc) {
4812 case 4:
4813 if (((insn >> 5) & 1) == 1) {
4814 return 1;
4816 break;
4817 case 8:
4818 if (((insn >> 4) & 3) == 3) {
4819 return 1;
4821 break;
4822 default:
4823 break;
4825 nregs = neon_ls_element_type[op].nregs;
4826 interleave = neon_ls_element_type[op].interleave;
4827 spacing = neon_ls_element_type[op].spacing;
4828 if (size == 3 && (interleave | spacing) != 1)
4829 return 1;
4830 addr = tcg_temp_new_i32();
4831 load_reg_var(s, addr, rn);
4832 stride = (1 << size) * interleave;
4833 for (reg = 0; reg < nregs; reg++) {
4834 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4835 load_reg_var(s, addr, rn);
4836 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4837 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4838 load_reg_var(s, addr, rn);
4839 tcg_gen_addi_i32(addr, addr, 1 << size);
4841 if (size == 3) {
4842 tmp64 = tcg_temp_new_i64();
4843 if (load) {
4844 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4845 neon_store_reg64(tmp64, rd);
4846 } else {
4847 neon_load_reg64(tmp64, rd);
4848 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4850 tcg_temp_free_i64(tmp64);
4851 tcg_gen_addi_i32(addr, addr, stride);
4852 } else {
4853 for (pass = 0; pass < 2; pass++) {
4854 if (size == 2) {
4855 if (load) {
4856 tmp = tcg_temp_new_i32();
4857 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4858 neon_store_reg(rd, pass, tmp);
4859 } else {
4860 tmp = neon_load_reg(rd, pass);
4861 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4862 tcg_temp_free_i32(tmp);
4864 tcg_gen_addi_i32(addr, addr, stride);
4865 } else if (size == 1) {
4866 if (load) {
4867 tmp = tcg_temp_new_i32();
4868 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4869 tcg_gen_addi_i32(addr, addr, stride);
4870 tmp2 = tcg_temp_new_i32();
4871 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4872 tcg_gen_addi_i32(addr, addr, stride);
4873 tcg_gen_shli_i32(tmp2, tmp2, 16);
4874 tcg_gen_or_i32(tmp, tmp, tmp2);
4875 tcg_temp_free_i32(tmp2);
4876 neon_store_reg(rd, pass, tmp);
4877 } else {
4878 tmp = neon_load_reg(rd, pass);
4879 tmp2 = tcg_temp_new_i32();
4880 tcg_gen_shri_i32(tmp2, tmp, 16);
4881 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4882 tcg_temp_free_i32(tmp);
4883 tcg_gen_addi_i32(addr, addr, stride);
4884 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4885 tcg_temp_free_i32(tmp2);
4886 tcg_gen_addi_i32(addr, addr, stride);
4888 } else /* size == 0 */ {
4889 if (load) {
4890 TCGV_UNUSED_I32(tmp2);
4891 for (n = 0; n < 4; n++) {
4892 tmp = tcg_temp_new_i32();
4893 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4894 tcg_gen_addi_i32(addr, addr, stride);
4895 if (n == 0) {
4896 tmp2 = tmp;
4897 } else {
4898 tcg_gen_shli_i32(tmp, tmp, n * 8);
4899 tcg_gen_or_i32(tmp2, tmp2, tmp);
4900 tcg_temp_free_i32(tmp);
4903 neon_store_reg(rd, pass, tmp2);
4904 } else {
4905 tmp2 = neon_load_reg(rd, pass);
4906 for (n = 0; n < 4; n++) {
4907 tmp = tcg_temp_new_i32();
4908 if (n == 0) {
4909 tcg_gen_mov_i32(tmp, tmp2);
4910 } else {
4911 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4913 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4914 tcg_temp_free_i32(tmp);
4915 tcg_gen_addi_i32(addr, addr, stride);
4917 tcg_temp_free_i32(tmp2);
4922 rd += spacing;
4924 tcg_temp_free_i32(addr);
4925 stride = nregs * 8;
4926 } else {
4927 size = (insn >> 10) & 3;
4928 if (size == 3) {
4929 /* Load single element to all lanes. */
4930 int a = (insn >> 4) & 1;
4931 if (!load) {
4932 return 1;
4934 size = (insn >> 6) & 3;
4935 nregs = ((insn >> 8) & 3) + 1;
4937 if (size == 3) {
4938 if (nregs != 4 || a == 0) {
4939 return 1;
4941 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4942 size = 2;
4944 if (nregs == 1 && a == 1 && size == 0) {
4945 return 1;
4947 if (nregs == 3 && a == 1) {
4948 return 1;
4950 addr = tcg_temp_new_i32();
4951 load_reg_var(s, addr, rn);
4952 if (nregs == 1) {
4953 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4954 tmp = gen_load_and_replicate(s, addr, size);
4955 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4956 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4957 if (insn & (1 << 5)) {
4958 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4959 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4961 tcg_temp_free_i32(tmp);
4962 } else {
4963 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4964 stride = (insn & (1 << 5)) ? 2 : 1;
4965 for (reg = 0; reg < nregs; reg++) {
4966 tmp = gen_load_and_replicate(s, addr, size);
4967 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4968 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4969 tcg_temp_free_i32(tmp);
4970 tcg_gen_addi_i32(addr, addr, 1 << size);
4971 rd += stride;
4974 tcg_temp_free_i32(addr);
4975 stride = (1 << size) * nregs;
4976 } else {
4977 /* Single element. */
4978 int idx = (insn >> 4) & 0xf;
4979 pass = (insn >> 7) & 1;
4980 switch (size) {
4981 case 0:
4982 shift = ((insn >> 5) & 3) * 8;
4983 stride = 1;
4984 break;
4985 case 1:
4986 shift = ((insn >> 6) & 1) * 16;
4987 stride = (insn & (1 << 5)) ? 2 : 1;
4988 break;
4989 case 2:
4990 shift = 0;
4991 stride = (insn & (1 << 6)) ? 2 : 1;
4992 break;
4993 default:
4994 abort();
4996 nregs = ((insn >> 8) & 3) + 1;
4997 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4998 switch (nregs) {
4999 case 1:
5000 if (((idx & (1 << size)) != 0) ||
5001 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5002 return 1;
5004 break;
5005 case 3:
5006 if ((idx & 1) != 0) {
5007 return 1;
5009 /* fall through */
5010 case 2:
5011 if (size == 2 && (idx & 2) != 0) {
5012 return 1;
5014 break;
5015 case 4:
5016 if ((size == 2) && ((idx & 3) == 3)) {
5017 return 1;
5019 break;
5020 default:
5021 abort();
5023 if ((rd + stride * (nregs - 1)) > 31) {
5024 /* Attempts to write off the end of the register file
5025 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5026 * the neon_load_reg() would write off the end of the array.
5028 return 1;
5030 addr = tcg_temp_new_i32();
5031 load_reg_var(s, addr, rn);
5032 for (reg = 0; reg < nregs; reg++) {
5033 if (load) {
5034 tmp = tcg_temp_new_i32();
5035 switch (size) {
5036 case 0:
5037 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5038 break;
5039 case 1:
5040 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5041 break;
5042 case 2:
5043 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5044 break;
5045 default: /* Avoid compiler warnings. */
5046 abort();
5048 if (size != 2) {
5049 tmp2 = neon_load_reg(rd, pass);
5050 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5051 shift, size ? 16 : 8);
5052 tcg_temp_free_i32(tmp2);
5054 neon_store_reg(rd, pass, tmp);
5055 } else { /* Store */
5056 tmp = neon_load_reg(rd, pass);
5057 if (shift)
5058 tcg_gen_shri_i32(tmp, tmp, shift);
5059 switch (size) {
5060 case 0:
5061 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5062 break;
5063 case 1:
5064 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5065 break;
5066 case 2:
5067 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5068 break;
5070 tcg_temp_free_i32(tmp);
5072 rd += stride;
5073 tcg_gen_addi_i32(addr, addr, 1 << size);
5075 tcg_temp_free_i32(addr);
5076 stride = nregs * (1 << size);
5079 if (rm != 15) {
5080 TCGv_i32 base;
5082 base = load_reg(s, rn);
5083 if (rm == 13) {
5084 tcg_gen_addi_i32(base, base, stride);
5085 } else {
5086 TCGv_i32 index;
5087 index = load_reg(s, rm);
5088 tcg_gen_add_i32(base, base, index);
5089 tcg_temp_free_i32(index);
5091 store_reg(s, rn, base);
5093 return 0;
5096 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5097 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5099 tcg_gen_and_i32(t, t, c);
5100 tcg_gen_andc_i32(f, f, c);
5101 tcg_gen_or_i32(dest, t, f);
5104 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5106 switch (size) {
5107 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5108 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5109 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5110 default: abort();
5114 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5116 switch (size) {
5117 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5118 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5119 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5120 default: abort();
5124 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5126 switch (size) {
5127 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5128 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5129 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5130 default: abort();
5134 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5136 switch (size) {
5137 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5138 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5139 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5140 default: abort();
5144 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5145 int q, int u)
5147 if (q) {
5148 if (u) {
5149 switch (size) {
5150 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5151 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5152 default: abort();
5154 } else {
5155 switch (size) {
5156 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5157 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5158 default: abort();
5161 } else {
5162 if (u) {
5163 switch (size) {
5164 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5165 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5166 default: abort();
5168 } else {
5169 switch (size) {
5170 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5171 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5172 default: abort();
5178 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5180 if (u) {
5181 switch (size) {
5182 case 0: gen_helper_neon_widen_u8(dest, src); break;
5183 case 1: gen_helper_neon_widen_u16(dest, src); break;
5184 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5185 default: abort();
5187 } else {
5188 switch (size) {
5189 case 0: gen_helper_neon_widen_s8(dest, src); break;
5190 case 1: gen_helper_neon_widen_s16(dest, src); break;
5191 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5192 default: abort();
5195 tcg_temp_free_i32(src);
5198 static inline void gen_neon_addl(int size)
5200 switch (size) {
5201 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5202 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5203 case 2: tcg_gen_add_i64(CPU_V001); break;
5204 default: abort();
5208 static inline void gen_neon_subl(int size)
5210 switch (size) {
5211 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5212 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5213 case 2: tcg_gen_sub_i64(CPU_V001); break;
5214 default: abort();
5218 static inline void gen_neon_negl(TCGv_i64 var, int size)
5220 switch (size) {
5221 case 0: gen_helper_neon_negl_u16(var, var); break;
5222 case 1: gen_helper_neon_negl_u32(var, var); break;
5223 case 2:
5224 tcg_gen_neg_i64(var, var);
5225 break;
5226 default: abort();
5230 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5232 switch (size) {
5233 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5234 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5235 default: abort();
5239 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5240 int size, int u)
5242 TCGv_i64 tmp;
5244 switch ((size << 1) | u) {
5245 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5246 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5247 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5248 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5249 case 4:
5250 tmp = gen_muls_i64_i32(a, b);
5251 tcg_gen_mov_i64(dest, tmp);
5252 tcg_temp_free_i64(tmp);
5253 break;
5254 case 5:
5255 tmp = gen_mulu_i64_i32(a, b);
5256 tcg_gen_mov_i64(dest, tmp);
5257 tcg_temp_free_i64(tmp);
5258 break;
5259 default: abort();
5262 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5263 Don't forget to clean them now. */
5264 if (size < 2) {
5265 tcg_temp_free_i32(a);
5266 tcg_temp_free_i32(b);
5270 static void gen_neon_narrow_op(int op, int u, int size,
5271 TCGv_i32 dest, TCGv_i64 src)
5273 if (op) {
5274 if (u) {
5275 gen_neon_unarrow_sats(size, dest, src);
5276 } else {
5277 gen_neon_narrow(size, dest, src);
5279 } else {
5280 if (u) {
5281 gen_neon_narrow_satu(size, dest, src);
5282 } else {
5283 gen_neon_narrow_sats(size, dest, src);
5288 /* Symbolic constants for op fields for Neon 3-register same-length.
5289 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5290 * table A7-9.
5292 #define NEON_3R_VHADD 0
5293 #define NEON_3R_VQADD 1
5294 #define NEON_3R_VRHADD 2
5295 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5296 #define NEON_3R_VHSUB 4
5297 #define NEON_3R_VQSUB 5
5298 #define NEON_3R_VCGT 6
5299 #define NEON_3R_VCGE 7
5300 #define NEON_3R_VSHL 8
5301 #define NEON_3R_VQSHL 9
5302 #define NEON_3R_VRSHL 10
5303 #define NEON_3R_VQRSHL 11
5304 #define NEON_3R_VMAX 12
5305 #define NEON_3R_VMIN 13
5306 #define NEON_3R_VABD 14
5307 #define NEON_3R_VABA 15
5308 #define NEON_3R_VADD_VSUB 16
5309 #define NEON_3R_VTST_VCEQ 17
5310 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5311 #define NEON_3R_VMUL 19
5312 #define NEON_3R_VPMAX 20
5313 #define NEON_3R_VPMIN 21
5314 #define NEON_3R_VQDMULH_VQRDMULH 22
5315 #define NEON_3R_VPADD 23
5316 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5317 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5318 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5319 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5320 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5321 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5322 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5323 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5325 static const uint8_t neon_3r_sizes[] = {
5326 [NEON_3R_VHADD] = 0x7,
5327 [NEON_3R_VQADD] = 0xf,
5328 [NEON_3R_VRHADD] = 0x7,
5329 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5330 [NEON_3R_VHSUB] = 0x7,
5331 [NEON_3R_VQSUB] = 0xf,
5332 [NEON_3R_VCGT] = 0x7,
5333 [NEON_3R_VCGE] = 0x7,
5334 [NEON_3R_VSHL] = 0xf,
5335 [NEON_3R_VQSHL] = 0xf,
5336 [NEON_3R_VRSHL] = 0xf,
5337 [NEON_3R_VQRSHL] = 0xf,
5338 [NEON_3R_VMAX] = 0x7,
5339 [NEON_3R_VMIN] = 0x7,
5340 [NEON_3R_VABD] = 0x7,
5341 [NEON_3R_VABA] = 0x7,
5342 [NEON_3R_VADD_VSUB] = 0xf,
5343 [NEON_3R_VTST_VCEQ] = 0x7,
5344 [NEON_3R_VML] = 0x7,
5345 [NEON_3R_VMUL] = 0x7,
5346 [NEON_3R_VPMAX] = 0x7,
5347 [NEON_3R_VPMIN] = 0x7,
5348 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5349 [NEON_3R_VPADD] = 0x7,
5350 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5351 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5352 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5353 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5354 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5355 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5356 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5357 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5360 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5361 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5362 * table A7-13.
5364 #define NEON_2RM_VREV64 0
5365 #define NEON_2RM_VREV32 1
5366 #define NEON_2RM_VREV16 2
5367 #define NEON_2RM_VPADDL 4
5368 #define NEON_2RM_VPADDL_U 5
5369 #define NEON_2RM_AESE 6 /* Includes AESD */
5370 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5371 #define NEON_2RM_VCLS 8
5372 #define NEON_2RM_VCLZ 9
5373 #define NEON_2RM_VCNT 10
5374 #define NEON_2RM_VMVN 11
5375 #define NEON_2RM_VPADAL 12
5376 #define NEON_2RM_VPADAL_U 13
5377 #define NEON_2RM_VQABS 14
5378 #define NEON_2RM_VQNEG 15
5379 #define NEON_2RM_VCGT0 16
5380 #define NEON_2RM_VCGE0 17
5381 #define NEON_2RM_VCEQ0 18
5382 #define NEON_2RM_VCLE0 19
5383 #define NEON_2RM_VCLT0 20
5384 #define NEON_2RM_SHA1H 21
5385 #define NEON_2RM_VABS 22
5386 #define NEON_2RM_VNEG 23
5387 #define NEON_2RM_VCGT0_F 24
5388 #define NEON_2RM_VCGE0_F 25
5389 #define NEON_2RM_VCEQ0_F 26
5390 #define NEON_2RM_VCLE0_F 27
5391 #define NEON_2RM_VCLT0_F 28
5392 #define NEON_2RM_VABS_F 30
5393 #define NEON_2RM_VNEG_F 31
5394 #define NEON_2RM_VSWP 32
5395 #define NEON_2RM_VTRN 33
5396 #define NEON_2RM_VUZP 34
5397 #define NEON_2RM_VZIP 35
5398 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5399 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5400 #define NEON_2RM_VSHLL 38
5401 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5402 #define NEON_2RM_VRINTN 40
5403 #define NEON_2RM_VRINTX 41
5404 #define NEON_2RM_VRINTA 42
5405 #define NEON_2RM_VRINTZ 43
5406 #define NEON_2RM_VCVT_F16_F32 44
5407 #define NEON_2RM_VRINTM 45
5408 #define NEON_2RM_VCVT_F32_F16 46
5409 #define NEON_2RM_VRINTP 47
5410 #define NEON_2RM_VCVTAU 48
5411 #define NEON_2RM_VCVTAS 49
5412 #define NEON_2RM_VCVTNU 50
5413 #define NEON_2RM_VCVTNS 51
5414 #define NEON_2RM_VCVTPU 52
5415 #define NEON_2RM_VCVTPS 53
5416 #define NEON_2RM_VCVTMU 54
5417 #define NEON_2RM_VCVTMS 55
5418 #define NEON_2RM_VRECPE 56
5419 #define NEON_2RM_VRSQRTE 57
5420 #define NEON_2RM_VRECPE_F 58
5421 #define NEON_2RM_VRSQRTE_F 59
5422 #define NEON_2RM_VCVT_FS 60
5423 #define NEON_2RM_VCVT_FU 61
5424 #define NEON_2RM_VCVT_SF 62
5425 #define NEON_2RM_VCVT_UF 63
5427 static int neon_2rm_is_float_op(int op)
5429 /* Return true if this neon 2reg-misc op is float-to-float */
5430 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5431 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5432 op == NEON_2RM_VRINTM ||
5433 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5434 op >= NEON_2RM_VRECPE_F);
5437 static bool neon_2rm_is_v8_op(int op)
5439 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5440 switch (op) {
5441 case NEON_2RM_VRINTN:
5442 case NEON_2RM_VRINTA:
5443 case NEON_2RM_VRINTM:
5444 case NEON_2RM_VRINTP:
5445 case NEON_2RM_VRINTZ:
5446 case NEON_2RM_VRINTX:
5447 case NEON_2RM_VCVTAU:
5448 case NEON_2RM_VCVTAS:
5449 case NEON_2RM_VCVTNU:
5450 case NEON_2RM_VCVTNS:
5451 case NEON_2RM_VCVTPU:
5452 case NEON_2RM_VCVTPS:
5453 case NEON_2RM_VCVTMU:
5454 case NEON_2RM_VCVTMS:
5455 return true;
5456 default:
5457 return false;
5461 /* Each entry in this array has bit n set if the insn allows
5462 * size value n (otherwise it will UNDEF). Since unallocated
5463 * op values will have no bits set they always UNDEF.
5465 static const uint8_t neon_2rm_sizes[] = {
5466 [NEON_2RM_VREV64] = 0x7,
5467 [NEON_2RM_VREV32] = 0x3,
5468 [NEON_2RM_VREV16] = 0x1,
5469 [NEON_2RM_VPADDL] = 0x7,
5470 [NEON_2RM_VPADDL_U] = 0x7,
5471 [NEON_2RM_AESE] = 0x1,
5472 [NEON_2RM_AESMC] = 0x1,
5473 [NEON_2RM_VCLS] = 0x7,
5474 [NEON_2RM_VCLZ] = 0x7,
5475 [NEON_2RM_VCNT] = 0x1,
5476 [NEON_2RM_VMVN] = 0x1,
5477 [NEON_2RM_VPADAL] = 0x7,
5478 [NEON_2RM_VPADAL_U] = 0x7,
5479 [NEON_2RM_VQABS] = 0x7,
5480 [NEON_2RM_VQNEG] = 0x7,
5481 [NEON_2RM_VCGT0] = 0x7,
5482 [NEON_2RM_VCGE0] = 0x7,
5483 [NEON_2RM_VCEQ0] = 0x7,
5484 [NEON_2RM_VCLE0] = 0x7,
5485 [NEON_2RM_VCLT0] = 0x7,
5486 [NEON_2RM_SHA1H] = 0x4,
5487 [NEON_2RM_VABS] = 0x7,
5488 [NEON_2RM_VNEG] = 0x7,
5489 [NEON_2RM_VCGT0_F] = 0x4,
5490 [NEON_2RM_VCGE0_F] = 0x4,
5491 [NEON_2RM_VCEQ0_F] = 0x4,
5492 [NEON_2RM_VCLE0_F] = 0x4,
5493 [NEON_2RM_VCLT0_F] = 0x4,
5494 [NEON_2RM_VABS_F] = 0x4,
5495 [NEON_2RM_VNEG_F] = 0x4,
5496 [NEON_2RM_VSWP] = 0x1,
5497 [NEON_2RM_VTRN] = 0x7,
5498 [NEON_2RM_VUZP] = 0x7,
5499 [NEON_2RM_VZIP] = 0x7,
5500 [NEON_2RM_VMOVN] = 0x7,
5501 [NEON_2RM_VQMOVN] = 0x7,
5502 [NEON_2RM_VSHLL] = 0x7,
5503 [NEON_2RM_SHA1SU1] = 0x4,
5504 [NEON_2RM_VRINTN] = 0x4,
5505 [NEON_2RM_VRINTX] = 0x4,
5506 [NEON_2RM_VRINTA] = 0x4,
5507 [NEON_2RM_VRINTZ] = 0x4,
5508 [NEON_2RM_VCVT_F16_F32] = 0x2,
5509 [NEON_2RM_VRINTM] = 0x4,
5510 [NEON_2RM_VCVT_F32_F16] = 0x2,
5511 [NEON_2RM_VRINTP] = 0x4,
5512 [NEON_2RM_VCVTAU] = 0x4,
5513 [NEON_2RM_VCVTAS] = 0x4,
5514 [NEON_2RM_VCVTNU] = 0x4,
5515 [NEON_2RM_VCVTNS] = 0x4,
5516 [NEON_2RM_VCVTPU] = 0x4,
5517 [NEON_2RM_VCVTPS] = 0x4,
5518 [NEON_2RM_VCVTMU] = 0x4,
5519 [NEON_2RM_VCVTMS] = 0x4,
5520 [NEON_2RM_VRECPE] = 0x4,
5521 [NEON_2RM_VRSQRTE] = 0x4,
5522 [NEON_2RM_VRECPE_F] = 0x4,
5523 [NEON_2RM_VRSQRTE_F] = 0x4,
5524 [NEON_2RM_VCVT_FS] = 0x4,
5525 [NEON_2RM_VCVT_FU] = 0x4,
5526 [NEON_2RM_VCVT_SF] = 0x4,
5527 [NEON_2RM_VCVT_UF] = 0x4,
5530 /* Translate a NEON data processing instruction. Return nonzero if the
5531 instruction is invalid.
5532 We process data in a mixture of 32-bit and 64-bit chunks.
5533 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5535 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5537 int op;
5538 int q;
5539 int rd, rn, rm;
5540 int size;
5541 int shift;
5542 int pass;
5543 int count;
5544 int pairwise;
5545 int u;
5546 uint32_t imm, mask;
5547 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5548 TCGv_i64 tmp64;
5550 /* FIXME: this access check should not take precedence over UNDEF
5551 * for invalid encodings; we will generate incorrect syndrome information
5552 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5554 if (s->fp_excp_el) {
5555 gen_exception_insn(s, 4, EXCP_UDEF,
5556 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5557 return 0;
5560 if (!s->vfp_enabled)
5561 return 1;
5562 q = (insn & (1 << 6)) != 0;
5563 u = (insn >> 24) & 1;
5564 VFP_DREG_D(rd, insn);
5565 VFP_DREG_N(rn, insn);
5566 VFP_DREG_M(rm, insn);
5567 size = (insn >> 20) & 3;
5568 if ((insn & (1 << 23)) == 0) {
5569 /* Three register same length. */
5570 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5571 /* Catch invalid op and bad size combinations: UNDEF */
5572 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5573 return 1;
5575 /* All insns of this form UNDEF for either this condition or the
5576 * superset of cases "Q==1"; we catch the latter later.
5578 if (q && ((rd | rn | rm) & 1)) {
5579 return 1;
5582 * The SHA-1/SHA-256 3-register instructions require special treatment
5583 * here, as their size field is overloaded as an op type selector, and
5584 * they all consume their input in a single pass.
5586 if (op == NEON_3R_SHA) {
5587 if (!q) {
5588 return 1;
5590 if (!u) { /* SHA-1 */
5591 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5592 return 1;
5594 tmp = tcg_const_i32(rd);
5595 tmp2 = tcg_const_i32(rn);
5596 tmp3 = tcg_const_i32(rm);
5597 tmp4 = tcg_const_i32(size);
5598 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5599 tcg_temp_free_i32(tmp4);
5600 } else { /* SHA-256 */
5601 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5602 return 1;
5604 tmp = tcg_const_i32(rd);
5605 tmp2 = tcg_const_i32(rn);
5606 tmp3 = tcg_const_i32(rm);
5607 switch (size) {
5608 case 0:
5609 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5610 break;
5611 case 1:
5612 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5613 break;
5614 case 2:
5615 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5616 break;
5619 tcg_temp_free_i32(tmp);
5620 tcg_temp_free_i32(tmp2);
5621 tcg_temp_free_i32(tmp3);
5622 return 0;
5624 if (size == 3 && op != NEON_3R_LOGIC) {
5625 /* 64-bit element instructions. */
5626 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5627 neon_load_reg64(cpu_V0, rn + pass);
5628 neon_load_reg64(cpu_V1, rm + pass);
5629 switch (op) {
5630 case NEON_3R_VQADD:
5631 if (u) {
5632 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5633 cpu_V0, cpu_V1);
5634 } else {
5635 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5636 cpu_V0, cpu_V1);
5638 break;
5639 case NEON_3R_VQSUB:
5640 if (u) {
5641 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5642 cpu_V0, cpu_V1);
5643 } else {
5644 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5645 cpu_V0, cpu_V1);
5647 break;
5648 case NEON_3R_VSHL:
5649 if (u) {
5650 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5651 } else {
5652 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5654 break;
5655 case NEON_3R_VQSHL:
5656 if (u) {
5657 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5658 cpu_V1, cpu_V0);
5659 } else {
5660 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5661 cpu_V1, cpu_V0);
5663 break;
5664 case NEON_3R_VRSHL:
5665 if (u) {
5666 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5667 } else {
5668 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5670 break;
5671 case NEON_3R_VQRSHL:
5672 if (u) {
5673 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5674 cpu_V1, cpu_V0);
5675 } else {
5676 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5677 cpu_V1, cpu_V0);
5679 break;
5680 case NEON_3R_VADD_VSUB:
5681 if (u) {
5682 tcg_gen_sub_i64(CPU_V001);
5683 } else {
5684 tcg_gen_add_i64(CPU_V001);
5686 break;
5687 default:
5688 abort();
5690 neon_store_reg64(cpu_V0, rd + pass);
5692 return 0;
5694 pairwise = 0;
5695 switch (op) {
5696 case NEON_3R_VSHL:
5697 case NEON_3R_VQSHL:
5698 case NEON_3R_VRSHL:
5699 case NEON_3R_VQRSHL:
5701 int rtmp;
5702 /* Shift instruction operands are reversed. */
5703 rtmp = rn;
5704 rn = rm;
5705 rm = rtmp;
5707 break;
5708 case NEON_3R_VPADD:
5709 if (u) {
5710 return 1;
5712 /* Fall through */
5713 case NEON_3R_VPMAX:
5714 case NEON_3R_VPMIN:
5715 pairwise = 1;
5716 break;
5717 case NEON_3R_FLOAT_ARITH:
5718 pairwise = (u && size < 2); /* if VPADD (float) */
5719 break;
5720 case NEON_3R_FLOAT_MINMAX:
5721 pairwise = u; /* if VPMIN/VPMAX (float) */
5722 break;
5723 case NEON_3R_FLOAT_CMP:
5724 if (!u && size) {
5725 /* no encoding for U=0 C=1x */
5726 return 1;
5728 break;
5729 case NEON_3R_FLOAT_ACMP:
5730 if (!u) {
5731 return 1;
5733 break;
5734 case NEON_3R_FLOAT_MISC:
5735 /* VMAXNM/VMINNM in ARMv8 */
5736 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5737 return 1;
5739 break;
5740 case NEON_3R_VMUL:
5741 if (u && (size != 0)) {
5742 /* UNDEF on invalid size for polynomial subcase */
5743 return 1;
5745 break;
5746 case NEON_3R_VFM:
5747 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5748 return 1;
5750 break;
5751 default:
5752 break;
5755 if (pairwise && q) {
5756 /* All the pairwise insns UNDEF if Q is set */
5757 return 1;
5760 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5762 if (pairwise) {
5763 /* Pairwise. */
5764 if (pass < 1) {
5765 tmp = neon_load_reg(rn, 0);
5766 tmp2 = neon_load_reg(rn, 1);
5767 } else {
5768 tmp = neon_load_reg(rm, 0);
5769 tmp2 = neon_load_reg(rm, 1);
5771 } else {
5772 /* Elementwise. */
5773 tmp = neon_load_reg(rn, pass);
5774 tmp2 = neon_load_reg(rm, pass);
5776 switch (op) {
5777 case NEON_3R_VHADD:
5778 GEN_NEON_INTEGER_OP(hadd);
5779 break;
5780 case NEON_3R_VQADD:
5781 GEN_NEON_INTEGER_OP_ENV(qadd);
5782 break;
5783 case NEON_3R_VRHADD:
5784 GEN_NEON_INTEGER_OP(rhadd);
5785 break;
5786 case NEON_3R_LOGIC: /* Logic ops. */
5787 switch ((u << 2) | size) {
5788 case 0: /* VAND */
5789 tcg_gen_and_i32(tmp, tmp, tmp2);
5790 break;
5791 case 1: /* BIC */
5792 tcg_gen_andc_i32(tmp, tmp, tmp2);
5793 break;
5794 case 2: /* VORR */
5795 tcg_gen_or_i32(tmp, tmp, tmp2);
5796 break;
5797 case 3: /* VORN */
5798 tcg_gen_orc_i32(tmp, tmp, tmp2);
5799 break;
5800 case 4: /* VEOR */
5801 tcg_gen_xor_i32(tmp, tmp, tmp2);
5802 break;
5803 case 5: /* VBSL */
5804 tmp3 = neon_load_reg(rd, pass);
5805 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5806 tcg_temp_free_i32(tmp3);
5807 break;
5808 case 6: /* VBIT */
5809 tmp3 = neon_load_reg(rd, pass);
5810 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5811 tcg_temp_free_i32(tmp3);
5812 break;
5813 case 7: /* VBIF */
5814 tmp3 = neon_load_reg(rd, pass);
5815 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5816 tcg_temp_free_i32(tmp3);
5817 break;
5819 break;
5820 case NEON_3R_VHSUB:
5821 GEN_NEON_INTEGER_OP(hsub);
5822 break;
5823 case NEON_3R_VQSUB:
5824 GEN_NEON_INTEGER_OP_ENV(qsub);
5825 break;
5826 case NEON_3R_VCGT:
5827 GEN_NEON_INTEGER_OP(cgt);
5828 break;
5829 case NEON_3R_VCGE:
5830 GEN_NEON_INTEGER_OP(cge);
5831 break;
5832 case NEON_3R_VSHL:
5833 GEN_NEON_INTEGER_OP(shl);
5834 break;
5835 case NEON_3R_VQSHL:
5836 GEN_NEON_INTEGER_OP_ENV(qshl);
5837 break;
5838 case NEON_3R_VRSHL:
5839 GEN_NEON_INTEGER_OP(rshl);
5840 break;
5841 case NEON_3R_VQRSHL:
5842 GEN_NEON_INTEGER_OP_ENV(qrshl);
5843 break;
5844 case NEON_3R_VMAX:
5845 GEN_NEON_INTEGER_OP(max);
5846 break;
5847 case NEON_3R_VMIN:
5848 GEN_NEON_INTEGER_OP(min);
5849 break;
5850 case NEON_3R_VABD:
5851 GEN_NEON_INTEGER_OP(abd);
5852 break;
5853 case NEON_3R_VABA:
5854 GEN_NEON_INTEGER_OP(abd);
5855 tcg_temp_free_i32(tmp2);
5856 tmp2 = neon_load_reg(rd, pass);
5857 gen_neon_add(size, tmp, tmp2);
5858 break;
5859 case NEON_3R_VADD_VSUB:
5860 if (!u) { /* VADD */
5861 gen_neon_add(size, tmp, tmp2);
5862 } else { /* VSUB */
5863 switch (size) {
5864 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5865 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5866 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5867 default: abort();
5870 break;
5871 case NEON_3R_VTST_VCEQ:
5872 if (!u) { /* VTST */
5873 switch (size) {
5874 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5875 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5876 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5877 default: abort();
5879 } else { /* VCEQ */
5880 switch (size) {
5881 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5882 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5883 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5884 default: abort();
5887 break;
5888 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5889 switch (size) {
5890 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5891 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5892 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5893 default: abort();
5895 tcg_temp_free_i32(tmp2);
5896 tmp2 = neon_load_reg(rd, pass);
5897 if (u) { /* VMLS */
5898 gen_neon_rsb(size, tmp, tmp2);
5899 } else { /* VMLA */
5900 gen_neon_add(size, tmp, tmp2);
5902 break;
5903 case NEON_3R_VMUL:
5904 if (u) { /* polynomial */
5905 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5906 } else { /* Integer */
5907 switch (size) {
5908 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5909 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5910 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5911 default: abort();
5914 break;
5915 case NEON_3R_VPMAX:
5916 GEN_NEON_INTEGER_OP(pmax);
5917 break;
5918 case NEON_3R_VPMIN:
5919 GEN_NEON_INTEGER_OP(pmin);
5920 break;
5921 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5922 if (!u) { /* VQDMULH */
5923 switch (size) {
5924 case 1:
5925 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5926 break;
5927 case 2:
5928 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5929 break;
5930 default: abort();
5932 } else { /* VQRDMULH */
5933 switch (size) {
5934 case 1:
5935 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5936 break;
5937 case 2:
5938 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5939 break;
5940 default: abort();
5943 break;
5944 case NEON_3R_VPADD:
5945 switch (size) {
5946 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5947 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5948 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5949 default: abort();
5951 break;
5952 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5954 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5955 switch ((u << 2) | size) {
5956 case 0: /* VADD */
5957 case 4: /* VPADD */
5958 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5959 break;
5960 case 2: /* VSUB */
5961 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5962 break;
5963 case 6: /* VABD */
5964 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5965 break;
5966 default:
5967 abort();
5969 tcg_temp_free_ptr(fpstatus);
5970 break;
5972 case NEON_3R_FLOAT_MULTIPLY:
5974 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5975 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5976 if (!u) {
5977 tcg_temp_free_i32(tmp2);
5978 tmp2 = neon_load_reg(rd, pass);
5979 if (size == 0) {
5980 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5981 } else {
5982 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5985 tcg_temp_free_ptr(fpstatus);
5986 break;
5988 case NEON_3R_FLOAT_CMP:
5990 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5991 if (!u) {
5992 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5993 } else {
5994 if (size == 0) {
5995 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5996 } else {
5997 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6000 tcg_temp_free_ptr(fpstatus);
6001 break;
6003 case NEON_3R_FLOAT_ACMP:
6005 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6006 if (size == 0) {
6007 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6008 } else {
6009 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6011 tcg_temp_free_ptr(fpstatus);
6012 break;
6014 case NEON_3R_FLOAT_MINMAX:
6016 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6017 if (size == 0) {
6018 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6019 } else {
6020 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6022 tcg_temp_free_ptr(fpstatus);
6023 break;
6025 case NEON_3R_FLOAT_MISC:
6026 if (u) {
6027 /* VMAXNM/VMINNM */
6028 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6029 if (size == 0) {
6030 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6031 } else {
6032 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6034 tcg_temp_free_ptr(fpstatus);
6035 } else {
6036 if (size == 0) {
6037 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6038 } else {
6039 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6042 break;
6043 case NEON_3R_VFM:
6045 /* VFMA, VFMS: fused multiply-add */
6046 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6047 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6048 if (size) {
6049 /* VFMS */
6050 gen_helper_vfp_negs(tmp, tmp);
6052 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6053 tcg_temp_free_i32(tmp3);
6054 tcg_temp_free_ptr(fpstatus);
6055 break;
6057 default:
6058 abort();
6060 tcg_temp_free_i32(tmp2);
6062 /* Save the result. For elementwise operations we can put it
6063 straight into the destination register. For pairwise operations
6064 we have to be careful to avoid clobbering the source operands. */
6065 if (pairwise && rd == rm) {
6066 neon_store_scratch(pass, tmp);
6067 } else {
6068 neon_store_reg(rd, pass, tmp);
6071 } /* for pass */
6072 if (pairwise && rd == rm) {
6073 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6074 tmp = neon_load_scratch(pass);
6075 neon_store_reg(rd, pass, tmp);
6078 /* End of 3 register same size operations. */
6079 } else if (insn & (1 << 4)) {
6080 if ((insn & 0x00380080) != 0) {
6081 /* Two registers and shift. */
6082 op = (insn >> 8) & 0xf;
6083 if (insn & (1 << 7)) {
6084 /* 64-bit shift. */
6085 if (op > 7) {
6086 return 1;
6088 size = 3;
6089 } else {
6090 size = 2;
6091 while ((insn & (1 << (size + 19))) == 0)
6092 size--;
6094 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6095 /* To avoid excessive duplication of ops we implement shift
6096 by immediate using the variable shift operations. */
6097 if (op < 8) {
6098 /* Shift by immediate:
6099 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6100 if (q && ((rd | rm) & 1)) {
6101 return 1;
6103 if (!u && (op == 4 || op == 6)) {
6104 return 1;
6106 /* Right shifts are encoded as N - shift, where N is the
6107 element size in bits. */
6108 if (op <= 4)
6109 shift = shift - (1 << (size + 3));
6110 if (size == 3) {
6111 count = q + 1;
6112 } else {
6113 count = q ? 4: 2;
6115 switch (size) {
6116 case 0:
6117 imm = (uint8_t) shift;
6118 imm |= imm << 8;
6119 imm |= imm << 16;
6120 break;
6121 case 1:
6122 imm = (uint16_t) shift;
6123 imm |= imm << 16;
6124 break;
6125 case 2:
6126 case 3:
6127 imm = shift;
6128 break;
6129 default:
6130 abort();
6133 for (pass = 0; pass < count; pass++) {
6134 if (size == 3) {
6135 neon_load_reg64(cpu_V0, rm + pass);
6136 tcg_gen_movi_i64(cpu_V1, imm);
6137 switch (op) {
6138 case 0: /* VSHR */
6139 case 1: /* VSRA */
6140 if (u)
6141 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6142 else
6143 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6144 break;
6145 case 2: /* VRSHR */
6146 case 3: /* VRSRA */
6147 if (u)
6148 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6149 else
6150 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6151 break;
6152 case 4: /* VSRI */
6153 case 5: /* VSHL, VSLI */
6154 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6155 break;
6156 case 6: /* VQSHLU */
6157 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6158 cpu_V0, cpu_V1);
6159 break;
6160 case 7: /* VQSHL */
6161 if (u) {
6162 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6163 cpu_V0, cpu_V1);
6164 } else {
6165 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6166 cpu_V0, cpu_V1);
6168 break;
6170 if (op == 1 || op == 3) {
6171 /* Accumulate. */
6172 neon_load_reg64(cpu_V1, rd + pass);
6173 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6174 } else if (op == 4 || (op == 5 && u)) {
6175 /* Insert */
6176 neon_load_reg64(cpu_V1, rd + pass);
6177 uint64_t mask;
6178 if (shift < -63 || shift > 63) {
6179 mask = 0;
6180 } else {
6181 if (op == 4) {
6182 mask = 0xffffffffffffffffull >> -shift;
6183 } else {
6184 mask = 0xffffffffffffffffull << shift;
6187 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6188 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6190 neon_store_reg64(cpu_V0, rd + pass);
6191 } else { /* size < 3 */
6192 /* Operands in T0 and T1. */
6193 tmp = neon_load_reg(rm, pass);
6194 tmp2 = tcg_temp_new_i32();
6195 tcg_gen_movi_i32(tmp2, imm);
6196 switch (op) {
6197 case 0: /* VSHR */
6198 case 1: /* VSRA */
6199 GEN_NEON_INTEGER_OP(shl);
6200 break;
6201 case 2: /* VRSHR */
6202 case 3: /* VRSRA */
6203 GEN_NEON_INTEGER_OP(rshl);
6204 break;
6205 case 4: /* VSRI */
6206 case 5: /* VSHL, VSLI */
6207 switch (size) {
6208 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6209 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6210 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6211 default: abort();
6213 break;
6214 case 6: /* VQSHLU */
6215 switch (size) {
6216 case 0:
6217 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6218 tmp, tmp2);
6219 break;
6220 case 1:
6221 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6222 tmp, tmp2);
6223 break;
6224 case 2:
6225 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6226 tmp, tmp2);
6227 break;
6228 default:
6229 abort();
6231 break;
6232 case 7: /* VQSHL */
6233 GEN_NEON_INTEGER_OP_ENV(qshl);
6234 break;
6236 tcg_temp_free_i32(tmp2);
6238 if (op == 1 || op == 3) {
6239 /* Accumulate. */
6240 tmp2 = neon_load_reg(rd, pass);
6241 gen_neon_add(size, tmp, tmp2);
6242 tcg_temp_free_i32(tmp2);
6243 } else if (op == 4 || (op == 5 && u)) {
6244 /* Insert */
6245 switch (size) {
6246 case 0:
6247 if (op == 4)
6248 mask = 0xff >> -shift;
6249 else
6250 mask = (uint8_t)(0xff << shift);
6251 mask |= mask << 8;
6252 mask |= mask << 16;
6253 break;
6254 case 1:
6255 if (op == 4)
6256 mask = 0xffff >> -shift;
6257 else
6258 mask = (uint16_t)(0xffff << shift);
6259 mask |= mask << 16;
6260 break;
6261 case 2:
6262 if (shift < -31 || shift > 31) {
6263 mask = 0;
6264 } else {
6265 if (op == 4)
6266 mask = 0xffffffffu >> -shift;
6267 else
6268 mask = 0xffffffffu << shift;
6270 break;
6271 default:
6272 abort();
6274 tmp2 = neon_load_reg(rd, pass);
6275 tcg_gen_andi_i32(tmp, tmp, mask);
6276 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6277 tcg_gen_or_i32(tmp, tmp, tmp2);
6278 tcg_temp_free_i32(tmp2);
6280 neon_store_reg(rd, pass, tmp);
6282 } /* for pass */
6283 } else if (op < 10) {
6284 /* Shift by immediate and narrow:
6285 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6286 int input_unsigned = (op == 8) ? !u : u;
6287 if (rm & 1) {
6288 return 1;
6290 shift = shift - (1 << (size + 3));
6291 size++;
6292 if (size == 3) {
6293 tmp64 = tcg_const_i64(shift);
6294 neon_load_reg64(cpu_V0, rm);
6295 neon_load_reg64(cpu_V1, rm + 1);
6296 for (pass = 0; pass < 2; pass++) {
6297 TCGv_i64 in;
6298 if (pass == 0) {
6299 in = cpu_V0;
6300 } else {
6301 in = cpu_V1;
6303 if (q) {
6304 if (input_unsigned) {
6305 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6306 } else {
6307 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6309 } else {
6310 if (input_unsigned) {
6311 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6312 } else {
6313 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6316 tmp = tcg_temp_new_i32();
6317 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6318 neon_store_reg(rd, pass, tmp);
6319 } /* for pass */
6320 tcg_temp_free_i64(tmp64);
6321 } else {
6322 if (size == 1) {
6323 imm = (uint16_t)shift;
6324 imm |= imm << 16;
6325 } else {
6326 /* size == 2 */
6327 imm = (uint32_t)shift;
6329 tmp2 = tcg_const_i32(imm);
6330 tmp4 = neon_load_reg(rm + 1, 0);
6331 tmp5 = neon_load_reg(rm + 1, 1);
6332 for (pass = 0; pass < 2; pass++) {
6333 if (pass == 0) {
6334 tmp = neon_load_reg(rm, 0);
6335 } else {
6336 tmp = tmp4;
6338 gen_neon_shift_narrow(size, tmp, tmp2, q,
6339 input_unsigned);
6340 if (pass == 0) {
6341 tmp3 = neon_load_reg(rm, 1);
6342 } else {
6343 tmp3 = tmp5;
6345 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6346 input_unsigned);
6347 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6348 tcg_temp_free_i32(tmp);
6349 tcg_temp_free_i32(tmp3);
6350 tmp = tcg_temp_new_i32();
6351 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6352 neon_store_reg(rd, pass, tmp);
6353 } /* for pass */
6354 tcg_temp_free_i32(tmp2);
6356 } else if (op == 10) {
6357 /* VSHLL, VMOVL */
6358 if (q || (rd & 1)) {
6359 return 1;
6361 tmp = neon_load_reg(rm, 0);
6362 tmp2 = neon_load_reg(rm, 1);
6363 for (pass = 0; pass < 2; pass++) {
6364 if (pass == 1)
6365 tmp = tmp2;
6367 gen_neon_widen(cpu_V0, tmp, size, u);
6369 if (shift != 0) {
6370 /* The shift is less than the width of the source
6371 type, so we can just shift the whole register. */
6372 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6373 /* Widen the result of shift: we need to clear
6374 * the potential overflow bits resulting from
6375 * left bits of the narrow input appearing as
6376 * right bits of left the neighbour narrow
6377 * input. */
6378 if (size < 2 || !u) {
6379 uint64_t imm64;
6380 if (size == 0) {
6381 imm = (0xffu >> (8 - shift));
6382 imm |= imm << 16;
6383 } else if (size == 1) {
6384 imm = 0xffff >> (16 - shift);
6385 } else {
6386 /* size == 2 */
6387 imm = 0xffffffff >> (32 - shift);
6389 if (size < 2) {
6390 imm64 = imm | (((uint64_t)imm) << 32);
6391 } else {
6392 imm64 = imm;
6394 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6397 neon_store_reg64(cpu_V0, rd + pass);
6399 } else if (op >= 14) {
6400 /* VCVT fixed-point. */
6401 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6402 return 1;
6404 /* We have already masked out the must-be-1 top bit of imm6,
6405 * hence this 32-shift where the ARM ARM has 64-imm6.
6407 shift = 32 - shift;
6408 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6409 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6410 if (!(op & 1)) {
6411 if (u)
6412 gen_vfp_ulto(0, shift, 1);
6413 else
6414 gen_vfp_slto(0, shift, 1);
6415 } else {
6416 if (u)
6417 gen_vfp_toul(0, shift, 1);
6418 else
6419 gen_vfp_tosl(0, shift, 1);
6421 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6423 } else {
6424 return 1;
6426 } else { /* (insn & 0x00380080) == 0 */
6427 int invert;
6428 if (q && (rd & 1)) {
6429 return 1;
6432 op = (insn >> 8) & 0xf;
6433 /* One register and immediate. */
6434 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6435 invert = (insn & (1 << 5)) != 0;
6436 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6437 * We choose to not special-case this and will behave as if a
6438 * valid constant encoding of 0 had been given.
6440 switch (op) {
6441 case 0: case 1:
6442 /* no-op */
6443 break;
6444 case 2: case 3:
6445 imm <<= 8;
6446 break;
6447 case 4: case 5:
6448 imm <<= 16;
6449 break;
6450 case 6: case 7:
6451 imm <<= 24;
6452 break;
6453 case 8: case 9:
6454 imm |= imm << 16;
6455 break;
6456 case 10: case 11:
6457 imm = (imm << 8) | (imm << 24);
6458 break;
6459 case 12:
6460 imm = (imm << 8) | 0xff;
6461 break;
6462 case 13:
6463 imm = (imm << 16) | 0xffff;
6464 break;
6465 case 14:
6466 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6467 if (invert)
6468 imm = ~imm;
6469 break;
6470 case 15:
6471 if (invert) {
6472 return 1;
6474 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6475 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6476 break;
6478 if (invert)
6479 imm = ~imm;
6481 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6482 if (op & 1 && op < 12) {
6483 tmp = neon_load_reg(rd, pass);
6484 if (invert) {
6485 /* The immediate value has already been inverted, so
6486 BIC becomes AND. */
6487 tcg_gen_andi_i32(tmp, tmp, imm);
6488 } else {
6489 tcg_gen_ori_i32(tmp, tmp, imm);
6491 } else {
6492 /* VMOV, VMVN. */
6493 tmp = tcg_temp_new_i32();
6494 if (op == 14 && invert) {
6495 int n;
6496 uint32_t val;
6497 val = 0;
6498 for (n = 0; n < 4; n++) {
6499 if (imm & (1 << (n + (pass & 1) * 4)))
6500 val |= 0xff << (n * 8);
6502 tcg_gen_movi_i32(tmp, val);
6503 } else {
6504 tcg_gen_movi_i32(tmp, imm);
6507 neon_store_reg(rd, pass, tmp);
6510 } else { /* (insn & 0x00800010 == 0x00800000) */
6511 if (size != 3) {
6512 op = (insn >> 8) & 0xf;
6513 if ((insn & (1 << 6)) == 0) {
6514 /* Three registers of different lengths. */
6515 int src1_wide;
6516 int src2_wide;
6517 int prewiden;
6518 /* undefreq: bit 0 : UNDEF if size == 0
6519 * bit 1 : UNDEF if size == 1
6520 * bit 2 : UNDEF if size == 2
6521 * bit 3 : UNDEF if U == 1
6522 * Note that [2:0] set implies 'always UNDEF'
6524 int undefreq;
6525 /* prewiden, src1_wide, src2_wide, undefreq */
6526 static const int neon_3reg_wide[16][4] = {
6527 {1, 0, 0, 0}, /* VADDL */
6528 {1, 1, 0, 0}, /* VADDW */
6529 {1, 0, 0, 0}, /* VSUBL */
6530 {1, 1, 0, 0}, /* VSUBW */
6531 {0, 1, 1, 0}, /* VADDHN */
6532 {0, 0, 0, 0}, /* VABAL */
6533 {0, 1, 1, 0}, /* VSUBHN */
6534 {0, 0, 0, 0}, /* VABDL */
6535 {0, 0, 0, 0}, /* VMLAL */
6536 {0, 0, 0, 9}, /* VQDMLAL */
6537 {0, 0, 0, 0}, /* VMLSL */
6538 {0, 0, 0, 9}, /* VQDMLSL */
6539 {0, 0, 0, 0}, /* Integer VMULL */
6540 {0, 0, 0, 1}, /* VQDMULL */
6541 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6542 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6545 prewiden = neon_3reg_wide[op][0];
6546 src1_wide = neon_3reg_wide[op][1];
6547 src2_wide = neon_3reg_wide[op][2];
6548 undefreq = neon_3reg_wide[op][3];
6550 if ((undefreq & (1 << size)) ||
6551 ((undefreq & 8) && u)) {
6552 return 1;
6554 if ((src1_wide && (rn & 1)) ||
6555 (src2_wide && (rm & 1)) ||
6556 (!src2_wide && (rd & 1))) {
6557 return 1;
6560 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6561 * outside the loop below as it only performs a single pass.
6563 if (op == 14 && size == 2) {
6564 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6566 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6567 return 1;
6569 tcg_rn = tcg_temp_new_i64();
6570 tcg_rm = tcg_temp_new_i64();
6571 tcg_rd = tcg_temp_new_i64();
6572 neon_load_reg64(tcg_rn, rn);
6573 neon_load_reg64(tcg_rm, rm);
6574 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6575 neon_store_reg64(tcg_rd, rd);
6576 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6577 neon_store_reg64(tcg_rd, rd + 1);
6578 tcg_temp_free_i64(tcg_rn);
6579 tcg_temp_free_i64(tcg_rm);
6580 tcg_temp_free_i64(tcg_rd);
6581 return 0;
6584 /* Avoid overlapping operands. Wide source operands are
6585 always aligned so will never overlap with wide
6586 destinations in problematic ways. */
6587 if (rd == rm && !src2_wide) {
6588 tmp = neon_load_reg(rm, 1);
6589 neon_store_scratch(2, tmp);
6590 } else if (rd == rn && !src1_wide) {
6591 tmp = neon_load_reg(rn, 1);
6592 neon_store_scratch(2, tmp);
6594 TCGV_UNUSED_I32(tmp3);
6595 for (pass = 0; pass < 2; pass++) {
6596 if (src1_wide) {
6597 neon_load_reg64(cpu_V0, rn + pass);
6598 TCGV_UNUSED_I32(tmp);
6599 } else {
6600 if (pass == 1 && rd == rn) {
6601 tmp = neon_load_scratch(2);
6602 } else {
6603 tmp = neon_load_reg(rn, pass);
6605 if (prewiden) {
6606 gen_neon_widen(cpu_V0, tmp, size, u);
6609 if (src2_wide) {
6610 neon_load_reg64(cpu_V1, rm + pass);
6611 TCGV_UNUSED_I32(tmp2);
6612 } else {
6613 if (pass == 1 && rd == rm) {
6614 tmp2 = neon_load_scratch(2);
6615 } else {
6616 tmp2 = neon_load_reg(rm, pass);
6618 if (prewiden) {
6619 gen_neon_widen(cpu_V1, tmp2, size, u);
6622 switch (op) {
6623 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6624 gen_neon_addl(size);
6625 break;
6626 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6627 gen_neon_subl(size);
6628 break;
6629 case 5: case 7: /* VABAL, VABDL */
6630 switch ((size << 1) | u) {
6631 case 0:
6632 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6633 break;
6634 case 1:
6635 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6636 break;
6637 case 2:
6638 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6639 break;
6640 case 3:
6641 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6642 break;
6643 case 4:
6644 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6645 break;
6646 case 5:
6647 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6648 break;
6649 default: abort();
6651 tcg_temp_free_i32(tmp2);
6652 tcg_temp_free_i32(tmp);
6653 break;
6654 case 8: case 9: case 10: case 11: case 12: case 13:
6655 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6656 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6657 break;
6658 case 14: /* Polynomial VMULL */
6659 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6660 tcg_temp_free_i32(tmp2);
6661 tcg_temp_free_i32(tmp);
6662 break;
6663 default: /* 15 is RESERVED: caught earlier */
6664 abort();
6666 if (op == 13) {
6667 /* VQDMULL */
6668 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6669 neon_store_reg64(cpu_V0, rd + pass);
6670 } else if (op == 5 || (op >= 8 && op <= 11)) {
6671 /* Accumulate. */
6672 neon_load_reg64(cpu_V1, rd + pass);
6673 switch (op) {
6674 case 10: /* VMLSL */
6675 gen_neon_negl(cpu_V0, size);
6676 /* Fall through */
6677 case 5: case 8: /* VABAL, VMLAL */
6678 gen_neon_addl(size);
6679 break;
6680 case 9: case 11: /* VQDMLAL, VQDMLSL */
6681 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6682 if (op == 11) {
6683 gen_neon_negl(cpu_V0, size);
6685 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6686 break;
6687 default:
6688 abort();
6690 neon_store_reg64(cpu_V0, rd + pass);
6691 } else if (op == 4 || op == 6) {
6692 /* Narrowing operation. */
6693 tmp = tcg_temp_new_i32();
6694 if (!u) {
6695 switch (size) {
6696 case 0:
6697 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6698 break;
6699 case 1:
6700 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6701 break;
6702 case 2:
6703 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6704 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6705 break;
6706 default: abort();
6708 } else {
6709 switch (size) {
6710 case 0:
6711 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6712 break;
6713 case 1:
6714 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6715 break;
6716 case 2:
6717 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6718 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6719 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6720 break;
6721 default: abort();
6724 if (pass == 0) {
6725 tmp3 = tmp;
6726 } else {
6727 neon_store_reg(rd, 0, tmp3);
6728 neon_store_reg(rd, 1, tmp);
6730 } else {
6731 /* Write back the result. */
6732 neon_store_reg64(cpu_V0, rd + pass);
6735 } else {
6736 /* Two registers and a scalar. NB that for ops of this form
6737 * the ARM ARM labels bit 24 as Q, but it is in our variable
6738 * 'u', not 'q'.
6740 if (size == 0) {
6741 return 1;
6743 switch (op) {
6744 case 1: /* Float VMLA scalar */
6745 case 5: /* Floating point VMLS scalar */
6746 case 9: /* Floating point VMUL scalar */
6747 if (size == 1) {
6748 return 1;
6750 /* fall through */
6751 case 0: /* Integer VMLA scalar */
6752 case 4: /* Integer VMLS scalar */
6753 case 8: /* Integer VMUL scalar */
6754 case 12: /* VQDMULH scalar */
6755 case 13: /* VQRDMULH scalar */
6756 if (u && ((rd | rn) & 1)) {
6757 return 1;
6759 tmp = neon_get_scalar(size, rm);
6760 neon_store_scratch(0, tmp);
6761 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6762 tmp = neon_load_scratch(0);
6763 tmp2 = neon_load_reg(rn, pass);
6764 if (op == 12) {
6765 if (size == 1) {
6766 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6767 } else {
6768 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6770 } else if (op == 13) {
6771 if (size == 1) {
6772 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6773 } else {
6774 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6776 } else if (op & 1) {
6777 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6778 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6779 tcg_temp_free_ptr(fpstatus);
6780 } else {
6781 switch (size) {
6782 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6783 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6784 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6785 default: abort();
6788 tcg_temp_free_i32(tmp2);
6789 if (op < 8) {
6790 /* Accumulate. */
6791 tmp2 = neon_load_reg(rd, pass);
6792 switch (op) {
6793 case 0:
6794 gen_neon_add(size, tmp, tmp2);
6795 break;
6796 case 1:
6798 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6799 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6800 tcg_temp_free_ptr(fpstatus);
6801 break;
6803 case 4:
6804 gen_neon_rsb(size, tmp, tmp2);
6805 break;
6806 case 5:
6808 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6809 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6810 tcg_temp_free_ptr(fpstatus);
6811 break;
6813 default:
6814 abort();
6816 tcg_temp_free_i32(tmp2);
6818 neon_store_reg(rd, pass, tmp);
6820 break;
6821 case 3: /* VQDMLAL scalar */
6822 case 7: /* VQDMLSL scalar */
6823 case 11: /* VQDMULL scalar */
6824 if (u == 1) {
6825 return 1;
6827 /* fall through */
6828 case 2: /* VMLAL sclar */
6829 case 6: /* VMLSL scalar */
6830 case 10: /* VMULL scalar */
6831 if (rd & 1) {
6832 return 1;
6834 tmp2 = neon_get_scalar(size, rm);
6835 /* We need a copy of tmp2 because gen_neon_mull
6836 * deletes it during pass 0. */
6837 tmp4 = tcg_temp_new_i32();
6838 tcg_gen_mov_i32(tmp4, tmp2);
6839 tmp3 = neon_load_reg(rn, 1);
6841 for (pass = 0; pass < 2; pass++) {
6842 if (pass == 0) {
6843 tmp = neon_load_reg(rn, 0);
6844 } else {
6845 tmp = tmp3;
6846 tmp2 = tmp4;
6848 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6849 if (op != 11) {
6850 neon_load_reg64(cpu_V1, rd + pass);
6852 switch (op) {
6853 case 6:
6854 gen_neon_negl(cpu_V0, size);
6855 /* Fall through */
6856 case 2:
6857 gen_neon_addl(size);
6858 break;
6859 case 3: case 7:
6860 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6861 if (op == 7) {
6862 gen_neon_negl(cpu_V0, size);
6864 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6865 break;
6866 case 10:
6867 /* no-op */
6868 break;
6869 case 11:
6870 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6871 break;
6872 default:
6873 abort();
6875 neon_store_reg64(cpu_V0, rd + pass);
6879 break;
6880 default: /* 14 and 15 are RESERVED */
6881 return 1;
6884 } else { /* size == 3 */
6885 if (!u) {
6886 /* Extract. */
6887 imm = (insn >> 8) & 0xf;
6889 if (imm > 7 && !q)
6890 return 1;
6892 if (q && ((rd | rn | rm) & 1)) {
6893 return 1;
6896 if (imm == 0) {
6897 neon_load_reg64(cpu_V0, rn);
6898 if (q) {
6899 neon_load_reg64(cpu_V1, rn + 1);
6901 } else if (imm == 8) {
6902 neon_load_reg64(cpu_V0, rn + 1);
6903 if (q) {
6904 neon_load_reg64(cpu_V1, rm);
6906 } else if (q) {
6907 tmp64 = tcg_temp_new_i64();
6908 if (imm < 8) {
6909 neon_load_reg64(cpu_V0, rn);
6910 neon_load_reg64(tmp64, rn + 1);
6911 } else {
6912 neon_load_reg64(cpu_V0, rn + 1);
6913 neon_load_reg64(tmp64, rm);
6915 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6916 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6917 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6918 if (imm < 8) {
6919 neon_load_reg64(cpu_V1, rm);
6920 } else {
6921 neon_load_reg64(cpu_V1, rm + 1);
6922 imm -= 8;
6924 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6925 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6926 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6927 tcg_temp_free_i64(tmp64);
6928 } else {
6929 /* BUGFIX */
6930 neon_load_reg64(cpu_V0, rn);
6931 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6932 neon_load_reg64(cpu_V1, rm);
6933 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6934 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6936 neon_store_reg64(cpu_V0, rd);
6937 if (q) {
6938 neon_store_reg64(cpu_V1, rd + 1);
6940 } else if ((insn & (1 << 11)) == 0) {
6941 /* Two register misc. */
6942 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6943 size = (insn >> 18) & 3;
6944 /* UNDEF for unknown op values and bad op-size combinations */
6945 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6946 return 1;
6948 if (neon_2rm_is_v8_op(op) &&
6949 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6950 return 1;
6952 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6953 q && ((rm | rd) & 1)) {
6954 return 1;
6956 switch (op) {
6957 case NEON_2RM_VREV64:
6958 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6959 tmp = neon_load_reg(rm, pass * 2);
6960 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6961 switch (size) {
6962 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6963 case 1: gen_swap_half(tmp); break;
6964 case 2: /* no-op */ break;
6965 default: abort();
6967 neon_store_reg(rd, pass * 2 + 1, tmp);
6968 if (size == 2) {
6969 neon_store_reg(rd, pass * 2, tmp2);
6970 } else {
6971 switch (size) {
6972 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6973 case 1: gen_swap_half(tmp2); break;
6974 default: abort();
6976 neon_store_reg(rd, pass * 2, tmp2);
6979 break;
6980 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6981 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6982 for (pass = 0; pass < q + 1; pass++) {
6983 tmp = neon_load_reg(rm, pass * 2);
6984 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6985 tmp = neon_load_reg(rm, pass * 2 + 1);
6986 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6987 switch (size) {
6988 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6989 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6990 case 2: tcg_gen_add_i64(CPU_V001); break;
6991 default: abort();
6993 if (op >= NEON_2RM_VPADAL) {
6994 /* Accumulate. */
6995 neon_load_reg64(cpu_V1, rd + pass);
6996 gen_neon_addl(size);
6998 neon_store_reg64(cpu_V0, rd + pass);
7000 break;
7001 case NEON_2RM_VTRN:
7002 if (size == 2) {
7003 int n;
7004 for (n = 0; n < (q ? 4 : 2); n += 2) {
7005 tmp = neon_load_reg(rm, n);
7006 tmp2 = neon_load_reg(rd, n + 1);
7007 neon_store_reg(rm, n, tmp2);
7008 neon_store_reg(rd, n + 1, tmp);
7010 } else {
7011 goto elementwise;
7013 break;
7014 case NEON_2RM_VUZP:
7015 if (gen_neon_unzip(rd, rm, size, q)) {
7016 return 1;
7018 break;
7019 case NEON_2RM_VZIP:
7020 if (gen_neon_zip(rd, rm, size, q)) {
7021 return 1;
7023 break;
7024 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7025 /* also VQMOVUN; op field and mnemonics don't line up */
7026 if (rm & 1) {
7027 return 1;
7029 TCGV_UNUSED_I32(tmp2);
7030 for (pass = 0; pass < 2; pass++) {
7031 neon_load_reg64(cpu_V0, rm + pass);
7032 tmp = tcg_temp_new_i32();
7033 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7034 tmp, cpu_V0);
7035 if (pass == 0) {
7036 tmp2 = tmp;
7037 } else {
7038 neon_store_reg(rd, 0, tmp2);
7039 neon_store_reg(rd, 1, tmp);
7042 break;
7043 case NEON_2RM_VSHLL:
7044 if (q || (rd & 1)) {
7045 return 1;
7047 tmp = neon_load_reg(rm, 0);
7048 tmp2 = neon_load_reg(rm, 1);
7049 for (pass = 0; pass < 2; pass++) {
7050 if (pass == 1)
7051 tmp = tmp2;
7052 gen_neon_widen(cpu_V0, tmp, size, 1);
7053 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7054 neon_store_reg64(cpu_V0, rd + pass);
7056 break;
7057 case NEON_2RM_VCVT_F16_F32:
7058 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7059 q || (rm & 1)) {
7060 return 1;
7062 tmp = tcg_temp_new_i32();
7063 tmp2 = tcg_temp_new_i32();
7064 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7065 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7066 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7067 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7068 tcg_gen_shli_i32(tmp2, tmp2, 16);
7069 tcg_gen_or_i32(tmp2, tmp2, tmp);
7070 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7071 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7072 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7073 neon_store_reg(rd, 0, tmp2);
7074 tmp2 = tcg_temp_new_i32();
7075 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7076 tcg_gen_shli_i32(tmp2, tmp2, 16);
7077 tcg_gen_or_i32(tmp2, tmp2, tmp);
7078 neon_store_reg(rd, 1, tmp2);
7079 tcg_temp_free_i32(tmp);
7080 break;
7081 case NEON_2RM_VCVT_F32_F16:
7082 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7083 q || (rd & 1)) {
7084 return 1;
7086 tmp3 = tcg_temp_new_i32();
7087 tmp = neon_load_reg(rm, 0);
7088 tmp2 = neon_load_reg(rm, 1);
7089 tcg_gen_ext16u_i32(tmp3, tmp);
7090 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7091 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7092 tcg_gen_shri_i32(tmp3, tmp, 16);
7093 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7094 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7095 tcg_temp_free_i32(tmp);
7096 tcg_gen_ext16u_i32(tmp3, tmp2);
7097 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7098 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7099 tcg_gen_shri_i32(tmp3, tmp2, 16);
7100 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7101 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7102 tcg_temp_free_i32(tmp2);
7103 tcg_temp_free_i32(tmp3);
7104 break;
7105 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7106 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7107 || ((rm | rd) & 1)) {
7108 return 1;
7110 tmp = tcg_const_i32(rd);
7111 tmp2 = tcg_const_i32(rm);
7113 /* Bit 6 is the lowest opcode bit; it distinguishes between
7114 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7116 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7118 if (op == NEON_2RM_AESE) {
7119 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
7120 } else {
7121 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
7123 tcg_temp_free_i32(tmp);
7124 tcg_temp_free_i32(tmp2);
7125 tcg_temp_free_i32(tmp3);
7126 break;
7127 case NEON_2RM_SHA1H:
7128 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7129 || ((rm | rd) & 1)) {
7130 return 1;
7132 tmp = tcg_const_i32(rd);
7133 tmp2 = tcg_const_i32(rm);
7135 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
7137 tcg_temp_free_i32(tmp);
7138 tcg_temp_free_i32(tmp2);
7139 break;
7140 case NEON_2RM_SHA1SU1:
7141 if ((rm | rd) & 1) {
7142 return 1;
7144 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7145 if (q) {
7146 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7147 return 1;
7149 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7150 return 1;
7152 tmp = tcg_const_i32(rd);
7153 tmp2 = tcg_const_i32(rm);
7154 if (q) {
7155 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7156 } else {
7157 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7159 tcg_temp_free_i32(tmp);
7160 tcg_temp_free_i32(tmp2);
7161 break;
7162 default:
7163 elementwise:
7164 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7165 if (neon_2rm_is_float_op(op)) {
7166 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7167 neon_reg_offset(rm, pass));
7168 TCGV_UNUSED_I32(tmp);
7169 } else {
7170 tmp = neon_load_reg(rm, pass);
7172 switch (op) {
7173 case NEON_2RM_VREV32:
7174 switch (size) {
7175 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7176 case 1: gen_swap_half(tmp); break;
7177 default: abort();
7179 break;
7180 case NEON_2RM_VREV16:
7181 gen_rev16(tmp);
7182 break;
7183 case NEON_2RM_VCLS:
7184 switch (size) {
7185 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7186 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7187 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7188 default: abort();
7190 break;
7191 case NEON_2RM_VCLZ:
7192 switch (size) {
7193 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7194 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7195 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7196 default: abort();
7198 break;
7199 case NEON_2RM_VCNT:
7200 gen_helper_neon_cnt_u8(tmp, tmp);
7201 break;
7202 case NEON_2RM_VMVN:
7203 tcg_gen_not_i32(tmp, tmp);
7204 break;
7205 case NEON_2RM_VQABS:
7206 switch (size) {
7207 case 0:
7208 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7209 break;
7210 case 1:
7211 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7212 break;
7213 case 2:
7214 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7215 break;
7216 default: abort();
7218 break;
7219 case NEON_2RM_VQNEG:
7220 switch (size) {
7221 case 0:
7222 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7223 break;
7224 case 1:
7225 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7226 break;
7227 case 2:
7228 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7229 break;
7230 default: abort();
7232 break;
7233 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7234 tmp2 = tcg_const_i32(0);
7235 switch(size) {
7236 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7237 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7238 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7239 default: abort();
7241 tcg_temp_free_i32(tmp2);
7242 if (op == NEON_2RM_VCLE0) {
7243 tcg_gen_not_i32(tmp, tmp);
7245 break;
7246 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7247 tmp2 = tcg_const_i32(0);
7248 switch(size) {
7249 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7250 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7251 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7252 default: abort();
7254 tcg_temp_free_i32(tmp2);
7255 if (op == NEON_2RM_VCLT0) {
7256 tcg_gen_not_i32(tmp, tmp);
7258 break;
7259 case NEON_2RM_VCEQ0:
7260 tmp2 = tcg_const_i32(0);
7261 switch(size) {
7262 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7263 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7264 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7265 default: abort();
7267 tcg_temp_free_i32(tmp2);
7268 break;
7269 case NEON_2RM_VABS:
7270 switch(size) {
7271 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7272 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7273 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7274 default: abort();
7276 break;
7277 case NEON_2RM_VNEG:
7278 tmp2 = tcg_const_i32(0);
7279 gen_neon_rsb(size, tmp, tmp2);
7280 tcg_temp_free_i32(tmp2);
7281 break;
7282 case NEON_2RM_VCGT0_F:
7284 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7285 tmp2 = tcg_const_i32(0);
7286 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7287 tcg_temp_free_i32(tmp2);
7288 tcg_temp_free_ptr(fpstatus);
7289 break;
7291 case NEON_2RM_VCGE0_F:
7293 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7294 tmp2 = tcg_const_i32(0);
7295 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7296 tcg_temp_free_i32(tmp2);
7297 tcg_temp_free_ptr(fpstatus);
7298 break;
7300 case NEON_2RM_VCEQ0_F:
7302 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7303 tmp2 = tcg_const_i32(0);
7304 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7305 tcg_temp_free_i32(tmp2);
7306 tcg_temp_free_ptr(fpstatus);
7307 break;
7309 case NEON_2RM_VCLE0_F:
7311 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7312 tmp2 = tcg_const_i32(0);
7313 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7314 tcg_temp_free_i32(tmp2);
7315 tcg_temp_free_ptr(fpstatus);
7316 break;
7318 case NEON_2RM_VCLT0_F:
7320 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7321 tmp2 = tcg_const_i32(0);
7322 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7323 tcg_temp_free_i32(tmp2);
7324 tcg_temp_free_ptr(fpstatus);
7325 break;
7327 case NEON_2RM_VABS_F:
7328 gen_vfp_abs(0);
7329 break;
7330 case NEON_2RM_VNEG_F:
7331 gen_vfp_neg(0);
7332 break;
7333 case NEON_2RM_VSWP:
7334 tmp2 = neon_load_reg(rd, pass);
7335 neon_store_reg(rm, pass, tmp2);
7336 break;
7337 case NEON_2RM_VTRN:
7338 tmp2 = neon_load_reg(rd, pass);
7339 switch (size) {
7340 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7341 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7342 default: abort();
7344 neon_store_reg(rm, pass, tmp2);
7345 break;
7346 case NEON_2RM_VRINTN:
7347 case NEON_2RM_VRINTA:
7348 case NEON_2RM_VRINTM:
7349 case NEON_2RM_VRINTP:
7350 case NEON_2RM_VRINTZ:
7352 TCGv_i32 tcg_rmode;
7353 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7354 int rmode;
7356 if (op == NEON_2RM_VRINTZ) {
7357 rmode = FPROUNDING_ZERO;
7358 } else {
7359 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7362 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7363 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7364 cpu_env);
7365 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7366 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7367 cpu_env);
7368 tcg_temp_free_ptr(fpstatus);
7369 tcg_temp_free_i32(tcg_rmode);
7370 break;
7372 case NEON_2RM_VRINTX:
7374 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7375 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7376 tcg_temp_free_ptr(fpstatus);
7377 break;
7379 case NEON_2RM_VCVTAU:
7380 case NEON_2RM_VCVTAS:
7381 case NEON_2RM_VCVTNU:
7382 case NEON_2RM_VCVTNS:
7383 case NEON_2RM_VCVTPU:
7384 case NEON_2RM_VCVTPS:
7385 case NEON_2RM_VCVTMU:
7386 case NEON_2RM_VCVTMS:
7388 bool is_signed = !extract32(insn, 7, 1);
7389 TCGv_ptr fpst = get_fpstatus_ptr(1);
7390 TCGv_i32 tcg_rmode, tcg_shift;
7391 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7393 tcg_shift = tcg_const_i32(0);
7394 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7395 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7396 cpu_env);
7398 if (is_signed) {
7399 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7400 tcg_shift, fpst);
7401 } else {
7402 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7403 tcg_shift, fpst);
7406 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7407 cpu_env);
7408 tcg_temp_free_i32(tcg_rmode);
7409 tcg_temp_free_i32(tcg_shift);
7410 tcg_temp_free_ptr(fpst);
7411 break;
7413 case NEON_2RM_VRECPE:
7415 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7416 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7417 tcg_temp_free_ptr(fpstatus);
7418 break;
7420 case NEON_2RM_VRSQRTE:
7422 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7423 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7424 tcg_temp_free_ptr(fpstatus);
7425 break;
7427 case NEON_2RM_VRECPE_F:
7429 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7430 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7431 tcg_temp_free_ptr(fpstatus);
7432 break;
7434 case NEON_2RM_VRSQRTE_F:
7436 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7437 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7438 tcg_temp_free_ptr(fpstatus);
7439 break;
7441 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7442 gen_vfp_sito(0, 1);
7443 break;
7444 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7445 gen_vfp_uito(0, 1);
7446 break;
7447 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7448 gen_vfp_tosiz(0, 1);
7449 break;
7450 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7451 gen_vfp_touiz(0, 1);
7452 break;
7453 default:
7454 /* Reserved op values were caught by the
7455 * neon_2rm_sizes[] check earlier.
7457 abort();
7459 if (neon_2rm_is_float_op(op)) {
7460 tcg_gen_st_f32(cpu_F0s, cpu_env,
7461 neon_reg_offset(rd, pass));
7462 } else {
7463 neon_store_reg(rd, pass, tmp);
7466 break;
7468 } else if ((insn & (1 << 10)) == 0) {
7469 /* VTBL, VTBX. */
7470 int n = ((insn >> 8) & 3) + 1;
7471 if ((rn + n) > 32) {
7472 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7473 * helper function running off the end of the register file.
7475 return 1;
7477 n <<= 3;
7478 if (insn & (1 << 6)) {
7479 tmp = neon_load_reg(rd, 0);
7480 } else {
7481 tmp = tcg_temp_new_i32();
7482 tcg_gen_movi_i32(tmp, 0);
7484 tmp2 = neon_load_reg(rm, 0);
7485 tmp4 = tcg_const_i32(rn);
7486 tmp5 = tcg_const_i32(n);
7487 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7488 tcg_temp_free_i32(tmp);
7489 if (insn & (1 << 6)) {
7490 tmp = neon_load_reg(rd, 1);
7491 } else {
7492 tmp = tcg_temp_new_i32();
7493 tcg_gen_movi_i32(tmp, 0);
7495 tmp3 = neon_load_reg(rm, 1);
7496 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7497 tcg_temp_free_i32(tmp5);
7498 tcg_temp_free_i32(tmp4);
7499 neon_store_reg(rd, 0, tmp2);
7500 neon_store_reg(rd, 1, tmp3);
7501 tcg_temp_free_i32(tmp);
7502 } else if ((insn & 0x380) == 0) {
7503 /* VDUP */
7504 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7505 return 1;
7507 if (insn & (1 << 19)) {
7508 tmp = neon_load_reg(rm, 1);
7509 } else {
7510 tmp = neon_load_reg(rm, 0);
7512 if (insn & (1 << 16)) {
7513 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7514 } else if (insn & (1 << 17)) {
7515 if ((insn >> 18) & 1)
7516 gen_neon_dup_high16(tmp);
7517 else
7518 gen_neon_dup_low16(tmp);
7520 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7521 tmp2 = tcg_temp_new_i32();
7522 tcg_gen_mov_i32(tmp2, tmp);
7523 neon_store_reg(rd, pass, tmp2);
7525 tcg_temp_free_i32(tmp);
7526 } else {
7527 return 1;
7531 return 0;
7534 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7536 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7537 const ARMCPRegInfo *ri;
7539 cpnum = (insn >> 8) & 0xf;
7541 /* First check for coprocessor space used for XScale/iwMMXt insns */
7542 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7543 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7544 return 1;
7546 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7547 return disas_iwmmxt_insn(s, insn);
7548 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7549 return disas_dsp_insn(s, insn);
7551 return 1;
7554 /* Otherwise treat as a generic register access */
7555 is64 = (insn & (1 << 25)) == 0;
7556 if (!is64 && ((insn & (1 << 4)) == 0)) {
7557 /* cdp */
7558 return 1;
7561 crm = insn & 0xf;
7562 if (is64) {
7563 crn = 0;
7564 opc1 = (insn >> 4) & 0xf;
7565 opc2 = 0;
7566 rt2 = (insn >> 16) & 0xf;
7567 } else {
7568 crn = (insn >> 16) & 0xf;
7569 opc1 = (insn >> 21) & 7;
7570 opc2 = (insn >> 5) & 7;
7571 rt2 = 0;
7573 isread = (insn >> 20) & 1;
7574 rt = (insn >> 12) & 0xf;
7576 ri = get_arm_cp_reginfo(s->cp_regs,
7577 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7578 if (ri) {
7579 /* Check access permissions */
7580 if (!cp_access_ok(s->current_el, ri, isread)) {
7581 return 1;
7584 if (ri->accessfn ||
7585 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7586 /* Emit code to perform further access permissions checks at
7587 * runtime; this may result in an exception.
7588 * Note that on XScale all cp0..c13 registers do an access check
7589 * call in order to handle c15_cpar.
7591 TCGv_ptr tmpptr;
7592 TCGv_i32 tcg_syn, tcg_isread;
7593 uint32_t syndrome;
7595 /* Note that since we are an implementation which takes an
7596 * exception on a trapped conditional instruction only if the
7597 * instruction passes its condition code check, we can take
7598 * advantage of the clause in the ARM ARM that allows us to set
7599 * the COND field in the instruction to 0xE in all cases.
7600 * We could fish the actual condition out of the insn (ARM)
7601 * or the condexec bits (Thumb) but it isn't necessary.
7603 switch (cpnum) {
7604 case 14:
7605 if (is64) {
7606 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7607 isread, false);
7608 } else {
7609 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7610 rt, isread, false);
7612 break;
7613 case 15:
7614 if (is64) {
7615 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7616 isread, false);
7617 } else {
7618 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7619 rt, isread, false);
7621 break;
7622 default:
7623 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7624 * so this can only happen if this is an ARMv7 or earlier CPU,
7625 * in which case the syndrome information won't actually be
7626 * guest visible.
7628 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7629 syndrome = syn_uncategorized();
7630 break;
7633 gen_set_condexec(s);
7634 gen_set_pc_im(s, s->pc - 4);
7635 tmpptr = tcg_const_ptr(ri);
7636 tcg_syn = tcg_const_i32(syndrome);
7637 tcg_isread = tcg_const_i32(isread);
7638 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7639 tcg_isread);
7640 tcg_temp_free_ptr(tmpptr);
7641 tcg_temp_free_i32(tcg_syn);
7642 tcg_temp_free_i32(tcg_isread);
7645 /* Handle special cases first */
7646 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7647 case ARM_CP_NOP:
7648 return 0;
7649 case ARM_CP_WFI:
7650 if (isread) {
7651 return 1;
7653 gen_set_pc_im(s, s->pc);
7654 s->is_jmp = DISAS_WFI;
7655 return 0;
7656 default:
7657 break;
7660 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7661 gen_io_start();
7664 if (isread) {
7665 /* Read */
7666 if (is64) {
7667 TCGv_i64 tmp64;
7668 TCGv_i32 tmp;
7669 if (ri->type & ARM_CP_CONST) {
7670 tmp64 = tcg_const_i64(ri->resetvalue);
7671 } else if (ri->readfn) {
7672 TCGv_ptr tmpptr;
7673 tmp64 = tcg_temp_new_i64();
7674 tmpptr = tcg_const_ptr(ri);
7675 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7676 tcg_temp_free_ptr(tmpptr);
7677 } else {
7678 tmp64 = tcg_temp_new_i64();
7679 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7681 tmp = tcg_temp_new_i32();
7682 tcg_gen_extrl_i64_i32(tmp, tmp64);
7683 store_reg(s, rt, tmp);
7684 tcg_gen_shri_i64(tmp64, tmp64, 32);
7685 tmp = tcg_temp_new_i32();
7686 tcg_gen_extrl_i64_i32(tmp, tmp64);
7687 tcg_temp_free_i64(tmp64);
7688 store_reg(s, rt2, tmp);
7689 } else {
7690 TCGv_i32 tmp;
7691 if (ri->type & ARM_CP_CONST) {
7692 tmp = tcg_const_i32(ri->resetvalue);
7693 } else if (ri->readfn) {
7694 TCGv_ptr tmpptr;
7695 tmp = tcg_temp_new_i32();
7696 tmpptr = tcg_const_ptr(ri);
7697 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7698 tcg_temp_free_ptr(tmpptr);
7699 } else {
7700 tmp = load_cpu_offset(ri->fieldoffset);
7702 if (rt == 15) {
7703 /* Destination register of r15 for 32 bit loads sets
7704 * the condition codes from the high 4 bits of the value
7706 gen_set_nzcv(tmp);
7707 tcg_temp_free_i32(tmp);
7708 } else {
7709 store_reg(s, rt, tmp);
7712 } else {
7713 /* Write */
7714 if (ri->type & ARM_CP_CONST) {
7715 /* If not forbidden by access permissions, treat as WI */
7716 return 0;
7719 if (is64) {
7720 TCGv_i32 tmplo, tmphi;
7721 TCGv_i64 tmp64 = tcg_temp_new_i64();
7722 tmplo = load_reg(s, rt);
7723 tmphi = load_reg(s, rt2);
7724 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7725 tcg_temp_free_i32(tmplo);
7726 tcg_temp_free_i32(tmphi);
7727 if (ri->writefn) {
7728 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7729 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7730 tcg_temp_free_ptr(tmpptr);
7731 } else {
7732 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7734 tcg_temp_free_i64(tmp64);
7735 } else {
7736 if (ri->writefn) {
7737 TCGv_i32 tmp;
7738 TCGv_ptr tmpptr;
7739 tmp = load_reg(s, rt);
7740 tmpptr = tcg_const_ptr(ri);
7741 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7742 tcg_temp_free_ptr(tmpptr);
7743 tcg_temp_free_i32(tmp);
7744 } else {
7745 TCGv_i32 tmp = load_reg(s, rt);
7746 store_cpu_offset(tmp, ri->fieldoffset);
7751 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7752 /* I/O operations must end the TB here (whether read or write) */
7753 gen_io_end();
7754 gen_lookup_tb(s);
7755 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7756 /* We default to ending the TB on a coprocessor register write,
7757 * but allow this to be suppressed by the register definition
7758 * (usually only necessary to work around guest bugs).
7760 gen_lookup_tb(s);
7763 return 0;
7766 /* Unknown register; this might be a guest error or a QEMU
7767 * unimplemented feature.
7769 if (is64) {
7770 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7771 "64 bit system register cp:%d opc1: %d crm:%d "
7772 "(%s)\n",
7773 isread ? "read" : "write", cpnum, opc1, crm,
7774 s->ns ? "non-secure" : "secure");
7775 } else {
7776 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7777 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7778 "(%s)\n",
7779 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7780 s->ns ? "non-secure" : "secure");
7783 return 1;
7787 /* Store a 64-bit value to a register pair. Clobbers val. */
7788 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7790 TCGv_i32 tmp;
7791 tmp = tcg_temp_new_i32();
7792 tcg_gen_extrl_i64_i32(tmp, val);
7793 store_reg(s, rlow, tmp);
7794 tmp = tcg_temp_new_i32();
7795 tcg_gen_shri_i64(val, val, 32);
7796 tcg_gen_extrl_i64_i32(tmp, val);
7797 store_reg(s, rhigh, tmp);
7800 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7801 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7803 TCGv_i64 tmp;
7804 TCGv_i32 tmp2;
7806 /* Load value and extend to 64 bits. */
7807 tmp = tcg_temp_new_i64();
7808 tmp2 = load_reg(s, rlow);
7809 tcg_gen_extu_i32_i64(tmp, tmp2);
7810 tcg_temp_free_i32(tmp2);
7811 tcg_gen_add_i64(val, val, tmp);
7812 tcg_temp_free_i64(tmp);
7815 /* load and add a 64-bit value from a register pair. */
7816 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7818 TCGv_i64 tmp;
7819 TCGv_i32 tmpl;
7820 TCGv_i32 tmph;
7822 /* Load 64-bit value rd:rn. */
7823 tmpl = load_reg(s, rlow);
7824 tmph = load_reg(s, rhigh);
7825 tmp = tcg_temp_new_i64();
7826 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7827 tcg_temp_free_i32(tmpl);
7828 tcg_temp_free_i32(tmph);
7829 tcg_gen_add_i64(val, val, tmp);
7830 tcg_temp_free_i64(tmp);
7833 /* Set N and Z flags from hi|lo. */
7834 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7836 tcg_gen_mov_i32(cpu_NF, hi);
7837 tcg_gen_or_i32(cpu_ZF, lo, hi);
7840 /* Load/Store exclusive instructions are implemented by remembering
7841 the value/address loaded, and seeing if these are the same
7842 when the store is performed. This should be sufficient to implement
7843 the architecturally mandated semantics, and avoids having to monitor
7844 regular stores. The compare vs the remembered value is done during
7845 the cmpxchg operation, but we must compare the addresses manually. */
7846 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7847 TCGv_i32 addr, int size)
7849 TCGv_i32 tmp = tcg_temp_new_i32();
7850 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7852 s->is_ldex = true;
7854 if (size == 3) {
7855 TCGv_i32 tmp2 = tcg_temp_new_i32();
7856 TCGv_i64 t64 = tcg_temp_new_i64();
7858 gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
7859 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7860 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7861 tcg_temp_free_i64(t64);
7863 store_reg(s, rt2, tmp2);
7864 } else {
7865 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7866 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7869 store_reg(s, rt, tmp);
7870 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7873 static void gen_clrex(DisasContext *s)
7875 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7878 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7879 TCGv_i32 addr, int size)
7881 TCGv_i32 t0, t1, t2;
7882 TCGv_i64 extaddr;
7883 TCGv taddr;
7884 TCGLabel *done_label;
7885 TCGLabel *fail_label;
7886 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7888 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7889 [addr] = {Rt};
7890 {Rd} = 0;
7891 } else {
7892 {Rd} = 1;
7893 } */
7894 fail_label = gen_new_label();
7895 done_label = gen_new_label();
7896 extaddr = tcg_temp_new_i64();
7897 tcg_gen_extu_i32_i64(extaddr, addr);
7898 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7899 tcg_temp_free_i64(extaddr);
7901 taddr = gen_aa32_addr(s, addr, opc);
7902 t0 = tcg_temp_new_i32();
7903 t1 = load_reg(s, rt);
7904 if (size == 3) {
7905 TCGv_i64 o64 = tcg_temp_new_i64();
7906 TCGv_i64 n64 = tcg_temp_new_i64();
7908 t2 = load_reg(s, rt2);
7909 tcg_gen_concat_i32_i64(n64, t1, t2);
7910 tcg_temp_free_i32(t2);
7911 gen_aa32_frob64(s, n64);
7913 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7914 get_mem_index(s), opc);
7915 tcg_temp_free_i64(n64);
7917 gen_aa32_frob64(s, o64);
7918 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7919 tcg_gen_extrl_i64_i32(t0, o64);
7921 tcg_temp_free_i64(o64);
7922 } else {
7923 t2 = tcg_temp_new_i32();
7924 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7925 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7926 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7927 tcg_temp_free_i32(t2);
7929 tcg_temp_free_i32(t1);
7930 tcg_temp_free(taddr);
7931 tcg_gen_mov_i32(cpu_R[rd], t0);
7932 tcg_temp_free_i32(t0);
7933 tcg_gen_br(done_label);
7935 gen_set_label(fail_label);
7936 tcg_gen_movi_i32(cpu_R[rd], 1);
7937 gen_set_label(done_label);
7938 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7941 /* gen_srs:
7942 * @env: CPUARMState
7943 * @s: DisasContext
7944 * @mode: mode field from insn (which stack to store to)
7945 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7946 * @writeback: true if writeback bit set
7948 * Generate code for the SRS (Store Return State) insn.
7950 static void gen_srs(DisasContext *s,
7951 uint32_t mode, uint32_t amode, bool writeback)
7953 int32_t offset;
7954 TCGv_i32 addr, tmp;
7955 bool undef = false;
7957 /* SRS is:
7958 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7959 * and specified mode is monitor mode
7960 * - UNDEFINED in Hyp mode
7961 * - UNPREDICTABLE in User or System mode
7962 * - UNPREDICTABLE if the specified mode is:
7963 * -- not implemented
7964 * -- not a valid mode number
7965 * -- a mode that's at a higher exception level
7966 * -- Monitor, if we are Non-secure
7967 * For the UNPREDICTABLE cases we choose to UNDEF.
7969 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7970 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7971 return;
7974 if (s->current_el == 0 || s->current_el == 2) {
7975 undef = true;
7978 switch (mode) {
7979 case ARM_CPU_MODE_USR:
7980 case ARM_CPU_MODE_FIQ:
7981 case ARM_CPU_MODE_IRQ:
7982 case ARM_CPU_MODE_SVC:
7983 case ARM_CPU_MODE_ABT:
7984 case ARM_CPU_MODE_UND:
7985 case ARM_CPU_MODE_SYS:
7986 break;
7987 case ARM_CPU_MODE_HYP:
7988 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7989 undef = true;
7991 break;
7992 case ARM_CPU_MODE_MON:
7993 /* No need to check specifically for "are we non-secure" because
7994 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7995 * so if this isn't EL3 then we must be non-secure.
7997 if (s->current_el != 3) {
7998 undef = true;
8000 break;
8001 default:
8002 undef = true;
8005 if (undef) {
8006 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8007 default_exception_el(s));
8008 return;
8011 addr = tcg_temp_new_i32();
8012 tmp = tcg_const_i32(mode);
8013 /* get_r13_banked() will raise an exception if called from System mode */
8014 gen_set_condexec(s);
8015 gen_set_pc_im(s, s->pc - 4);
8016 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8017 tcg_temp_free_i32(tmp);
8018 switch (amode) {
8019 case 0: /* DA */
8020 offset = -4;
8021 break;
8022 case 1: /* IA */
8023 offset = 0;
8024 break;
8025 case 2: /* DB */
8026 offset = -8;
8027 break;
8028 case 3: /* IB */
8029 offset = 4;
8030 break;
8031 default:
8032 abort();
8034 tcg_gen_addi_i32(addr, addr, offset);
8035 tmp = load_reg(s, 14);
8036 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8037 tcg_temp_free_i32(tmp);
8038 tmp = load_cpu_field(spsr);
8039 tcg_gen_addi_i32(addr, addr, 4);
8040 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8041 tcg_temp_free_i32(tmp);
8042 if (writeback) {
8043 switch (amode) {
8044 case 0:
8045 offset = -8;
8046 break;
8047 case 1:
8048 offset = 4;
8049 break;
8050 case 2:
8051 offset = -4;
8052 break;
8053 case 3:
8054 offset = 0;
8055 break;
8056 default:
8057 abort();
8059 tcg_gen_addi_i32(addr, addr, offset);
8060 tmp = tcg_const_i32(mode);
8061 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8062 tcg_temp_free_i32(tmp);
8064 tcg_temp_free_i32(addr);
8065 s->is_jmp = DISAS_UPDATE;
8068 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8070 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8071 TCGv_i32 tmp;
8072 TCGv_i32 tmp2;
8073 TCGv_i32 tmp3;
8074 TCGv_i32 addr;
8075 TCGv_i64 tmp64;
8077 /* M variants do not implement ARM mode; this must raise the INVSTATE
8078 * UsageFault exception.
8080 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8081 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8082 default_exception_el(s));
8083 return;
8085 cond = insn >> 28;
8086 if (cond == 0xf){
8087 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8088 * choose to UNDEF. In ARMv5 and above the space is used
8089 * for miscellaneous unconditional instructions.
8091 ARCH(5);
8093 /* Unconditional instructions. */
8094 if (((insn >> 25) & 7) == 1) {
8095 /* NEON Data processing. */
8096 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8097 goto illegal_op;
8100 if (disas_neon_data_insn(s, insn)) {
8101 goto illegal_op;
8103 return;
8105 if ((insn & 0x0f100000) == 0x04000000) {
8106 /* NEON load/store. */
8107 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8108 goto illegal_op;
8111 if (disas_neon_ls_insn(s, insn)) {
8112 goto illegal_op;
8114 return;
8116 if ((insn & 0x0f000e10) == 0x0e000a00) {
8117 /* VFP. */
8118 if (disas_vfp_insn(s, insn)) {
8119 goto illegal_op;
8121 return;
8123 if (((insn & 0x0f30f000) == 0x0510f000) ||
8124 ((insn & 0x0f30f010) == 0x0710f000)) {
8125 if ((insn & (1 << 22)) == 0) {
8126 /* PLDW; v7MP */
8127 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8128 goto illegal_op;
8131 /* Otherwise PLD; v5TE+ */
8132 ARCH(5TE);
8133 return;
8135 if (((insn & 0x0f70f000) == 0x0450f000) ||
8136 ((insn & 0x0f70f010) == 0x0650f000)) {
8137 ARCH(7);
8138 return; /* PLI; V7 */
8140 if (((insn & 0x0f700000) == 0x04100000) ||
8141 ((insn & 0x0f700010) == 0x06100000)) {
8142 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8143 goto illegal_op;
8145 return; /* v7MP: Unallocated memory hint: must NOP */
8148 if ((insn & 0x0ffffdff) == 0x01010000) {
8149 ARCH(6);
8150 /* setend */
8151 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8152 gen_helper_setend(cpu_env);
8153 s->is_jmp = DISAS_UPDATE;
8155 return;
8156 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8157 switch ((insn >> 4) & 0xf) {
8158 case 1: /* clrex */
8159 ARCH(6K);
8160 gen_clrex(s);
8161 return;
8162 case 4: /* dsb */
8163 case 5: /* dmb */
8164 ARCH(7);
8165 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8166 return;
8167 case 6: /* isb */
8168 /* We need to break the TB after this insn to execute
8169 * self-modifying code correctly and also to take
8170 * any pending interrupts immediately.
8172 gen_goto_tb(s, 0, s->pc & ~1);
8173 return;
8174 default:
8175 goto illegal_op;
8177 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8178 /* srs */
8179 ARCH(6);
8180 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8181 return;
8182 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8183 /* rfe */
8184 int32_t offset;
8185 if (IS_USER(s))
8186 goto illegal_op;
8187 ARCH(6);
8188 rn = (insn >> 16) & 0xf;
8189 addr = load_reg(s, rn);
8190 i = (insn >> 23) & 3;
8191 switch (i) {
8192 case 0: offset = -4; break; /* DA */
8193 case 1: offset = 0; break; /* IA */
8194 case 2: offset = -8; break; /* DB */
8195 case 3: offset = 4; break; /* IB */
8196 default: abort();
8198 if (offset)
8199 tcg_gen_addi_i32(addr, addr, offset);
8200 /* Load PC into tmp and CPSR into tmp2. */
8201 tmp = tcg_temp_new_i32();
8202 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8203 tcg_gen_addi_i32(addr, addr, 4);
8204 tmp2 = tcg_temp_new_i32();
8205 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8206 if (insn & (1 << 21)) {
8207 /* Base writeback. */
8208 switch (i) {
8209 case 0: offset = -8; break;
8210 case 1: offset = 4; break;
8211 case 2: offset = -4; break;
8212 case 3: offset = 0; break;
8213 default: abort();
8215 if (offset)
8216 tcg_gen_addi_i32(addr, addr, offset);
8217 store_reg(s, rn, addr);
8218 } else {
8219 tcg_temp_free_i32(addr);
8221 gen_rfe(s, tmp, tmp2);
8222 return;
8223 } else if ((insn & 0x0e000000) == 0x0a000000) {
8224 /* branch link and change to thumb (blx <offset>) */
8225 int32_t offset;
8227 val = (uint32_t)s->pc;
8228 tmp = tcg_temp_new_i32();
8229 tcg_gen_movi_i32(tmp, val);
8230 store_reg(s, 14, tmp);
8231 /* Sign-extend the 24-bit offset */
8232 offset = (((int32_t)insn) << 8) >> 8;
8233 /* offset * 4 + bit24 * 2 + (thumb bit) */
8234 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8235 /* pipeline offset */
8236 val += 4;
8237 /* protected by ARCH(5); above, near the start of uncond block */
8238 gen_bx_im(s, val);
8239 return;
8240 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8241 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8242 /* iWMMXt register transfer. */
8243 if (extract32(s->c15_cpar, 1, 1)) {
8244 if (!disas_iwmmxt_insn(s, insn)) {
8245 return;
8249 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8250 /* Coprocessor double register transfer. */
8251 ARCH(5TE);
8252 } else if ((insn & 0x0f000010) == 0x0e000010) {
8253 /* Additional coprocessor register transfer. */
8254 } else if ((insn & 0x0ff10020) == 0x01000000) {
8255 uint32_t mask;
8256 uint32_t val;
8257 /* cps (privileged) */
8258 if (IS_USER(s))
8259 return;
8260 mask = val = 0;
8261 if (insn & (1 << 19)) {
8262 if (insn & (1 << 8))
8263 mask |= CPSR_A;
8264 if (insn & (1 << 7))
8265 mask |= CPSR_I;
8266 if (insn & (1 << 6))
8267 mask |= CPSR_F;
8268 if (insn & (1 << 18))
8269 val |= mask;
8271 if (insn & (1 << 17)) {
8272 mask |= CPSR_M;
8273 val |= (insn & 0x1f);
8275 if (mask) {
8276 gen_set_psr_im(s, mask, 0, val);
8278 return;
8280 goto illegal_op;
8282 if (cond != 0xe) {
8283 /* if not always execute, we generate a conditional jump to
8284 next instruction */
8285 s->condlabel = gen_new_label();
8286 arm_gen_test_cc(cond ^ 1, s->condlabel);
8287 s->condjmp = 1;
8289 if ((insn & 0x0f900000) == 0x03000000) {
8290 if ((insn & (1 << 21)) == 0) {
8291 ARCH(6T2);
8292 rd = (insn >> 12) & 0xf;
8293 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8294 if ((insn & (1 << 22)) == 0) {
8295 /* MOVW */
8296 tmp = tcg_temp_new_i32();
8297 tcg_gen_movi_i32(tmp, val);
8298 } else {
8299 /* MOVT */
8300 tmp = load_reg(s, rd);
8301 tcg_gen_ext16u_i32(tmp, tmp);
8302 tcg_gen_ori_i32(tmp, tmp, val << 16);
8304 store_reg(s, rd, tmp);
8305 } else {
8306 if (((insn >> 12) & 0xf) != 0xf)
8307 goto illegal_op;
8308 if (((insn >> 16) & 0xf) == 0) {
8309 gen_nop_hint(s, insn & 0xff);
8310 } else {
8311 /* CPSR = immediate */
8312 val = insn & 0xff;
8313 shift = ((insn >> 8) & 0xf) * 2;
8314 if (shift)
8315 val = (val >> shift) | (val << (32 - shift));
8316 i = ((insn & (1 << 22)) != 0);
8317 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8318 i, val)) {
8319 goto illegal_op;
8323 } else if ((insn & 0x0f900000) == 0x01000000
8324 && (insn & 0x00000090) != 0x00000090) {
8325 /* miscellaneous instructions */
8326 op1 = (insn >> 21) & 3;
8327 sh = (insn >> 4) & 0xf;
8328 rm = insn & 0xf;
8329 switch (sh) {
8330 case 0x0: /* MSR, MRS */
8331 if (insn & (1 << 9)) {
8332 /* MSR (banked) and MRS (banked) */
8333 int sysm = extract32(insn, 16, 4) |
8334 (extract32(insn, 8, 1) << 4);
8335 int r = extract32(insn, 22, 1);
8337 if (op1 & 1) {
8338 /* MSR (banked) */
8339 gen_msr_banked(s, r, sysm, rm);
8340 } else {
8341 /* MRS (banked) */
8342 int rd = extract32(insn, 12, 4);
8344 gen_mrs_banked(s, r, sysm, rd);
8346 break;
8349 /* MSR, MRS (for PSRs) */
8350 if (op1 & 1) {
8351 /* PSR = reg */
8352 tmp = load_reg(s, rm);
8353 i = ((op1 & 2) != 0);
8354 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8355 goto illegal_op;
8356 } else {
8357 /* reg = PSR */
8358 rd = (insn >> 12) & 0xf;
8359 if (op1 & 2) {
8360 if (IS_USER(s))
8361 goto illegal_op;
8362 tmp = load_cpu_field(spsr);
8363 } else {
8364 tmp = tcg_temp_new_i32();
8365 gen_helper_cpsr_read(tmp, cpu_env);
8367 store_reg(s, rd, tmp);
8369 break;
8370 case 0x1:
8371 if (op1 == 1) {
8372 /* branch/exchange thumb (bx). */
8373 ARCH(4T);
8374 tmp = load_reg(s, rm);
8375 gen_bx(s, tmp);
8376 } else if (op1 == 3) {
8377 /* clz */
8378 ARCH(5);
8379 rd = (insn >> 12) & 0xf;
8380 tmp = load_reg(s, rm);
8381 tcg_gen_clzi_i32(tmp, tmp, 32);
8382 store_reg(s, rd, tmp);
8383 } else {
8384 goto illegal_op;
8386 break;
8387 case 0x2:
8388 if (op1 == 1) {
8389 ARCH(5J); /* bxj */
8390 /* Trivial implementation equivalent to bx. */
8391 tmp = load_reg(s, rm);
8392 gen_bx(s, tmp);
8393 } else {
8394 goto illegal_op;
8396 break;
8397 case 0x3:
8398 if (op1 != 1)
8399 goto illegal_op;
8401 ARCH(5);
8402 /* branch link/exchange thumb (blx) */
8403 tmp = load_reg(s, rm);
8404 tmp2 = tcg_temp_new_i32();
8405 tcg_gen_movi_i32(tmp2, s->pc);
8406 store_reg(s, 14, tmp2);
8407 gen_bx(s, tmp);
8408 break;
8409 case 0x4:
8411 /* crc32/crc32c */
8412 uint32_t c = extract32(insn, 8, 4);
8414 /* Check this CPU supports ARMv8 CRC instructions.
8415 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8416 * Bits 8, 10 and 11 should be zero.
8418 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8419 (c & 0xd) != 0) {
8420 goto illegal_op;
8423 rn = extract32(insn, 16, 4);
8424 rd = extract32(insn, 12, 4);
8426 tmp = load_reg(s, rn);
8427 tmp2 = load_reg(s, rm);
8428 if (op1 == 0) {
8429 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8430 } else if (op1 == 1) {
8431 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8433 tmp3 = tcg_const_i32(1 << op1);
8434 if (c & 0x2) {
8435 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8436 } else {
8437 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8439 tcg_temp_free_i32(tmp2);
8440 tcg_temp_free_i32(tmp3);
8441 store_reg(s, rd, tmp);
8442 break;
8444 case 0x5: /* saturating add/subtract */
8445 ARCH(5TE);
8446 rd = (insn >> 12) & 0xf;
8447 rn = (insn >> 16) & 0xf;
8448 tmp = load_reg(s, rm);
8449 tmp2 = load_reg(s, rn);
8450 if (op1 & 2)
8451 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8452 if (op1 & 1)
8453 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8454 else
8455 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8456 tcg_temp_free_i32(tmp2);
8457 store_reg(s, rd, tmp);
8458 break;
8459 case 7:
8461 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8462 switch (op1) {
8463 case 0:
8464 /* HLT */
8465 gen_hlt(s, imm16);
8466 break;
8467 case 1:
8468 /* bkpt */
8469 ARCH(5);
8470 gen_exception_insn(s, 4, EXCP_BKPT,
8471 syn_aa32_bkpt(imm16, false),
8472 default_exception_el(s));
8473 break;
8474 case 2:
8475 /* Hypervisor call (v7) */
8476 ARCH(7);
8477 if (IS_USER(s)) {
8478 goto illegal_op;
8480 gen_hvc(s, imm16);
8481 break;
8482 case 3:
8483 /* Secure monitor call (v6+) */
8484 ARCH(6K);
8485 if (IS_USER(s)) {
8486 goto illegal_op;
8488 gen_smc(s);
8489 break;
8490 default:
8491 g_assert_not_reached();
8493 break;
8495 case 0x8: /* signed multiply */
8496 case 0xa:
8497 case 0xc:
8498 case 0xe:
8499 ARCH(5TE);
8500 rs = (insn >> 8) & 0xf;
8501 rn = (insn >> 12) & 0xf;
8502 rd = (insn >> 16) & 0xf;
8503 if (op1 == 1) {
8504 /* (32 * 16) >> 16 */
8505 tmp = load_reg(s, rm);
8506 tmp2 = load_reg(s, rs);
8507 if (sh & 4)
8508 tcg_gen_sari_i32(tmp2, tmp2, 16);
8509 else
8510 gen_sxth(tmp2);
8511 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8512 tcg_gen_shri_i64(tmp64, tmp64, 16);
8513 tmp = tcg_temp_new_i32();
8514 tcg_gen_extrl_i64_i32(tmp, tmp64);
8515 tcg_temp_free_i64(tmp64);
8516 if ((sh & 2) == 0) {
8517 tmp2 = load_reg(s, rn);
8518 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8519 tcg_temp_free_i32(tmp2);
8521 store_reg(s, rd, tmp);
8522 } else {
8523 /* 16 * 16 */
8524 tmp = load_reg(s, rm);
8525 tmp2 = load_reg(s, rs);
8526 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8527 tcg_temp_free_i32(tmp2);
8528 if (op1 == 2) {
8529 tmp64 = tcg_temp_new_i64();
8530 tcg_gen_ext_i32_i64(tmp64, tmp);
8531 tcg_temp_free_i32(tmp);
8532 gen_addq(s, tmp64, rn, rd);
8533 gen_storeq_reg(s, rn, rd, tmp64);
8534 tcg_temp_free_i64(tmp64);
8535 } else {
8536 if (op1 == 0) {
8537 tmp2 = load_reg(s, rn);
8538 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8539 tcg_temp_free_i32(tmp2);
8541 store_reg(s, rd, tmp);
8544 break;
8545 default:
8546 goto illegal_op;
8548 } else if (((insn & 0x0e000000) == 0 &&
8549 (insn & 0x00000090) != 0x90) ||
8550 ((insn & 0x0e000000) == (1 << 25))) {
8551 int set_cc, logic_cc, shiftop;
8553 op1 = (insn >> 21) & 0xf;
8554 set_cc = (insn >> 20) & 1;
8555 logic_cc = table_logic_cc[op1] & set_cc;
8557 /* data processing instruction */
8558 if (insn & (1 << 25)) {
8559 /* immediate operand */
8560 val = insn & 0xff;
8561 shift = ((insn >> 8) & 0xf) * 2;
8562 if (shift) {
8563 val = (val >> shift) | (val << (32 - shift));
8565 tmp2 = tcg_temp_new_i32();
8566 tcg_gen_movi_i32(tmp2, val);
8567 if (logic_cc && shift) {
8568 gen_set_CF_bit31(tmp2);
8570 } else {
8571 /* register */
8572 rm = (insn) & 0xf;
8573 tmp2 = load_reg(s, rm);
8574 shiftop = (insn >> 5) & 3;
8575 if (!(insn & (1 << 4))) {
8576 shift = (insn >> 7) & 0x1f;
8577 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8578 } else {
8579 rs = (insn >> 8) & 0xf;
8580 tmp = load_reg(s, rs);
8581 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8584 if (op1 != 0x0f && op1 != 0x0d) {
8585 rn = (insn >> 16) & 0xf;
8586 tmp = load_reg(s, rn);
8587 } else {
8588 TCGV_UNUSED_I32(tmp);
8590 rd = (insn >> 12) & 0xf;
8591 switch(op1) {
8592 case 0x00:
8593 tcg_gen_and_i32(tmp, tmp, tmp2);
8594 if (logic_cc) {
8595 gen_logic_CC(tmp);
8597 store_reg_bx(s, rd, tmp);
8598 break;
8599 case 0x01:
8600 tcg_gen_xor_i32(tmp, tmp, tmp2);
8601 if (logic_cc) {
8602 gen_logic_CC(tmp);
8604 store_reg_bx(s, rd, tmp);
8605 break;
8606 case 0x02:
8607 if (set_cc && rd == 15) {
8608 /* SUBS r15, ... is used for exception return. */
8609 if (IS_USER(s)) {
8610 goto illegal_op;
8612 gen_sub_CC(tmp, tmp, tmp2);
8613 gen_exception_return(s, tmp);
8614 } else {
8615 if (set_cc) {
8616 gen_sub_CC(tmp, tmp, tmp2);
8617 } else {
8618 tcg_gen_sub_i32(tmp, tmp, tmp2);
8620 store_reg_bx(s, rd, tmp);
8622 break;
8623 case 0x03:
8624 if (set_cc) {
8625 gen_sub_CC(tmp, tmp2, tmp);
8626 } else {
8627 tcg_gen_sub_i32(tmp, tmp2, tmp);
8629 store_reg_bx(s, rd, tmp);
8630 break;
8631 case 0x04:
8632 if (set_cc) {
8633 gen_add_CC(tmp, tmp, tmp2);
8634 } else {
8635 tcg_gen_add_i32(tmp, tmp, tmp2);
8637 store_reg_bx(s, rd, tmp);
8638 break;
8639 case 0x05:
8640 if (set_cc) {
8641 gen_adc_CC(tmp, tmp, tmp2);
8642 } else {
8643 gen_add_carry(tmp, tmp, tmp2);
8645 store_reg_bx(s, rd, tmp);
8646 break;
8647 case 0x06:
8648 if (set_cc) {
8649 gen_sbc_CC(tmp, tmp, tmp2);
8650 } else {
8651 gen_sub_carry(tmp, tmp, tmp2);
8653 store_reg_bx(s, rd, tmp);
8654 break;
8655 case 0x07:
8656 if (set_cc) {
8657 gen_sbc_CC(tmp, tmp2, tmp);
8658 } else {
8659 gen_sub_carry(tmp, tmp2, tmp);
8661 store_reg_bx(s, rd, tmp);
8662 break;
8663 case 0x08:
8664 if (set_cc) {
8665 tcg_gen_and_i32(tmp, tmp, tmp2);
8666 gen_logic_CC(tmp);
8668 tcg_temp_free_i32(tmp);
8669 break;
8670 case 0x09:
8671 if (set_cc) {
8672 tcg_gen_xor_i32(tmp, tmp, tmp2);
8673 gen_logic_CC(tmp);
8675 tcg_temp_free_i32(tmp);
8676 break;
8677 case 0x0a:
8678 if (set_cc) {
8679 gen_sub_CC(tmp, tmp, tmp2);
8681 tcg_temp_free_i32(tmp);
8682 break;
8683 case 0x0b:
8684 if (set_cc) {
8685 gen_add_CC(tmp, tmp, tmp2);
8687 tcg_temp_free_i32(tmp);
8688 break;
8689 case 0x0c:
8690 tcg_gen_or_i32(tmp, tmp, tmp2);
8691 if (logic_cc) {
8692 gen_logic_CC(tmp);
8694 store_reg_bx(s, rd, tmp);
8695 break;
8696 case 0x0d:
8697 if (logic_cc && rd == 15) {
8698 /* MOVS r15, ... is used for exception return. */
8699 if (IS_USER(s)) {
8700 goto illegal_op;
8702 gen_exception_return(s, tmp2);
8703 } else {
8704 if (logic_cc) {
8705 gen_logic_CC(tmp2);
8707 store_reg_bx(s, rd, tmp2);
8709 break;
8710 case 0x0e:
8711 tcg_gen_andc_i32(tmp, tmp, tmp2);
8712 if (logic_cc) {
8713 gen_logic_CC(tmp);
8715 store_reg_bx(s, rd, tmp);
8716 break;
8717 default:
8718 case 0x0f:
8719 tcg_gen_not_i32(tmp2, tmp2);
8720 if (logic_cc) {
8721 gen_logic_CC(tmp2);
8723 store_reg_bx(s, rd, tmp2);
8724 break;
8726 if (op1 != 0x0f && op1 != 0x0d) {
8727 tcg_temp_free_i32(tmp2);
8729 } else {
8730 /* other instructions */
8731 op1 = (insn >> 24) & 0xf;
8732 switch(op1) {
8733 case 0x0:
8734 case 0x1:
8735 /* multiplies, extra load/stores */
8736 sh = (insn >> 5) & 3;
8737 if (sh == 0) {
8738 if (op1 == 0x0) {
8739 rd = (insn >> 16) & 0xf;
8740 rn = (insn >> 12) & 0xf;
8741 rs = (insn >> 8) & 0xf;
8742 rm = (insn) & 0xf;
8743 op1 = (insn >> 20) & 0xf;
8744 switch (op1) {
8745 case 0: case 1: case 2: case 3: case 6:
8746 /* 32 bit mul */
8747 tmp = load_reg(s, rs);
8748 tmp2 = load_reg(s, rm);
8749 tcg_gen_mul_i32(tmp, tmp, tmp2);
8750 tcg_temp_free_i32(tmp2);
8751 if (insn & (1 << 22)) {
8752 /* Subtract (mls) */
8753 ARCH(6T2);
8754 tmp2 = load_reg(s, rn);
8755 tcg_gen_sub_i32(tmp, tmp2, tmp);
8756 tcg_temp_free_i32(tmp2);
8757 } else if (insn & (1 << 21)) {
8758 /* Add */
8759 tmp2 = load_reg(s, rn);
8760 tcg_gen_add_i32(tmp, tmp, tmp2);
8761 tcg_temp_free_i32(tmp2);
8763 if (insn & (1 << 20))
8764 gen_logic_CC(tmp);
8765 store_reg(s, rd, tmp);
8766 break;
8767 case 4:
8768 /* 64 bit mul double accumulate (UMAAL) */
8769 ARCH(6);
8770 tmp = load_reg(s, rs);
8771 tmp2 = load_reg(s, rm);
8772 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8773 gen_addq_lo(s, tmp64, rn);
8774 gen_addq_lo(s, tmp64, rd);
8775 gen_storeq_reg(s, rn, rd, tmp64);
8776 tcg_temp_free_i64(tmp64);
8777 break;
8778 case 8: case 9: case 10: case 11:
8779 case 12: case 13: case 14: case 15:
8780 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8781 tmp = load_reg(s, rs);
8782 tmp2 = load_reg(s, rm);
8783 if (insn & (1 << 22)) {
8784 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8785 } else {
8786 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8788 if (insn & (1 << 21)) { /* mult accumulate */
8789 TCGv_i32 al = load_reg(s, rn);
8790 TCGv_i32 ah = load_reg(s, rd);
8791 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8792 tcg_temp_free_i32(al);
8793 tcg_temp_free_i32(ah);
8795 if (insn & (1 << 20)) {
8796 gen_logicq_cc(tmp, tmp2);
8798 store_reg(s, rn, tmp);
8799 store_reg(s, rd, tmp2);
8800 break;
8801 default:
8802 goto illegal_op;
8804 } else {
8805 rn = (insn >> 16) & 0xf;
8806 rd = (insn >> 12) & 0xf;
8807 if (insn & (1 << 23)) {
8808 /* load/store exclusive */
8809 int op2 = (insn >> 8) & 3;
8810 op1 = (insn >> 21) & 0x3;
8812 switch (op2) {
8813 case 0: /* lda/stl */
8814 if (op1 == 1) {
8815 goto illegal_op;
8817 ARCH(8);
8818 break;
8819 case 1: /* reserved */
8820 goto illegal_op;
8821 case 2: /* ldaex/stlex */
8822 ARCH(8);
8823 break;
8824 case 3: /* ldrex/strex */
8825 if (op1) {
8826 ARCH(6K);
8827 } else {
8828 ARCH(6);
8830 break;
8833 addr = tcg_temp_local_new_i32();
8834 load_reg_var(s, addr, rn);
8836 /* Since the emulation does not have barriers,
8837 the acquire/release semantics need no special
8838 handling */
8839 if (op2 == 0) {
8840 if (insn & (1 << 20)) {
8841 tmp = tcg_temp_new_i32();
8842 switch (op1) {
8843 case 0: /* lda */
8844 gen_aa32_ld32u_iss(s, tmp, addr,
8845 get_mem_index(s),
8846 rd | ISSIsAcqRel);
8847 break;
8848 case 2: /* ldab */
8849 gen_aa32_ld8u_iss(s, tmp, addr,
8850 get_mem_index(s),
8851 rd | ISSIsAcqRel);
8852 break;
8853 case 3: /* ldah */
8854 gen_aa32_ld16u_iss(s, tmp, addr,
8855 get_mem_index(s),
8856 rd | ISSIsAcqRel);
8857 break;
8858 default:
8859 abort();
8861 store_reg(s, rd, tmp);
8862 } else {
8863 rm = insn & 0xf;
8864 tmp = load_reg(s, rm);
8865 switch (op1) {
8866 case 0: /* stl */
8867 gen_aa32_st32_iss(s, tmp, addr,
8868 get_mem_index(s),
8869 rm | ISSIsAcqRel);
8870 break;
8871 case 2: /* stlb */
8872 gen_aa32_st8_iss(s, tmp, addr,
8873 get_mem_index(s),
8874 rm | ISSIsAcqRel);
8875 break;
8876 case 3: /* stlh */
8877 gen_aa32_st16_iss(s, tmp, addr,
8878 get_mem_index(s),
8879 rm | ISSIsAcqRel);
8880 break;
8881 default:
8882 abort();
8884 tcg_temp_free_i32(tmp);
8886 } else if (insn & (1 << 20)) {
8887 switch (op1) {
8888 case 0: /* ldrex */
8889 gen_load_exclusive(s, rd, 15, addr, 2);
8890 break;
8891 case 1: /* ldrexd */
8892 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8893 break;
8894 case 2: /* ldrexb */
8895 gen_load_exclusive(s, rd, 15, addr, 0);
8896 break;
8897 case 3: /* ldrexh */
8898 gen_load_exclusive(s, rd, 15, addr, 1);
8899 break;
8900 default:
8901 abort();
8903 } else {
8904 rm = insn & 0xf;
8905 switch (op1) {
8906 case 0: /* strex */
8907 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8908 break;
8909 case 1: /* strexd */
8910 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8911 break;
8912 case 2: /* strexb */
8913 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8914 break;
8915 case 3: /* strexh */
8916 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8917 break;
8918 default:
8919 abort();
8922 tcg_temp_free_i32(addr);
8923 } else {
8924 TCGv taddr;
8925 TCGMemOp opc = s->be_data;
8927 /* SWP instruction */
8928 rm = (insn) & 0xf;
8930 if (insn & (1 << 22)) {
8931 opc |= MO_UB;
8932 } else {
8933 opc |= MO_UL | MO_ALIGN;
8936 addr = load_reg(s, rn);
8937 taddr = gen_aa32_addr(s, addr, opc);
8938 tcg_temp_free_i32(addr);
8940 tmp = load_reg(s, rm);
8941 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8942 get_mem_index(s), opc);
8943 tcg_temp_free(taddr);
8944 store_reg(s, rd, tmp);
8947 } else {
8948 int address_offset;
8949 bool load = insn & (1 << 20);
8950 bool wbit = insn & (1 << 21);
8951 bool pbit = insn & (1 << 24);
8952 bool doubleword = false;
8953 ISSInfo issinfo;
8955 /* Misc load/store */
8956 rn = (insn >> 16) & 0xf;
8957 rd = (insn >> 12) & 0xf;
8959 /* ISS not valid if writeback */
8960 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8962 if (!load && (sh & 2)) {
8963 /* doubleword */
8964 ARCH(5TE);
8965 if (rd & 1) {
8966 /* UNPREDICTABLE; we choose to UNDEF */
8967 goto illegal_op;
8969 load = (sh & 1) == 0;
8970 doubleword = true;
8973 addr = load_reg(s, rn);
8974 if (pbit) {
8975 gen_add_datah_offset(s, insn, 0, addr);
8977 address_offset = 0;
8979 if (doubleword) {
8980 if (!load) {
8981 /* store */
8982 tmp = load_reg(s, rd);
8983 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8984 tcg_temp_free_i32(tmp);
8985 tcg_gen_addi_i32(addr, addr, 4);
8986 tmp = load_reg(s, rd + 1);
8987 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8988 tcg_temp_free_i32(tmp);
8989 } else {
8990 /* load */
8991 tmp = tcg_temp_new_i32();
8992 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8993 store_reg(s, rd, tmp);
8994 tcg_gen_addi_i32(addr, addr, 4);
8995 tmp = tcg_temp_new_i32();
8996 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8997 rd++;
8999 address_offset = -4;
9000 } else if (load) {
9001 /* load */
9002 tmp = tcg_temp_new_i32();
9003 switch (sh) {
9004 case 1:
9005 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9006 issinfo);
9007 break;
9008 case 2:
9009 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9010 issinfo);
9011 break;
9012 default:
9013 case 3:
9014 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9015 issinfo);
9016 break;
9018 } else {
9019 /* store */
9020 tmp = load_reg(s, rd);
9021 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9022 tcg_temp_free_i32(tmp);
9024 /* Perform base writeback before the loaded value to
9025 ensure correct behavior with overlapping index registers.
9026 ldrd with base writeback is undefined if the
9027 destination and index registers overlap. */
9028 if (!pbit) {
9029 gen_add_datah_offset(s, insn, address_offset, addr);
9030 store_reg(s, rn, addr);
9031 } else if (wbit) {
9032 if (address_offset)
9033 tcg_gen_addi_i32(addr, addr, address_offset);
9034 store_reg(s, rn, addr);
9035 } else {
9036 tcg_temp_free_i32(addr);
9038 if (load) {
9039 /* Complete the load. */
9040 store_reg(s, rd, tmp);
9043 break;
9044 case 0x4:
9045 case 0x5:
9046 goto do_ldst;
9047 case 0x6:
9048 case 0x7:
9049 if (insn & (1 << 4)) {
9050 ARCH(6);
9051 /* Armv6 Media instructions. */
9052 rm = insn & 0xf;
9053 rn = (insn >> 16) & 0xf;
9054 rd = (insn >> 12) & 0xf;
9055 rs = (insn >> 8) & 0xf;
9056 switch ((insn >> 23) & 3) {
9057 case 0: /* Parallel add/subtract. */
9058 op1 = (insn >> 20) & 7;
9059 tmp = load_reg(s, rn);
9060 tmp2 = load_reg(s, rm);
9061 sh = (insn >> 5) & 7;
9062 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9063 goto illegal_op;
9064 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9065 tcg_temp_free_i32(tmp2);
9066 store_reg(s, rd, tmp);
9067 break;
9068 case 1:
9069 if ((insn & 0x00700020) == 0) {
9070 /* Halfword pack. */
9071 tmp = load_reg(s, rn);
9072 tmp2 = load_reg(s, rm);
9073 shift = (insn >> 7) & 0x1f;
9074 if (insn & (1 << 6)) {
9075 /* pkhtb */
9076 if (shift == 0)
9077 shift = 31;
9078 tcg_gen_sari_i32(tmp2, tmp2, shift);
9079 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9080 tcg_gen_ext16u_i32(tmp2, tmp2);
9081 } else {
9082 /* pkhbt */
9083 if (shift)
9084 tcg_gen_shli_i32(tmp2, tmp2, shift);
9085 tcg_gen_ext16u_i32(tmp, tmp);
9086 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9088 tcg_gen_or_i32(tmp, tmp, tmp2);
9089 tcg_temp_free_i32(tmp2);
9090 store_reg(s, rd, tmp);
9091 } else if ((insn & 0x00200020) == 0x00200000) {
9092 /* [us]sat */
9093 tmp = load_reg(s, rm);
9094 shift = (insn >> 7) & 0x1f;
9095 if (insn & (1 << 6)) {
9096 if (shift == 0)
9097 shift = 31;
9098 tcg_gen_sari_i32(tmp, tmp, shift);
9099 } else {
9100 tcg_gen_shli_i32(tmp, tmp, shift);
9102 sh = (insn >> 16) & 0x1f;
9103 tmp2 = tcg_const_i32(sh);
9104 if (insn & (1 << 22))
9105 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9106 else
9107 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9108 tcg_temp_free_i32(tmp2);
9109 store_reg(s, rd, tmp);
9110 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9111 /* [us]sat16 */
9112 tmp = load_reg(s, rm);
9113 sh = (insn >> 16) & 0x1f;
9114 tmp2 = tcg_const_i32(sh);
9115 if (insn & (1 << 22))
9116 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9117 else
9118 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9119 tcg_temp_free_i32(tmp2);
9120 store_reg(s, rd, tmp);
9121 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9122 /* Select bytes. */
9123 tmp = load_reg(s, rn);
9124 tmp2 = load_reg(s, rm);
9125 tmp3 = tcg_temp_new_i32();
9126 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9127 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9128 tcg_temp_free_i32(tmp3);
9129 tcg_temp_free_i32(tmp2);
9130 store_reg(s, rd, tmp);
9131 } else if ((insn & 0x000003e0) == 0x00000060) {
9132 tmp = load_reg(s, rm);
9133 shift = (insn >> 10) & 3;
9134 /* ??? In many cases it's not necessary to do a
9135 rotate, a shift is sufficient. */
9136 if (shift != 0)
9137 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9138 op1 = (insn >> 20) & 7;
9139 switch (op1) {
9140 case 0: gen_sxtb16(tmp); break;
9141 case 2: gen_sxtb(tmp); break;
9142 case 3: gen_sxth(tmp); break;
9143 case 4: gen_uxtb16(tmp); break;
9144 case 6: gen_uxtb(tmp); break;
9145 case 7: gen_uxth(tmp); break;
9146 default: goto illegal_op;
9148 if (rn != 15) {
9149 tmp2 = load_reg(s, rn);
9150 if ((op1 & 3) == 0) {
9151 gen_add16(tmp, tmp2);
9152 } else {
9153 tcg_gen_add_i32(tmp, tmp, tmp2);
9154 tcg_temp_free_i32(tmp2);
9157 store_reg(s, rd, tmp);
9158 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9159 /* rev */
9160 tmp = load_reg(s, rm);
9161 if (insn & (1 << 22)) {
9162 if (insn & (1 << 7)) {
9163 gen_revsh(tmp);
9164 } else {
9165 ARCH(6T2);
9166 gen_helper_rbit(tmp, tmp);
9168 } else {
9169 if (insn & (1 << 7))
9170 gen_rev16(tmp);
9171 else
9172 tcg_gen_bswap32_i32(tmp, tmp);
9174 store_reg(s, rd, tmp);
9175 } else {
9176 goto illegal_op;
9178 break;
9179 case 2: /* Multiplies (Type 3). */
9180 switch ((insn >> 20) & 0x7) {
9181 case 5:
9182 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9183 /* op2 not 00x or 11x : UNDEF */
9184 goto illegal_op;
9186 /* Signed multiply most significant [accumulate].
9187 (SMMUL, SMMLA, SMMLS) */
9188 tmp = load_reg(s, rm);
9189 tmp2 = load_reg(s, rs);
9190 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9192 if (rd != 15) {
9193 tmp = load_reg(s, rd);
9194 if (insn & (1 << 6)) {
9195 tmp64 = gen_subq_msw(tmp64, tmp);
9196 } else {
9197 tmp64 = gen_addq_msw(tmp64, tmp);
9200 if (insn & (1 << 5)) {
9201 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9203 tcg_gen_shri_i64(tmp64, tmp64, 32);
9204 tmp = tcg_temp_new_i32();
9205 tcg_gen_extrl_i64_i32(tmp, tmp64);
9206 tcg_temp_free_i64(tmp64);
9207 store_reg(s, rn, tmp);
9208 break;
9209 case 0:
9210 case 4:
9211 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9212 if (insn & (1 << 7)) {
9213 goto illegal_op;
9215 tmp = load_reg(s, rm);
9216 tmp2 = load_reg(s, rs);
9217 if (insn & (1 << 5))
9218 gen_swap_half(tmp2);
9219 gen_smul_dual(tmp, tmp2);
9220 if (insn & (1 << 22)) {
9221 /* smlald, smlsld */
9222 TCGv_i64 tmp64_2;
9224 tmp64 = tcg_temp_new_i64();
9225 tmp64_2 = tcg_temp_new_i64();
9226 tcg_gen_ext_i32_i64(tmp64, tmp);
9227 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9228 tcg_temp_free_i32(tmp);
9229 tcg_temp_free_i32(tmp2);
9230 if (insn & (1 << 6)) {
9231 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9232 } else {
9233 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9235 tcg_temp_free_i64(tmp64_2);
9236 gen_addq(s, tmp64, rd, rn);
9237 gen_storeq_reg(s, rd, rn, tmp64);
9238 tcg_temp_free_i64(tmp64);
9239 } else {
9240 /* smuad, smusd, smlad, smlsd */
9241 if (insn & (1 << 6)) {
9242 /* This subtraction cannot overflow. */
9243 tcg_gen_sub_i32(tmp, tmp, tmp2);
9244 } else {
9245 /* This addition cannot overflow 32 bits;
9246 * however it may overflow considered as a
9247 * signed operation, in which case we must set
9248 * the Q flag.
9250 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9252 tcg_temp_free_i32(tmp2);
9253 if (rd != 15)
9255 tmp2 = load_reg(s, rd);
9256 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9257 tcg_temp_free_i32(tmp2);
9259 store_reg(s, rn, tmp);
9261 break;
9262 case 1:
9263 case 3:
9264 /* SDIV, UDIV */
9265 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9266 goto illegal_op;
9268 if (((insn >> 5) & 7) || (rd != 15)) {
9269 goto illegal_op;
9271 tmp = load_reg(s, rm);
9272 tmp2 = load_reg(s, rs);
9273 if (insn & (1 << 21)) {
9274 gen_helper_udiv(tmp, tmp, tmp2);
9275 } else {
9276 gen_helper_sdiv(tmp, tmp, tmp2);
9278 tcg_temp_free_i32(tmp2);
9279 store_reg(s, rn, tmp);
9280 break;
9281 default:
9282 goto illegal_op;
9284 break;
9285 case 3:
9286 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9287 switch (op1) {
9288 case 0: /* Unsigned sum of absolute differences. */
9289 ARCH(6);
9290 tmp = load_reg(s, rm);
9291 tmp2 = load_reg(s, rs);
9292 gen_helper_usad8(tmp, tmp, tmp2);
9293 tcg_temp_free_i32(tmp2);
9294 if (rd != 15) {
9295 tmp2 = load_reg(s, rd);
9296 tcg_gen_add_i32(tmp, tmp, tmp2);
9297 tcg_temp_free_i32(tmp2);
9299 store_reg(s, rn, tmp);
9300 break;
9301 case 0x20: case 0x24: case 0x28: case 0x2c:
9302 /* Bitfield insert/clear. */
9303 ARCH(6T2);
9304 shift = (insn >> 7) & 0x1f;
9305 i = (insn >> 16) & 0x1f;
9306 if (i < shift) {
9307 /* UNPREDICTABLE; we choose to UNDEF */
9308 goto illegal_op;
9310 i = i + 1 - shift;
9311 if (rm == 15) {
9312 tmp = tcg_temp_new_i32();
9313 tcg_gen_movi_i32(tmp, 0);
9314 } else {
9315 tmp = load_reg(s, rm);
9317 if (i != 32) {
9318 tmp2 = load_reg(s, rd);
9319 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9320 tcg_temp_free_i32(tmp2);
9322 store_reg(s, rd, tmp);
9323 break;
9324 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9325 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9326 ARCH(6T2);
9327 tmp = load_reg(s, rm);
9328 shift = (insn >> 7) & 0x1f;
9329 i = ((insn >> 16) & 0x1f) + 1;
9330 if (shift + i > 32)
9331 goto illegal_op;
9332 if (i < 32) {
9333 if (op1 & 0x20) {
9334 tcg_gen_extract_i32(tmp, tmp, shift, i);
9335 } else {
9336 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9339 store_reg(s, rd, tmp);
9340 break;
9341 default:
9342 goto illegal_op;
9344 break;
9346 break;
9348 do_ldst:
9349 /* Check for undefined extension instructions
9350 * per the ARM Bible IE:
9351 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9353 sh = (0xf << 20) | (0xf << 4);
9354 if (op1 == 0x7 && ((insn & sh) == sh))
9356 goto illegal_op;
9358 /* load/store byte/word */
9359 rn = (insn >> 16) & 0xf;
9360 rd = (insn >> 12) & 0xf;
9361 tmp2 = load_reg(s, rn);
9362 if ((insn & 0x01200000) == 0x00200000) {
9363 /* ldrt/strt */
9364 i = get_a32_user_mem_index(s);
9365 } else {
9366 i = get_mem_index(s);
9368 if (insn & (1 << 24))
9369 gen_add_data_offset(s, insn, tmp2);
9370 if (insn & (1 << 20)) {
9371 /* load */
9372 tmp = tcg_temp_new_i32();
9373 if (insn & (1 << 22)) {
9374 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9375 } else {
9376 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9378 } else {
9379 /* store */
9380 tmp = load_reg(s, rd);
9381 if (insn & (1 << 22)) {
9382 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9383 } else {
9384 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9386 tcg_temp_free_i32(tmp);
9388 if (!(insn & (1 << 24))) {
9389 gen_add_data_offset(s, insn, tmp2);
9390 store_reg(s, rn, tmp2);
9391 } else if (insn & (1 << 21)) {
9392 store_reg(s, rn, tmp2);
9393 } else {
9394 tcg_temp_free_i32(tmp2);
9396 if (insn & (1 << 20)) {
9397 /* Complete the load. */
9398 store_reg_from_load(s, rd, tmp);
9400 break;
9401 case 0x08:
9402 case 0x09:
9404 int j, n, loaded_base;
9405 bool exc_return = false;
9406 bool is_load = extract32(insn, 20, 1);
9407 bool user = false;
9408 TCGv_i32 loaded_var;
9409 /* load/store multiple words */
9410 /* XXX: store correct base if write back */
9411 if (insn & (1 << 22)) {
9412 /* LDM (user), LDM (exception return) and STM (user) */
9413 if (IS_USER(s))
9414 goto illegal_op; /* only usable in supervisor mode */
9416 if (is_load && extract32(insn, 15, 1)) {
9417 exc_return = true;
9418 } else {
9419 user = true;
9422 rn = (insn >> 16) & 0xf;
9423 addr = load_reg(s, rn);
9425 /* compute total size */
9426 loaded_base = 0;
9427 TCGV_UNUSED_I32(loaded_var);
9428 n = 0;
9429 for(i=0;i<16;i++) {
9430 if (insn & (1 << i))
9431 n++;
9433 /* XXX: test invalid n == 0 case ? */
9434 if (insn & (1 << 23)) {
9435 if (insn & (1 << 24)) {
9436 /* pre increment */
9437 tcg_gen_addi_i32(addr, addr, 4);
9438 } else {
9439 /* post increment */
9441 } else {
9442 if (insn & (1 << 24)) {
9443 /* pre decrement */
9444 tcg_gen_addi_i32(addr, addr, -(n * 4));
9445 } else {
9446 /* post decrement */
9447 if (n != 1)
9448 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9451 j = 0;
9452 for(i=0;i<16;i++) {
9453 if (insn & (1 << i)) {
9454 if (is_load) {
9455 /* load */
9456 tmp = tcg_temp_new_i32();
9457 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9458 if (user) {
9459 tmp2 = tcg_const_i32(i);
9460 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9461 tcg_temp_free_i32(tmp2);
9462 tcg_temp_free_i32(tmp);
9463 } else if (i == rn) {
9464 loaded_var = tmp;
9465 loaded_base = 1;
9466 } else if (rn == 15 && exc_return) {
9467 store_pc_exc_ret(s, tmp);
9468 } else {
9469 store_reg_from_load(s, i, tmp);
9471 } else {
9472 /* store */
9473 if (i == 15) {
9474 /* special case: r15 = PC + 8 */
9475 val = (long)s->pc + 4;
9476 tmp = tcg_temp_new_i32();
9477 tcg_gen_movi_i32(tmp, val);
9478 } else if (user) {
9479 tmp = tcg_temp_new_i32();
9480 tmp2 = tcg_const_i32(i);
9481 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9482 tcg_temp_free_i32(tmp2);
9483 } else {
9484 tmp = load_reg(s, i);
9486 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9487 tcg_temp_free_i32(tmp);
9489 j++;
9490 /* no need to add after the last transfer */
9491 if (j != n)
9492 tcg_gen_addi_i32(addr, addr, 4);
9495 if (insn & (1 << 21)) {
9496 /* write back */
9497 if (insn & (1 << 23)) {
9498 if (insn & (1 << 24)) {
9499 /* pre increment */
9500 } else {
9501 /* post increment */
9502 tcg_gen_addi_i32(addr, addr, 4);
9504 } else {
9505 if (insn & (1 << 24)) {
9506 /* pre decrement */
9507 if (n != 1)
9508 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9509 } else {
9510 /* post decrement */
9511 tcg_gen_addi_i32(addr, addr, -(n * 4));
9514 store_reg(s, rn, addr);
9515 } else {
9516 tcg_temp_free_i32(addr);
9518 if (loaded_base) {
9519 store_reg(s, rn, loaded_var);
9521 if (exc_return) {
9522 /* Restore CPSR from SPSR. */
9523 tmp = load_cpu_field(spsr);
9524 gen_helper_cpsr_write_eret(cpu_env, tmp);
9525 tcg_temp_free_i32(tmp);
9526 s->is_jmp = DISAS_JUMP;
9529 break;
9530 case 0xa:
9531 case 0xb:
9533 int32_t offset;
9535 /* branch (and link) */
9536 val = (int32_t)s->pc;
9537 if (insn & (1 << 24)) {
9538 tmp = tcg_temp_new_i32();
9539 tcg_gen_movi_i32(tmp, val);
9540 store_reg(s, 14, tmp);
9542 offset = sextract32(insn << 2, 0, 26);
9543 val += offset + 4;
9544 gen_jmp(s, val);
9546 break;
9547 case 0xc:
9548 case 0xd:
9549 case 0xe:
9550 if (((insn >> 8) & 0xe) == 10) {
9551 /* VFP. */
9552 if (disas_vfp_insn(s, insn)) {
9553 goto illegal_op;
9555 } else if (disas_coproc_insn(s, insn)) {
9556 /* Coprocessor. */
9557 goto illegal_op;
9559 break;
9560 case 0xf:
9561 /* swi */
9562 gen_set_pc_im(s, s->pc);
9563 s->svc_imm = extract32(insn, 0, 24);
9564 s->is_jmp = DISAS_SWI;
9565 break;
9566 default:
9567 illegal_op:
9568 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9569 default_exception_el(s));
9570 break;
9575 /* Return true if this is a Thumb-2 logical op. */
9576 static int
9577 thumb2_logic_op(int op)
9579 return (op < 8);
9582 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9583 then set condition code flags based on the result of the operation.
9584 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9585 to the high bit of T1.
9586 Returns zero if the opcode is valid. */
9588 static int
9589 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9590 TCGv_i32 t0, TCGv_i32 t1)
9592 int logic_cc;
9594 logic_cc = 0;
9595 switch (op) {
9596 case 0: /* and */
9597 tcg_gen_and_i32(t0, t0, t1);
9598 logic_cc = conds;
9599 break;
9600 case 1: /* bic */
9601 tcg_gen_andc_i32(t0, t0, t1);
9602 logic_cc = conds;
9603 break;
9604 case 2: /* orr */
9605 tcg_gen_or_i32(t0, t0, t1);
9606 logic_cc = conds;
9607 break;
9608 case 3: /* orn */
9609 tcg_gen_orc_i32(t0, t0, t1);
9610 logic_cc = conds;
9611 break;
9612 case 4: /* eor */
9613 tcg_gen_xor_i32(t0, t0, t1);
9614 logic_cc = conds;
9615 break;
9616 case 8: /* add */
9617 if (conds)
9618 gen_add_CC(t0, t0, t1);
9619 else
9620 tcg_gen_add_i32(t0, t0, t1);
9621 break;
9622 case 10: /* adc */
9623 if (conds)
9624 gen_adc_CC(t0, t0, t1);
9625 else
9626 gen_adc(t0, t1);
9627 break;
9628 case 11: /* sbc */
9629 if (conds) {
9630 gen_sbc_CC(t0, t0, t1);
9631 } else {
9632 gen_sub_carry(t0, t0, t1);
9634 break;
9635 case 13: /* sub */
9636 if (conds)
9637 gen_sub_CC(t0, t0, t1);
9638 else
9639 tcg_gen_sub_i32(t0, t0, t1);
9640 break;
9641 case 14: /* rsb */
9642 if (conds)
9643 gen_sub_CC(t0, t1, t0);
9644 else
9645 tcg_gen_sub_i32(t0, t1, t0);
9646 break;
9647 default: /* 5, 6, 7, 9, 12, 15. */
9648 return 1;
9650 if (logic_cc) {
9651 gen_logic_CC(t0);
9652 if (shifter_out)
9653 gen_set_CF_bit31(t1);
9655 return 0;
9658 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9659 is not legal. */
9660 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9662 uint32_t insn, imm, shift, offset;
9663 uint32_t rd, rn, rm, rs;
9664 TCGv_i32 tmp;
9665 TCGv_i32 tmp2;
9666 TCGv_i32 tmp3;
9667 TCGv_i32 addr;
9668 TCGv_i64 tmp64;
9669 int op;
9670 int shiftop;
9671 int conds;
9672 int logic_cc;
9674 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9675 || arm_dc_feature(s, ARM_FEATURE_M))) {
9676 /* Thumb-1 cores may need to treat bl and blx as a pair of
9677 16-bit instructions to get correct prefetch abort behavior. */
9678 insn = insn_hw1;
9679 if ((insn & (1 << 12)) == 0) {
9680 ARCH(5);
9681 /* Second half of blx. */
9682 offset = ((insn & 0x7ff) << 1);
9683 tmp = load_reg(s, 14);
9684 tcg_gen_addi_i32(tmp, tmp, offset);
9685 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9687 tmp2 = tcg_temp_new_i32();
9688 tcg_gen_movi_i32(tmp2, s->pc | 1);
9689 store_reg(s, 14, tmp2);
9690 gen_bx(s, tmp);
9691 return 0;
9693 if (insn & (1 << 11)) {
9694 /* Second half of bl. */
9695 offset = ((insn & 0x7ff) << 1) | 1;
9696 tmp = load_reg(s, 14);
9697 tcg_gen_addi_i32(tmp, tmp, offset);
9699 tmp2 = tcg_temp_new_i32();
9700 tcg_gen_movi_i32(tmp2, s->pc | 1);
9701 store_reg(s, 14, tmp2);
9702 gen_bx(s, tmp);
9703 return 0;
9705 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9706 /* Instruction spans a page boundary. Implement it as two
9707 16-bit instructions in case the second half causes an
9708 prefetch abort. */
9709 offset = ((int32_t)insn << 21) >> 9;
9710 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9711 return 0;
9713 /* Fall through to 32-bit decode. */
9716 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9717 s->pc += 2;
9718 insn |= (uint32_t)insn_hw1 << 16;
9720 if ((insn & 0xf800e800) != 0xf000e800) {
9721 ARCH(6T2);
9724 rn = (insn >> 16) & 0xf;
9725 rs = (insn >> 12) & 0xf;
9726 rd = (insn >> 8) & 0xf;
9727 rm = insn & 0xf;
9728 switch ((insn >> 25) & 0xf) {
9729 case 0: case 1: case 2: case 3:
9730 /* 16-bit instructions. Should never happen. */
9731 abort();
9732 case 4:
9733 if (insn & (1 << 22)) {
9734 /* Other load/store, table branch. */
9735 if (insn & 0x01200000) {
9736 /* Load/store doubleword. */
9737 if (rn == 15) {
9738 addr = tcg_temp_new_i32();
9739 tcg_gen_movi_i32(addr, s->pc & ~3);
9740 } else {
9741 addr = load_reg(s, rn);
9743 offset = (insn & 0xff) * 4;
9744 if ((insn & (1 << 23)) == 0)
9745 offset = -offset;
9746 if (insn & (1 << 24)) {
9747 tcg_gen_addi_i32(addr, addr, offset);
9748 offset = 0;
9750 if (insn & (1 << 20)) {
9751 /* ldrd */
9752 tmp = tcg_temp_new_i32();
9753 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9754 store_reg(s, rs, tmp);
9755 tcg_gen_addi_i32(addr, addr, 4);
9756 tmp = tcg_temp_new_i32();
9757 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9758 store_reg(s, rd, tmp);
9759 } else {
9760 /* strd */
9761 tmp = load_reg(s, rs);
9762 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9763 tcg_temp_free_i32(tmp);
9764 tcg_gen_addi_i32(addr, addr, 4);
9765 tmp = load_reg(s, rd);
9766 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9767 tcg_temp_free_i32(tmp);
9769 if (insn & (1 << 21)) {
9770 /* Base writeback. */
9771 if (rn == 15)
9772 goto illegal_op;
9773 tcg_gen_addi_i32(addr, addr, offset - 4);
9774 store_reg(s, rn, addr);
9775 } else {
9776 tcg_temp_free_i32(addr);
9778 } else if ((insn & (1 << 23)) == 0) {
9779 /* Load/store exclusive word. */
9780 addr = tcg_temp_local_new_i32();
9781 load_reg_var(s, addr, rn);
9782 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9783 if (insn & (1 << 20)) {
9784 gen_load_exclusive(s, rs, 15, addr, 2);
9785 } else {
9786 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9788 tcg_temp_free_i32(addr);
9789 } else if ((insn & (7 << 5)) == 0) {
9790 /* Table Branch. */
9791 if (rn == 15) {
9792 addr = tcg_temp_new_i32();
9793 tcg_gen_movi_i32(addr, s->pc);
9794 } else {
9795 addr = load_reg(s, rn);
9797 tmp = load_reg(s, rm);
9798 tcg_gen_add_i32(addr, addr, tmp);
9799 if (insn & (1 << 4)) {
9800 /* tbh */
9801 tcg_gen_add_i32(addr, addr, tmp);
9802 tcg_temp_free_i32(tmp);
9803 tmp = tcg_temp_new_i32();
9804 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9805 } else { /* tbb */
9806 tcg_temp_free_i32(tmp);
9807 tmp = tcg_temp_new_i32();
9808 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9810 tcg_temp_free_i32(addr);
9811 tcg_gen_shli_i32(tmp, tmp, 1);
9812 tcg_gen_addi_i32(tmp, tmp, s->pc);
9813 store_reg(s, 15, tmp);
9814 } else {
9815 int op2 = (insn >> 6) & 0x3;
9816 op = (insn >> 4) & 0x3;
9817 switch (op2) {
9818 case 0:
9819 goto illegal_op;
9820 case 1:
9821 /* Load/store exclusive byte/halfword/doubleword */
9822 if (op == 2) {
9823 goto illegal_op;
9825 ARCH(7);
9826 break;
9827 case 2:
9828 /* Load-acquire/store-release */
9829 if (op == 3) {
9830 goto illegal_op;
9832 /* Fall through */
9833 case 3:
9834 /* Load-acquire/store-release exclusive */
9835 ARCH(8);
9836 break;
9838 addr = tcg_temp_local_new_i32();
9839 load_reg_var(s, addr, rn);
9840 if (!(op2 & 1)) {
9841 if (insn & (1 << 20)) {
9842 tmp = tcg_temp_new_i32();
9843 switch (op) {
9844 case 0: /* ldab */
9845 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9846 rs | ISSIsAcqRel);
9847 break;
9848 case 1: /* ldah */
9849 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9850 rs | ISSIsAcqRel);
9851 break;
9852 case 2: /* lda */
9853 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9854 rs | ISSIsAcqRel);
9855 break;
9856 default:
9857 abort();
9859 store_reg(s, rs, tmp);
9860 } else {
9861 tmp = load_reg(s, rs);
9862 switch (op) {
9863 case 0: /* stlb */
9864 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9865 rs | ISSIsAcqRel);
9866 break;
9867 case 1: /* stlh */
9868 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9869 rs | ISSIsAcqRel);
9870 break;
9871 case 2: /* stl */
9872 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9873 rs | ISSIsAcqRel);
9874 break;
9875 default:
9876 abort();
9878 tcg_temp_free_i32(tmp);
9880 } else if (insn & (1 << 20)) {
9881 gen_load_exclusive(s, rs, rd, addr, op);
9882 } else {
9883 gen_store_exclusive(s, rm, rs, rd, addr, op);
9885 tcg_temp_free_i32(addr);
9887 } else {
9888 /* Load/store multiple, RFE, SRS. */
9889 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9890 /* RFE, SRS: not available in user mode or on M profile */
9891 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9892 goto illegal_op;
9894 if (insn & (1 << 20)) {
9895 /* rfe */
9896 addr = load_reg(s, rn);
9897 if ((insn & (1 << 24)) == 0)
9898 tcg_gen_addi_i32(addr, addr, -8);
9899 /* Load PC into tmp and CPSR into tmp2. */
9900 tmp = tcg_temp_new_i32();
9901 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9902 tcg_gen_addi_i32(addr, addr, 4);
9903 tmp2 = tcg_temp_new_i32();
9904 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9905 if (insn & (1 << 21)) {
9906 /* Base writeback. */
9907 if (insn & (1 << 24)) {
9908 tcg_gen_addi_i32(addr, addr, 4);
9909 } else {
9910 tcg_gen_addi_i32(addr, addr, -4);
9912 store_reg(s, rn, addr);
9913 } else {
9914 tcg_temp_free_i32(addr);
9916 gen_rfe(s, tmp, tmp2);
9917 } else {
9918 /* srs */
9919 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9920 insn & (1 << 21));
9922 } else {
9923 int i, loaded_base = 0;
9924 TCGv_i32 loaded_var;
9925 /* Load/store multiple. */
9926 addr = load_reg(s, rn);
9927 offset = 0;
9928 for (i = 0; i < 16; i++) {
9929 if (insn & (1 << i))
9930 offset += 4;
9932 if (insn & (1 << 24)) {
9933 tcg_gen_addi_i32(addr, addr, -offset);
9936 TCGV_UNUSED_I32(loaded_var);
9937 for (i = 0; i < 16; i++) {
9938 if ((insn & (1 << i)) == 0)
9939 continue;
9940 if (insn & (1 << 20)) {
9941 /* Load. */
9942 tmp = tcg_temp_new_i32();
9943 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9944 if (i == 15) {
9945 gen_bx_excret(s, tmp);
9946 } else if (i == rn) {
9947 loaded_var = tmp;
9948 loaded_base = 1;
9949 } else {
9950 store_reg(s, i, tmp);
9952 } else {
9953 /* Store. */
9954 tmp = load_reg(s, i);
9955 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9956 tcg_temp_free_i32(tmp);
9958 tcg_gen_addi_i32(addr, addr, 4);
9960 if (loaded_base) {
9961 store_reg(s, rn, loaded_var);
9963 if (insn & (1 << 21)) {
9964 /* Base register writeback. */
9965 if (insn & (1 << 24)) {
9966 tcg_gen_addi_i32(addr, addr, -offset);
9968 /* Fault if writeback register is in register list. */
9969 if (insn & (1 << rn))
9970 goto illegal_op;
9971 store_reg(s, rn, addr);
9972 } else {
9973 tcg_temp_free_i32(addr);
9977 break;
9978 case 5:
9980 op = (insn >> 21) & 0xf;
9981 if (op == 6) {
9982 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9983 goto illegal_op;
9985 /* Halfword pack. */
9986 tmp = load_reg(s, rn);
9987 tmp2 = load_reg(s, rm);
9988 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9989 if (insn & (1 << 5)) {
9990 /* pkhtb */
9991 if (shift == 0)
9992 shift = 31;
9993 tcg_gen_sari_i32(tmp2, tmp2, shift);
9994 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9995 tcg_gen_ext16u_i32(tmp2, tmp2);
9996 } else {
9997 /* pkhbt */
9998 if (shift)
9999 tcg_gen_shli_i32(tmp2, tmp2, shift);
10000 tcg_gen_ext16u_i32(tmp, tmp);
10001 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10003 tcg_gen_or_i32(tmp, tmp, tmp2);
10004 tcg_temp_free_i32(tmp2);
10005 store_reg(s, rd, tmp);
10006 } else {
10007 /* Data processing register constant shift. */
10008 if (rn == 15) {
10009 tmp = tcg_temp_new_i32();
10010 tcg_gen_movi_i32(tmp, 0);
10011 } else {
10012 tmp = load_reg(s, rn);
10014 tmp2 = load_reg(s, rm);
10016 shiftop = (insn >> 4) & 3;
10017 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10018 conds = (insn & (1 << 20)) != 0;
10019 logic_cc = (conds && thumb2_logic_op(op));
10020 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10021 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10022 goto illegal_op;
10023 tcg_temp_free_i32(tmp2);
10024 if (rd != 15) {
10025 store_reg(s, rd, tmp);
10026 } else {
10027 tcg_temp_free_i32(tmp);
10030 break;
10031 case 13: /* Misc data processing. */
10032 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10033 if (op < 4 && (insn & 0xf000) != 0xf000)
10034 goto illegal_op;
10035 switch (op) {
10036 case 0: /* Register controlled shift. */
10037 tmp = load_reg(s, rn);
10038 tmp2 = load_reg(s, rm);
10039 if ((insn & 0x70) != 0)
10040 goto illegal_op;
10041 op = (insn >> 21) & 3;
10042 logic_cc = (insn & (1 << 20)) != 0;
10043 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10044 if (logic_cc)
10045 gen_logic_CC(tmp);
10046 store_reg(s, rd, tmp);
10047 break;
10048 case 1: /* Sign/zero extend. */
10049 op = (insn >> 20) & 7;
10050 switch (op) {
10051 case 0: /* SXTAH, SXTH */
10052 case 1: /* UXTAH, UXTH */
10053 case 4: /* SXTAB, SXTB */
10054 case 5: /* UXTAB, UXTB */
10055 break;
10056 case 2: /* SXTAB16, SXTB16 */
10057 case 3: /* UXTAB16, UXTB16 */
10058 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10059 goto illegal_op;
10061 break;
10062 default:
10063 goto illegal_op;
10065 if (rn != 15) {
10066 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10067 goto illegal_op;
10070 tmp = load_reg(s, rm);
10071 shift = (insn >> 4) & 3;
10072 /* ??? In many cases it's not necessary to do a
10073 rotate, a shift is sufficient. */
10074 if (shift != 0)
10075 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10076 op = (insn >> 20) & 7;
10077 switch (op) {
10078 case 0: gen_sxth(tmp); break;
10079 case 1: gen_uxth(tmp); break;
10080 case 2: gen_sxtb16(tmp); break;
10081 case 3: gen_uxtb16(tmp); break;
10082 case 4: gen_sxtb(tmp); break;
10083 case 5: gen_uxtb(tmp); break;
10084 default:
10085 g_assert_not_reached();
10087 if (rn != 15) {
10088 tmp2 = load_reg(s, rn);
10089 if ((op >> 1) == 1) {
10090 gen_add16(tmp, tmp2);
10091 } else {
10092 tcg_gen_add_i32(tmp, tmp, tmp2);
10093 tcg_temp_free_i32(tmp2);
10096 store_reg(s, rd, tmp);
10097 break;
10098 case 2: /* SIMD add/subtract. */
10099 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10100 goto illegal_op;
10102 op = (insn >> 20) & 7;
10103 shift = (insn >> 4) & 7;
10104 if ((op & 3) == 3 || (shift & 3) == 3)
10105 goto illegal_op;
10106 tmp = load_reg(s, rn);
10107 tmp2 = load_reg(s, rm);
10108 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10109 tcg_temp_free_i32(tmp2);
10110 store_reg(s, rd, tmp);
10111 break;
10112 case 3: /* Other data processing. */
10113 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10114 if (op < 4) {
10115 /* Saturating add/subtract. */
10116 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10117 goto illegal_op;
10119 tmp = load_reg(s, rn);
10120 tmp2 = load_reg(s, rm);
10121 if (op & 1)
10122 gen_helper_double_saturate(tmp, cpu_env, tmp);
10123 if (op & 2)
10124 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10125 else
10126 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10127 tcg_temp_free_i32(tmp2);
10128 } else {
10129 switch (op) {
10130 case 0x0a: /* rbit */
10131 case 0x08: /* rev */
10132 case 0x09: /* rev16 */
10133 case 0x0b: /* revsh */
10134 case 0x18: /* clz */
10135 break;
10136 case 0x10: /* sel */
10137 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10138 goto illegal_op;
10140 break;
10141 case 0x20: /* crc32/crc32c */
10142 case 0x21:
10143 case 0x22:
10144 case 0x28:
10145 case 0x29:
10146 case 0x2a:
10147 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10148 goto illegal_op;
10150 break;
10151 default:
10152 goto illegal_op;
10154 tmp = load_reg(s, rn);
10155 switch (op) {
10156 case 0x0a: /* rbit */
10157 gen_helper_rbit(tmp, tmp);
10158 break;
10159 case 0x08: /* rev */
10160 tcg_gen_bswap32_i32(tmp, tmp);
10161 break;
10162 case 0x09: /* rev16 */
10163 gen_rev16(tmp);
10164 break;
10165 case 0x0b: /* revsh */
10166 gen_revsh(tmp);
10167 break;
10168 case 0x10: /* sel */
10169 tmp2 = load_reg(s, rm);
10170 tmp3 = tcg_temp_new_i32();
10171 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10172 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10173 tcg_temp_free_i32(tmp3);
10174 tcg_temp_free_i32(tmp2);
10175 break;
10176 case 0x18: /* clz */
10177 tcg_gen_clzi_i32(tmp, tmp, 32);
10178 break;
10179 case 0x20:
10180 case 0x21:
10181 case 0x22:
10182 case 0x28:
10183 case 0x29:
10184 case 0x2a:
10186 /* crc32/crc32c */
10187 uint32_t sz = op & 0x3;
10188 uint32_t c = op & 0x8;
10190 tmp2 = load_reg(s, rm);
10191 if (sz == 0) {
10192 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10193 } else if (sz == 1) {
10194 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10196 tmp3 = tcg_const_i32(1 << sz);
10197 if (c) {
10198 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10199 } else {
10200 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10202 tcg_temp_free_i32(tmp2);
10203 tcg_temp_free_i32(tmp3);
10204 break;
10206 default:
10207 g_assert_not_reached();
10210 store_reg(s, rd, tmp);
10211 break;
10212 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10213 switch ((insn >> 20) & 7) {
10214 case 0: /* 32 x 32 -> 32 */
10215 case 7: /* Unsigned sum of absolute differences. */
10216 break;
10217 case 1: /* 16 x 16 -> 32 */
10218 case 2: /* Dual multiply add. */
10219 case 3: /* 32 * 16 -> 32msb */
10220 case 4: /* Dual multiply subtract. */
10221 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10222 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10223 goto illegal_op;
10225 break;
10227 op = (insn >> 4) & 0xf;
10228 tmp = load_reg(s, rn);
10229 tmp2 = load_reg(s, rm);
10230 switch ((insn >> 20) & 7) {
10231 case 0: /* 32 x 32 -> 32 */
10232 tcg_gen_mul_i32(tmp, tmp, tmp2);
10233 tcg_temp_free_i32(tmp2);
10234 if (rs != 15) {
10235 tmp2 = load_reg(s, rs);
10236 if (op)
10237 tcg_gen_sub_i32(tmp, tmp2, tmp);
10238 else
10239 tcg_gen_add_i32(tmp, tmp, tmp2);
10240 tcg_temp_free_i32(tmp2);
10242 break;
10243 case 1: /* 16 x 16 -> 32 */
10244 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10245 tcg_temp_free_i32(tmp2);
10246 if (rs != 15) {
10247 tmp2 = load_reg(s, rs);
10248 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10249 tcg_temp_free_i32(tmp2);
10251 break;
10252 case 2: /* Dual multiply add. */
10253 case 4: /* Dual multiply subtract. */
10254 if (op)
10255 gen_swap_half(tmp2);
10256 gen_smul_dual(tmp, tmp2);
10257 if (insn & (1 << 22)) {
10258 /* This subtraction cannot overflow. */
10259 tcg_gen_sub_i32(tmp, tmp, tmp2);
10260 } else {
10261 /* This addition cannot overflow 32 bits;
10262 * however it may overflow considered as a signed
10263 * operation, in which case we must set the Q flag.
10265 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10267 tcg_temp_free_i32(tmp2);
10268 if (rs != 15)
10270 tmp2 = load_reg(s, rs);
10271 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10272 tcg_temp_free_i32(tmp2);
10274 break;
10275 case 3: /* 32 * 16 -> 32msb */
10276 if (op)
10277 tcg_gen_sari_i32(tmp2, tmp2, 16);
10278 else
10279 gen_sxth(tmp2);
10280 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10281 tcg_gen_shri_i64(tmp64, tmp64, 16);
10282 tmp = tcg_temp_new_i32();
10283 tcg_gen_extrl_i64_i32(tmp, tmp64);
10284 tcg_temp_free_i64(tmp64);
10285 if (rs != 15)
10287 tmp2 = load_reg(s, rs);
10288 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10289 tcg_temp_free_i32(tmp2);
10291 break;
10292 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10293 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10294 if (rs != 15) {
10295 tmp = load_reg(s, rs);
10296 if (insn & (1 << 20)) {
10297 tmp64 = gen_addq_msw(tmp64, tmp);
10298 } else {
10299 tmp64 = gen_subq_msw(tmp64, tmp);
10302 if (insn & (1 << 4)) {
10303 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10305 tcg_gen_shri_i64(tmp64, tmp64, 32);
10306 tmp = tcg_temp_new_i32();
10307 tcg_gen_extrl_i64_i32(tmp, tmp64);
10308 tcg_temp_free_i64(tmp64);
10309 break;
10310 case 7: /* Unsigned sum of absolute differences. */
10311 gen_helper_usad8(tmp, tmp, tmp2);
10312 tcg_temp_free_i32(tmp2);
10313 if (rs != 15) {
10314 tmp2 = load_reg(s, rs);
10315 tcg_gen_add_i32(tmp, tmp, tmp2);
10316 tcg_temp_free_i32(tmp2);
10318 break;
10320 store_reg(s, rd, tmp);
10321 break;
10322 case 6: case 7: /* 64-bit multiply, Divide. */
10323 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10324 tmp = load_reg(s, rn);
10325 tmp2 = load_reg(s, rm);
10326 if ((op & 0x50) == 0x10) {
10327 /* sdiv, udiv */
10328 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10329 goto illegal_op;
10331 if (op & 0x20)
10332 gen_helper_udiv(tmp, tmp, tmp2);
10333 else
10334 gen_helper_sdiv(tmp, tmp, tmp2);
10335 tcg_temp_free_i32(tmp2);
10336 store_reg(s, rd, tmp);
10337 } else if ((op & 0xe) == 0xc) {
10338 /* Dual multiply accumulate long. */
10339 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10340 tcg_temp_free_i32(tmp);
10341 tcg_temp_free_i32(tmp2);
10342 goto illegal_op;
10344 if (op & 1)
10345 gen_swap_half(tmp2);
10346 gen_smul_dual(tmp, tmp2);
10347 if (op & 0x10) {
10348 tcg_gen_sub_i32(tmp, tmp, tmp2);
10349 } else {
10350 tcg_gen_add_i32(tmp, tmp, tmp2);
10352 tcg_temp_free_i32(tmp2);
10353 /* BUGFIX */
10354 tmp64 = tcg_temp_new_i64();
10355 tcg_gen_ext_i32_i64(tmp64, tmp);
10356 tcg_temp_free_i32(tmp);
10357 gen_addq(s, tmp64, rs, rd);
10358 gen_storeq_reg(s, rs, rd, tmp64);
10359 tcg_temp_free_i64(tmp64);
10360 } else {
10361 if (op & 0x20) {
10362 /* Unsigned 64-bit multiply */
10363 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10364 } else {
10365 if (op & 8) {
10366 /* smlalxy */
10367 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10368 tcg_temp_free_i32(tmp2);
10369 tcg_temp_free_i32(tmp);
10370 goto illegal_op;
10372 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10373 tcg_temp_free_i32(tmp2);
10374 tmp64 = tcg_temp_new_i64();
10375 tcg_gen_ext_i32_i64(tmp64, tmp);
10376 tcg_temp_free_i32(tmp);
10377 } else {
10378 /* Signed 64-bit multiply */
10379 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10382 if (op & 4) {
10383 /* umaal */
10384 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10385 tcg_temp_free_i64(tmp64);
10386 goto illegal_op;
10388 gen_addq_lo(s, tmp64, rs);
10389 gen_addq_lo(s, tmp64, rd);
10390 } else if (op & 0x40) {
10391 /* 64-bit accumulate. */
10392 gen_addq(s, tmp64, rs, rd);
10394 gen_storeq_reg(s, rs, rd, tmp64);
10395 tcg_temp_free_i64(tmp64);
10397 break;
10399 break;
10400 case 6: case 7: case 14: case 15:
10401 /* Coprocessor. */
10402 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10403 /* We don't currently implement M profile FP support,
10404 * so this entire space should give a NOCP fault.
10406 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10407 default_exception_el(s));
10408 break;
10410 if (((insn >> 24) & 3) == 3) {
10411 /* Translate into the equivalent ARM encoding. */
10412 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10413 if (disas_neon_data_insn(s, insn)) {
10414 goto illegal_op;
10416 } else if (((insn >> 8) & 0xe) == 10) {
10417 if (disas_vfp_insn(s, insn)) {
10418 goto illegal_op;
10420 } else {
10421 if (insn & (1 << 28))
10422 goto illegal_op;
10423 if (disas_coproc_insn(s, insn)) {
10424 goto illegal_op;
10427 break;
10428 case 8: case 9: case 10: case 11:
10429 if (insn & (1 << 15)) {
10430 /* Branches, misc control. */
10431 if (insn & 0x5000) {
10432 /* Unconditional branch. */
10433 /* signextend(hw1[10:0]) -> offset[:12]. */
10434 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10435 /* hw1[10:0] -> offset[11:1]. */
10436 offset |= (insn & 0x7ff) << 1;
10437 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10438 offset[24:22] already have the same value because of the
10439 sign extension above. */
10440 offset ^= ((~insn) & (1 << 13)) << 10;
10441 offset ^= ((~insn) & (1 << 11)) << 11;
10443 if (insn & (1 << 14)) {
10444 /* Branch and link. */
10445 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10448 offset += s->pc;
10449 if (insn & (1 << 12)) {
10450 /* b/bl */
10451 gen_jmp(s, offset);
10452 } else {
10453 /* blx */
10454 offset &= ~(uint32_t)2;
10455 /* thumb2 bx, no need to check */
10456 gen_bx_im(s, offset);
10458 } else if (((insn >> 23) & 7) == 7) {
10459 /* Misc control */
10460 if (insn & (1 << 13))
10461 goto illegal_op;
10463 if (insn & (1 << 26)) {
10464 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10465 goto illegal_op;
10467 if (!(insn & (1 << 20))) {
10468 /* Hypervisor call (v7) */
10469 int imm16 = extract32(insn, 16, 4) << 12
10470 | extract32(insn, 0, 12);
10471 ARCH(7);
10472 if (IS_USER(s)) {
10473 goto illegal_op;
10475 gen_hvc(s, imm16);
10476 } else {
10477 /* Secure monitor call (v6+) */
10478 ARCH(6K);
10479 if (IS_USER(s)) {
10480 goto illegal_op;
10482 gen_smc(s);
10484 } else {
10485 op = (insn >> 20) & 7;
10486 switch (op) {
10487 case 0: /* msr cpsr. */
10488 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10489 tmp = load_reg(s, rn);
10490 /* the constant is the mask and SYSm fields */
10491 addr = tcg_const_i32(insn & 0xfff);
10492 gen_helper_v7m_msr(cpu_env, addr, tmp);
10493 tcg_temp_free_i32(addr);
10494 tcg_temp_free_i32(tmp);
10495 gen_lookup_tb(s);
10496 break;
10498 /* fall through */
10499 case 1: /* msr spsr. */
10500 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10501 goto illegal_op;
10504 if (extract32(insn, 5, 1)) {
10505 /* MSR (banked) */
10506 int sysm = extract32(insn, 8, 4) |
10507 (extract32(insn, 4, 1) << 4);
10508 int r = op & 1;
10510 gen_msr_banked(s, r, sysm, rm);
10511 break;
10514 /* MSR (for PSRs) */
10515 tmp = load_reg(s, rn);
10516 if (gen_set_psr(s,
10517 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10518 op == 1, tmp))
10519 goto illegal_op;
10520 break;
10521 case 2: /* cps, nop-hint. */
10522 if (((insn >> 8) & 7) == 0) {
10523 gen_nop_hint(s, insn & 0xff);
10525 /* Implemented as NOP in user mode. */
10526 if (IS_USER(s))
10527 break;
10528 offset = 0;
10529 imm = 0;
10530 if (insn & (1 << 10)) {
10531 if (insn & (1 << 7))
10532 offset |= CPSR_A;
10533 if (insn & (1 << 6))
10534 offset |= CPSR_I;
10535 if (insn & (1 << 5))
10536 offset |= CPSR_F;
10537 if (insn & (1 << 9))
10538 imm = CPSR_A | CPSR_I | CPSR_F;
10540 if (insn & (1 << 8)) {
10541 offset |= 0x1f;
10542 imm |= (insn & 0x1f);
10544 if (offset) {
10545 gen_set_psr_im(s, offset, 0, imm);
10547 break;
10548 case 3: /* Special control operations. */
10549 ARCH(7);
10550 op = (insn >> 4) & 0xf;
10551 switch (op) {
10552 case 2: /* clrex */
10553 gen_clrex(s);
10554 break;
10555 case 4: /* dsb */
10556 case 5: /* dmb */
10557 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10558 break;
10559 case 6: /* isb */
10560 /* We need to break the TB after this insn
10561 * to execute self-modifying code correctly
10562 * and also to take any pending interrupts
10563 * immediately.
10565 gen_goto_tb(s, 0, s->pc & ~1);
10566 break;
10567 default:
10568 goto illegal_op;
10570 break;
10571 case 4: /* bxj */
10572 /* Trivial implementation equivalent to bx.
10573 * This instruction doesn't exist at all for M-profile.
10575 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10576 goto illegal_op;
10578 tmp = load_reg(s, rn);
10579 gen_bx(s, tmp);
10580 break;
10581 case 5: /* Exception return. */
10582 if (IS_USER(s)) {
10583 goto illegal_op;
10585 if (rn != 14 || rd != 15) {
10586 goto illegal_op;
10588 tmp = load_reg(s, rn);
10589 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10590 gen_exception_return(s, tmp);
10591 break;
10592 case 6: /* MRS */
10593 if (extract32(insn, 5, 1) &&
10594 !arm_dc_feature(s, ARM_FEATURE_M)) {
10595 /* MRS (banked) */
10596 int sysm = extract32(insn, 16, 4) |
10597 (extract32(insn, 4, 1) << 4);
10599 gen_mrs_banked(s, 0, sysm, rd);
10600 break;
10603 if (extract32(insn, 16, 4) != 0xf) {
10604 goto illegal_op;
10606 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10607 extract32(insn, 0, 8) != 0) {
10608 goto illegal_op;
10611 /* mrs cpsr */
10612 tmp = tcg_temp_new_i32();
10613 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10614 addr = tcg_const_i32(insn & 0xff);
10615 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10616 tcg_temp_free_i32(addr);
10617 } else {
10618 gen_helper_cpsr_read(tmp, cpu_env);
10620 store_reg(s, rd, tmp);
10621 break;
10622 case 7: /* MRS */
10623 if (extract32(insn, 5, 1) &&
10624 !arm_dc_feature(s, ARM_FEATURE_M)) {
10625 /* MRS (banked) */
10626 int sysm = extract32(insn, 16, 4) |
10627 (extract32(insn, 4, 1) << 4);
10629 gen_mrs_banked(s, 1, sysm, rd);
10630 break;
10633 /* mrs spsr. */
10634 /* Not accessible in user mode. */
10635 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10636 goto illegal_op;
10639 if (extract32(insn, 16, 4) != 0xf ||
10640 extract32(insn, 0, 8) != 0) {
10641 goto illegal_op;
10644 tmp = load_cpu_field(spsr);
10645 store_reg(s, rd, tmp);
10646 break;
10649 } else {
10650 /* Conditional branch. */
10651 op = (insn >> 22) & 0xf;
10652 /* Generate a conditional jump to next instruction. */
10653 s->condlabel = gen_new_label();
10654 arm_gen_test_cc(op ^ 1, s->condlabel);
10655 s->condjmp = 1;
10657 /* offset[11:1] = insn[10:0] */
10658 offset = (insn & 0x7ff) << 1;
10659 /* offset[17:12] = insn[21:16]. */
10660 offset |= (insn & 0x003f0000) >> 4;
10661 /* offset[31:20] = insn[26]. */
10662 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10663 /* offset[18] = insn[13]. */
10664 offset |= (insn & (1 << 13)) << 5;
10665 /* offset[19] = insn[11]. */
10666 offset |= (insn & (1 << 11)) << 8;
10668 /* jump to the offset */
10669 gen_jmp(s, s->pc + offset);
10671 } else {
10672 /* Data processing immediate. */
10673 if (insn & (1 << 25)) {
10674 if (insn & (1 << 24)) {
10675 if (insn & (1 << 20))
10676 goto illegal_op;
10677 /* Bitfield/Saturate. */
10678 op = (insn >> 21) & 7;
10679 imm = insn & 0x1f;
10680 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10681 if (rn == 15) {
10682 tmp = tcg_temp_new_i32();
10683 tcg_gen_movi_i32(tmp, 0);
10684 } else {
10685 tmp = load_reg(s, rn);
10687 switch (op) {
10688 case 2: /* Signed bitfield extract. */
10689 imm++;
10690 if (shift + imm > 32)
10691 goto illegal_op;
10692 if (imm < 32) {
10693 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10695 break;
10696 case 6: /* Unsigned bitfield extract. */
10697 imm++;
10698 if (shift + imm > 32)
10699 goto illegal_op;
10700 if (imm < 32) {
10701 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10703 break;
10704 case 3: /* Bitfield insert/clear. */
10705 if (imm < shift)
10706 goto illegal_op;
10707 imm = imm + 1 - shift;
10708 if (imm != 32) {
10709 tmp2 = load_reg(s, rd);
10710 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10711 tcg_temp_free_i32(tmp2);
10713 break;
10714 case 7:
10715 goto illegal_op;
10716 default: /* Saturate. */
10717 if (shift) {
10718 if (op & 1)
10719 tcg_gen_sari_i32(tmp, tmp, shift);
10720 else
10721 tcg_gen_shli_i32(tmp, tmp, shift);
10723 tmp2 = tcg_const_i32(imm);
10724 if (op & 4) {
10725 /* Unsigned. */
10726 if ((op & 1) && shift == 0) {
10727 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10728 tcg_temp_free_i32(tmp);
10729 tcg_temp_free_i32(tmp2);
10730 goto illegal_op;
10732 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10733 } else {
10734 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10736 } else {
10737 /* Signed. */
10738 if ((op & 1) && shift == 0) {
10739 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10740 tcg_temp_free_i32(tmp);
10741 tcg_temp_free_i32(tmp2);
10742 goto illegal_op;
10744 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10745 } else {
10746 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10749 tcg_temp_free_i32(tmp2);
10750 break;
10752 store_reg(s, rd, tmp);
10753 } else {
10754 imm = ((insn & 0x04000000) >> 15)
10755 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10756 if (insn & (1 << 22)) {
10757 /* 16-bit immediate. */
10758 imm |= (insn >> 4) & 0xf000;
10759 if (insn & (1 << 23)) {
10760 /* movt */
10761 tmp = load_reg(s, rd);
10762 tcg_gen_ext16u_i32(tmp, tmp);
10763 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10764 } else {
10765 /* movw */
10766 tmp = tcg_temp_new_i32();
10767 tcg_gen_movi_i32(tmp, imm);
10769 } else {
10770 /* Add/sub 12-bit immediate. */
10771 if (rn == 15) {
10772 offset = s->pc & ~(uint32_t)3;
10773 if (insn & (1 << 23))
10774 offset -= imm;
10775 else
10776 offset += imm;
10777 tmp = tcg_temp_new_i32();
10778 tcg_gen_movi_i32(tmp, offset);
10779 } else {
10780 tmp = load_reg(s, rn);
10781 if (insn & (1 << 23))
10782 tcg_gen_subi_i32(tmp, tmp, imm);
10783 else
10784 tcg_gen_addi_i32(tmp, tmp, imm);
10787 store_reg(s, rd, tmp);
10789 } else {
10790 int shifter_out = 0;
10791 /* modified 12-bit immediate. */
10792 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10793 imm = (insn & 0xff);
10794 switch (shift) {
10795 case 0: /* XY */
10796 /* Nothing to do. */
10797 break;
10798 case 1: /* 00XY00XY */
10799 imm |= imm << 16;
10800 break;
10801 case 2: /* XY00XY00 */
10802 imm |= imm << 16;
10803 imm <<= 8;
10804 break;
10805 case 3: /* XYXYXYXY */
10806 imm |= imm << 16;
10807 imm |= imm << 8;
10808 break;
10809 default: /* Rotated constant. */
10810 shift = (shift << 1) | (imm >> 7);
10811 imm |= 0x80;
10812 imm = imm << (32 - shift);
10813 shifter_out = 1;
10814 break;
10816 tmp2 = tcg_temp_new_i32();
10817 tcg_gen_movi_i32(tmp2, imm);
10818 rn = (insn >> 16) & 0xf;
10819 if (rn == 15) {
10820 tmp = tcg_temp_new_i32();
10821 tcg_gen_movi_i32(tmp, 0);
10822 } else {
10823 tmp = load_reg(s, rn);
10825 op = (insn >> 21) & 0xf;
10826 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10827 shifter_out, tmp, tmp2))
10828 goto illegal_op;
10829 tcg_temp_free_i32(tmp2);
10830 rd = (insn >> 8) & 0xf;
10831 if (rd != 15) {
10832 store_reg(s, rd, tmp);
10833 } else {
10834 tcg_temp_free_i32(tmp);
10838 break;
10839 case 12: /* Load/store single data item. */
10841 int postinc = 0;
10842 int writeback = 0;
10843 int memidx;
10844 ISSInfo issinfo;
10846 if ((insn & 0x01100000) == 0x01000000) {
10847 if (disas_neon_ls_insn(s, insn)) {
10848 goto illegal_op;
10850 break;
10852 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10853 if (rs == 15) {
10854 if (!(insn & (1 << 20))) {
10855 goto illegal_op;
10857 if (op != 2) {
10858 /* Byte or halfword load space with dest == r15 : memory hints.
10859 * Catch them early so we don't emit pointless addressing code.
10860 * This space is a mix of:
10861 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10862 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10863 * cores)
10864 * unallocated hints, which must be treated as NOPs
10865 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10866 * which is easiest for the decoding logic
10867 * Some space which must UNDEF
10869 int op1 = (insn >> 23) & 3;
10870 int op2 = (insn >> 6) & 0x3f;
10871 if (op & 2) {
10872 goto illegal_op;
10874 if (rn == 15) {
10875 /* UNPREDICTABLE, unallocated hint or
10876 * PLD/PLDW/PLI (literal)
10878 return 0;
10880 if (op1 & 1) {
10881 return 0; /* PLD/PLDW/PLI or unallocated hint */
10883 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10884 return 0; /* PLD/PLDW/PLI or unallocated hint */
10886 /* UNDEF space, or an UNPREDICTABLE */
10887 return 1;
10890 memidx = get_mem_index(s);
10891 if (rn == 15) {
10892 addr = tcg_temp_new_i32();
10893 /* PC relative. */
10894 /* s->pc has already been incremented by 4. */
10895 imm = s->pc & 0xfffffffc;
10896 if (insn & (1 << 23))
10897 imm += insn & 0xfff;
10898 else
10899 imm -= insn & 0xfff;
10900 tcg_gen_movi_i32(addr, imm);
10901 } else {
10902 addr = load_reg(s, rn);
10903 if (insn & (1 << 23)) {
10904 /* Positive offset. */
10905 imm = insn & 0xfff;
10906 tcg_gen_addi_i32(addr, addr, imm);
10907 } else {
10908 imm = insn & 0xff;
10909 switch ((insn >> 8) & 0xf) {
10910 case 0x0: /* Shifted Register. */
10911 shift = (insn >> 4) & 0xf;
10912 if (shift > 3) {
10913 tcg_temp_free_i32(addr);
10914 goto illegal_op;
10916 tmp = load_reg(s, rm);
10917 if (shift)
10918 tcg_gen_shli_i32(tmp, tmp, shift);
10919 tcg_gen_add_i32(addr, addr, tmp);
10920 tcg_temp_free_i32(tmp);
10921 break;
10922 case 0xc: /* Negative offset. */
10923 tcg_gen_addi_i32(addr, addr, -imm);
10924 break;
10925 case 0xe: /* User privilege. */
10926 tcg_gen_addi_i32(addr, addr, imm);
10927 memidx = get_a32_user_mem_index(s);
10928 break;
10929 case 0x9: /* Post-decrement. */
10930 imm = -imm;
10931 /* Fall through. */
10932 case 0xb: /* Post-increment. */
10933 postinc = 1;
10934 writeback = 1;
10935 break;
10936 case 0xd: /* Pre-decrement. */
10937 imm = -imm;
10938 /* Fall through. */
10939 case 0xf: /* Pre-increment. */
10940 tcg_gen_addi_i32(addr, addr, imm);
10941 writeback = 1;
10942 break;
10943 default:
10944 tcg_temp_free_i32(addr);
10945 goto illegal_op;
10950 issinfo = writeback ? ISSInvalid : rs;
10952 if (insn & (1 << 20)) {
10953 /* Load. */
10954 tmp = tcg_temp_new_i32();
10955 switch (op) {
10956 case 0:
10957 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10958 break;
10959 case 4:
10960 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10961 break;
10962 case 1:
10963 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10964 break;
10965 case 5:
10966 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10967 break;
10968 case 2:
10969 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10970 break;
10971 default:
10972 tcg_temp_free_i32(tmp);
10973 tcg_temp_free_i32(addr);
10974 goto illegal_op;
10976 if (rs == 15) {
10977 gen_bx_excret(s, tmp);
10978 } else {
10979 store_reg(s, rs, tmp);
10981 } else {
10982 /* Store. */
10983 tmp = load_reg(s, rs);
10984 switch (op) {
10985 case 0:
10986 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10987 break;
10988 case 1:
10989 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10990 break;
10991 case 2:
10992 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10993 break;
10994 default:
10995 tcg_temp_free_i32(tmp);
10996 tcg_temp_free_i32(addr);
10997 goto illegal_op;
10999 tcg_temp_free_i32(tmp);
11001 if (postinc)
11002 tcg_gen_addi_i32(addr, addr, imm);
11003 if (writeback) {
11004 store_reg(s, rn, addr);
11005 } else {
11006 tcg_temp_free_i32(addr);
11009 break;
11010 default:
11011 goto illegal_op;
11013 return 0;
11014 illegal_op:
11015 return 1;
11018 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
11020 uint32_t val, insn, op, rm, rn, rd, shift, cond;
11021 int32_t offset;
11022 int i;
11023 TCGv_i32 tmp;
11024 TCGv_i32 tmp2;
11025 TCGv_i32 addr;
11027 if (s->condexec_mask) {
11028 cond = s->condexec_cond;
11029 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
11030 s->condlabel = gen_new_label();
11031 arm_gen_test_cc(cond ^ 1, s->condlabel);
11032 s->condjmp = 1;
11036 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11037 s->pc += 2;
11039 switch (insn >> 12) {
11040 case 0: case 1:
11042 rd = insn & 7;
11043 op = (insn >> 11) & 3;
11044 if (op == 3) {
11045 /* add/subtract */
11046 rn = (insn >> 3) & 7;
11047 tmp = load_reg(s, rn);
11048 if (insn & (1 << 10)) {
11049 /* immediate */
11050 tmp2 = tcg_temp_new_i32();
11051 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11052 } else {
11053 /* reg */
11054 rm = (insn >> 6) & 7;
11055 tmp2 = load_reg(s, rm);
11057 if (insn & (1 << 9)) {
11058 if (s->condexec_mask)
11059 tcg_gen_sub_i32(tmp, tmp, tmp2);
11060 else
11061 gen_sub_CC(tmp, tmp, tmp2);
11062 } else {
11063 if (s->condexec_mask)
11064 tcg_gen_add_i32(tmp, tmp, tmp2);
11065 else
11066 gen_add_CC(tmp, tmp, tmp2);
11068 tcg_temp_free_i32(tmp2);
11069 store_reg(s, rd, tmp);
11070 } else {
11071 /* shift immediate */
11072 rm = (insn >> 3) & 7;
11073 shift = (insn >> 6) & 0x1f;
11074 tmp = load_reg(s, rm);
11075 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11076 if (!s->condexec_mask)
11077 gen_logic_CC(tmp);
11078 store_reg(s, rd, tmp);
11080 break;
11081 case 2: case 3:
11082 /* arithmetic large immediate */
11083 op = (insn >> 11) & 3;
11084 rd = (insn >> 8) & 0x7;
11085 if (op == 0) { /* mov */
11086 tmp = tcg_temp_new_i32();
11087 tcg_gen_movi_i32(tmp, insn & 0xff);
11088 if (!s->condexec_mask)
11089 gen_logic_CC(tmp);
11090 store_reg(s, rd, tmp);
11091 } else {
11092 tmp = load_reg(s, rd);
11093 tmp2 = tcg_temp_new_i32();
11094 tcg_gen_movi_i32(tmp2, insn & 0xff);
11095 switch (op) {
11096 case 1: /* cmp */
11097 gen_sub_CC(tmp, tmp, tmp2);
11098 tcg_temp_free_i32(tmp);
11099 tcg_temp_free_i32(tmp2);
11100 break;
11101 case 2: /* add */
11102 if (s->condexec_mask)
11103 tcg_gen_add_i32(tmp, tmp, tmp2);
11104 else
11105 gen_add_CC(tmp, tmp, tmp2);
11106 tcg_temp_free_i32(tmp2);
11107 store_reg(s, rd, tmp);
11108 break;
11109 case 3: /* sub */
11110 if (s->condexec_mask)
11111 tcg_gen_sub_i32(tmp, tmp, tmp2);
11112 else
11113 gen_sub_CC(tmp, tmp, tmp2);
11114 tcg_temp_free_i32(tmp2);
11115 store_reg(s, rd, tmp);
11116 break;
11119 break;
11120 case 4:
11121 if (insn & (1 << 11)) {
11122 rd = (insn >> 8) & 7;
11123 /* load pc-relative. Bit 1 of PC is ignored. */
11124 val = s->pc + 2 + ((insn & 0xff) * 4);
11125 val &= ~(uint32_t)2;
11126 addr = tcg_temp_new_i32();
11127 tcg_gen_movi_i32(addr, val);
11128 tmp = tcg_temp_new_i32();
11129 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11130 rd | ISSIs16Bit);
11131 tcg_temp_free_i32(addr);
11132 store_reg(s, rd, tmp);
11133 break;
11135 if (insn & (1 << 10)) {
11136 /* data processing extended or blx */
11137 rd = (insn & 7) | ((insn >> 4) & 8);
11138 rm = (insn >> 3) & 0xf;
11139 op = (insn >> 8) & 3;
11140 switch (op) {
11141 case 0: /* add */
11142 tmp = load_reg(s, rd);
11143 tmp2 = load_reg(s, rm);
11144 tcg_gen_add_i32(tmp, tmp, tmp2);
11145 tcg_temp_free_i32(tmp2);
11146 store_reg(s, rd, tmp);
11147 break;
11148 case 1: /* cmp */
11149 tmp = load_reg(s, rd);
11150 tmp2 = load_reg(s, rm);
11151 gen_sub_CC(tmp, tmp, tmp2);
11152 tcg_temp_free_i32(tmp2);
11153 tcg_temp_free_i32(tmp);
11154 break;
11155 case 2: /* mov/cpy */
11156 tmp = load_reg(s, rm);
11157 store_reg(s, rd, tmp);
11158 break;
11159 case 3:/* branch [and link] exchange thumb register */
11160 tmp = load_reg(s, rm);
11161 if (insn & (1 << 7)) {
11162 ARCH(5);
11163 val = (uint32_t)s->pc | 1;
11164 tmp2 = tcg_temp_new_i32();
11165 tcg_gen_movi_i32(tmp2, val);
11166 store_reg(s, 14, tmp2);
11167 gen_bx(s, tmp);
11168 } else {
11169 /* Only BX works as exception-return, not BLX */
11170 gen_bx_excret(s, tmp);
11172 break;
11174 break;
11177 /* data processing register */
11178 rd = insn & 7;
11179 rm = (insn >> 3) & 7;
11180 op = (insn >> 6) & 0xf;
11181 if (op == 2 || op == 3 || op == 4 || op == 7) {
11182 /* the shift/rotate ops want the operands backwards */
11183 val = rm;
11184 rm = rd;
11185 rd = val;
11186 val = 1;
11187 } else {
11188 val = 0;
11191 if (op == 9) { /* neg */
11192 tmp = tcg_temp_new_i32();
11193 tcg_gen_movi_i32(tmp, 0);
11194 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11195 tmp = load_reg(s, rd);
11196 } else {
11197 TCGV_UNUSED_I32(tmp);
11200 tmp2 = load_reg(s, rm);
11201 switch (op) {
11202 case 0x0: /* and */
11203 tcg_gen_and_i32(tmp, tmp, tmp2);
11204 if (!s->condexec_mask)
11205 gen_logic_CC(tmp);
11206 break;
11207 case 0x1: /* eor */
11208 tcg_gen_xor_i32(tmp, tmp, tmp2);
11209 if (!s->condexec_mask)
11210 gen_logic_CC(tmp);
11211 break;
11212 case 0x2: /* lsl */
11213 if (s->condexec_mask) {
11214 gen_shl(tmp2, tmp2, tmp);
11215 } else {
11216 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11217 gen_logic_CC(tmp2);
11219 break;
11220 case 0x3: /* lsr */
11221 if (s->condexec_mask) {
11222 gen_shr(tmp2, tmp2, tmp);
11223 } else {
11224 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11225 gen_logic_CC(tmp2);
11227 break;
11228 case 0x4: /* asr */
11229 if (s->condexec_mask) {
11230 gen_sar(tmp2, tmp2, tmp);
11231 } else {
11232 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11233 gen_logic_CC(tmp2);
11235 break;
11236 case 0x5: /* adc */
11237 if (s->condexec_mask) {
11238 gen_adc(tmp, tmp2);
11239 } else {
11240 gen_adc_CC(tmp, tmp, tmp2);
11242 break;
11243 case 0x6: /* sbc */
11244 if (s->condexec_mask) {
11245 gen_sub_carry(tmp, tmp, tmp2);
11246 } else {
11247 gen_sbc_CC(tmp, tmp, tmp2);
11249 break;
11250 case 0x7: /* ror */
11251 if (s->condexec_mask) {
11252 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11253 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11254 } else {
11255 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11256 gen_logic_CC(tmp2);
11258 break;
11259 case 0x8: /* tst */
11260 tcg_gen_and_i32(tmp, tmp, tmp2);
11261 gen_logic_CC(tmp);
11262 rd = 16;
11263 break;
11264 case 0x9: /* neg */
11265 if (s->condexec_mask)
11266 tcg_gen_neg_i32(tmp, tmp2);
11267 else
11268 gen_sub_CC(tmp, tmp, tmp2);
11269 break;
11270 case 0xa: /* cmp */
11271 gen_sub_CC(tmp, tmp, tmp2);
11272 rd = 16;
11273 break;
11274 case 0xb: /* cmn */
11275 gen_add_CC(tmp, tmp, tmp2);
11276 rd = 16;
11277 break;
11278 case 0xc: /* orr */
11279 tcg_gen_or_i32(tmp, tmp, tmp2);
11280 if (!s->condexec_mask)
11281 gen_logic_CC(tmp);
11282 break;
11283 case 0xd: /* mul */
11284 tcg_gen_mul_i32(tmp, tmp, tmp2);
11285 if (!s->condexec_mask)
11286 gen_logic_CC(tmp);
11287 break;
11288 case 0xe: /* bic */
11289 tcg_gen_andc_i32(tmp, tmp, tmp2);
11290 if (!s->condexec_mask)
11291 gen_logic_CC(tmp);
11292 break;
11293 case 0xf: /* mvn */
11294 tcg_gen_not_i32(tmp2, tmp2);
11295 if (!s->condexec_mask)
11296 gen_logic_CC(tmp2);
11297 val = 1;
11298 rm = rd;
11299 break;
11301 if (rd != 16) {
11302 if (val) {
11303 store_reg(s, rm, tmp2);
11304 if (op != 0xf)
11305 tcg_temp_free_i32(tmp);
11306 } else {
11307 store_reg(s, rd, tmp);
11308 tcg_temp_free_i32(tmp2);
11310 } else {
11311 tcg_temp_free_i32(tmp);
11312 tcg_temp_free_i32(tmp2);
11314 break;
11316 case 5:
11317 /* load/store register offset. */
11318 rd = insn & 7;
11319 rn = (insn >> 3) & 7;
11320 rm = (insn >> 6) & 7;
11321 op = (insn >> 9) & 7;
11322 addr = load_reg(s, rn);
11323 tmp = load_reg(s, rm);
11324 tcg_gen_add_i32(addr, addr, tmp);
11325 tcg_temp_free_i32(tmp);
11327 if (op < 3) { /* store */
11328 tmp = load_reg(s, rd);
11329 } else {
11330 tmp = tcg_temp_new_i32();
11333 switch (op) {
11334 case 0: /* str */
11335 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11336 break;
11337 case 1: /* strh */
11338 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11339 break;
11340 case 2: /* strb */
11341 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11342 break;
11343 case 3: /* ldrsb */
11344 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11345 break;
11346 case 4: /* ldr */
11347 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11348 break;
11349 case 5: /* ldrh */
11350 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11351 break;
11352 case 6: /* ldrb */
11353 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11354 break;
11355 case 7: /* ldrsh */
11356 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11357 break;
11359 if (op >= 3) { /* load */
11360 store_reg(s, rd, tmp);
11361 } else {
11362 tcg_temp_free_i32(tmp);
11364 tcg_temp_free_i32(addr);
11365 break;
11367 case 6:
11368 /* load/store word immediate offset */
11369 rd = insn & 7;
11370 rn = (insn >> 3) & 7;
11371 addr = load_reg(s, rn);
11372 val = (insn >> 4) & 0x7c;
11373 tcg_gen_addi_i32(addr, addr, val);
11375 if (insn & (1 << 11)) {
11376 /* load */
11377 tmp = tcg_temp_new_i32();
11378 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11379 store_reg(s, rd, tmp);
11380 } else {
11381 /* store */
11382 tmp = load_reg(s, rd);
11383 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11384 tcg_temp_free_i32(tmp);
11386 tcg_temp_free_i32(addr);
11387 break;
11389 case 7:
11390 /* load/store byte immediate offset */
11391 rd = insn & 7;
11392 rn = (insn >> 3) & 7;
11393 addr = load_reg(s, rn);
11394 val = (insn >> 6) & 0x1f;
11395 tcg_gen_addi_i32(addr, addr, val);
11397 if (insn & (1 << 11)) {
11398 /* load */
11399 tmp = tcg_temp_new_i32();
11400 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11401 store_reg(s, rd, tmp);
11402 } else {
11403 /* store */
11404 tmp = load_reg(s, rd);
11405 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11406 tcg_temp_free_i32(tmp);
11408 tcg_temp_free_i32(addr);
11409 break;
11411 case 8:
11412 /* load/store halfword immediate offset */
11413 rd = insn & 7;
11414 rn = (insn >> 3) & 7;
11415 addr = load_reg(s, rn);
11416 val = (insn >> 5) & 0x3e;
11417 tcg_gen_addi_i32(addr, addr, val);
11419 if (insn & (1 << 11)) {
11420 /* load */
11421 tmp = tcg_temp_new_i32();
11422 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11423 store_reg(s, rd, tmp);
11424 } else {
11425 /* store */
11426 tmp = load_reg(s, rd);
11427 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11428 tcg_temp_free_i32(tmp);
11430 tcg_temp_free_i32(addr);
11431 break;
11433 case 9:
11434 /* load/store from stack */
11435 rd = (insn >> 8) & 7;
11436 addr = load_reg(s, 13);
11437 val = (insn & 0xff) * 4;
11438 tcg_gen_addi_i32(addr, addr, val);
11440 if (insn & (1 << 11)) {
11441 /* load */
11442 tmp = tcg_temp_new_i32();
11443 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11444 store_reg(s, rd, tmp);
11445 } else {
11446 /* store */
11447 tmp = load_reg(s, rd);
11448 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11449 tcg_temp_free_i32(tmp);
11451 tcg_temp_free_i32(addr);
11452 break;
11454 case 10:
11455 /* add to high reg */
11456 rd = (insn >> 8) & 7;
11457 if (insn & (1 << 11)) {
11458 /* SP */
11459 tmp = load_reg(s, 13);
11460 } else {
11461 /* PC. bit 1 is ignored. */
11462 tmp = tcg_temp_new_i32();
11463 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11465 val = (insn & 0xff) * 4;
11466 tcg_gen_addi_i32(tmp, tmp, val);
11467 store_reg(s, rd, tmp);
11468 break;
11470 case 11:
11471 /* misc */
11472 op = (insn >> 8) & 0xf;
11473 switch (op) {
11474 case 0:
11475 /* adjust stack pointer */
11476 tmp = load_reg(s, 13);
11477 val = (insn & 0x7f) * 4;
11478 if (insn & (1 << 7))
11479 val = -(int32_t)val;
11480 tcg_gen_addi_i32(tmp, tmp, val);
11481 store_reg(s, 13, tmp);
11482 break;
11484 case 2: /* sign/zero extend. */
11485 ARCH(6);
11486 rd = insn & 7;
11487 rm = (insn >> 3) & 7;
11488 tmp = load_reg(s, rm);
11489 switch ((insn >> 6) & 3) {
11490 case 0: gen_sxth(tmp); break;
11491 case 1: gen_sxtb(tmp); break;
11492 case 2: gen_uxth(tmp); break;
11493 case 3: gen_uxtb(tmp); break;
11495 store_reg(s, rd, tmp);
11496 break;
11497 case 4: case 5: case 0xc: case 0xd:
11498 /* push/pop */
11499 addr = load_reg(s, 13);
11500 if (insn & (1 << 8))
11501 offset = 4;
11502 else
11503 offset = 0;
11504 for (i = 0; i < 8; i++) {
11505 if (insn & (1 << i))
11506 offset += 4;
11508 if ((insn & (1 << 11)) == 0) {
11509 tcg_gen_addi_i32(addr, addr, -offset);
11511 for (i = 0; i < 8; i++) {
11512 if (insn & (1 << i)) {
11513 if (insn & (1 << 11)) {
11514 /* pop */
11515 tmp = tcg_temp_new_i32();
11516 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11517 store_reg(s, i, tmp);
11518 } else {
11519 /* push */
11520 tmp = load_reg(s, i);
11521 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11522 tcg_temp_free_i32(tmp);
11524 /* advance to the next address. */
11525 tcg_gen_addi_i32(addr, addr, 4);
11528 TCGV_UNUSED_I32(tmp);
11529 if (insn & (1 << 8)) {
11530 if (insn & (1 << 11)) {
11531 /* pop pc */
11532 tmp = tcg_temp_new_i32();
11533 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11534 /* don't set the pc until the rest of the instruction
11535 has completed */
11536 } else {
11537 /* push lr */
11538 tmp = load_reg(s, 14);
11539 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11540 tcg_temp_free_i32(tmp);
11542 tcg_gen_addi_i32(addr, addr, 4);
11544 if ((insn & (1 << 11)) == 0) {
11545 tcg_gen_addi_i32(addr, addr, -offset);
11547 /* write back the new stack pointer */
11548 store_reg(s, 13, addr);
11549 /* set the new PC value */
11550 if ((insn & 0x0900) == 0x0900) {
11551 store_reg_from_load(s, 15, tmp);
11553 break;
11555 case 1: case 3: case 9: case 11: /* czb */
11556 rm = insn & 7;
11557 tmp = load_reg(s, rm);
11558 s->condlabel = gen_new_label();
11559 s->condjmp = 1;
11560 if (insn & (1 << 11))
11561 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11562 else
11563 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11564 tcg_temp_free_i32(tmp);
11565 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11566 val = (uint32_t)s->pc + 2;
11567 val += offset;
11568 gen_jmp(s, val);
11569 break;
11571 case 15: /* IT, nop-hint. */
11572 if ((insn & 0xf) == 0) {
11573 gen_nop_hint(s, (insn >> 4) & 0xf);
11574 break;
11576 /* If Then. */
11577 s->condexec_cond = (insn >> 4) & 0xe;
11578 s->condexec_mask = insn & 0x1f;
11579 /* No actual code generated for this insn, just setup state. */
11580 break;
11582 case 0xe: /* bkpt */
11584 int imm8 = extract32(insn, 0, 8);
11585 ARCH(5);
11586 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11587 default_exception_el(s));
11588 break;
11591 case 0xa: /* rev, and hlt */
11593 int op1 = extract32(insn, 6, 2);
11595 if (op1 == 2) {
11596 /* HLT */
11597 int imm6 = extract32(insn, 0, 6);
11599 gen_hlt(s, imm6);
11600 break;
11603 /* Otherwise this is rev */
11604 ARCH(6);
11605 rn = (insn >> 3) & 0x7;
11606 rd = insn & 0x7;
11607 tmp = load_reg(s, rn);
11608 switch (op1) {
11609 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11610 case 1: gen_rev16(tmp); break;
11611 case 3: gen_revsh(tmp); break;
11612 default:
11613 g_assert_not_reached();
11615 store_reg(s, rd, tmp);
11616 break;
11619 case 6:
11620 switch ((insn >> 5) & 7) {
11621 case 2:
11622 /* setend */
11623 ARCH(6);
11624 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11625 gen_helper_setend(cpu_env);
11626 s->is_jmp = DISAS_UPDATE;
11628 break;
11629 case 3:
11630 /* cps */
11631 ARCH(6);
11632 if (IS_USER(s)) {
11633 break;
11635 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11636 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11637 /* FAULTMASK */
11638 if (insn & 1) {
11639 addr = tcg_const_i32(19);
11640 gen_helper_v7m_msr(cpu_env, addr, tmp);
11641 tcg_temp_free_i32(addr);
11643 /* PRIMASK */
11644 if (insn & 2) {
11645 addr = tcg_const_i32(16);
11646 gen_helper_v7m_msr(cpu_env, addr, tmp);
11647 tcg_temp_free_i32(addr);
11649 tcg_temp_free_i32(tmp);
11650 gen_lookup_tb(s);
11651 } else {
11652 if (insn & (1 << 4)) {
11653 shift = CPSR_A | CPSR_I | CPSR_F;
11654 } else {
11655 shift = 0;
11657 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11659 break;
11660 default:
11661 goto undef;
11663 break;
11665 default:
11666 goto undef;
11668 break;
11670 case 12:
11672 /* load/store multiple */
11673 TCGv_i32 loaded_var;
11674 TCGV_UNUSED_I32(loaded_var);
11675 rn = (insn >> 8) & 0x7;
11676 addr = load_reg(s, rn);
11677 for (i = 0; i < 8; i++) {
11678 if (insn & (1 << i)) {
11679 if (insn & (1 << 11)) {
11680 /* load */
11681 tmp = tcg_temp_new_i32();
11682 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11683 if (i == rn) {
11684 loaded_var = tmp;
11685 } else {
11686 store_reg(s, i, tmp);
11688 } else {
11689 /* store */
11690 tmp = load_reg(s, i);
11691 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11692 tcg_temp_free_i32(tmp);
11694 /* advance to the next address */
11695 tcg_gen_addi_i32(addr, addr, 4);
11698 if ((insn & (1 << rn)) == 0) {
11699 /* base reg not in list: base register writeback */
11700 store_reg(s, rn, addr);
11701 } else {
11702 /* base reg in list: if load, complete it now */
11703 if (insn & (1 << 11)) {
11704 store_reg(s, rn, loaded_var);
11706 tcg_temp_free_i32(addr);
11708 break;
11710 case 13:
11711 /* conditional branch or swi */
11712 cond = (insn >> 8) & 0xf;
11713 if (cond == 0xe)
11714 goto undef;
11716 if (cond == 0xf) {
11717 /* swi */
11718 gen_set_pc_im(s, s->pc);
11719 s->svc_imm = extract32(insn, 0, 8);
11720 s->is_jmp = DISAS_SWI;
11721 break;
11723 /* generate a conditional jump to next instruction */
11724 s->condlabel = gen_new_label();
11725 arm_gen_test_cc(cond ^ 1, s->condlabel);
11726 s->condjmp = 1;
11728 /* jump to the offset */
11729 val = (uint32_t)s->pc + 2;
11730 offset = ((int32_t)insn << 24) >> 24;
11731 val += offset << 1;
11732 gen_jmp(s, val);
11733 break;
11735 case 14:
11736 if (insn & (1 << 11)) {
11737 if (disas_thumb2_insn(env, s, insn))
11738 goto undef32;
11739 break;
11741 /* unconditional branch */
11742 val = (uint32_t)s->pc;
11743 offset = ((int32_t)insn << 21) >> 21;
11744 val += (offset << 1) + 2;
11745 gen_jmp(s, val);
11746 break;
11748 case 15:
11749 if (disas_thumb2_insn(env, s, insn))
11750 goto undef32;
11751 break;
11753 return;
11754 undef32:
11755 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11756 default_exception_el(s));
11757 return;
11758 illegal_op:
11759 undef:
11760 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11761 default_exception_el(s));
11764 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11766 /* Return true if the insn at dc->pc might cross a page boundary.
11767 * (False positives are OK, false negatives are not.)
11769 uint16_t insn;
11771 if ((s->pc & 3) == 0) {
11772 /* At a 4-aligned address we can't be crossing a page */
11773 return false;
11776 /* This must be a Thumb insn */
11777 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11779 if ((insn >> 11) >= 0x1d) {
11780 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11781 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11782 * end up actually treating this as two 16-bit insns (see the
11783 * code at the start of disas_thumb2_insn()) but we don't bother
11784 * to check for that as it is unlikely, and false positives here
11785 * are harmless.
11787 return true;
11789 /* Definitely a 16-bit insn, can't be crossing a page. */
11790 return false;
11793 /* generate intermediate code for basic block 'tb'. */
11794 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11796 ARMCPU *cpu = arm_env_get_cpu(env);
11797 CPUState *cs = CPU(cpu);
11798 DisasContext dc1, *dc = &dc1;
11799 target_ulong pc_start;
11800 target_ulong next_page_start;
11801 int num_insns;
11802 int max_insns;
11803 bool end_of_page;
11805 /* generate intermediate code */
11807 /* The A64 decoder has its own top level loop, because it doesn't need
11808 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11810 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11811 gen_intermediate_code_a64(cpu, tb);
11812 return;
11815 pc_start = tb->pc;
11817 dc->tb = tb;
11819 dc->is_jmp = DISAS_NEXT;
11820 dc->pc = pc_start;
11821 dc->singlestep_enabled = cs->singlestep_enabled;
11822 dc->condjmp = 0;
11824 dc->aarch64 = 0;
11825 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11826 * there is no secure EL1, so we route exceptions to EL3.
11828 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11829 !arm_el_is_aa64(env, 3);
11830 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11831 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11832 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11833 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11834 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11835 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
11836 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11837 #if !defined(CONFIG_USER_ONLY)
11838 dc->user = (dc->current_el == 0);
11839 #endif
11840 dc->ns = ARM_TBFLAG_NS(tb->flags);
11841 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11842 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11843 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11844 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11845 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11846 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags);
11847 dc->cp_regs = cpu->cp_regs;
11848 dc->features = env->features;
11850 /* Single step state. The code-generation logic here is:
11851 * SS_ACTIVE == 0:
11852 * generate code with no special handling for single-stepping (except
11853 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11854 * this happens anyway because those changes are all system register or
11855 * PSTATE writes).
11856 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11857 * emit code for one insn
11858 * emit code to clear PSTATE.SS
11859 * emit code to generate software step exception for completed step
11860 * end TB (as usual for having generated an exception)
11861 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11862 * emit code to generate a software step exception
11863 * end the TB
11865 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11866 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11867 dc->is_ldex = false;
11868 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11870 cpu_F0s = tcg_temp_new_i32();
11871 cpu_F1s = tcg_temp_new_i32();
11872 cpu_F0d = tcg_temp_new_i64();
11873 cpu_F1d = tcg_temp_new_i64();
11874 cpu_V0 = cpu_F0d;
11875 cpu_V1 = cpu_F1d;
11876 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11877 cpu_M0 = tcg_temp_new_i64();
11878 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11879 num_insns = 0;
11880 max_insns = tb->cflags & CF_COUNT_MASK;
11881 if (max_insns == 0) {
11882 max_insns = CF_COUNT_MASK;
11884 if (max_insns > TCG_MAX_INSNS) {
11885 max_insns = TCG_MAX_INSNS;
11888 gen_tb_start(tb);
11890 tcg_clear_temp_count();
11892 /* A note on handling of the condexec (IT) bits:
11894 * We want to avoid the overhead of having to write the updated condexec
11895 * bits back to the CPUARMState for every instruction in an IT block. So:
11896 * (1) if the condexec bits are not already zero then we write
11897 * zero back into the CPUARMState now. This avoids complications trying
11898 * to do it at the end of the block. (For example if we don't do this
11899 * it's hard to identify whether we can safely skip writing condexec
11900 * at the end of the TB, which we definitely want to do for the case
11901 * where a TB doesn't do anything with the IT state at all.)
11902 * (2) if we are going to leave the TB then we call gen_set_condexec()
11903 * which will write the correct value into CPUARMState if zero is wrong.
11904 * This is done both for leaving the TB at the end, and for leaving
11905 * it because of an exception we know will happen, which is done in
11906 * gen_exception_insn(). The latter is necessary because we need to
11907 * leave the TB with the PC/IT state just prior to execution of the
11908 * instruction which caused the exception.
11909 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11910 * then the CPUARMState will be wrong and we need to reset it.
11911 * This is handled in the same way as restoration of the
11912 * PC in these situations; we save the value of the condexec bits
11913 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11914 * then uses this to restore them after an exception.
11916 * Note that there are no instructions which can read the condexec
11917 * bits, and none which can write non-static values to them, so
11918 * we don't need to care about whether CPUARMState is correct in the
11919 * middle of a TB.
11922 /* Reset the conditional execution bits immediately. This avoids
11923 complications trying to do it at the end of the block. */
11924 if (dc->condexec_mask || dc->condexec_cond)
11926 TCGv_i32 tmp = tcg_temp_new_i32();
11927 tcg_gen_movi_i32(tmp, 0);
11928 store_cpu_field(tmp, condexec_bits);
11930 do {
11931 dc->insn_start_idx = tcg_op_buf_count();
11932 tcg_gen_insn_start(dc->pc,
11933 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11935 num_insns++;
11937 #ifdef CONFIG_USER_ONLY
11938 /* Intercept jump to the magic kernel page. */
11939 if (dc->pc >= 0xffff0000) {
11940 /* We always get here via a jump, so know we are not in a
11941 conditional execution block. */
11942 gen_exception_internal(EXCP_KERNEL_TRAP);
11943 dc->is_jmp = DISAS_EXC;
11944 break;
11946 #endif
11948 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11949 CPUBreakpoint *bp;
11950 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11951 if (bp->pc == dc->pc) {
11952 if (bp->flags & BP_CPU) {
11953 gen_set_condexec(dc);
11954 gen_set_pc_im(dc, dc->pc);
11955 gen_helper_check_breakpoints(cpu_env);
11956 /* End the TB early; it's likely not going to be executed */
11957 dc->is_jmp = DISAS_UPDATE;
11958 } else {
11959 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11960 /* The address covered by the breakpoint must be
11961 included in [tb->pc, tb->pc + tb->size) in order
11962 to for it to be properly cleared -- thus we
11963 increment the PC here so that the logic setting
11964 tb->size below does the right thing. */
11965 /* TODO: Advance PC by correct instruction length to
11966 * avoid disassembler error messages */
11967 dc->pc += 2;
11968 goto done_generating;
11970 break;
11975 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11976 gen_io_start();
11979 if (dc->ss_active && !dc->pstate_ss) {
11980 /* Singlestep state is Active-pending.
11981 * If we're in this state at the start of a TB then either
11982 * a) we just took an exception to an EL which is being debugged
11983 * and this is the first insn in the exception handler
11984 * b) debug exceptions were masked and we just unmasked them
11985 * without changing EL (eg by clearing PSTATE.D)
11986 * In either case we're going to take a swstep exception in the
11987 * "did not step an insn" case, and so the syndrome ISV and EX
11988 * bits should be zero.
11990 assert(num_insns == 1);
11991 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11992 default_exception_el(dc));
11993 goto done_generating;
11996 if (dc->thumb) {
11997 disas_thumb_insn(env, dc);
11998 if (dc->condexec_mask) {
11999 dc->condexec_cond = (dc->condexec_cond & 0xe)
12000 | ((dc->condexec_mask >> 4) & 1);
12001 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12002 if (dc->condexec_mask == 0) {
12003 dc->condexec_cond = 0;
12006 } else {
12007 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12008 dc->pc += 4;
12009 disas_arm_insn(dc, insn);
12012 if (dc->condjmp && !dc->is_jmp) {
12013 gen_set_label(dc->condlabel);
12014 dc->condjmp = 0;
12017 if (tcg_check_temp_count()) {
12018 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
12019 dc->pc);
12022 /* Translation stops when a conditional branch is encountered.
12023 * Otherwise the subsequent code could get translated several times.
12024 * Also stop translation when a page boundary is reached. This
12025 * ensures prefetch aborts occur at the right place. */
12027 /* We want to stop the TB if the next insn starts in a new page,
12028 * or if it spans between this page and the next. This means that
12029 * if we're looking at the last halfword in the page we need to
12030 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12031 * or a 32-bit Thumb insn (which won't).
12032 * This is to avoid generating a silly TB with a single 16-bit insn
12033 * in it at the end of this page (which would execute correctly
12034 * but isn't very efficient).
12036 end_of_page = (dc->pc >= next_page_start) ||
12037 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
12039 } while (!dc->is_jmp && !tcg_op_buf_full() &&
12040 !is_singlestepping(dc) &&
12041 !singlestep &&
12042 !end_of_page &&
12043 num_insns < max_insns);
12045 if (tb->cflags & CF_LAST_IO) {
12046 if (dc->condjmp) {
12047 /* FIXME: This can theoretically happen with self-modifying
12048 code. */
12049 cpu_abort(cs, "IO on conditional branch instruction");
12051 gen_io_end();
12054 /* At this stage dc->condjmp will only be set when the skipped
12055 instruction was a conditional branch or trap, and the PC has
12056 already been written. */
12057 gen_set_condexec(dc);
12058 if (dc->is_jmp == DISAS_BX_EXCRET) {
12059 /* Exception return branches need some special case code at the
12060 * end of the TB, which is complex enough that it has to
12061 * handle the single-step vs not and the condition-failed
12062 * insn codepath itself.
12064 gen_bx_excret_final_code(dc);
12065 } else if (unlikely(is_singlestepping(dc))) {
12066 /* Unconditional and "condition passed" instruction codepath. */
12067 switch (dc->is_jmp) {
12068 case DISAS_SWI:
12069 gen_ss_advance(dc);
12070 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12071 default_exception_el(dc));
12072 break;
12073 case DISAS_HVC:
12074 gen_ss_advance(dc);
12075 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12076 break;
12077 case DISAS_SMC:
12078 gen_ss_advance(dc);
12079 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12080 break;
12081 case DISAS_NEXT:
12082 case DISAS_UPDATE:
12083 gen_set_pc_im(dc, dc->pc);
12084 /* fall through */
12085 default:
12086 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12087 gen_singlestep_exception(dc);
12089 } else {
12090 /* While branches must always occur at the end of an IT block,
12091 there are a few other things that can cause us to terminate
12092 the TB in the middle of an IT block:
12093 - Exception generating instructions (bkpt, swi, undefined).
12094 - Page boundaries.
12095 - Hardware watchpoints.
12096 Hardware breakpoints have already been handled and skip this code.
12098 switch(dc->is_jmp) {
12099 case DISAS_NEXT:
12100 gen_goto_tb(dc, 1, dc->pc);
12101 break;
12102 case DISAS_JUMP:
12103 gen_goto_ptr();
12104 break;
12105 case DISAS_UPDATE:
12106 gen_set_pc_im(dc, dc->pc);
12107 /* fall through */
12108 default:
12109 /* indicate that the hash table must be used to find the next TB */
12110 tcg_gen_exit_tb(0);
12111 break;
12112 case DISAS_TB_JUMP:
12113 case DISAS_EXC:
12114 /* nothing more to generate */
12115 break;
12116 case DISAS_WFI:
12117 gen_helper_wfi(cpu_env);
12118 /* The helper doesn't necessarily throw an exception, but we
12119 * must go back to the main loop to check for interrupts anyway.
12121 tcg_gen_exit_tb(0);
12122 break;
12123 case DISAS_WFE:
12124 gen_helper_wfe(cpu_env);
12125 break;
12126 case DISAS_YIELD:
12127 gen_helper_yield(cpu_env);
12128 break;
12129 case DISAS_SWI:
12130 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12131 default_exception_el(dc));
12132 break;
12133 case DISAS_HVC:
12134 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12135 break;
12136 case DISAS_SMC:
12137 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12138 break;
12142 if (dc->condjmp) {
12143 /* "Condition failed" instruction codepath for the branch/trap insn */
12144 gen_set_label(dc->condlabel);
12145 gen_set_condexec(dc);
12146 if (unlikely(is_singlestepping(dc))) {
12147 gen_set_pc_im(dc, dc->pc);
12148 gen_singlestep_exception(dc);
12149 } else {
12150 gen_goto_tb(dc, 1, dc->pc);
12154 done_generating:
12155 gen_tb_end(tb, num_insns);
12157 #ifdef DEBUG_DISAS
12158 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
12159 qemu_log_in_addr_range(pc_start)) {
12160 qemu_log_lock();
12161 qemu_log("----------------\n");
12162 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12163 log_target_disas(cs, pc_start, dc->pc - pc_start,
12164 dc->thumb | (dc->sctlr_b << 1));
12165 qemu_log("\n");
12166 qemu_log_unlock();
12168 #endif
12169 tb->size = dc->pc - pc_start;
12170 tb->icount = num_insns;
12173 static const char *cpu_mode_names[16] = {
12174 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12175 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12178 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12179 int flags)
12181 ARMCPU *cpu = ARM_CPU(cs);
12182 CPUARMState *env = &cpu->env;
12183 int i;
12184 uint32_t psr;
12185 const char *ns_status;
12187 if (is_a64(env)) {
12188 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12189 return;
12192 for(i=0;i<16;i++) {
12193 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12194 if ((i % 4) == 3)
12195 cpu_fprintf(f, "\n");
12196 else
12197 cpu_fprintf(f, " ");
12199 psr = cpsr_read(env);
12201 if (arm_feature(env, ARM_FEATURE_EL3) &&
12202 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12203 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12204 } else {
12205 ns_status = "";
12208 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12209 psr,
12210 psr & (1 << 31) ? 'N' : '-',
12211 psr & (1 << 30) ? 'Z' : '-',
12212 psr & (1 << 29) ? 'C' : '-',
12213 psr & (1 << 28) ? 'V' : '-',
12214 psr & CPSR_T ? 'T' : 'A',
12215 ns_status,
12216 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12218 if (flags & CPU_DUMP_FPU) {
12219 int numvfpregs = 0;
12220 if (arm_feature(env, ARM_FEATURE_VFP)) {
12221 numvfpregs += 16;
12223 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12224 numvfpregs += 16;
12226 for (i = 0; i < numvfpregs; i++) {
12227 uint64_t v = float64_val(env->vfp.regs[i]);
12228 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12229 i * 2, (uint32_t)v,
12230 i * 2 + 1, (uint32_t)(v >> 32),
12231 i, v);
12233 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12237 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12238 target_ulong *data)
12240 if (is_a64(env)) {
12241 env->pc = data[0];
12242 env->condexec_bits = 0;
12243 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12244 } else {
12245 env->regs[15] = data[0];
12246 env->condexec_bits = data[1];
12247 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;