target/arm: optimize indirect branches
[qemu.git] / target / arm / translate.c
blob0862f9e4aabd1501cae6487cbe138692620360da
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 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4163 if (use_goto_tb(s, dest)) {
4164 tcg_gen_goto_tb(n);
4165 gen_set_pc_im(s, dest);
4166 tcg_gen_exit_tb((uintptr_t)s->tb + n);
4167 } else {
4168 gen_set_pc_im(s, dest);
4169 gen_goto_ptr();
4173 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4175 if (unlikely(is_singlestepping(s))) {
4176 /* An indirect jump so that we still trigger the debug exception. */
4177 if (s->thumb)
4178 dest |= 1;
4179 gen_bx_im(s, dest);
4180 } else {
4181 gen_goto_tb(s, 0, dest);
4182 s->is_jmp = DISAS_TB_JUMP;
4186 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4188 if (x)
4189 tcg_gen_sari_i32(t0, t0, 16);
4190 else
4191 gen_sxth(t0);
4192 if (y)
4193 tcg_gen_sari_i32(t1, t1, 16);
4194 else
4195 gen_sxth(t1);
4196 tcg_gen_mul_i32(t0, t0, t1);
4199 /* Return the mask of PSR bits set by a MSR instruction. */
4200 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4202 uint32_t mask;
4204 mask = 0;
4205 if (flags & (1 << 0))
4206 mask |= 0xff;
4207 if (flags & (1 << 1))
4208 mask |= 0xff00;
4209 if (flags & (1 << 2))
4210 mask |= 0xff0000;
4211 if (flags & (1 << 3))
4212 mask |= 0xff000000;
4214 /* Mask out undefined bits. */
4215 mask &= ~CPSR_RESERVED;
4216 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4217 mask &= ~CPSR_T;
4219 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4220 mask &= ~CPSR_Q; /* V5TE in reality*/
4222 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4223 mask &= ~(CPSR_E | CPSR_GE);
4225 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4226 mask &= ~CPSR_IT;
4228 /* Mask out execution state and reserved bits. */
4229 if (!spsr) {
4230 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4232 /* Mask out privileged bits. */
4233 if (IS_USER(s))
4234 mask &= CPSR_USER;
4235 return mask;
4238 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4239 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4241 TCGv_i32 tmp;
4242 if (spsr) {
4243 /* ??? This is also undefined in system mode. */
4244 if (IS_USER(s))
4245 return 1;
4247 tmp = load_cpu_field(spsr);
4248 tcg_gen_andi_i32(tmp, tmp, ~mask);
4249 tcg_gen_andi_i32(t0, t0, mask);
4250 tcg_gen_or_i32(tmp, tmp, t0);
4251 store_cpu_field(tmp, spsr);
4252 } else {
4253 gen_set_cpsr(t0, mask);
4255 tcg_temp_free_i32(t0);
4256 gen_lookup_tb(s);
4257 return 0;
4260 /* Returns nonzero if access to the PSR is not permitted. */
4261 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4263 TCGv_i32 tmp;
4264 tmp = tcg_temp_new_i32();
4265 tcg_gen_movi_i32(tmp, val);
4266 return gen_set_psr(s, mask, spsr, tmp);
4269 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4270 int *tgtmode, int *regno)
4272 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4273 * the target mode and register number, and identify the various
4274 * unpredictable cases.
4275 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4276 * + executed in user mode
4277 * + using R15 as the src/dest register
4278 * + accessing an unimplemented register
4279 * + accessing a register that's inaccessible at current PL/security state*
4280 * + accessing a register that you could access with a different insn
4281 * We choose to UNDEF in all these cases.
4282 * Since we don't know which of the various AArch32 modes we are in
4283 * we have to defer some checks to runtime.
4284 * Accesses to Monitor mode registers from Secure EL1 (which implies
4285 * that EL3 is AArch64) must trap to EL3.
4287 * If the access checks fail this function will emit code to take
4288 * an exception and return false. Otherwise it will return true,
4289 * and set *tgtmode and *regno appropriately.
4291 int exc_target = default_exception_el(s);
4293 /* These instructions are present only in ARMv8, or in ARMv7 with the
4294 * Virtualization Extensions.
4296 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4297 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4298 goto undef;
4301 if (IS_USER(s) || rn == 15) {
4302 goto undef;
4305 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4306 * of registers into (r, sysm).
4308 if (r) {
4309 /* SPSRs for other modes */
4310 switch (sysm) {
4311 case 0xe: /* SPSR_fiq */
4312 *tgtmode = ARM_CPU_MODE_FIQ;
4313 break;
4314 case 0x10: /* SPSR_irq */
4315 *tgtmode = ARM_CPU_MODE_IRQ;
4316 break;
4317 case 0x12: /* SPSR_svc */
4318 *tgtmode = ARM_CPU_MODE_SVC;
4319 break;
4320 case 0x14: /* SPSR_abt */
4321 *tgtmode = ARM_CPU_MODE_ABT;
4322 break;
4323 case 0x16: /* SPSR_und */
4324 *tgtmode = ARM_CPU_MODE_UND;
4325 break;
4326 case 0x1c: /* SPSR_mon */
4327 *tgtmode = ARM_CPU_MODE_MON;
4328 break;
4329 case 0x1e: /* SPSR_hyp */
4330 *tgtmode = ARM_CPU_MODE_HYP;
4331 break;
4332 default: /* unallocated */
4333 goto undef;
4335 /* We arbitrarily assign SPSR a register number of 16. */
4336 *regno = 16;
4337 } else {
4338 /* general purpose registers for other modes */
4339 switch (sysm) {
4340 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4341 *tgtmode = ARM_CPU_MODE_USR;
4342 *regno = sysm + 8;
4343 break;
4344 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4345 *tgtmode = ARM_CPU_MODE_FIQ;
4346 *regno = sysm;
4347 break;
4348 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4349 *tgtmode = ARM_CPU_MODE_IRQ;
4350 *regno = sysm & 1 ? 13 : 14;
4351 break;
4352 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4353 *tgtmode = ARM_CPU_MODE_SVC;
4354 *regno = sysm & 1 ? 13 : 14;
4355 break;
4356 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4357 *tgtmode = ARM_CPU_MODE_ABT;
4358 *regno = sysm & 1 ? 13 : 14;
4359 break;
4360 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4361 *tgtmode = ARM_CPU_MODE_UND;
4362 *regno = sysm & 1 ? 13 : 14;
4363 break;
4364 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4365 *tgtmode = ARM_CPU_MODE_MON;
4366 *regno = sysm & 1 ? 13 : 14;
4367 break;
4368 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4369 *tgtmode = ARM_CPU_MODE_HYP;
4370 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4371 *regno = sysm & 1 ? 13 : 17;
4372 break;
4373 default: /* unallocated */
4374 goto undef;
4378 /* Catch the 'accessing inaccessible register' cases we can detect
4379 * at translate time.
4381 switch (*tgtmode) {
4382 case ARM_CPU_MODE_MON:
4383 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4384 goto undef;
4386 if (s->current_el == 1) {
4387 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4388 * then accesses to Mon registers trap to EL3
4390 exc_target = 3;
4391 goto undef;
4393 break;
4394 case ARM_CPU_MODE_HYP:
4395 /* Note that we can forbid accesses from EL2 here because they
4396 * must be from Hyp mode itself
4398 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4399 goto undef;
4401 break;
4402 default:
4403 break;
4406 return true;
4408 undef:
4409 /* If we get here then some access check did not pass */
4410 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4411 return false;
4414 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4416 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4417 int tgtmode = 0, regno = 0;
4419 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4420 return;
4423 /* Sync state because msr_banked() can raise exceptions */
4424 gen_set_condexec(s);
4425 gen_set_pc_im(s, s->pc - 4);
4426 tcg_reg = load_reg(s, rn);
4427 tcg_tgtmode = tcg_const_i32(tgtmode);
4428 tcg_regno = tcg_const_i32(regno);
4429 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4430 tcg_temp_free_i32(tcg_tgtmode);
4431 tcg_temp_free_i32(tcg_regno);
4432 tcg_temp_free_i32(tcg_reg);
4433 s->is_jmp = DISAS_UPDATE;
4436 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4438 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4439 int tgtmode = 0, regno = 0;
4441 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4442 return;
4445 /* Sync state because mrs_banked() can raise exceptions */
4446 gen_set_condexec(s);
4447 gen_set_pc_im(s, s->pc - 4);
4448 tcg_reg = tcg_temp_new_i32();
4449 tcg_tgtmode = tcg_const_i32(tgtmode);
4450 tcg_regno = tcg_const_i32(regno);
4451 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4452 tcg_temp_free_i32(tcg_tgtmode);
4453 tcg_temp_free_i32(tcg_regno);
4454 store_reg(s, rn, tcg_reg);
4455 s->is_jmp = DISAS_UPDATE;
4458 /* Store value to PC as for an exception return (ie don't
4459 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4460 * will do the masking based on the new value of the Thumb bit.
4462 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4464 tcg_gen_mov_i32(cpu_R[15], pc);
4465 tcg_temp_free_i32(pc);
4468 /* Generate a v6 exception return. Marks both values as dead. */
4469 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4471 store_pc_exc_ret(s, pc);
4472 /* The cpsr_write_eret helper will mask the low bits of PC
4473 * appropriately depending on the new Thumb bit, so it must
4474 * be called after storing the new PC.
4476 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4477 tcg_temp_free_i32(cpsr);
4478 s->is_jmp = DISAS_JUMP;
4481 /* Generate an old-style exception return. Marks pc as dead. */
4482 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4484 gen_rfe(s, pc, load_cpu_field(spsr));
4488 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4489 * only call the helper when running single threaded TCG code to ensure
4490 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4491 * just skip this instruction. Currently the SEV/SEVL instructions
4492 * which are *one* of many ways to wake the CPU from WFE are not
4493 * implemented so we can't sleep like WFI does.
4495 static void gen_nop_hint(DisasContext *s, int val)
4497 switch (val) {
4498 case 1: /* yield */
4499 if (!parallel_cpus) {
4500 gen_set_pc_im(s, s->pc);
4501 s->is_jmp = DISAS_YIELD;
4503 break;
4504 case 3: /* wfi */
4505 gen_set_pc_im(s, s->pc);
4506 s->is_jmp = DISAS_WFI;
4507 break;
4508 case 2: /* wfe */
4509 if (!parallel_cpus) {
4510 gen_set_pc_im(s, s->pc);
4511 s->is_jmp = DISAS_WFE;
4513 break;
4514 case 4: /* sev */
4515 case 5: /* sevl */
4516 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4517 default: /* nop */
4518 break;
4522 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4524 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4526 switch (size) {
4527 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4528 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4529 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4530 default: abort();
4534 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4536 switch (size) {
4537 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4538 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4539 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4540 default: return;
4544 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4545 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4546 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4547 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4548 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4550 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4551 switch ((size << 1) | u) { \
4552 case 0: \
4553 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4554 break; \
4555 case 1: \
4556 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4557 break; \
4558 case 2: \
4559 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4560 break; \
4561 case 3: \
4562 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4563 break; \
4564 case 4: \
4565 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4566 break; \
4567 case 5: \
4568 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4569 break; \
4570 default: return 1; \
4571 }} while (0)
4573 #define GEN_NEON_INTEGER_OP(name) do { \
4574 switch ((size << 1) | u) { \
4575 case 0: \
4576 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4577 break; \
4578 case 1: \
4579 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4580 break; \
4581 case 2: \
4582 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4583 break; \
4584 case 3: \
4585 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4586 break; \
4587 case 4: \
4588 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4589 break; \
4590 case 5: \
4591 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4592 break; \
4593 default: return 1; \
4594 }} while (0)
4596 static TCGv_i32 neon_load_scratch(int scratch)
4598 TCGv_i32 tmp = tcg_temp_new_i32();
4599 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4600 return tmp;
4603 static void neon_store_scratch(int scratch, TCGv_i32 var)
4605 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4606 tcg_temp_free_i32(var);
4609 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4611 TCGv_i32 tmp;
4612 if (size == 1) {
4613 tmp = neon_load_reg(reg & 7, reg >> 4);
4614 if (reg & 8) {
4615 gen_neon_dup_high16(tmp);
4616 } else {
4617 gen_neon_dup_low16(tmp);
4619 } else {
4620 tmp = neon_load_reg(reg & 15, reg >> 4);
4622 return tmp;
4625 static int gen_neon_unzip(int rd, int rm, int size, int q)
4627 TCGv_i32 tmp, tmp2;
4628 if (!q && size == 2) {
4629 return 1;
4631 tmp = tcg_const_i32(rd);
4632 tmp2 = tcg_const_i32(rm);
4633 if (q) {
4634 switch (size) {
4635 case 0:
4636 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4637 break;
4638 case 1:
4639 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4640 break;
4641 case 2:
4642 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4643 break;
4644 default:
4645 abort();
4647 } else {
4648 switch (size) {
4649 case 0:
4650 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4651 break;
4652 case 1:
4653 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4654 break;
4655 default:
4656 abort();
4659 tcg_temp_free_i32(tmp);
4660 tcg_temp_free_i32(tmp2);
4661 return 0;
4664 static int gen_neon_zip(int rd, int rm, int size, int q)
4666 TCGv_i32 tmp, tmp2;
4667 if (!q && size == 2) {
4668 return 1;
4670 tmp = tcg_const_i32(rd);
4671 tmp2 = tcg_const_i32(rm);
4672 if (q) {
4673 switch (size) {
4674 case 0:
4675 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4676 break;
4677 case 1:
4678 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4679 break;
4680 case 2:
4681 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4682 break;
4683 default:
4684 abort();
4686 } else {
4687 switch (size) {
4688 case 0:
4689 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4690 break;
4691 case 1:
4692 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4693 break;
4694 default:
4695 abort();
4698 tcg_temp_free_i32(tmp);
4699 tcg_temp_free_i32(tmp2);
4700 return 0;
4703 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4705 TCGv_i32 rd, tmp;
4707 rd = tcg_temp_new_i32();
4708 tmp = tcg_temp_new_i32();
4710 tcg_gen_shli_i32(rd, t0, 8);
4711 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4712 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4713 tcg_gen_or_i32(rd, rd, tmp);
4715 tcg_gen_shri_i32(t1, t1, 8);
4716 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4717 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4718 tcg_gen_or_i32(t1, t1, tmp);
4719 tcg_gen_mov_i32(t0, rd);
4721 tcg_temp_free_i32(tmp);
4722 tcg_temp_free_i32(rd);
4725 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4727 TCGv_i32 rd, tmp;
4729 rd = tcg_temp_new_i32();
4730 tmp = tcg_temp_new_i32();
4732 tcg_gen_shli_i32(rd, t0, 16);
4733 tcg_gen_andi_i32(tmp, t1, 0xffff);
4734 tcg_gen_or_i32(rd, rd, tmp);
4735 tcg_gen_shri_i32(t1, t1, 16);
4736 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4737 tcg_gen_or_i32(t1, t1, tmp);
4738 tcg_gen_mov_i32(t0, rd);
4740 tcg_temp_free_i32(tmp);
4741 tcg_temp_free_i32(rd);
4745 static struct {
4746 int nregs;
4747 int interleave;
4748 int spacing;
4749 } neon_ls_element_type[11] = {
4750 {4, 4, 1},
4751 {4, 4, 2},
4752 {4, 1, 1},
4753 {4, 2, 1},
4754 {3, 3, 1},
4755 {3, 3, 2},
4756 {3, 1, 1},
4757 {1, 1, 1},
4758 {2, 2, 1},
4759 {2, 2, 2},
4760 {2, 1, 1}
4763 /* Translate a NEON load/store element instruction. Return nonzero if the
4764 instruction is invalid. */
4765 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4767 int rd, rn, rm;
4768 int op;
4769 int nregs;
4770 int interleave;
4771 int spacing;
4772 int stride;
4773 int size;
4774 int reg;
4775 int pass;
4776 int load;
4777 int shift;
4778 int n;
4779 TCGv_i32 addr;
4780 TCGv_i32 tmp;
4781 TCGv_i32 tmp2;
4782 TCGv_i64 tmp64;
4784 /* FIXME: this access check should not take precedence over UNDEF
4785 * for invalid encodings; we will generate incorrect syndrome information
4786 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4788 if (s->fp_excp_el) {
4789 gen_exception_insn(s, 4, EXCP_UDEF,
4790 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4791 return 0;
4794 if (!s->vfp_enabled)
4795 return 1;
4796 VFP_DREG_D(rd, insn);
4797 rn = (insn >> 16) & 0xf;
4798 rm = insn & 0xf;
4799 load = (insn & (1 << 21)) != 0;
4800 if ((insn & (1 << 23)) == 0) {
4801 /* Load store all elements. */
4802 op = (insn >> 8) & 0xf;
4803 size = (insn >> 6) & 3;
4804 if (op > 10)
4805 return 1;
4806 /* Catch UNDEF cases for bad values of align field */
4807 switch (op & 0xc) {
4808 case 4:
4809 if (((insn >> 5) & 1) == 1) {
4810 return 1;
4812 break;
4813 case 8:
4814 if (((insn >> 4) & 3) == 3) {
4815 return 1;
4817 break;
4818 default:
4819 break;
4821 nregs = neon_ls_element_type[op].nregs;
4822 interleave = neon_ls_element_type[op].interleave;
4823 spacing = neon_ls_element_type[op].spacing;
4824 if (size == 3 && (interleave | spacing) != 1)
4825 return 1;
4826 addr = tcg_temp_new_i32();
4827 load_reg_var(s, addr, rn);
4828 stride = (1 << size) * interleave;
4829 for (reg = 0; reg < nregs; reg++) {
4830 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4831 load_reg_var(s, addr, rn);
4832 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4833 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4834 load_reg_var(s, addr, rn);
4835 tcg_gen_addi_i32(addr, addr, 1 << size);
4837 if (size == 3) {
4838 tmp64 = tcg_temp_new_i64();
4839 if (load) {
4840 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4841 neon_store_reg64(tmp64, rd);
4842 } else {
4843 neon_load_reg64(tmp64, rd);
4844 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4846 tcg_temp_free_i64(tmp64);
4847 tcg_gen_addi_i32(addr, addr, stride);
4848 } else {
4849 for (pass = 0; pass < 2; pass++) {
4850 if (size == 2) {
4851 if (load) {
4852 tmp = tcg_temp_new_i32();
4853 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4854 neon_store_reg(rd, pass, tmp);
4855 } else {
4856 tmp = neon_load_reg(rd, pass);
4857 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4858 tcg_temp_free_i32(tmp);
4860 tcg_gen_addi_i32(addr, addr, stride);
4861 } else if (size == 1) {
4862 if (load) {
4863 tmp = tcg_temp_new_i32();
4864 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4865 tcg_gen_addi_i32(addr, addr, stride);
4866 tmp2 = tcg_temp_new_i32();
4867 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4868 tcg_gen_addi_i32(addr, addr, stride);
4869 tcg_gen_shli_i32(tmp2, tmp2, 16);
4870 tcg_gen_or_i32(tmp, tmp, tmp2);
4871 tcg_temp_free_i32(tmp2);
4872 neon_store_reg(rd, pass, tmp);
4873 } else {
4874 tmp = neon_load_reg(rd, pass);
4875 tmp2 = tcg_temp_new_i32();
4876 tcg_gen_shri_i32(tmp2, tmp, 16);
4877 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4878 tcg_temp_free_i32(tmp);
4879 tcg_gen_addi_i32(addr, addr, stride);
4880 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4881 tcg_temp_free_i32(tmp2);
4882 tcg_gen_addi_i32(addr, addr, stride);
4884 } else /* size == 0 */ {
4885 if (load) {
4886 TCGV_UNUSED_I32(tmp2);
4887 for (n = 0; n < 4; n++) {
4888 tmp = tcg_temp_new_i32();
4889 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4890 tcg_gen_addi_i32(addr, addr, stride);
4891 if (n == 0) {
4892 tmp2 = tmp;
4893 } else {
4894 tcg_gen_shli_i32(tmp, tmp, n * 8);
4895 tcg_gen_or_i32(tmp2, tmp2, tmp);
4896 tcg_temp_free_i32(tmp);
4899 neon_store_reg(rd, pass, tmp2);
4900 } else {
4901 tmp2 = neon_load_reg(rd, pass);
4902 for (n = 0; n < 4; n++) {
4903 tmp = tcg_temp_new_i32();
4904 if (n == 0) {
4905 tcg_gen_mov_i32(tmp, tmp2);
4906 } else {
4907 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4909 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4910 tcg_temp_free_i32(tmp);
4911 tcg_gen_addi_i32(addr, addr, stride);
4913 tcg_temp_free_i32(tmp2);
4918 rd += spacing;
4920 tcg_temp_free_i32(addr);
4921 stride = nregs * 8;
4922 } else {
4923 size = (insn >> 10) & 3;
4924 if (size == 3) {
4925 /* Load single element to all lanes. */
4926 int a = (insn >> 4) & 1;
4927 if (!load) {
4928 return 1;
4930 size = (insn >> 6) & 3;
4931 nregs = ((insn >> 8) & 3) + 1;
4933 if (size == 3) {
4934 if (nregs != 4 || a == 0) {
4935 return 1;
4937 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4938 size = 2;
4940 if (nregs == 1 && a == 1 && size == 0) {
4941 return 1;
4943 if (nregs == 3 && a == 1) {
4944 return 1;
4946 addr = tcg_temp_new_i32();
4947 load_reg_var(s, addr, rn);
4948 if (nregs == 1) {
4949 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4950 tmp = gen_load_and_replicate(s, addr, size);
4951 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4952 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4953 if (insn & (1 << 5)) {
4954 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4955 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4957 tcg_temp_free_i32(tmp);
4958 } else {
4959 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4960 stride = (insn & (1 << 5)) ? 2 : 1;
4961 for (reg = 0; reg < nregs; reg++) {
4962 tmp = gen_load_and_replicate(s, addr, size);
4963 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4964 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4965 tcg_temp_free_i32(tmp);
4966 tcg_gen_addi_i32(addr, addr, 1 << size);
4967 rd += stride;
4970 tcg_temp_free_i32(addr);
4971 stride = (1 << size) * nregs;
4972 } else {
4973 /* Single element. */
4974 int idx = (insn >> 4) & 0xf;
4975 pass = (insn >> 7) & 1;
4976 switch (size) {
4977 case 0:
4978 shift = ((insn >> 5) & 3) * 8;
4979 stride = 1;
4980 break;
4981 case 1:
4982 shift = ((insn >> 6) & 1) * 16;
4983 stride = (insn & (1 << 5)) ? 2 : 1;
4984 break;
4985 case 2:
4986 shift = 0;
4987 stride = (insn & (1 << 6)) ? 2 : 1;
4988 break;
4989 default:
4990 abort();
4992 nregs = ((insn >> 8) & 3) + 1;
4993 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4994 switch (nregs) {
4995 case 1:
4996 if (((idx & (1 << size)) != 0) ||
4997 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4998 return 1;
5000 break;
5001 case 3:
5002 if ((idx & 1) != 0) {
5003 return 1;
5005 /* fall through */
5006 case 2:
5007 if (size == 2 && (idx & 2) != 0) {
5008 return 1;
5010 break;
5011 case 4:
5012 if ((size == 2) && ((idx & 3) == 3)) {
5013 return 1;
5015 break;
5016 default:
5017 abort();
5019 if ((rd + stride * (nregs - 1)) > 31) {
5020 /* Attempts to write off the end of the register file
5021 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5022 * the neon_load_reg() would write off the end of the array.
5024 return 1;
5026 addr = tcg_temp_new_i32();
5027 load_reg_var(s, addr, rn);
5028 for (reg = 0; reg < nregs; reg++) {
5029 if (load) {
5030 tmp = tcg_temp_new_i32();
5031 switch (size) {
5032 case 0:
5033 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5034 break;
5035 case 1:
5036 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5037 break;
5038 case 2:
5039 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5040 break;
5041 default: /* Avoid compiler warnings. */
5042 abort();
5044 if (size != 2) {
5045 tmp2 = neon_load_reg(rd, pass);
5046 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5047 shift, size ? 16 : 8);
5048 tcg_temp_free_i32(tmp2);
5050 neon_store_reg(rd, pass, tmp);
5051 } else { /* Store */
5052 tmp = neon_load_reg(rd, pass);
5053 if (shift)
5054 tcg_gen_shri_i32(tmp, tmp, shift);
5055 switch (size) {
5056 case 0:
5057 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5058 break;
5059 case 1:
5060 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5061 break;
5062 case 2:
5063 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5064 break;
5066 tcg_temp_free_i32(tmp);
5068 rd += stride;
5069 tcg_gen_addi_i32(addr, addr, 1 << size);
5071 tcg_temp_free_i32(addr);
5072 stride = nregs * (1 << size);
5075 if (rm != 15) {
5076 TCGv_i32 base;
5078 base = load_reg(s, rn);
5079 if (rm == 13) {
5080 tcg_gen_addi_i32(base, base, stride);
5081 } else {
5082 TCGv_i32 index;
5083 index = load_reg(s, rm);
5084 tcg_gen_add_i32(base, base, index);
5085 tcg_temp_free_i32(index);
5087 store_reg(s, rn, base);
5089 return 0;
5092 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5093 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5095 tcg_gen_and_i32(t, t, c);
5096 tcg_gen_andc_i32(f, f, c);
5097 tcg_gen_or_i32(dest, t, f);
5100 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5102 switch (size) {
5103 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5104 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5105 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5106 default: abort();
5110 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5112 switch (size) {
5113 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5114 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5115 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5116 default: abort();
5120 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5122 switch (size) {
5123 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5124 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5125 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5126 default: abort();
5130 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5132 switch (size) {
5133 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5134 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5135 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5136 default: abort();
5140 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5141 int q, int u)
5143 if (q) {
5144 if (u) {
5145 switch (size) {
5146 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5147 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5148 default: abort();
5150 } else {
5151 switch (size) {
5152 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5153 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5154 default: abort();
5157 } else {
5158 if (u) {
5159 switch (size) {
5160 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5161 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5162 default: abort();
5164 } else {
5165 switch (size) {
5166 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5167 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5168 default: abort();
5174 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5176 if (u) {
5177 switch (size) {
5178 case 0: gen_helper_neon_widen_u8(dest, src); break;
5179 case 1: gen_helper_neon_widen_u16(dest, src); break;
5180 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5181 default: abort();
5183 } else {
5184 switch (size) {
5185 case 0: gen_helper_neon_widen_s8(dest, src); break;
5186 case 1: gen_helper_neon_widen_s16(dest, src); break;
5187 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5188 default: abort();
5191 tcg_temp_free_i32(src);
5194 static inline void gen_neon_addl(int size)
5196 switch (size) {
5197 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5198 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5199 case 2: tcg_gen_add_i64(CPU_V001); break;
5200 default: abort();
5204 static inline void gen_neon_subl(int size)
5206 switch (size) {
5207 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5208 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5209 case 2: tcg_gen_sub_i64(CPU_V001); break;
5210 default: abort();
5214 static inline void gen_neon_negl(TCGv_i64 var, int size)
5216 switch (size) {
5217 case 0: gen_helper_neon_negl_u16(var, var); break;
5218 case 1: gen_helper_neon_negl_u32(var, var); break;
5219 case 2:
5220 tcg_gen_neg_i64(var, var);
5221 break;
5222 default: abort();
5226 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5228 switch (size) {
5229 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5230 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5231 default: abort();
5235 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5236 int size, int u)
5238 TCGv_i64 tmp;
5240 switch ((size << 1) | u) {
5241 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5242 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5243 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5244 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5245 case 4:
5246 tmp = gen_muls_i64_i32(a, b);
5247 tcg_gen_mov_i64(dest, tmp);
5248 tcg_temp_free_i64(tmp);
5249 break;
5250 case 5:
5251 tmp = gen_mulu_i64_i32(a, b);
5252 tcg_gen_mov_i64(dest, tmp);
5253 tcg_temp_free_i64(tmp);
5254 break;
5255 default: abort();
5258 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5259 Don't forget to clean them now. */
5260 if (size < 2) {
5261 tcg_temp_free_i32(a);
5262 tcg_temp_free_i32(b);
5266 static void gen_neon_narrow_op(int op, int u, int size,
5267 TCGv_i32 dest, TCGv_i64 src)
5269 if (op) {
5270 if (u) {
5271 gen_neon_unarrow_sats(size, dest, src);
5272 } else {
5273 gen_neon_narrow(size, dest, src);
5275 } else {
5276 if (u) {
5277 gen_neon_narrow_satu(size, dest, src);
5278 } else {
5279 gen_neon_narrow_sats(size, dest, src);
5284 /* Symbolic constants for op fields for Neon 3-register same-length.
5285 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5286 * table A7-9.
5288 #define NEON_3R_VHADD 0
5289 #define NEON_3R_VQADD 1
5290 #define NEON_3R_VRHADD 2
5291 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5292 #define NEON_3R_VHSUB 4
5293 #define NEON_3R_VQSUB 5
5294 #define NEON_3R_VCGT 6
5295 #define NEON_3R_VCGE 7
5296 #define NEON_3R_VSHL 8
5297 #define NEON_3R_VQSHL 9
5298 #define NEON_3R_VRSHL 10
5299 #define NEON_3R_VQRSHL 11
5300 #define NEON_3R_VMAX 12
5301 #define NEON_3R_VMIN 13
5302 #define NEON_3R_VABD 14
5303 #define NEON_3R_VABA 15
5304 #define NEON_3R_VADD_VSUB 16
5305 #define NEON_3R_VTST_VCEQ 17
5306 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5307 #define NEON_3R_VMUL 19
5308 #define NEON_3R_VPMAX 20
5309 #define NEON_3R_VPMIN 21
5310 #define NEON_3R_VQDMULH_VQRDMULH 22
5311 #define NEON_3R_VPADD 23
5312 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5313 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5314 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5315 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5316 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5317 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5318 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5319 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5321 static const uint8_t neon_3r_sizes[] = {
5322 [NEON_3R_VHADD] = 0x7,
5323 [NEON_3R_VQADD] = 0xf,
5324 [NEON_3R_VRHADD] = 0x7,
5325 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5326 [NEON_3R_VHSUB] = 0x7,
5327 [NEON_3R_VQSUB] = 0xf,
5328 [NEON_3R_VCGT] = 0x7,
5329 [NEON_3R_VCGE] = 0x7,
5330 [NEON_3R_VSHL] = 0xf,
5331 [NEON_3R_VQSHL] = 0xf,
5332 [NEON_3R_VRSHL] = 0xf,
5333 [NEON_3R_VQRSHL] = 0xf,
5334 [NEON_3R_VMAX] = 0x7,
5335 [NEON_3R_VMIN] = 0x7,
5336 [NEON_3R_VABD] = 0x7,
5337 [NEON_3R_VABA] = 0x7,
5338 [NEON_3R_VADD_VSUB] = 0xf,
5339 [NEON_3R_VTST_VCEQ] = 0x7,
5340 [NEON_3R_VML] = 0x7,
5341 [NEON_3R_VMUL] = 0x7,
5342 [NEON_3R_VPMAX] = 0x7,
5343 [NEON_3R_VPMIN] = 0x7,
5344 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5345 [NEON_3R_VPADD] = 0x7,
5346 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5347 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5348 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5349 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5350 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5351 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5352 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5353 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5356 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5357 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5358 * table A7-13.
5360 #define NEON_2RM_VREV64 0
5361 #define NEON_2RM_VREV32 1
5362 #define NEON_2RM_VREV16 2
5363 #define NEON_2RM_VPADDL 4
5364 #define NEON_2RM_VPADDL_U 5
5365 #define NEON_2RM_AESE 6 /* Includes AESD */
5366 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5367 #define NEON_2RM_VCLS 8
5368 #define NEON_2RM_VCLZ 9
5369 #define NEON_2RM_VCNT 10
5370 #define NEON_2RM_VMVN 11
5371 #define NEON_2RM_VPADAL 12
5372 #define NEON_2RM_VPADAL_U 13
5373 #define NEON_2RM_VQABS 14
5374 #define NEON_2RM_VQNEG 15
5375 #define NEON_2RM_VCGT0 16
5376 #define NEON_2RM_VCGE0 17
5377 #define NEON_2RM_VCEQ0 18
5378 #define NEON_2RM_VCLE0 19
5379 #define NEON_2RM_VCLT0 20
5380 #define NEON_2RM_SHA1H 21
5381 #define NEON_2RM_VABS 22
5382 #define NEON_2RM_VNEG 23
5383 #define NEON_2RM_VCGT0_F 24
5384 #define NEON_2RM_VCGE0_F 25
5385 #define NEON_2RM_VCEQ0_F 26
5386 #define NEON_2RM_VCLE0_F 27
5387 #define NEON_2RM_VCLT0_F 28
5388 #define NEON_2RM_VABS_F 30
5389 #define NEON_2RM_VNEG_F 31
5390 #define NEON_2RM_VSWP 32
5391 #define NEON_2RM_VTRN 33
5392 #define NEON_2RM_VUZP 34
5393 #define NEON_2RM_VZIP 35
5394 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5395 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5396 #define NEON_2RM_VSHLL 38
5397 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5398 #define NEON_2RM_VRINTN 40
5399 #define NEON_2RM_VRINTX 41
5400 #define NEON_2RM_VRINTA 42
5401 #define NEON_2RM_VRINTZ 43
5402 #define NEON_2RM_VCVT_F16_F32 44
5403 #define NEON_2RM_VRINTM 45
5404 #define NEON_2RM_VCVT_F32_F16 46
5405 #define NEON_2RM_VRINTP 47
5406 #define NEON_2RM_VCVTAU 48
5407 #define NEON_2RM_VCVTAS 49
5408 #define NEON_2RM_VCVTNU 50
5409 #define NEON_2RM_VCVTNS 51
5410 #define NEON_2RM_VCVTPU 52
5411 #define NEON_2RM_VCVTPS 53
5412 #define NEON_2RM_VCVTMU 54
5413 #define NEON_2RM_VCVTMS 55
5414 #define NEON_2RM_VRECPE 56
5415 #define NEON_2RM_VRSQRTE 57
5416 #define NEON_2RM_VRECPE_F 58
5417 #define NEON_2RM_VRSQRTE_F 59
5418 #define NEON_2RM_VCVT_FS 60
5419 #define NEON_2RM_VCVT_FU 61
5420 #define NEON_2RM_VCVT_SF 62
5421 #define NEON_2RM_VCVT_UF 63
5423 static int neon_2rm_is_float_op(int op)
5425 /* Return true if this neon 2reg-misc op is float-to-float */
5426 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5427 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5428 op == NEON_2RM_VRINTM ||
5429 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5430 op >= NEON_2RM_VRECPE_F);
5433 static bool neon_2rm_is_v8_op(int op)
5435 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5436 switch (op) {
5437 case NEON_2RM_VRINTN:
5438 case NEON_2RM_VRINTA:
5439 case NEON_2RM_VRINTM:
5440 case NEON_2RM_VRINTP:
5441 case NEON_2RM_VRINTZ:
5442 case NEON_2RM_VRINTX:
5443 case NEON_2RM_VCVTAU:
5444 case NEON_2RM_VCVTAS:
5445 case NEON_2RM_VCVTNU:
5446 case NEON_2RM_VCVTNS:
5447 case NEON_2RM_VCVTPU:
5448 case NEON_2RM_VCVTPS:
5449 case NEON_2RM_VCVTMU:
5450 case NEON_2RM_VCVTMS:
5451 return true;
5452 default:
5453 return false;
5457 /* Each entry in this array has bit n set if the insn allows
5458 * size value n (otherwise it will UNDEF). Since unallocated
5459 * op values will have no bits set they always UNDEF.
5461 static const uint8_t neon_2rm_sizes[] = {
5462 [NEON_2RM_VREV64] = 0x7,
5463 [NEON_2RM_VREV32] = 0x3,
5464 [NEON_2RM_VREV16] = 0x1,
5465 [NEON_2RM_VPADDL] = 0x7,
5466 [NEON_2RM_VPADDL_U] = 0x7,
5467 [NEON_2RM_AESE] = 0x1,
5468 [NEON_2RM_AESMC] = 0x1,
5469 [NEON_2RM_VCLS] = 0x7,
5470 [NEON_2RM_VCLZ] = 0x7,
5471 [NEON_2RM_VCNT] = 0x1,
5472 [NEON_2RM_VMVN] = 0x1,
5473 [NEON_2RM_VPADAL] = 0x7,
5474 [NEON_2RM_VPADAL_U] = 0x7,
5475 [NEON_2RM_VQABS] = 0x7,
5476 [NEON_2RM_VQNEG] = 0x7,
5477 [NEON_2RM_VCGT0] = 0x7,
5478 [NEON_2RM_VCGE0] = 0x7,
5479 [NEON_2RM_VCEQ0] = 0x7,
5480 [NEON_2RM_VCLE0] = 0x7,
5481 [NEON_2RM_VCLT0] = 0x7,
5482 [NEON_2RM_SHA1H] = 0x4,
5483 [NEON_2RM_VABS] = 0x7,
5484 [NEON_2RM_VNEG] = 0x7,
5485 [NEON_2RM_VCGT0_F] = 0x4,
5486 [NEON_2RM_VCGE0_F] = 0x4,
5487 [NEON_2RM_VCEQ0_F] = 0x4,
5488 [NEON_2RM_VCLE0_F] = 0x4,
5489 [NEON_2RM_VCLT0_F] = 0x4,
5490 [NEON_2RM_VABS_F] = 0x4,
5491 [NEON_2RM_VNEG_F] = 0x4,
5492 [NEON_2RM_VSWP] = 0x1,
5493 [NEON_2RM_VTRN] = 0x7,
5494 [NEON_2RM_VUZP] = 0x7,
5495 [NEON_2RM_VZIP] = 0x7,
5496 [NEON_2RM_VMOVN] = 0x7,
5497 [NEON_2RM_VQMOVN] = 0x7,
5498 [NEON_2RM_VSHLL] = 0x7,
5499 [NEON_2RM_SHA1SU1] = 0x4,
5500 [NEON_2RM_VRINTN] = 0x4,
5501 [NEON_2RM_VRINTX] = 0x4,
5502 [NEON_2RM_VRINTA] = 0x4,
5503 [NEON_2RM_VRINTZ] = 0x4,
5504 [NEON_2RM_VCVT_F16_F32] = 0x2,
5505 [NEON_2RM_VRINTM] = 0x4,
5506 [NEON_2RM_VCVT_F32_F16] = 0x2,
5507 [NEON_2RM_VRINTP] = 0x4,
5508 [NEON_2RM_VCVTAU] = 0x4,
5509 [NEON_2RM_VCVTAS] = 0x4,
5510 [NEON_2RM_VCVTNU] = 0x4,
5511 [NEON_2RM_VCVTNS] = 0x4,
5512 [NEON_2RM_VCVTPU] = 0x4,
5513 [NEON_2RM_VCVTPS] = 0x4,
5514 [NEON_2RM_VCVTMU] = 0x4,
5515 [NEON_2RM_VCVTMS] = 0x4,
5516 [NEON_2RM_VRECPE] = 0x4,
5517 [NEON_2RM_VRSQRTE] = 0x4,
5518 [NEON_2RM_VRECPE_F] = 0x4,
5519 [NEON_2RM_VRSQRTE_F] = 0x4,
5520 [NEON_2RM_VCVT_FS] = 0x4,
5521 [NEON_2RM_VCVT_FU] = 0x4,
5522 [NEON_2RM_VCVT_SF] = 0x4,
5523 [NEON_2RM_VCVT_UF] = 0x4,
5526 /* Translate a NEON data processing instruction. Return nonzero if the
5527 instruction is invalid.
5528 We process data in a mixture of 32-bit and 64-bit chunks.
5529 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5531 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5533 int op;
5534 int q;
5535 int rd, rn, rm;
5536 int size;
5537 int shift;
5538 int pass;
5539 int count;
5540 int pairwise;
5541 int u;
5542 uint32_t imm, mask;
5543 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5544 TCGv_i64 tmp64;
5546 /* FIXME: this access check should not take precedence over UNDEF
5547 * for invalid encodings; we will generate incorrect syndrome information
5548 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5550 if (s->fp_excp_el) {
5551 gen_exception_insn(s, 4, EXCP_UDEF,
5552 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5553 return 0;
5556 if (!s->vfp_enabled)
5557 return 1;
5558 q = (insn & (1 << 6)) != 0;
5559 u = (insn >> 24) & 1;
5560 VFP_DREG_D(rd, insn);
5561 VFP_DREG_N(rn, insn);
5562 VFP_DREG_M(rm, insn);
5563 size = (insn >> 20) & 3;
5564 if ((insn & (1 << 23)) == 0) {
5565 /* Three register same length. */
5566 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5567 /* Catch invalid op and bad size combinations: UNDEF */
5568 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5569 return 1;
5571 /* All insns of this form UNDEF for either this condition or the
5572 * superset of cases "Q==1"; we catch the latter later.
5574 if (q && ((rd | rn | rm) & 1)) {
5575 return 1;
5578 * The SHA-1/SHA-256 3-register instructions require special treatment
5579 * here, as their size field is overloaded as an op type selector, and
5580 * they all consume their input in a single pass.
5582 if (op == NEON_3R_SHA) {
5583 if (!q) {
5584 return 1;
5586 if (!u) { /* SHA-1 */
5587 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5588 return 1;
5590 tmp = tcg_const_i32(rd);
5591 tmp2 = tcg_const_i32(rn);
5592 tmp3 = tcg_const_i32(rm);
5593 tmp4 = tcg_const_i32(size);
5594 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5595 tcg_temp_free_i32(tmp4);
5596 } else { /* SHA-256 */
5597 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5598 return 1;
5600 tmp = tcg_const_i32(rd);
5601 tmp2 = tcg_const_i32(rn);
5602 tmp3 = tcg_const_i32(rm);
5603 switch (size) {
5604 case 0:
5605 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5606 break;
5607 case 1:
5608 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5609 break;
5610 case 2:
5611 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5612 break;
5615 tcg_temp_free_i32(tmp);
5616 tcg_temp_free_i32(tmp2);
5617 tcg_temp_free_i32(tmp3);
5618 return 0;
5620 if (size == 3 && op != NEON_3R_LOGIC) {
5621 /* 64-bit element instructions. */
5622 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5623 neon_load_reg64(cpu_V0, rn + pass);
5624 neon_load_reg64(cpu_V1, rm + pass);
5625 switch (op) {
5626 case NEON_3R_VQADD:
5627 if (u) {
5628 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5629 cpu_V0, cpu_V1);
5630 } else {
5631 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5632 cpu_V0, cpu_V1);
5634 break;
5635 case NEON_3R_VQSUB:
5636 if (u) {
5637 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5638 cpu_V0, cpu_V1);
5639 } else {
5640 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5641 cpu_V0, cpu_V1);
5643 break;
5644 case NEON_3R_VSHL:
5645 if (u) {
5646 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5647 } else {
5648 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5650 break;
5651 case NEON_3R_VQSHL:
5652 if (u) {
5653 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5654 cpu_V1, cpu_V0);
5655 } else {
5656 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5657 cpu_V1, cpu_V0);
5659 break;
5660 case NEON_3R_VRSHL:
5661 if (u) {
5662 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5663 } else {
5664 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5666 break;
5667 case NEON_3R_VQRSHL:
5668 if (u) {
5669 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5670 cpu_V1, cpu_V0);
5671 } else {
5672 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5673 cpu_V1, cpu_V0);
5675 break;
5676 case NEON_3R_VADD_VSUB:
5677 if (u) {
5678 tcg_gen_sub_i64(CPU_V001);
5679 } else {
5680 tcg_gen_add_i64(CPU_V001);
5682 break;
5683 default:
5684 abort();
5686 neon_store_reg64(cpu_V0, rd + pass);
5688 return 0;
5690 pairwise = 0;
5691 switch (op) {
5692 case NEON_3R_VSHL:
5693 case NEON_3R_VQSHL:
5694 case NEON_3R_VRSHL:
5695 case NEON_3R_VQRSHL:
5697 int rtmp;
5698 /* Shift instruction operands are reversed. */
5699 rtmp = rn;
5700 rn = rm;
5701 rm = rtmp;
5703 break;
5704 case NEON_3R_VPADD:
5705 if (u) {
5706 return 1;
5708 /* Fall through */
5709 case NEON_3R_VPMAX:
5710 case NEON_3R_VPMIN:
5711 pairwise = 1;
5712 break;
5713 case NEON_3R_FLOAT_ARITH:
5714 pairwise = (u && size < 2); /* if VPADD (float) */
5715 break;
5716 case NEON_3R_FLOAT_MINMAX:
5717 pairwise = u; /* if VPMIN/VPMAX (float) */
5718 break;
5719 case NEON_3R_FLOAT_CMP:
5720 if (!u && size) {
5721 /* no encoding for U=0 C=1x */
5722 return 1;
5724 break;
5725 case NEON_3R_FLOAT_ACMP:
5726 if (!u) {
5727 return 1;
5729 break;
5730 case NEON_3R_FLOAT_MISC:
5731 /* VMAXNM/VMINNM in ARMv8 */
5732 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5733 return 1;
5735 break;
5736 case NEON_3R_VMUL:
5737 if (u && (size != 0)) {
5738 /* UNDEF on invalid size for polynomial subcase */
5739 return 1;
5741 break;
5742 case NEON_3R_VFM:
5743 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5744 return 1;
5746 break;
5747 default:
5748 break;
5751 if (pairwise && q) {
5752 /* All the pairwise insns UNDEF if Q is set */
5753 return 1;
5756 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5758 if (pairwise) {
5759 /* Pairwise. */
5760 if (pass < 1) {
5761 tmp = neon_load_reg(rn, 0);
5762 tmp2 = neon_load_reg(rn, 1);
5763 } else {
5764 tmp = neon_load_reg(rm, 0);
5765 tmp2 = neon_load_reg(rm, 1);
5767 } else {
5768 /* Elementwise. */
5769 tmp = neon_load_reg(rn, pass);
5770 tmp2 = neon_load_reg(rm, pass);
5772 switch (op) {
5773 case NEON_3R_VHADD:
5774 GEN_NEON_INTEGER_OP(hadd);
5775 break;
5776 case NEON_3R_VQADD:
5777 GEN_NEON_INTEGER_OP_ENV(qadd);
5778 break;
5779 case NEON_3R_VRHADD:
5780 GEN_NEON_INTEGER_OP(rhadd);
5781 break;
5782 case NEON_3R_LOGIC: /* Logic ops. */
5783 switch ((u << 2) | size) {
5784 case 0: /* VAND */
5785 tcg_gen_and_i32(tmp, tmp, tmp2);
5786 break;
5787 case 1: /* BIC */
5788 tcg_gen_andc_i32(tmp, tmp, tmp2);
5789 break;
5790 case 2: /* VORR */
5791 tcg_gen_or_i32(tmp, tmp, tmp2);
5792 break;
5793 case 3: /* VORN */
5794 tcg_gen_orc_i32(tmp, tmp, tmp2);
5795 break;
5796 case 4: /* VEOR */
5797 tcg_gen_xor_i32(tmp, tmp, tmp2);
5798 break;
5799 case 5: /* VBSL */
5800 tmp3 = neon_load_reg(rd, pass);
5801 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5802 tcg_temp_free_i32(tmp3);
5803 break;
5804 case 6: /* VBIT */
5805 tmp3 = neon_load_reg(rd, pass);
5806 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5807 tcg_temp_free_i32(tmp3);
5808 break;
5809 case 7: /* VBIF */
5810 tmp3 = neon_load_reg(rd, pass);
5811 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5812 tcg_temp_free_i32(tmp3);
5813 break;
5815 break;
5816 case NEON_3R_VHSUB:
5817 GEN_NEON_INTEGER_OP(hsub);
5818 break;
5819 case NEON_3R_VQSUB:
5820 GEN_NEON_INTEGER_OP_ENV(qsub);
5821 break;
5822 case NEON_3R_VCGT:
5823 GEN_NEON_INTEGER_OP(cgt);
5824 break;
5825 case NEON_3R_VCGE:
5826 GEN_NEON_INTEGER_OP(cge);
5827 break;
5828 case NEON_3R_VSHL:
5829 GEN_NEON_INTEGER_OP(shl);
5830 break;
5831 case NEON_3R_VQSHL:
5832 GEN_NEON_INTEGER_OP_ENV(qshl);
5833 break;
5834 case NEON_3R_VRSHL:
5835 GEN_NEON_INTEGER_OP(rshl);
5836 break;
5837 case NEON_3R_VQRSHL:
5838 GEN_NEON_INTEGER_OP_ENV(qrshl);
5839 break;
5840 case NEON_3R_VMAX:
5841 GEN_NEON_INTEGER_OP(max);
5842 break;
5843 case NEON_3R_VMIN:
5844 GEN_NEON_INTEGER_OP(min);
5845 break;
5846 case NEON_3R_VABD:
5847 GEN_NEON_INTEGER_OP(abd);
5848 break;
5849 case NEON_3R_VABA:
5850 GEN_NEON_INTEGER_OP(abd);
5851 tcg_temp_free_i32(tmp2);
5852 tmp2 = neon_load_reg(rd, pass);
5853 gen_neon_add(size, tmp, tmp2);
5854 break;
5855 case NEON_3R_VADD_VSUB:
5856 if (!u) { /* VADD */
5857 gen_neon_add(size, tmp, tmp2);
5858 } else { /* VSUB */
5859 switch (size) {
5860 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5861 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5862 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5863 default: abort();
5866 break;
5867 case NEON_3R_VTST_VCEQ:
5868 if (!u) { /* VTST */
5869 switch (size) {
5870 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5871 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5872 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5873 default: abort();
5875 } else { /* VCEQ */
5876 switch (size) {
5877 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5878 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5879 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5880 default: abort();
5883 break;
5884 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5885 switch (size) {
5886 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5887 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5888 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5889 default: abort();
5891 tcg_temp_free_i32(tmp2);
5892 tmp2 = neon_load_reg(rd, pass);
5893 if (u) { /* VMLS */
5894 gen_neon_rsb(size, tmp, tmp2);
5895 } else { /* VMLA */
5896 gen_neon_add(size, tmp, tmp2);
5898 break;
5899 case NEON_3R_VMUL:
5900 if (u) { /* polynomial */
5901 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5902 } else { /* Integer */
5903 switch (size) {
5904 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5905 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5906 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5907 default: abort();
5910 break;
5911 case NEON_3R_VPMAX:
5912 GEN_NEON_INTEGER_OP(pmax);
5913 break;
5914 case NEON_3R_VPMIN:
5915 GEN_NEON_INTEGER_OP(pmin);
5916 break;
5917 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5918 if (!u) { /* VQDMULH */
5919 switch (size) {
5920 case 1:
5921 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5922 break;
5923 case 2:
5924 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5925 break;
5926 default: abort();
5928 } else { /* VQRDMULH */
5929 switch (size) {
5930 case 1:
5931 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5932 break;
5933 case 2:
5934 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5935 break;
5936 default: abort();
5939 break;
5940 case NEON_3R_VPADD:
5941 switch (size) {
5942 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5943 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5944 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5945 default: abort();
5947 break;
5948 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5950 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5951 switch ((u << 2) | size) {
5952 case 0: /* VADD */
5953 case 4: /* VPADD */
5954 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5955 break;
5956 case 2: /* VSUB */
5957 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5958 break;
5959 case 6: /* VABD */
5960 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5961 break;
5962 default:
5963 abort();
5965 tcg_temp_free_ptr(fpstatus);
5966 break;
5968 case NEON_3R_FLOAT_MULTIPLY:
5970 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5971 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5972 if (!u) {
5973 tcg_temp_free_i32(tmp2);
5974 tmp2 = neon_load_reg(rd, pass);
5975 if (size == 0) {
5976 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5977 } else {
5978 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5981 tcg_temp_free_ptr(fpstatus);
5982 break;
5984 case NEON_3R_FLOAT_CMP:
5986 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5987 if (!u) {
5988 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5989 } else {
5990 if (size == 0) {
5991 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5992 } else {
5993 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5996 tcg_temp_free_ptr(fpstatus);
5997 break;
5999 case NEON_3R_FLOAT_ACMP:
6001 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6002 if (size == 0) {
6003 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6004 } else {
6005 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6007 tcg_temp_free_ptr(fpstatus);
6008 break;
6010 case NEON_3R_FLOAT_MINMAX:
6012 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6013 if (size == 0) {
6014 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6015 } else {
6016 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6018 tcg_temp_free_ptr(fpstatus);
6019 break;
6021 case NEON_3R_FLOAT_MISC:
6022 if (u) {
6023 /* VMAXNM/VMINNM */
6024 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6025 if (size == 0) {
6026 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6027 } else {
6028 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6030 tcg_temp_free_ptr(fpstatus);
6031 } else {
6032 if (size == 0) {
6033 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6034 } else {
6035 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6038 break;
6039 case NEON_3R_VFM:
6041 /* VFMA, VFMS: fused multiply-add */
6042 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6043 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6044 if (size) {
6045 /* VFMS */
6046 gen_helper_vfp_negs(tmp, tmp);
6048 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6049 tcg_temp_free_i32(tmp3);
6050 tcg_temp_free_ptr(fpstatus);
6051 break;
6053 default:
6054 abort();
6056 tcg_temp_free_i32(tmp2);
6058 /* Save the result. For elementwise operations we can put it
6059 straight into the destination register. For pairwise operations
6060 we have to be careful to avoid clobbering the source operands. */
6061 if (pairwise && rd == rm) {
6062 neon_store_scratch(pass, tmp);
6063 } else {
6064 neon_store_reg(rd, pass, tmp);
6067 } /* for pass */
6068 if (pairwise && rd == rm) {
6069 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6070 tmp = neon_load_scratch(pass);
6071 neon_store_reg(rd, pass, tmp);
6074 /* End of 3 register same size operations. */
6075 } else if (insn & (1 << 4)) {
6076 if ((insn & 0x00380080) != 0) {
6077 /* Two registers and shift. */
6078 op = (insn >> 8) & 0xf;
6079 if (insn & (1 << 7)) {
6080 /* 64-bit shift. */
6081 if (op > 7) {
6082 return 1;
6084 size = 3;
6085 } else {
6086 size = 2;
6087 while ((insn & (1 << (size + 19))) == 0)
6088 size--;
6090 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6091 /* To avoid excessive duplication of ops we implement shift
6092 by immediate using the variable shift operations. */
6093 if (op < 8) {
6094 /* Shift by immediate:
6095 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6096 if (q && ((rd | rm) & 1)) {
6097 return 1;
6099 if (!u && (op == 4 || op == 6)) {
6100 return 1;
6102 /* Right shifts are encoded as N - shift, where N is the
6103 element size in bits. */
6104 if (op <= 4)
6105 shift = shift - (1 << (size + 3));
6106 if (size == 3) {
6107 count = q + 1;
6108 } else {
6109 count = q ? 4: 2;
6111 switch (size) {
6112 case 0:
6113 imm = (uint8_t) shift;
6114 imm |= imm << 8;
6115 imm |= imm << 16;
6116 break;
6117 case 1:
6118 imm = (uint16_t) shift;
6119 imm |= imm << 16;
6120 break;
6121 case 2:
6122 case 3:
6123 imm = shift;
6124 break;
6125 default:
6126 abort();
6129 for (pass = 0; pass < count; pass++) {
6130 if (size == 3) {
6131 neon_load_reg64(cpu_V0, rm + pass);
6132 tcg_gen_movi_i64(cpu_V1, imm);
6133 switch (op) {
6134 case 0: /* VSHR */
6135 case 1: /* VSRA */
6136 if (u)
6137 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6138 else
6139 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6140 break;
6141 case 2: /* VRSHR */
6142 case 3: /* VRSRA */
6143 if (u)
6144 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6145 else
6146 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6147 break;
6148 case 4: /* VSRI */
6149 case 5: /* VSHL, VSLI */
6150 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6151 break;
6152 case 6: /* VQSHLU */
6153 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6154 cpu_V0, cpu_V1);
6155 break;
6156 case 7: /* VQSHL */
6157 if (u) {
6158 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6159 cpu_V0, cpu_V1);
6160 } else {
6161 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6162 cpu_V0, cpu_V1);
6164 break;
6166 if (op == 1 || op == 3) {
6167 /* Accumulate. */
6168 neon_load_reg64(cpu_V1, rd + pass);
6169 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6170 } else if (op == 4 || (op == 5 && u)) {
6171 /* Insert */
6172 neon_load_reg64(cpu_V1, rd + pass);
6173 uint64_t mask;
6174 if (shift < -63 || shift > 63) {
6175 mask = 0;
6176 } else {
6177 if (op == 4) {
6178 mask = 0xffffffffffffffffull >> -shift;
6179 } else {
6180 mask = 0xffffffffffffffffull << shift;
6183 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6184 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6186 neon_store_reg64(cpu_V0, rd + pass);
6187 } else { /* size < 3 */
6188 /* Operands in T0 and T1. */
6189 tmp = neon_load_reg(rm, pass);
6190 tmp2 = tcg_temp_new_i32();
6191 tcg_gen_movi_i32(tmp2, imm);
6192 switch (op) {
6193 case 0: /* VSHR */
6194 case 1: /* VSRA */
6195 GEN_NEON_INTEGER_OP(shl);
6196 break;
6197 case 2: /* VRSHR */
6198 case 3: /* VRSRA */
6199 GEN_NEON_INTEGER_OP(rshl);
6200 break;
6201 case 4: /* VSRI */
6202 case 5: /* VSHL, VSLI */
6203 switch (size) {
6204 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6205 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6206 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6207 default: abort();
6209 break;
6210 case 6: /* VQSHLU */
6211 switch (size) {
6212 case 0:
6213 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6214 tmp, tmp2);
6215 break;
6216 case 1:
6217 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6218 tmp, tmp2);
6219 break;
6220 case 2:
6221 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6222 tmp, tmp2);
6223 break;
6224 default:
6225 abort();
6227 break;
6228 case 7: /* VQSHL */
6229 GEN_NEON_INTEGER_OP_ENV(qshl);
6230 break;
6232 tcg_temp_free_i32(tmp2);
6234 if (op == 1 || op == 3) {
6235 /* Accumulate. */
6236 tmp2 = neon_load_reg(rd, pass);
6237 gen_neon_add(size, tmp, tmp2);
6238 tcg_temp_free_i32(tmp2);
6239 } else if (op == 4 || (op == 5 && u)) {
6240 /* Insert */
6241 switch (size) {
6242 case 0:
6243 if (op == 4)
6244 mask = 0xff >> -shift;
6245 else
6246 mask = (uint8_t)(0xff << shift);
6247 mask |= mask << 8;
6248 mask |= mask << 16;
6249 break;
6250 case 1:
6251 if (op == 4)
6252 mask = 0xffff >> -shift;
6253 else
6254 mask = (uint16_t)(0xffff << shift);
6255 mask |= mask << 16;
6256 break;
6257 case 2:
6258 if (shift < -31 || shift > 31) {
6259 mask = 0;
6260 } else {
6261 if (op == 4)
6262 mask = 0xffffffffu >> -shift;
6263 else
6264 mask = 0xffffffffu << shift;
6266 break;
6267 default:
6268 abort();
6270 tmp2 = neon_load_reg(rd, pass);
6271 tcg_gen_andi_i32(tmp, tmp, mask);
6272 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6273 tcg_gen_or_i32(tmp, tmp, tmp2);
6274 tcg_temp_free_i32(tmp2);
6276 neon_store_reg(rd, pass, tmp);
6278 } /* for pass */
6279 } else if (op < 10) {
6280 /* Shift by immediate and narrow:
6281 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6282 int input_unsigned = (op == 8) ? !u : u;
6283 if (rm & 1) {
6284 return 1;
6286 shift = shift - (1 << (size + 3));
6287 size++;
6288 if (size == 3) {
6289 tmp64 = tcg_const_i64(shift);
6290 neon_load_reg64(cpu_V0, rm);
6291 neon_load_reg64(cpu_V1, rm + 1);
6292 for (pass = 0; pass < 2; pass++) {
6293 TCGv_i64 in;
6294 if (pass == 0) {
6295 in = cpu_V0;
6296 } else {
6297 in = cpu_V1;
6299 if (q) {
6300 if (input_unsigned) {
6301 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6302 } else {
6303 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6305 } else {
6306 if (input_unsigned) {
6307 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6308 } else {
6309 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6312 tmp = tcg_temp_new_i32();
6313 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6314 neon_store_reg(rd, pass, tmp);
6315 } /* for pass */
6316 tcg_temp_free_i64(tmp64);
6317 } else {
6318 if (size == 1) {
6319 imm = (uint16_t)shift;
6320 imm |= imm << 16;
6321 } else {
6322 /* size == 2 */
6323 imm = (uint32_t)shift;
6325 tmp2 = tcg_const_i32(imm);
6326 tmp4 = neon_load_reg(rm + 1, 0);
6327 tmp5 = neon_load_reg(rm + 1, 1);
6328 for (pass = 0; pass < 2; pass++) {
6329 if (pass == 0) {
6330 tmp = neon_load_reg(rm, 0);
6331 } else {
6332 tmp = tmp4;
6334 gen_neon_shift_narrow(size, tmp, tmp2, q,
6335 input_unsigned);
6336 if (pass == 0) {
6337 tmp3 = neon_load_reg(rm, 1);
6338 } else {
6339 tmp3 = tmp5;
6341 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6342 input_unsigned);
6343 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6344 tcg_temp_free_i32(tmp);
6345 tcg_temp_free_i32(tmp3);
6346 tmp = tcg_temp_new_i32();
6347 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6348 neon_store_reg(rd, pass, tmp);
6349 } /* for pass */
6350 tcg_temp_free_i32(tmp2);
6352 } else if (op == 10) {
6353 /* VSHLL, VMOVL */
6354 if (q || (rd & 1)) {
6355 return 1;
6357 tmp = neon_load_reg(rm, 0);
6358 tmp2 = neon_load_reg(rm, 1);
6359 for (pass = 0; pass < 2; pass++) {
6360 if (pass == 1)
6361 tmp = tmp2;
6363 gen_neon_widen(cpu_V0, tmp, size, u);
6365 if (shift != 0) {
6366 /* The shift is less than the width of the source
6367 type, so we can just shift the whole register. */
6368 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6369 /* Widen the result of shift: we need to clear
6370 * the potential overflow bits resulting from
6371 * left bits of the narrow input appearing as
6372 * right bits of left the neighbour narrow
6373 * input. */
6374 if (size < 2 || !u) {
6375 uint64_t imm64;
6376 if (size == 0) {
6377 imm = (0xffu >> (8 - shift));
6378 imm |= imm << 16;
6379 } else if (size == 1) {
6380 imm = 0xffff >> (16 - shift);
6381 } else {
6382 /* size == 2 */
6383 imm = 0xffffffff >> (32 - shift);
6385 if (size < 2) {
6386 imm64 = imm | (((uint64_t)imm) << 32);
6387 } else {
6388 imm64 = imm;
6390 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6393 neon_store_reg64(cpu_V0, rd + pass);
6395 } else if (op >= 14) {
6396 /* VCVT fixed-point. */
6397 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6398 return 1;
6400 /* We have already masked out the must-be-1 top bit of imm6,
6401 * hence this 32-shift where the ARM ARM has 64-imm6.
6403 shift = 32 - shift;
6404 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6405 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6406 if (!(op & 1)) {
6407 if (u)
6408 gen_vfp_ulto(0, shift, 1);
6409 else
6410 gen_vfp_slto(0, shift, 1);
6411 } else {
6412 if (u)
6413 gen_vfp_toul(0, shift, 1);
6414 else
6415 gen_vfp_tosl(0, shift, 1);
6417 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6419 } else {
6420 return 1;
6422 } else { /* (insn & 0x00380080) == 0 */
6423 int invert;
6424 if (q && (rd & 1)) {
6425 return 1;
6428 op = (insn >> 8) & 0xf;
6429 /* One register and immediate. */
6430 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6431 invert = (insn & (1 << 5)) != 0;
6432 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6433 * We choose to not special-case this and will behave as if a
6434 * valid constant encoding of 0 had been given.
6436 switch (op) {
6437 case 0: case 1:
6438 /* no-op */
6439 break;
6440 case 2: case 3:
6441 imm <<= 8;
6442 break;
6443 case 4: case 5:
6444 imm <<= 16;
6445 break;
6446 case 6: case 7:
6447 imm <<= 24;
6448 break;
6449 case 8: case 9:
6450 imm |= imm << 16;
6451 break;
6452 case 10: case 11:
6453 imm = (imm << 8) | (imm << 24);
6454 break;
6455 case 12:
6456 imm = (imm << 8) | 0xff;
6457 break;
6458 case 13:
6459 imm = (imm << 16) | 0xffff;
6460 break;
6461 case 14:
6462 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6463 if (invert)
6464 imm = ~imm;
6465 break;
6466 case 15:
6467 if (invert) {
6468 return 1;
6470 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6471 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6472 break;
6474 if (invert)
6475 imm = ~imm;
6477 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6478 if (op & 1 && op < 12) {
6479 tmp = neon_load_reg(rd, pass);
6480 if (invert) {
6481 /* The immediate value has already been inverted, so
6482 BIC becomes AND. */
6483 tcg_gen_andi_i32(tmp, tmp, imm);
6484 } else {
6485 tcg_gen_ori_i32(tmp, tmp, imm);
6487 } else {
6488 /* VMOV, VMVN. */
6489 tmp = tcg_temp_new_i32();
6490 if (op == 14 && invert) {
6491 int n;
6492 uint32_t val;
6493 val = 0;
6494 for (n = 0; n < 4; n++) {
6495 if (imm & (1 << (n + (pass & 1) * 4)))
6496 val |= 0xff << (n * 8);
6498 tcg_gen_movi_i32(tmp, val);
6499 } else {
6500 tcg_gen_movi_i32(tmp, imm);
6503 neon_store_reg(rd, pass, tmp);
6506 } else { /* (insn & 0x00800010 == 0x00800000) */
6507 if (size != 3) {
6508 op = (insn >> 8) & 0xf;
6509 if ((insn & (1 << 6)) == 0) {
6510 /* Three registers of different lengths. */
6511 int src1_wide;
6512 int src2_wide;
6513 int prewiden;
6514 /* undefreq: bit 0 : UNDEF if size == 0
6515 * bit 1 : UNDEF if size == 1
6516 * bit 2 : UNDEF if size == 2
6517 * bit 3 : UNDEF if U == 1
6518 * Note that [2:0] set implies 'always UNDEF'
6520 int undefreq;
6521 /* prewiden, src1_wide, src2_wide, undefreq */
6522 static const int neon_3reg_wide[16][4] = {
6523 {1, 0, 0, 0}, /* VADDL */
6524 {1, 1, 0, 0}, /* VADDW */
6525 {1, 0, 0, 0}, /* VSUBL */
6526 {1, 1, 0, 0}, /* VSUBW */
6527 {0, 1, 1, 0}, /* VADDHN */
6528 {0, 0, 0, 0}, /* VABAL */
6529 {0, 1, 1, 0}, /* VSUBHN */
6530 {0, 0, 0, 0}, /* VABDL */
6531 {0, 0, 0, 0}, /* VMLAL */
6532 {0, 0, 0, 9}, /* VQDMLAL */
6533 {0, 0, 0, 0}, /* VMLSL */
6534 {0, 0, 0, 9}, /* VQDMLSL */
6535 {0, 0, 0, 0}, /* Integer VMULL */
6536 {0, 0, 0, 1}, /* VQDMULL */
6537 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6538 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6541 prewiden = neon_3reg_wide[op][0];
6542 src1_wide = neon_3reg_wide[op][1];
6543 src2_wide = neon_3reg_wide[op][2];
6544 undefreq = neon_3reg_wide[op][3];
6546 if ((undefreq & (1 << size)) ||
6547 ((undefreq & 8) && u)) {
6548 return 1;
6550 if ((src1_wide && (rn & 1)) ||
6551 (src2_wide && (rm & 1)) ||
6552 (!src2_wide && (rd & 1))) {
6553 return 1;
6556 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6557 * outside the loop below as it only performs a single pass.
6559 if (op == 14 && size == 2) {
6560 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6562 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6563 return 1;
6565 tcg_rn = tcg_temp_new_i64();
6566 tcg_rm = tcg_temp_new_i64();
6567 tcg_rd = tcg_temp_new_i64();
6568 neon_load_reg64(tcg_rn, rn);
6569 neon_load_reg64(tcg_rm, rm);
6570 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6571 neon_store_reg64(tcg_rd, rd);
6572 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6573 neon_store_reg64(tcg_rd, rd + 1);
6574 tcg_temp_free_i64(tcg_rn);
6575 tcg_temp_free_i64(tcg_rm);
6576 tcg_temp_free_i64(tcg_rd);
6577 return 0;
6580 /* Avoid overlapping operands. Wide source operands are
6581 always aligned so will never overlap with wide
6582 destinations in problematic ways. */
6583 if (rd == rm && !src2_wide) {
6584 tmp = neon_load_reg(rm, 1);
6585 neon_store_scratch(2, tmp);
6586 } else if (rd == rn && !src1_wide) {
6587 tmp = neon_load_reg(rn, 1);
6588 neon_store_scratch(2, tmp);
6590 TCGV_UNUSED_I32(tmp3);
6591 for (pass = 0; pass < 2; pass++) {
6592 if (src1_wide) {
6593 neon_load_reg64(cpu_V0, rn + pass);
6594 TCGV_UNUSED_I32(tmp);
6595 } else {
6596 if (pass == 1 && rd == rn) {
6597 tmp = neon_load_scratch(2);
6598 } else {
6599 tmp = neon_load_reg(rn, pass);
6601 if (prewiden) {
6602 gen_neon_widen(cpu_V0, tmp, size, u);
6605 if (src2_wide) {
6606 neon_load_reg64(cpu_V1, rm + pass);
6607 TCGV_UNUSED_I32(tmp2);
6608 } else {
6609 if (pass == 1 && rd == rm) {
6610 tmp2 = neon_load_scratch(2);
6611 } else {
6612 tmp2 = neon_load_reg(rm, pass);
6614 if (prewiden) {
6615 gen_neon_widen(cpu_V1, tmp2, size, u);
6618 switch (op) {
6619 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6620 gen_neon_addl(size);
6621 break;
6622 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6623 gen_neon_subl(size);
6624 break;
6625 case 5: case 7: /* VABAL, VABDL */
6626 switch ((size << 1) | u) {
6627 case 0:
6628 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6629 break;
6630 case 1:
6631 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6632 break;
6633 case 2:
6634 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6635 break;
6636 case 3:
6637 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6638 break;
6639 case 4:
6640 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6641 break;
6642 case 5:
6643 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6644 break;
6645 default: abort();
6647 tcg_temp_free_i32(tmp2);
6648 tcg_temp_free_i32(tmp);
6649 break;
6650 case 8: case 9: case 10: case 11: case 12: case 13:
6651 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6652 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6653 break;
6654 case 14: /* Polynomial VMULL */
6655 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6656 tcg_temp_free_i32(tmp2);
6657 tcg_temp_free_i32(tmp);
6658 break;
6659 default: /* 15 is RESERVED: caught earlier */
6660 abort();
6662 if (op == 13) {
6663 /* VQDMULL */
6664 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6665 neon_store_reg64(cpu_V0, rd + pass);
6666 } else if (op == 5 || (op >= 8 && op <= 11)) {
6667 /* Accumulate. */
6668 neon_load_reg64(cpu_V1, rd + pass);
6669 switch (op) {
6670 case 10: /* VMLSL */
6671 gen_neon_negl(cpu_V0, size);
6672 /* Fall through */
6673 case 5: case 8: /* VABAL, VMLAL */
6674 gen_neon_addl(size);
6675 break;
6676 case 9: case 11: /* VQDMLAL, VQDMLSL */
6677 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6678 if (op == 11) {
6679 gen_neon_negl(cpu_V0, size);
6681 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6682 break;
6683 default:
6684 abort();
6686 neon_store_reg64(cpu_V0, rd + pass);
6687 } else if (op == 4 || op == 6) {
6688 /* Narrowing operation. */
6689 tmp = tcg_temp_new_i32();
6690 if (!u) {
6691 switch (size) {
6692 case 0:
6693 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6694 break;
6695 case 1:
6696 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6697 break;
6698 case 2:
6699 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6700 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6701 break;
6702 default: abort();
6704 } else {
6705 switch (size) {
6706 case 0:
6707 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6708 break;
6709 case 1:
6710 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6711 break;
6712 case 2:
6713 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6714 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6715 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6716 break;
6717 default: abort();
6720 if (pass == 0) {
6721 tmp3 = tmp;
6722 } else {
6723 neon_store_reg(rd, 0, tmp3);
6724 neon_store_reg(rd, 1, tmp);
6726 } else {
6727 /* Write back the result. */
6728 neon_store_reg64(cpu_V0, rd + pass);
6731 } else {
6732 /* Two registers and a scalar. NB that for ops of this form
6733 * the ARM ARM labels bit 24 as Q, but it is in our variable
6734 * 'u', not 'q'.
6736 if (size == 0) {
6737 return 1;
6739 switch (op) {
6740 case 1: /* Float VMLA scalar */
6741 case 5: /* Floating point VMLS scalar */
6742 case 9: /* Floating point VMUL scalar */
6743 if (size == 1) {
6744 return 1;
6746 /* fall through */
6747 case 0: /* Integer VMLA scalar */
6748 case 4: /* Integer VMLS scalar */
6749 case 8: /* Integer VMUL scalar */
6750 case 12: /* VQDMULH scalar */
6751 case 13: /* VQRDMULH scalar */
6752 if (u && ((rd | rn) & 1)) {
6753 return 1;
6755 tmp = neon_get_scalar(size, rm);
6756 neon_store_scratch(0, tmp);
6757 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6758 tmp = neon_load_scratch(0);
6759 tmp2 = neon_load_reg(rn, pass);
6760 if (op == 12) {
6761 if (size == 1) {
6762 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6763 } else {
6764 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6766 } else if (op == 13) {
6767 if (size == 1) {
6768 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6769 } else {
6770 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6772 } else if (op & 1) {
6773 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6774 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6775 tcg_temp_free_ptr(fpstatus);
6776 } else {
6777 switch (size) {
6778 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6779 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6780 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6781 default: abort();
6784 tcg_temp_free_i32(tmp2);
6785 if (op < 8) {
6786 /* Accumulate. */
6787 tmp2 = neon_load_reg(rd, pass);
6788 switch (op) {
6789 case 0:
6790 gen_neon_add(size, tmp, tmp2);
6791 break;
6792 case 1:
6794 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6795 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6796 tcg_temp_free_ptr(fpstatus);
6797 break;
6799 case 4:
6800 gen_neon_rsb(size, tmp, tmp2);
6801 break;
6802 case 5:
6804 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6805 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6806 tcg_temp_free_ptr(fpstatus);
6807 break;
6809 default:
6810 abort();
6812 tcg_temp_free_i32(tmp2);
6814 neon_store_reg(rd, pass, tmp);
6816 break;
6817 case 3: /* VQDMLAL scalar */
6818 case 7: /* VQDMLSL scalar */
6819 case 11: /* VQDMULL scalar */
6820 if (u == 1) {
6821 return 1;
6823 /* fall through */
6824 case 2: /* VMLAL sclar */
6825 case 6: /* VMLSL scalar */
6826 case 10: /* VMULL scalar */
6827 if (rd & 1) {
6828 return 1;
6830 tmp2 = neon_get_scalar(size, rm);
6831 /* We need a copy of tmp2 because gen_neon_mull
6832 * deletes it during pass 0. */
6833 tmp4 = tcg_temp_new_i32();
6834 tcg_gen_mov_i32(tmp4, tmp2);
6835 tmp3 = neon_load_reg(rn, 1);
6837 for (pass = 0; pass < 2; pass++) {
6838 if (pass == 0) {
6839 tmp = neon_load_reg(rn, 0);
6840 } else {
6841 tmp = tmp3;
6842 tmp2 = tmp4;
6844 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6845 if (op != 11) {
6846 neon_load_reg64(cpu_V1, rd + pass);
6848 switch (op) {
6849 case 6:
6850 gen_neon_negl(cpu_V0, size);
6851 /* Fall through */
6852 case 2:
6853 gen_neon_addl(size);
6854 break;
6855 case 3: case 7:
6856 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6857 if (op == 7) {
6858 gen_neon_negl(cpu_V0, size);
6860 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6861 break;
6862 case 10:
6863 /* no-op */
6864 break;
6865 case 11:
6866 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6867 break;
6868 default:
6869 abort();
6871 neon_store_reg64(cpu_V0, rd + pass);
6875 break;
6876 default: /* 14 and 15 are RESERVED */
6877 return 1;
6880 } else { /* size == 3 */
6881 if (!u) {
6882 /* Extract. */
6883 imm = (insn >> 8) & 0xf;
6885 if (imm > 7 && !q)
6886 return 1;
6888 if (q && ((rd | rn | rm) & 1)) {
6889 return 1;
6892 if (imm == 0) {
6893 neon_load_reg64(cpu_V0, rn);
6894 if (q) {
6895 neon_load_reg64(cpu_V1, rn + 1);
6897 } else if (imm == 8) {
6898 neon_load_reg64(cpu_V0, rn + 1);
6899 if (q) {
6900 neon_load_reg64(cpu_V1, rm);
6902 } else if (q) {
6903 tmp64 = tcg_temp_new_i64();
6904 if (imm < 8) {
6905 neon_load_reg64(cpu_V0, rn);
6906 neon_load_reg64(tmp64, rn + 1);
6907 } else {
6908 neon_load_reg64(cpu_V0, rn + 1);
6909 neon_load_reg64(tmp64, rm);
6911 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6912 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6913 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6914 if (imm < 8) {
6915 neon_load_reg64(cpu_V1, rm);
6916 } else {
6917 neon_load_reg64(cpu_V1, rm + 1);
6918 imm -= 8;
6920 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6921 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6922 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6923 tcg_temp_free_i64(tmp64);
6924 } else {
6925 /* BUGFIX */
6926 neon_load_reg64(cpu_V0, rn);
6927 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6928 neon_load_reg64(cpu_V1, rm);
6929 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6930 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6932 neon_store_reg64(cpu_V0, rd);
6933 if (q) {
6934 neon_store_reg64(cpu_V1, rd + 1);
6936 } else if ((insn & (1 << 11)) == 0) {
6937 /* Two register misc. */
6938 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6939 size = (insn >> 18) & 3;
6940 /* UNDEF for unknown op values and bad op-size combinations */
6941 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6942 return 1;
6944 if (neon_2rm_is_v8_op(op) &&
6945 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6946 return 1;
6948 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6949 q && ((rm | rd) & 1)) {
6950 return 1;
6952 switch (op) {
6953 case NEON_2RM_VREV64:
6954 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6955 tmp = neon_load_reg(rm, pass * 2);
6956 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6957 switch (size) {
6958 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6959 case 1: gen_swap_half(tmp); break;
6960 case 2: /* no-op */ break;
6961 default: abort();
6963 neon_store_reg(rd, pass * 2 + 1, tmp);
6964 if (size == 2) {
6965 neon_store_reg(rd, pass * 2, tmp2);
6966 } else {
6967 switch (size) {
6968 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6969 case 1: gen_swap_half(tmp2); break;
6970 default: abort();
6972 neon_store_reg(rd, pass * 2, tmp2);
6975 break;
6976 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6977 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6978 for (pass = 0; pass < q + 1; pass++) {
6979 tmp = neon_load_reg(rm, pass * 2);
6980 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6981 tmp = neon_load_reg(rm, pass * 2 + 1);
6982 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6983 switch (size) {
6984 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6985 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6986 case 2: tcg_gen_add_i64(CPU_V001); break;
6987 default: abort();
6989 if (op >= NEON_2RM_VPADAL) {
6990 /* Accumulate. */
6991 neon_load_reg64(cpu_V1, rd + pass);
6992 gen_neon_addl(size);
6994 neon_store_reg64(cpu_V0, rd + pass);
6996 break;
6997 case NEON_2RM_VTRN:
6998 if (size == 2) {
6999 int n;
7000 for (n = 0; n < (q ? 4 : 2); n += 2) {
7001 tmp = neon_load_reg(rm, n);
7002 tmp2 = neon_load_reg(rd, n + 1);
7003 neon_store_reg(rm, n, tmp2);
7004 neon_store_reg(rd, n + 1, tmp);
7006 } else {
7007 goto elementwise;
7009 break;
7010 case NEON_2RM_VUZP:
7011 if (gen_neon_unzip(rd, rm, size, q)) {
7012 return 1;
7014 break;
7015 case NEON_2RM_VZIP:
7016 if (gen_neon_zip(rd, rm, size, q)) {
7017 return 1;
7019 break;
7020 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7021 /* also VQMOVUN; op field and mnemonics don't line up */
7022 if (rm & 1) {
7023 return 1;
7025 TCGV_UNUSED_I32(tmp2);
7026 for (pass = 0; pass < 2; pass++) {
7027 neon_load_reg64(cpu_V0, rm + pass);
7028 tmp = tcg_temp_new_i32();
7029 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7030 tmp, cpu_V0);
7031 if (pass == 0) {
7032 tmp2 = tmp;
7033 } else {
7034 neon_store_reg(rd, 0, tmp2);
7035 neon_store_reg(rd, 1, tmp);
7038 break;
7039 case NEON_2RM_VSHLL:
7040 if (q || (rd & 1)) {
7041 return 1;
7043 tmp = neon_load_reg(rm, 0);
7044 tmp2 = neon_load_reg(rm, 1);
7045 for (pass = 0; pass < 2; pass++) {
7046 if (pass == 1)
7047 tmp = tmp2;
7048 gen_neon_widen(cpu_V0, tmp, size, 1);
7049 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7050 neon_store_reg64(cpu_V0, rd + pass);
7052 break;
7053 case NEON_2RM_VCVT_F16_F32:
7054 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7055 q || (rm & 1)) {
7056 return 1;
7058 tmp = tcg_temp_new_i32();
7059 tmp2 = tcg_temp_new_i32();
7060 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7061 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7062 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7063 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7064 tcg_gen_shli_i32(tmp2, tmp2, 16);
7065 tcg_gen_or_i32(tmp2, tmp2, tmp);
7066 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7067 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7068 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7069 neon_store_reg(rd, 0, tmp2);
7070 tmp2 = tcg_temp_new_i32();
7071 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7072 tcg_gen_shli_i32(tmp2, tmp2, 16);
7073 tcg_gen_or_i32(tmp2, tmp2, tmp);
7074 neon_store_reg(rd, 1, tmp2);
7075 tcg_temp_free_i32(tmp);
7076 break;
7077 case NEON_2RM_VCVT_F32_F16:
7078 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7079 q || (rd & 1)) {
7080 return 1;
7082 tmp3 = tcg_temp_new_i32();
7083 tmp = neon_load_reg(rm, 0);
7084 tmp2 = neon_load_reg(rm, 1);
7085 tcg_gen_ext16u_i32(tmp3, tmp);
7086 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7087 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7088 tcg_gen_shri_i32(tmp3, tmp, 16);
7089 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7090 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7091 tcg_temp_free_i32(tmp);
7092 tcg_gen_ext16u_i32(tmp3, tmp2);
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, 2));
7095 tcg_gen_shri_i32(tmp3, tmp2, 16);
7096 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7097 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7098 tcg_temp_free_i32(tmp2);
7099 tcg_temp_free_i32(tmp3);
7100 break;
7101 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7102 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7103 || ((rm | rd) & 1)) {
7104 return 1;
7106 tmp = tcg_const_i32(rd);
7107 tmp2 = tcg_const_i32(rm);
7109 /* Bit 6 is the lowest opcode bit; it distinguishes between
7110 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7112 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7114 if (op == NEON_2RM_AESE) {
7115 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
7116 } else {
7117 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
7119 tcg_temp_free_i32(tmp);
7120 tcg_temp_free_i32(tmp2);
7121 tcg_temp_free_i32(tmp3);
7122 break;
7123 case NEON_2RM_SHA1H:
7124 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7125 || ((rm | rd) & 1)) {
7126 return 1;
7128 tmp = tcg_const_i32(rd);
7129 tmp2 = tcg_const_i32(rm);
7131 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
7133 tcg_temp_free_i32(tmp);
7134 tcg_temp_free_i32(tmp2);
7135 break;
7136 case NEON_2RM_SHA1SU1:
7137 if ((rm | rd) & 1) {
7138 return 1;
7140 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7141 if (q) {
7142 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7143 return 1;
7145 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7146 return 1;
7148 tmp = tcg_const_i32(rd);
7149 tmp2 = tcg_const_i32(rm);
7150 if (q) {
7151 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7152 } else {
7153 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7155 tcg_temp_free_i32(tmp);
7156 tcg_temp_free_i32(tmp2);
7157 break;
7158 default:
7159 elementwise:
7160 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7161 if (neon_2rm_is_float_op(op)) {
7162 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7163 neon_reg_offset(rm, pass));
7164 TCGV_UNUSED_I32(tmp);
7165 } else {
7166 tmp = neon_load_reg(rm, pass);
7168 switch (op) {
7169 case NEON_2RM_VREV32:
7170 switch (size) {
7171 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7172 case 1: gen_swap_half(tmp); break;
7173 default: abort();
7175 break;
7176 case NEON_2RM_VREV16:
7177 gen_rev16(tmp);
7178 break;
7179 case NEON_2RM_VCLS:
7180 switch (size) {
7181 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7182 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7183 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7184 default: abort();
7186 break;
7187 case NEON_2RM_VCLZ:
7188 switch (size) {
7189 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7190 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7191 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7192 default: abort();
7194 break;
7195 case NEON_2RM_VCNT:
7196 gen_helper_neon_cnt_u8(tmp, tmp);
7197 break;
7198 case NEON_2RM_VMVN:
7199 tcg_gen_not_i32(tmp, tmp);
7200 break;
7201 case NEON_2RM_VQABS:
7202 switch (size) {
7203 case 0:
7204 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7205 break;
7206 case 1:
7207 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7208 break;
7209 case 2:
7210 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7211 break;
7212 default: abort();
7214 break;
7215 case NEON_2RM_VQNEG:
7216 switch (size) {
7217 case 0:
7218 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7219 break;
7220 case 1:
7221 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7222 break;
7223 case 2:
7224 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7225 break;
7226 default: abort();
7228 break;
7229 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7230 tmp2 = tcg_const_i32(0);
7231 switch(size) {
7232 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7233 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7234 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7235 default: abort();
7237 tcg_temp_free_i32(tmp2);
7238 if (op == NEON_2RM_VCLE0) {
7239 tcg_gen_not_i32(tmp, tmp);
7241 break;
7242 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7243 tmp2 = tcg_const_i32(0);
7244 switch(size) {
7245 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7246 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7247 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7248 default: abort();
7250 tcg_temp_free_i32(tmp2);
7251 if (op == NEON_2RM_VCLT0) {
7252 tcg_gen_not_i32(tmp, tmp);
7254 break;
7255 case NEON_2RM_VCEQ0:
7256 tmp2 = tcg_const_i32(0);
7257 switch(size) {
7258 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7259 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7260 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7261 default: abort();
7263 tcg_temp_free_i32(tmp2);
7264 break;
7265 case NEON_2RM_VABS:
7266 switch(size) {
7267 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7268 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7269 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7270 default: abort();
7272 break;
7273 case NEON_2RM_VNEG:
7274 tmp2 = tcg_const_i32(0);
7275 gen_neon_rsb(size, tmp, tmp2);
7276 tcg_temp_free_i32(tmp2);
7277 break;
7278 case NEON_2RM_VCGT0_F:
7280 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7281 tmp2 = tcg_const_i32(0);
7282 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7283 tcg_temp_free_i32(tmp2);
7284 tcg_temp_free_ptr(fpstatus);
7285 break;
7287 case NEON_2RM_VCGE0_F:
7289 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7290 tmp2 = tcg_const_i32(0);
7291 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7292 tcg_temp_free_i32(tmp2);
7293 tcg_temp_free_ptr(fpstatus);
7294 break;
7296 case NEON_2RM_VCEQ0_F:
7298 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7299 tmp2 = tcg_const_i32(0);
7300 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7301 tcg_temp_free_i32(tmp2);
7302 tcg_temp_free_ptr(fpstatus);
7303 break;
7305 case NEON_2RM_VCLE0_F:
7307 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7308 tmp2 = tcg_const_i32(0);
7309 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7310 tcg_temp_free_i32(tmp2);
7311 tcg_temp_free_ptr(fpstatus);
7312 break;
7314 case NEON_2RM_VCLT0_F:
7316 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7317 tmp2 = tcg_const_i32(0);
7318 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7319 tcg_temp_free_i32(tmp2);
7320 tcg_temp_free_ptr(fpstatus);
7321 break;
7323 case NEON_2RM_VABS_F:
7324 gen_vfp_abs(0);
7325 break;
7326 case NEON_2RM_VNEG_F:
7327 gen_vfp_neg(0);
7328 break;
7329 case NEON_2RM_VSWP:
7330 tmp2 = neon_load_reg(rd, pass);
7331 neon_store_reg(rm, pass, tmp2);
7332 break;
7333 case NEON_2RM_VTRN:
7334 tmp2 = neon_load_reg(rd, pass);
7335 switch (size) {
7336 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7337 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7338 default: abort();
7340 neon_store_reg(rm, pass, tmp2);
7341 break;
7342 case NEON_2RM_VRINTN:
7343 case NEON_2RM_VRINTA:
7344 case NEON_2RM_VRINTM:
7345 case NEON_2RM_VRINTP:
7346 case NEON_2RM_VRINTZ:
7348 TCGv_i32 tcg_rmode;
7349 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7350 int rmode;
7352 if (op == NEON_2RM_VRINTZ) {
7353 rmode = FPROUNDING_ZERO;
7354 } else {
7355 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7358 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7359 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7360 cpu_env);
7361 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7362 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7363 cpu_env);
7364 tcg_temp_free_ptr(fpstatus);
7365 tcg_temp_free_i32(tcg_rmode);
7366 break;
7368 case NEON_2RM_VRINTX:
7370 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7371 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7372 tcg_temp_free_ptr(fpstatus);
7373 break;
7375 case NEON_2RM_VCVTAU:
7376 case NEON_2RM_VCVTAS:
7377 case NEON_2RM_VCVTNU:
7378 case NEON_2RM_VCVTNS:
7379 case NEON_2RM_VCVTPU:
7380 case NEON_2RM_VCVTPS:
7381 case NEON_2RM_VCVTMU:
7382 case NEON_2RM_VCVTMS:
7384 bool is_signed = !extract32(insn, 7, 1);
7385 TCGv_ptr fpst = get_fpstatus_ptr(1);
7386 TCGv_i32 tcg_rmode, tcg_shift;
7387 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7389 tcg_shift = tcg_const_i32(0);
7390 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7391 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7392 cpu_env);
7394 if (is_signed) {
7395 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7396 tcg_shift, fpst);
7397 } else {
7398 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7399 tcg_shift, fpst);
7402 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7403 cpu_env);
7404 tcg_temp_free_i32(tcg_rmode);
7405 tcg_temp_free_i32(tcg_shift);
7406 tcg_temp_free_ptr(fpst);
7407 break;
7409 case NEON_2RM_VRECPE:
7411 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7412 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7413 tcg_temp_free_ptr(fpstatus);
7414 break;
7416 case NEON_2RM_VRSQRTE:
7418 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7419 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7420 tcg_temp_free_ptr(fpstatus);
7421 break;
7423 case NEON_2RM_VRECPE_F:
7425 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7426 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7427 tcg_temp_free_ptr(fpstatus);
7428 break;
7430 case NEON_2RM_VRSQRTE_F:
7432 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7433 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7434 tcg_temp_free_ptr(fpstatus);
7435 break;
7437 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7438 gen_vfp_sito(0, 1);
7439 break;
7440 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7441 gen_vfp_uito(0, 1);
7442 break;
7443 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7444 gen_vfp_tosiz(0, 1);
7445 break;
7446 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7447 gen_vfp_touiz(0, 1);
7448 break;
7449 default:
7450 /* Reserved op values were caught by the
7451 * neon_2rm_sizes[] check earlier.
7453 abort();
7455 if (neon_2rm_is_float_op(op)) {
7456 tcg_gen_st_f32(cpu_F0s, cpu_env,
7457 neon_reg_offset(rd, pass));
7458 } else {
7459 neon_store_reg(rd, pass, tmp);
7462 break;
7464 } else if ((insn & (1 << 10)) == 0) {
7465 /* VTBL, VTBX. */
7466 int n = ((insn >> 8) & 3) + 1;
7467 if ((rn + n) > 32) {
7468 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7469 * helper function running off the end of the register file.
7471 return 1;
7473 n <<= 3;
7474 if (insn & (1 << 6)) {
7475 tmp = neon_load_reg(rd, 0);
7476 } else {
7477 tmp = tcg_temp_new_i32();
7478 tcg_gen_movi_i32(tmp, 0);
7480 tmp2 = neon_load_reg(rm, 0);
7481 tmp4 = tcg_const_i32(rn);
7482 tmp5 = tcg_const_i32(n);
7483 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7484 tcg_temp_free_i32(tmp);
7485 if (insn & (1 << 6)) {
7486 tmp = neon_load_reg(rd, 1);
7487 } else {
7488 tmp = tcg_temp_new_i32();
7489 tcg_gen_movi_i32(tmp, 0);
7491 tmp3 = neon_load_reg(rm, 1);
7492 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7493 tcg_temp_free_i32(tmp5);
7494 tcg_temp_free_i32(tmp4);
7495 neon_store_reg(rd, 0, tmp2);
7496 neon_store_reg(rd, 1, tmp3);
7497 tcg_temp_free_i32(tmp);
7498 } else if ((insn & 0x380) == 0) {
7499 /* VDUP */
7500 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7501 return 1;
7503 if (insn & (1 << 19)) {
7504 tmp = neon_load_reg(rm, 1);
7505 } else {
7506 tmp = neon_load_reg(rm, 0);
7508 if (insn & (1 << 16)) {
7509 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7510 } else if (insn & (1 << 17)) {
7511 if ((insn >> 18) & 1)
7512 gen_neon_dup_high16(tmp);
7513 else
7514 gen_neon_dup_low16(tmp);
7516 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7517 tmp2 = tcg_temp_new_i32();
7518 tcg_gen_mov_i32(tmp2, tmp);
7519 neon_store_reg(rd, pass, tmp2);
7521 tcg_temp_free_i32(tmp);
7522 } else {
7523 return 1;
7527 return 0;
7530 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7532 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7533 const ARMCPRegInfo *ri;
7535 cpnum = (insn >> 8) & 0xf;
7537 /* First check for coprocessor space used for XScale/iwMMXt insns */
7538 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7539 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7540 return 1;
7542 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7543 return disas_iwmmxt_insn(s, insn);
7544 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7545 return disas_dsp_insn(s, insn);
7547 return 1;
7550 /* Otherwise treat as a generic register access */
7551 is64 = (insn & (1 << 25)) == 0;
7552 if (!is64 && ((insn & (1 << 4)) == 0)) {
7553 /* cdp */
7554 return 1;
7557 crm = insn & 0xf;
7558 if (is64) {
7559 crn = 0;
7560 opc1 = (insn >> 4) & 0xf;
7561 opc2 = 0;
7562 rt2 = (insn >> 16) & 0xf;
7563 } else {
7564 crn = (insn >> 16) & 0xf;
7565 opc1 = (insn >> 21) & 7;
7566 opc2 = (insn >> 5) & 7;
7567 rt2 = 0;
7569 isread = (insn >> 20) & 1;
7570 rt = (insn >> 12) & 0xf;
7572 ri = get_arm_cp_reginfo(s->cp_regs,
7573 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7574 if (ri) {
7575 /* Check access permissions */
7576 if (!cp_access_ok(s->current_el, ri, isread)) {
7577 return 1;
7580 if (ri->accessfn ||
7581 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7582 /* Emit code to perform further access permissions checks at
7583 * runtime; this may result in an exception.
7584 * Note that on XScale all cp0..c13 registers do an access check
7585 * call in order to handle c15_cpar.
7587 TCGv_ptr tmpptr;
7588 TCGv_i32 tcg_syn, tcg_isread;
7589 uint32_t syndrome;
7591 /* Note that since we are an implementation which takes an
7592 * exception on a trapped conditional instruction only if the
7593 * instruction passes its condition code check, we can take
7594 * advantage of the clause in the ARM ARM that allows us to set
7595 * the COND field in the instruction to 0xE in all cases.
7596 * We could fish the actual condition out of the insn (ARM)
7597 * or the condexec bits (Thumb) but it isn't necessary.
7599 switch (cpnum) {
7600 case 14:
7601 if (is64) {
7602 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7603 isread, false);
7604 } else {
7605 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7606 rt, isread, false);
7608 break;
7609 case 15:
7610 if (is64) {
7611 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7612 isread, false);
7613 } else {
7614 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7615 rt, isread, false);
7617 break;
7618 default:
7619 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7620 * so this can only happen if this is an ARMv7 or earlier CPU,
7621 * in which case the syndrome information won't actually be
7622 * guest visible.
7624 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7625 syndrome = syn_uncategorized();
7626 break;
7629 gen_set_condexec(s);
7630 gen_set_pc_im(s, s->pc - 4);
7631 tmpptr = tcg_const_ptr(ri);
7632 tcg_syn = tcg_const_i32(syndrome);
7633 tcg_isread = tcg_const_i32(isread);
7634 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7635 tcg_isread);
7636 tcg_temp_free_ptr(tmpptr);
7637 tcg_temp_free_i32(tcg_syn);
7638 tcg_temp_free_i32(tcg_isread);
7641 /* Handle special cases first */
7642 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7643 case ARM_CP_NOP:
7644 return 0;
7645 case ARM_CP_WFI:
7646 if (isread) {
7647 return 1;
7649 gen_set_pc_im(s, s->pc);
7650 s->is_jmp = DISAS_WFI;
7651 return 0;
7652 default:
7653 break;
7656 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7657 gen_io_start();
7660 if (isread) {
7661 /* Read */
7662 if (is64) {
7663 TCGv_i64 tmp64;
7664 TCGv_i32 tmp;
7665 if (ri->type & ARM_CP_CONST) {
7666 tmp64 = tcg_const_i64(ri->resetvalue);
7667 } else if (ri->readfn) {
7668 TCGv_ptr tmpptr;
7669 tmp64 = tcg_temp_new_i64();
7670 tmpptr = tcg_const_ptr(ri);
7671 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7672 tcg_temp_free_ptr(tmpptr);
7673 } else {
7674 tmp64 = tcg_temp_new_i64();
7675 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7677 tmp = tcg_temp_new_i32();
7678 tcg_gen_extrl_i64_i32(tmp, tmp64);
7679 store_reg(s, rt, tmp);
7680 tcg_gen_shri_i64(tmp64, tmp64, 32);
7681 tmp = tcg_temp_new_i32();
7682 tcg_gen_extrl_i64_i32(tmp, tmp64);
7683 tcg_temp_free_i64(tmp64);
7684 store_reg(s, rt2, tmp);
7685 } else {
7686 TCGv_i32 tmp;
7687 if (ri->type & ARM_CP_CONST) {
7688 tmp = tcg_const_i32(ri->resetvalue);
7689 } else if (ri->readfn) {
7690 TCGv_ptr tmpptr;
7691 tmp = tcg_temp_new_i32();
7692 tmpptr = tcg_const_ptr(ri);
7693 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7694 tcg_temp_free_ptr(tmpptr);
7695 } else {
7696 tmp = load_cpu_offset(ri->fieldoffset);
7698 if (rt == 15) {
7699 /* Destination register of r15 for 32 bit loads sets
7700 * the condition codes from the high 4 bits of the value
7702 gen_set_nzcv(tmp);
7703 tcg_temp_free_i32(tmp);
7704 } else {
7705 store_reg(s, rt, tmp);
7708 } else {
7709 /* Write */
7710 if (ri->type & ARM_CP_CONST) {
7711 /* If not forbidden by access permissions, treat as WI */
7712 return 0;
7715 if (is64) {
7716 TCGv_i32 tmplo, tmphi;
7717 TCGv_i64 tmp64 = tcg_temp_new_i64();
7718 tmplo = load_reg(s, rt);
7719 tmphi = load_reg(s, rt2);
7720 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7721 tcg_temp_free_i32(tmplo);
7722 tcg_temp_free_i32(tmphi);
7723 if (ri->writefn) {
7724 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7725 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7726 tcg_temp_free_ptr(tmpptr);
7727 } else {
7728 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7730 tcg_temp_free_i64(tmp64);
7731 } else {
7732 if (ri->writefn) {
7733 TCGv_i32 tmp;
7734 TCGv_ptr tmpptr;
7735 tmp = load_reg(s, rt);
7736 tmpptr = tcg_const_ptr(ri);
7737 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7738 tcg_temp_free_ptr(tmpptr);
7739 tcg_temp_free_i32(tmp);
7740 } else {
7741 TCGv_i32 tmp = load_reg(s, rt);
7742 store_cpu_offset(tmp, ri->fieldoffset);
7747 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7748 /* I/O operations must end the TB here (whether read or write) */
7749 gen_io_end();
7750 gen_lookup_tb(s);
7751 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7752 /* We default to ending the TB on a coprocessor register write,
7753 * but allow this to be suppressed by the register definition
7754 * (usually only necessary to work around guest bugs).
7756 gen_lookup_tb(s);
7759 return 0;
7762 /* Unknown register; this might be a guest error or a QEMU
7763 * unimplemented feature.
7765 if (is64) {
7766 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7767 "64 bit system register cp:%d opc1: %d crm:%d "
7768 "(%s)\n",
7769 isread ? "read" : "write", cpnum, opc1, crm,
7770 s->ns ? "non-secure" : "secure");
7771 } else {
7772 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7773 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7774 "(%s)\n",
7775 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7776 s->ns ? "non-secure" : "secure");
7779 return 1;
7783 /* Store a 64-bit value to a register pair. Clobbers val. */
7784 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7786 TCGv_i32 tmp;
7787 tmp = tcg_temp_new_i32();
7788 tcg_gen_extrl_i64_i32(tmp, val);
7789 store_reg(s, rlow, tmp);
7790 tmp = tcg_temp_new_i32();
7791 tcg_gen_shri_i64(val, val, 32);
7792 tcg_gen_extrl_i64_i32(tmp, val);
7793 store_reg(s, rhigh, tmp);
7796 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7797 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7799 TCGv_i64 tmp;
7800 TCGv_i32 tmp2;
7802 /* Load value and extend to 64 bits. */
7803 tmp = tcg_temp_new_i64();
7804 tmp2 = load_reg(s, rlow);
7805 tcg_gen_extu_i32_i64(tmp, tmp2);
7806 tcg_temp_free_i32(tmp2);
7807 tcg_gen_add_i64(val, val, tmp);
7808 tcg_temp_free_i64(tmp);
7811 /* load and add a 64-bit value from a register pair. */
7812 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7814 TCGv_i64 tmp;
7815 TCGv_i32 tmpl;
7816 TCGv_i32 tmph;
7818 /* Load 64-bit value rd:rn. */
7819 tmpl = load_reg(s, rlow);
7820 tmph = load_reg(s, rhigh);
7821 tmp = tcg_temp_new_i64();
7822 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7823 tcg_temp_free_i32(tmpl);
7824 tcg_temp_free_i32(tmph);
7825 tcg_gen_add_i64(val, val, tmp);
7826 tcg_temp_free_i64(tmp);
7829 /* Set N and Z flags from hi|lo. */
7830 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7832 tcg_gen_mov_i32(cpu_NF, hi);
7833 tcg_gen_or_i32(cpu_ZF, lo, hi);
7836 /* Load/Store exclusive instructions are implemented by remembering
7837 the value/address loaded, and seeing if these are the same
7838 when the store is performed. This should be sufficient to implement
7839 the architecturally mandated semantics, and avoids having to monitor
7840 regular stores. The compare vs the remembered value is done during
7841 the cmpxchg operation, but we must compare the addresses manually. */
7842 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7843 TCGv_i32 addr, int size)
7845 TCGv_i32 tmp = tcg_temp_new_i32();
7846 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7848 s->is_ldex = true;
7850 if (size == 3) {
7851 TCGv_i32 tmp2 = tcg_temp_new_i32();
7852 TCGv_i64 t64 = tcg_temp_new_i64();
7854 gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
7855 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7856 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7857 tcg_temp_free_i64(t64);
7859 store_reg(s, rt2, tmp2);
7860 } else {
7861 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7862 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7865 store_reg(s, rt, tmp);
7866 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7869 static void gen_clrex(DisasContext *s)
7871 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7874 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7875 TCGv_i32 addr, int size)
7877 TCGv_i32 t0, t1, t2;
7878 TCGv_i64 extaddr;
7879 TCGv taddr;
7880 TCGLabel *done_label;
7881 TCGLabel *fail_label;
7882 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7884 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7885 [addr] = {Rt};
7886 {Rd} = 0;
7887 } else {
7888 {Rd} = 1;
7889 } */
7890 fail_label = gen_new_label();
7891 done_label = gen_new_label();
7892 extaddr = tcg_temp_new_i64();
7893 tcg_gen_extu_i32_i64(extaddr, addr);
7894 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7895 tcg_temp_free_i64(extaddr);
7897 taddr = gen_aa32_addr(s, addr, opc);
7898 t0 = tcg_temp_new_i32();
7899 t1 = load_reg(s, rt);
7900 if (size == 3) {
7901 TCGv_i64 o64 = tcg_temp_new_i64();
7902 TCGv_i64 n64 = tcg_temp_new_i64();
7904 t2 = load_reg(s, rt2);
7905 tcg_gen_concat_i32_i64(n64, t1, t2);
7906 tcg_temp_free_i32(t2);
7907 gen_aa32_frob64(s, n64);
7909 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7910 get_mem_index(s), opc);
7911 tcg_temp_free_i64(n64);
7913 gen_aa32_frob64(s, o64);
7914 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7915 tcg_gen_extrl_i64_i32(t0, o64);
7917 tcg_temp_free_i64(o64);
7918 } else {
7919 t2 = tcg_temp_new_i32();
7920 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7921 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7922 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7923 tcg_temp_free_i32(t2);
7925 tcg_temp_free_i32(t1);
7926 tcg_temp_free(taddr);
7927 tcg_gen_mov_i32(cpu_R[rd], t0);
7928 tcg_temp_free_i32(t0);
7929 tcg_gen_br(done_label);
7931 gen_set_label(fail_label);
7932 tcg_gen_movi_i32(cpu_R[rd], 1);
7933 gen_set_label(done_label);
7934 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7937 /* gen_srs:
7938 * @env: CPUARMState
7939 * @s: DisasContext
7940 * @mode: mode field from insn (which stack to store to)
7941 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7942 * @writeback: true if writeback bit set
7944 * Generate code for the SRS (Store Return State) insn.
7946 static void gen_srs(DisasContext *s,
7947 uint32_t mode, uint32_t amode, bool writeback)
7949 int32_t offset;
7950 TCGv_i32 addr, tmp;
7951 bool undef = false;
7953 /* SRS is:
7954 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7955 * and specified mode is monitor mode
7956 * - UNDEFINED in Hyp mode
7957 * - UNPREDICTABLE in User or System mode
7958 * - UNPREDICTABLE if the specified mode is:
7959 * -- not implemented
7960 * -- not a valid mode number
7961 * -- a mode that's at a higher exception level
7962 * -- Monitor, if we are Non-secure
7963 * For the UNPREDICTABLE cases we choose to UNDEF.
7965 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7966 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7967 return;
7970 if (s->current_el == 0 || s->current_el == 2) {
7971 undef = true;
7974 switch (mode) {
7975 case ARM_CPU_MODE_USR:
7976 case ARM_CPU_MODE_FIQ:
7977 case ARM_CPU_MODE_IRQ:
7978 case ARM_CPU_MODE_SVC:
7979 case ARM_CPU_MODE_ABT:
7980 case ARM_CPU_MODE_UND:
7981 case ARM_CPU_MODE_SYS:
7982 break;
7983 case ARM_CPU_MODE_HYP:
7984 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7985 undef = true;
7987 break;
7988 case ARM_CPU_MODE_MON:
7989 /* No need to check specifically for "are we non-secure" because
7990 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7991 * so if this isn't EL3 then we must be non-secure.
7993 if (s->current_el != 3) {
7994 undef = true;
7996 break;
7997 default:
7998 undef = true;
8001 if (undef) {
8002 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8003 default_exception_el(s));
8004 return;
8007 addr = tcg_temp_new_i32();
8008 tmp = tcg_const_i32(mode);
8009 /* get_r13_banked() will raise an exception if called from System mode */
8010 gen_set_condexec(s);
8011 gen_set_pc_im(s, s->pc - 4);
8012 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8013 tcg_temp_free_i32(tmp);
8014 switch (amode) {
8015 case 0: /* DA */
8016 offset = -4;
8017 break;
8018 case 1: /* IA */
8019 offset = 0;
8020 break;
8021 case 2: /* DB */
8022 offset = -8;
8023 break;
8024 case 3: /* IB */
8025 offset = 4;
8026 break;
8027 default:
8028 abort();
8030 tcg_gen_addi_i32(addr, addr, offset);
8031 tmp = load_reg(s, 14);
8032 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8033 tcg_temp_free_i32(tmp);
8034 tmp = load_cpu_field(spsr);
8035 tcg_gen_addi_i32(addr, addr, 4);
8036 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8037 tcg_temp_free_i32(tmp);
8038 if (writeback) {
8039 switch (amode) {
8040 case 0:
8041 offset = -8;
8042 break;
8043 case 1:
8044 offset = 4;
8045 break;
8046 case 2:
8047 offset = -4;
8048 break;
8049 case 3:
8050 offset = 0;
8051 break;
8052 default:
8053 abort();
8055 tcg_gen_addi_i32(addr, addr, offset);
8056 tmp = tcg_const_i32(mode);
8057 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8058 tcg_temp_free_i32(tmp);
8060 tcg_temp_free_i32(addr);
8061 s->is_jmp = DISAS_UPDATE;
8064 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8066 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8067 TCGv_i32 tmp;
8068 TCGv_i32 tmp2;
8069 TCGv_i32 tmp3;
8070 TCGv_i32 addr;
8071 TCGv_i64 tmp64;
8073 /* M variants do not implement ARM mode; this must raise the INVSTATE
8074 * UsageFault exception.
8076 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8077 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8078 default_exception_el(s));
8079 return;
8081 cond = insn >> 28;
8082 if (cond == 0xf){
8083 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8084 * choose to UNDEF. In ARMv5 and above the space is used
8085 * for miscellaneous unconditional instructions.
8087 ARCH(5);
8089 /* Unconditional instructions. */
8090 if (((insn >> 25) & 7) == 1) {
8091 /* NEON Data processing. */
8092 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8093 goto illegal_op;
8096 if (disas_neon_data_insn(s, insn)) {
8097 goto illegal_op;
8099 return;
8101 if ((insn & 0x0f100000) == 0x04000000) {
8102 /* NEON load/store. */
8103 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8104 goto illegal_op;
8107 if (disas_neon_ls_insn(s, insn)) {
8108 goto illegal_op;
8110 return;
8112 if ((insn & 0x0f000e10) == 0x0e000a00) {
8113 /* VFP. */
8114 if (disas_vfp_insn(s, insn)) {
8115 goto illegal_op;
8117 return;
8119 if (((insn & 0x0f30f000) == 0x0510f000) ||
8120 ((insn & 0x0f30f010) == 0x0710f000)) {
8121 if ((insn & (1 << 22)) == 0) {
8122 /* PLDW; v7MP */
8123 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8124 goto illegal_op;
8127 /* Otherwise PLD; v5TE+ */
8128 ARCH(5TE);
8129 return;
8131 if (((insn & 0x0f70f000) == 0x0450f000) ||
8132 ((insn & 0x0f70f010) == 0x0650f000)) {
8133 ARCH(7);
8134 return; /* PLI; V7 */
8136 if (((insn & 0x0f700000) == 0x04100000) ||
8137 ((insn & 0x0f700010) == 0x06100000)) {
8138 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8139 goto illegal_op;
8141 return; /* v7MP: Unallocated memory hint: must NOP */
8144 if ((insn & 0x0ffffdff) == 0x01010000) {
8145 ARCH(6);
8146 /* setend */
8147 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8148 gen_helper_setend(cpu_env);
8149 s->is_jmp = DISAS_UPDATE;
8151 return;
8152 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8153 switch ((insn >> 4) & 0xf) {
8154 case 1: /* clrex */
8155 ARCH(6K);
8156 gen_clrex(s);
8157 return;
8158 case 4: /* dsb */
8159 case 5: /* dmb */
8160 ARCH(7);
8161 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8162 return;
8163 case 6: /* isb */
8164 /* We need to break the TB after this insn to execute
8165 * self-modifying code correctly and also to take
8166 * any pending interrupts immediately.
8168 gen_lookup_tb(s);
8169 return;
8170 default:
8171 goto illegal_op;
8173 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8174 /* srs */
8175 ARCH(6);
8176 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8177 return;
8178 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8179 /* rfe */
8180 int32_t offset;
8181 if (IS_USER(s))
8182 goto illegal_op;
8183 ARCH(6);
8184 rn = (insn >> 16) & 0xf;
8185 addr = load_reg(s, rn);
8186 i = (insn >> 23) & 3;
8187 switch (i) {
8188 case 0: offset = -4; break; /* DA */
8189 case 1: offset = 0; break; /* IA */
8190 case 2: offset = -8; break; /* DB */
8191 case 3: offset = 4; break; /* IB */
8192 default: abort();
8194 if (offset)
8195 tcg_gen_addi_i32(addr, addr, offset);
8196 /* Load PC into tmp and CPSR into tmp2. */
8197 tmp = tcg_temp_new_i32();
8198 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8199 tcg_gen_addi_i32(addr, addr, 4);
8200 tmp2 = tcg_temp_new_i32();
8201 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8202 if (insn & (1 << 21)) {
8203 /* Base writeback. */
8204 switch (i) {
8205 case 0: offset = -8; break;
8206 case 1: offset = 4; break;
8207 case 2: offset = -4; break;
8208 case 3: offset = 0; break;
8209 default: abort();
8211 if (offset)
8212 tcg_gen_addi_i32(addr, addr, offset);
8213 store_reg(s, rn, addr);
8214 } else {
8215 tcg_temp_free_i32(addr);
8217 gen_rfe(s, tmp, tmp2);
8218 return;
8219 } else if ((insn & 0x0e000000) == 0x0a000000) {
8220 /* branch link and change to thumb (blx <offset>) */
8221 int32_t offset;
8223 val = (uint32_t)s->pc;
8224 tmp = tcg_temp_new_i32();
8225 tcg_gen_movi_i32(tmp, val);
8226 store_reg(s, 14, tmp);
8227 /* Sign-extend the 24-bit offset */
8228 offset = (((int32_t)insn) << 8) >> 8;
8229 /* offset * 4 + bit24 * 2 + (thumb bit) */
8230 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8231 /* pipeline offset */
8232 val += 4;
8233 /* protected by ARCH(5); above, near the start of uncond block */
8234 gen_bx_im(s, val);
8235 return;
8236 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8237 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8238 /* iWMMXt register transfer. */
8239 if (extract32(s->c15_cpar, 1, 1)) {
8240 if (!disas_iwmmxt_insn(s, insn)) {
8241 return;
8245 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8246 /* Coprocessor double register transfer. */
8247 ARCH(5TE);
8248 } else if ((insn & 0x0f000010) == 0x0e000010) {
8249 /* Additional coprocessor register transfer. */
8250 } else if ((insn & 0x0ff10020) == 0x01000000) {
8251 uint32_t mask;
8252 uint32_t val;
8253 /* cps (privileged) */
8254 if (IS_USER(s))
8255 return;
8256 mask = val = 0;
8257 if (insn & (1 << 19)) {
8258 if (insn & (1 << 8))
8259 mask |= CPSR_A;
8260 if (insn & (1 << 7))
8261 mask |= CPSR_I;
8262 if (insn & (1 << 6))
8263 mask |= CPSR_F;
8264 if (insn & (1 << 18))
8265 val |= mask;
8267 if (insn & (1 << 17)) {
8268 mask |= CPSR_M;
8269 val |= (insn & 0x1f);
8271 if (mask) {
8272 gen_set_psr_im(s, mask, 0, val);
8274 return;
8276 goto illegal_op;
8278 if (cond != 0xe) {
8279 /* if not always execute, we generate a conditional jump to
8280 next instruction */
8281 s->condlabel = gen_new_label();
8282 arm_gen_test_cc(cond ^ 1, s->condlabel);
8283 s->condjmp = 1;
8285 if ((insn & 0x0f900000) == 0x03000000) {
8286 if ((insn & (1 << 21)) == 0) {
8287 ARCH(6T2);
8288 rd = (insn >> 12) & 0xf;
8289 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8290 if ((insn & (1 << 22)) == 0) {
8291 /* MOVW */
8292 tmp = tcg_temp_new_i32();
8293 tcg_gen_movi_i32(tmp, val);
8294 } else {
8295 /* MOVT */
8296 tmp = load_reg(s, rd);
8297 tcg_gen_ext16u_i32(tmp, tmp);
8298 tcg_gen_ori_i32(tmp, tmp, val << 16);
8300 store_reg(s, rd, tmp);
8301 } else {
8302 if (((insn >> 12) & 0xf) != 0xf)
8303 goto illegal_op;
8304 if (((insn >> 16) & 0xf) == 0) {
8305 gen_nop_hint(s, insn & 0xff);
8306 } else {
8307 /* CPSR = immediate */
8308 val = insn & 0xff;
8309 shift = ((insn >> 8) & 0xf) * 2;
8310 if (shift)
8311 val = (val >> shift) | (val << (32 - shift));
8312 i = ((insn & (1 << 22)) != 0);
8313 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8314 i, val)) {
8315 goto illegal_op;
8319 } else if ((insn & 0x0f900000) == 0x01000000
8320 && (insn & 0x00000090) != 0x00000090) {
8321 /* miscellaneous instructions */
8322 op1 = (insn >> 21) & 3;
8323 sh = (insn >> 4) & 0xf;
8324 rm = insn & 0xf;
8325 switch (sh) {
8326 case 0x0: /* MSR, MRS */
8327 if (insn & (1 << 9)) {
8328 /* MSR (banked) and MRS (banked) */
8329 int sysm = extract32(insn, 16, 4) |
8330 (extract32(insn, 8, 1) << 4);
8331 int r = extract32(insn, 22, 1);
8333 if (op1 & 1) {
8334 /* MSR (banked) */
8335 gen_msr_banked(s, r, sysm, rm);
8336 } else {
8337 /* MRS (banked) */
8338 int rd = extract32(insn, 12, 4);
8340 gen_mrs_banked(s, r, sysm, rd);
8342 break;
8345 /* MSR, MRS (for PSRs) */
8346 if (op1 & 1) {
8347 /* PSR = reg */
8348 tmp = load_reg(s, rm);
8349 i = ((op1 & 2) != 0);
8350 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8351 goto illegal_op;
8352 } else {
8353 /* reg = PSR */
8354 rd = (insn >> 12) & 0xf;
8355 if (op1 & 2) {
8356 if (IS_USER(s))
8357 goto illegal_op;
8358 tmp = load_cpu_field(spsr);
8359 } else {
8360 tmp = tcg_temp_new_i32();
8361 gen_helper_cpsr_read(tmp, cpu_env);
8363 store_reg(s, rd, tmp);
8365 break;
8366 case 0x1:
8367 if (op1 == 1) {
8368 /* branch/exchange thumb (bx). */
8369 ARCH(4T);
8370 tmp = load_reg(s, rm);
8371 gen_bx(s, tmp);
8372 } else if (op1 == 3) {
8373 /* clz */
8374 ARCH(5);
8375 rd = (insn >> 12) & 0xf;
8376 tmp = load_reg(s, rm);
8377 tcg_gen_clzi_i32(tmp, tmp, 32);
8378 store_reg(s, rd, tmp);
8379 } else {
8380 goto illegal_op;
8382 break;
8383 case 0x2:
8384 if (op1 == 1) {
8385 ARCH(5J); /* bxj */
8386 /* Trivial implementation equivalent to bx. */
8387 tmp = load_reg(s, rm);
8388 gen_bx(s, tmp);
8389 } else {
8390 goto illegal_op;
8392 break;
8393 case 0x3:
8394 if (op1 != 1)
8395 goto illegal_op;
8397 ARCH(5);
8398 /* branch link/exchange thumb (blx) */
8399 tmp = load_reg(s, rm);
8400 tmp2 = tcg_temp_new_i32();
8401 tcg_gen_movi_i32(tmp2, s->pc);
8402 store_reg(s, 14, tmp2);
8403 gen_bx(s, tmp);
8404 break;
8405 case 0x4:
8407 /* crc32/crc32c */
8408 uint32_t c = extract32(insn, 8, 4);
8410 /* Check this CPU supports ARMv8 CRC instructions.
8411 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8412 * Bits 8, 10 and 11 should be zero.
8414 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8415 (c & 0xd) != 0) {
8416 goto illegal_op;
8419 rn = extract32(insn, 16, 4);
8420 rd = extract32(insn, 12, 4);
8422 tmp = load_reg(s, rn);
8423 tmp2 = load_reg(s, rm);
8424 if (op1 == 0) {
8425 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8426 } else if (op1 == 1) {
8427 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8429 tmp3 = tcg_const_i32(1 << op1);
8430 if (c & 0x2) {
8431 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8432 } else {
8433 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8435 tcg_temp_free_i32(tmp2);
8436 tcg_temp_free_i32(tmp3);
8437 store_reg(s, rd, tmp);
8438 break;
8440 case 0x5: /* saturating add/subtract */
8441 ARCH(5TE);
8442 rd = (insn >> 12) & 0xf;
8443 rn = (insn >> 16) & 0xf;
8444 tmp = load_reg(s, rm);
8445 tmp2 = load_reg(s, rn);
8446 if (op1 & 2)
8447 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8448 if (op1 & 1)
8449 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8450 else
8451 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8452 tcg_temp_free_i32(tmp2);
8453 store_reg(s, rd, tmp);
8454 break;
8455 case 7:
8457 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8458 switch (op1) {
8459 case 0:
8460 /* HLT */
8461 gen_hlt(s, imm16);
8462 break;
8463 case 1:
8464 /* bkpt */
8465 ARCH(5);
8466 gen_exception_insn(s, 4, EXCP_BKPT,
8467 syn_aa32_bkpt(imm16, false),
8468 default_exception_el(s));
8469 break;
8470 case 2:
8471 /* Hypervisor call (v7) */
8472 ARCH(7);
8473 if (IS_USER(s)) {
8474 goto illegal_op;
8476 gen_hvc(s, imm16);
8477 break;
8478 case 3:
8479 /* Secure monitor call (v6+) */
8480 ARCH(6K);
8481 if (IS_USER(s)) {
8482 goto illegal_op;
8484 gen_smc(s);
8485 break;
8486 default:
8487 g_assert_not_reached();
8489 break;
8491 case 0x8: /* signed multiply */
8492 case 0xa:
8493 case 0xc:
8494 case 0xe:
8495 ARCH(5TE);
8496 rs = (insn >> 8) & 0xf;
8497 rn = (insn >> 12) & 0xf;
8498 rd = (insn >> 16) & 0xf;
8499 if (op1 == 1) {
8500 /* (32 * 16) >> 16 */
8501 tmp = load_reg(s, rm);
8502 tmp2 = load_reg(s, rs);
8503 if (sh & 4)
8504 tcg_gen_sari_i32(tmp2, tmp2, 16);
8505 else
8506 gen_sxth(tmp2);
8507 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8508 tcg_gen_shri_i64(tmp64, tmp64, 16);
8509 tmp = tcg_temp_new_i32();
8510 tcg_gen_extrl_i64_i32(tmp, tmp64);
8511 tcg_temp_free_i64(tmp64);
8512 if ((sh & 2) == 0) {
8513 tmp2 = load_reg(s, rn);
8514 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8515 tcg_temp_free_i32(tmp2);
8517 store_reg(s, rd, tmp);
8518 } else {
8519 /* 16 * 16 */
8520 tmp = load_reg(s, rm);
8521 tmp2 = load_reg(s, rs);
8522 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8523 tcg_temp_free_i32(tmp2);
8524 if (op1 == 2) {
8525 tmp64 = tcg_temp_new_i64();
8526 tcg_gen_ext_i32_i64(tmp64, tmp);
8527 tcg_temp_free_i32(tmp);
8528 gen_addq(s, tmp64, rn, rd);
8529 gen_storeq_reg(s, rn, rd, tmp64);
8530 tcg_temp_free_i64(tmp64);
8531 } else {
8532 if (op1 == 0) {
8533 tmp2 = load_reg(s, rn);
8534 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8535 tcg_temp_free_i32(tmp2);
8537 store_reg(s, rd, tmp);
8540 break;
8541 default:
8542 goto illegal_op;
8544 } else if (((insn & 0x0e000000) == 0 &&
8545 (insn & 0x00000090) != 0x90) ||
8546 ((insn & 0x0e000000) == (1 << 25))) {
8547 int set_cc, logic_cc, shiftop;
8549 op1 = (insn >> 21) & 0xf;
8550 set_cc = (insn >> 20) & 1;
8551 logic_cc = table_logic_cc[op1] & set_cc;
8553 /* data processing instruction */
8554 if (insn & (1 << 25)) {
8555 /* immediate operand */
8556 val = insn & 0xff;
8557 shift = ((insn >> 8) & 0xf) * 2;
8558 if (shift) {
8559 val = (val >> shift) | (val << (32 - shift));
8561 tmp2 = tcg_temp_new_i32();
8562 tcg_gen_movi_i32(tmp2, val);
8563 if (logic_cc && shift) {
8564 gen_set_CF_bit31(tmp2);
8566 } else {
8567 /* register */
8568 rm = (insn) & 0xf;
8569 tmp2 = load_reg(s, rm);
8570 shiftop = (insn >> 5) & 3;
8571 if (!(insn & (1 << 4))) {
8572 shift = (insn >> 7) & 0x1f;
8573 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8574 } else {
8575 rs = (insn >> 8) & 0xf;
8576 tmp = load_reg(s, rs);
8577 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8580 if (op1 != 0x0f && op1 != 0x0d) {
8581 rn = (insn >> 16) & 0xf;
8582 tmp = load_reg(s, rn);
8583 } else {
8584 TCGV_UNUSED_I32(tmp);
8586 rd = (insn >> 12) & 0xf;
8587 switch(op1) {
8588 case 0x00:
8589 tcg_gen_and_i32(tmp, tmp, tmp2);
8590 if (logic_cc) {
8591 gen_logic_CC(tmp);
8593 store_reg_bx(s, rd, tmp);
8594 break;
8595 case 0x01:
8596 tcg_gen_xor_i32(tmp, tmp, tmp2);
8597 if (logic_cc) {
8598 gen_logic_CC(tmp);
8600 store_reg_bx(s, rd, tmp);
8601 break;
8602 case 0x02:
8603 if (set_cc && rd == 15) {
8604 /* SUBS r15, ... is used for exception return. */
8605 if (IS_USER(s)) {
8606 goto illegal_op;
8608 gen_sub_CC(tmp, tmp, tmp2);
8609 gen_exception_return(s, tmp);
8610 } else {
8611 if (set_cc) {
8612 gen_sub_CC(tmp, tmp, tmp2);
8613 } else {
8614 tcg_gen_sub_i32(tmp, tmp, tmp2);
8616 store_reg_bx(s, rd, tmp);
8618 break;
8619 case 0x03:
8620 if (set_cc) {
8621 gen_sub_CC(tmp, tmp2, tmp);
8622 } else {
8623 tcg_gen_sub_i32(tmp, tmp2, tmp);
8625 store_reg_bx(s, rd, tmp);
8626 break;
8627 case 0x04:
8628 if (set_cc) {
8629 gen_add_CC(tmp, tmp, tmp2);
8630 } else {
8631 tcg_gen_add_i32(tmp, tmp, tmp2);
8633 store_reg_bx(s, rd, tmp);
8634 break;
8635 case 0x05:
8636 if (set_cc) {
8637 gen_adc_CC(tmp, tmp, tmp2);
8638 } else {
8639 gen_add_carry(tmp, tmp, tmp2);
8641 store_reg_bx(s, rd, tmp);
8642 break;
8643 case 0x06:
8644 if (set_cc) {
8645 gen_sbc_CC(tmp, tmp, tmp2);
8646 } else {
8647 gen_sub_carry(tmp, tmp, tmp2);
8649 store_reg_bx(s, rd, tmp);
8650 break;
8651 case 0x07:
8652 if (set_cc) {
8653 gen_sbc_CC(tmp, tmp2, tmp);
8654 } else {
8655 gen_sub_carry(tmp, tmp2, tmp);
8657 store_reg_bx(s, rd, tmp);
8658 break;
8659 case 0x08:
8660 if (set_cc) {
8661 tcg_gen_and_i32(tmp, tmp, tmp2);
8662 gen_logic_CC(tmp);
8664 tcg_temp_free_i32(tmp);
8665 break;
8666 case 0x09:
8667 if (set_cc) {
8668 tcg_gen_xor_i32(tmp, tmp, tmp2);
8669 gen_logic_CC(tmp);
8671 tcg_temp_free_i32(tmp);
8672 break;
8673 case 0x0a:
8674 if (set_cc) {
8675 gen_sub_CC(tmp, tmp, tmp2);
8677 tcg_temp_free_i32(tmp);
8678 break;
8679 case 0x0b:
8680 if (set_cc) {
8681 gen_add_CC(tmp, tmp, tmp2);
8683 tcg_temp_free_i32(tmp);
8684 break;
8685 case 0x0c:
8686 tcg_gen_or_i32(tmp, tmp, tmp2);
8687 if (logic_cc) {
8688 gen_logic_CC(tmp);
8690 store_reg_bx(s, rd, tmp);
8691 break;
8692 case 0x0d:
8693 if (logic_cc && rd == 15) {
8694 /* MOVS r15, ... is used for exception return. */
8695 if (IS_USER(s)) {
8696 goto illegal_op;
8698 gen_exception_return(s, tmp2);
8699 } else {
8700 if (logic_cc) {
8701 gen_logic_CC(tmp2);
8703 store_reg_bx(s, rd, tmp2);
8705 break;
8706 case 0x0e:
8707 tcg_gen_andc_i32(tmp, tmp, tmp2);
8708 if (logic_cc) {
8709 gen_logic_CC(tmp);
8711 store_reg_bx(s, rd, tmp);
8712 break;
8713 default:
8714 case 0x0f:
8715 tcg_gen_not_i32(tmp2, tmp2);
8716 if (logic_cc) {
8717 gen_logic_CC(tmp2);
8719 store_reg_bx(s, rd, tmp2);
8720 break;
8722 if (op1 != 0x0f && op1 != 0x0d) {
8723 tcg_temp_free_i32(tmp2);
8725 } else {
8726 /* other instructions */
8727 op1 = (insn >> 24) & 0xf;
8728 switch(op1) {
8729 case 0x0:
8730 case 0x1:
8731 /* multiplies, extra load/stores */
8732 sh = (insn >> 5) & 3;
8733 if (sh == 0) {
8734 if (op1 == 0x0) {
8735 rd = (insn >> 16) & 0xf;
8736 rn = (insn >> 12) & 0xf;
8737 rs = (insn >> 8) & 0xf;
8738 rm = (insn) & 0xf;
8739 op1 = (insn >> 20) & 0xf;
8740 switch (op1) {
8741 case 0: case 1: case 2: case 3: case 6:
8742 /* 32 bit mul */
8743 tmp = load_reg(s, rs);
8744 tmp2 = load_reg(s, rm);
8745 tcg_gen_mul_i32(tmp, tmp, tmp2);
8746 tcg_temp_free_i32(tmp2);
8747 if (insn & (1 << 22)) {
8748 /* Subtract (mls) */
8749 ARCH(6T2);
8750 tmp2 = load_reg(s, rn);
8751 tcg_gen_sub_i32(tmp, tmp2, tmp);
8752 tcg_temp_free_i32(tmp2);
8753 } else if (insn & (1 << 21)) {
8754 /* Add */
8755 tmp2 = load_reg(s, rn);
8756 tcg_gen_add_i32(tmp, tmp, tmp2);
8757 tcg_temp_free_i32(tmp2);
8759 if (insn & (1 << 20))
8760 gen_logic_CC(tmp);
8761 store_reg(s, rd, tmp);
8762 break;
8763 case 4:
8764 /* 64 bit mul double accumulate (UMAAL) */
8765 ARCH(6);
8766 tmp = load_reg(s, rs);
8767 tmp2 = load_reg(s, rm);
8768 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8769 gen_addq_lo(s, tmp64, rn);
8770 gen_addq_lo(s, tmp64, rd);
8771 gen_storeq_reg(s, rn, rd, tmp64);
8772 tcg_temp_free_i64(tmp64);
8773 break;
8774 case 8: case 9: case 10: case 11:
8775 case 12: case 13: case 14: case 15:
8776 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8777 tmp = load_reg(s, rs);
8778 tmp2 = load_reg(s, rm);
8779 if (insn & (1 << 22)) {
8780 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8781 } else {
8782 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8784 if (insn & (1 << 21)) { /* mult accumulate */
8785 TCGv_i32 al = load_reg(s, rn);
8786 TCGv_i32 ah = load_reg(s, rd);
8787 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8788 tcg_temp_free_i32(al);
8789 tcg_temp_free_i32(ah);
8791 if (insn & (1 << 20)) {
8792 gen_logicq_cc(tmp, tmp2);
8794 store_reg(s, rn, tmp);
8795 store_reg(s, rd, tmp2);
8796 break;
8797 default:
8798 goto illegal_op;
8800 } else {
8801 rn = (insn >> 16) & 0xf;
8802 rd = (insn >> 12) & 0xf;
8803 if (insn & (1 << 23)) {
8804 /* load/store exclusive */
8805 int op2 = (insn >> 8) & 3;
8806 op1 = (insn >> 21) & 0x3;
8808 switch (op2) {
8809 case 0: /* lda/stl */
8810 if (op1 == 1) {
8811 goto illegal_op;
8813 ARCH(8);
8814 break;
8815 case 1: /* reserved */
8816 goto illegal_op;
8817 case 2: /* ldaex/stlex */
8818 ARCH(8);
8819 break;
8820 case 3: /* ldrex/strex */
8821 if (op1) {
8822 ARCH(6K);
8823 } else {
8824 ARCH(6);
8826 break;
8829 addr = tcg_temp_local_new_i32();
8830 load_reg_var(s, addr, rn);
8832 /* Since the emulation does not have barriers,
8833 the acquire/release semantics need no special
8834 handling */
8835 if (op2 == 0) {
8836 if (insn & (1 << 20)) {
8837 tmp = tcg_temp_new_i32();
8838 switch (op1) {
8839 case 0: /* lda */
8840 gen_aa32_ld32u_iss(s, tmp, addr,
8841 get_mem_index(s),
8842 rd | ISSIsAcqRel);
8843 break;
8844 case 2: /* ldab */
8845 gen_aa32_ld8u_iss(s, tmp, addr,
8846 get_mem_index(s),
8847 rd | ISSIsAcqRel);
8848 break;
8849 case 3: /* ldah */
8850 gen_aa32_ld16u_iss(s, tmp, addr,
8851 get_mem_index(s),
8852 rd | ISSIsAcqRel);
8853 break;
8854 default:
8855 abort();
8857 store_reg(s, rd, tmp);
8858 } else {
8859 rm = insn & 0xf;
8860 tmp = load_reg(s, rm);
8861 switch (op1) {
8862 case 0: /* stl */
8863 gen_aa32_st32_iss(s, tmp, addr,
8864 get_mem_index(s),
8865 rm | ISSIsAcqRel);
8866 break;
8867 case 2: /* stlb */
8868 gen_aa32_st8_iss(s, tmp, addr,
8869 get_mem_index(s),
8870 rm | ISSIsAcqRel);
8871 break;
8872 case 3: /* stlh */
8873 gen_aa32_st16_iss(s, tmp, addr,
8874 get_mem_index(s),
8875 rm | ISSIsAcqRel);
8876 break;
8877 default:
8878 abort();
8880 tcg_temp_free_i32(tmp);
8882 } else if (insn & (1 << 20)) {
8883 switch (op1) {
8884 case 0: /* ldrex */
8885 gen_load_exclusive(s, rd, 15, addr, 2);
8886 break;
8887 case 1: /* ldrexd */
8888 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8889 break;
8890 case 2: /* ldrexb */
8891 gen_load_exclusive(s, rd, 15, addr, 0);
8892 break;
8893 case 3: /* ldrexh */
8894 gen_load_exclusive(s, rd, 15, addr, 1);
8895 break;
8896 default:
8897 abort();
8899 } else {
8900 rm = insn & 0xf;
8901 switch (op1) {
8902 case 0: /* strex */
8903 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8904 break;
8905 case 1: /* strexd */
8906 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8907 break;
8908 case 2: /* strexb */
8909 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8910 break;
8911 case 3: /* strexh */
8912 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8913 break;
8914 default:
8915 abort();
8918 tcg_temp_free_i32(addr);
8919 } else {
8920 TCGv taddr;
8921 TCGMemOp opc = s->be_data;
8923 /* SWP instruction */
8924 rm = (insn) & 0xf;
8926 if (insn & (1 << 22)) {
8927 opc |= MO_UB;
8928 } else {
8929 opc |= MO_UL | MO_ALIGN;
8932 addr = load_reg(s, rn);
8933 taddr = gen_aa32_addr(s, addr, opc);
8934 tcg_temp_free_i32(addr);
8936 tmp = load_reg(s, rm);
8937 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8938 get_mem_index(s), opc);
8939 tcg_temp_free(taddr);
8940 store_reg(s, rd, tmp);
8943 } else {
8944 int address_offset;
8945 bool load = insn & (1 << 20);
8946 bool wbit = insn & (1 << 21);
8947 bool pbit = insn & (1 << 24);
8948 bool doubleword = false;
8949 ISSInfo issinfo;
8951 /* Misc load/store */
8952 rn = (insn >> 16) & 0xf;
8953 rd = (insn >> 12) & 0xf;
8955 /* ISS not valid if writeback */
8956 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8958 if (!load && (sh & 2)) {
8959 /* doubleword */
8960 ARCH(5TE);
8961 if (rd & 1) {
8962 /* UNPREDICTABLE; we choose to UNDEF */
8963 goto illegal_op;
8965 load = (sh & 1) == 0;
8966 doubleword = true;
8969 addr = load_reg(s, rn);
8970 if (pbit) {
8971 gen_add_datah_offset(s, insn, 0, addr);
8973 address_offset = 0;
8975 if (doubleword) {
8976 if (!load) {
8977 /* store */
8978 tmp = load_reg(s, rd);
8979 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8980 tcg_temp_free_i32(tmp);
8981 tcg_gen_addi_i32(addr, addr, 4);
8982 tmp = load_reg(s, rd + 1);
8983 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8984 tcg_temp_free_i32(tmp);
8985 } else {
8986 /* load */
8987 tmp = tcg_temp_new_i32();
8988 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8989 store_reg(s, rd, tmp);
8990 tcg_gen_addi_i32(addr, addr, 4);
8991 tmp = tcg_temp_new_i32();
8992 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8993 rd++;
8995 address_offset = -4;
8996 } else if (load) {
8997 /* load */
8998 tmp = tcg_temp_new_i32();
8999 switch (sh) {
9000 case 1:
9001 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9002 issinfo);
9003 break;
9004 case 2:
9005 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9006 issinfo);
9007 break;
9008 default:
9009 case 3:
9010 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9011 issinfo);
9012 break;
9014 } else {
9015 /* store */
9016 tmp = load_reg(s, rd);
9017 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9018 tcg_temp_free_i32(tmp);
9020 /* Perform base writeback before the loaded value to
9021 ensure correct behavior with overlapping index registers.
9022 ldrd with base writeback is undefined if the
9023 destination and index registers overlap. */
9024 if (!pbit) {
9025 gen_add_datah_offset(s, insn, address_offset, addr);
9026 store_reg(s, rn, addr);
9027 } else if (wbit) {
9028 if (address_offset)
9029 tcg_gen_addi_i32(addr, addr, address_offset);
9030 store_reg(s, rn, addr);
9031 } else {
9032 tcg_temp_free_i32(addr);
9034 if (load) {
9035 /* Complete the load. */
9036 store_reg(s, rd, tmp);
9039 break;
9040 case 0x4:
9041 case 0x5:
9042 goto do_ldst;
9043 case 0x6:
9044 case 0x7:
9045 if (insn & (1 << 4)) {
9046 ARCH(6);
9047 /* Armv6 Media instructions. */
9048 rm = insn & 0xf;
9049 rn = (insn >> 16) & 0xf;
9050 rd = (insn >> 12) & 0xf;
9051 rs = (insn >> 8) & 0xf;
9052 switch ((insn >> 23) & 3) {
9053 case 0: /* Parallel add/subtract. */
9054 op1 = (insn >> 20) & 7;
9055 tmp = load_reg(s, rn);
9056 tmp2 = load_reg(s, rm);
9057 sh = (insn >> 5) & 7;
9058 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9059 goto illegal_op;
9060 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9061 tcg_temp_free_i32(tmp2);
9062 store_reg(s, rd, tmp);
9063 break;
9064 case 1:
9065 if ((insn & 0x00700020) == 0) {
9066 /* Halfword pack. */
9067 tmp = load_reg(s, rn);
9068 tmp2 = load_reg(s, rm);
9069 shift = (insn >> 7) & 0x1f;
9070 if (insn & (1 << 6)) {
9071 /* pkhtb */
9072 if (shift == 0)
9073 shift = 31;
9074 tcg_gen_sari_i32(tmp2, tmp2, shift);
9075 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9076 tcg_gen_ext16u_i32(tmp2, tmp2);
9077 } else {
9078 /* pkhbt */
9079 if (shift)
9080 tcg_gen_shli_i32(tmp2, tmp2, shift);
9081 tcg_gen_ext16u_i32(tmp, tmp);
9082 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9084 tcg_gen_or_i32(tmp, tmp, tmp2);
9085 tcg_temp_free_i32(tmp2);
9086 store_reg(s, rd, tmp);
9087 } else if ((insn & 0x00200020) == 0x00200000) {
9088 /* [us]sat */
9089 tmp = load_reg(s, rm);
9090 shift = (insn >> 7) & 0x1f;
9091 if (insn & (1 << 6)) {
9092 if (shift == 0)
9093 shift = 31;
9094 tcg_gen_sari_i32(tmp, tmp, shift);
9095 } else {
9096 tcg_gen_shli_i32(tmp, tmp, shift);
9098 sh = (insn >> 16) & 0x1f;
9099 tmp2 = tcg_const_i32(sh);
9100 if (insn & (1 << 22))
9101 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9102 else
9103 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9104 tcg_temp_free_i32(tmp2);
9105 store_reg(s, rd, tmp);
9106 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9107 /* [us]sat16 */
9108 tmp = load_reg(s, rm);
9109 sh = (insn >> 16) & 0x1f;
9110 tmp2 = tcg_const_i32(sh);
9111 if (insn & (1 << 22))
9112 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9113 else
9114 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9115 tcg_temp_free_i32(tmp2);
9116 store_reg(s, rd, tmp);
9117 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9118 /* Select bytes. */
9119 tmp = load_reg(s, rn);
9120 tmp2 = load_reg(s, rm);
9121 tmp3 = tcg_temp_new_i32();
9122 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9123 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9124 tcg_temp_free_i32(tmp3);
9125 tcg_temp_free_i32(tmp2);
9126 store_reg(s, rd, tmp);
9127 } else if ((insn & 0x000003e0) == 0x00000060) {
9128 tmp = load_reg(s, rm);
9129 shift = (insn >> 10) & 3;
9130 /* ??? In many cases it's not necessary to do a
9131 rotate, a shift is sufficient. */
9132 if (shift != 0)
9133 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9134 op1 = (insn >> 20) & 7;
9135 switch (op1) {
9136 case 0: gen_sxtb16(tmp); break;
9137 case 2: gen_sxtb(tmp); break;
9138 case 3: gen_sxth(tmp); break;
9139 case 4: gen_uxtb16(tmp); break;
9140 case 6: gen_uxtb(tmp); break;
9141 case 7: gen_uxth(tmp); break;
9142 default: goto illegal_op;
9144 if (rn != 15) {
9145 tmp2 = load_reg(s, rn);
9146 if ((op1 & 3) == 0) {
9147 gen_add16(tmp, tmp2);
9148 } else {
9149 tcg_gen_add_i32(tmp, tmp, tmp2);
9150 tcg_temp_free_i32(tmp2);
9153 store_reg(s, rd, tmp);
9154 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9155 /* rev */
9156 tmp = load_reg(s, rm);
9157 if (insn & (1 << 22)) {
9158 if (insn & (1 << 7)) {
9159 gen_revsh(tmp);
9160 } else {
9161 ARCH(6T2);
9162 gen_helper_rbit(tmp, tmp);
9164 } else {
9165 if (insn & (1 << 7))
9166 gen_rev16(tmp);
9167 else
9168 tcg_gen_bswap32_i32(tmp, tmp);
9170 store_reg(s, rd, tmp);
9171 } else {
9172 goto illegal_op;
9174 break;
9175 case 2: /* Multiplies (Type 3). */
9176 switch ((insn >> 20) & 0x7) {
9177 case 5:
9178 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9179 /* op2 not 00x or 11x : UNDEF */
9180 goto illegal_op;
9182 /* Signed multiply most significant [accumulate].
9183 (SMMUL, SMMLA, SMMLS) */
9184 tmp = load_reg(s, rm);
9185 tmp2 = load_reg(s, rs);
9186 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9188 if (rd != 15) {
9189 tmp = load_reg(s, rd);
9190 if (insn & (1 << 6)) {
9191 tmp64 = gen_subq_msw(tmp64, tmp);
9192 } else {
9193 tmp64 = gen_addq_msw(tmp64, tmp);
9196 if (insn & (1 << 5)) {
9197 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9199 tcg_gen_shri_i64(tmp64, tmp64, 32);
9200 tmp = tcg_temp_new_i32();
9201 tcg_gen_extrl_i64_i32(tmp, tmp64);
9202 tcg_temp_free_i64(tmp64);
9203 store_reg(s, rn, tmp);
9204 break;
9205 case 0:
9206 case 4:
9207 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9208 if (insn & (1 << 7)) {
9209 goto illegal_op;
9211 tmp = load_reg(s, rm);
9212 tmp2 = load_reg(s, rs);
9213 if (insn & (1 << 5))
9214 gen_swap_half(tmp2);
9215 gen_smul_dual(tmp, tmp2);
9216 if (insn & (1 << 22)) {
9217 /* smlald, smlsld */
9218 TCGv_i64 tmp64_2;
9220 tmp64 = tcg_temp_new_i64();
9221 tmp64_2 = tcg_temp_new_i64();
9222 tcg_gen_ext_i32_i64(tmp64, tmp);
9223 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9224 tcg_temp_free_i32(tmp);
9225 tcg_temp_free_i32(tmp2);
9226 if (insn & (1 << 6)) {
9227 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9228 } else {
9229 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9231 tcg_temp_free_i64(tmp64_2);
9232 gen_addq(s, tmp64, rd, rn);
9233 gen_storeq_reg(s, rd, rn, tmp64);
9234 tcg_temp_free_i64(tmp64);
9235 } else {
9236 /* smuad, smusd, smlad, smlsd */
9237 if (insn & (1 << 6)) {
9238 /* This subtraction cannot overflow. */
9239 tcg_gen_sub_i32(tmp, tmp, tmp2);
9240 } else {
9241 /* This addition cannot overflow 32 bits;
9242 * however it may overflow considered as a
9243 * signed operation, in which case we must set
9244 * the Q flag.
9246 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9248 tcg_temp_free_i32(tmp2);
9249 if (rd != 15)
9251 tmp2 = load_reg(s, rd);
9252 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9253 tcg_temp_free_i32(tmp2);
9255 store_reg(s, rn, tmp);
9257 break;
9258 case 1:
9259 case 3:
9260 /* SDIV, UDIV */
9261 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9262 goto illegal_op;
9264 if (((insn >> 5) & 7) || (rd != 15)) {
9265 goto illegal_op;
9267 tmp = load_reg(s, rm);
9268 tmp2 = load_reg(s, rs);
9269 if (insn & (1 << 21)) {
9270 gen_helper_udiv(tmp, tmp, tmp2);
9271 } else {
9272 gen_helper_sdiv(tmp, tmp, tmp2);
9274 tcg_temp_free_i32(tmp2);
9275 store_reg(s, rn, tmp);
9276 break;
9277 default:
9278 goto illegal_op;
9280 break;
9281 case 3:
9282 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9283 switch (op1) {
9284 case 0: /* Unsigned sum of absolute differences. */
9285 ARCH(6);
9286 tmp = load_reg(s, rm);
9287 tmp2 = load_reg(s, rs);
9288 gen_helper_usad8(tmp, tmp, tmp2);
9289 tcg_temp_free_i32(tmp2);
9290 if (rd != 15) {
9291 tmp2 = load_reg(s, rd);
9292 tcg_gen_add_i32(tmp, tmp, tmp2);
9293 tcg_temp_free_i32(tmp2);
9295 store_reg(s, rn, tmp);
9296 break;
9297 case 0x20: case 0x24: case 0x28: case 0x2c:
9298 /* Bitfield insert/clear. */
9299 ARCH(6T2);
9300 shift = (insn >> 7) & 0x1f;
9301 i = (insn >> 16) & 0x1f;
9302 if (i < shift) {
9303 /* UNPREDICTABLE; we choose to UNDEF */
9304 goto illegal_op;
9306 i = i + 1 - shift;
9307 if (rm == 15) {
9308 tmp = tcg_temp_new_i32();
9309 tcg_gen_movi_i32(tmp, 0);
9310 } else {
9311 tmp = load_reg(s, rm);
9313 if (i != 32) {
9314 tmp2 = load_reg(s, rd);
9315 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9316 tcg_temp_free_i32(tmp2);
9318 store_reg(s, rd, tmp);
9319 break;
9320 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9321 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9322 ARCH(6T2);
9323 tmp = load_reg(s, rm);
9324 shift = (insn >> 7) & 0x1f;
9325 i = ((insn >> 16) & 0x1f) + 1;
9326 if (shift + i > 32)
9327 goto illegal_op;
9328 if (i < 32) {
9329 if (op1 & 0x20) {
9330 tcg_gen_extract_i32(tmp, tmp, shift, i);
9331 } else {
9332 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9335 store_reg(s, rd, tmp);
9336 break;
9337 default:
9338 goto illegal_op;
9340 break;
9342 break;
9344 do_ldst:
9345 /* Check for undefined extension instructions
9346 * per the ARM Bible IE:
9347 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9349 sh = (0xf << 20) | (0xf << 4);
9350 if (op1 == 0x7 && ((insn & sh) == sh))
9352 goto illegal_op;
9354 /* load/store byte/word */
9355 rn = (insn >> 16) & 0xf;
9356 rd = (insn >> 12) & 0xf;
9357 tmp2 = load_reg(s, rn);
9358 if ((insn & 0x01200000) == 0x00200000) {
9359 /* ldrt/strt */
9360 i = get_a32_user_mem_index(s);
9361 } else {
9362 i = get_mem_index(s);
9364 if (insn & (1 << 24))
9365 gen_add_data_offset(s, insn, tmp2);
9366 if (insn & (1 << 20)) {
9367 /* load */
9368 tmp = tcg_temp_new_i32();
9369 if (insn & (1 << 22)) {
9370 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9371 } else {
9372 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9374 } else {
9375 /* store */
9376 tmp = load_reg(s, rd);
9377 if (insn & (1 << 22)) {
9378 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9379 } else {
9380 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9382 tcg_temp_free_i32(tmp);
9384 if (!(insn & (1 << 24))) {
9385 gen_add_data_offset(s, insn, tmp2);
9386 store_reg(s, rn, tmp2);
9387 } else if (insn & (1 << 21)) {
9388 store_reg(s, rn, tmp2);
9389 } else {
9390 tcg_temp_free_i32(tmp2);
9392 if (insn & (1 << 20)) {
9393 /* Complete the load. */
9394 store_reg_from_load(s, rd, tmp);
9396 break;
9397 case 0x08:
9398 case 0x09:
9400 int j, n, loaded_base;
9401 bool exc_return = false;
9402 bool is_load = extract32(insn, 20, 1);
9403 bool user = false;
9404 TCGv_i32 loaded_var;
9405 /* load/store multiple words */
9406 /* XXX: store correct base if write back */
9407 if (insn & (1 << 22)) {
9408 /* LDM (user), LDM (exception return) and STM (user) */
9409 if (IS_USER(s))
9410 goto illegal_op; /* only usable in supervisor mode */
9412 if (is_load && extract32(insn, 15, 1)) {
9413 exc_return = true;
9414 } else {
9415 user = true;
9418 rn = (insn >> 16) & 0xf;
9419 addr = load_reg(s, rn);
9421 /* compute total size */
9422 loaded_base = 0;
9423 TCGV_UNUSED_I32(loaded_var);
9424 n = 0;
9425 for(i=0;i<16;i++) {
9426 if (insn & (1 << i))
9427 n++;
9429 /* XXX: test invalid n == 0 case ? */
9430 if (insn & (1 << 23)) {
9431 if (insn & (1 << 24)) {
9432 /* pre increment */
9433 tcg_gen_addi_i32(addr, addr, 4);
9434 } else {
9435 /* post increment */
9437 } else {
9438 if (insn & (1 << 24)) {
9439 /* pre decrement */
9440 tcg_gen_addi_i32(addr, addr, -(n * 4));
9441 } else {
9442 /* post decrement */
9443 if (n != 1)
9444 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9447 j = 0;
9448 for(i=0;i<16;i++) {
9449 if (insn & (1 << i)) {
9450 if (is_load) {
9451 /* load */
9452 tmp = tcg_temp_new_i32();
9453 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9454 if (user) {
9455 tmp2 = tcg_const_i32(i);
9456 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9457 tcg_temp_free_i32(tmp2);
9458 tcg_temp_free_i32(tmp);
9459 } else if (i == rn) {
9460 loaded_var = tmp;
9461 loaded_base = 1;
9462 } else if (rn == 15 && exc_return) {
9463 store_pc_exc_ret(s, tmp);
9464 } else {
9465 store_reg_from_load(s, i, tmp);
9467 } else {
9468 /* store */
9469 if (i == 15) {
9470 /* special case: r15 = PC + 8 */
9471 val = (long)s->pc + 4;
9472 tmp = tcg_temp_new_i32();
9473 tcg_gen_movi_i32(tmp, val);
9474 } else if (user) {
9475 tmp = tcg_temp_new_i32();
9476 tmp2 = tcg_const_i32(i);
9477 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9478 tcg_temp_free_i32(tmp2);
9479 } else {
9480 tmp = load_reg(s, i);
9482 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9483 tcg_temp_free_i32(tmp);
9485 j++;
9486 /* no need to add after the last transfer */
9487 if (j != n)
9488 tcg_gen_addi_i32(addr, addr, 4);
9491 if (insn & (1 << 21)) {
9492 /* write back */
9493 if (insn & (1 << 23)) {
9494 if (insn & (1 << 24)) {
9495 /* pre increment */
9496 } else {
9497 /* post increment */
9498 tcg_gen_addi_i32(addr, addr, 4);
9500 } else {
9501 if (insn & (1 << 24)) {
9502 /* pre decrement */
9503 if (n != 1)
9504 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9505 } else {
9506 /* post decrement */
9507 tcg_gen_addi_i32(addr, addr, -(n * 4));
9510 store_reg(s, rn, addr);
9511 } else {
9512 tcg_temp_free_i32(addr);
9514 if (loaded_base) {
9515 store_reg(s, rn, loaded_var);
9517 if (exc_return) {
9518 /* Restore CPSR from SPSR. */
9519 tmp = load_cpu_field(spsr);
9520 gen_helper_cpsr_write_eret(cpu_env, tmp);
9521 tcg_temp_free_i32(tmp);
9522 s->is_jmp = DISAS_JUMP;
9525 break;
9526 case 0xa:
9527 case 0xb:
9529 int32_t offset;
9531 /* branch (and link) */
9532 val = (int32_t)s->pc;
9533 if (insn & (1 << 24)) {
9534 tmp = tcg_temp_new_i32();
9535 tcg_gen_movi_i32(tmp, val);
9536 store_reg(s, 14, tmp);
9538 offset = sextract32(insn << 2, 0, 26);
9539 val += offset + 4;
9540 gen_jmp(s, val);
9542 break;
9543 case 0xc:
9544 case 0xd:
9545 case 0xe:
9546 if (((insn >> 8) & 0xe) == 10) {
9547 /* VFP. */
9548 if (disas_vfp_insn(s, insn)) {
9549 goto illegal_op;
9551 } else if (disas_coproc_insn(s, insn)) {
9552 /* Coprocessor. */
9553 goto illegal_op;
9555 break;
9556 case 0xf:
9557 /* swi */
9558 gen_set_pc_im(s, s->pc);
9559 s->svc_imm = extract32(insn, 0, 24);
9560 s->is_jmp = DISAS_SWI;
9561 break;
9562 default:
9563 illegal_op:
9564 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9565 default_exception_el(s));
9566 break;
9571 /* Return true if this is a Thumb-2 logical op. */
9572 static int
9573 thumb2_logic_op(int op)
9575 return (op < 8);
9578 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9579 then set condition code flags based on the result of the operation.
9580 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9581 to the high bit of T1.
9582 Returns zero if the opcode is valid. */
9584 static int
9585 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9586 TCGv_i32 t0, TCGv_i32 t1)
9588 int logic_cc;
9590 logic_cc = 0;
9591 switch (op) {
9592 case 0: /* and */
9593 tcg_gen_and_i32(t0, t0, t1);
9594 logic_cc = conds;
9595 break;
9596 case 1: /* bic */
9597 tcg_gen_andc_i32(t0, t0, t1);
9598 logic_cc = conds;
9599 break;
9600 case 2: /* orr */
9601 tcg_gen_or_i32(t0, t0, t1);
9602 logic_cc = conds;
9603 break;
9604 case 3: /* orn */
9605 tcg_gen_orc_i32(t0, t0, t1);
9606 logic_cc = conds;
9607 break;
9608 case 4: /* eor */
9609 tcg_gen_xor_i32(t0, t0, t1);
9610 logic_cc = conds;
9611 break;
9612 case 8: /* add */
9613 if (conds)
9614 gen_add_CC(t0, t0, t1);
9615 else
9616 tcg_gen_add_i32(t0, t0, t1);
9617 break;
9618 case 10: /* adc */
9619 if (conds)
9620 gen_adc_CC(t0, t0, t1);
9621 else
9622 gen_adc(t0, t1);
9623 break;
9624 case 11: /* sbc */
9625 if (conds) {
9626 gen_sbc_CC(t0, t0, t1);
9627 } else {
9628 gen_sub_carry(t0, t0, t1);
9630 break;
9631 case 13: /* sub */
9632 if (conds)
9633 gen_sub_CC(t0, t0, t1);
9634 else
9635 tcg_gen_sub_i32(t0, t0, t1);
9636 break;
9637 case 14: /* rsb */
9638 if (conds)
9639 gen_sub_CC(t0, t1, t0);
9640 else
9641 tcg_gen_sub_i32(t0, t1, t0);
9642 break;
9643 default: /* 5, 6, 7, 9, 12, 15. */
9644 return 1;
9646 if (logic_cc) {
9647 gen_logic_CC(t0);
9648 if (shifter_out)
9649 gen_set_CF_bit31(t1);
9651 return 0;
9654 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9655 is not legal. */
9656 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9658 uint32_t insn, imm, shift, offset;
9659 uint32_t rd, rn, rm, rs;
9660 TCGv_i32 tmp;
9661 TCGv_i32 tmp2;
9662 TCGv_i32 tmp3;
9663 TCGv_i32 addr;
9664 TCGv_i64 tmp64;
9665 int op;
9666 int shiftop;
9667 int conds;
9668 int logic_cc;
9670 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9671 || arm_dc_feature(s, ARM_FEATURE_M))) {
9672 /* Thumb-1 cores may need to treat bl and blx as a pair of
9673 16-bit instructions to get correct prefetch abort behavior. */
9674 insn = insn_hw1;
9675 if ((insn & (1 << 12)) == 0) {
9676 ARCH(5);
9677 /* Second half of blx. */
9678 offset = ((insn & 0x7ff) << 1);
9679 tmp = load_reg(s, 14);
9680 tcg_gen_addi_i32(tmp, tmp, offset);
9681 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9683 tmp2 = tcg_temp_new_i32();
9684 tcg_gen_movi_i32(tmp2, s->pc | 1);
9685 store_reg(s, 14, tmp2);
9686 gen_bx(s, tmp);
9687 return 0;
9689 if (insn & (1 << 11)) {
9690 /* Second half of bl. */
9691 offset = ((insn & 0x7ff) << 1) | 1;
9692 tmp = load_reg(s, 14);
9693 tcg_gen_addi_i32(tmp, tmp, offset);
9695 tmp2 = tcg_temp_new_i32();
9696 tcg_gen_movi_i32(tmp2, s->pc | 1);
9697 store_reg(s, 14, tmp2);
9698 gen_bx(s, tmp);
9699 return 0;
9701 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9702 /* Instruction spans a page boundary. Implement it as two
9703 16-bit instructions in case the second half causes an
9704 prefetch abort. */
9705 offset = ((int32_t)insn << 21) >> 9;
9706 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9707 return 0;
9709 /* Fall through to 32-bit decode. */
9712 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9713 s->pc += 2;
9714 insn |= (uint32_t)insn_hw1 << 16;
9716 if ((insn & 0xf800e800) != 0xf000e800) {
9717 ARCH(6T2);
9720 rn = (insn >> 16) & 0xf;
9721 rs = (insn >> 12) & 0xf;
9722 rd = (insn >> 8) & 0xf;
9723 rm = insn & 0xf;
9724 switch ((insn >> 25) & 0xf) {
9725 case 0: case 1: case 2: case 3:
9726 /* 16-bit instructions. Should never happen. */
9727 abort();
9728 case 4:
9729 if (insn & (1 << 22)) {
9730 /* Other load/store, table branch. */
9731 if (insn & 0x01200000) {
9732 /* Load/store doubleword. */
9733 if (rn == 15) {
9734 addr = tcg_temp_new_i32();
9735 tcg_gen_movi_i32(addr, s->pc & ~3);
9736 } else {
9737 addr = load_reg(s, rn);
9739 offset = (insn & 0xff) * 4;
9740 if ((insn & (1 << 23)) == 0)
9741 offset = -offset;
9742 if (insn & (1 << 24)) {
9743 tcg_gen_addi_i32(addr, addr, offset);
9744 offset = 0;
9746 if (insn & (1 << 20)) {
9747 /* ldrd */
9748 tmp = tcg_temp_new_i32();
9749 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9750 store_reg(s, rs, tmp);
9751 tcg_gen_addi_i32(addr, addr, 4);
9752 tmp = tcg_temp_new_i32();
9753 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9754 store_reg(s, rd, tmp);
9755 } else {
9756 /* strd */
9757 tmp = load_reg(s, rs);
9758 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9759 tcg_temp_free_i32(tmp);
9760 tcg_gen_addi_i32(addr, addr, 4);
9761 tmp = load_reg(s, rd);
9762 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9763 tcg_temp_free_i32(tmp);
9765 if (insn & (1 << 21)) {
9766 /* Base writeback. */
9767 if (rn == 15)
9768 goto illegal_op;
9769 tcg_gen_addi_i32(addr, addr, offset - 4);
9770 store_reg(s, rn, addr);
9771 } else {
9772 tcg_temp_free_i32(addr);
9774 } else if ((insn & (1 << 23)) == 0) {
9775 /* Load/store exclusive word. */
9776 addr = tcg_temp_local_new_i32();
9777 load_reg_var(s, addr, rn);
9778 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9779 if (insn & (1 << 20)) {
9780 gen_load_exclusive(s, rs, 15, addr, 2);
9781 } else {
9782 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9784 tcg_temp_free_i32(addr);
9785 } else if ((insn & (7 << 5)) == 0) {
9786 /* Table Branch. */
9787 if (rn == 15) {
9788 addr = tcg_temp_new_i32();
9789 tcg_gen_movi_i32(addr, s->pc);
9790 } else {
9791 addr = load_reg(s, rn);
9793 tmp = load_reg(s, rm);
9794 tcg_gen_add_i32(addr, addr, tmp);
9795 if (insn & (1 << 4)) {
9796 /* tbh */
9797 tcg_gen_add_i32(addr, addr, tmp);
9798 tcg_temp_free_i32(tmp);
9799 tmp = tcg_temp_new_i32();
9800 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9801 } else { /* tbb */
9802 tcg_temp_free_i32(tmp);
9803 tmp = tcg_temp_new_i32();
9804 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9806 tcg_temp_free_i32(addr);
9807 tcg_gen_shli_i32(tmp, tmp, 1);
9808 tcg_gen_addi_i32(tmp, tmp, s->pc);
9809 store_reg(s, 15, tmp);
9810 } else {
9811 int op2 = (insn >> 6) & 0x3;
9812 op = (insn >> 4) & 0x3;
9813 switch (op2) {
9814 case 0:
9815 goto illegal_op;
9816 case 1:
9817 /* Load/store exclusive byte/halfword/doubleword */
9818 if (op == 2) {
9819 goto illegal_op;
9821 ARCH(7);
9822 break;
9823 case 2:
9824 /* Load-acquire/store-release */
9825 if (op == 3) {
9826 goto illegal_op;
9828 /* Fall through */
9829 case 3:
9830 /* Load-acquire/store-release exclusive */
9831 ARCH(8);
9832 break;
9834 addr = tcg_temp_local_new_i32();
9835 load_reg_var(s, addr, rn);
9836 if (!(op2 & 1)) {
9837 if (insn & (1 << 20)) {
9838 tmp = tcg_temp_new_i32();
9839 switch (op) {
9840 case 0: /* ldab */
9841 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9842 rs | ISSIsAcqRel);
9843 break;
9844 case 1: /* ldah */
9845 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9846 rs | ISSIsAcqRel);
9847 break;
9848 case 2: /* lda */
9849 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9850 rs | ISSIsAcqRel);
9851 break;
9852 default:
9853 abort();
9855 store_reg(s, rs, tmp);
9856 } else {
9857 tmp = load_reg(s, rs);
9858 switch (op) {
9859 case 0: /* stlb */
9860 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9861 rs | ISSIsAcqRel);
9862 break;
9863 case 1: /* stlh */
9864 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9865 rs | ISSIsAcqRel);
9866 break;
9867 case 2: /* stl */
9868 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9869 rs | ISSIsAcqRel);
9870 break;
9871 default:
9872 abort();
9874 tcg_temp_free_i32(tmp);
9876 } else if (insn & (1 << 20)) {
9877 gen_load_exclusive(s, rs, rd, addr, op);
9878 } else {
9879 gen_store_exclusive(s, rm, rs, rd, addr, op);
9881 tcg_temp_free_i32(addr);
9883 } else {
9884 /* Load/store multiple, RFE, SRS. */
9885 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9886 /* RFE, SRS: not available in user mode or on M profile */
9887 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9888 goto illegal_op;
9890 if (insn & (1 << 20)) {
9891 /* rfe */
9892 addr = load_reg(s, rn);
9893 if ((insn & (1 << 24)) == 0)
9894 tcg_gen_addi_i32(addr, addr, -8);
9895 /* Load PC into tmp and CPSR into tmp2. */
9896 tmp = tcg_temp_new_i32();
9897 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9898 tcg_gen_addi_i32(addr, addr, 4);
9899 tmp2 = tcg_temp_new_i32();
9900 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9901 if (insn & (1 << 21)) {
9902 /* Base writeback. */
9903 if (insn & (1 << 24)) {
9904 tcg_gen_addi_i32(addr, addr, 4);
9905 } else {
9906 tcg_gen_addi_i32(addr, addr, -4);
9908 store_reg(s, rn, addr);
9909 } else {
9910 tcg_temp_free_i32(addr);
9912 gen_rfe(s, tmp, tmp2);
9913 } else {
9914 /* srs */
9915 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9916 insn & (1 << 21));
9918 } else {
9919 int i, loaded_base = 0;
9920 TCGv_i32 loaded_var;
9921 /* Load/store multiple. */
9922 addr = load_reg(s, rn);
9923 offset = 0;
9924 for (i = 0; i < 16; i++) {
9925 if (insn & (1 << i))
9926 offset += 4;
9928 if (insn & (1 << 24)) {
9929 tcg_gen_addi_i32(addr, addr, -offset);
9932 TCGV_UNUSED_I32(loaded_var);
9933 for (i = 0; i < 16; i++) {
9934 if ((insn & (1 << i)) == 0)
9935 continue;
9936 if (insn & (1 << 20)) {
9937 /* Load. */
9938 tmp = tcg_temp_new_i32();
9939 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9940 if (i == 15) {
9941 gen_bx_excret(s, tmp);
9942 } else if (i == rn) {
9943 loaded_var = tmp;
9944 loaded_base = 1;
9945 } else {
9946 store_reg(s, i, tmp);
9948 } else {
9949 /* Store. */
9950 tmp = load_reg(s, i);
9951 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9952 tcg_temp_free_i32(tmp);
9954 tcg_gen_addi_i32(addr, addr, 4);
9956 if (loaded_base) {
9957 store_reg(s, rn, loaded_var);
9959 if (insn & (1 << 21)) {
9960 /* Base register writeback. */
9961 if (insn & (1 << 24)) {
9962 tcg_gen_addi_i32(addr, addr, -offset);
9964 /* Fault if writeback register is in register list. */
9965 if (insn & (1 << rn))
9966 goto illegal_op;
9967 store_reg(s, rn, addr);
9968 } else {
9969 tcg_temp_free_i32(addr);
9973 break;
9974 case 5:
9976 op = (insn >> 21) & 0xf;
9977 if (op == 6) {
9978 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9979 goto illegal_op;
9981 /* Halfword pack. */
9982 tmp = load_reg(s, rn);
9983 tmp2 = load_reg(s, rm);
9984 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9985 if (insn & (1 << 5)) {
9986 /* pkhtb */
9987 if (shift == 0)
9988 shift = 31;
9989 tcg_gen_sari_i32(tmp2, tmp2, shift);
9990 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9991 tcg_gen_ext16u_i32(tmp2, tmp2);
9992 } else {
9993 /* pkhbt */
9994 if (shift)
9995 tcg_gen_shli_i32(tmp2, tmp2, shift);
9996 tcg_gen_ext16u_i32(tmp, tmp);
9997 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9999 tcg_gen_or_i32(tmp, tmp, tmp2);
10000 tcg_temp_free_i32(tmp2);
10001 store_reg(s, rd, tmp);
10002 } else {
10003 /* Data processing register constant shift. */
10004 if (rn == 15) {
10005 tmp = tcg_temp_new_i32();
10006 tcg_gen_movi_i32(tmp, 0);
10007 } else {
10008 tmp = load_reg(s, rn);
10010 tmp2 = load_reg(s, rm);
10012 shiftop = (insn >> 4) & 3;
10013 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10014 conds = (insn & (1 << 20)) != 0;
10015 logic_cc = (conds && thumb2_logic_op(op));
10016 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10017 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10018 goto illegal_op;
10019 tcg_temp_free_i32(tmp2);
10020 if (rd != 15) {
10021 store_reg(s, rd, tmp);
10022 } else {
10023 tcg_temp_free_i32(tmp);
10026 break;
10027 case 13: /* Misc data processing. */
10028 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10029 if (op < 4 && (insn & 0xf000) != 0xf000)
10030 goto illegal_op;
10031 switch (op) {
10032 case 0: /* Register controlled shift. */
10033 tmp = load_reg(s, rn);
10034 tmp2 = load_reg(s, rm);
10035 if ((insn & 0x70) != 0)
10036 goto illegal_op;
10037 op = (insn >> 21) & 3;
10038 logic_cc = (insn & (1 << 20)) != 0;
10039 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10040 if (logic_cc)
10041 gen_logic_CC(tmp);
10042 store_reg(s, rd, tmp);
10043 break;
10044 case 1: /* Sign/zero extend. */
10045 op = (insn >> 20) & 7;
10046 switch (op) {
10047 case 0: /* SXTAH, SXTH */
10048 case 1: /* UXTAH, UXTH */
10049 case 4: /* SXTAB, SXTB */
10050 case 5: /* UXTAB, UXTB */
10051 break;
10052 case 2: /* SXTAB16, SXTB16 */
10053 case 3: /* UXTAB16, UXTB16 */
10054 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10055 goto illegal_op;
10057 break;
10058 default:
10059 goto illegal_op;
10061 if (rn != 15) {
10062 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10063 goto illegal_op;
10066 tmp = load_reg(s, rm);
10067 shift = (insn >> 4) & 3;
10068 /* ??? In many cases it's not necessary to do a
10069 rotate, a shift is sufficient. */
10070 if (shift != 0)
10071 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10072 op = (insn >> 20) & 7;
10073 switch (op) {
10074 case 0: gen_sxth(tmp); break;
10075 case 1: gen_uxth(tmp); break;
10076 case 2: gen_sxtb16(tmp); break;
10077 case 3: gen_uxtb16(tmp); break;
10078 case 4: gen_sxtb(tmp); break;
10079 case 5: gen_uxtb(tmp); break;
10080 default:
10081 g_assert_not_reached();
10083 if (rn != 15) {
10084 tmp2 = load_reg(s, rn);
10085 if ((op >> 1) == 1) {
10086 gen_add16(tmp, tmp2);
10087 } else {
10088 tcg_gen_add_i32(tmp, tmp, tmp2);
10089 tcg_temp_free_i32(tmp2);
10092 store_reg(s, rd, tmp);
10093 break;
10094 case 2: /* SIMD add/subtract. */
10095 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10096 goto illegal_op;
10098 op = (insn >> 20) & 7;
10099 shift = (insn >> 4) & 7;
10100 if ((op & 3) == 3 || (shift & 3) == 3)
10101 goto illegal_op;
10102 tmp = load_reg(s, rn);
10103 tmp2 = load_reg(s, rm);
10104 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10105 tcg_temp_free_i32(tmp2);
10106 store_reg(s, rd, tmp);
10107 break;
10108 case 3: /* Other data processing. */
10109 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10110 if (op < 4) {
10111 /* Saturating add/subtract. */
10112 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10113 goto illegal_op;
10115 tmp = load_reg(s, rn);
10116 tmp2 = load_reg(s, rm);
10117 if (op & 1)
10118 gen_helper_double_saturate(tmp, cpu_env, tmp);
10119 if (op & 2)
10120 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10121 else
10122 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10123 tcg_temp_free_i32(tmp2);
10124 } else {
10125 switch (op) {
10126 case 0x0a: /* rbit */
10127 case 0x08: /* rev */
10128 case 0x09: /* rev16 */
10129 case 0x0b: /* revsh */
10130 case 0x18: /* clz */
10131 break;
10132 case 0x10: /* sel */
10133 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10134 goto illegal_op;
10136 break;
10137 case 0x20: /* crc32/crc32c */
10138 case 0x21:
10139 case 0x22:
10140 case 0x28:
10141 case 0x29:
10142 case 0x2a:
10143 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10144 goto illegal_op;
10146 break;
10147 default:
10148 goto illegal_op;
10150 tmp = load_reg(s, rn);
10151 switch (op) {
10152 case 0x0a: /* rbit */
10153 gen_helper_rbit(tmp, tmp);
10154 break;
10155 case 0x08: /* rev */
10156 tcg_gen_bswap32_i32(tmp, tmp);
10157 break;
10158 case 0x09: /* rev16 */
10159 gen_rev16(tmp);
10160 break;
10161 case 0x0b: /* revsh */
10162 gen_revsh(tmp);
10163 break;
10164 case 0x10: /* sel */
10165 tmp2 = load_reg(s, rm);
10166 tmp3 = tcg_temp_new_i32();
10167 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10168 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10169 tcg_temp_free_i32(tmp3);
10170 tcg_temp_free_i32(tmp2);
10171 break;
10172 case 0x18: /* clz */
10173 tcg_gen_clzi_i32(tmp, tmp, 32);
10174 break;
10175 case 0x20:
10176 case 0x21:
10177 case 0x22:
10178 case 0x28:
10179 case 0x29:
10180 case 0x2a:
10182 /* crc32/crc32c */
10183 uint32_t sz = op & 0x3;
10184 uint32_t c = op & 0x8;
10186 tmp2 = load_reg(s, rm);
10187 if (sz == 0) {
10188 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10189 } else if (sz == 1) {
10190 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10192 tmp3 = tcg_const_i32(1 << sz);
10193 if (c) {
10194 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10195 } else {
10196 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10198 tcg_temp_free_i32(tmp2);
10199 tcg_temp_free_i32(tmp3);
10200 break;
10202 default:
10203 g_assert_not_reached();
10206 store_reg(s, rd, tmp);
10207 break;
10208 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10209 switch ((insn >> 20) & 7) {
10210 case 0: /* 32 x 32 -> 32 */
10211 case 7: /* Unsigned sum of absolute differences. */
10212 break;
10213 case 1: /* 16 x 16 -> 32 */
10214 case 2: /* Dual multiply add. */
10215 case 3: /* 32 * 16 -> 32msb */
10216 case 4: /* Dual multiply subtract. */
10217 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10218 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10219 goto illegal_op;
10221 break;
10223 op = (insn >> 4) & 0xf;
10224 tmp = load_reg(s, rn);
10225 tmp2 = load_reg(s, rm);
10226 switch ((insn >> 20) & 7) {
10227 case 0: /* 32 x 32 -> 32 */
10228 tcg_gen_mul_i32(tmp, tmp, tmp2);
10229 tcg_temp_free_i32(tmp2);
10230 if (rs != 15) {
10231 tmp2 = load_reg(s, rs);
10232 if (op)
10233 tcg_gen_sub_i32(tmp, tmp2, tmp);
10234 else
10235 tcg_gen_add_i32(tmp, tmp, tmp2);
10236 tcg_temp_free_i32(tmp2);
10238 break;
10239 case 1: /* 16 x 16 -> 32 */
10240 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10241 tcg_temp_free_i32(tmp2);
10242 if (rs != 15) {
10243 tmp2 = load_reg(s, rs);
10244 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10245 tcg_temp_free_i32(tmp2);
10247 break;
10248 case 2: /* Dual multiply add. */
10249 case 4: /* Dual multiply subtract. */
10250 if (op)
10251 gen_swap_half(tmp2);
10252 gen_smul_dual(tmp, tmp2);
10253 if (insn & (1 << 22)) {
10254 /* This subtraction cannot overflow. */
10255 tcg_gen_sub_i32(tmp, tmp, tmp2);
10256 } else {
10257 /* This addition cannot overflow 32 bits;
10258 * however it may overflow considered as a signed
10259 * operation, in which case we must set the Q flag.
10261 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10263 tcg_temp_free_i32(tmp2);
10264 if (rs != 15)
10266 tmp2 = load_reg(s, rs);
10267 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10268 tcg_temp_free_i32(tmp2);
10270 break;
10271 case 3: /* 32 * 16 -> 32msb */
10272 if (op)
10273 tcg_gen_sari_i32(tmp2, tmp2, 16);
10274 else
10275 gen_sxth(tmp2);
10276 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10277 tcg_gen_shri_i64(tmp64, tmp64, 16);
10278 tmp = tcg_temp_new_i32();
10279 tcg_gen_extrl_i64_i32(tmp, tmp64);
10280 tcg_temp_free_i64(tmp64);
10281 if (rs != 15)
10283 tmp2 = load_reg(s, rs);
10284 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10285 tcg_temp_free_i32(tmp2);
10287 break;
10288 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10289 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10290 if (rs != 15) {
10291 tmp = load_reg(s, rs);
10292 if (insn & (1 << 20)) {
10293 tmp64 = gen_addq_msw(tmp64, tmp);
10294 } else {
10295 tmp64 = gen_subq_msw(tmp64, tmp);
10298 if (insn & (1 << 4)) {
10299 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10301 tcg_gen_shri_i64(tmp64, tmp64, 32);
10302 tmp = tcg_temp_new_i32();
10303 tcg_gen_extrl_i64_i32(tmp, tmp64);
10304 tcg_temp_free_i64(tmp64);
10305 break;
10306 case 7: /* Unsigned sum of absolute differences. */
10307 gen_helper_usad8(tmp, tmp, tmp2);
10308 tcg_temp_free_i32(tmp2);
10309 if (rs != 15) {
10310 tmp2 = load_reg(s, rs);
10311 tcg_gen_add_i32(tmp, tmp, tmp2);
10312 tcg_temp_free_i32(tmp2);
10314 break;
10316 store_reg(s, rd, tmp);
10317 break;
10318 case 6: case 7: /* 64-bit multiply, Divide. */
10319 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10320 tmp = load_reg(s, rn);
10321 tmp2 = load_reg(s, rm);
10322 if ((op & 0x50) == 0x10) {
10323 /* sdiv, udiv */
10324 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10325 goto illegal_op;
10327 if (op & 0x20)
10328 gen_helper_udiv(tmp, tmp, tmp2);
10329 else
10330 gen_helper_sdiv(tmp, tmp, tmp2);
10331 tcg_temp_free_i32(tmp2);
10332 store_reg(s, rd, tmp);
10333 } else if ((op & 0xe) == 0xc) {
10334 /* Dual multiply accumulate long. */
10335 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10336 tcg_temp_free_i32(tmp);
10337 tcg_temp_free_i32(tmp2);
10338 goto illegal_op;
10340 if (op & 1)
10341 gen_swap_half(tmp2);
10342 gen_smul_dual(tmp, tmp2);
10343 if (op & 0x10) {
10344 tcg_gen_sub_i32(tmp, tmp, tmp2);
10345 } else {
10346 tcg_gen_add_i32(tmp, tmp, tmp2);
10348 tcg_temp_free_i32(tmp2);
10349 /* BUGFIX */
10350 tmp64 = tcg_temp_new_i64();
10351 tcg_gen_ext_i32_i64(tmp64, tmp);
10352 tcg_temp_free_i32(tmp);
10353 gen_addq(s, tmp64, rs, rd);
10354 gen_storeq_reg(s, rs, rd, tmp64);
10355 tcg_temp_free_i64(tmp64);
10356 } else {
10357 if (op & 0x20) {
10358 /* Unsigned 64-bit multiply */
10359 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10360 } else {
10361 if (op & 8) {
10362 /* smlalxy */
10363 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10364 tcg_temp_free_i32(tmp2);
10365 tcg_temp_free_i32(tmp);
10366 goto illegal_op;
10368 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10369 tcg_temp_free_i32(tmp2);
10370 tmp64 = tcg_temp_new_i64();
10371 tcg_gen_ext_i32_i64(tmp64, tmp);
10372 tcg_temp_free_i32(tmp);
10373 } else {
10374 /* Signed 64-bit multiply */
10375 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10378 if (op & 4) {
10379 /* umaal */
10380 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10381 tcg_temp_free_i64(tmp64);
10382 goto illegal_op;
10384 gen_addq_lo(s, tmp64, rs);
10385 gen_addq_lo(s, tmp64, rd);
10386 } else if (op & 0x40) {
10387 /* 64-bit accumulate. */
10388 gen_addq(s, tmp64, rs, rd);
10390 gen_storeq_reg(s, rs, rd, tmp64);
10391 tcg_temp_free_i64(tmp64);
10393 break;
10395 break;
10396 case 6: case 7: case 14: case 15:
10397 /* Coprocessor. */
10398 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10399 /* We don't currently implement M profile FP support,
10400 * so this entire space should give a NOCP fault.
10402 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10403 default_exception_el(s));
10404 break;
10406 if (((insn >> 24) & 3) == 3) {
10407 /* Translate into the equivalent ARM encoding. */
10408 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10409 if (disas_neon_data_insn(s, insn)) {
10410 goto illegal_op;
10412 } else if (((insn >> 8) & 0xe) == 10) {
10413 if (disas_vfp_insn(s, insn)) {
10414 goto illegal_op;
10416 } else {
10417 if (insn & (1 << 28))
10418 goto illegal_op;
10419 if (disas_coproc_insn(s, insn)) {
10420 goto illegal_op;
10423 break;
10424 case 8: case 9: case 10: case 11:
10425 if (insn & (1 << 15)) {
10426 /* Branches, misc control. */
10427 if (insn & 0x5000) {
10428 /* Unconditional branch. */
10429 /* signextend(hw1[10:0]) -> offset[:12]. */
10430 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10431 /* hw1[10:0] -> offset[11:1]. */
10432 offset |= (insn & 0x7ff) << 1;
10433 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10434 offset[24:22] already have the same value because of the
10435 sign extension above. */
10436 offset ^= ((~insn) & (1 << 13)) << 10;
10437 offset ^= ((~insn) & (1 << 11)) << 11;
10439 if (insn & (1 << 14)) {
10440 /* Branch and link. */
10441 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10444 offset += s->pc;
10445 if (insn & (1 << 12)) {
10446 /* b/bl */
10447 gen_jmp(s, offset);
10448 } else {
10449 /* blx */
10450 offset &= ~(uint32_t)2;
10451 /* thumb2 bx, no need to check */
10452 gen_bx_im(s, offset);
10454 } else if (((insn >> 23) & 7) == 7) {
10455 /* Misc control */
10456 if (insn & (1 << 13))
10457 goto illegal_op;
10459 if (insn & (1 << 26)) {
10460 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10461 goto illegal_op;
10463 if (!(insn & (1 << 20))) {
10464 /* Hypervisor call (v7) */
10465 int imm16 = extract32(insn, 16, 4) << 12
10466 | extract32(insn, 0, 12);
10467 ARCH(7);
10468 if (IS_USER(s)) {
10469 goto illegal_op;
10471 gen_hvc(s, imm16);
10472 } else {
10473 /* Secure monitor call (v6+) */
10474 ARCH(6K);
10475 if (IS_USER(s)) {
10476 goto illegal_op;
10478 gen_smc(s);
10480 } else {
10481 op = (insn >> 20) & 7;
10482 switch (op) {
10483 case 0: /* msr cpsr. */
10484 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10485 tmp = load_reg(s, rn);
10486 /* the constant is the mask and SYSm fields */
10487 addr = tcg_const_i32(insn & 0xfff);
10488 gen_helper_v7m_msr(cpu_env, addr, tmp);
10489 tcg_temp_free_i32(addr);
10490 tcg_temp_free_i32(tmp);
10491 gen_lookup_tb(s);
10492 break;
10494 /* fall through */
10495 case 1: /* msr spsr. */
10496 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10497 goto illegal_op;
10500 if (extract32(insn, 5, 1)) {
10501 /* MSR (banked) */
10502 int sysm = extract32(insn, 8, 4) |
10503 (extract32(insn, 4, 1) << 4);
10504 int r = op & 1;
10506 gen_msr_banked(s, r, sysm, rm);
10507 break;
10510 /* MSR (for PSRs) */
10511 tmp = load_reg(s, rn);
10512 if (gen_set_psr(s,
10513 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10514 op == 1, tmp))
10515 goto illegal_op;
10516 break;
10517 case 2: /* cps, nop-hint. */
10518 if (((insn >> 8) & 7) == 0) {
10519 gen_nop_hint(s, insn & 0xff);
10521 /* Implemented as NOP in user mode. */
10522 if (IS_USER(s))
10523 break;
10524 offset = 0;
10525 imm = 0;
10526 if (insn & (1 << 10)) {
10527 if (insn & (1 << 7))
10528 offset |= CPSR_A;
10529 if (insn & (1 << 6))
10530 offset |= CPSR_I;
10531 if (insn & (1 << 5))
10532 offset |= CPSR_F;
10533 if (insn & (1 << 9))
10534 imm = CPSR_A | CPSR_I | CPSR_F;
10536 if (insn & (1 << 8)) {
10537 offset |= 0x1f;
10538 imm |= (insn & 0x1f);
10540 if (offset) {
10541 gen_set_psr_im(s, offset, 0, imm);
10543 break;
10544 case 3: /* Special control operations. */
10545 ARCH(7);
10546 op = (insn >> 4) & 0xf;
10547 switch (op) {
10548 case 2: /* clrex */
10549 gen_clrex(s);
10550 break;
10551 case 4: /* dsb */
10552 case 5: /* dmb */
10553 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10554 break;
10555 case 6: /* isb */
10556 /* We need to break the TB after this insn
10557 * to execute self-modifying code correctly
10558 * and also to take any pending interrupts
10559 * immediately.
10561 gen_lookup_tb(s);
10562 break;
10563 default:
10564 goto illegal_op;
10566 break;
10567 case 4: /* bxj */
10568 /* Trivial implementation equivalent to bx.
10569 * This instruction doesn't exist at all for M-profile.
10571 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10572 goto illegal_op;
10574 tmp = load_reg(s, rn);
10575 gen_bx(s, tmp);
10576 break;
10577 case 5: /* Exception return. */
10578 if (IS_USER(s)) {
10579 goto illegal_op;
10581 if (rn != 14 || rd != 15) {
10582 goto illegal_op;
10584 tmp = load_reg(s, rn);
10585 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10586 gen_exception_return(s, tmp);
10587 break;
10588 case 6: /* MRS */
10589 if (extract32(insn, 5, 1) &&
10590 !arm_dc_feature(s, ARM_FEATURE_M)) {
10591 /* MRS (banked) */
10592 int sysm = extract32(insn, 16, 4) |
10593 (extract32(insn, 4, 1) << 4);
10595 gen_mrs_banked(s, 0, sysm, rd);
10596 break;
10599 if (extract32(insn, 16, 4) != 0xf) {
10600 goto illegal_op;
10602 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10603 extract32(insn, 0, 8) != 0) {
10604 goto illegal_op;
10607 /* mrs cpsr */
10608 tmp = tcg_temp_new_i32();
10609 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10610 addr = tcg_const_i32(insn & 0xff);
10611 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10612 tcg_temp_free_i32(addr);
10613 } else {
10614 gen_helper_cpsr_read(tmp, cpu_env);
10616 store_reg(s, rd, tmp);
10617 break;
10618 case 7: /* MRS */
10619 if (extract32(insn, 5, 1) &&
10620 !arm_dc_feature(s, ARM_FEATURE_M)) {
10621 /* MRS (banked) */
10622 int sysm = extract32(insn, 16, 4) |
10623 (extract32(insn, 4, 1) << 4);
10625 gen_mrs_banked(s, 1, sysm, rd);
10626 break;
10629 /* mrs spsr. */
10630 /* Not accessible in user mode. */
10631 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10632 goto illegal_op;
10635 if (extract32(insn, 16, 4) != 0xf ||
10636 extract32(insn, 0, 8) != 0) {
10637 goto illegal_op;
10640 tmp = load_cpu_field(spsr);
10641 store_reg(s, rd, tmp);
10642 break;
10645 } else {
10646 /* Conditional branch. */
10647 op = (insn >> 22) & 0xf;
10648 /* Generate a conditional jump to next instruction. */
10649 s->condlabel = gen_new_label();
10650 arm_gen_test_cc(op ^ 1, s->condlabel);
10651 s->condjmp = 1;
10653 /* offset[11:1] = insn[10:0] */
10654 offset = (insn & 0x7ff) << 1;
10655 /* offset[17:12] = insn[21:16]. */
10656 offset |= (insn & 0x003f0000) >> 4;
10657 /* offset[31:20] = insn[26]. */
10658 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10659 /* offset[18] = insn[13]. */
10660 offset |= (insn & (1 << 13)) << 5;
10661 /* offset[19] = insn[11]. */
10662 offset |= (insn & (1 << 11)) << 8;
10664 /* jump to the offset */
10665 gen_jmp(s, s->pc + offset);
10667 } else {
10668 /* Data processing immediate. */
10669 if (insn & (1 << 25)) {
10670 if (insn & (1 << 24)) {
10671 if (insn & (1 << 20))
10672 goto illegal_op;
10673 /* Bitfield/Saturate. */
10674 op = (insn >> 21) & 7;
10675 imm = insn & 0x1f;
10676 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10677 if (rn == 15) {
10678 tmp = tcg_temp_new_i32();
10679 tcg_gen_movi_i32(tmp, 0);
10680 } else {
10681 tmp = load_reg(s, rn);
10683 switch (op) {
10684 case 2: /* Signed bitfield extract. */
10685 imm++;
10686 if (shift + imm > 32)
10687 goto illegal_op;
10688 if (imm < 32) {
10689 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10691 break;
10692 case 6: /* Unsigned bitfield extract. */
10693 imm++;
10694 if (shift + imm > 32)
10695 goto illegal_op;
10696 if (imm < 32) {
10697 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10699 break;
10700 case 3: /* Bitfield insert/clear. */
10701 if (imm < shift)
10702 goto illegal_op;
10703 imm = imm + 1 - shift;
10704 if (imm != 32) {
10705 tmp2 = load_reg(s, rd);
10706 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10707 tcg_temp_free_i32(tmp2);
10709 break;
10710 case 7:
10711 goto illegal_op;
10712 default: /* Saturate. */
10713 if (shift) {
10714 if (op & 1)
10715 tcg_gen_sari_i32(tmp, tmp, shift);
10716 else
10717 tcg_gen_shli_i32(tmp, tmp, shift);
10719 tmp2 = tcg_const_i32(imm);
10720 if (op & 4) {
10721 /* Unsigned. */
10722 if ((op & 1) && shift == 0) {
10723 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10724 tcg_temp_free_i32(tmp);
10725 tcg_temp_free_i32(tmp2);
10726 goto illegal_op;
10728 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10729 } else {
10730 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10732 } else {
10733 /* Signed. */
10734 if ((op & 1) && shift == 0) {
10735 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10736 tcg_temp_free_i32(tmp);
10737 tcg_temp_free_i32(tmp2);
10738 goto illegal_op;
10740 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10741 } else {
10742 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10745 tcg_temp_free_i32(tmp2);
10746 break;
10748 store_reg(s, rd, tmp);
10749 } else {
10750 imm = ((insn & 0x04000000) >> 15)
10751 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10752 if (insn & (1 << 22)) {
10753 /* 16-bit immediate. */
10754 imm |= (insn >> 4) & 0xf000;
10755 if (insn & (1 << 23)) {
10756 /* movt */
10757 tmp = load_reg(s, rd);
10758 tcg_gen_ext16u_i32(tmp, tmp);
10759 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10760 } else {
10761 /* movw */
10762 tmp = tcg_temp_new_i32();
10763 tcg_gen_movi_i32(tmp, imm);
10765 } else {
10766 /* Add/sub 12-bit immediate. */
10767 if (rn == 15) {
10768 offset = s->pc & ~(uint32_t)3;
10769 if (insn & (1 << 23))
10770 offset -= imm;
10771 else
10772 offset += imm;
10773 tmp = tcg_temp_new_i32();
10774 tcg_gen_movi_i32(tmp, offset);
10775 } else {
10776 tmp = load_reg(s, rn);
10777 if (insn & (1 << 23))
10778 tcg_gen_subi_i32(tmp, tmp, imm);
10779 else
10780 tcg_gen_addi_i32(tmp, tmp, imm);
10783 store_reg(s, rd, tmp);
10785 } else {
10786 int shifter_out = 0;
10787 /* modified 12-bit immediate. */
10788 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10789 imm = (insn & 0xff);
10790 switch (shift) {
10791 case 0: /* XY */
10792 /* Nothing to do. */
10793 break;
10794 case 1: /* 00XY00XY */
10795 imm |= imm << 16;
10796 break;
10797 case 2: /* XY00XY00 */
10798 imm |= imm << 16;
10799 imm <<= 8;
10800 break;
10801 case 3: /* XYXYXYXY */
10802 imm |= imm << 16;
10803 imm |= imm << 8;
10804 break;
10805 default: /* Rotated constant. */
10806 shift = (shift << 1) | (imm >> 7);
10807 imm |= 0x80;
10808 imm = imm << (32 - shift);
10809 shifter_out = 1;
10810 break;
10812 tmp2 = tcg_temp_new_i32();
10813 tcg_gen_movi_i32(tmp2, imm);
10814 rn = (insn >> 16) & 0xf;
10815 if (rn == 15) {
10816 tmp = tcg_temp_new_i32();
10817 tcg_gen_movi_i32(tmp, 0);
10818 } else {
10819 tmp = load_reg(s, rn);
10821 op = (insn >> 21) & 0xf;
10822 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10823 shifter_out, tmp, tmp2))
10824 goto illegal_op;
10825 tcg_temp_free_i32(tmp2);
10826 rd = (insn >> 8) & 0xf;
10827 if (rd != 15) {
10828 store_reg(s, rd, tmp);
10829 } else {
10830 tcg_temp_free_i32(tmp);
10834 break;
10835 case 12: /* Load/store single data item. */
10837 int postinc = 0;
10838 int writeback = 0;
10839 int memidx;
10840 ISSInfo issinfo;
10842 if ((insn & 0x01100000) == 0x01000000) {
10843 if (disas_neon_ls_insn(s, insn)) {
10844 goto illegal_op;
10846 break;
10848 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10849 if (rs == 15) {
10850 if (!(insn & (1 << 20))) {
10851 goto illegal_op;
10853 if (op != 2) {
10854 /* Byte or halfword load space with dest == r15 : memory hints.
10855 * Catch them early so we don't emit pointless addressing code.
10856 * This space is a mix of:
10857 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10858 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10859 * cores)
10860 * unallocated hints, which must be treated as NOPs
10861 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10862 * which is easiest for the decoding logic
10863 * Some space which must UNDEF
10865 int op1 = (insn >> 23) & 3;
10866 int op2 = (insn >> 6) & 0x3f;
10867 if (op & 2) {
10868 goto illegal_op;
10870 if (rn == 15) {
10871 /* UNPREDICTABLE, unallocated hint or
10872 * PLD/PLDW/PLI (literal)
10874 return 0;
10876 if (op1 & 1) {
10877 return 0; /* PLD/PLDW/PLI or unallocated hint */
10879 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10880 return 0; /* PLD/PLDW/PLI or unallocated hint */
10882 /* UNDEF space, or an UNPREDICTABLE */
10883 return 1;
10886 memidx = get_mem_index(s);
10887 if (rn == 15) {
10888 addr = tcg_temp_new_i32();
10889 /* PC relative. */
10890 /* s->pc has already been incremented by 4. */
10891 imm = s->pc & 0xfffffffc;
10892 if (insn & (1 << 23))
10893 imm += insn & 0xfff;
10894 else
10895 imm -= insn & 0xfff;
10896 tcg_gen_movi_i32(addr, imm);
10897 } else {
10898 addr = load_reg(s, rn);
10899 if (insn & (1 << 23)) {
10900 /* Positive offset. */
10901 imm = insn & 0xfff;
10902 tcg_gen_addi_i32(addr, addr, imm);
10903 } else {
10904 imm = insn & 0xff;
10905 switch ((insn >> 8) & 0xf) {
10906 case 0x0: /* Shifted Register. */
10907 shift = (insn >> 4) & 0xf;
10908 if (shift > 3) {
10909 tcg_temp_free_i32(addr);
10910 goto illegal_op;
10912 tmp = load_reg(s, rm);
10913 if (shift)
10914 tcg_gen_shli_i32(tmp, tmp, shift);
10915 tcg_gen_add_i32(addr, addr, tmp);
10916 tcg_temp_free_i32(tmp);
10917 break;
10918 case 0xc: /* Negative offset. */
10919 tcg_gen_addi_i32(addr, addr, -imm);
10920 break;
10921 case 0xe: /* User privilege. */
10922 tcg_gen_addi_i32(addr, addr, imm);
10923 memidx = get_a32_user_mem_index(s);
10924 break;
10925 case 0x9: /* Post-decrement. */
10926 imm = -imm;
10927 /* Fall through. */
10928 case 0xb: /* Post-increment. */
10929 postinc = 1;
10930 writeback = 1;
10931 break;
10932 case 0xd: /* Pre-decrement. */
10933 imm = -imm;
10934 /* Fall through. */
10935 case 0xf: /* Pre-increment. */
10936 tcg_gen_addi_i32(addr, addr, imm);
10937 writeback = 1;
10938 break;
10939 default:
10940 tcg_temp_free_i32(addr);
10941 goto illegal_op;
10946 issinfo = writeback ? ISSInvalid : rs;
10948 if (insn & (1 << 20)) {
10949 /* Load. */
10950 tmp = tcg_temp_new_i32();
10951 switch (op) {
10952 case 0:
10953 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10954 break;
10955 case 4:
10956 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10957 break;
10958 case 1:
10959 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10960 break;
10961 case 5:
10962 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10963 break;
10964 case 2:
10965 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10966 break;
10967 default:
10968 tcg_temp_free_i32(tmp);
10969 tcg_temp_free_i32(addr);
10970 goto illegal_op;
10972 if (rs == 15) {
10973 gen_bx_excret(s, tmp);
10974 } else {
10975 store_reg(s, rs, tmp);
10977 } else {
10978 /* Store. */
10979 tmp = load_reg(s, rs);
10980 switch (op) {
10981 case 0:
10982 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10983 break;
10984 case 1:
10985 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10986 break;
10987 case 2:
10988 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10989 break;
10990 default:
10991 tcg_temp_free_i32(tmp);
10992 tcg_temp_free_i32(addr);
10993 goto illegal_op;
10995 tcg_temp_free_i32(tmp);
10997 if (postinc)
10998 tcg_gen_addi_i32(addr, addr, imm);
10999 if (writeback) {
11000 store_reg(s, rn, addr);
11001 } else {
11002 tcg_temp_free_i32(addr);
11005 break;
11006 default:
11007 goto illegal_op;
11009 return 0;
11010 illegal_op:
11011 return 1;
11014 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
11016 uint32_t val, insn, op, rm, rn, rd, shift, cond;
11017 int32_t offset;
11018 int i;
11019 TCGv_i32 tmp;
11020 TCGv_i32 tmp2;
11021 TCGv_i32 addr;
11023 if (s->condexec_mask) {
11024 cond = s->condexec_cond;
11025 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
11026 s->condlabel = gen_new_label();
11027 arm_gen_test_cc(cond ^ 1, s->condlabel);
11028 s->condjmp = 1;
11032 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11033 s->pc += 2;
11035 switch (insn >> 12) {
11036 case 0: case 1:
11038 rd = insn & 7;
11039 op = (insn >> 11) & 3;
11040 if (op == 3) {
11041 /* add/subtract */
11042 rn = (insn >> 3) & 7;
11043 tmp = load_reg(s, rn);
11044 if (insn & (1 << 10)) {
11045 /* immediate */
11046 tmp2 = tcg_temp_new_i32();
11047 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11048 } else {
11049 /* reg */
11050 rm = (insn >> 6) & 7;
11051 tmp2 = load_reg(s, rm);
11053 if (insn & (1 << 9)) {
11054 if (s->condexec_mask)
11055 tcg_gen_sub_i32(tmp, tmp, tmp2);
11056 else
11057 gen_sub_CC(tmp, tmp, tmp2);
11058 } else {
11059 if (s->condexec_mask)
11060 tcg_gen_add_i32(tmp, tmp, tmp2);
11061 else
11062 gen_add_CC(tmp, tmp, tmp2);
11064 tcg_temp_free_i32(tmp2);
11065 store_reg(s, rd, tmp);
11066 } else {
11067 /* shift immediate */
11068 rm = (insn >> 3) & 7;
11069 shift = (insn >> 6) & 0x1f;
11070 tmp = load_reg(s, rm);
11071 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11072 if (!s->condexec_mask)
11073 gen_logic_CC(tmp);
11074 store_reg(s, rd, tmp);
11076 break;
11077 case 2: case 3:
11078 /* arithmetic large immediate */
11079 op = (insn >> 11) & 3;
11080 rd = (insn >> 8) & 0x7;
11081 if (op == 0) { /* mov */
11082 tmp = tcg_temp_new_i32();
11083 tcg_gen_movi_i32(tmp, insn & 0xff);
11084 if (!s->condexec_mask)
11085 gen_logic_CC(tmp);
11086 store_reg(s, rd, tmp);
11087 } else {
11088 tmp = load_reg(s, rd);
11089 tmp2 = tcg_temp_new_i32();
11090 tcg_gen_movi_i32(tmp2, insn & 0xff);
11091 switch (op) {
11092 case 1: /* cmp */
11093 gen_sub_CC(tmp, tmp, tmp2);
11094 tcg_temp_free_i32(tmp);
11095 tcg_temp_free_i32(tmp2);
11096 break;
11097 case 2: /* add */
11098 if (s->condexec_mask)
11099 tcg_gen_add_i32(tmp, tmp, tmp2);
11100 else
11101 gen_add_CC(tmp, tmp, tmp2);
11102 tcg_temp_free_i32(tmp2);
11103 store_reg(s, rd, tmp);
11104 break;
11105 case 3: /* sub */
11106 if (s->condexec_mask)
11107 tcg_gen_sub_i32(tmp, tmp, tmp2);
11108 else
11109 gen_sub_CC(tmp, tmp, tmp2);
11110 tcg_temp_free_i32(tmp2);
11111 store_reg(s, rd, tmp);
11112 break;
11115 break;
11116 case 4:
11117 if (insn & (1 << 11)) {
11118 rd = (insn >> 8) & 7;
11119 /* load pc-relative. Bit 1 of PC is ignored. */
11120 val = s->pc + 2 + ((insn & 0xff) * 4);
11121 val &= ~(uint32_t)2;
11122 addr = tcg_temp_new_i32();
11123 tcg_gen_movi_i32(addr, val);
11124 tmp = tcg_temp_new_i32();
11125 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11126 rd | ISSIs16Bit);
11127 tcg_temp_free_i32(addr);
11128 store_reg(s, rd, tmp);
11129 break;
11131 if (insn & (1 << 10)) {
11132 /* data processing extended or blx */
11133 rd = (insn & 7) | ((insn >> 4) & 8);
11134 rm = (insn >> 3) & 0xf;
11135 op = (insn >> 8) & 3;
11136 switch (op) {
11137 case 0: /* add */
11138 tmp = load_reg(s, rd);
11139 tmp2 = load_reg(s, rm);
11140 tcg_gen_add_i32(tmp, tmp, tmp2);
11141 tcg_temp_free_i32(tmp2);
11142 store_reg(s, rd, tmp);
11143 break;
11144 case 1: /* cmp */
11145 tmp = load_reg(s, rd);
11146 tmp2 = load_reg(s, rm);
11147 gen_sub_CC(tmp, tmp, tmp2);
11148 tcg_temp_free_i32(tmp2);
11149 tcg_temp_free_i32(tmp);
11150 break;
11151 case 2: /* mov/cpy */
11152 tmp = load_reg(s, rm);
11153 store_reg(s, rd, tmp);
11154 break;
11155 case 3:/* branch [and link] exchange thumb register */
11156 tmp = load_reg(s, rm);
11157 if (insn & (1 << 7)) {
11158 ARCH(5);
11159 val = (uint32_t)s->pc | 1;
11160 tmp2 = tcg_temp_new_i32();
11161 tcg_gen_movi_i32(tmp2, val);
11162 store_reg(s, 14, tmp2);
11163 gen_bx(s, tmp);
11164 } else {
11165 /* Only BX works as exception-return, not BLX */
11166 gen_bx_excret(s, tmp);
11168 break;
11170 break;
11173 /* data processing register */
11174 rd = insn & 7;
11175 rm = (insn >> 3) & 7;
11176 op = (insn >> 6) & 0xf;
11177 if (op == 2 || op == 3 || op == 4 || op == 7) {
11178 /* the shift/rotate ops want the operands backwards */
11179 val = rm;
11180 rm = rd;
11181 rd = val;
11182 val = 1;
11183 } else {
11184 val = 0;
11187 if (op == 9) { /* neg */
11188 tmp = tcg_temp_new_i32();
11189 tcg_gen_movi_i32(tmp, 0);
11190 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11191 tmp = load_reg(s, rd);
11192 } else {
11193 TCGV_UNUSED_I32(tmp);
11196 tmp2 = load_reg(s, rm);
11197 switch (op) {
11198 case 0x0: /* and */
11199 tcg_gen_and_i32(tmp, tmp, tmp2);
11200 if (!s->condexec_mask)
11201 gen_logic_CC(tmp);
11202 break;
11203 case 0x1: /* eor */
11204 tcg_gen_xor_i32(tmp, tmp, tmp2);
11205 if (!s->condexec_mask)
11206 gen_logic_CC(tmp);
11207 break;
11208 case 0x2: /* lsl */
11209 if (s->condexec_mask) {
11210 gen_shl(tmp2, tmp2, tmp);
11211 } else {
11212 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11213 gen_logic_CC(tmp2);
11215 break;
11216 case 0x3: /* lsr */
11217 if (s->condexec_mask) {
11218 gen_shr(tmp2, tmp2, tmp);
11219 } else {
11220 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11221 gen_logic_CC(tmp2);
11223 break;
11224 case 0x4: /* asr */
11225 if (s->condexec_mask) {
11226 gen_sar(tmp2, tmp2, tmp);
11227 } else {
11228 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11229 gen_logic_CC(tmp2);
11231 break;
11232 case 0x5: /* adc */
11233 if (s->condexec_mask) {
11234 gen_adc(tmp, tmp2);
11235 } else {
11236 gen_adc_CC(tmp, tmp, tmp2);
11238 break;
11239 case 0x6: /* sbc */
11240 if (s->condexec_mask) {
11241 gen_sub_carry(tmp, tmp, tmp2);
11242 } else {
11243 gen_sbc_CC(tmp, tmp, tmp2);
11245 break;
11246 case 0x7: /* ror */
11247 if (s->condexec_mask) {
11248 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11249 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11250 } else {
11251 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11252 gen_logic_CC(tmp2);
11254 break;
11255 case 0x8: /* tst */
11256 tcg_gen_and_i32(tmp, tmp, tmp2);
11257 gen_logic_CC(tmp);
11258 rd = 16;
11259 break;
11260 case 0x9: /* neg */
11261 if (s->condexec_mask)
11262 tcg_gen_neg_i32(tmp, tmp2);
11263 else
11264 gen_sub_CC(tmp, tmp, tmp2);
11265 break;
11266 case 0xa: /* cmp */
11267 gen_sub_CC(tmp, tmp, tmp2);
11268 rd = 16;
11269 break;
11270 case 0xb: /* cmn */
11271 gen_add_CC(tmp, tmp, tmp2);
11272 rd = 16;
11273 break;
11274 case 0xc: /* orr */
11275 tcg_gen_or_i32(tmp, tmp, tmp2);
11276 if (!s->condexec_mask)
11277 gen_logic_CC(tmp);
11278 break;
11279 case 0xd: /* mul */
11280 tcg_gen_mul_i32(tmp, tmp, tmp2);
11281 if (!s->condexec_mask)
11282 gen_logic_CC(tmp);
11283 break;
11284 case 0xe: /* bic */
11285 tcg_gen_andc_i32(tmp, tmp, tmp2);
11286 if (!s->condexec_mask)
11287 gen_logic_CC(tmp);
11288 break;
11289 case 0xf: /* mvn */
11290 tcg_gen_not_i32(tmp2, tmp2);
11291 if (!s->condexec_mask)
11292 gen_logic_CC(tmp2);
11293 val = 1;
11294 rm = rd;
11295 break;
11297 if (rd != 16) {
11298 if (val) {
11299 store_reg(s, rm, tmp2);
11300 if (op != 0xf)
11301 tcg_temp_free_i32(tmp);
11302 } else {
11303 store_reg(s, rd, tmp);
11304 tcg_temp_free_i32(tmp2);
11306 } else {
11307 tcg_temp_free_i32(tmp);
11308 tcg_temp_free_i32(tmp2);
11310 break;
11312 case 5:
11313 /* load/store register offset. */
11314 rd = insn & 7;
11315 rn = (insn >> 3) & 7;
11316 rm = (insn >> 6) & 7;
11317 op = (insn >> 9) & 7;
11318 addr = load_reg(s, rn);
11319 tmp = load_reg(s, rm);
11320 tcg_gen_add_i32(addr, addr, tmp);
11321 tcg_temp_free_i32(tmp);
11323 if (op < 3) { /* store */
11324 tmp = load_reg(s, rd);
11325 } else {
11326 tmp = tcg_temp_new_i32();
11329 switch (op) {
11330 case 0: /* str */
11331 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11332 break;
11333 case 1: /* strh */
11334 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11335 break;
11336 case 2: /* strb */
11337 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11338 break;
11339 case 3: /* ldrsb */
11340 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11341 break;
11342 case 4: /* ldr */
11343 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11344 break;
11345 case 5: /* ldrh */
11346 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11347 break;
11348 case 6: /* ldrb */
11349 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11350 break;
11351 case 7: /* ldrsh */
11352 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11353 break;
11355 if (op >= 3) { /* load */
11356 store_reg(s, rd, tmp);
11357 } else {
11358 tcg_temp_free_i32(tmp);
11360 tcg_temp_free_i32(addr);
11361 break;
11363 case 6:
11364 /* load/store word immediate offset */
11365 rd = insn & 7;
11366 rn = (insn >> 3) & 7;
11367 addr = load_reg(s, rn);
11368 val = (insn >> 4) & 0x7c;
11369 tcg_gen_addi_i32(addr, addr, val);
11371 if (insn & (1 << 11)) {
11372 /* load */
11373 tmp = tcg_temp_new_i32();
11374 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11375 store_reg(s, rd, tmp);
11376 } else {
11377 /* store */
11378 tmp = load_reg(s, rd);
11379 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11380 tcg_temp_free_i32(tmp);
11382 tcg_temp_free_i32(addr);
11383 break;
11385 case 7:
11386 /* load/store byte immediate offset */
11387 rd = insn & 7;
11388 rn = (insn >> 3) & 7;
11389 addr = load_reg(s, rn);
11390 val = (insn >> 6) & 0x1f;
11391 tcg_gen_addi_i32(addr, addr, val);
11393 if (insn & (1 << 11)) {
11394 /* load */
11395 tmp = tcg_temp_new_i32();
11396 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11397 store_reg(s, rd, tmp);
11398 } else {
11399 /* store */
11400 tmp = load_reg(s, rd);
11401 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11402 tcg_temp_free_i32(tmp);
11404 tcg_temp_free_i32(addr);
11405 break;
11407 case 8:
11408 /* load/store halfword immediate offset */
11409 rd = insn & 7;
11410 rn = (insn >> 3) & 7;
11411 addr = load_reg(s, rn);
11412 val = (insn >> 5) & 0x3e;
11413 tcg_gen_addi_i32(addr, addr, val);
11415 if (insn & (1 << 11)) {
11416 /* load */
11417 tmp = tcg_temp_new_i32();
11418 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11419 store_reg(s, rd, tmp);
11420 } else {
11421 /* store */
11422 tmp = load_reg(s, rd);
11423 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11424 tcg_temp_free_i32(tmp);
11426 tcg_temp_free_i32(addr);
11427 break;
11429 case 9:
11430 /* load/store from stack */
11431 rd = (insn >> 8) & 7;
11432 addr = load_reg(s, 13);
11433 val = (insn & 0xff) * 4;
11434 tcg_gen_addi_i32(addr, addr, val);
11436 if (insn & (1 << 11)) {
11437 /* load */
11438 tmp = tcg_temp_new_i32();
11439 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11440 store_reg(s, rd, tmp);
11441 } else {
11442 /* store */
11443 tmp = load_reg(s, rd);
11444 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11445 tcg_temp_free_i32(tmp);
11447 tcg_temp_free_i32(addr);
11448 break;
11450 case 10:
11451 /* add to high reg */
11452 rd = (insn >> 8) & 7;
11453 if (insn & (1 << 11)) {
11454 /* SP */
11455 tmp = load_reg(s, 13);
11456 } else {
11457 /* PC. bit 1 is ignored. */
11458 tmp = tcg_temp_new_i32();
11459 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11461 val = (insn & 0xff) * 4;
11462 tcg_gen_addi_i32(tmp, tmp, val);
11463 store_reg(s, rd, tmp);
11464 break;
11466 case 11:
11467 /* misc */
11468 op = (insn >> 8) & 0xf;
11469 switch (op) {
11470 case 0:
11471 /* adjust stack pointer */
11472 tmp = load_reg(s, 13);
11473 val = (insn & 0x7f) * 4;
11474 if (insn & (1 << 7))
11475 val = -(int32_t)val;
11476 tcg_gen_addi_i32(tmp, tmp, val);
11477 store_reg(s, 13, tmp);
11478 break;
11480 case 2: /* sign/zero extend. */
11481 ARCH(6);
11482 rd = insn & 7;
11483 rm = (insn >> 3) & 7;
11484 tmp = load_reg(s, rm);
11485 switch ((insn >> 6) & 3) {
11486 case 0: gen_sxth(tmp); break;
11487 case 1: gen_sxtb(tmp); break;
11488 case 2: gen_uxth(tmp); break;
11489 case 3: gen_uxtb(tmp); break;
11491 store_reg(s, rd, tmp);
11492 break;
11493 case 4: case 5: case 0xc: case 0xd:
11494 /* push/pop */
11495 addr = load_reg(s, 13);
11496 if (insn & (1 << 8))
11497 offset = 4;
11498 else
11499 offset = 0;
11500 for (i = 0; i < 8; i++) {
11501 if (insn & (1 << i))
11502 offset += 4;
11504 if ((insn & (1 << 11)) == 0) {
11505 tcg_gen_addi_i32(addr, addr, -offset);
11507 for (i = 0; i < 8; i++) {
11508 if (insn & (1 << i)) {
11509 if (insn & (1 << 11)) {
11510 /* pop */
11511 tmp = tcg_temp_new_i32();
11512 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11513 store_reg(s, i, tmp);
11514 } else {
11515 /* push */
11516 tmp = load_reg(s, i);
11517 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11518 tcg_temp_free_i32(tmp);
11520 /* advance to the next address. */
11521 tcg_gen_addi_i32(addr, addr, 4);
11524 TCGV_UNUSED_I32(tmp);
11525 if (insn & (1 << 8)) {
11526 if (insn & (1 << 11)) {
11527 /* pop pc */
11528 tmp = tcg_temp_new_i32();
11529 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11530 /* don't set the pc until the rest of the instruction
11531 has completed */
11532 } else {
11533 /* push lr */
11534 tmp = load_reg(s, 14);
11535 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11536 tcg_temp_free_i32(tmp);
11538 tcg_gen_addi_i32(addr, addr, 4);
11540 if ((insn & (1 << 11)) == 0) {
11541 tcg_gen_addi_i32(addr, addr, -offset);
11543 /* write back the new stack pointer */
11544 store_reg(s, 13, addr);
11545 /* set the new PC value */
11546 if ((insn & 0x0900) == 0x0900) {
11547 store_reg_from_load(s, 15, tmp);
11549 break;
11551 case 1: case 3: case 9: case 11: /* czb */
11552 rm = insn & 7;
11553 tmp = load_reg(s, rm);
11554 s->condlabel = gen_new_label();
11555 s->condjmp = 1;
11556 if (insn & (1 << 11))
11557 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11558 else
11559 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11560 tcg_temp_free_i32(tmp);
11561 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11562 val = (uint32_t)s->pc + 2;
11563 val += offset;
11564 gen_jmp(s, val);
11565 break;
11567 case 15: /* IT, nop-hint. */
11568 if ((insn & 0xf) == 0) {
11569 gen_nop_hint(s, (insn >> 4) & 0xf);
11570 break;
11572 /* If Then. */
11573 s->condexec_cond = (insn >> 4) & 0xe;
11574 s->condexec_mask = insn & 0x1f;
11575 /* No actual code generated for this insn, just setup state. */
11576 break;
11578 case 0xe: /* bkpt */
11580 int imm8 = extract32(insn, 0, 8);
11581 ARCH(5);
11582 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11583 default_exception_el(s));
11584 break;
11587 case 0xa: /* rev, and hlt */
11589 int op1 = extract32(insn, 6, 2);
11591 if (op1 == 2) {
11592 /* HLT */
11593 int imm6 = extract32(insn, 0, 6);
11595 gen_hlt(s, imm6);
11596 break;
11599 /* Otherwise this is rev */
11600 ARCH(6);
11601 rn = (insn >> 3) & 0x7;
11602 rd = insn & 0x7;
11603 tmp = load_reg(s, rn);
11604 switch (op1) {
11605 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11606 case 1: gen_rev16(tmp); break;
11607 case 3: gen_revsh(tmp); break;
11608 default:
11609 g_assert_not_reached();
11611 store_reg(s, rd, tmp);
11612 break;
11615 case 6:
11616 switch ((insn >> 5) & 7) {
11617 case 2:
11618 /* setend */
11619 ARCH(6);
11620 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11621 gen_helper_setend(cpu_env);
11622 s->is_jmp = DISAS_UPDATE;
11624 break;
11625 case 3:
11626 /* cps */
11627 ARCH(6);
11628 if (IS_USER(s)) {
11629 break;
11631 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11632 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11633 /* FAULTMASK */
11634 if (insn & 1) {
11635 addr = tcg_const_i32(19);
11636 gen_helper_v7m_msr(cpu_env, addr, tmp);
11637 tcg_temp_free_i32(addr);
11639 /* PRIMASK */
11640 if (insn & 2) {
11641 addr = tcg_const_i32(16);
11642 gen_helper_v7m_msr(cpu_env, addr, tmp);
11643 tcg_temp_free_i32(addr);
11645 tcg_temp_free_i32(tmp);
11646 gen_lookup_tb(s);
11647 } else {
11648 if (insn & (1 << 4)) {
11649 shift = CPSR_A | CPSR_I | CPSR_F;
11650 } else {
11651 shift = 0;
11653 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11655 break;
11656 default:
11657 goto undef;
11659 break;
11661 default:
11662 goto undef;
11664 break;
11666 case 12:
11668 /* load/store multiple */
11669 TCGv_i32 loaded_var;
11670 TCGV_UNUSED_I32(loaded_var);
11671 rn = (insn >> 8) & 0x7;
11672 addr = load_reg(s, rn);
11673 for (i = 0; i < 8; i++) {
11674 if (insn & (1 << i)) {
11675 if (insn & (1 << 11)) {
11676 /* load */
11677 tmp = tcg_temp_new_i32();
11678 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11679 if (i == rn) {
11680 loaded_var = tmp;
11681 } else {
11682 store_reg(s, i, tmp);
11684 } else {
11685 /* store */
11686 tmp = load_reg(s, i);
11687 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11688 tcg_temp_free_i32(tmp);
11690 /* advance to the next address */
11691 tcg_gen_addi_i32(addr, addr, 4);
11694 if ((insn & (1 << rn)) == 0) {
11695 /* base reg not in list: base register writeback */
11696 store_reg(s, rn, addr);
11697 } else {
11698 /* base reg in list: if load, complete it now */
11699 if (insn & (1 << 11)) {
11700 store_reg(s, rn, loaded_var);
11702 tcg_temp_free_i32(addr);
11704 break;
11706 case 13:
11707 /* conditional branch or swi */
11708 cond = (insn >> 8) & 0xf;
11709 if (cond == 0xe)
11710 goto undef;
11712 if (cond == 0xf) {
11713 /* swi */
11714 gen_set_pc_im(s, s->pc);
11715 s->svc_imm = extract32(insn, 0, 8);
11716 s->is_jmp = DISAS_SWI;
11717 break;
11719 /* generate a conditional jump to next instruction */
11720 s->condlabel = gen_new_label();
11721 arm_gen_test_cc(cond ^ 1, s->condlabel);
11722 s->condjmp = 1;
11724 /* jump to the offset */
11725 val = (uint32_t)s->pc + 2;
11726 offset = ((int32_t)insn << 24) >> 24;
11727 val += offset << 1;
11728 gen_jmp(s, val);
11729 break;
11731 case 14:
11732 if (insn & (1 << 11)) {
11733 if (disas_thumb2_insn(env, s, insn))
11734 goto undef32;
11735 break;
11737 /* unconditional branch */
11738 val = (uint32_t)s->pc;
11739 offset = ((int32_t)insn << 21) >> 21;
11740 val += (offset << 1) + 2;
11741 gen_jmp(s, val);
11742 break;
11744 case 15:
11745 if (disas_thumb2_insn(env, s, insn))
11746 goto undef32;
11747 break;
11749 return;
11750 undef32:
11751 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11752 default_exception_el(s));
11753 return;
11754 illegal_op:
11755 undef:
11756 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11757 default_exception_el(s));
11760 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11762 /* Return true if the insn at dc->pc might cross a page boundary.
11763 * (False positives are OK, false negatives are not.)
11765 uint16_t insn;
11767 if ((s->pc & 3) == 0) {
11768 /* At a 4-aligned address we can't be crossing a page */
11769 return false;
11772 /* This must be a Thumb insn */
11773 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11775 if ((insn >> 11) >= 0x1d) {
11776 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11777 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11778 * end up actually treating this as two 16-bit insns (see the
11779 * code at the start of disas_thumb2_insn()) but we don't bother
11780 * to check for that as it is unlikely, and false positives here
11781 * are harmless.
11783 return true;
11785 /* Definitely a 16-bit insn, can't be crossing a page. */
11786 return false;
11789 /* generate intermediate code for basic block 'tb'. */
11790 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11792 ARMCPU *cpu = arm_env_get_cpu(env);
11793 CPUState *cs = CPU(cpu);
11794 DisasContext dc1, *dc = &dc1;
11795 target_ulong pc_start;
11796 target_ulong next_page_start;
11797 int num_insns;
11798 int max_insns;
11799 bool end_of_page;
11801 /* generate intermediate code */
11803 /* The A64 decoder has its own top level loop, because it doesn't need
11804 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11806 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11807 gen_intermediate_code_a64(cpu, tb);
11808 return;
11811 pc_start = tb->pc;
11813 dc->tb = tb;
11815 dc->is_jmp = DISAS_NEXT;
11816 dc->pc = pc_start;
11817 dc->singlestep_enabled = cs->singlestep_enabled;
11818 dc->condjmp = 0;
11820 dc->aarch64 = 0;
11821 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11822 * there is no secure EL1, so we route exceptions to EL3.
11824 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11825 !arm_el_is_aa64(env, 3);
11826 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11827 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11828 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11829 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11830 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11831 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
11832 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11833 #if !defined(CONFIG_USER_ONLY)
11834 dc->user = (dc->current_el == 0);
11835 #endif
11836 dc->ns = ARM_TBFLAG_NS(tb->flags);
11837 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11838 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11839 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11840 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11841 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11842 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags);
11843 dc->cp_regs = cpu->cp_regs;
11844 dc->features = env->features;
11846 /* Single step state. The code-generation logic here is:
11847 * SS_ACTIVE == 0:
11848 * generate code with no special handling for single-stepping (except
11849 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11850 * this happens anyway because those changes are all system register or
11851 * PSTATE writes).
11852 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11853 * emit code for one insn
11854 * emit code to clear PSTATE.SS
11855 * emit code to generate software step exception for completed step
11856 * end TB (as usual for having generated an exception)
11857 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11858 * emit code to generate a software step exception
11859 * end the TB
11861 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11862 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11863 dc->is_ldex = false;
11864 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11866 cpu_F0s = tcg_temp_new_i32();
11867 cpu_F1s = tcg_temp_new_i32();
11868 cpu_F0d = tcg_temp_new_i64();
11869 cpu_F1d = tcg_temp_new_i64();
11870 cpu_V0 = cpu_F0d;
11871 cpu_V1 = cpu_F1d;
11872 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11873 cpu_M0 = tcg_temp_new_i64();
11874 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11875 num_insns = 0;
11876 max_insns = tb->cflags & CF_COUNT_MASK;
11877 if (max_insns == 0) {
11878 max_insns = CF_COUNT_MASK;
11880 if (max_insns > TCG_MAX_INSNS) {
11881 max_insns = TCG_MAX_INSNS;
11884 gen_tb_start(tb);
11886 tcg_clear_temp_count();
11888 /* A note on handling of the condexec (IT) bits:
11890 * We want to avoid the overhead of having to write the updated condexec
11891 * bits back to the CPUARMState for every instruction in an IT block. So:
11892 * (1) if the condexec bits are not already zero then we write
11893 * zero back into the CPUARMState now. This avoids complications trying
11894 * to do it at the end of the block. (For example if we don't do this
11895 * it's hard to identify whether we can safely skip writing condexec
11896 * at the end of the TB, which we definitely want to do for the case
11897 * where a TB doesn't do anything with the IT state at all.)
11898 * (2) if we are going to leave the TB then we call gen_set_condexec()
11899 * which will write the correct value into CPUARMState if zero is wrong.
11900 * This is done both for leaving the TB at the end, and for leaving
11901 * it because of an exception we know will happen, which is done in
11902 * gen_exception_insn(). The latter is necessary because we need to
11903 * leave the TB with the PC/IT state just prior to execution of the
11904 * instruction which caused the exception.
11905 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11906 * then the CPUARMState will be wrong and we need to reset it.
11907 * This is handled in the same way as restoration of the
11908 * PC in these situations; we save the value of the condexec bits
11909 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11910 * then uses this to restore them after an exception.
11912 * Note that there are no instructions which can read the condexec
11913 * bits, and none which can write non-static values to them, so
11914 * we don't need to care about whether CPUARMState is correct in the
11915 * middle of a TB.
11918 /* Reset the conditional execution bits immediately. This avoids
11919 complications trying to do it at the end of the block. */
11920 if (dc->condexec_mask || dc->condexec_cond)
11922 TCGv_i32 tmp = tcg_temp_new_i32();
11923 tcg_gen_movi_i32(tmp, 0);
11924 store_cpu_field(tmp, condexec_bits);
11926 do {
11927 dc->insn_start_idx = tcg_op_buf_count();
11928 tcg_gen_insn_start(dc->pc,
11929 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11931 num_insns++;
11933 #ifdef CONFIG_USER_ONLY
11934 /* Intercept jump to the magic kernel page. */
11935 if (dc->pc >= 0xffff0000) {
11936 /* We always get here via a jump, so know we are not in a
11937 conditional execution block. */
11938 gen_exception_internal(EXCP_KERNEL_TRAP);
11939 dc->is_jmp = DISAS_EXC;
11940 break;
11942 #endif
11944 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11945 CPUBreakpoint *bp;
11946 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11947 if (bp->pc == dc->pc) {
11948 if (bp->flags & BP_CPU) {
11949 gen_set_condexec(dc);
11950 gen_set_pc_im(dc, dc->pc);
11951 gen_helper_check_breakpoints(cpu_env);
11952 /* End the TB early; it's likely not going to be executed */
11953 dc->is_jmp = DISAS_UPDATE;
11954 } else {
11955 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11956 /* The address covered by the breakpoint must be
11957 included in [tb->pc, tb->pc + tb->size) in order
11958 to for it to be properly cleared -- thus we
11959 increment the PC here so that the logic setting
11960 tb->size below does the right thing. */
11961 /* TODO: Advance PC by correct instruction length to
11962 * avoid disassembler error messages */
11963 dc->pc += 2;
11964 goto done_generating;
11966 break;
11971 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11972 gen_io_start();
11975 if (dc->ss_active && !dc->pstate_ss) {
11976 /* Singlestep state is Active-pending.
11977 * If we're in this state at the start of a TB then either
11978 * a) we just took an exception to an EL which is being debugged
11979 * and this is the first insn in the exception handler
11980 * b) debug exceptions were masked and we just unmasked them
11981 * without changing EL (eg by clearing PSTATE.D)
11982 * In either case we're going to take a swstep exception in the
11983 * "did not step an insn" case, and so the syndrome ISV and EX
11984 * bits should be zero.
11986 assert(num_insns == 1);
11987 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11988 default_exception_el(dc));
11989 goto done_generating;
11992 if (dc->thumb) {
11993 disas_thumb_insn(env, dc);
11994 if (dc->condexec_mask) {
11995 dc->condexec_cond = (dc->condexec_cond & 0xe)
11996 | ((dc->condexec_mask >> 4) & 1);
11997 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11998 if (dc->condexec_mask == 0) {
11999 dc->condexec_cond = 0;
12002 } else {
12003 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12004 dc->pc += 4;
12005 disas_arm_insn(dc, insn);
12008 if (dc->condjmp && !dc->is_jmp) {
12009 gen_set_label(dc->condlabel);
12010 dc->condjmp = 0;
12013 if (tcg_check_temp_count()) {
12014 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
12015 dc->pc);
12018 /* Translation stops when a conditional branch is encountered.
12019 * Otherwise the subsequent code could get translated several times.
12020 * Also stop translation when a page boundary is reached. This
12021 * ensures prefetch aborts occur at the right place. */
12023 /* We want to stop the TB if the next insn starts in a new page,
12024 * or if it spans between this page and the next. This means that
12025 * if we're looking at the last halfword in the page we need to
12026 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12027 * or a 32-bit Thumb insn (which won't).
12028 * This is to avoid generating a silly TB with a single 16-bit insn
12029 * in it at the end of this page (which would execute correctly
12030 * but isn't very efficient).
12032 end_of_page = (dc->pc >= next_page_start) ||
12033 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
12035 } while (!dc->is_jmp && !tcg_op_buf_full() &&
12036 !is_singlestepping(dc) &&
12037 !singlestep &&
12038 !end_of_page &&
12039 num_insns < max_insns);
12041 if (tb->cflags & CF_LAST_IO) {
12042 if (dc->condjmp) {
12043 /* FIXME: This can theoretically happen with self-modifying
12044 code. */
12045 cpu_abort(cs, "IO on conditional branch instruction");
12047 gen_io_end();
12050 /* At this stage dc->condjmp will only be set when the skipped
12051 instruction was a conditional branch or trap, and the PC has
12052 already been written. */
12053 gen_set_condexec(dc);
12054 if (dc->is_jmp == DISAS_BX_EXCRET) {
12055 /* Exception return branches need some special case code at the
12056 * end of the TB, which is complex enough that it has to
12057 * handle the single-step vs not and the condition-failed
12058 * insn codepath itself.
12060 gen_bx_excret_final_code(dc);
12061 } else if (unlikely(is_singlestepping(dc))) {
12062 /* Unconditional and "condition passed" instruction codepath. */
12063 switch (dc->is_jmp) {
12064 case DISAS_SWI:
12065 gen_ss_advance(dc);
12066 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12067 default_exception_el(dc));
12068 break;
12069 case DISAS_HVC:
12070 gen_ss_advance(dc);
12071 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12072 break;
12073 case DISAS_SMC:
12074 gen_ss_advance(dc);
12075 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12076 break;
12077 case DISAS_NEXT:
12078 case DISAS_UPDATE:
12079 gen_set_pc_im(dc, dc->pc);
12080 /* fall through */
12081 default:
12082 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12083 gen_singlestep_exception(dc);
12085 } else {
12086 /* While branches must always occur at the end of an IT block,
12087 there are a few other things that can cause us to terminate
12088 the TB in the middle of an IT block:
12089 - Exception generating instructions (bkpt, swi, undefined).
12090 - Page boundaries.
12091 - Hardware watchpoints.
12092 Hardware breakpoints have already been handled and skip this code.
12094 switch(dc->is_jmp) {
12095 case DISAS_NEXT:
12096 gen_goto_tb(dc, 1, dc->pc);
12097 break;
12098 case DISAS_UPDATE:
12099 gen_set_pc_im(dc, dc->pc);
12100 /* fall through */
12101 case DISAS_JUMP:
12102 gen_goto_ptr();
12103 break;
12104 default:
12105 /* indicate that the hash table must be used to find the next TB */
12106 tcg_gen_exit_tb(0);
12107 break;
12108 case DISAS_TB_JUMP:
12109 case DISAS_EXC:
12110 /* nothing more to generate */
12111 break;
12112 case DISAS_WFI:
12113 gen_helper_wfi(cpu_env);
12114 /* The helper doesn't necessarily throw an exception, but we
12115 * must go back to the main loop to check for interrupts anyway.
12117 tcg_gen_exit_tb(0);
12118 break;
12119 case DISAS_WFE:
12120 gen_helper_wfe(cpu_env);
12121 break;
12122 case DISAS_YIELD:
12123 gen_helper_yield(cpu_env);
12124 break;
12125 case DISAS_SWI:
12126 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12127 default_exception_el(dc));
12128 break;
12129 case DISAS_HVC:
12130 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12131 break;
12132 case DISAS_SMC:
12133 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12134 break;
12138 if (dc->condjmp) {
12139 /* "Condition failed" instruction codepath for the branch/trap insn */
12140 gen_set_label(dc->condlabel);
12141 gen_set_condexec(dc);
12142 if (unlikely(is_singlestepping(dc))) {
12143 gen_set_pc_im(dc, dc->pc);
12144 gen_singlestep_exception(dc);
12145 } else {
12146 gen_goto_tb(dc, 1, dc->pc);
12150 done_generating:
12151 gen_tb_end(tb, num_insns);
12153 #ifdef DEBUG_DISAS
12154 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
12155 qemu_log_in_addr_range(pc_start)) {
12156 qemu_log_lock();
12157 qemu_log("----------------\n");
12158 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12159 log_target_disas(cs, pc_start, dc->pc - pc_start,
12160 dc->thumb | (dc->sctlr_b << 1));
12161 qemu_log("\n");
12162 qemu_log_unlock();
12164 #endif
12165 tb->size = dc->pc - pc_start;
12166 tb->icount = num_insns;
12169 static const char *cpu_mode_names[16] = {
12170 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12171 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12174 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12175 int flags)
12177 ARMCPU *cpu = ARM_CPU(cs);
12178 CPUARMState *env = &cpu->env;
12179 int i;
12180 uint32_t psr;
12181 const char *ns_status;
12183 if (is_a64(env)) {
12184 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12185 return;
12188 for(i=0;i<16;i++) {
12189 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12190 if ((i % 4) == 3)
12191 cpu_fprintf(f, "\n");
12192 else
12193 cpu_fprintf(f, " ");
12195 psr = cpsr_read(env);
12197 if (arm_feature(env, ARM_FEATURE_EL3) &&
12198 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12199 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12200 } else {
12201 ns_status = "";
12204 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12205 psr,
12206 psr & (1 << 31) ? 'N' : '-',
12207 psr & (1 << 30) ? 'Z' : '-',
12208 psr & (1 << 29) ? 'C' : '-',
12209 psr & (1 << 28) ? 'V' : '-',
12210 psr & CPSR_T ? 'T' : 'A',
12211 ns_status,
12212 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12214 if (flags & CPU_DUMP_FPU) {
12215 int numvfpregs = 0;
12216 if (arm_feature(env, ARM_FEATURE_VFP)) {
12217 numvfpregs += 16;
12219 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12220 numvfpregs += 16;
12222 for (i = 0; i < numvfpregs; i++) {
12223 uint64_t v = float64_val(env->vfp.regs[i]);
12224 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12225 i * 2, (uint32_t)v,
12226 i * 2 + 1, (uint32_t)(v >> 32),
12227 i, v);
12229 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12233 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12234 target_ulong *data)
12236 if (is_a64(env)) {
12237 env->pc = data[0];
12238 env->condexec_bits = 0;
12239 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12240 } else {
12241 env->regs[15] = data[0];
12242 env->condexec_bits = data[1];
12243 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;