target-arm: Don't check for "Thumb2 or M profile" for not-Thumb1
[qemu/kevin.git] / target / arm / translate.c
blob530a5c4ac0ecc9d8a3e64cb8b4b9a7f4f8603ead
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 arm_dc_feature(s, ARM_FEATURE_JAZELLE)
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_MSUser:
169 case ARMMMUIdx_MSPriv:
170 case ARMMMUIdx_MSNegPri:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
172 case ARMMMUIdx_S2NS:
173 default:
174 g_assert_not_reached();
178 static inline TCGv_i32 load_cpu_offset(int offset)
180 TCGv_i32 tmp = tcg_temp_new_i32();
181 tcg_gen_ld_i32(tmp, cpu_env, offset);
182 return tmp;
185 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
187 static inline void store_cpu_offset(TCGv_i32 var, int offset)
189 tcg_gen_st_i32(var, cpu_env, offset);
190 tcg_temp_free_i32(var);
193 #define store_cpu_field(var, name) \
194 store_cpu_offset(var, offsetof(CPUARMState, name))
196 /* Set a variable to the value of a CPU register. */
197 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
199 if (reg == 15) {
200 uint32_t addr;
201 /* normally, since we updated PC, we need only to add one insn */
202 if (s->thumb)
203 addr = (long)s->pc + 2;
204 else
205 addr = (long)s->pc + 4;
206 tcg_gen_movi_i32(var, addr);
207 } else {
208 tcg_gen_mov_i32(var, cpu_R[reg]);
212 /* Create a new temporary and set it to the value of a CPU register. */
213 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
215 TCGv_i32 tmp = tcg_temp_new_i32();
216 load_reg_var(s, tmp, reg);
217 return tmp;
220 /* Set a CPU register. The source must be a temporary and will be
221 marked as dead. */
222 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
224 if (reg == 15) {
225 /* In Thumb mode, we must ignore bit 0.
226 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
227 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
228 * We choose to ignore [1:0] in ARM mode for all architecture versions.
230 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
231 s->base.is_jmp = DISAS_JUMP;
233 tcg_gen_mov_i32(cpu_R[reg], var);
234 tcg_temp_free_i32(var);
237 /* Value extensions. */
238 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
239 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
240 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
241 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
243 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
244 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
247 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
249 TCGv_i32 tmp_mask = tcg_const_i32(mask);
250 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
251 tcg_temp_free_i32(tmp_mask);
253 /* Set NZCV flags from the high 4 bits of var. */
254 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
256 static void gen_exception_internal(int excp)
258 TCGv_i32 tcg_excp = tcg_const_i32(excp);
260 assert(excp_is_internal(excp));
261 gen_helper_exception_internal(cpu_env, tcg_excp);
262 tcg_temp_free_i32(tcg_excp);
265 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
267 TCGv_i32 tcg_excp = tcg_const_i32(excp);
268 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
269 TCGv_i32 tcg_el = tcg_const_i32(target_el);
271 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
272 tcg_syn, tcg_el);
274 tcg_temp_free_i32(tcg_el);
275 tcg_temp_free_i32(tcg_syn);
276 tcg_temp_free_i32(tcg_excp);
279 static void gen_ss_advance(DisasContext *s)
281 /* If the singlestep state is Active-not-pending, advance to
282 * Active-pending.
284 if (s->ss_active) {
285 s->pstate_ss = 0;
286 gen_helper_clear_pstate_ss(cpu_env);
290 static void gen_step_complete_exception(DisasContext *s)
292 /* We just completed step of an insn. Move from Active-not-pending
293 * to Active-pending, and then also take the swstep exception.
294 * This corresponds to making the (IMPDEF) choice to prioritize
295 * swstep exceptions over asynchronous exceptions taken to an exception
296 * level where debug is disabled. This choice has the advantage that
297 * we do not need to maintain internal state corresponding to the
298 * ISV/EX syndrome bits between completion of the step and generation
299 * of the exception, and our syndrome information is always correct.
301 gen_ss_advance(s);
302 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
303 default_exception_el(s));
304 s->base.is_jmp = DISAS_NORETURN;
307 static void gen_singlestep_exception(DisasContext *s)
309 /* Generate the right kind of exception for singlestep, which is
310 * either the architectural singlestep or EXCP_DEBUG for QEMU's
311 * gdb singlestepping.
313 if (s->ss_active) {
314 gen_step_complete_exception(s);
315 } else {
316 gen_exception_internal(EXCP_DEBUG);
320 static inline bool is_singlestepping(DisasContext *s)
322 /* Return true if we are singlestepping either because of
323 * architectural singlestep or QEMU gdbstub singlestep. This does
324 * not include the command line '-singlestep' mode which is rather
325 * misnamed as it only means "one instruction per TB" and doesn't
326 * affect the code we generate.
328 return s->base.singlestep_enabled || s->ss_active;
331 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
333 TCGv_i32 tmp1 = tcg_temp_new_i32();
334 TCGv_i32 tmp2 = tcg_temp_new_i32();
335 tcg_gen_ext16s_i32(tmp1, a);
336 tcg_gen_ext16s_i32(tmp2, b);
337 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
338 tcg_temp_free_i32(tmp2);
339 tcg_gen_sari_i32(a, a, 16);
340 tcg_gen_sari_i32(b, b, 16);
341 tcg_gen_mul_i32(b, b, a);
342 tcg_gen_mov_i32(a, tmp1);
343 tcg_temp_free_i32(tmp1);
346 /* Byteswap each halfword. */
347 static void gen_rev16(TCGv_i32 var)
349 TCGv_i32 tmp = tcg_temp_new_i32();
350 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
351 tcg_gen_shri_i32(tmp, var, 8);
352 tcg_gen_and_i32(tmp, tmp, mask);
353 tcg_gen_and_i32(var, var, mask);
354 tcg_gen_shli_i32(var, var, 8);
355 tcg_gen_or_i32(var, var, tmp);
356 tcg_temp_free_i32(mask);
357 tcg_temp_free_i32(tmp);
360 /* Byteswap low halfword and sign extend. */
361 static void gen_revsh(TCGv_i32 var)
363 tcg_gen_ext16u_i32(var, var);
364 tcg_gen_bswap16_i32(var, var);
365 tcg_gen_ext16s_i32(var, var);
368 /* Return (b << 32) + a. Mark inputs as dead */
369 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
371 TCGv_i64 tmp64 = tcg_temp_new_i64();
373 tcg_gen_extu_i32_i64(tmp64, b);
374 tcg_temp_free_i32(b);
375 tcg_gen_shli_i64(tmp64, tmp64, 32);
376 tcg_gen_add_i64(a, tmp64, a);
378 tcg_temp_free_i64(tmp64);
379 return a;
382 /* Return (b << 32) - a. Mark inputs as dead. */
383 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
385 TCGv_i64 tmp64 = tcg_temp_new_i64();
387 tcg_gen_extu_i32_i64(tmp64, b);
388 tcg_temp_free_i32(b);
389 tcg_gen_shli_i64(tmp64, tmp64, 32);
390 tcg_gen_sub_i64(a, tmp64, a);
392 tcg_temp_free_i64(tmp64);
393 return a;
396 /* 32x32->64 multiply. Marks inputs as dead. */
397 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
399 TCGv_i32 lo = tcg_temp_new_i32();
400 TCGv_i32 hi = tcg_temp_new_i32();
401 TCGv_i64 ret;
403 tcg_gen_mulu2_i32(lo, hi, a, b);
404 tcg_temp_free_i32(a);
405 tcg_temp_free_i32(b);
407 ret = tcg_temp_new_i64();
408 tcg_gen_concat_i32_i64(ret, lo, hi);
409 tcg_temp_free_i32(lo);
410 tcg_temp_free_i32(hi);
412 return ret;
415 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
417 TCGv_i32 lo = tcg_temp_new_i32();
418 TCGv_i32 hi = tcg_temp_new_i32();
419 TCGv_i64 ret;
421 tcg_gen_muls2_i32(lo, hi, a, b);
422 tcg_temp_free_i32(a);
423 tcg_temp_free_i32(b);
425 ret = tcg_temp_new_i64();
426 tcg_gen_concat_i32_i64(ret, lo, hi);
427 tcg_temp_free_i32(lo);
428 tcg_temp_free_i32(hi);
430 return ret;
433 /* Swap low and high halfwords. */
434 static void gen_swap_half(TCGv_i32 var)
436 TCGv_i32 tmp = tcg_temp_new_i32();
437 tcg_gen_shri_i32(tmp, var, 16);
438 tcg_gen_shli_i32(var, var, 16);
439 tcg_gen_or_i32(var, var, tmp);
440 tcg_temp_free_i32(tmp);
443 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
444 tmp = (t0 ^ t1) & 0x8000;
445 t0 &= ~0x8000;
446 t1 &= ~0x8000;
447 t0 = (t0 + t1) ^ tmp;
450 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
452 TCGv_i32 tmp = tcg_temp_new_i32();
453 tcg_gen_xor_i32(tmp, t0, t1);
454 tcg_gen_andi_i32(tmp, tmp, 0x8000);
455 tcg_gen_andi_i32(t0, t0, ~0x8000);
456 tcg_gen_andi_i32(t1, t1, ~0x8000);
457 tcg_gen_add_i32(t0, t0, t1);
458 tcg_gen_xor_i32(t0, t0, tmp);
459 tcg_temp_free_i32(tmp);
460 tcg_temp_free_i32(t1);
463 /* Set CF to the top bit of var. */
464 static void gen_set_CF_bit31(TCGv_i32 var)
466 tcg_gen_shri_i32(cpu_CF, var, 31);
469 /* Set N and Z flags from var. */
470 static inline void gen_logic_CC(TCGv_i32 var)
472 tcg_gen_mov_i32(cpu_NF, var);
473 tcg_gen_mov_i32(cpu_ZF, var);
476 /* T0 += T1 + CF. */
477 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
479 tcg_gen_add_i32(t0, t0, t1);
480 tcg_gen_add_i32(t0, t0, cpu_CF);
483 /* dest = T0 + T1 + CF. */
484 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
486 tcg_gen_add_i32(dest, t0, t1);
487 tcg_gen_add_i32(dest, dest, cpu_CF);
490 /* dest = T0 - T1 + CF - 1. */
491 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
493 tcg_gen_sub_i32(dest, t0, t1);
494 tcg_gen_add_i32(dest, dest, cpu_CF);
495 tcg_gen_subi_i32(dest, dest, 1);
498 /* dest = T0 + T1. Compute C, N, V and Z flags */
499 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
501 TCGv_i32 tmp = tcg_temp_new_i32();
502 tcg_gen_movi_i32(tmp, 0);
503 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
504 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
505 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
506 tcg_gen_xor_i32(tmp, t0, t1);
507 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
508 tcg_temp_free_i32(tmp);
509 tcg_gen_mov_i32(dest, cpu_NF);
512 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
513 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
515 TCGv_i32 tmp = tcg_temp_new_i32();
516 if (TCG_TARGET_HAS_add2_i32) {
517 tcg_gen_movi_i32(tmp, 0);
518 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
519 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
520 } else {
521 TCGv_i64 q0 = tcg_temp_new_i64();
522 TCGv_i64 q1 = tcg_temp_new_i64();
523 tcg_gen_extu_i32_i64(q0, t0);
524 tcg_gen_extu_i32_i64(q1, t1);
525 tcg_gen_add_i64(q0, q0, q1);
526 tcg_gen_extu_i32_i64(q1, cpu_CF);
527 tcg_gen_add_i64(q0, q0, q1);
528 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
529 tcg_temp_free_i64(q0);
530 tcg_temp_free_i64(q1);
532 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
533 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
534 tcg_gen_xor_i32(tmp, t0, t1);
535 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
536 tcg_temp_free_i32(tmp);
537 tcg_gen_mov_i32(dest, cpu_NF);
540 /* dest = T0 - T1. Compute C, N, V and Z flags */
541 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
543 TCGv_i32 tmp;
544 tcg_gen_sub_i32(cpu_NF, t0, t1);
545 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
546 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
547 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
548 tmp = tcg_temp_new_i32();
549 tcg_gen_xor_i32(tmp, t0, t1);
550 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
551 tcg_temp_free_i32(tmp);
552 tcg_gen_mov_i32(dest, cpu_NF);
555 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
556 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
558 TCGv_i32 tmp = tcg_temp_new_i32();
559 tcg_gen_not_i32(tmp, t1);
560 gen_adc_CC(dest, t0, tmp);
561 tcg_temp_free_i32(tmp);
564 #define GEN_SHIFT(name) \
565 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
567 TCGv_i32 tmp1, tmp2, tmp3; \
568 tmp1 = tcg_temp_new_i32(); \
569 tcg_gen_andi_i32(tmp1, t1, 0xff); \
570 tmp2 = tcg_const_i32(0); \
571 tmp3 = tcg_const_i32(0x1f); \
572 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
573 tcg_temp_free_i32(tmp3); \
574 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
575 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
576 tcg_temp_free_i32(tmp2); \
577 tcg_temp_free_i32(tmp1); \
579 GEN_SHIFT(shl)
580 GEN_SHIFT(shr)
581 #undef GEN_SHIFT
583 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
585 TCGv_i32 tmp1, tmp2;
586 tmp1 = tcg_temp_new_i32();
587 tcg_gen_andi_i32(tmp1, t1, 0xff);
588 tmp2 = tcg_const_i32(0x1f);
589 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
590 tcg_temp_free_i32(tmp2);
591 tcg_gen_sar_i32(dest, t0, tmp1);
592 tcg_temp_free_i32(tmp1);
595 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
597 TCGv_i32 c0 = tcg_const_i32(0);
598 TCGv_i32 tmp = tcg_temp_new_i32();
599 tcg_gen_neg_i32(tmp, src);
600 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
601 tcg_temp_free_i32(c0);
602 tcg_temp_free_i32(tmp);
605 static void shifter_out_im(TCGv_i32 var, int shift)
607 if (shift == 0) {
608 tcg_gen_andi_i32(cpu_CF, var, 1);
609 } else {
610 tcg_gen_shri_i32(cpu_CF, var, shift);
611 if (shift != 31) {
612 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
617 /* Shift by immediate. Includes special handling for shift == 0. */
618 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
619 int shift, int flags)
621 switch (shiftop) {
622 case 0: /* LSL */
623 if (shift != 0) {
624 if (flags)
625 shifter_out_im(var, 32 - shift);
626 tcg_gen_shli_i32(var, var, shift);
628 break;
629 case 1: /* LSR */
630 if (shift == 0) {
631 if (flags) {
632 tcg_gen_shri_i32(cpu_CF, var, 31);
634 tcg_gen_movi_i32(var, 0);
635 } else {
636 if (flags)
637 shifter_out_im(var, shift - 1);
638 tcg_gen_shri_i32(var, var, shift);
640 break;
641 case 2: /* ASR */
642 if (shift == 0)
643 shift = 32;
644 if (flags)
645 shifter_out_im(var, shift - 1);
646 if (shift == 32)
647 shift = 31;
648 tcg_gen_sari_i32(var, var, shift);
649 break;
650 case 3: /* ROR/RRX */
651 if (shift != 0) {
652 if (flags)
653 shifter_out_im(var, shift - 1);
654 tcg_gen_rotri_i32(var, var, shift); break;
655 } else {
656 TCGv_i32 tmp = tcg_temp_new_i32();
657 tcg_gen_shli_i32(tmp, cpu_CF, 31);
658 if (flags)
659 shifter_out_im(var, 0);
660 tcg_gen_shri_i32(var, var, 1);
661 tcg_gen_or_i32(var, var, tmp);
662 tcg_temp_free_i32(tmp);
667 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
668 TCGv_i32 shift, int flags)
670 if (flags) {
671 switch (shiftop) {
672 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
673 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
674 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
675 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
677 } else {
678 switch (shiftop) {
679 case 0:
680 gen_shl(var, var, shift);
681 break;
682 case 1:
683 gen_shr(var, var, shift);
684 break;
685 case 2:
686 gen_sar(var, var, shift);
687 break;
688 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
689 tcg_gen_rotr_i32(var, var, shift); break;
692 tcg_temp_free_i32(shift);
695 #define PAS_OP(pfx) \
696 switch (op2) { \
697 case 0: gen_pas_helper(glue(pfx,add16)); break; \
698 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
699 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
700 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
701 case 4: gen_pas_helper(glue(pfx,add8)); break; \
702 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
704 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
706 TCGv_ptr tmp;
708 switch (op1) {
709 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
710 case 1:
711 tmp = tcg_temp_new_ptr();
712 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
713 PAS_OP(s)
714 tcg_temp_free_ptr(tmp);
715 break;
716 case 5:
717 tmp = tcg_temp_new_ptr();
718 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
719 PAS_OP(u)
720 tcg_temp_free_ptr(tmp);
721 break;
722 #undef gen_pas_helper
723 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
724 case 2:
725 PAS_OP(q);
726 break;
727 case 3:
728 PAS_OP(sh);
729 break;
730 case 6:
731 PAS_OP(uq);
732 break;
733 case 7:
734 PAS_OP(uh);
735 break;
736 #undef gen_pas_helper
739 #undef PAS_OP
741 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
742 #define PAS_OP(pfx) \
743 switch (op1) { \
744 case 0: gen_pas_helper(glue(pfx,add8)); break; \
745 case 1: gen_pas_helper(glue(pfx,add16)); break; \
746 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
747 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
748 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
749 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
751 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
753 TCGv_ptr tmp;
755 switch (op2) {
756 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
757 case 0:
758 tmp = tcg_temp_new_ptr();
759 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
760 PAS_OP(s)
761 tcg_temp_free_ptr(tmp);
762 break;
763 case 4:
764 tmp = tcg_temp_new_ptr();
765 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
766 PAS_OP(u)
767 tcg_temp_free_ptr(tmp);
768 break;
769 #undef gen_pas_helper
770 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
771 case 1:
772 PAS_OP(q);
773 break;
774 case 2:
775 PAS_OP(sh);
776 break;
777 case 5:
778 PAS_OP(uq);
779 break;
780 case 6:
781 PAS_OP(uh);
782 break;
783 #undef gen_pas_helper
786 #undef PAS_OP
789 * Generate a conditional based on ARM condition code cc.
790 * This is common between ARM and Aarch64 targets.
792 void arm_test_cc(DisasCompare *cmp, int cc)
794 TCGv_i32 value;
795 TCGCond cond;
796 bool global = true;
798 switch (cc) {
799 case 0: /* eq: Z */
800 case 1: /* ne: !Z */
801 cond = TCG_COND_EQ;
802 value = cpu_ZF;
803 break;
805 case 2: /* cs: C */
806 case 3: /* cc: !C */
807 cond = TCG_COND_NE;
808 value = cpu_CF;
809 break;
811 case 4: /* mi: N */
812 case 5: /* pl: !N */
813 cond = TCG_COND_LT;
814 value = cpu_NF;
815 break;
817 case 6: /* vs: V */
818 case 7: /* vc: !V */
819 cond = TCG_COND_LT;
820 value = cpu_VF;
821 break;
823 case 8: /* hi: C && !Z */
824 case 9: /* ls: !C || Z -> !(C && !Z) */
825 cond = TCG_COND_NE;
826 value = tcg_temp_new_i32();
827 global = false;
828 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
829 ZF is non-zero for !Z; so AND the two subexpressions. */
830 tcg_gen_neg_i32(value, cpu_CF);
831 tcg_gen_and_i32(value, value, cpu_ZF);
832 break;
834 case 10: /* ge: N == V -> N ^ V == 0 */
835 case 11: /* lt: N != V -> N ^ V != 0 */
836 /* Since we're only interested in the sign bit, == 0 is >= 0. */
837 cond = TCG_COND_GE;
838 value = tcg_temp_new_i32();
839 global = false;
840 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
841 break;
843 case 12: /* gt: !Z && N == V */
844 case 13: /* le: Z || N != V */
845 cond = TCG_COND_NE;
846 value = tcg_temp_new_i32();
847 global = false;
848 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
849 * the sign bit then AND with ZF to yield the result. */
850 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
851 tcg_gen_sari_i32(value, value, 31);
852 tcg_gen_andc_i32(value, cpu_ZF, value);
853 break;
855 case 14: /* always */
856 case 15: /* always */
857 /* Use the ALWAYS condition, which will fold early.
858 * It doesn't matter what we use for the value. */
859 cond = TCG_COND_ALWAYS;
860 value = cpu_ZF;
861 goto no_invert;
863 default:
864 fprintf(stderr, "Bad condition code 0x%x\n", cc);
865 abort();
868 if (cc & 1) {
869 cond = tcg_invert_cond(cond);
872 no_invert:
873 cmp->cond = cond;
874 cmp->value = value;
875 cmp->value_global = global;
878 void arm_free_cc(DisasCompare *cmp)
880 if (!cmp->value_global) {
881 tcg_temp_free_i32(cmp->value);
885 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
887 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
890 void arm_gen_test_cc(int cc, TCGLabel *label)
892 DisasCompare cmp;
893 arm_test_cc(&cmp, cc);
894 arm_jump_cc(&cmp, label);
895 arm_free_cc(&cmp);
898 static const uint8_t table_logic_cc[16] = {
899 1, /* and */
900 1, /* xor */
901 0, /* sub */
902 0, /* rsb */
903 0, /* add */
904 0, /* adc */
905 0, /* sbc */
906 0, /* rsc */
907 1, /* andl */
908 1, /* xorl */
909 0, /* cmp */
910 0, /* cmn */
911 1, /* orr */
912 1, /* mov */
913 1, /* bic */
914 1, /* mvn */
917 static inline void gen_set_condexec(DisasContext *s)
919 if (s->condexec_mask) {
920 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
921 TCGv_i32 tmp = tcg_temp_new_i32();
922 tcg_gen_movi_i32(tmp, val);
923 store_cpu_field(tmp, condexec_bits);
927 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
929 tcg_gen_movi_i32(cpu_R[15], val);
932 /* Set PC and Thumb state from an immediate address. */
933 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
935 TCGv_i32 tmp;
937 s->base.is_jmp = DISAS_JUMP;
938 if (s->thumb != (addr & 1)) {
939 tmp = tcg_temp_new_i32();
940 tcg_gen_movi_i32(tmp, addr & 1);
941 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
942 tcg_temp_free_i32(tmp);
944 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
947 /* Set PC and Thumb state from var. var is marked as dead. */
948 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
950 s->base.is_jmp = DISAS_JUMP;
951 tcg_gen_andi_i32(cpu_R[15], var, ~1);
952 tcg_gen_andi_i32(var, var, 1);
953 store_cpu_field(var, thumb);
956 /* Set PC and Thumb state from var. var is marked as dead.
957 * For M-profile CPUs, include logic to detect exception-return
958 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
959 * and BX reg, and no others, and happens only for code in Handler mode.
961 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
963 /* Generate the same code here as for a simple bx, but flag via
964 * s->base.is_jmp that we need to do the rest of the work later.
966 gen_bx(s, var);
967 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
968 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
969 s->base.is_jmp = DISAS_BX_EXCRET;
973 static inline void gen_bx_excret_final_code(DisasContext *s)
975 /* Generate the code to finish possible exception return and end the TB */
976 TCGLabel *excret_label = gen_new_label();
977 uint32_t min_magic;
979 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
980 /* Covers FNC_RETURN and EXC_RETURN magic */
981 min_magic = FNC_RETURN_MIN_MAGIC;
982 } else {
983 /* EXC_RETURN magic only */
984 min_magic = EXC_RETURN_MIN_MAGIC;
987 /* Is the new PC value in the magic range indicating exception return? */
988 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
989 /* No: end the TB as we would for a DISAS_JMP */
990 if (is_singlestepping(s)) {
991 gen_singlestep_exception(s);
992 } else {
993 tcg_gen_exit_tb(0);
995 gen_set_label(excret_label);
996 /* Yes: this is an exception return.
997 * At this point in runtime env->regs[15] and env->thumb will hold
998 * the exception-return magic number, which do_v7m_exception_exit()
999 * will read. Nothing else will be able to see those values because
1000 * the cpu-exec main loop guarantees that we will always go straight
1001 * from raising the exception to the exception-handling code.
1003 * gen_ss_advance(s) does nothing on M profile currently but
1004 * calling it is conceptually the right thing as we have executed
1005 * this instruction (compare SWI, HVC, SMC handling).
1007 gen_ss_advance(s);
1008 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1011 static inline void gen_bxns(DisasContext *s, int rm)
1013 TCGv_i32 var = load_reg(s, rm);
1015 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1016 * we need to sync state before calling it, but:
1017 * - we don't need to do gen_set_pc_im() because the bxns helper will
1018 * always set the PC itself
1019 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1020 * unless it's outside an IT block or the last insn in an IT block,
1021 * so we know that condexec == 0 (already set at the top of the TB)
1022 * is correct in the non-UNPREDICTABLE cases, and we can choose
1023 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1025 gen_helper_v7m_bxns(cpu_env, var);
1026 tcg_temp_free_i32(var);
1027 s->base.is_jmp = DISAS_EXIT;
1030 static inline void gen_blxns(DisasContext *s, int rm)
1032 TCGv_i32 var = load_reg(s, rm);
1034 /* We don't need to sync condexec state, for the same reason as bxns.
1035 * We do however need to set the PC, because the blxns helper reads it.
1036 * The blxns helper may throw an exception.
1038 gen_set_pc_im(s, s->pc);
1039 gen_helper_v7m_blxns(cpu_env, var);
1040 tcg_temp_free_i32(var);
1041 s->base.is_jmp = DISAS_EXIT;
1044 /* Variant of store_reg which uses branch&exchange logic when storing
1045 to r15 in ARM architecture v7 and above. The source must be a temporary
1046 and will be marked as dead. */
1047 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1049 if (reg == 15 && ENABLE_ARCH_7) {
1050 gen_bx(s, var);
1051 } else {
1052 store_reg(s, reg, var);
1056 /* Variant of store_reg which uses branch&exchange logic when storing
1057 * to r15 in ARM architecture v5T and above. This is used for storing
1058 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1059 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1060 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1062 if (reg == 15 && ENABLE_ARCH_5) {
1063 gen_bx_excret(s, var);
1064 } else {
1065 store_reg(s, reg, var);
1069 #ifdef CONFIG_USER_ONLY
1070 #define IS_USER_ONLY 1
1071 #else
1072 #define IS_USER_ONLY 0
1073 #endif
1075 /* Abstractions of "generate code to do a guest load/store for
1076 * AArch32", where a vaddr is always 32 bits (and is zero
1077 * extended if we're a 64 bit core) and data is also
1078 * 32 bits unless specifically doing a 64 bit access.
1079 * These functions work like tcg_gen_qemu_{ld,st}* except
1080 * that the address argument is TCGv_i32 rather than TCGv.
1083 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1085 TCGv addr = tcg_temp_new();
1086 tcg_gen_extu_i32_tl(addr, a32);
1088 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1089 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1090 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1092 return addr;
1095 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1096 int index, TCGMemOp opc)
1098 TCGv addr = gen_aa32_addr(s, a32, opc);
1099 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1100 tcg_temp_free(addr);
1103 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1104 int index, TCGMemOp opc)
1106 TCGv addr = gen_aa32_addr(s, a32, opc);
1107 tcg_gen_qemu_st_i32(val, addr, index, opc);
1108 tcg_temp_free(addr);
1111 #define DO_GEN_LD(SUFF, OPC) \
1112 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1113 TCGv_i32 a32, int index) \
1115 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1117 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1118 TCGv_i32 val, \
1119 TCGv_i32 a32, int index, \
1120 ISSInfo issinfo) \
1122 gen_aa32_ld##SUFF(s, val, a32, index); \
1123 disas_set_da_iss(s, OPC, issinfo); \
1126 #define DO_GEN_ST(SUFF, OPC) \
1127 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1128 TCGv_i32 a32, int index) \
1130 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1132 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1133 TCGv_i32 val, \
1134 TCGv_i32 a32, int index, \
1135 ISSInfo issinfo) \
1137 gen_aa32_st##SUFF(s, val, a32, index); \
1138 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1141 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1143 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1144 if (!IS_USER_ONLY && s->sctlr_b) {
1145 tcg_gen_rotri_i64(val, val, 32);
1149 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1150 int index, TCGMemOp opc)
1152 TCGv addr = gen_aa32_addr(s, a32, opc);
1153 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1154 gen_aa32_frob64(s, val);
1155 tcg_temp_free(addr);
1158 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1159 TCGv_i32 a32, int index)
1161 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1164 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1165 int index, TCGMemOp opc)
1167 TCGv addr = gen_aa32_addr(s, a32, opc);
1169 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1170 if (!IS_USER_ONLY && s->sctlr_b) {
1171 TCGv_i64 tmp = tcg_temp_new_i64();
1172 tcg_gen_rotri_i64(tmp, val, 32);
1173 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1174 tcg_temp_free_i64(tmp);
1175 } else {
1176 tcg_gen_qemu_st_i64(val, addr, index, opc);
1178 tcg_temp_free(addr);
1181 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1182 TCGv_i32 a32, int index)
1184 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1187 DO_GEN_LD(8s, MO_SB)
1188 DO_GEN_LD(8u, MO_UB)
1189 DO_GEN_LD(16s, MO_SW)
1190 DO_GEN_LD(16u, MO_UW)
1191 DO_GEN_LD(32u, MO_UL)
1192 DO_GEN_ST(8, MO_UB)
1193 DO_GEN_ST(16, MO_UW)
1194 DO_GEN_ST(32, MO_UL)
1196 static inline void gen_hvc(DisasContext *s, int imm16)
1198 /* The pre HVC helper handles cases when HVC gets trapped
1199 * as an undefined insn by runtime configuration (ie before
1200 * the insn really executes).
1202 gen_set_pc_im(s, s->pc - 4);
1203 gen_helper_pre_hvc(cpu_env);
1204 /* Otherwise we will treat this as a real exception which
1205 * happens after execution of the insn. (The distinction matters
1206 * for the PC value reported to the exception handler and also
1207 * for single stepping.)
1209 s->svc_imm = imm16;
1210 gen_set_pc_im(s, s->pc);
1211 s->base.is_jmp = DISAS_HVC;
1214 static inline void gen_smc(DisasContext *s)
1216 /* As with HVC, we may take an exception either before or after
1217 * the insn executes.
1219 TCGv_i32 tmp;
1221 gen_set_pc_im(s, s->pc - 4);
1222 tmp = tcg_const_i32(syn_aa32_smc());
1223 gen_helper_pre_smc(cpu_env, tmp);
1224 tcg_temp_free_i32(tmp);
1225 gen_set_pc_im(s, s->pc);
1226 s->base.is_jmp = DISAS_SMC;
1229 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1231 gen_set_condexec(s);
1232 gen_set_pc_im(s, s->pc - offset);
1233 gen_exception_internal(excp);
1234 s->base.is_jmp = DISAS_NORETURN;
1237 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1238 int syn, uint32_t target_el)
1240 gen_set_condexec(s);
1241 gen_set_pc_im(s, s->pc - offset);
1242 gen_exception(excp, syn, target_el);
1243 s->base.is_jmp = DISAS_NORETURN;
1246 /* Force a TB lookup after an instruction that changes the CPU state. */
1247 static inline void gen_lookup_tb(DisasContext *s)
1249 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1250 s->base.is_jmp = DISAS_EXIT;
1253 static inline void gen_hlt(DisasContext *s, int imm)
1255 /* HLT. This has two purposes.
1256 * Architecturally, it is an external halting debug instruction.
1257 * Since QEMU doesn't implement external debug, we treat this as
1258 * it is required for halting debug disabled: it will UNDEF.
1259 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1260 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1261 * must trigger semihosting even for ARMv7 and earlier, where
1262 * HLT was an undefined encoding.
1263 * In system mode, we don't allow userspace access to
1264 * semihosting, to provide some semblance of security
1265 * (and for consistency with our 32-bit semihosting).
1267 if (semihosting_enabled() &&
1268 #ifndef CONFIG_USER_ONLY
1269 s->current_el != 0 &&
1270 #endif
1271 (imm == (s->thumb ? 0x3c : 0xf000))) {
1272 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1273 return;
1276 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1277 default_exception_el(s));
1280 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1281 TCGv_i32 var)
1283 int val, rm, shift, shiftop;
1284 TCGv_i32 offset;
1286 if (!(insn & (1 << 25))) {
1287 /* immediate */
1288 val = insn & 0xfff;
1289 if (!(insn & (1 << 23)))
1290 val = -val;
1291 if (val != 0)
1292 tcg_gen_addi_i32(var, var, val);
1293 } else {
1294 /* shift/register */
1295 rm = (insn) & 0xf;
1296 shift = (insn >> 7) & 0x1f;
1297 shiftop = (insn >> 5) & 3;
1298 offset = load_reg(s, rm);
1299 gen_arm_shift_im(offset, shiftop, shift, 0);
1300 if (!(insn & (1 << 23)))
1301 tcg_gen_sub_i32(var, var, offset);
1302 else
1303 tcg_gen_add_i32(var, var, offset);
1304 tcg_temp_free_i32(offset);
1308 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1309 int extra, TCGv_i32 var)
1311 int val, rm;
1312 TCGv_i32 offset;
1314 if (insn & (1 << 22)) {
1315 /* immediate */
1316 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1317 if (!(insn & (1 << 23)))
1318 val = -val;
1319 val += extra;
1320 if (val != 0)
1321 tcg_gen_addi_i32(var, var, val);
1322 } else {
1323 /* register */
1324 if (extra)
1325 tcg_gen_addi_i32(var, var, extra);
1326 rm = (insn) & 0xf;
1327 offset = load_reg(s, rm);
1328 if (!(insn & (1 << 23)))
1329 tcg_gen_sub_i32(var, var, offset);
1330 else
1331 tcg_gen_add_i32(var, var, offset);
1332 tcg_temp_free_i32(offset);
1336 static TCGv_ptr get_fpstatus_ptr(int neon)
1338 TCGv_ptr statusptr = tcg_temp_new_ptr();
1339 int offset;
1340 if (neon) {
1341 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1342 } else {
1343 offset = offsetof(CPUARMState, vfp.fp_status);
1345 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1346 return statusptr;
1349 #define VFP_OP2(name) \
1350 static inline void gen_vfp_##name(int dp) \
1352 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1353 if (dp) { \
1354 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1355 } else { \
1356 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1358 tcg_temp_free_ptr(fpst); \
1361 VFP_OP2(add)
1362 VFP_OP2(sub)
1363 VFP_OP2(mul)
1364 VFP_OP2(div)
1366 #undef VFP_OP2
1368 static inline void gen_vfp_F1_mul(int dp)
1370 /* Like gen_vfp_mul() but put result in F1 */
1371 TCGv_ptr fpst = get_fpstatus_ptr(0);
1372 if (dp) {
1373 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1374 } else {
1375 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1377 tcg_temp_free_ptr(fpst);
1380 static inline void gen_vfp_F1_neg(int dp)
1382 /* Like gen_vfp_neg() but put result in F1 */
1383 if (dp) {
1384 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1385 } else {
1386 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1390 static inline void gen_vfp_abs(int dp)
1392 if (dp)
1393 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1394 else
1395 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1398 static inline void gen_vfp_neg(int dp)
1400 if (dp)
1401 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1402 else
1403 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1406 static inline void gen_vfp_sqrt(int dp)
1408 if (dp)
1409 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1410 else
1411 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1414 static inline void gen_vfp_cmp(int dp)
1416 if (dp)
1417 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1418 else
1419 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1422 static inline void gen_vfp_cmpe(int dp)
1424 if (dp)
1425 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1426 else
1427 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1430 static inline void gen_vfp_F1_ld0(int dp)
1432 if (dp)
1433 tcg_gen_movi_i64(cpu_F1d, 0);
1434 else
1435 tcg_gen_movi_i32(cpu_F1s, 0);
1438 #define VFP_GEN_ITOF(name) \
1439 static inline void gen_vfp_##name(int dp, int neon) \
1441 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1442 if (dp) { \
1443 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1444 } else { \
1445 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1447 tcg_temp_free_ptr(statusptr); \
1450 VFP_GEN_ITOF(uito)
1451 VFP_GEN_ITOF(sito)
1452 #undef VFP_GEN_ITOF
1454 #define VFP_GEN_FTOI(name) \
1455 static inline void gen_vfp_##name(int dp, int neon) \
1457 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1458 if (dp) { \
1459 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1460 } else { \
1461 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1463 tcg_temp_free_ptr(statusptr); \
1466 VFP_GEN_FTOI(toui)
1467 VFP_GEN_FTOI(touiz)
1468 VFP_GEN_FTOI(tosi)
1469 VFP_GEN_FTOI(tosiz)
1470 #undef VFP_GEN_FTOI
1472 #define VFP_GEN_FIX(name, round) \
1473 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1475 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1476 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1477 if (dp) { \
1478 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1479 statusptr); \
1480 } else { \
1481 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1482 statusptr); \
1484 tcg_temp_free_i32(tmp_shift); \
1485 tcg_temp_free_ptr(statusptr); \
1487 VFP_GEN_FIX(tosh, _round_to_zero)
1488 VFP_GEN_FIX(tosl, _round_to_zero)
1489 VFP_GEN_FIX(touh, _round_to_zero)
1490 VFP_GEN_FIX(toul, _round_to_zero)
1491 VFP_GEN_FIX(shto, )
1492 VFP_GEN_FIX(slto, )
1493 VFP_GEN_FIX(uhto, )
1494 VFP_GEN_FIX(ulto, )
1495 #undef VFP_GEN_FIX
1497 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1499 if (dp) {
1500 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1501 } else {
1502 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1506 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1508 if (dp) {
1509 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1510 } else {
1511 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1515 static inline long
1516 vfp_reg_offset (int dp, int reg)
1518 if (dp)
1519 return offsetof(CPUARMState, vfp.regs[reg]);
1520 else if (reg & 1) {
1521 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1522 + offsetof(CPU_DoubleU, l.upper);
1523 } else {
1524 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1525 + offsetof(CPU_DoubleU, l.lower);
1529 /* Return the offset of a 32-bit piece of a NEON register.
1530 zero is the least significant end of the register. */
1531 static inline long
1532 neon_reg_offset (int reg, int n)
1534 int sreg;
1535 sreg = reg * 2 + n;
1536 return vfp_reg_offset(0, sreg);
1539 static TCGv_i32 neon_load_reg(int reg, int pass)
1541 TCGv_i32 tmp = tcg_temp_new_i32();
1542 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1543 return tmp;
1546 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1548 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1549 tcg_temp_free_i32(var);
1552 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1554 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1557 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1559 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1562 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1563 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1564 #define tcg_gen_st_f32 tcg_gen_st_i32
1565 #define tcg_gen_st_f64 tcg_gen_st_i64
1567 static inline void gen_mov_F0_vreg(int dp, int reg)
1569 if (dp)
1570 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1571 else
1572 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1575 static inline void gen_mov_F1_vreg(int dp, int reg)
1577 if (dp)
1578 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1579 else
1580 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1583 static inline void gen_mov_vreg_F0(int dp, int reg)
1585 if (dp)
1586 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1587 else
1588 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1591 #define ARM_CP_RW_BIT (1 << 20)
1593 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1595 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1598 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1600 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1603 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1605 TCGv_i32 var = tcg_temp_new_i32();
1606 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1607 return var;
1610 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1612 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1613 tcg_temp_free_i32(var);
1616 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1618 iwmmxt_store_reg(cpu_M0, rn);
1621 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1623 iwmmxt_load_reg(cpu_M0, rn);
1626 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1628 iwmmxt_load_reg(cpu_V1, rn);
1629 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1632 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1634 iwmmxt_load_reg(cpu_V1, rn);
1635 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1638 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1640 iwmmxt_load_reg(cpu_V1, rn);
1641 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1644 #define IWMMXT_OP(name) \
1645 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1647 iwmmxt_load_reg(cpu_V1, rn); \
1648 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1651 #define IWMMXT_OP_ENV(name) \
1652 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1654 iwmmxt_load_reg(cpu_V1, rn); \
1655 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1658 #define IWMMXT_OP_ENV_SIZE(name) \
1659 IWMMXT_OP_ENV(name##b) \
1660 IWMMXT_OP_ENV(name##w) \
1661 IWMMXT_OP_ENV(name##l)
1663 #define IWMMXT_OP_ENV1(name) \
1664 static inline void gen_op_iwmmxt_##name##_M0(void) \
1666 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1669 IWMMXT_OP(maddsq)
1670 IWMMXT_OP(madduq)
1671 IWMMXT_OP(sadb)
1672 IWMMXT_OP(sadw)
1673 IWMMXT_OP(mulslw)
1674 IWMMXT_OP(mulshw)
1675 IWMMXT_OP(mululw)
1676 IWMMXT_OP(muluhw)
1677 IWMMXT_OP(macsw)
1678 IWMMXT_OP(macuw)
1680 IWMMXT_OP_ENV_SIZE(unpackl)
1681 IWMMXT_OP_ENV_SIZE(unpackh)
1683 IWMMXT_OP_ENV1(unpacklub)
1684 IWMMXT_OP_ENV1(unpackluw)
1685 IWMMXT_OP_ENV1(unpacklul)
1686 IWMMXT_OP_ENV1(unpackhub)
1687 IWMMXT_OP_ENV1(unpackhuw)
1688 IWMMXT_OP_ENV1(unpackhul)
1689 IWMMXT_OP_ENV1(unpacklsb)
1690 IWMMXT_OP_ENV1(unpacklsw)
1691 IWMMXT_OP_ENV1(unpacklsl)
1692 IWMMXT_OP_ENV1(unpackhsb)
1693 IWMMXT_OP_ENV1(unpackhsw)
1694 IWMMXT_OP_ENV1(unpackhsl)
1696 IWMMXT_OP_ENV_SIZE(cmpeq)
1697 IWMMXT_OP_ENV_SIZE(cmpgtu)
1698 IWMMXT_OP_ENV_SIZE(cmpgts)
1700 IWMMXT_OP_ENV_SIZE(mins)
1701 IWMMXT_OP_ENV_SIZE(minu)
1702 IWMMXT_OP_ENV_SIZE(maxs)
1703 IWMMXT_OP_ENV_SIZE(maxu)
1705 IWMMXT_OP_ENV_SIZE(subn)
1706 IWMMXT_OP_ENV_SIZE(addn)
1707 IWMMXT_OP_ENV_SIZE(subu)
1708 IWMMXT_OP_ENV_SIZE(addu)
1709 IWMMXT_OP_ENV_SIZE(subs)
1710 IWMMXT_OP_ENV_SIZE(adds)
1712 IWMMXT_OP_ENV(avgb0)
1713 IWMMXT_OP_ENV(avgb1)
1714 IWMMXT_OP_ENV(avgw0)
1715 IWMMXT_OP_ENV(avgw1)
1717 IWMMXT_OP_ENV(packuw)
1718 IWMMXT_OP_ENV(packul)
1719 IWMMXT_OP_ENV(packuq)
1720 IWMMXT_OP_ENV(packsw)
1721 IWMMXT_OP_ENV(packsl)
1722 IWMMXT_OP_ENV(packsq)
1724 static void gen_op_iwmmxt_set_mup(void)
1726 TCGv_i32 tmp;
1727 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1728 tcg_gen_ori_i32(tmp, tmp, 2);
1729 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1732 static void gen_op_iwmmxt_set_cup(void)
1734 TCGv_i32 tmp;
1735 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1736 tcg_gen_ori_i32(tmp, tmp, 1);
1737 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1740 static void gen_op_iwmmxt_setpsr_nz(void)
1742 TCGv_i32 tmp = tcg_temp_new_i32();
1743 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1744 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1747 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1749 iwmmxt_load_reg(cpu_V1, rn);
1750 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1751 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1754 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1755 TCGv_i32 dest)
1757 int rd;
1758 uint32_t offset;
1759 TCGv_i32 tmp;
1761 rd = (insn >> 16) & 0xf;
1762 tmp = load_reg(s, rd);
1764 offset = (insn & 0xff) << ((insn >> 7) & 2);
1765 if (insn & (1 << 24)) {
1766 /* Pre indexed */
1767 if (insn & (1 << 23))
1768 tcg_gen_addi_i32(tmp, tmp, offset);
1769 else
1770 tcg_gen_addi_i32(tmp, tmp, -offset);
1771 tcg_gen_mov_i32(dest, tmp);
1772 if (insn & (1 << 21))
1773 store_reg(s, rd, tmp);
1774 else
1775 tcg_temp_free_i32(tmp);
1776 } else if (insn & (1 << 21)) {
1777 /* Post indexed */
1778 tcg_gen_mov_i32(dest, tmp);
1779 if (insn & (1 << 23))
1780 tcg_gen_addi_i32(tmp, tmp, offset);
1781 else
1782 tcg_gen_addi_i32(tmp, tmp, -offset);
1783 store_reg(s, rd, tmp);
1784 } else if (!(insn & (1 << 23)))
1785 return 1;
1786 return 0;
1789 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1791 int rd = (insn >> 0) & 0xf;
1792 TCGv_i32 tmp;
1794 if (insn & (1 << 8)) {
1795 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1796 return 1;
1797 } else {
1798 tmp = iwmmxt_load_creg(rd);
1800 } else {
1801 tmp = tcg_temp_new_i32();
1802 iwmmxt_load_reg(cpu_V0, rd);
1803 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1805 tcg_gen_andi_i32(tmp, tmp, mask);
1806 tcg_gen_mov_i32(dest, tmp);
1807 tcg_temp_free_i32(tmp);
1808 return 0;
1811 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1812 (ie. an undefined instruction). */
1813 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1815 int rd, wrd;
1816 int rdhi, rdlo, rd0, rd1, i;
1817 TCGv_i32 addr;
1818 TCGv_i32 tmp, tmp2, tmp3;
1820 if ((insn & 0x0e000e00) == 0x0c000000) {
1821 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1822 wrd = insn & 0xf;
1823 rdlo = (insn >> 12) & 0xf;
1824 rdhi = (insn >> 16) & 0xf;
1825 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1826 iwmmxt_load_reg(cpu_V0, wrd);
1827 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1828 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1829 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1830 } else { /* TMCRR */
1831 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1832 iwmmxt_store_reg(cpu_V0, wrd);
1833 gen_op_iwmmxt_set_mup();
1835 return 0;
1838 wrd = (insn >> 12) & 0xf;
1839 addr = tcg_temp_new_i32();
1840 if (gen_iwmmxt_address(s, insn, addr)) {
1841 tcg_temp_free_i32(addr);
1842 return 1;
1844 if (insn & ARM_CP_RW_BIT) {
1845 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1846 tmp = tcg_temp_new_i32();
1847 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1848 iwmmxt_store_creg(wrd, tmp);
1849 } else {
1850 i = 1;
1851 if (insn & (1 << 8)) {
1852 if (insn & (1 << 22)) { /* WLDRD */
1853 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1854 i = 0;
1855 } else { /* WLDRW wRd */
1856 tmp = tcg_temp_new_i32();
1857 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1859 } else {
1860 tmp = tcg_temp_new_i32();
1861 if (insn & (1 << 22)) { /* WLDRH */
1862 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1863 } else { /* WLDRB */
1864 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1867 if (i) {
1868 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1869 tcg_temp_free_i32(tmp);
1871 gen_op_iwmmxt_movq_wRn_M0(wrd);
1873 } else {
1874 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1875 tmp = iwmmxt_load_creg(wrd);
1876 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1877 } else {
1878 gen_op_iwmmxt_movq_M0_wRn(wrd);
1879 tmp = tcg_temp_new_i32();
1880 if (insn & (1 << 8)) {
1881 if (insn & (1 << 22)) { /* WSTRD */
1882 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1883 } else { /* WSTRW wRd */
1884 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1885 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1887 } else {
1888 if (insn & (1 << 22)) { /* WSTRH */
1889 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1890 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1891 } else { /* WSTRB */
1892 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1893 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1897 tcg_temp_free_i32(tmp);
1899 tcg_temp_free_i32(addr);
1900 return 0;
1903 if ((insn & 0x0f000000) != 0x0e000000)
1904 return 1;
1906 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1907 case 0x000: /* WOR */
1908 wrd = (insn >> 12) & 0xf;
1909 rd0 = (insn >> 0) & 0xf;
1910 rd1 = (insn >> 16) & 0xf;
1911 gen_op_iwmmxt_movq_M0_wRn(rd0);
1912 gen_op_iwmmxt_orq_M0_wRn(rd1);
1913 gen_op_iwmmxt_setpsr_nz();
1914 gen_op_iwmmxt_movq_wRn_M0(wrd);
1915 gen_op_iwmmxt_set_mup();
1916 gen_op_iwmmxt_set_cup();
1917 break;
1918 case 0x011: /* TMCR */
1919 if (insn & 0xf)
1920 return 1;
1921 rd = (insn >> 12) & 0xf;
1922 wrd = (insn >> 16) & 0xf;
1923 switch (wrd) {
1924 case ARM_IWMMXT_wCID:
1925 case ARM_IWMMXT_wCASF:
1926 break;
1927 case ARM_IWMMXT_wCon:
1928 gen_op_iwmmxt_set_cup();
1929 /* Fall through. */
1930 case ARM_IWMMXT_wCSSF:
1931 tmp = iwmmxt_load_creg(wrd);
1932 tmp2 = load_reg(s, rd);
1933 tcg_gen_andc_i32(tmp, tmp, tmp2);
1934 tcg_temp_free_i32(tmp2);
1935 iwmmxt_store_creg(wrd, tmp);
1936 break;
1937 case ARM_IWMMXT_wCGR0:
1938 case ARM_IWMMXT_wCGR1:
1939 case ARM_IWMMXT_wCGR2:
1940 case ARM_IWMMXT_wCGR3:
1941 gen_op_iwmmxt_set_cup();
1942 tmp = load_reg(s, rd);
1943 iwmmxt_store_creg(wrd, tmp);
1944 break;
1945 default:
1946 return 1;
1948 break;
1949 case 0x100: /* WXOR */
1950 wrd = (insn >> 12) & 0xf;
1951 rd0 = (insn >> 0) & 0xf;
1952 rd1 = (insn >> 16) & 0xf;
1953 gen_op_iwmmxt_movq_M0_wRn(rd0);
1954 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1955 gen_op_iwmmxt_setpsr_nz();
1956 gen_op_iwmmxt_movq_wRn_M0(wrd);
1957 gen_op_iwmmxt_set_mup();
1958 gen_op_iwmmxt_set_cup();
1959 break;
1960 case 0x111: /* TMRC */
1961 if (insn & 0xf)
1962 return 1;
1963 rd = (insn >> 12) & 0xf;
1964 wrd = (insn >> 16) & 0xf;
1965 tmp = iwmmxt_load_creg(wrd);
1966 store_reg(s, rd, tmp);
1967 break;
1968 case 0x300: /* WANDN */
1969 wrd = (insn >> 12) & 0xf;
1970 rd0 = (insn >> 0) & 0xf;
1971 rd1 = (insn >> 16) & 0xf;
1972 gen_op_iwmmxt_movq_M0_wRn(rd0);
1973 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1974 gen_op_iwmmxt_andq_M0_wRn(rd1);
1975 gen_op_iwmmxt_setpsr_nz();
1976 gen_op_iwmmxt_movq_wRn_M0(wrd);
1977 gen_op_iwmmxt_set_mup();
1978 gen_op_iwmmxt_set_cup();
1979 break;
1980 case 0x200: /* WAND */
1981 wrd = (insn >> 12) & 0xf;
1982 rd0 = (insn >> 0) & 0xf;
1983 rd1 = (insn >> 16) & 0xf;
1984 gen_op_iwmmxt_movq_M0_wRn(rd0);
1985 gen_op_iwmmxt_andq_M0_wRn(rd1);
1986 gen_op_iwmmxt_setpsr_nz();
1987 gen_op_iwmmxt_movq_wRn_M0(wrd);
1988 gen_op_iwmmxt_set_mup();
1989 gen_op_iwmmxt_set_cup();
1990 break;
1991 case 0x810: case 0xa10: /* WMADD */
1992 wrd = (insn >> 12) & 0xf;
1993 rd0 = (insn >> 0) & 0xf;
1994 rd1 = (insn >> 16) & 0xf;
1995 gen_op_iwmmxt_movq_M0_wRn(rd0);
1996 if (insn & (1 << 21))
1997 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1998 else
1999 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2000 gen_op_iwmmxt_movq_wRn_M0(wrd);
2001 gen_op_iwmmxt_set_mup();
2002 break;
2003 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2004 wrd = (insn >> 12) & 0xf;
2005 rd0 = (insn >> 16) & 0xf;
2006 rd1 = (insn >> 0) & 0xf;
2007 gen_op_iwmmxt_movq_M0_wRn(rd0);
2008 switch ((insn >> 22) & 3) {
2009 case 0:
2010 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2011 break;
2012 case 1:
2013 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2014 break;
2015 case 2:
2016 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2017 break;
2018 case 3:
2019 return 1;
2021 gen_op_iwmmxt_movq_wRn_M0(wrd);
2022 gen_op_iwmmxt_set_mup();
2023 gen_op_iwmmxt_set_cup();
2024 break;
2025 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2026 wrd = (insn >> 12) & 0xf;
2027 rd0 = (insn >> 16) & 0xf;
2028 rd1 = (insn >> 0) & 0xf;
2029 gen_op_iwmmxt_movq_M0_wRn(rd0);
2030 switch ((insn >> 22) & 3) {
2031 case 0:
2032 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2033 break;
2034 case 1:
2035 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2036 break;
2037 case 2:
2038 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2039 break;
2040 case 3:
2041 return 1;
2043 gen_op_iwmmxt_movq_wRn_M0(wrd);
2044 gen_op_iwmmxt_set_mup();
2045 gen_op_iwmmxt_set_cup();
2046 break;
2047 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2048 wrd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 16) & 0xf;
2050 rd1 = (insn >> 0) & 0xf;
2051 gen_op_iwmmxt_movq_M0_wRn(rd0);
2052 if (insn & (1 << 22))
2053 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2054 else
2055 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2056 if (!(insn & (1 << 20)))
2057 gen_op_iwmmxt_addl_M0_wRn(wrd);
2058 gen_op_iwmmxt_movq_wRn_M0(wrd);
2059 gen_op_iwmmxt_set_mup();
2060 break;
2061 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2062 wrd = (insn >> 12) & 0xf;
2063 rd0 = (insn >> 16) & 0xf;
2064 rd1 = (insn >> 0) & 0xf;
2065 gen_op_iwmmxt_movq_M0_wRn(rd0);
2066 if (insn & (1 << 21)) {
2067 if (insn & (1 << 20))
2068 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2069 else
2070 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2071 } else {
2072 if (insn & (1 << 20))
2073 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2074 else
2075 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2077 gen_op_iwmmxt_movq_wRn_M0(wrd);
2078 gen_op_iwmmxt_set_mup();
2079 break;
2080 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2081 wrd = (insn >> 12) & 0xf;
2082 rd0 = (insn >> 16) & 0xf;
2083 rd1 = (insn >> 0) & 0xf;
2084 gen_op_iwmmxt_movq_M0_wRn(rd0);
2085 if (insn & (1 << 21))
2086 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2087 else
2088 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2089 if (!(insn & (1 << 20))) {
2090 iwmmxt_load_reg(cpu_V1, wrd);
2091 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2093 gen_op_iwmmxt_movq_wRn_M0(wrd);
2094 gen_op_iwmmxt_set_mup();
2095 break;
2096 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2097 wrd = (insn >> 12) & 0xf;
2098 rd0 = (insn >> 16) & 0xf;
2099 rd1 = (insn >> 0) & 0xf;
2100 gen_op_iwmmxt_movq_M0_wRn(rd0);
2101 switch ((insn >> 22) & 3) {
2102 case 0:
2103 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2104 break;
2105 case 1:
2106 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2107 break;
2108 case 2:
2109 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2110 break;
2111 case 3:
2112 return 1;
2114 gen_op_iwmmxt_movq_wRn_M0(wrd);
2115 gen_op_iwmmxt_set_mup();
2116 gen_op_iwmmxt_set_cup();
2117 break;
2118 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2119 wrd = (insn >> 12) & 0xf;
2120 rd0 = (insn >> 16) & 0xf;
2121 rd1 = (insn >> 0) & 0xf;
2122 gen_op_iwmmxt_movq_M0_wRn(rd0);
2123 if (insn & (1 << 22)) {
2124 if (insn & (1 << 20))
2125 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2126 else
2127 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2128 } else {
2129 if (insn & (1 << 20))
2130 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2131 else
2132 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2134 gen_op_iwmmxt_movq_wRn_M0(wrd);
2135 gen_op_iwmmxt_set_mup();
2136 gen_op_iwmmxt_set_cup();
2137 break;
2138 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2139 wrd = (insn >> 12) & 0xf;
2140 rd0 = (insn >> 16) & 0xf;
2141 rd1 = (insn >> 0) & 0xf;
2142 gen_op_iwmmxt_movq_M0_wRn(rd0);
2143 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2144 tcg_gen_andi_i32(tmp, tmp, 7);
2145 iwmmxt_load_reg(cpu_V1, rd1);
2146 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2147 tcg_temp_free_i32(tmp);
2148 gen_op_iwmmxt_movq_wRn_M0(wrd);
2149 gen_op_iwmmxt_set_mup();
2150 break;
2151 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2152 if (((insn >> 6) & 3) == 3)
2153 return 1;
2154 rd = (insn >> 12) & 0xf;
2155 wrd = (insn >> 16) & 0xf;
2156 tmp = load_reg(s, rd);
2157 gen_op_iwmmxt_movq_M0_wRn(wrd);
2158 switch ((insn >> 6) & 3) {
2159 case 0:
2160 tmp2 = tcg_const_i32(0xff);
2161 tmp3 = tcg_const_i32((insn & 7) << 3);
2162 break;
2163 case 1:
2164 tmp2 = tcg_const_i32(0xffff);
2165 tmp3 = tcg_const_i32((insn & 3) << 4);
2166 break;
2167 case 2:
2168 tmp2 = tcg_const_i32(0xffffffff);
2169 tmp3 = tcg_const_i32((insn & 1) << 5);
2170 break;
2171 default:
2172 TCGV_UNUSED_I32(tmp2);
2173 TCGV_UNUSED_I32(tmp3);
2175 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2176 tcg_temp_free_i32(tmp3);
2177 tcg_temp_free_i32(tmp2);
2178 tcg_temp_free_i32(tmp);
2179 gen_op_iwmmxt_movq_wRn_M0(wrd);
2180 gen_op_iwmmxt_set_mup();
2181 break;
2182 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2183 rd = (insn >> 12) & 0xf;
2184 wrd = (insn >> 16) & 0xf;
2185 if (rd == 15 || ((insn >> 22) & 3) == 3)
2186 return 1;
2187 gen_op_iwmmxt_movq_M0_wRn(wrd);
2188 tmp = tcg_temp_new_i32();
2189 switch ((insn >> 22) & 3) {
2190 case 0:
2191 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2192 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2193 if (insn & 8) {
2194 tcg_gen_ext8s_i32(tmp, tmp);
2195 } else {
2196 tcg_gen_andi_i32(tmp, tmp, 0xff);
2198 break;
2199 case 1:
2200 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2201 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2202 if (insn & 8) {
2203 tcg_gen_ext16s_i32(tmp, tmp);
2204 } else {
2205 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2207 break;
2208 case 2:
2209 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2210 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2211 break;
2213 store_reg(s, rd, tmp);
2214 break;
2215 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2216 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2217 return 1;
2218 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2219 switch ((insn >> 22) & 3) {
2220 case 0:
2221 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2222 break;
2223 case 1:
2224 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2225 break;
2226 case 2:
2227 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2228 break;
2230 tcg_gen_shli_i32(tmp, tmp, 28);
2231 gen_set_nzcv(tmp);
2232 tcg_temp_free_i32(tmp);
2233 break;
2234 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2235 if (((insn >> 6) & 3) == 3)
2236 return 1;
2237 rd = (insn >> 12) & 0xf;
2238 wrd = (insn >> 16) & 0xf;
2239 tmp = load_reg(s, rd);
2240 switch ((insn >> 6) & 3) {
2241 case 0:
2242 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2243 break;
2244 case 1:
2245 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2246 break;
2247 case 2:
2248 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2249 break;
2251 tcg_temp_free_i32(tmp);
2252 gen_op_iwmmxt_movq_wRn_M0(wrd);
2253 gen_op_iwmmxt_set_mup();
2254 break;
2255 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2256 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2257 return 1;
2258 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2259 tmp2 = tcg_temp_new_i32();
2260 tcg_gen_mov_i32(tmp2, tmp);
2261 switch ((insn >> 22) & 3) {
2262 case 0:
2263 for (i = 0; i < 7; i ++) {
2264 tcg_gen_shli_i32(tmp2, tmp2, 4);
2265 tcg_gen_and_i32(tmp, tmp, tmp2);
2267 break;
2268 case 1:
2269 for (i = 0; i < 3; i ++) {
2270 tcg_gen_shli_i32(tmp2, tmp2, 8);
2271 tcg_gen_and_i32(tmp, tmp, tmp2);
2273 break;
2274 case 2:
2275 tcg_gen_shli_i32(tmp2, tmp2, 16);
2276 tcg_gen_and_i32(tmp, tmp, tmp2);
2277 break;
2279 gen_set_nzcv(tmp);
2280 tcg_temp_free_i32(tmp2);
2281 tcg_temp_free_i32(tmp);
2282 break;
2283 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2284 wrd = (insn >> 12) & 0xf;
2285 rd0 = (insn >> 16) & 0xf;
2286 gen_op_iwmmxt_movq_M0_wRn(rd0);
2287 switch ((insn >> 22) & 3) {
2288 case 0:
2289 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2290 break;
2291 case 1:
2292 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2293 break;
2294 case 2:
2295 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2296 break;
2297 case 3:
2298 return 1;
2300 gen_op_iwmmxt_movq_wRn_M0(wrd);
2301 gen_op_iwmmxt_set_mup();
2302 break;
2303 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2304 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2305 return 1;
2306 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2307 tmp2 = tcg_temp_new_i32();
2308 tcg_gen_mov_i32(tmp2, tmp);
2309 switch ((insn >> 22) & 3) {
2310 case 0:
2311 for (i = 0; i < 7; i ++) {
2312 tcg_gen_shli_i32(tmp2, tmp2, 4);
2313 tcg_gen_or_i32(tmp, tmp, tmp2);
2315 break;
2316 case 1:
2317 for (i = 0; i < 3; i ++) {
2318 tcg_gen_shli_i32(tmp2, tmp2, 8);
2319 tcg_gen_or_i32(tmp, tmp, tmp2);
2321 break;
2322 case 2:
2323 tcg_gen_shli_i32(tmp2, tmp2, 16);
2324 tcg_gen_or_i32(tmp, tmp, tmp2);
2325 break;
2327 gen_set_nzcv(tmp);
2328 tcg_temp_free_i32(tmp2);
2329 tcg_temp_free_i32(tmp);
2330 break;
2331 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2332 rd = (insn >> 12) & 0xf;
2333 rd0 = (insn >> 16) & 0xf;
2334 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2335 return 1;
2336 gen_op_iwmmxt_movq_M0_wRn(rd0);
2337 tmp = tcg_temp_new_i32();
2338 switch ((insn >> 22) & 3) {
2339 case 0:
2340 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2341 break;
2342 case 1:
2343 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2344 break;
2345 case 2:
2346 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2347 break;
2349 store_reg(s, rd, tmp);
2350 break;
2351 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2352 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2353 wrd = (insn >> 12) & 0xf;
2354 rd0 = (insn >> 16) & 0xf;
2355 rd1 = (insn >> 0) & 0xf;
2356 gen_op_iwmmxt_movq_M0_wRn(rd0);
2357 switch ((insn >> 22) & 3) {
2358 case 0:
2359 if (insn & (1 << 21))
2360 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2361 else
2362 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2363 break;
2364 case 1:
2365 if (insn & (1 << 21))
2366 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2367 else
2368 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2369 break;
2370 case 2:
2371 if (insn & (1 << 21))
2372 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2373 else
2374 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2375 break;
2376 case 3:
2377 return 1;
2379 gen_op_iwmmxt_movq_wRn_M0(wrd);
2380 gen_op_iwmmxt_set_mup();
2381 gen_op_iwmmxt_set_cup();
2382 break;
2383 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2384 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2385 wrd = (insn >> 12) & 0xf;
2386 rd0 = (insn >> 16) & 0xf;
2387 gen_op_iwmmxt_movq_M0_wRn(rd0);
2388 switch ((insn >> 22) & 3) {
2389 case 0:
2390 if (insn & (1 << 21))
2391 gen_op_iwmmxt_unpacklsb_M0();
2392 else
2393 gen_op_iwmmxt_unpacklub_M0();
2394 break;
2395 case 1:
2396 if (insn & (1 << 21))
2397 gen_op_iwmmxt_unpacklsw_M0();
2398 else
2399 gen_op_iwmmxt_unpackluw_M0();
2400 break;
2401 case 2:
2402 if (insn & (1 << 21))
2403 gen_op_iwmmxt_unpacklsl_M0();
2404 else
2405 gen_op_iwmmxt_unpacklul_M0();
2406 break;
2407 case 3:
2408 return 1;
2410 gen_op_iwmmxt_movq_wRn_M0(wrd);
2411 gen_op_iwmmxt_set_mup();
2412 gen_op_iwmmxt_set_cup();
2413 break;
2414 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2415 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2416 wrd = (insn >> 12) & 0xf;
2417 rd0 = (insn >> 16) & 0xf;
2418 gen_op_iwmmxt_movq_M0_wRn(rd0);
2419 switch ((insn >> 22) & 3) {
2420 case 0:
2421 if (insn & (1 << 21))
2422 gen_op_iwmmxt_unpackhsb_M0();
2423 else
2424 gen_op_iwmmxt_unpackhub_M0();
2425 break;
2426 case 1:
2427 if (insn & (1 << 21))
2428 gen_op_iwmmxt_unpackhsw_M0();
2429 else
2430 gen_op_iwmmxt_unpackhuw_M0();
2431 break;
2432 case 2:
2433 if (insn & (1 << 21))
2434 gen_op_iwmmxt_unpackhsl_M0();
2435 else
2436 gen_op_iwmmxt_unpackhul_M0();
2437 break;
2438 case 3:
2439 return 1;
2441 gen_op_iwmmxt_movq_wRn_M0(wrd);
2442 gen_op_iwmmxt_set_mup();
2443 gen_op_iwmmxt_set_cup();
2444 break;
2445 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2446 case 0x214: case 0x614: case 0xa14: case 0xe14:
2447 if (((insn >> 22) & 3) == 0)
2448 return 1;
2449 wrd = (insn >> 12) & 0xf;
2450 rd0 = (insn >> 16) & 0xf;
2451 gen_op_iwmmxt_movq_M0_wRn(rd0);
2452 tmp = tcg_temp_new_i32();
2453 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2454 tcg_temp_free_i32(tmp);
2455 return 1;
2457 switch ((insn >> 22) & 3) {
2458 case 1:
2459 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2460 break;
2461 case 2:
2462 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2463 break;
2464 case 3:
2465 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2466 break;
2468 tcg_temp_free_i32(tmp);
2469 gen_op_iwmmxt_movq_wRn_M0(wrd);
2470 gen_op_iwmmxt_set_mup();
2471 gen_op_iwmmxt_set_cup();
2472 break;
2473 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2474 case 0x014: case 0x414: case 0x814: case 0xc14:
2475 if (((insn >> 22) & 3) == 0)
2476 return 1;
2477 wrd = (insn >> 12) & 0xf;
2478 rd0 = (insn >> 16) & 0xf;
2479 gen_op_iwmmxt_movq_M0_wRn(rd0);
2480 tmp = tcg_temp_new_i32();
2481 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2482 tcg_temp_free_i32(tmp);
2483 return 1;
2485 switch ((insn >> 22) & 3) {
2486 case 1:
2487 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2488 break;
2489 case 2:
2490 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2491 break;
2492 case 3:
2493 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2494 break;
2496 tcg_temp_free_i32(tmp);
2497 gen_op_iwmmxt_movq_wRn_M0(wrd);
2498 gen_op_iwmmxt_set_mup();
2499 gen_op_iwmmxt_set_cup();
2500 break;
2501 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2502 case 0x114: case 0x514: case 0x914: case 0xd14:
2503 if (((insn >> 22) & 3) == 0)
2504 return 1;
2505 wrd = (insn >> 12) & 0xf;
2506 rd0 = (insn >> 16) & 0xf;
2507 gen_op_iwmmxt_movq_M0_wRn(rd0);
2508 tmp = tcg_temp_new_i32();
2509 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2510 tcg_temp_free_i32(tmp);
2511 return 1;
2513 switch ((insn >> 22) & 3) {
2514 case 1:
2515 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2516 break;
2517 case 2:
2518 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2519 break;
2520 case 3:
2521 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2522 break;
2524 tcg_temp_free_i32(tmp);
2525 gen_op_iwmmxt_movq_wRn_M0(wrd);
2526 gen_op_iwmmxt_set_mup();
2527 gen_op_iwmmxt_set_cup();
2528 break;
2529 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2530 case 0x314: case 0x714: case 0xb14: case 0xf14:
2531 if (((insn >> 22) & 3) == 0)
2532 return 1;
2533 wrd = (insn >> 12) & 0xf;
2534 rd0 = (insn >> 16) & 0xf;
2535 gen_op_iwmmxt_movq_M0_wRn(rd0);
2536 tmp = tcg_temp_new_i32();
2537 switch ((insn >> 22) & 3) {
2538 case 1:
2539 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2540 tcg_temp_free_i32(tmp);
2541 return 1;
2543 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2544 break;
2545 case 2:
2546 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2547 tcg_temp_free_i32(tmp);
2548 return 1;
2550 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2551 break;
2552 case 3:
2553 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2554 tcg_temp_free_i32(tmp);
2555 return 1;
2557 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2558 break;
2560 tcg_temp_free_i32(tmp);
2561 gen_op_iwmmxt_movq_wRn_M0(wrd);
2562 gen_op_iwmmxt_set_mup();
2563 gen_op_iwmmxt_set_cup();
2564 break;
2565 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2566 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2567 wrd = (insn >> 12) & 0xf;
2568 rd0 = (insn >> 16) & 0xf;
2569 rd1 = (insn >> 0) & 0xf;
2570 gen_op_iwmmxt_movq_M0_wRn(rd0);
2571 switch ((insn >> 22) & 3) {
2572 case 0:
2573 if (insn & (1 << 21))
2574 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2575 else
2576 gen_op_iwmmxt_minub_M0_wRn(rd1);
2577 break;
2578 case 1:
2579 if (insn & (1 << 21))
2580 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2581 else
2582 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2583 break;
2584 case 2:
2585 if (insn & (1 << 21))
2586 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2587 else
2588 gen_op_iwmmxt_minul_M0_wRn(rd1);
2589 break;
2590 case 3:
2591 return 1;
2593 gen_op_iwmmxt_movq_wRn_M0(wrd);
2594 gen_op_iwmmxt_set_mup();
2595 break;
2596 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2597 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2598 wrd = (insn >> 12) & 0xf;
2599 rd0 = (insn >> 16) & 0xf;
2600 rd1 = (insn >> 0) & 0xf;
2601 gen_op_iwmmxt_movq_M0_wRn(rd0);
2602 switch ((insn >> 22) & 3) {
2603 case 0:
2604 if (insn & (1 << 21))
2605 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2606 else
2607 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2608 break;
2609 case 1:
2610 if (insn & (1 << 21))
2611 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2612 else
2613 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2614 break;
2615 case 2:
2616 if (insn & (1 << 21))
2617 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2618 else
2619 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2620 break;
2621 case 3:
2622 return 1;
2624 gen_op_iwmmxt_movq_wRn_M0(wrd);
2625 gen_op_iwmmxt_set_mup();
2626 break;
2627 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2628 case 0x402: case 0x502: case 0x602: case 0x702:
2629 wrd = (insn >> 12) & 0xf;
2630 rd0 = (insn >> 16) & 0xf;
2631 rd1 = (insn >> 0) & 0xf;
2632 gen_op_iwmmxt_movq_M0_wRn(rd0);
2633 tmp = tcg_const_i32((insn >> 20) & 3);
2634 iwmmxt_load_reg(cpu_V1, rd1);
2635 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2636 tcg_temp_free_i32(tmp);
2637 gen_op_iwmmxt_movq_wRn_M0(wrd);
2638 gen_op_iwmmxt_set_mup();
2639 break;
2640 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2641 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2642 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2643 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2644 wrd = (insn >> 12) & 0xf;
2645 rd0 = (insn >> 16) & 0xf;
2646 rd1 = (insn >> 0) & 0xf;
2647 gen_op_iwmmxt_movq_M0_wRn(rd0);
2648 switch ((insn >> 20) & 0xf) {
2649 case 0x0:
2650 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2651 break;
2652 case 0x1:
2653 gen_op_iwmmxt_subub_M0_wRn(rd1);
2654 break;
2655 case 0x3:
2656 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2657 break;
2658 case 0x4:
2659 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2660 break;
2661 case 0x5:
2662 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2663 break;
2664 case 0x7:
2665 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2666 break;
2667 case 0x8:
2668 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2669 break;
2670 case 0x9:
2671 gen_op_iwmmxt_subul_M0_wRn(rd1);
2672 break;
2673 case 0xb:
2674 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2675 break;
2676 default:
2677 return 1;
2679 gen_op_iwmmxt_movq_wRn_M0(wrd);
2680 gen_op_iwmmxt_set_mup();
2681 gen_op_iwmmxt_set_cup();
2682 break;
2683 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2684 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2685 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2686 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2687 wrd = (insn >> 12) & 0xf;
2688 rd0 = (insn >> 16) & 0xf;
2689 gen_op_iwmmxt_movq_M0_wRn(rd0);
2690 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2691 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2692 tcg_temp_free_i32(tmp);
2693 gen_op_iwmmxt_movq_wRn_M0(wrd);
2694 gen_op_iwmmxt_set_mup();
2695 gen_op_iwmmxt_set_cup();
2696 break;
2697 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2698 case 0x418: case 0x518: case 0x618: case 0x718:
2699 case 0x818: case 0x918: case 0xa18: case 0xb18:
2700 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2701 wrd = (insn >> 12) & 0xf;
2702 rd0 = (insn >> 16) & 0xf;
2703 rd1 = (insn >> 0) & 0xf;
2704 gen_op_iwmmxt_movq_M0_wRn(rd0);
2705 switch ((insn >> 20) & 0xf) {
2706 case 0x0:
2707 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2708 break;
2709 case 0x1:
2710 gen_op_iwmmxt_addub_M0_wRn(rd1);
2711 break;
2712 case 0x3:
2713 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2714 break;
2715 case 0x4:
2716 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2717 break;
2718 case 0x5:
2719 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2720 break;
2721 case 0x7:
2722 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2723 break;
2724 case 0x8:
2725 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2726 break;
2727 case 0x9:
2728 gen_op_iwmmxt_addul_M0_wRn(rd1);
2729 break;
2730 case 0xb:
2731 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2732 break;
2733 default:
2734 return 1;
2736 gen_op_iwmmxt_movq_wRn_M0(wrd);
2737 gen_op_iwmmxt_set_mup();
2738 gen_op_iwmmxt_set_cup();
2739 break;
2740 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2741 case 0x408: case 0x508: case 0x608: case 0x708:
2742 case 0x808: case 0x908: case 0xa08: case 0xb08:
2743 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2744 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2745 return 1;
2746 wrd = (insn >> 12) & 0xf;
2747 rd0 = (insn >> 16) & 0xf;
2748 rd1 = (insn >> 0) & 0xf;
2749 gen_op_iwmmxt_movq_M0_wRn(rd0);
2750 switch ((insn >> 22) & 3) {
2751 case 1:
2752 if (insn & (1 << 21))
2753 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2754 else
2755 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2756 break;
2757 case 2:
2758 if (insn & (1 << 21))
2759 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2760 else
2761 gen_op_iwmmxt_packul_M0_wRn(rd1);
2762 break;
2763 case 3:
2764 if (insn & (1 << 21))
2765 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2766 else
2767 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2768 break;
2770 gen_op_iwmmxt_movq_wRn_M0(wrd);
2771 gen_op_iwmmxt_set_mup();
2772 gen_op_iwmmxt_set_cup();
2773 break;
2774 case 0x201: case 0x203: case 0x205: case 0x207:
2775 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2776 case 0x211: case 0x213: case 0x215: case 0x217:
2777 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2778 wrd = (insn >> 5) & 0xf;
2779 rd0 = (insn >> 12) & 0xf;
2780 rd1 = (insn >> 0) & 0xf;
2781 if (rd0 == 0xf || rd1 == 0xf)
2782 return 1;
2783 gen_op_iwmmxt_movq_M0_wRn(wrd);
2784 tmp = load_reg(s, rd0);
2785 tmp2 = load_reg(s, rd1);
2786 switch ((insn >> 16) & 0xf) {
2787 case 0x0: /* TMIA */
2788 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2789 break;
2790 case 0x8: /* TMIAPH */
2791 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2792 break;
2793 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2794 if (insn & (1 << 16))
2795 tcg_gen_shri_i32(tmp, tmp, 16);
2796 if (insn & (1 << 17))
2797 tcg_gen_shri_i32(tmp2, tmp2, 16);
2798 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2799 break;
2800 default:
2801 tcg_temp_free_i32(tmp2);
2802 tcg_temp_free_i32(tmp);
2803 return 1;
2805 tcg_temp_free_i32(tmp2);
2806 tcg_temp_free_i32(tmp);
2807 gen_op_iwmmxt_movq_wRn_M0(wrd);
2808 gen_op_iwmmxt_set_mup();
2809 break;
2810 default:
2811 return 1;
2814 return 0;
2817 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2818 (ie. an undefined instruction). */
2819 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2821 int acc, rd0, rd1, rdhi, rdlo;
2822 TCGv_i32 tmp, tmp2;
2824 if ((insn & 0x0ff00f10) == 0x0e200010) {
2825 /* Multiply with Internal Accumulate Format */
2826 rd0 = (insn >> 12) & 0xf;
2827 rd1 = insn & 0xf;
2828 acc = (insn >> 5) & 7;
2830 if (acc != 0)
2831 return 1;
2833 tmp = load_reg(s, rd0);
2834 tmp2 = load_reg(s, rd1);
2835 switch ((insn >> 16) & 0xf) {
2836 case 0x0: /* MIA */
2837 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2838 break;
2839 case 0x8: /* MIAPH */
2840 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2841 break;
2842 case 0xc: /* MIABB */
2843 case 0xd: /* MIABT */
2844 case 0xe: /* MIATB */
2845 case 0xf: /* MIATT */
2846 if (insn & (1 << 16))
2847 tcg_gen_shri_i32(tmp, tmp, 16);
2848 if (insn & (1 << 17))
2849 tcg_gen_shri_i32(tmp2, tmp2, 16);
2850 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2851 break;
2852 default:
2853 return 1;
2855 tcg_temp_free_i32(tmp2);
2856 tcg_temp_free_i32(tmp);
2858 gen_op_iwmmxt_movq_wRn_M0(acc);
2859 return 0;
2862 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2863 /* Internal Accumulator Access Format */
2864 rdhi = (insn >> 16) & 0xf;
2865 rdlo = (insn >> 12) & 0xf;
2866 acc = insn & 7;
2868 if (acc != 0)
2869 return 1;
2871 if (insn & ARM_CP_RW_BIT) { /* MRA */
2872 iwmmxt_load_reg(cpu_V0, acc);
2873 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2874 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2875 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2876 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2877 } else { /* MAR */
2878 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2879 iwmmxt_store_reg(cpu_V0, acc);
2881 return 0;
2884 return 1;
2887 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2888 #define VFP_SREG(insn, bigbit, smallbit) \
2889 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2890 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2891 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2892 reg = (((insn) >> (bigbit)) & 0x0f) \
2893 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2894 } else { \
2895 if (insn & (1 << (smallbit))) \
2896 return 1; \
2897 reg = ((insn) >> (bigbit)) & 0x0f; \
2898 }} while (0)
2900 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2901 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2902 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2903 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2904 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2905 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2907 /* Move between integer and VFP cores. */
2908 static TCGv_i32 gen_vfp_mrs(void)
2910 TCGv_i32 tmp = tcg_temp_new_i32();
2911 tcg_gen_mov_i32(tmp, cpu_F0s);
2912 return tmp;
2915 static void gen_vfp_msr(TCGv_i32 tmp)
2917 tcg_gen_mov_i32(cpu_F0s, tmp);
2918 tcg_temp_free_i32(tmp);
2921 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2923 TCGv_i32 tmp = tcg_temp_new_i32();
2924 if (shift)
2925 tcg_gen_shri_i32(var, var, shift);
2926 tcg_gen_ext8u_i32(var, var);
2927 tcg_gen_shli_i32(tmp, var, 8);
2928 tcg_gen_or_i32(var, var, tmp);
2929 tcg_gen_shli_i32(tmp, var, 16);
2930 tcg_gen_or_i32(var, var, tmp);
2931 tcg_temp_free_i32(tmp);
2934 static void gen_neon_dup_low16(TCGv_i32 var)
2936 TCGv_i32 tmp = tcg_temp_new_i32();
2937 tcg_gen_ext16u_i32(var, var);
2938 tcg_gen_shli_i32(tmp, var, 16);
2939 tcg_gen_or_i32(var, var, tmp);
2940 tcg_temp_free_i32(tmp);
2943 static void gen_neon_dup_high16(TCGv_i32 var)
2945 TCGv_i32 tmp = tcg_temp_new_i32();
2946 tcg_gen_andi_i32(var, var, 0xffff0000);
2947 tcg_gen_shri_i32(tmp, var, 16);
2948 tcg_gen_or_i32(var, var, tmp);
2949 tcg_temp_free_i32(tmp);
2952 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2954 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2955 TCGv_i32 tmp = tcg_temp_new_i32();
2956 switch (size) {
2957 case 0:
2958 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2959 gen_neon_dup_u8(tmp, 0);
2960 break;
2961 case 1:
2962 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2963 gen_neon_dup_low16(tmp);
2964 break;
2965 case 2:
2966 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2967 break;
2968 default: /* Avoid compiler warnings. */
2969 abort();
2971 return tmp;
2974 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2975 uint32_t dp)
2977 uint32_t cc = extract32(insn, 20, 2);
2979 if (dp) {
2980 TCGv_i64 frn, frm, dest;
2981 TCGv_i64 tmp, zero, zf, nf, vf;
2983 zero = tcg_const_i64(0);
2985 frn = tcg_temp_new_i64();
2986 frm = tcg_temp_new_i64();
2987 dest = tcg_temp_new_i64();
2989 zf = tcg_temp_new_i64();
2990 nf = tcg_temp_new_i64();
2991 vf = tcg_temp_new_i64();
2993 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2994 tcg_gen_ext_i32_i64(nf, cpu_NF);
2995 tcg_gen_ext_i32_i64(vf, cpu_VF);
2997 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2998 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2999 switch (cc) {
3000 case 0: /* eq: Z */
3001 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3002 frn, frm);
3003 break;
3004 case 1: /* vs: V */
3005 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3006 frn, frm);
3007 break;
3008 case 2: /* ge: N == V -> N ^ V == 0 */
3009 tmp = tcg_temp_new_i64();
3010 tcg_gen_xor_i64(tmp, vf, nf);
3011 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3012 frn, frm);
3013 tcg_temp_free_i64(tmp);
3014 break;
3015 case 3: /* gt: !Z && N == V */
3016 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3017 frn, frm);
3018 tmp = tcg_temp_new_i64();
3019 tcg_gen_xor_i64(tmp, vf, nf);
3020 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3021 dest, frm);
3022 tcg_temp_free_i64(tmp);
3023 break;
3025 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3026 tcg_temp_free_i64(frn);
3027 tcg_temp_free_i64(frm);
3028 tcg_temp_free_i64(dest);
3030 tcg_temp_free_i64(zf);
3031 tcg_temp_free_i64(nf);
3032 tcg_temp_free_i64(vf);
3034 tcg_temp_free_i64(zero);
3035 } else {
3036 TCGv_i32 frn, frm, dest;
3037 TCGv_i32 tmp, zero;
3039 zero = tcg_const_i32(0);
3041 frn = tcg_temp_new_i32();
3042 frm = tcg_temp_new_i32();
3043 dest = tcg_temp_new_i32();
3044 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3045 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3046 switch (cc) {
3047 case 0: /* eq: Z */
3048 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3049 frn, frm);
3050 break;
3051 case 1: /* vs: V */
3052 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3053 frn, frm);
3054 break;
3055 case 2: /* ge: N == V -> N ^ V == 0 */
3056 tmp = tcg_temp_new_i32();
3057 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3058 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3059 frn, frm);
3060 tcg_temp_free_i32(tmp);
3061 break;
3062 case 3: /* gt: !Z && N == V */
3063 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3064 frn, frm);
3065 tmp = tcg_temp_new_i32();
3066 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3067 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3068 dest, frm);
3069 tcg_temp_free_i32(tmp);
3070 break;
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);
3077 tcg_temp_free_i32(zero);
3080 return 0;
3083 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3084 uint32_t rm, uint32_t dp)
3086 uint32_t vmin = extract32(insn, 6, 1);
3087 TCGv_ptr fpst = get_fpstatus_ptr(0);
3089 if (dp) {
3090 TCGv_i64 frn, frm, dest;
3092 frn = tcg_temp_new_i64();
3093 frm = tcg_temp_new_i64();
3094 dest = tcg_temp_new_i64();
3096 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3097 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3098 if (vmin) {
3099 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3100 } else {
3101 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3103 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3104 tcg_temp_free_i64(frn);
3105 tcg_temp_free_i64(frm);
3106 tcg_temp_free_i64(dest);
3107 } else {
3108 TCGv_i32 frn, frm, dest;
3110 frn = tcg_temp_new_i32();
3111 frm = tcg_temp_new_i32();
3112 dest = tcg_temp_new_i32();
3114 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3115 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3116 if (vmin) {
3117 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3118 } else {
3119 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3121 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3122 tcg_temp_free_i32(frn);
3123 tcg_temp_free_i32(frm);
3124 tcg_temp_free_i32(dest);
3127 tcg_temp_free_ptr(fpst);
3128 return 0;
3131 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3132 int rounding)
3134 TCGv_ptr fpst = get_fpstatus_ptr(0);
3135 TCGv_i32 tcg_rmode;
3137 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3138 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3140 if (dp) {
3141 TCGv_i64 tcg_op;
3142 TCGv_i64 tcg_res;
3143 tcg_op = tcg_temp_new_i64();
3144 tcg_res = tcg_temp_new_i64();
3145 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3146 gen_helper_rintd(tcg_res, tcg_op, fpst);
3147 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3148 tcg_temp_free_i64(tcg_op);
3149 tcg_temp_free_i64(tcg_res);
3150 } else {
3151 TCGv_i32 tcg_op;
3152 TCGv_i32 tcg_res;
3153 tcg_op = tcg_temp_new_i32();
3154 tcg_res = tcg_temp_new_i32();
3155 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3156 gen_helper_rints(tcg_res, tcg_op, fpst);
3157 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3158 tcg_temp_free_i32(tcg_op);
3159 tcg_temp_free_i32(tcg_res);
3162 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3163 tcg_temp_free_i32(tcg_rmode);
3165 tcg_temp_free_ptr(fpst);
3166 return 0;
3169 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3170 int rounding)
3172 bool is_signed = extract32(insn, 7, 1);
3173 TCGv_ptr fpst = get_fpstatus_ptr(0);
3174 TCGv_i32 tcg_rmode, tcg_shift;
3176 tcg_shift = tcg_const_i32(0);
3178 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3179 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3181 if (dp) {
3182 TCGv_i64 tcg_double, tcg_res;
3183 TCGv_i32 tcg_tmp;
3184 /* Rd is encoded as a single precision register even when the source
3185 * is double precision.
3187 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3188 tcg_double = tcg_temp_new_i64();
3189 tcg_res = tcg_temp_new_i64();
3190 tcg_tmp = tcg_temp_new_i32();
3191 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3192 if (is_signed) {
3193 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3194 } else {
3195 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3197 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3198 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3199 tcg_temp_free_i32(tcg_tmp);
3200 tcg_temp_free_i64(tcg_res);
3201 tcg_temp_free_i64(tcg_double);
3202 } else {
3203 TCGv_i32 tcg_single, tcg_res;
3204 tcg_single = tcg_temp_new_i32();
3205 tcg_res = tcg_temp_new_i32();
3206 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3207 if (is_signed) {
3208 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3209 } else {
3210 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3212 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3213 tcg_temp_free_i32(tcg_res);
3214 tcg_temp_free_i32(tcg_single);
3217 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3218 tcg_temp_free_i32(tcg_rmode);
3220 tcg_temp_free_i32(tcg_shift);
3222 tcg_temp_free_ptr(fpst);
3224 return 0;
3227 /* Table for converting the most common AArch32 encoding of
3228 * rounding mode to arm_fprounding order (which matches the
3229 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3231 static const uint8_t fp_decode_rm[] = {
3232 FPROUNDING_TIEAWAY,
3233 FPROUNDING_TIEEVEN,
3234 FPROUNDING_POSINF,
3235 FPROUNDING_NEGINF,
3238 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3240 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3242 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3243 return 1;
3246 if (dp) {
3247 VFP_DREG_D(rd, insn);
3248 VFP_DREG_N(rn, insn);
3249 VFP_DREG_M(rm, insn);
3250 } else {
3251 rd = VFP_SREG_D(insn);
3252 rn = VFP_SREG_N(insn);
3253 rm = VFP_SREG_M(insn);
3256 if ((insn & 0x0f800e50) == 0x0e000a00) {
3257 return handle_vsel(insn, rd, rn, rm, dp);
3258 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3259 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3260 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3261 /* VRINTA, VRINTN, VRINTP, VRINTM */
3262 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3263 return handle_vrint(insn, rd, rm, dp, rounding);
3264 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3265 /* VCVTA, VCVTN, VCVTP, VCVTM */
3266 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3267 return handle_vcvt(insn, rd, rm, dp, rounding);
3269 return 1;
3272 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3273 (ie. an undefined instruction). */
3274 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3276 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3277 int dp, veclen;
3278 TCGv_i32 addr;
3279 TCGv_i32 tmp;
3280 TCGv_i32 tmp2;
3282 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3283 return 1;
3286 /* FIXME: this access check should not take precedence over UNDEF
3287 * for invalid encodings; we will generate incorrect syndrome information
3288 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3290 if (s->fp_excp_el) {
3291 gen_exception_insn(s, 4, EXCP_UDEF,
3292 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3293 return 0;
3296 if (!s->vfp_enabled) {
3297 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3298 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3299 return 1;
3300 rn = (insn >> 16) & 0xf;
3301 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3302 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3303 return 1;
3307 if (extract32(insn, 28, 4) == 0xf) {
3308 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3309 * only used in v8 and above.
3311 return disas_vfp_v8_insn(s, insn);
3314 dp = ((insn & 0xf00) == 0xb00);
3315 switch ((insn >> 24) & 0xf) {
3316 case 0xe:
3317 if (insn & (1 << 4)) {
3318 /* single register transfer */
3319 rd = (insn >> 12) & 0xf;
3320 if (dp) {
3321 int size;
3322 int pass;
3324 VFP_DREG_N(rn, insn);
3325 if (insn & 0xf)
3326 return 1;
3327 if (insn & 0x00c00060
3328 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3329 return 1;
3332 pass = (insn >> 21) & 1;
3333 if (insn & (1 << 22)) {
3334 size = 0;
3335 offset = ((insn >> 5) & 3) * 8;
3336 } else if (insn & (1 << 5)) {
3337 size = 1;
3338 offset = (insn & (1 << 6)) ? 16 : 0;
3339 } else {
3340 size = 2;
3341 offset = 0;
3343 if (insn & ARM_CP_RW_BIT) {
3344 /* vfp->arm */
3345 tmp = neon_load_reg(rn, pass);
3346 switch (size) {
3347 case 0:
3348 if (offset)
3349 tcg_gen_shri_i32(tmp, tmp, offset);
3350 if (insn & (1 << 23))
3351 gen_uxtb(tmp);
3352 else
3353 gen_sxtb(tmp);
3354 break;
3355 case 1:
3356 if (insn & (1 << 23)) {
3357 if (offset) {
3358 tcg_gen_shri_i32(tmp, tmp, 16);
3359 } else {
3360 gen_uxth(tmp);
3362 } else {
3363 if (offset) {
3364 tcg_gen_sari_i32(tmp, tmp, 16);
3365 } else {
3366 gen_sxth(tmp);
3369 break;
3370 case 2:
3371 break;
3373 store_reg(s, rd, tmp);
3374 } else {
3375 /* arm->vfp */
3376 tmp = load_reg(s, rd);
3377 if (insn & (1 << 23)) {
3378 /* VDUP */
3379 if (size == 0) {
3380 gen_neon_dup_u8(tmp, 0);
3381 } else if (size == 1) {
3382 gen_neon_dup_low16(tmp);
3384 for (n = 0; n <= pass * 2; n++) {
3385 tmp2 = tcg_temp_new_i32();
3386 tcg_gen_mov_i32(tmp2, tmp);
3387 neon_store_reg(rn, n, tmp2);
3389 neon_store_reg(rn, n, tmp);
3390 } else {
3391 /* VMOV */
3392 switch (size) {
3393 case 0:
3394 tmp2 = neon_load_reg(rn, pass);
3395 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3396 tcg_temp_free_i32(tmp2);
3397 break;
3398 case 1:
3399 tmp2 = neon_load_reg(rn, pass);
3400 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3401 tcg_temp_free_i32(tmp2);
3402 break;
3403 case 2:
3404 break;
3406 neon_store_reg(rn, pass, tmp);
3409 } else { /* !dp */
3410 if ((insn & 0x6f) != 0x00)
3411 return 1;
3412 rn = VFP_SREG_N(insn);
3413 if (insn & ARM_CP_RW_BIT) {
3414 /* vfp->arm */
3415 if (insn & (1 << 21)) {
3416 /* system register */
3417 rn >>= 1;
3419 switch (rn) {
3420 case ARM_VFP_FPSID:
3421 /* VFP2 allows access to FSID from userspace.
3422 VFP3 restricts all id registers to privileged
3423 accesses. */
3424 if (IS_USER(s)
3425 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3426 return 1;
3428 tmp = load_cpu_field(vfp.xregs[rn]);
3429 break;
3430 case ARM_VFP_FPEXC:
3431 if (IS_USER(s))
3432 return 1;
3433 tmp = load_cpu_field(vfp.xregs[rn]);
3434 break;
3435 case ARM_VFP_FPINST:
3436 case ARM_VFP_FPINST2:
3437 /* Not present in VFP3. */
3438 if (IS_USER(s)
3439 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3440 return 1;
3442 tmp = load_cpu_field(vfp.xregs[rn]);
3443 break;
3444 case ARM_VFP_FPSCR:
3445 if (rd == 15) {
3446 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3447 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3448 } else {
3449 tmp = tcg_temp_new_i32();
3450 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3452 break;
3453 case ARM_VFP_MVFR2:
3454 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3455 return 1;
3457 /* fall through */
3458 case ARM_VFP_MVFR0:
3459 case ARM_VFP_MVFR1:
3460 if (IS_USER(s)
3461 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3462 return 1;
3464 tmp = load_cpu_field(vfp.xregs[rn]);
3465 break;
3466 default:
3467 return 1;
3469 } else {
3470 gen_mov_F0_vreg(0, rn);
3471 tmp = gen_vfp_mrs();
3473 if (rd == 15) {
3474 /* Set the 4 flag bits in the CPSR. */
3475 gen_set_nzcv(tmp);
3476 tcg_temp_free_i32(tmp);
3477 } else {
3478 store_reg(s, rd, tmp);
3480 } else {
3481 /* arm->vfp */
3482 if (insn & (1 << 21)) {
3483 rn >>= 1;
3484 /* system register */
3485 switch (rn) {
3486 case ARM_VFP_FPSID:
3487 case ARM_VFP_MVFR0:
3488 case ARM_VFP_MVFR1:
3489 /* Writes are ignored. */
3490 break;
3491 case ARM_VFP_FPSCR:
3492 tmp = load_reg(s, rd);
3493 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3494 tcg_temp_free_i32(tmp);
3495 gen_lookup_tb(s);
3496 break;
3497 case ARM_VFP_FPEXC:
3498 if (IS_USER(s))
3499 return 1;
3500 /* TODO: VFP subarchitecture support.
3501 * For now, keep the EN bit only */
3502 tmp = load_reg(s, rd);
3503 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3504 store_cpu_field(tmp, vfp.xregs[rn]);
3505 gen_lookup_tb(s);
3506 break;
3507 case ARM_VFP_FPINST:
3508 case ARM_VFP_FPINST2:
3509 if (IS_USER(s)) {
3510 return 1;
3512 tmp = load_reg(s, rd);
3513 store_cpu_field(tmp, vfp.xregs[rn]);
3514 break;
3515 default:
3516 return 1;
3518 } else {
3519 tmp = load_reg(s, rd);
3520 gen_vfp_msr(tmp);
3521 gen_mov_vreg_F0(0, rn);
3525 } else {
3526 /* data processing */
3527 /* The opcode is in bits 23, 21, 20 and 6. */
3528 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3529 if (dp) {
3530 if (op == 15) {
3531 /* rn is opcode */
3532 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3533 } else {
3534 /* rn is register number */
3535 VFP_DREG_N(rn, insn);
3538 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3539 ((rn & 0x1e) == 0x6))) {
3540 /* Integer or single/half precision destination. */
3541 rd = VFP_SREG_D(insn);
3542 } else {
3543 VFP_DREG_D(rd, insn);
3545 if (op == 15 &&
3546 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3547 ((rn & 0x1e) == 0x4))) {
3548 /* VCVT from int or half precision is always from S reg
3549 * regardless of dp bit. VCVT with immediate frac_bits
3550 * has same format as SREG_M.
3552 rm = VFP_SREG_M(insn);
3553 } else {
3554 VFP_DREG_M(rm, insn);
3556 } else {
3557 rn = VFP_SREG_N(insn);
3558 if (op == 15 && rn == 15) {
3559 /* Double precision destination. */
3560 VFP_DREG_D(rd, insn);
3561 } else {
3562 rd = VFP_SREG_D(insn);
3564 /* NB that we implicitly rely on the encoding for the frac_bits
3565 * in VCVT of fixed to float being the same as that of an SREG_M
3567 rm = VFP_SREG_M(insn);
3570 veclen = s->vec_len;
3571 if (op == 15 && rn > 3)
3572 veclen = 0;
3574 /* Shut up compiler warnings. */
3575 delta_m = 0;
3576 delta_d = 0;
3577 bank_mask = 0;
3579 if (veclen > 0) {
3580 if (dp)
3581 bank_mask = 0xc;
3582 else
3583 bank_mask = 0x18;
3585 /* Figure out what type of vector operation this is. */
3586 if ((rd & bank_mask) == 0) {
3587 /* scalar */
3588 veclen = 0;
3589 } else {
3590 if (dp)
3591 delta_d = (s->vec_stride >> 1) + 1;
3592 else
3593 delta_d = s->vec_stride + 1;
3595 if ((rm & bank_mask) == 0) {
3596 /* mixed scalar/vector */
3597 delta_m = 0;
3598 } else {
3599 /* vector */
3600 delta_m = delta_d;
3605 /* Load the initial operands. */
3606 if (op == 15) {
3607 switch (rn) {
3608 case 16:
3609 case 17:
3610 /* Integer source */
3611 gen_mov_F0_vreg(0, rm);
3612 break;
3613 case 8:
3614 case 9:
3615 /* Compare */
3616 gen_mov_F0_vreg(dp, rd);
3617 gen_mov_F1_vreg(dp, rm);
3618 break;
3619 case 10:
3620 case 11:
3621 /* Compare with zero */
3622 gen_mov_F0_vreg(dp, rd);
3623 gen_vfp_F1_ld0(dp);
3624 break;
3625 case 20:
3626 case 21:
3627 case 22:
3628 case 23:
3629 case 28:
3630 case 29:
3631 case 30:
3632 case 31:
3633 /* Source and destination the same. */
3634 gen_mov_F0_vreg(dp, rd);
3635 break;
3636 case 4:
3637 case 5:
3638 case 6:
3639 case 7:
3640 /* VCVTB, VCVTT: only present with the halfprec extension
3641 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3642 * (we choose to UNDEF)
3644 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3645 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3646 return 1;
3648 if (!extract32(rn, 1, 1)) {
3649 /* Half precision source. */
3650 gen_mov_F0_vreg(0, rm);
3651 break;
3653 /* Otherwise fall through */
3654 default:
3655 /* One source operand. */
3656 gen_mov_F0_vreg(dp, rm);
3657 break;
3659 } else {
3660 /* Two source operands. */
3661 gen_mov_F0_vreg(dp, rn);
3662 gen_mov_F1_vreg(dp, rm);
3665 for (;;) {
3666 /* Perform the calculation. */
3667 switch (op) {
3668 case 0: /* VMLA: fd + (fn * fm) */
3669 /* Note that order of inputs to the add matters for NaNs */
3670 gen_vfp_F1_mul(dp);
3671 gen_mov_F0_vreg(dp, rd);
3672 gen_vfp_add(dp);
3673 break;
3674 case 1: /* VMLS: fd + -(fn * fm) */
3675 gen_vfp_mul(dp);
3676 gen_vfp_F1_neg(dp);
3677 gen_mov_F0_vreg(dp, rd);
3678 gen_vfp_add(dp);
3679 break;
3680 case 2: /* VNMLS: -fd + (fn * fm) */
3681 /* Note that it isn't valid to replace (-A + B) with (B - A)
3682 * or similar plausible looking simplifications
3683 * because this will give wrong results for NaNs.
3685 gen_vfp_F1_mul(dp);
3686 gen_mov_F0_vreg(dp, rd);
3687 gen_vfp_neg(dp);
3688 gen_vfp_add(dp);
3689 break;
3690 case 3: /* VNMLA: -fd + -(fn * fm) */
3691 gen_vfp_mul(dp);
3692 gen_vfp_F1_neg(dp);
3693 gen_mov_F0_vreg(dp, rd);
3694 gen_vfp_neg(dp);
3695 gen_vfp_add(dp);
3696 break;
3697 case 4: /* mul: fn * fm */
3698 gen_vfp_mul(dp);
3699 break;
3700 case 5: /* nmul: -(fn * fm) */
3701 gen_vfp_mul(dp);
3702 gen_vfp_neg(dp);
3703 break;
3704 case 6: /* add: fn + fm */
3705 gen_vfp_add(dp);
3706 break;
3707 case 7: /* sub: fn - fm */
3708 gen_vfp_sub(dp);
3709 break;
3710 case 8: /* div: fn / fm */
3711 gen_vfp_div(dp);
3712 break;
3713 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3714 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3715 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3716 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3717 /* These are fused multiply-add, and must be done as one
3718 * floating point operation with no rounding between the
3719 * multiplication and addition steps.
3720 * NB that doing the negations here as separate steps is
3721 * correct : an input NaN should come out with its sign bit
3722 * flipped if it is a negated-input.
3724 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3725 return 1;
3727 if (dp) {
3728 TCGv_ptr fpst;
3729 TCGv_i64 frd;
3730 if (op & 1) {
3731 /* VFNMS, VFMS */
3732 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3734 frd = tcg_temp_new_i64();
3735 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3736 if (op & 2) {
3737 /* VFNMA, VFNMS */
3738 gen_helper_vfp_negd(frd, frd);
3740 fpst = get_fpstatus_ptr(0);
3741 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3742 cpu_F1d, frd, fpst);
3743 tcg_temp_free_ptr(fpst);
3744 tcg_temp_free_i64(frd);
3745 } else {
3746 TCGv_ptr fpst;
3747 TCGv_i32 frd;
3748 if (op & 1) {
3749 /* VFNMS, VFMS */
3750 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3752 frd = tcg_temp_new_i32();
3753 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3754 if (op & 2) {
3755 gen_helper_vfp_negs(frd, frd);
3757 fpst = get_fpstatus_ptr(0);
3758 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3759 cpu_F1s, frd, fpst);
3760 tcg_temp_free_ptr(fpst);
3761 tcg_temp_free_i32(frd);
3763 break;
3764 case 14: /* fconst */
3765 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3766 return 1;
3769 n = (insn << 12) & 0x80000000;
3770 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3771 if (dp) {
3772 if (i & 0x40)
3773 i |= 0x3f80;
3774 else
3775 i |= 0x4000;
3776 n |= i << 16;
3777 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3778 } else {
3779 if (i & 0x40)
3780 i |= 0x780;
3781 else
3782 i |= 0x800;
3783 n |= i << 19;
3784 tcg_gen_movi_i32(cpu_F0s, n);
3786 break;
3787 case 15: /* extension space */
3788 switch (rn) {
3789 case 0: /* cpy */
3790 /* no-op */
3791 break;
3792 case 1: /* abs */
3793 gen_vfp_abs(dp);
3794 break;
3795 case 2: /* neg */
3796 gen_vfp_neg(dp);
3797 break;
3798 case 3: /* sqrt */
3799 gen_vfp_sqrt(dp);
3800 break;
3801 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3802 tmp = gen_vfp_mrs();
3803 tcg_gen_ext16u_i32(tmp, tmp);
3804 if (dp) {
3805 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3806 cpu_env);
3807 } else {
3808 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3809 cpu_env);
3811 tcg_temp_free_i32(tmp);
3812 break;
3813 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3814 tmp = gen_vfp_mrs();
3815 tcg_gen_shri_i32(tmp, tmp, 16);
3816 if (dp) {
3817 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3818 cpu_env);
3819 } else {
3820 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3821 cpu_env);
3823 tcg_temp_free_i32(tmp);
3824 break;
3825 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3826 tmp = tcg_temp_new_i32();
3827 if (dp) {
3828 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3829 cpu_env);
3830 } else {
3831 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3832 cpu_env);
3834 gen_mov_F0_vreg(0, rd);
3835 tmp2 = gen_vfp_mrs();
3836 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3837 tcg_gen_or_i32(tmp, tmp, tmp2);
3838 tcg_temp_free_i32(tmp2);
3839 gen_vfp_msr(tmp);
3840 break;
3841 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3842 tmp = tcg_temp_new_i32();
3843 if (dp) {
3844 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3845 cpu_env);
3846 } else {
3847 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3848 cpu_env);
3850 tcg_gen_shli_i32(tmp, tmp, 16);
3851 gen_mov_F0_vreg(0, rd);
3852 tmp2 = gen_vfp_mrs();
3853 tcg_gen_ext16u_i32(tmp2, tmp2);
3854 tcg_gen_or_i32(tmp, tmp, tmp2);
3855 tcg_temp_free_i32(tmp2);
3856 gen_vfp_msr(tmp);
3857 break;
3858 case 8: /* cmp */
3859 gen_vfp_cmp(dp);
3860 break;
3861 case 9: /* cmpe */
3862 gen_vfp_cmpe(dp);
3863 break;
3864 case 10: /* cmpz */
3865 gen_vfp_cmp(dp);
3866 break;
3867 case 11: /* cmpez */
3868 gen_vfp_F1_ld0(dp);
3869 gen_vfp_cmpe(dp);
3870 break;
3871 case 12: /* vrintr */
3873 TCGv_ptr fpst = get_fpstatus_ptr(0);
3874 if (dp) {
3875 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3876 } else {
3877 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3879 tcg_temp_free_ptr(fpst);
3880 break;
3882 case 13: /* vrintz */
3884 TCGv_ptr fpst = get_fpstatus_ptr(0);
3885 TCGv_i32 tcg_rmode;
3886 tcg_rmode = tcg_const_i32(float_round_to_zero);
3887 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3888 if (dp) {
3889 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3890 } else {
3891 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3893 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3894 tcg_temp_free_i32(tcg_rmode);
3895 tcg_temp_free_ptr(fpst);
3896 break;
3898 case 14: /* vrintx */
3900 TCGv_ptr fpst = get_fpstatus_ptr(0);
3901 if (dp) {
3902 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3903 } else {
3904 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3906 tcg_temp_free_ptr(fpst);
3907 break;
3909 case 15: /* single<->double conversion */
3910 if (dp)
3911 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3912 else
3913 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3914 break;
3915 case 16: /* fuito */
3916 gen_vfp_uito(dp, 0);
3917 break;
3918 case 17: /* fsito */
3919 gen_vfp_sito(dp, 0);
3920 break;
3921 case 20: /* fshto */
3922 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3923 return 1;
3925 gen_vfp_shto(dp, 16 - rm, 0);
3926 break;
3927 case 21: /* fslto */
3928 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3929 return 1;
3931 gen_vfp_slto(dp, 32 - rm, 0);
3932 break;
3933 case 22: /* fuhto */
3934 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3935 return 1;
3937 gen_vfp_uhto(dp, 16 - rm, 0);
3938 break;
3939 case 23: /* fulto */
3940 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3941 return 1;
3943 gen_vfp_ulto(dp, 32 - rm, 0);
3944 break;
3945 case 24: /* ftoui */
3946 gen_vfp_toui(dp, 0);
3947 break;
3948 case 25: /* ftouiz */
3949 gen_vfp_touiz(dp, 0);
3950 break;
3951 case 26: /* ftosi */
3952 gen_vfp_tosi(dp, 0);
3953 break;
3954 case 27: /* ftosiz */
3955 gen_vfp_tosiz(dp, 0);
3956 break;
3957 case 28: /* ftosh */
3958 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3959 return 1;
3961 gen_vfp_tosh(dp, 16 - rm, 0);
3962 break;
3963 case 29: /* ftosl */
3964 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3965 return 1;
3967 gen_vfp_tosl(dp, 32 - rm, 0);
3968 break;
3969 case 30: /* ftouh */
3970 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3971 return 1;
3973 gen_vfp_touh(dp, 16 - rm, 0);
3974 break;
3975 case 31: /* ftoul */
3976 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3977 return 1;
3979 gen_vfp_toul(dp, 32 - rm, 0);
3980 break;
3981 default: /* undefined */
3982 return 1;
3984 break;
3985 default: /* undefined */
3986 return 1;
3989 /* Write back the result. */
3990 if (op == 15 && (rn >= 8 && rn <= 11)) {
3991 /* Comparison, do nothing. */
3992 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3993 (rn & 0x1e) == 0x6)) {
3994 /* VCVT double to int: always integer result.
3995 * VCVT double to half precision is always a single
3996 * precision result.
3998 gen_mov_vreg_F0(0, rd);
3999 } else if (op == 15 && rn == 15) {
4000 /* conversion */
4001 gen_mov_vreg_F0(!dp, rd);
4002 } else {
4003 gen_mov_vreg_F0(dp, rd);
4006 /* break out of the loop if we have finished */
4007 if (veclen == 0)
4008 break;
4010 if (op == 15 && delta_m == 0) {
4011 /* single source one-many */
4012 while (veclen--) {
4013 rd = ((rd + delta_d) & (bank_mask - 1))
4014 | (rd & bank_mask);
4015 gen_mov_vreg_F0(dp, rd);
4017 break;
4019 /* Setup the next operands. */
4020 veclen--;
4021 rd = ((rd + delta_d) & (bank_mask - 1))
4022 | (rd & bank_mask);
4024 if (op == 15) {
4025 /* One source operand. */
4026 rm = ((rm + delta_m) & (bank_mask - 1))
4027 | (rm & bank_mask);
4028 gen_mov_F0_vreg(dp, rm);
4029 } else {
4030 /* Two source operands. */
4031 rn = ((rn + delta_d) & (bank_mask - 1))
4032 | (rn & bank_mask);
4033 gen_mov_F0_vreg(dp, rn);
4034 if (delta_m) {
4035 rm = ((rm + delta_m) & (bank_mask - 1))
4036 | (rm & bank_mask);
4037 gen_mov_F1_vreg(dp, rm);
4042 break;
4043 case 0xc:
4044 case 0xd:
4045 if ((insn & 0x03e00000) == 0x00400000) {
4046 /* two-register transfer */
4047 rn = (insn >> 16) & 0xf;
4048 rd = (insn >> 12) & 0xf;
4049 if (dp) {
4050 VFP_DREG_M(rm, insn);
4051 } else {
4052 rm = VFP_SREG_M(insn);
4055 if (insn & ARM_CP_RW_BIT) {
4056 /* vfp->arm */
4057 if (dp) {
4058 gen_mov_F0_vreg(0, rm * 2);
4059 tmp = gen_vfp_mrs();
4060 store_reg(s, rd, tmp);
4061 gen_mov_F0_vreg(0, rm * 2 + 1);
4062 tmp = gen_vfp_mrs();
4063 store_reg(s, rn, tmp);
4064 } else {
4065 gen_mov_F0_vreg(0, rm);
4066 tmp = gen_vfp_mrs();
4067 store_reg(s, rd, tmp);
4068 gen_mov_F0_vreg(0, rm + 1);
4069 tmp = gen_vfp_mrs();
4070 store_reg(s, rn, tmp);
4072 } else {
4073 /* arm->vfp */
4074 if (dp) {
4075 tmp = load_reg(s, rd);
4076 gen_vfp_msr(tmp);
4077 gen_mov_vreg_F0(0, rm * 2);
4078 tmp = load_reg(s, rn);
4079 gen_vfp_msr(tmp);
4080 gen_mov_vreg_F0(0, rm * 2 + 1);
4081 } else {
4082 tmp = load_reg(s, rd);
4083 gen_vfp_msr(tmp);
4084 gen_mov_vreg_F0(0, rm);
4085 tmp = load_reg(s, rn);
4086 gen_vfp_msr(tmp);
4087 gen_mov_vreg_F0(0, rm + 1);
4090 } else {
4091 /* Load/store */
4092 rn = (insn >> 16) & 0xf;
4093 if (dp)
4094 VFP_DREG_D(rd, insn);
4095 else
4096 rd = VFP_SREG_D(insn);
4097 if ((insn & 0x01200000) == 0x01000000) {
4098 /* Single load/store */
4099 offset = (insn & 0xff) << 2;
4100 if ((insn & (1 << 23)) == 0)
4101 offset = -offset;
4102 if (s->thumb && rn == 15) {
4103 /* This is actually UNPREDICTABLE */
4104 addr = tcg_temp_new_i32();
4105 tcg_gen_movi_i32(addr, s->pc & ~2);
4106 } else {
4107 addr = load_reg(s, rn);
4109 tcg_gen_addi_i32(addr, addr, offset);
4110 if (insn & (1 << 20)) {
4111 gen_vfp_ld(s, dp, addr);
4112 gen_mov_vreg_F0(dp, rd);
4113 } else {
4114 gen_mov_F0_vreg(dp, rd);
4115 gen_vfp_st(s, dp, addr);
4117 tcg_temp_free_i32(addr);
4118 } else {
4119 /* load/store multiple */
4120 int w = insn & (1 << 21);
4121 if (dp)
4122 n = (insn >> 1) & 0x7f;
4123 else
4124 n = insn & 0xff;
4126 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4127 /* P == U , W == 1 => UNDEF */
4128 return 1;
4130 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4131 /* UNPREDICTABLE cases for bad immediates: we choose to
4132 * UNDEF to avoid generating huge numbers of TCG ops
4134 return 1;
4136 if (rn == 15 && w) {
4137 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4138 return 1;
4141 if (s->thumb && rn == 15) {
4142 /* This is actually UNPREDICTABLE */
4143 addr = tcg_temp_new_i32();
4144 tcg_gen_movi_i32(addr, s->pc & ~2);
4145 } else {
4146 addr = load_reg(s, rn);
4148 if (insn & (1 << 24)) /* pre-decrement */
4149 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4151 if (dp)
4152 offset = 8;
4153 else
4154 offset = 4;
4155 for (i = 0; i < n; i++) {
4156 if (insn & ARM_CP_RW_BIT) {
4157 /* load */
4158 gen_vfp_ld(s, dp, addr);
4159 gen_mov_vreg_F0(dp, rd + i);
4160 } else {
4161 /* store */
4162 gen_mov_F0_vreg(dp, rd + i);
4163 gen_vfp_st(s, dp, addr);
4165 tcg_gen_addi_i32(addr, addr, offset);
4167 if (w) {
4168 /* writeback */
4169 if (insn & (1 << 24))
4170 offset = -offset * n;
4171 else if (dp && (insn & 1))
4172 offset = 4;
4173 else
4174 offset = 0;
4176 if (offset != 0)
4177 tcg_gen_addi_i32(addr, addr, offset);
4178 store_reg(s, rn, addr);
4179 } else {
4180 tcg_temp_free_i32(addr);
4184 break;
4185 default:
4186 /* Should never happen. */
4187 return 1;
4189 return 0;
4192 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4194 #ifndef CONFIG_USER_ONLY
4195 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4196 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4197 #else
4198 return true;
4199 #endif
4202 static void gen_goto_ptr(void)
4204 tcg_gen_lookup_and_goto_ptr();
4207 /* This will end the TB but doesn't guarantee we'll return to
4208 * cpu_loop_exec. Any live exit_requests will be processed as we
4209 * enter the next TB.
4211 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4213 if (use_goto_tb(s, dest)) {
4214 tcg_gen_goto_tb(n);
4215 gen_set_pc_im(s, dest);
4216 tcg_gen_exit_tb((uintptr_t)s->base.tb + n);
4217 } else {
4218 gen_set_pc_im(s, dest);
4219 gen_goto_ptr();
4221 s->base.is_jmp = DISAS_NORETURN;
4224 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4226 if (unlikely(is_singlestepping(s))) {
4227 /* An indirect jump so that we still trigger the debug exception. */
4228 if (s->thumb)
4229 dest |= 1;
4230 gen_bx_im(s, dest);
4231 } else {
4232 gen_goto_tb(s, 0, dest);
4236 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4238 if (x)
4239 tcg_gen_sari_i32(t0, t0, 16);
4240 else
4241 gen_sxth(t0);
4242 if (y)
4243 tcg_gen_sari_i32(t1, t1, 16);
4244 else
4245 gen_sxth(t1);
4246 tcg_gen_mul_i32(t0, t0, t1);
4249 /* Return the mask of PSR bits set by a MSR instruction. */
4250 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4252 uint32_t mask;
4254 mask = 0;
4255 if (flags & (1 << 0))
4256 mask |= 0xff;
4257 if (flags & (1 << 1))
4258 mask |= 0xff00;
4259 if (flags & (1 << 2))
4260 mask |= 0xff0000;
4261 if (flags & (1 << 3))
4262 mask |= 0xff000000;
4264 /* Mask out undefined bits. */
4265 mask &= ~CPSR_RESERVED;
4266 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4267 mask &= ~CPSR_T;
4269 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4270 mask &= ~CPSR_Q; /* V5TE in reality*/
4272 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4273 mask &= ~(CPSR_E | CPSR_GE);
4275 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4276 mask &= ~CPSR_IT;
4278 /* Mask out execution state and reserved bits. */
4279 if (!spsr) {
4280 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4282 /* Mask out privileged bits. */
4283 if (IS_USER(s))
4284 mask &= CPSR_USER;
4285 return mask;
4288 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4289 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4291 TCGv_i32 tmp;
4292 if (spsr) {
4293 /* ??? This is also undefined in system mode. */
4294 if (IS_USER(s))
4295 return 1;
4297 tmp = load_cpu_field(spsr);
4298 tcg_gen_andi_i32(tmp, tmp, ~mask);
4299 tcg_gen_andi_i32(t0, t0, mask);
4300 tcg_gen_or_i32(tmp, tmp, t0);
4301 store_cpu_field(tmp, spsr);
4302 } else {
4303 gen_set_cpsr(t0, mask);
4305 tcg_temp_free_i32(t0);
4306 gen_lookup_tb(s);
4307 return 0;
4310 /* Returns nonzero if access to the PSR is not permitted. */
4311 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4313 TCGv_i32 tmp;
4314 tmp = tcg_temp_new_i32();
4315 tcg_gen_movi_i32(tmp, val);
4316 return gen_set_psr(s, mask, spsr, tmp);
4319 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4320 int *tgtmode, int *regno)
4322 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4323 * the target mode and register number, and identify the various
4324 * unpredictable cases.
4325 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4326 * + executed in user mode
4327 * + using R15 as the src/dest register
4328 * + accessing an unimplemented register
4329 * + accessing a register that's inaccessible at current PL/security state*
4330 * + accessing a register that you could access with a different insn
4331 * We choose to UNDEF in all these cases.
4332 * Since we don't know which of the various AArch32 modes we are in
4333 * we have to defer some checks to runtime.
4334 * Accesses to Monitor mode registers from Secure EL1 (which implies
4335 * that EL3 is AArch64) must trap to EL3.
4337 * If the access checks fail this function will emit code to take
4338 * an exception and return false. Otherwise it will return true,
4339 * and set *tgtmode and *regno appropriately.
4341 int exc_target = default_exception_el(s);
4343 /* These instructions are present only in ARMv8, or in ARMv7 with the
4344 * Virtualization Extensions.
4346 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4347 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4348 goto undef;
4351 if (IS_USER(s) || rn == 15) {
4352 goto undef;
4355 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4356 * of registers into (r, sysm).
4358 if (r) {
4359 /* SPSRs for other modes */
4360 switch (sysm) {
4361 case 0xe: /* SPSR_fiq */
4362 *tgtmode = ARM_CPU_MODE_FIQ;
4363 break;
4364 case 0x10: /* SPSR_irq */
4365 *tgtmode = ARM_CPU_MODE_IRQ;
4366 break;
4367 case 0x12: /* SPSR_svc */
4368 *tgtmode = ARM_CPU_MODE_SVC;
4369 break;
4370 case 0x14: /* SPSR_abt */
4371 *tgtmode = ARM_CPU_MODE_ABT;
4372 break;
4373 case 0x16: /* SPSR_und */
4374 *tgtmode = ARM_CPU_MODE_UND;
4375 break;
4376 case 0x1c: /* SPSR_mon */
4377 *tgtmode = ARM_CPU_MODE_MON;
4378 break;
4379 case 0x1e: /* SPSR_hyp */
4380 *tgtmode = ARM_CPU_MODE_HYP;
4381 break;
4382 default: /* unallocated */
4383 goto undef;
4385 /* We arbitrarily assign SPSR a register number of 16. */
4386 *regno = 16;
4387 } else {
4388 /* general purpose registers for other modes */
4389 switch (sysm) {
4390 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4391 *tgtmode = ARM_CPU_MODE_USR;
4392 *regno = sysm + 8;
4393 break;
4394 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4395 *tgtmode = ARM_CPU_MODE_FIQ;
4396 *regno = sysm;
4397 break;
4398 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4399 *tgtmode = ARM_CPU_MODE_IRQ;
4400 *regno = sysm & 1 ? 13 : 14;
4401 break;
4402 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4403 *tgtmode = ARM_CPU_MODE_SVC;
4404 *regno = sysm & 1 ? 13 : 14;
4405 break;
4406 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4407 *tgtmode = ARM_CPU_MODE_ABT;
4408 *regno = sysm & 1 ? 13 : 14;
4409 break;
4410 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4411 *tgtmode = ARM_CPU_MODE_UND;
4412 *regno = sysm & 1 ? 13 : 14;
4413 break;
4414 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4415 *tgtmode = ARM_CPU_MODE_MON;
4416 *regno = sysm & 1 ? 13 : 14;
4417 break;
4418 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4419 *tgtmode = ARM_CPU_MODE_HYP;
4420 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4421 *regno = sysm & 1 ? 13 : 17;
4422 break;
4423 default: /* unallocated */
4424 goto undef;
4428 /* Catch the 'accessing inaccessible register' cases we can detect
4429 * at translate time.
4431 switch (*tgtmode) {
4432 case ARM_CPU_MODE_MON:
4433 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4434 goto undef;
4436 if (s->current_el == 1) {
4437 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4438 * then accesses to Mon registers trap to EL3
4440 exc_target = 3;
4441 goto undef;
4443 break;
4444 case ARM_CPU_MODE_HYP:
4445 /* Note that we can forbid accesses from EL2 here because they
4446 * must be from Hyp mode itself
4448 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4449 goto undef;
4451 break;
4452 default:
4453 break;
4456 return true;
4458 undef:
4459 /* If we get here then some access check did not pass */
4460 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4461 return false;
4464 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4466 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4467 int tgtmode = 0, regno = 0;
4469 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4470 return;
4473 /* Sync state because msr_banked() can raise exceptions */
4474 gen_set_condexec(s);
4475 gen_set_pc_im(s, s->pc - 4);
4476 tcg_reg = load_reg(s, rn);
4477 tcg_tgtmode = tcg_const_i32(tgtmode);
4478 tcg_regno = tcg_const_i32(regno);
4479 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4480 tcg_temp_free_i32(tcg_tgtmode);
4481 tcg_temp_free_i32(tcg_regno);
4482 tcg_temp_free_i32(tcg_reg);
4483 s->base.is_jmp = DISAS_UPDATE;
4486 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4488 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4489 int tgtmode = 0, regno = 0;
4491 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4492 return;
4495 /* Sync state because mrs_banked() can raise exceptions */
4496 gen_set_condexec(s);
4497 gen_set_pc_im(s, s->pc - 4);
4498 tcg_reg = tcg_temp_new_i32();
4499 tcg_tgtmode = tcg_const_i32(tgtmode);
4500 tcg_regno = tcg_const_i32(regno);
4501 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4502 tcg_temp_free_i32(tcg_tgtmode);
4503 tcg_temp_free_i32(tcg_regno);
4504 store_reg(s, rn, tcg_reg);
4505 s->base.is_jmp = DISAS_UPDATE;
4508 /* Store value to PC as for an exception return (ie don't
4509 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4510 * will do the masking based on the new value of the Thumb bit.
4512 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4514 tcg_gen_mov_i32(cpu_R[15], pc);
4515 tcg_temp_free_i32(pc);
4518 /* Generate a v6 exception return. Marks both values as dead. */
4519 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4521 store_pc_exc_ret(s, pc);
4522 /* The cpsr_write_eret helper will mask the low bits of PC
4523 * appropriately depending on the new Thumb bit, so it must
4524 * be called after storing the new PC.
4526 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4527 tcg_temp_free_i32(cpsr);
4528 /* Must exit loop to check un-masked IRQs */
4529 s->base.is_jmp = DISAS_EXIT;
4532 /* Generate an old-style exception return. Marks pc as dead. */
4533 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4535 gen_rfe(s, pc, load_cpu_field(spsr));
4539 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4540 * only call the helper when running single threaded TCG code to ensure
4541 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4542 * just skip this instruction. Currently the SEV/SEVL instructions
4543 * which are *one* of many ways to wake the CPU from WFE are not
4544 * implemented so we can't sleep like WFI does.
4546 static void gen_nop_hint(DisasContext *s, int val)
4548 switch (val) {
4549 case 1: /* yield */
4550 if (!parallel_cpus) {
4551 gen_set_pc_im(s, s->pc);
4552 s->base.is_jmp = DISAS_YIELD;
4554 break;
4555 case 3: /* wfi */
4556 gen_set_pc_im(s, s->pc);
4557 s->base.is_jmp = DISAS_WFI;
4558 break;
4559 case 2: /* wfe */
4560 if (!parallel_cpus) {
4561 gen_set_pc_im(s, s->pc);
4562 s->base.is_jmp = DISAS_WFE;
4564 break;
4565 case 4: /* sev */
4566 case 5: /* sevl */
4567 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4568 default: /* nop */
4569 break;
4573 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4575 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4577 switch (size) {
4578 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4579 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4580 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4581 default: abort();
4585 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4587 switch (size) {
4588 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4589 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4590 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4591 default: return;
4595 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4596 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4597 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4598 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4599 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4601 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4602 switch ((size << 1) | u) { \
4603 case 0: \
4604 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4605 break; \
4606 case 1: \
4607 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4608 break; \
4609 case 2: \
4610 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4611 break; \
4612 case 3: \
4613 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4614 break; \
4615 case 4: \
4616 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4617 break; \
4618 case 5: \
4619 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4620 break; \
4621 default: return 1; \
4622 }} while (0)
4624 #define GEN_NEON_INTEGER_OP(name) do { \
4625 switch ((size << 1) | u) { \
4626 case 0: \
4627 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4628 break; \
4629 case 1: \
4630 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4631 break; \
4632 case 2: \
4633 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4634 break; \
4635 case 3: \
4636 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4637 break; \
4638 case 4: \
4639 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4640 break; \
4641 case 5: \
4642 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4643 break; \
4644 default: return 1; \
4645 }} while (0)
4647 static TCGv_i32 neon_load_scratch(int scratch)
4649 TCGv_i32 tmp = tcg_temp_new_i32();
4650 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4651 return tmp;
4654 static void neon_store_scratch(int scratch, TCGv_i32 var)
4656 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4657 tcg_temp_free_i32(var);
4660 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4662 TCGv_i32 tmp;
4663 if (size == 1) {
4664 tmp = neon_load_reg(reg & 7, reg >> 4);
4665 if (reg & 8) {
4666 gen_neon_dup_high16(tmp);
4667 } else {
4668 gen_neon_dup_low16(tmp);
4670 } else {
4671 tmp = neon_load_reg(reg & 15, reg >> 4);
4673 return tmp;
4676 static int gen_neon_unzip(int rd, int rm, int size, int q)
4678 TCGv_i32 tmp, tmp2;
4679 if (!q && size == 2) {
4680 return 1;
4682 tmp = tcg_const_i32(rd);
4683 tmp2 = tcg_const_i32(rm);
4684 if (q) {
4685 switch (size) {
4686 case 0:
4687 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4688 break;
4689 case 1:
4690 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4691 break;
4692 case 2:
4693 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4694 break;
4695 default:
4696 abort();
4698 } else {
4699 switch (size) {
4700 case 0:
4701 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4702 break;
4703 case 1:
4704 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4705 break;
4706 default:
4707 abort();
4710 tcg_temp_free_i32(tmp);
4711 tcg_temp_free_i32(tmp2);
4712 return 0;
4715 static int gen_neon_zip(int rd, int rm, int size, int q)
4717 TCGv_i32 tmp, tmp2;
4718 if (!q && size == 2) {
4719 return 1;
4721 tmp = tcg_const_i32(rd);
4722 tmp2 = tcg_const_i32(rm);
4723 if (q) {
4724 switch (size) {
4725 case 0:
4726 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4727 break;
4728 case 1:
4729 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4730 break;
4731 case 2:
4732 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4733 break;
4734 default:
4735 abort();
4737 } else {
4738 switch (size) {
4739 case 0:
4740 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4741 break;
4742 case 1:
4743 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4744 break;
4745 default:
4746 abort();
4749 tcg_temp_free_i32(tmp);
4750 tcg_temp_free_i32(tmp2);
4751 return 0;
4754 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4756 TCGv_i32 rd, tmp;
4758 rd = tcg_temp_new_i32();
4759 tmp = tcg_temp_new_i32();
4761 tcg_gen_shli_i32(rd, t0, 8);
4762 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4763 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4764 tcg_gen_or_i32(rd, rd, tmp);
4766 tcg_gen_shri_i32(t1, t1, 8);
4767 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4768 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4769 tcg_gen_or_i32(t1, t1, tmp);
4770 tcg_gen_mov_i32(t0, rd);
4772 tcg_temp_free_i32(tmp);
4773 tcg_temp_free_i32(rd);
4776 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4778 TCGv_i32 rd, tmp;
4780 rd = tcg_temp_new_i32();
4781 tmp = tcg_temp_new_i32();
4783 tcg_gen_shli_i32(rd, t0, 16);
4784 tcg_gen_andi_i32(tmp, t1, 0xffff);
4785 tcg_gen_or_i32(rd, rd, tmp);
4786 tcg_gen_shri_i32(t1, t1, 16);
4787 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4788 tcg_gen_or_i32(t1, t1, tmp);
4789 tcg_gen_mov_i32(t0, rd);
4791 tcg_temp_free_i32(tmp);
4792 tcg_temp_free_i32(rd);
4796 static struct {
4797 int nregs;
4798 int interleave;
4799 int spacing;
4800 } neon_ls_element_type[11] = {
4801 {4, 4, 1},
4802 {4, 4, 2},
4803 {4, 1, 1},
4804 {4, 2, 1},
4805 {3, 3, 1},
4806 {3, 3, 2},
4807 {3, 1, 1},
4808 {1, 1, 1},
4809 {2, 2, 1},
4810 {2, 2, 2},
4811 {2, 1, 1}
4814 /* Translate a NEON load/store element instruction. Return nonzero if the
4815 instruction is invalid. */
4816 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4818 int rd, rn, rm;
4819 int op;
4820 int nregs;
4821 int interleave;
4822 int spacing;
4823 int stride;
4824 int size;
4825 int reg;
4826 int pass;
4827 int load;
4828 int shift;
4829 int n;
4830 TCGv_i32 addr;
4831 TCGv_i32 tmp;
4832 TCGv_i32 tmp2;
4833 TCGv_i64 tmp64;
4835 /* FIXME: this access check should not take precedence over UNDEF
4836 * for invalid encodings; we will generate incorrect syndrome information
4837 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4839 if (s->fp_excp_el) {
4840 gen_exception_insn(s, 4, EXCP_UDEF,
4841 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4842 return 0;
4845 if (!s->vfp_enabled)
4846 return 1;
4847 VFP_DREG_D(rd, insn);
4848 rn = (insn >> 16) & 0xf;
4849 rm = insn & 0xf;
4850 load = (insn & (1 << 21)) != 0;
4851 if ((insn & (1 << 23)) == 0) {
4852 /* Load store all elements. */
4853 op = (insn >> 8) & 0xf;
4854 size = (insn >> 6) & 3;
4855 if (op > 10)
4856 return 1;
4857 /* Catch UNDEF cases for bad values of align field */
4858 switch (op & 0xc) {
4859 case 4:
4860 if (((insn >> 5) & 1) == 1) {
4861 return 1;
4863 break;
4864 case 8:
4865 if (((insn >> 4) & 3) == 3) {
4866 return 1;
4868 break;
4869 default:
4870 break;
4872 nregs = neon_ls_element_type[op].nregs;
4873 interleave = neon_ls_element_type[op].interleave;
4874 spacing = neon_ls_element_type[op].spacing;
4875 if (size == 3 && (interleave | spacing) != 1)
4876 return 1;
4877 addr = tcg_temp_new_i32();
4878 load_reg_var(s, addr, rn);
4879 stride = (1 << size) * interleave;
4880 for (reg = 0; reg < nregs; reg++) {
4881 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4882 load_reg_var(s, addr, rn);
4883 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4884 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4885 load_reg_var(s, addr, rn);
4886 tcg_gen_addi_i32(addr, addr, 1 << size);
4888 if (size == 3) {
4889 tmp64 = tcg_temp_new_i64();
4890 if (load) {
4891 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4892 neon_store_reg64(tmp64, rd);
4893 } else {
4894 neon_load_reg64(tmp64, rd);
4895 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4897 tcg_temp_free_i64(tmp64);
4898 tcg_gen_addi_i32(addr, addr, stride);
4899 } else {
4900 for (pass = 0; pass < 2; pass++) {
4901 if (size == 2) {
4902 if (load) {
4903 tmp = tcg_temp_new_i32();
4904 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4905 neon_store_reg(rd, pass, tmp);
4906 } else {
4907 tmp = neon_load_reg(rd, pass);
4908 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4909 tcg_temp_free_i32(tmp);
4911 tcg_gen_addi_i32(addr, addr, stride);
4912 } else if (size == 1) {
4913 if (load) {
4914 tmp = tcg_temp_new_i32();
4915 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4916 tcg_gen_addi_i32(addr, addr, stride);
4917 tmp2 = tcg_temp_new_i32();
4918 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4919 tcg_gen_addi_i32(addr, addr, stride);
4920 tcg_gen_shli_i32(tmp2, tmp2, 16);
4921 tcg_gen_or_i32(tmp, tmp, tmp2);
4922 tcg_temp_free_i32(tmp2);
4923 neon_store_reg(rd, pass, tmp);
4924 } else {
4925 tmp = neon_load_reg(rd, pass);
4926 tmp2 = tcg_temp_new_i32();
4927 tcg_gen_shri_i32(tmp2, tmp, 16);
4928 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4929 tcg_temp_free_i32(tmp);
4930 tcg_gen_addi_i32(addr, addr, stride);
4931 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4932 tcg_temp_free_i32(tmp2);
4933 tcg_gen_addi_i32(addr, addr, stride);
4935 } else /* size == 0 */ {
4936 if (load) {
4937 TCGV_UNUSED_I32(tmp2);
4938 for (n = 0; n < 4; n++) {
4939 tmp = tcg_temp_new_i32();
4940 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4941 tcg_gen_addi_i32(addr, addr, stride);
4942 if (n == 0) {
4943 tmp2 = tmp;
4944 } else {
4945 tcg_gen_shli_i32(tmp, tmp, n * 8);
4946 tcg_gen_or_i32(tmp2, tmp2, tmp);
4947 tcg_temp_free_i32(tmp);
4950 neon_store_reg(rd, pass, tmp2);
4951 } else {
4952 tmp2 = neon_load_reg(rd, pass);
4953 for (n = 0; n < 4; n++) {
4954 tmp = tcg_temp_new_i32();
4955 if (n == 0) {
4956 tcg_gen_mov_i32(tmp, tmp2);
4957 } else {
4958 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4960 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4961 tcg_temp_free_i32(tmp);
4962 tcg_gen_addi_i32(addr, addr, stride);
4964 tcg_temp_free_i32(tmp2);
4969 rd += spacing;
4971 tcg_temp_free_i32(addr);
4972 stride = nregs * 8;
4973 } else {
4974 size = (insn >> 10) & 3;
4975 if (size == 3) {
4976 /* Load single element to all lanes. */
4977 int a = (insn >> 4) & 1;
4978 if (!load) {
4979 return 1;
4981 size = (insn >> 6) & 3;
4982 nregs = ((insn >> 8) & 3) + 1;
4984 if (size == 3) {
4985 if (nregs != 4 || a == 0) {
4986 return 1;
4988 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4989 size = 2;
4991 if (nregs == 1 && a == 1 && size == 0) {
4992 return 1;
4994 if (nregs == 3 && a == 1) {
4995 return 1;
4997 addr = tcg_temp_new_i32();
4998 load_reg_var(s, addr, rn);
4999 if (nregs == 1) {
5000 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5001 tmp = gen_load_and_replicate(s, addr, size);
5002 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5003 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5004 if (insn & (1 << 5)) {
5005 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5006 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5008 tcg_temp_free_i32(tmp);
5009 } else {
5010 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5011 stride = (insn & (1 << 5)) ? 2 : 1;
5012 for (reg = 0; reg < nregs; reg++) {
5013 tmp = gen_load_and_replicate(s, addr, size);
5014 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5015 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5016 tcg_temp_free_i32(tmp);
5017 tcg_gen_addi_i32(addr, addr, 1 << size);
5018 rd += stride;
5021 tcg_temp_free_i32(addr);
5022 stride = (1 << size) * nregs;
5023 } else {
5024 /* Single element. */
5025 int idx = (insn >> 4) & 0xf;
5026 pass = (insn >> 7) & 1;
5027 switch (size) {
5028 case 0:
5029 shift = ((insn >> 5) & 3) * 8;
5030 stride = 1;
5031 break;
5032 case 1:
5033 shift = ((insn >> 6) & 1) * 16;
5034 stride = (insn & (1 << 5)) ? 2 : 1;
5035 break;
5036 case 2:
5037 shift = 0;
5038 stride = (insn & (1 << 6)) ? 2 : 1;
5039 break;
5040 default:
5041 abort();
5043 nregs = ((insn >> 8) & 3) + 1;
5044 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5045 switch (nregs) {
5046 case 1:
5047 if (((idx & (1 << size)) != 0) ||
5048 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5049 return 1;
5051 break;
5052 case 3:
5053 if ((idx & 1) != 0) {
5054 return 1;
5056 /* fall through */
5057 case 2:
5058 if (size == 2 && (idx & 2) != 0) {
5059 return 1;
5061 break;
5062 case 4:
5063 if ((size == 2) && ((idx & 3) == 3)) {
5064 return 1;
5066 break;
5067 default:
5068 abort();
5070 if ((rd + stride * (nregs - 1)) > 31) {
5071 /* Attempts to write off the end of the register file
5072 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5073 * the neon_load_reg() would write off the end of the array.
5075 return 1;
5077 addr = tcg_temp_new_i32();
5078 load_reg_var(s, addr, rn);
5079 for (reg = 0; reg < nregs; reg++) {
5080 if (load) {
5081 tmp = tcg_temp_new_i32();
5082 switch (size) {
5083 case 0:
5084 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5085 break;
5086 case 1:
5087 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5088 break;
5089 case 2:
5090 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5091 break;
5092 default: /* Avoid compiler warnings. */
5093 abort();
5095 if (size != 2) {
5096 tmp2 = neon_load_reg(rd, pass);
5097 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5098 shift, size ? 16 : 8);
5099 tcg_temp_free_i32(tmp2);
5101 neon_store_reg(rd, pass, tmp);
5102 } else { /* Store */
5103 tmp = neon_load_reg(rd, pass);
5104 if (shift)
5105 tcg_gen_shri_i32(tmp, tmp, shift);
5106 switch (size) {
5107 case 0:
5108 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5109 break;
5110 case 1:
5111 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5112 break;
5113 case 2:
5114 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5115 break;
5117 tcg_temp_free_i32(tmp);
5119 rd += stride;
5120 tcg_gen_addi_i32(addr, addr, 1 << size);
5122 tcg_temp_free_i32(addr);
5123 stride = nregs * (1 << size);
5126 if (rm != 15) {
5127 TCGv_i32 base;
5129 base = load_reg(s, rn);
5130 if (rm == 13) {
5131 tcg_gen_addi_i32(base, base, stride);
5132 } else {
5133 TCGv_i32 index;
5134 index = load_reg(s, rm);
5135 tcg_gen_add_i32(base, base, index);
5136 tcg_temp_free_i32(index);
5138 store_reg(s, rn, base);
5140 return 0;
5143 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5144 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5146 tcg_gen_and_i32(t, t, c);
5147 tcg_gen_andc_i32(f, f, c);
5148 tcg_gen_or_i32(dest, t, f);
5151 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5153 switch (size) {
5154 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5155 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5156 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5157 default: abort();
5161 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5163 switch (size) {
5164 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5165 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5166 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5167 default: abort();
5171 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5173 switch (size) {
5174 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5175 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5176 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5177 default: abort();
5181 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5183 switch (size) {
5184 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5185 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5186 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5187 default: abort();
5191 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5192 int q, int u)
5194 if (q) {
5195 if (u) {
5196 switch (size) {
5197 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5198 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5199 default: abort();
5201 } else {
5202 switch (size) {
5203 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5204 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5205 default: abort();
5208 } else {
5209 if (u) {
5210 switch (size) {
5211 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5212 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5213 default: abort();
5215 } else {
5216 switch (size) {
5217 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5218 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5219 default: abort();
5225 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5227 if (u) {
5228 switch (size) {
5229 case 0: gen_helper_neon_widen_u8(dest, src); break;
5230 case 1: gen_helper_neon_widen_u16(dest, src); break;
5231 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5232 default: abort();
5234 } else {
5235 switch (size) {
5236 case 0: gen_helper_neon_widen_s8(dest, src); break;
5237 case 1: gen_helper_neon_widen_s16(dest, src); break;
5238 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5239 default: abort();
5242 tcg_temp_free_i32(src);
5245 static inline void gen_neon_addl(int size)
5247 switch (size) {
5248 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5249 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5250 case 2: tcg_gen_add_i64(CPU_V001); break;
5251 default: abort();
5255 static inline void gen_neon_subl(int size)
5257 switch (size) {
5258 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5259 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5260 case 2: tcg_gen_sub_i64(CPU_V001); break;
5261 default: abort();
5265 static inline void gen_neon_negl(TCGv_i64 var, int size)
5267 switch (size) {
5268 case 0: gen_helper_neon_negl_u16(var, var); break;
5269 case 1: gen_helper_neon_negl_u32(var, var); break;
5270 case 2:
5271 tcg_gen_neg_i64(var, var);
5272 break;
5273 default: abort();
5277 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5279 switch (size) {
5280 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5281 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5282 default: abort();
5286 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5287 int size, int u)
5289 TCGv_i64 tmp;
5291 switch ((size << 1) | u) {
5292 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5293 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5294 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5295 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5296 case 4:
5297 tmp = gen_muls_i64_i32(a, b);
5298 tcg_gen_mov_i64(dest, tmp);
5299 tcg_temp_free_i64(tmp);
5300 break;
5301 case 5:
5302 tmp = gen_mulu_i64_i32(a, b);
5303 tcg_gen_mov_i64(dest, tmp);
5304 tcg_temp_free_i64(tmp);
5305 break;
5306 default: abort();
5309 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5310 Don't forget to clean them now. */
5311 if (size < 2) {
5312 tcg_temp_free_i32(a);
5313 tcg_temp_free_i32(b);
5317 static void gen_neon_narrow_op(int op, int u, int size,
5318 TCGv_i32 dest, TCGv_i64 src)
5320 if (op) {
5321 if (u) {
5322 gen_neon_unarrow_sats(size, dest, src);
5323 } else {
5324 gen_neon_narrow(size, dest, src);
5326 } else {
5327 if (u) {
5328 gen_neon_narrow_satu(size, dest, src);
5329 } else {
5330 gen_neon_narrow_sats(size, dest, src);
5335 /* Symbolic constants for op fields for Neon 3-register same-length.
5336 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5337 * table A7-9.
5339 #define NEON_3R_VHADD 0
5340 #define NEON_3R_VQADD 1
5341 #define NEON_3R_VRHADD 2
5342 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5343 #define NEON_3R_VHSUB 4
5344 #define NEON_3R_VQSUB 5
5345 #define NEON_3R_VCGT 6
5346 #define NEON_3R_VCGE 7
5347 #define NEON_3R_VSHL 8
5348 #define NEON_3R_VQSHL 9
5349 #define NEON_3R_VRSHL 10
5350 #define NEON_3R_VQRSHL 11
5351 #define NEON_3R_VMAX 12
5352 #define NEON_3R_VMIN 13
5353 #define NEON_3R_VABD 14
5354 #define NEON_3R_VABA 15
5355 #define NEON_3R_VADD_VSUB 16
5356 #define NEON_3R_VTST_VCEQ 17
5357 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5358 #define NEON_3R_VMUL 19
5359 #define NEON_3R_VPMAX 20
5360 #define NEON_3R_VPMIN 21
5361 #define NEON_3R_VQDMULH_VQRDMULH 22
5362 #define NEON_3R_VPADD 23
5363 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5364 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5365 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5366 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5367 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5368 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5369 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5370 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5372 static const uint8_t neon_3r_sizes[] = {
5373 [NEON_3R_VHADD] = 0x7,
5374 [NEON_3R_VQADD] = 0xf,
5375 [NEON_3R_VRHADD] = 0x7,
5376 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5377 [NEON_3R_VHSUB] = 0x7,
5378 [NEON_3R_VQSUB] = 0xf,
5379 [NEON_3R_VCGT] = 0x7,
5380 [NEON_3R_VCGE] = 0x7,
5381 [NEON_3R_VSHL] = 0xf,
5382 [NEON_3R_VQSHL] = 0xf,
5383 [NEON_3R_VRSHL] = 0xf,
5384 [NEON_3R_VQRSHL] = 0xf,
5385 [NEON_3R_VMAX] = 0x7,
5386 [NEON_3R_VMIN] = 0x7,
5387 [NEON_3R_VABD] = 0x7,
5388 [NEON_3R_VABA] = 0x7,
5389 [NEON_3R_VADD_VSUB] = 0xf,
5390 [NEON_3R_VTST_VCEQ] = 0x7,
5391 [NEON_3R_VML] = 0x7,
5392 [NEON_3R_VMUL] = 0x7,
5393 [NEON_3R_VPMAX] = 0x7,
5394 [NEON_3R_VPMIN] = 0x7,
5395 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5396 [NEON_3R_VPADD] = 0x7,
5397 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5398 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5399 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5400 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5401 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5402 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5403 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5404 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5407 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5408 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5409 * table A7-13.
5411 #define NEON_2RM_VREV64 0
5412 #define NEON_2RM_VREV32 1
5413 #define NEON_2RM_VREV16 2
5414 #define NEON_2RM_VPADDL 4
5415 #define NEON_2RM_VPADDL_U 5
5416 #define NEON_2RM_AESE 6 /* Includes AESD */
5417 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5418 #define NEON_2RM_VCLS 8
5419 #define NEON_2RM_VCLZ 9
5420 #define NEON_2RM_VCNT 10
5421 #define NEON_2RM_VMVN 11
5422 #define NEON_2RM_VPADAL 12
5423 #define NEON_2RM_VPADAL_U 13
5424 #define NEON_2RM_VQABS 14
5425 #define NEON_2RM_VQNEG 15
5426 #define NEON_2RM_VCGT0 16
5427 #define NEON_2RM_VCGE0 17
5428 #define NEON_2RM_VCEQ0 18
5429 #define NEON_2RM_VCLE0 19
5430 #define NEON_2RM_VCLT0 20
5431 #define NEON_2RM_SHA1H 21
5432 #define NEON_2RM_VABS 22
5433 #define NEON_2RM_VNEG 23
5434 #define NEON_2RM_VCGT0_F 24
5435 #define NEON_2RM_VCGE0_F 25
5436 #define NEON_2RM_VCEQ0_F 26
5437 #define NEON_2RM_VCLE0_F 27
5438 #define NEON_2RM_VCLT0_F 28
5439 #define NEON_2RM_VABS_F 30
5440 #define NEON_2RM_VNEG_F 31
5441 #define NEON_2RM_VSWP 32
5442 #define NEON_2RM_VTRN 33
5443 #define NEON_2RM_VUZP 34
5444 #define NEON_2RM_VZIP 35
5445 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5446 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5447 #define NEON_2RM_VSHLL 38
5448 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5449 #define NEON_2RM_VRINTN 40
5450 #define NEON_2RM_VRINTX 41
5451 #define NEON_2RM_VRINTA 42
5452 #define NEON_2RM_VRINTZ 43
5453 #define NEON_2RM_VCVT_F16_F32 44
5454 #define NEON_2RM_VRINTM 45
5455 #define NEON_2RM_VCVT_F32_F16 46
5456 #define NEON_2RM_VRINTP 47
5457 #define NEON_2RM_VCVTAU 48
5458 #define NEON_2RM_VCVTAS 49
5459 #define NEON_2RM_VCVTNU 50
5460 #define NEON_2RM_VCVTNS 51
5461 #define NEON_2RM_VCVTPU 52
5462 #define NEON_2RM_VCVTPS 53
5463 #define NEON_2RM_VCVTMU 54
5464 #define NEON_2RM_VCVTMS 55
5465 #define NEON_2RM_VRECPE 56
5466 #define NEON_2RM_VRSQRTE 57
5467 #define NEON_2RM_VRECPE_F 58
5468 #define NEON_2RM_VRSQRTE_F 59
5469 #define NEON_2RM_VCVT_FS 60
5470 #define NEON_2RM_VCVT_FU 61
5471 #define NEON_2RM_VCVT_SF 62
5472 #define NEON_2RM_VCVT_UF 63
5474 static int neon_2rm_is_float_op(int op)
5476 /* Return true if this neon 2reg-misc op is float-to-float */
5477 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5478 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5479 op == NEON_2RM_VRINTM ||
5480 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5481 op >= NEON_2RM_VRECPE_F);
5484 static bool neon_2rm_is_v8_op(int op)
5486 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5487 switch (op) {
5488 case NEON_2RM_VRINTN:
5489 case NEON_2RM_VRINTA:
5490 case NEON_2RM_VRINTM:
5491 case NEON_2RM_VRINTP:
5492 case NEON_2RM_VRINTZ:
5493 case NEON_2RM_VRINTX:
5494 case NEON_2RM_VCVTAU:
5495 case NEON_2RM_VCVTAS:
5496 case NEON_2RM_VCVTNU:
5497 case NEON_2RM_VCVTNS:
5498 case NEON_2RM_VCVTPU:
5499 case NEON_2RM_VCVTPS:
5500 case NEON_2RM_VCVTMU:
5501 case NEON_2RM_VCVTMS:
5502 return true;
5503 default:
5504 return false;
5508 /* Each entry in this array has bit n set if the insn allows
5509 * size value n (otherwise it will UNDEF). Since unallocated
5510 * op values will have no bits set they always UNDEF.
5512 static const uint8_t neon_2rm_sizes[] = {
5513 [NEON_2RM_VREV64] = 0x7,
5514 [NEON_2RM_VREV32] = 0x3,
5515 [NEON_2RM_VREV16] = 0x1,
5516 [NEON_2RM_VPADDL] = 0x7,
5517 [NEON_2RM_VPADDL_U] = 0x7,
5518 [NEON_2RM_AESE] = 0x1,
5519 [NEON_2RM_AESMC] = 0x1,
5520 [NEON_2RM_VCLS] = 0x7,
5521 [NEON_2RM_VCLZ] = 0x7,
5522 [NEON_2RM_VCNT] = 0x1,
5523 [NEON_2RM_VMVN] = 0x1,
5524 [NEON_2RM_VPADAL] = 0x7,
5525 [NEON_2RM_VPADAL_U] = 0x7,
5526 [NEON_2RM_VQABS] = 0x7,
5527 [NEON_2RM_VQNEG] = 0x7,
5528 [NEON_2RM_VCGT0] = 0x7,
5529 [NEON_2RM_VCGE0] = 0x7,
5530 [NEON_2RM_VCEQ0] = 0x7,
5531 [NEON_2RM_VCLE0] = 0x7,
5532 [NEON_2RM_VCLT0] = 0x7,
5533 [NEON_2RM_SHA1H] = 0x4,
5534 [NEON_2RM_VABS] = 0x7,
5535 [NEON_2RM_VNEG] = 0x7,
5536 [NEON_2RM_VCGT0_F] = 0x4,
5537 [NEON_2RM_VCGE0_F] = 0x4,
5538 [NEON_2RM_VCEQ0_F] = 0x4,
5539 [NEON_2RM_VCLE0_F] = 0x4,
5540 [NEON_2RM_VCLT0_F] = 0x4,
5541 [NEON_2RM_VABS_F] = 0x4,
5542 [NEON_2RM_VNEG_F] = 0x4,
5543 [NEON_2RM_VSWP] = 0x1,
5544 [NEON_2RM_VTRN] = 0x7,
5545 [NEON_2RM_VUZP] = 0x7,
5546 [NEON_2RM_VZIP] = 0x7,
5547 [NEON_2RM_VMOVN] = 0x7,
5548 [NEON_2RM_VQMOVN] = 0x7,
5549 [NEON_2RM_VSHLL] = 0x7,
5550 [NEON_2RM_SHA1SU1] = 0x4,
5551 [NEON_2RM_VRINTN] = 0x4,
5552 [NEON_2RM_VRINTX] = 0x4,
5553 [NEON_2RM_VRINTA] = 0x4,
5554 [NEON_2RM_VRINTZ] = 0x4,
5555 [NEON_2RM_VCVT_F16_F32] = 0x2,
5556 [NEON_2RM_VRINTM] = 0x4,
5557 [NEON_2RM_VCVT_F32_F16] = 0x2,
5558 [NEON_2RM_VRINTP] = 0x4,
5559 [NEON_2RM_VCVTAU] = 0x4,
5560 [NEON_2RM_VCVTAS] = 0x4,
5561 [NEON_2RM_VCVTNU] = 0x4,
5562 [NEON_2RM_VCVTNS] = 0x4,
5563 [NEON_2RM_VCVTPU] = 0x4,
5564 [NEON_2RM_VCVTPS] = 0x4,
5565 [NEON_2RM_VCVTMU] = 0x4,
5566 [NEON_2RM_VCVTMS] = 0x4,
5567 [NEON_2RM_VRECPE] = 0x4,
5568 [NEON_2RM_VRSQRTE] = 0x4,
5569 [NEON_2RM_VRECPE_F] = 0x4,
5570 [NEON_2RM_VRSQRTE_F] = 0x4,
5571 [NEON_2RM_VCVT_FS] = 0x4,
5572 [NEON_2RM_VCVT_FU] = 0x4,
5573 [NEON_2RM_VCVT_SF] = 0x4,
5574 [NEON_2RM_VCVT_UF] = 0x4,
5577 /* Translate a NEON data processing instruction. Return nonzero if the
5578 instruction is invalid.
5579 We process data in a mixture of 32-bit and 64-bit chunks.
5580 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5582 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5584 int op;
5585 int q;
5586 int rd, rn, rm;
5587 int size;
5588 int shift;
5589 int pass;
5590 int count;
5591 int pairwise;
5592 int u;
5593 uint32_t imm, mask;
5594 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5595 TCGv_i64 tmp64;
5597 /* FIXME: this access check should not take precedence over UNDEF
5598 * for invalid encodings; we will generate incorrect syndrome information
5599 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5601 if (s->fp_excp_el) {
5602 gen_exception_insn(s, 4, EXCP_UDEF,
5603 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5604 return 0;
5607 if (!s->vfp_enabled)
5608 return 1;
5609 q = (insn & (1 << 6)) != 0;
5610 u = (insn >> 24) & 1;
5611 VFP_DREG_D(rd, insn);
5612 VFP_DREG_N(rn, insn);
5613 VFP_DREG_M(rm, insn);
5614 size = (insn >> 20) & 3;
5615 if ((insn & (1 << 23)) == 0) {
5616 /* Three register same length. */
5617 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5618 /* Catch invalid op and bad size combinations: UNDEF */
5619 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5620 return 1;
5622 /* All insns of this form UNDEF for either this condition or the
5623 * superset of cases "Q==1"; we catch the latter later.
5625 if (q && ((rd | rn | rm) & 1)) {
5626 return 1;
5629 * The SHA-1/SHA-256 3-register instructions require special treatment
5630 * here, as their size field is overloaded as an op type selector, and
5631 * they all consume their input in a single pass.
5633 if (op == NEON_3R_SHA) {
5634 if (!q) {
5635 return 1;
5637 if (!u) { /* SHA-1 */
5638 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5639 return 1;
5641 tmp = tcg_const_i32(rd);
5642 tmp2 = tcg_const_i32(rn);
5643 tmp3 = tcg_const_i32(rm);
5644 tmp4 = tcg_const_i32(size);
5645 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5646 tcg_temp_free_i32(tmp4);
5647 } else { /* SHA-256 */
5648 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5649 return 1;
5651 tmp = tcg_const_i32(rd);
5652 tmp2 = tcg_const_i32(rn);
5653 tmp3 = tcg_const_i32(rm);
5654 switch (size) {
5655 case 0:
5656 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5657 break;
5658 case 1:
5659 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5660 break;
5661 case 2:
5662 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5663 break;
5666 tcg_temp_free_i32(tmp);
5667 tcg_temp_free_i32(tmp2);
5668 tcg_temp_free_i32(tmp3);
5669 return 0;
5671 if (size == 3 && op != NEON_3R_LOGIC) {
5672 /* 64-bit element instructions. */
5673 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5674 neon_load_reg64(cpu_V0, rn + pass);
5675 neon_load_reg64(cpu_V1, rm + pass);
5676 switch (op) {
5677 case NEON_3R_VQADD:
5678 if (u) {
5679 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5680 cpu_V0, cpu_V1);
5681 } else {
5682 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5683 cpu_V0, cpu_V1);
5685 break;
5686 case NEON_3R_VQSUB:
5687 if (u) {
5688 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5689 cpu_V0, cpu_V1);
5690 } else {
5691 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5692 cpu_V0, cpu_V1);
5694 break;
5695 case NEON_3R_VSHL:
5696 if (u) {
5697 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5698 } else {
5699 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5701 break;
5702 case NEON_3R_VQSHL:
5703 if (u) {
5704 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5705 cpu_V1, cpu_V0);
5706 } else {
5707 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5708 cpu_V1, cpu_V0);
5710 break;
5711 case NEON_3R_VRSHL:
5712 if (u) {
5713 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5714 } else {
5715 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5717 break;
5718 case NEON_3R_VQRSHL:
5719 if (u) {
5720 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5721 cpu_V1, cpu_V0);
5722 } else {
5723 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5724 cpu_V1, cpu_V0);
5726 break;
5727 case NEON_3R_VADD_VSUB:
5728 if (u) {
5729 tcg_gen_sub_i64(CPU_V001);
5730 } else {
5731 tcg_gen_add_i64(CPU_V001);
5733 break;
5734 default:
5735 abort();
5737 neon_store_reg64(cpu_V0, rd + pass);
5739 return 0;
5741 pairwise = 0;
5742 switch (op) {
5743 case NEON_3R_VSHL:
5744 case NEON_3R_VQSHL:
5745 case NEON_3R_VRSHL:
5746 case NEON_3R_VQRSHL:
5748 int rtmp;
5749 /* Shift instruction operands are reversed. */
5750 rtmp = rn;
5751 rn = rm;
5752 rm = rtmp;
5754 break;
5755 case NEON_3R_VPADD:
5756 if (u) {
5757 return 1;
5759 /* Fall through */
5760 case NEON_3R_VPMAX:
5761 case NEON_3R_VPMIN:
5762 pairwise = 1;
5763 break;
5764 case NEON_3R_FLOAT_ARITH:
5765 pairwise = (u && size < 2); /* if VPADD (float) */
5766 break;
5767 case NEON_3R_FLOAT_MINMAX:
5768 pairwise = u; /* if VPMIN/VPMAX (float) */
5769 break;
5770 case NEON_3R_FLOAT_CMP:
5771 if (!u && size) {
5772 /* no encoding for U=0 C=1x */
5773 return 1;
5775 break;
5776 case NEON_3R_FLOAT_ACMP:
5777 if (!u) {
5778 return 1;
5780 break;
5781 case NEON_3R_FLOAT_MISC:
5782 /* VMAXNM/VMINNM in ARMv8 */
5783 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5784 return 1;
5786 break;
5787 case NEON_3R_VMUL:
5788 if (u && (size != 0)) {
5789 /* UNDEF on invalid size for polynomial subcase */
5790 return 1;
5792 break;
5793 case NEON_3R_VFM:
5794 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5795 return 1;
5797 break;
5798 default:
5799 break;
5802 if (pairwise && q) {
5803 /* All the pairwise insns UNDEF if Q is set */
5804 return 1;
5807 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5809 if (pairwise) {
5810 /* Pairwise. */
5811 if (pass < 1) {
5812 tmp = neon_load_reg(rn, 0);
5813 tmp2 = neon_load_reg(rn, 1);
5814 } else {
5815 tmp = neon_load_reg(rm, 0);
5816 tmp2 = neon_load_reg(rm, 1);
5818 } else {
5819 /* Elementwise. */
5820 tmp = neon_load_reg(rn, pass);
5821 tmp2 = neon_load_reg(rm, pass);
5823 switch (op) {
5824 case NEON_3R_VHADD:
5825 GEN_NEON_INTEGER_OP(hadd);
5826 break;
5827 case NEON_3R_VQADD:
5828 GEN_NEON_INTEGER_OP_ENV(qadd);
5829 break;
5830 case NEON_3R_VRHADD:
5831 GEN_NEON_INTEGER_OP(rhadd);
5832 break;
5833 case NEON_3R_LOGIC: /* Logic ops. */
5834 switch ((u << 2) | size) {
5835 case 0: /* VAND */
5836 tcg_gen_and_i32(tmp, tmp, tmp2);
5837 break;
5838 case 1: /* BIC */
5839 tcg_gen_andc_i32(tmp, tmp, tmp2);
5840 break;
5841 case 2: /* VORR */
5842 tcg_gen_or_i32(tmp, tmp, tmp2);
5843 break;
5844 case 3: /* VORN */
5845 tcg_gen_orc_i32(tmp, tmp, tmp2);
5846 break;
5847 case 4: /* VEOR */
5848 tcg_gen_xor_i32(tmp, tmp, tmp2);
5849 break;
5850 case 5: /* VBSL */
5851 tmp3 = neon_load_reg(rd, pass);
5852 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5853 tcg_temp_free_i32(tmp3);
5854 break;
5855 case 6: /* VBIT */
5856 tmp3 = neon_load_reg(rd, pass);
5857 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5858 tcg_temp_free_i32(tmp3);
5859 break;
5860 case 7: /* VBIF */
5861 tmp3 = neon_load_reg(rd, pass);
5862 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5863 tcg_temp_free_i32(tmp3);
5864 break;
5866 break;
5867 case NEON_3R_VHSUB:
5868 GEN_NEON_INTEGER_OP(hsub);
5869 break;
5870 case NEON_3R_VQSUB:
5871 GEN_NEON_INTEGER_OP_ENV(qsub);
5872 break;
5873 case NEON_3R_VCGT:
5874 GEN_NEON_INTEGER_OP(cgt);
5875 break;
5876 case NEON_3R_VCGE:
5877 GEN_NEON_INTEGER_OP(cge);
5878 break;
5879 case NEON_3R_VSHL:
5880 GEN_NEON_INTEGER_OP(shl);
5881 break;
5882 case NEON_3R_VQSHL:
5883 GEN_NEON_INTEGER_OP_ENV(qshl);
5884 break;
5885 case NEON_3R_VRSHL:
5886 GEN_NEON_INTEGER_OP(rshl);
5887 break;
5888 case NEON_3R_VQRSHL:
5889 GEN_NEON_INTEGER_OP_ENV(qrshl);
5890 break;
5891 case NEON_3R_VMAX:
5892 GEN_NEON_INTEGER_OP(max);
5893 break;
5894 case NEON_3R_VMIN:
5895 GEN_NEON_INTEGER_OP(min);
5896 break;
5897 case NEON_3R_VABD:
5898 GEN_NEON_INTEGER_OP(abd);
5899 break;
5900 case NEON_3R_VABA:
5901 GEN_NEON_INTEGER_OP(abd);
5902 tcg_temp_free_i32(tmp2);
5903 tmp2 = neon_load_reg(rd, pass);
5904 gen_neon_add(size, tmp, tmp2);
5905 break;
5906 case NEON_3R_VADD_VSUB:
5907 if (!u) { /* VADD */
5908 gen_neon_add(size, tmp, tmp2);
5909 } else { /* VSUB */
5910 switch (size) {
5911 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5912 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5913 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5914 default: abort();
5917 break;
5918 case NEON_3R_VTST_VCEQ:
5919 if (!u) { /* VTST */
5920 switch (size) {
5921 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5922 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5923 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5924 default: abort();
5926 } else { /* VCEQ */
5927 switch (size) {
5928 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5929 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5930 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5931 default: abort();
5934 break;
5935 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5936 switch (size) {
5937 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5938 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5939 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5940 default: abort();
5942 tcg_temp_free_i32(tmp2);
5943 tmp2 = neon_load_reg(rd, pass);
5944 if (u) { /* VMLS */
5945 gen_neon_rsb(size, tmp, tmp2);
5946 } else { /* VMLA */
5947 gen_neon_add(size, tmp, tmp2);
5949 break;
5950 case NEON_3R_VMUL:
5951 if (u) { /* polynomial */
5952 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5953 } else { /* Integer */
5954 switch (size) {
5955 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5956 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5957 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5958 default: abort();
5961 break;
5962 case NEON_3R_VPMAX:
5963 GEN_NEON_INTEGER_OP(pmax);
5964 break;
5965 case NEON_3R_VPMIN:
5966 GEN_NEON_INTEGER_OP(pmin);
5967 break;
5968 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5969 if (!u) { /* VQDMULH */
5970 switch (size) {
5971 case 1:
5972 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5973 break;
5974 case 2:
5975 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5976 break;
5977 default: abort();
5979 } else { /* VQRDMULH */
5980 switch (size) {
5981 case 1:
5982 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5983 break;
5984 case 2:
5985 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5986 break;
5987 default: abort();
5990 break;
5991 case NEON_3R_VPADD:
5992 switch (size) {
5993 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5994 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5995 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5996 default: abort();
5998 break;
5999 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6001 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6002 switch ((u << 2) | size) {
6003 case 0: /* VADD */
6004 case 4: /* VPADD */
6005 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6006 break;
6007 case 2: /* VSUB */
6008 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6009 break;
6010 case 6: /* VABD */
6011 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6012 break;
6013 default:
6014 abort();
6016 tcg_temp_free_ptr(fpstatus);
6017 break;
6019 case NEON_3R_FLOAT_MULTIPLY:
6021 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6022 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6023 if (!u) {
6024 tcg_temp_free_i32(tmp2);
6025 tmp2 = neon_load_reg(rd, pass);
6026 if (size == 0) {
6027 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6028 } else {
6029 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6032 tcg_temp_free_ptr(fpstatus);
6033 break;
6035 case NEON_3R_FLOAT_CMP:
6037 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6038 if (!u) {
6039 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6040 } else {
6041 if (size == 0) {
6042 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6043 } else {
6044 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6047 tcg_temp_free_ptr(fpstatus);
6048 break;
6050 case NEON_3R_FLOAT_ACMP:
6052 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6053 if (size == 0) {
6054 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6055 } else {
6056 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6058 tcg_temp_free_ptr(fpstatus);
6059 break;
6061 case NEON_3R_FLOAT_MINMAX:
6063 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6064 if (size == 0) {
6065 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6066 } else {
6067 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6069 tcg_temp_free_ptr(fpstatus);
6070 break;
6072 case NEON_3R_FLOAT_MISC:
6073 if (u) {
6074 /* VMAXNM/VMINNM */
6075 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6076 if (size == 0) {
6077 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6078 } else {
6079 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6081 tcg_temp_free_ptr(fpstatus);
6082 } else {
6083 if (size == 0) {
6084 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6085 } else {
6086 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6089 break;
6090 case NEON_3R_VFM:
6092 /* VFMA, VFMS: fused multiply-add */
6093 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6094 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6095 if (size) {
6096 /* VFMS */
6097 gen_helper_vfp_negs(tmp, tmp);
6099 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6100 tcg_temp_free_i32(tmp3);
6101 tcg_temp_free_ptr(fpstatus);
6102 break;
6104 default:
6105 abort();
6107 tcg_temp_free_i32(tmp2);
6109 /* Save the result. For elementwise operations we can put it
6110 straight into the destination register. For pairwise operations
6111 we have to be careful to avoid clobbering the source operands. */
6112 if (pairwise && rd == rm) {
6113 neon_store_scratch(pass, tmp);
6114 } else {
6115 neon_store_reg(rd, pass, tmp);
6118 } /* for pass */
6119 if (pairwise && rd == rm) {
6120 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6121 tmp = neon_load_scratch(pass);
6122 neon_store_reg(rd, pass, tmp);
6125 /* End of 3 register same size operations. */
6126 } else if (insn & (1 << 4)) {
6127 if ((insn & 0x00380080) != 0) {
6128 /* Two registers and shift. */
6129 op = (insn >> 8) & 0xf;
6130 if (insn & (1 << 7)) {
6131 /* 64-bit shift. */
6132 if (op > 7) {
6133 return 1;
6135 size = 3;
6136 } else {
6137 size = 2;
6138 while ((insn & (1 << (size + 19))) == 0)
6139 size--;
6141 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6142 /* To avoid excessive duplication of ops we implement shift
6143 by immediate using the variable shift operations. */
6144 if (op < 8) {
6145 /* Shift by immediate:
6146 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6147 if (q && ((rd | rm) & 1)) {
6148 return 1;
6150 if (!u && (op == 4 || op == 6)) {
6151 return 1;
6153 /* Right shifts are encoded as N - shift, where N is the
6154 element size in bits. */
6155 if (op <= 4)
6156 shift = shift - (1 << (size + 3));
6157 if (size == 3) {
6158 count = q + 1;
6159 } else {
6160 count = q ? 4: 2;
6162 switch (size) {
6163 case 0:
6164 imm = (uint8_t) shift;
6165 imm |= imm << 8;
6166 imm |= imm << 16;
6167 break;
6168 case 1:
6169 imm = (uint16_t) shift;
6170 imm |= imm << 16;
6171 break;
6172 case 2:
6173 case 3:
6174 imm = shift;
6175 break;
6176 default:
6177 abort();
6180 for (pass = 0; pass < count; pass++) {
6181 if (size == 3) {
6182 neon_load_reg64(cpu_V0, rm + pass);
6183 tcg_gen_movi_i64(cpu_V1, imm);
6184 switch (op) {
6185 case 0: /* VSHR */
6186 case 1: /* VSRA */
6187 if (u)
6188 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6189 else
6190 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6191 break;
6192 case 2: /* VRSHR */
6193 case 3: /* VRSRA */
6194 if (u)
6195 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6196 else
6197 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6198 break;
6199 case 4: /* VSRI */
6200 case 5: /* VSHL, VSLI */
6201 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6202 break;
6203 case 6: /* VQSHLU */
6204 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6205 cpu_V0, cpu_V1);
6206 break;
6207 case 7: /* VQSHL */
6208 if (u) {
6209 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6210 cpu_V0, cpu_V1);
6211 } else {
6212 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6213 cpu_V0, cpu_V1);
6215 break;
6217 if (op == 1 || op == 3) {
6218 /* Accumulate. */
6219 neon_load_reg64(cpu_V1, rd + pass);
6220 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6221 } else if (op == 4 || (op == 5 && u)) {
6222 /* Insert */
6223 neon_load_reg64(cpu_V1, rd + pass);
6224 uint64_t mask;
6225 if (shift < -63 || shift > 63) {
6226 mask = 0;
6227 } else {
6228 if (op == 4) {
6229 mask = 0xffffffffffffffffull >> -shift;
6230 } else {
6231 mask = 0xffffffffffffffffull << shift;
6234 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6235 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6237 neon_store_reg64(cpu_V0, rd + pass);
6238 } else { /* size < 3 */
6239 /* Operands in T0 and T1. */
6240 tmp = neon_load_reg(rm, pass);
6241 tmp2 = tcg_temp_new_i32();
6242 tcg_gen_movi_i32(tmp2, imm);
6243 switch (op) {
6244 case 0: /* VSHR */
6245 case 1: /* VSRA */
6246 GEN_NEON_INTEGER_OP(shl);
6247 break;
6248 case 2: /* VRSHR */
6249 case 3: /* VRSRA */
6250 GEN_NEON_INTEGER_OP(rshl);
6251 break;
6252 case 4: /* VSRI */
6253 case 5: /* VSHL, VSLI */
6254 switch (size) {
6255 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6256 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6257 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6258 default: abort();
6260 break;
6261 case 6: /* VQSHLU */
6262 switch (size) {
6263 case 0:
6264 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6265 tmp, tmp2);
6266 break;
6267 case 1:
6268 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6269 tmp, tmp2);
6270 break;
6271 case 2:
6272 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6273 tmp, tmp2);
6274 break;
6275 default:
6276 abort();
6278 break;
6279 case 7: /* VQSHL */
6280 GEN_NEON_INTEGER_OP_ENV(qshl);
6281 break;
6283 tcg_temp_free_i32(tmp2);
6285 if (op == 1 || op == 3) {
6286 /* Accumulate. */
6287 tmp2 = neon_load_reg(rd, pass);
6288 gen_neon_add(size, tmp, tmp2);
6289 tcg_temp_free_i32(tmp2);
6290 } else if (op == 4 || (op == 5 && u)) {
6291 /* Insert */
6292 switch (size) {
6293 case 0:
6294 if (op == 4)
6295 mask = 0xff >> -shift;
6296 else
6297 mask = (uint8_t)(0xff << shift);
6298 mask |= mask << 8;
6299 mask |= mask << 16;
6300 break;
6301 case 1:
6302 if (op == 4)
6303 mask = 0xffff >> -shift;
6304 else
6305 mask = (uint16_t)(0xffff << shift);
6306 mask |= mask << 16;
6307 break;
6308 case 2:
6309 if (shift < -31 || shift > 31) {
6310 mask = 0;
6311 } else {
6312 if (op == 4)
6313 mask = 0xffffffffu >> -shift;
6314 else
6315 mask = 0xffffffffu << shift;
6317 break;
6318 default:
6319 abort();
6321 tmp2 = neon_load_reg(rd, pass);
6322 tcg_gen_andi_i32(tmp, tmp, mask);
6323 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6324 tcg_gen_or_i32(tmp, tmp, tmp2);
6325 tcg_temp_free_i32(tmp2);
6327 neon_store_reg(rd, pass, tmp);
6329 } /* for pass */
6330 } else if (op < 10) {
6331 /* Shift by immediate and narrow:
6332 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6333 int input_unsigned = (op == 8) ? !u : u;
6334 if (rm & 1) {
6335 return 1;
6337 shift = shift - (1 << (size + 3));
6338 size++;
6339 if (size == 3) {
6340 tmp64 = tcg_const_i64(shift);
6341 neon_load_reg64(cpu_V0, rm);
6342 neon_load_reg64(cpu_V1, rm + 1);
6343 for (pass = 0; pass < 2; pass++) {
6344 TCGv_i64 in;
6345 if (pass == 0) {
6346 in = cpu_V0;
6347 } else {
6348 in = cpu_V1;
6350 if (q) {
6351 if (input_unsigned) {
6352 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6353 } else {
6354 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6356 } else {
6357 if (input_unsigned) {
6358 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6359 } else {
6360 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6363 tmp = tcg_temp_new_i32();
6364 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6365 neon_store_reg(rd, pass, tmp);
6366 } /* for pass */
6367 tcg_temp_free_i64(tmp64);
6368 } else {
6369 if (size == 1) {
6370 imm = (uint16_t)shift;
6371 imm |= imm << 16;
6372 } else {
6373 /* size == 2 */
6374 imm = (uint32_t)shift;
6376 tmp2 = tcg_const_i32(imm);
6377 tmp4 = neon_load_reg(rm + 1, 0);
6378 tmp5 = neon_load_reg(rm + 1, 1);
6379 for (pass = 0; pass < 2; pass++) {
6380 if (pass == 0) {
6381 tmp = neon_load_reg(rm, 0);
6382 } else {
6383 tmp = tmp4;
6385 gen_neon_shift_narrow(size, tmp, tmp2, q,
6386 input_unsigned);
6387 if (pass == 0) {
6388 tmp3 = neon_load_reg(rm, 1);
6389 } else {
6390 tmp3 = tmp5;
6392 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6393 input_unsigned);
6394 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6395 tcg_temp_free_i32(tmp);
6396 tcg_temp_free_i32(tmp3);
6397 tmp = tcg_temp_new_i32();
6398 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6399 neon_store_reg(rd, pass, tmp);
6400 } /* for pass */
6401 tcg_temp_free_i32(tmp2);
6403 } else if (op == 10) {
6404 /* VSHLL, VMOVL */
6405 if (q || (rd & 1)) {
6406 return 1;
6408 tmp = neon_load_reg(rm, 0);
6409 tmp2 = neon_load_reg(rm, 1);
6410 for (pass = 0; pass < 2; pass++) {
6411 if (pass == 1)
6412 tmp = tmp2;
6414 gen_neon_widen(cpu_V0, tmp, size, u);
6416 if (shift != 0) {
6417 /* The shift is less than the width of the source
6418 type, so we can just shift the whole register. */
6419 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6420 /* Widen the result of shift: we need to clear
6421 * the potential overflow bits resulting from
6422 * left bits of the narrow input appearing as
6423 * right bits of left the neighbour narrow
6424 * input. */
6425 if (size < 2 || !u) {
6426 uint64_t imm64;
6427 if (size == 0) {
6428 imm = (0xffu >> (8 - shift));
6429 imm |= imm << 16;
6430 } else if (size == 1) {
6431 imm = 0xffff >> (16 - shift);
6432 } else {
6433 /* size == 2 */
6434 imm = 0xffffffff >> (32 - shift);
6436 if (size < 2) {
6437 imm64 = imm | (((uint64_t)imm) << 32);
6438 } else {
6439 imm64 = imm;
6441 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6444 neon_store_reg64(cpu_V0, rd + pass);
6446 } else if (op >= 14) {
6447 /* VCVT fixed-point. */
6448 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6449 return 1;
6451 /* We have already masked out the must-be-1 top bit of imm6,
6452 * hence this 32-shift where the ARM ARM has 64-imm6.
6454 shift = 32 - shift;
6455 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6456 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6457 if (!(op & 1)) {
6458 if (u)
6459 gen_vfp_ulto(0, shift, 1);
6460 else
6461 gen_vfp_slto(0, shift, 1);
6462 } else {
6463 if (u)
6464 gen_vfp_toul(0, shift, 1);
6465 else
6466 gen_vfp_tosl(0, shift, 1);
6468 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6470 } else {
6471 return 1;
6473 } else { /* (insn & 0x00380080) == 0 */
6474 int invert;
6475 if (q && (rd & 1)) {
6476 return 1;
6479 op = (insn >> 8) & 0xf;
6480 /* One register and immediate. */
6481 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6482 invert = (insn & (1 << 5)) != 0;
6483 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6484 * We choose to not special-case this and will behave as if a
6485 * valid constant encoding of 0 had been given.
6487 switch (op) {
6488 case 0: case 1:
6489 /* no-op */
6490 break;
6491 case 2: case 3:
6492 imm <<= 8;
6493 break;
6494 case 4: case 5:
6495 imm <<= 16;
6496 break;
6497 case 6: case 7:
6498 imm <<= 24;
6499 break;
6500 case 8: case 9:
6501 imm |= imm << 16;
6502 break;
6503 case 10: case 11:
6504 imm = (imm << 8) | (imm << 24);
6505 break;
6506 case 12:
6507 imm = (imm << 8) | 0xff;
6508 break;
6509 case 13:
6510 imm = (imm << 16) | 0xffff;
6511 break;
6512 case 14:
6513 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6514 if (invert)
6515 imm = ~imm;
6516 break;
6517 case 15:
6518 if (invert) {
6519 return 1;
6521 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6522 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6523 break;
6525 if (invert)
6526 imm = ~imm;
6528 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6529 if (op & 1 && op < 12) {
6530 tmp = neon_load_reg(rd, pass);
6531 if (invert) {
6532 /* The immediate value has already been inverted, so
6533 BIC becomes AND. */
6534 tcg_gen_andi_i32(tmp, tmp, imm);
6535 } else {
6536 tcg_gen_ori_i32(tmp, tmp, imm);
6538 } else {
6539 /* VMOV, VMVN. */
6540 tmp = tcg_temp_new_i32();
6541 if (op == 14 && invert) {
6542 int n;
6543 uint32_t val;
6544 val = 0;
6545 for (n = 0; n < 4; n++) {
6546 if (imm & (1 << (n + (pass & 1) * 4)))
6547 val |= 0xff << (n * 8);
6549 tcg_gen_movi_i32(tmp, val);
6550 } else {
6551 tcg_gen_movi_i32(tmp, imm);
6554 neon_store_reg(rd, pass, tmp);
6557 } else { /* (insn & 0x00800010 == 0x00800000) */
6558 if (size != 3) {
6559 op = (insn >> 8) & 0xf;
6560 if ((insn & (1 << 6)) == 0) {
6561 /* Three registers of different lengths. */
6562 int src1_wide;
6563 int src2_wide;
6564 int prewiden;
6565 /* undefreq: bit 0 : UNDEF if size == 0
6566 * bit 1 : UNDEF if size == 1
6567 * bit 2 : UNDEF if size == 2
6568 * bit 3 : UNDEF if U == 1
6569 * Note that [2:0] set implies 'always UNDEF'
6571 int undefreq;
6572 /* prewiden, src1_wide, src2_wide, undefreq */
6573 static const int neon_3reg_wide[16][4] = {
6574 {1, 0, 0, 0}, /* VADDL */
6575 {1, 1, 0, 0}, /* VADDW */
6576 {1, 0, 0, 0}, /* VSUBL */
6577 {1, 1, 0, 0}, /* VSUBW */
6578 {0, 1, 1, 0}, /* VADDHN */
6579 {0, 0, 0, 0}, /* VABAL */
6580 {0, 1, 1, 0}, /* VSUBHN */
6581 {0, 0, 0, 0}, /* VABDL */
6582 {0, 0, 0, 0}, /* VMLAL */
6583 {0, 0, 0, 9}, /* VQDMLAL */
6584 {0, 0, 0, 0}, /* VMLSL */
6585 {0, 0, 0, 9}, /* VQDMLSL */
6586 {0, 0, 0, 0}, /* Integer VMULL */
6587 {0, 0, 0, 1}, /* VQDMULL */
6588 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6589 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6592 prewiden = neon_3reg_wide[op][0];
6593 src1_wide = neon_3reg_wide[op][1];
6594 src2_wide = neon_3reg_wide[op][2];
6595 undefreq = neon_3reg_wide[op][3];
6597 if ((undefreq & (1 << size)) ||
6598 ((undefreq & 8) && u)) {
6599 return 1;
6601 if ((src1_wide && (rn & 1)) ||
6602 (src2_wide && (rm & 1)) ||
6603 (!src2_wide && (rd & 1))) {
6604 return 1;
6607 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6608 * outside the loop below as it only performs a single pass.
6610 if (op == 14 && size == 2) {
6611 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6613 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6614 return 1;
6616 tcg_rn = tcg_temp_new_i64();
6617 tcg_rm = tcg_temp_new_i64();
6618 tcg_rd = tcg_temp_new_i64();
6619 neon_load_reg64(tcg_rn, rn);
6620 neon_load_reg64(tcg_rm, rm);
6621 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6622 neon_store_reg64(tcg_rd, rd);
6623 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6624 neon_store_reg64(tcg_rd, rd + 1);
6625 tcg_temp_free_i64(tcg_rn);
6626 tcg_temp_free_i64(tcg_rm);
6627 tcg_temp_free_i64(tcg_rd);
6628 return 0;
6631 /* Avoid overlapping operands. Wide source operands are
6632 always aligned so will never overlap with wide
6633 destinations in problematic ways. */
6634 if (rd == rm && !src2_wide) {
6635 tmp = neon_load_reg(rm, 1);
6636 neon_store_scratch(2, tmp);
6637 } else if (rd == rn && !src1_wide) {
6638 tmp = neon_load_reg(rn, 1);
6639 neon_store_scratch(2, tmp);
6641 TCGV_UNUSED_I32(tmp3);
6642 for (pass = 0; pass < 2; pass++) {
6643 if (src1_wide) {
6644 neon_load_reg64(cpu_V0, rn + pass);
6645 TCGV_UNUSED_I32(tmp);
6646 } else {
6647 if (pass == 1 && rd == rn) {
6648 tmp = neon_load_scratch(2);
6649 } else {
6650 tmp = neon_load_reg(rn, pass);
6652 if (prewiden) {
6653 gen_neon_widen(cpu_V0, tmp, size, u);
6656 if (src2_wide) {
6657 neon_load_reg64(cpu_V1, rm + pass);
6658 TCGV_UNUSED_I32(tmp2);
6659 } else {
6660 if (pass == 1 && rd == rm) {
6661 tmp2 = neon_load_scratch(2);
6662 } else {
6663 tmp2 = neon_load_reg(rm, pass);
6665 if (prewiden) {
6666 gen_neon_widen(cpu_V1, tmp2, size, u);
6669 switch (op) {
6670 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6671 gen_neon_addl(size);
6672 break;
6673 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6674 gen_neon_subl(size);
6675 break;
6676 case 5: case 7: /* VABAL, VABDL */
6677 switch ((size << 1) | u) {
6678 case 0:
6679 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6680 break;
6681 case 1:
6682 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6683 break;
6684 case 2:
6685 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6686 break;
6687 case 3:
6688 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6689 break;
6690 case 4:
6691 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6692 break;
6693 case 5:
6694 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6695 break;
6696 default: abort();
6698 tcg_temp_free_i32(tmp2);
6699 tcg_temp_free_i32(tmp);
6700 break;
6701 case 8: case 9: case 10: case 11: case 12: case 13:
6702 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6703 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6704 break;
6705 case 14: /* Polynomial VMULL */
6706 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6707 tcg_temp_free_i32(tmp2);
6708 tcg_temp_free_i32(tmp);
6709 break;
6710 default: /* 15 is RESERVED: caught earlier */
6711 abort();
6713 if (op == 13) {
6714 /* VQDMULL */
6715 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6716 neon_store_reg64(cpu_V0, rd + pass);
6717 } else if (op == 5 || (op >= 8 && op <= 11)) {
6718 /* Accumulate. */
6719 neon_load_reg64(cpu_V1, rd + pass);
6720 switch (op) {
6721 case 10: /* VMLSL */
6722 gen_neon_negl(cpu_V0, size);
6723 /* Fall through */
6724 case 5: case 8: /* VABAL, VMLAL */
6725 gen_neon_addl(size);
6726 break;
6727 case 9: case 11: /* VQDMLAL, VQDMLSL */
6728 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6729 if (op == 11) {
6730 gen_neon_negl(cpu_V0, size);
6732 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6733 break;
6734 default:
6735 abort();
6737 neon_store_reg64(cpu_V0, rd + pass);
6738 } else if (op == 4 || op == 6) {
6739 /* Narrowing operation. */
6740 tmp = tcg_temp_new_i32();
6741 if (!u) {
6742 switch (size) {
6743 case 0:
6744 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6745 break;
6746 case 1:
6747 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6748 break;
6749 case 2:
6750 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6751 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6752 break;
6753 default: abort();
6755 } else {
6756 switch (size) {
6757 case 0:
6758 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6759 break;
6760 case 1:
6761 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6762 break;
6763 case 2:
6764 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6765 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6766 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6767 break;
6768 default: abort();
6771 if (pass == 0) {
6772 tmp3 = tmp;
6773 } else {
6774 neon_store_reg(rd, 0, tmp3);
6775 neon_store_reg(rd, 1, tmp);
6777 } else {
6778 /* Write back the result. */
6779 neon_store_reg64(cpu_V0, rd + pass);
6782 } else {
6783 /* Two registers and a scalar. NB that for ops of this form
6784 * the ARM ARM labels bit 24 as Q, but it is in our variable
6785 * 'u', not 'q'.
6787 if (size == 0) {
6788 return 1;
6790 switch (op) {
6791 case 1: /* Float VMLA scalar */
6792 case 5: /* Floating point VMLS scalar */
6793 case 9: /* Floating point VMUL scalar */
6794 if (size == 1) {
6795 return 1;
6797 /* fall through */
6798 case 0: /* Integer VMLA scalar */
6799 case 4: /* Integer VMLS scalar */
6800 case 8: /* Integer VMUL scalar */
6801 case 12: /* VQDMULH scalar */
6802 case 13: /* VQRDMULH scalar */
6803 if (u && ((rd | rn) & 1)) {
6804 return 1;
6806 tmp = neon_get_scalar(size, rm);
6807 neon_store_scratch(0, tmp);
6808 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6809 tmp = neon_load_scratch(0);
6810 tmp2 = neon_load_reg(rn, pass);
6811 if (op == 12) {
6812 if (size == 1) {
6813 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6814 } else {
6815 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6817 } else if (op == 13) {
6818 if (size == 1) {
6819 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6820 } else {
6821 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6823 } else if (op & 1) {
6824 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6825 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6826 tcg_temp_free_ptr(fpstatus);
6827 } else {
6828 switch (size) {
6829 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6830 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6831 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6832 default: abort();
6835 tcg_temp_free_i32(tmp2);
6836 if (op < 8) {
6837 /* Accumulate. */
6838 tmp2 = neon_load_reg(rd, pass);
6839 switch (op) {
6840 case 0:
6841 gen_neon_add(size, tmp, tmp2);
6842 break;
6843 case 1:
6845 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6846 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6847 tcg_temp_free_ptr(fpstatus);
6848 break;
6850 case 4:
6851 gen_neon_rsb(size, tmp, tmp2);
6852 break;
6853 case 5:
6855 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6856 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6857 tcg_temp_free_ptr(fpstatus);
6858 break;
6860 default:
6861 abort();
6863 tcg_temp_free_i32(tmp2);
6865 neon_store_reg(rd, pass, tmp);
6867 break;
6868 case 3: /* VQDMLAL scalar */
6869 case 7: /* VQDMLSL scalar */
6870 case 11: /* VQDMULL scalar */
6871 if (u == 1) {
6872 return 1;
6874 /* fall through */
6875 case 2: /* VMLAL sclar */
6876 case 6: /* VMLSL scalar */
6877 case 10: /* VMULL scalar */
6878 if (rd & 1) {
6879 return 1;
6881 tmp2 = neon_get_scalar(size, rm);
6882 /* We need a copy of tmp2 because gen_neon_mull
6883 * deletes it during pass 0. */
6884 tmp4 = tcg_temp_new_i32();
6885 tcg_gen_mov_i32(tmp4, tmp2);
6886 tmp3 = neon_load_reg(rn, 1);
6888 for (pass = 0; pass < 2; pass++) {
6889 if (pass == 0) {
6890 tmp = neon_load_reg(rn, 0);
6891 } else {
6892 tmp = tmp3;
6893 tmp2 = tmp4;
6895 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6896 if (op != 11) {
6897 neon_load_reg64(cpu_V1, rd + pass);
6899 switch (op) {
6900 case 6:
6901 gen_neon_negl(cpu_V0, size);
6902 /* Fall through */
6903 case 2:
6904 gen_neon_addl(size);
6905 break;
6906 case 3: case 7:
6907 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6908 if (op == 7) {
6909 gen_neon_negl(cpu_V0, size);
6911 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6912 break;
6913 case 10:
6914 /* no-op */
6915 break;
6916 case 11:
6917 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6918 break;
6919 default:
6920 abort();
6922 neon_store_reg64(cpu_V0, rd + pass);
6926 break;
6927 default: /* 14 and 15 are RESERVED */
6928 return 1;
6931 } else { /* size == 3 */
6932 if (!u) {
6933 /* Extract. */
6934 imm = (insn >> 8) & 0xf;
6936 if (imm > 7 && !q)
6937 return 1;
6939 if (q && ((rd | rn | rm) & 1)) {
6940 return 1;
6943 if (imm == 0) {
6944 neon_load_reg64(cpu_V0, rn);
6945 if (q) {
6946 neon_load_reg64(cpu_V1, rn + 1);
6948 } else if (imm == 8) {
6949 neon_load_reg64(cpu_V0, rn + 1);
6950 if (q) {
6951 neon_load_reg64(cpu_V1, rm);
6953 } else if (q) {
6954 tmp64 = tcg_temp_new_i64();
6955 if (imm < 8) {
6956 neon_load_reg64(cpu_V0, rn);
6957 neon_load_reg64(tmp64, rn + 1);
6958 } else {
6959 neon_load_reg64(cpu_V0, rn + 1);
6960 neon_load_reg64(tmp64, rm);
6962 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6963 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6964 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6965 if (imm < 8) {
6966 neon_load_reg64(cpu_V1, rm);
6967 } else {
6968 neon_load_reg64(cpu_V1, rm + 1);
6969 imm -= 8;
6971 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6972 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6973 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6974 tcg_temp_free_i64(tmp64);
6975 } else {
6976 /* BUGFIX */
6977 neon_load_reg64(cpu_V0, rn);
6978 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6979 neon_load_reg64(cpu_V1, rm);
6980 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6981 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6983 neon_store_reg64(cpu_V0, rd);
6984 if (q) {
6985 neon_store_reg64(cpu_V1, rd + 1);
6987 } else if ((insn & (1 << 11)) == 0) {
6988 /* Two register misc. */
6989 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6990 size = (insn >> 18) & 3;
6991 /* UNDEF for unknown op values and bad op-size combinations */
6992 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6993 return 1;
6995 if (neon_2rm_is_v8_op(op) &&
6996 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6997 return 1;
6999 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7000 q && ((rm | rd) & 1)) {
7001 return 1;
7003 switch (op) {
7004 case NEON_2RM_VREV64:
7005 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7006 tmp = neon_load_reg(rm, pass * 2);
7007 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7008 switch (size) {
7009 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7010 case 1: gen_swap_half(tmp); break;
7011 case 2: /* no-op */ break;
7012 default: abort();
7014 neon_store_reg(rd, pass * 2 + 1, tmp);
7015 if (size == 2) {
7016 neon_store_reg(rd, pass * 2, tmp2);
7017 } else {
7018 switch (size) {
7019 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7020 case 1: gen_swap_half(tmp2); break;
7021 default: abort();
7023 neon_store_reg(rd, pass * 2, tmp2);
7026 break;
7027 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7028 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7029 for (pass = 0; pass < q + 1; pass++) {
7030 tmp = neon_load_reg(rm, pass * 2);
7031 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7032 tmp = neon_load_reg(rm, pass * 2 + 1);
7033 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7034 switch (size) {
7035 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7036 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7037 case 2: tcg_gen_add_i64(CPU_V001); break;
7038 default: abort();
7040 if (op >= NEON_2RM_VPADAL) {
7041 /* Accumulate. */
7042 neon_load_reg64(cpu_V1, rd + pass);
7043 gen_neon_addl(size);
7045 neon_store_reg64(cpu_V0, rd + pass);
7047 break;
7048 case NEON_2RM_VTRN:
7049 if (size == 2) {
7050 int n;
7051 for (n = 0; n < (q ? 4 : 2); n += 2) {
7052 tmp = neon_load_reg(rm, n);
7053 tmp2 = neon_load_reg(rd, n + 1);
7054 neon_store_reg(rm, n, tmp2);
7055 neon_store_reg(rd, n + 1, tmp);
7057 } else {
7058 goto elementwise;
7060 break;
7061 case NEON_2RM_VUZP:
7062 if (gen_neon_unzip(rd, rm, size, q)) {
7063 return 1;
7065 break;
7066 case NEON_2RM_VZIP:
7067 if (gen_neon_zip(rd, rm, size, q)) {
7068 return 1;
7070 break;
7071 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7072 /* also VQMOVUN; op field and mnemonics don't line up */
7073 if (rm & 1) {
7074 return 1;
7076 TCGV_UNUSED_I32(tmp2);
7077 for (pass = 0; pass < 2; pass++) {
7078 neon_load_reg64(cpu_V0, rm + pass);
7079 tmp = tcg_temp_new_i32();
7080 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7081 tmp, cpu_V0);
7082 if (pass == 0) {
7083 tmp2 = tmp;
7084 } else {
7085 neon_store_reg(rd, 0, tmp2);
7086 neon_store_reg(rd, 1, tmp);
7089 break;
7090 case NEON_2RM_VSHLL:
7091 if (q || (rd & 1)) {
7092 return 1;
7094 tmp = neon_load_reg(rm, 0);
7095 tmp2 = neon_load_reg(rm, 1);
7096 for (pass = 0; pass < 2; pass++) {
7097 if (pass == 1)
7098 tmp = tmp2;
7099 gen_neon_widen(cpu_V0, tmp, size, 1);
7100 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7101 neon_store_reg64(cpu_V0, rd + pass);
7103 break;
7104 case NEON_2RM_VCVT_F16_F32:
7105 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7106 q || (rm & 1)) {
7107 return 1;
7109 tmp = tcg_temp_new_i32();
7110 tmp2 = tcg_temp_new_i32();
7111 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7112 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7113 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7114 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7115 tcg_gen_shli_i32(tmp2, tmp2, 16);
7116 tcg_gen_or_i32(tmp2, tmp2, tmp);
7117 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7118 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7119 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7120 neon_store_reg(rd, 0, tmp2);
7121 tmp2 = tcg_temp_new_i32();
7122 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7123 tcg_gen_shli_i32(tmp2, tmp2, 16);
7124 tcg_gen_or_i32(tmp2, tmp2, tmp);
7125 neon_store_reg(rd, 1, tmp2);
7126 tcg_temp_free_i32(tmp);
7127 break;
7128 case NEON_2RM_VCVT_F32_F16:
7129 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7130 q || (rd & 1)) {
7131 return 1;
7133 tmp3 = tcg_temp_new_i32();
7134 tmp = neon_load_reg(rm, 0);
7135 tmp2 = neon_load_reg(rm, 1);
7136 tcg_gen_ext16u_i32(tmp3, tmp);
7137 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7138 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7139 tcg_gen_shri_i32(tmp3, tmp, 16);
7140 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7141 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7142 tcg_temp_free_i32(tmp);
7143 tcg_gen_ext16u_i32(tmp3, tmp2);
7144 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7145 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7146 tcg_gen_shri_i32(tmp3, tmp2, 16);
7147 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7148 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7149 tcg_temp_free_i32(tmp2);
7150 tcg_temp_free_i32(tmp3);
7151 break;
7152 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7153 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7154 || ((rm | rd) & 1)) {
7155 return 1;
7157 tmp = tcg_const_i32(rd);
7158 tmp2 = tcg_const_i32(rm);
7160 /* Bit 6 is the lowest opcode bit; it distinguishes between
7161 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7163 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7165 if (op == NEON_2RM_AESE) {
7166 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
7167 } else {
7168 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
7170 tcg_temp_free_i32(tmp);
7171 tcg_temp_free_i32(tmp2);
7172 tcg_temp_free_i32(tmp3);
7173 break;
7174 case NEON_2RM_SHA1H:
7175 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7176 || ((rm | rd) & 1)) {
7177 return 1;
7179 tmp = tcg_const_i32(rd);
7180 tmp2 = tcg_const_i32(rm);
7182 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
7184 tcg_temp_free_i32(tmp);
7185 tcg_temp_free_i32(tmp2);
7186 break;
7187 case NEON_2RM_SHA1SU1:
7188 if ((rm | rd) & 1) {
7189 return 1;
7191 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7192 if (q) {
7193 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7194 return 1;
7196 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7197 return 1;
7199 tmp = tcg_const_i32(rd);
7200 tmp2 = tcg_const_i32(rm);
7201 if (q) {
7202 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7203 } else {
7204 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7206 tcg_temp_free_i32(tmp);
7207 tcg_temp_free_i32(tmp2);
7208 break;
7209 default:
7210 elementwise:
7211 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7212 if (neon_2rm_is_float_op(op)) {
7213 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7214 neon_reg_offset(rm, pass));
7215 TCGV_UNUSED_I32(tmp);
7216 } else {
7217 tmp = neon_load_reg(rm, pass);
7219 switch (op) {
7220 case NEON_2RM_VREV32:
7221 switch (size) {
7222 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7223 case 1: gen_swap_half(tmp); break;
7224 default: abort();
7226 break;
7227 case NEON_2RM_VREV16:
7228 gen_rev16(tmp);
7229 break;
7230 case NEON_2RM_VCLS:
7231 switch (size) {
7232 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7233 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7234 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7235 default: abort();
7237 break;
7238 case NEON_2RM_VCLZ:
7239 switch (size) {
7240 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7241 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7242 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7243 default: abort();
7245 break;
7246 case NEON_2RM_VCNT:
7247 gen_helper_neon_cnt_u8(tmp, tmp);
7248 break;
7249 case NEON_2RM_VMVN:
7250 tcg_gen_not_i32(tmp, tmp);
7251 break;
7252 case NEON_2RM_VQABS:
7253 switch (size) {
7254 case 0:
7255 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7256 break;
7257 case 1:
7258 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7259 break;
7260 case 2:
7261 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7262 break;
7263 default: abort();
7265 break;
7266 case NEON_2RM_VQNEG:
7267 switch (size) {
7268 case 0:
7269 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7270 break;
7271 case 1:
7272 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7273 break;
7274 case 2:
7275 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7276 break;
7277 default: abort();
7279 break;
7280 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7281 tmp2 = tcg_const_i32(0);
7282 switch(size) {
7283 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7284 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7285 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7286 default: abort();
7288 tcg_temp_free_i32(tmp2);
7289 if (op == NEON_2RM_VCLE0) {
7290 tcg_gen_not_i32(tmp, tmp);
7292 break;
7293 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7294 tmp2 = tcg_const_i32(0);
7295 switch(size) {
7296 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7297 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7298 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7299 default: abort();
7301 tcg_temp_free_i32(tmp2);
7302 if (op == NEON_2RM_VCLT0) {
7303 tcg_gen_not_i32(tmp, tmp);
7305 break;
7306 case NEON_2RM_VCEQ0:
7307 tmp2 = tcg_const_i32(0);
7308 switch(size) {
7309 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7310 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7311 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7312 default: abort();
7314 tcg_temp_free_i32(tmp2);
7315 break;
7316 case NEON_2RM_VABS:
7317 switch(size) {
7318 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7319 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7320 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7321 default: abort();
7323 break;
7324 case NEON_2RM_VNEG:
7325 tmp2 = tcg_const_i32(0);
7326 gen_neon_rsb(size, tmp, tmp2);
7327 tcg_temp_free_i32(tmp2);
7328 break;
7329 case NEON_2RM_VCGT0_F:
7331 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7332 tmp2 = tcg_const_i32(0);
7333 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7334 tcg_temp_free_i32(tmp2);
7335 tcg_temp_free_ptr(fpstatus);
7336 break;
7338 case NEON_2RM_VCGE0_F:
7340 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7341 tmp2 = tcg_const_i32(0);
7342 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7343 tcg_temp_free_i32(tmp2);
7344 tcg_temp_free_ptr(fpstatus);
7345 break;
7347 case NEON_2RM_VCEQ0_F:
7349 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7350 tmp2 = tcg_const_i32(0);
7351 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7352 tcg_temp_free_i32(tmp2);
7353 tcg_temp_free_ptr(fpstatus);
7354 break;
7356 case NEON_2RM_VCLE0_F:
7358 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7359 tmp2 = tcg_const_i32(0);
7360 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7361 tcg_temp_free_i32(tmp2);
7362 tcg_temp_free_ptr(fpstatus);
7363 break;
7365 case NEON_2RM_VCLT0_F:
7367 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7368 tmp2 = tcg_const_i32(0);
7369 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7370 tcg_temp_free_i32(tmp2);
7371 tcg_temp_free_ptr(fpstatus);
7372 break;
7374 case NEON_2RM_VABS_F:
7375 gen_vfp_abs(0);
7376 break;
7377 case NEON_2RM_VNEG_F:
7378 gen_vfp_neg(0);
7379 break;
7380 case NEON_2RM_VSWP:
7381 tmp2 = neon_load_reg(rd, pass);
7382 neon_store_reg(rm, pass, tmp2);
7383 break;
7384 case NEON_2RM_VTRN:
7385 tmp2 = neon_load_reg(rd, pass);
7386 switch (size) {
7387 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7388 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7389 default: abort();
7391 neon_store_reg(rm, pass, tmp2);
7392 break;
7393 case NEON_2RM_VRINTN:
7394 case NEON_2RM_VRINTA:
7395 case NEON_2RM_VRINTM:
7396 case NEON_2RM_VRINTP:
7397 case NEON_2RM_VRINTZ:
7399 TCGv_i32 tcg_rmode;
7400 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7401 int rmode;
7403 if (op == NEON_2RM_VRINTZ) {
7404 rmode = FPROUNDING_ZERO;
7405 } else {
7406 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7409 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7410 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7411 cpu_env);
7412 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7413 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7414 cpu_env);
7415 tcg_temp_free_ptr(fpstatus);
7416 tcg_temp_free_i32(tcg_rmode);
7417 break;
7419 case NEON_2RM_VRINTX:
7421 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7422 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7423 tcg_temp_free_ptr(fpstatus);
7424 break;
7426 case NEON_2RM_VCVTAU:
7427 case NEON_2RM_VCVTAS:
7428 case NEON_2RM_VCVTNU:
7429 case NEON_2RM_VCVTNS:
7430 case NEON_2RM_VCVTPU:
7431 case NEON_2RM_VCVTPS:
7432 case NEON_2RM_VCVTMU:
7433 case NEON_2RM_VCVTMS:
7435 bool is_signed = !extract32(insn, 7, 1);
7436 TCGv_ptr fpst = get_fpstatus_ptr(1);
7437 TCGv_i32 tcg_rmode, tcg_shift;
7438 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7440 tcg_shift = tcg_const_i32(0);
7441 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7442 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7443 cpu_env);
7445 if (is_signed) {
7446 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7447 tcg_shift, fpst);
7448 } else {
7449 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7450 tcg_shift, fpst);
7453 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7454 cpu_env);
7455 tcg_temp_free_i32(tcg_rmode);
7456 tcg_temp_free_i32(tcg_shift);
7457 tcg_temp_free_ptr(fpst);
7458 break;
7460 case NEON_2RM_VRECPE:
7462 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7463 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7464 tcg_temp_free_ptr(fpstatus);
7465 break;
7467 case NEON_2RM_VRSQRTE:
7469 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7470 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7471 tcg_temp_free_ptr(fpstatus);
7472 break;
7474 case NEON_2RM_VRECPE_F:
7476 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7477 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7478 tcg_temp_free_ptr(fpstatus);
7479 break;
7481 case NEON_2RM_VRSQRTE_F:
7483 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7484 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7485 tcg_temp_free_ptr(fpstatus);
7486 break;
7488 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7489 gen_vfp_sito(0, 1);
7490 break;
7491 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7492 gen_vfp_uito(0, 1);
7493 break;
7494 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7495 gen_vfp_tosiz(0, 1);
7496 break;
7497 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7498 gen_vfp_touiz(0, 1);
7499 break;
7500 default:
7501 /* Reserved op values were caught by the
7502 * neon_2rm_sizes[] check earlier.
7504 abort();
7506 if (neon_2rm_is_float_op(op)) {
7507 tcg_gen_st_f32(cpu_F0s, cpu_env,
7508 neon_reg_offset(rd, pass));
7509 } else {
7510 neon_store_reg(rd, pass, tmp);
7513 break;
7515 } else if ((insn & (1 << 10)) == 0) {
7516 /* VTBL, VTBX. */
7517 int n = ((insn >> 8) & 3) + 1;
7518 if ((rn + n) > 32) {
7519 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7520 * helper function running off the end of the register file.
7522 return 1;
7524 n <<= 3;
7525 if (insn & (1 << 6)) {
7526 tmp = neon_load_reg(rd, 0);
7527 } else {
7528 tmp = tcg_temp_new_i32();
7529 tcg_gen_movi_i32(tmp, 0);
7531 tmp2 = neon_load_reg(rm, 0);
7532 tmp4 = tcg_const_i32(rn);
7533 tmp5 = tcg_const_i32(n);
7534 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7535 tcg_temp_free_i32(tmp);
7536 if (insn & (1 << 6)) {
7537 tmp = neon_load_reg(rd, 1);
7538 } else {
7539 tmp = tcg_temp_new_i32();
7540 tcg_gen_movi_i32(tmp, 0);
7542 tmp3 = neon_load_reg(rm, 1);
7543 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7544 tcg_temp_free_i32(tmp5);
7545 tcg_temp_free_i32(tmp4);
7546 neon_store_reg(rd, 0, tmp2);
7547 neon_store_reg(rd, 1, tmp3);
7548 tcg_temp_free_i32(tmp);
7549 } else if ((insn & 0x380) == 0) {
7550 /* VDUP */
7551 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7552 return 1;
7554 if (insn & (1 << 19)) {
7555 tmp = neon_load_reg(rm, 1);
7556 } else {
7557 tmp = neon_load_reg(rm, 0);
7559 if (insn & (1 << 16)) {
7560 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7561 } else if (insn & (1 << 17)) {
7562 if ((insn >> 18) & 1)
7563 gen_neon_dup_high16(tmp);
7564 else
7565 gen_neon_dup_low16(tmp);
7567 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7568 tmp2 = tcg_temp_new_i32();
7569 tcg_gen_mov_i32(tmp2, tmp);
7570 neon_store_reg(rd, pass, tmp2);
7572 tcg_temp_free_i32(tmp);
7573 } else {
7574 return 1;
7578 return 0;
7581 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7583 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7584 const ARMCPRegInfo *ri;
7586 cpnum = (insn >> 8) & 0xf;
7588 /* First check for coprocessor space used for XScale/iwMMXt insns */
7589 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7590 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7591 return 1;
7593 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7594 return disas_iwmmxt_insn(s, insn);
7595 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7596 return disas_dsp_insn(s, insn);
7598 return 1;
7601 /* Otherwise treat as a generic register access */
7602 is64 = (insn & (1 << 25)) == 0;
7603 if (!is64 && ((insn & (1 << 4)) == 0)) {
7604 /* cdp */
7605 return 1;
7608 crm = insn & 0xf;
7609 if (is64) {
7610 crn = 0;
7611 opc1 = (insn >> 4) & 0xf;
7612 opc2 = 0;
7613 rt2 = (insn >> 16) & 0xf;
7614 } else {
7615 crn = (insn >> 16) & 0xf;
7616 opc1 = (insn >> 21) & 7;
7617 opc2 = (insn >> 5) & 7;
7618 rt2 = 0;
7620 isread = (insn >> 20) & 1;
7621 rt = (insn >> 12) & 0xf;
7623 ri = get_arm_cp_reginfo(s->cp_regs,
7624 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7625 if (ri) {
7626 /* Check access permissions */
7627 if (!cp_access_ok(s->current_el, ri, isread)) {
7628 return 1;
7631 if (ri->accessfn ||
7632 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7633 /* Emit code to perform further access permissions checks at
7634 * runtime; this may result in an exception.
7635 * Note that on XScale all cp0..c13 registers do an access check
7636 * call in order to handle c15_cpar.
7638 TCGv_ptr tmpptr;
7639 TCGv_i32 tcg_syn, tcg_isread;
7640 uint32_t syndrome;
7642 /* Note that since we are an implementation which takes an
7643 * exception on a trapped conditional instruction only if the
7644 * instruction passes its condition code check, we can take
7645 * advantage of the clause in the ARM ARM that allows us to set
7646 * the COND field in the instruction to 0xE in all cases.
7647 * We could fish the actual condition out of the insn (ARM)
7648 * or the condexec bits (Thumb) but it isn't necessary.
7650 switch (cpnum) {
7651 case 14:
7652 if (is64) {
7653 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7654 isread, false);
7655 } else {
7656 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7657 rt, isread, false);
7659 break;
7660 case 15:
7661 if (is64) {
7662 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7663 isread, false);
7664 } else {
7665 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7666 rt, isread, false);
7668 break;
7669 default:
7670 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7671 * so this can only happen if this is an ARMv7 or earlier CPU,
7672 * in which case the syndrome information won't actually be
7673 * guest visible.
7675 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7676 syndrome = syn_uncategorized();
7677 break;
7680 gen_set_condexec(s);
7681 gen_set_pc_im(s, s->pc - 4);
7682 tmpptr = tcg_const_ptr(ri);
7683 tcg_syn = tcg_const_i32(syndrome);
7684 tcg_isread = tcg_const_i32(isread);
7685 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7686 tcg_isread);
7687 tcg_temp_free_ptr(tmpptr);
7688 tcg_temp_free_i32(tcg_syn);
7689 tcg_temp_free_i32(tcg_isread);
7692 /* Handle special cases first */
7693 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7694 case ARM_CP_NOP:
7695 return 0;
7696 case ARM_CP_WFI:
7697 if (isread) {
7698 return 1;
7700 gen_set_pc_im(s, s->pc);
7701 s->base.is_jmp = DISAS_WFI;
7702 return 0;
7703 default:
7704 break;
7707 if ((s->base.tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7708 gen_io_start();
7711 if (isread) {
7712 /* Read */
7713 if (is64) {
7714 TCGv_i64 tmp64;
7715 TCGv_i32 tmp;
7716 if (ri->type & ARM_CP_CONST) {
7717 tmp64 = tcg_const_i64(ri->resetvalue);
7718 } else if (ri->readfn) {
7719 TCGv_ptr tmpptr;
7720 tmp64 = tcg_temp_new_i64();
7721 tmpptr = tcg_const_ptr(ri);
7722 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7723 tcg_temp_free_ptr(tmpptr);
7724 } else {
7725 tmp64 = tcg_temp_new_i64();
7726 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7728 tmp = tcg_temp_new_i32();
7729 tcg_gen_extrl_i64_i32(tmp, tmp64);
7730 store_reg(s, rt, tmp);
7731 tcg_gen_shri_i64(tmp64, tmp64, 32);
7732 tmp = tcg_temp_new_i32();
7733 tcg_gen_extrl_i64_i32(tmp, tmp64);
7734 tcg_temp_free_i64(tmp64);
7735 store_reg(s, rt2, tmp);
7736 } else {
7737 TCGv_i32 tmp;
7738 if (ri->type & ARM_CP_CONST) {
7739 tmp = tcg_const_i32(ri->resetvalue);
7740 } else if (ri->readfn) {
7741 TCGv_ptr tmpptr;
7742 tmp = tcg_temp_new_i32();
7743 tmpptr = tcg_const_ptr(ri);
7744 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7745 tcg_temp_free_ptr(tmpptr);
7746 } else {
7747 tmp = load_cpu_offset(ri->fieldoffset);
7749 if (rt == 15) {
7750 /* Destination register of r15 for 32 bit loads sets
7751 * the condition codes from the high 4 bits of the value
7753 gen_set_nzcv(tmp);
7754 tcg_temp_free_i32(tmp);
7755 } else {
7756 store_reg(s, rt, tmp);
7759 } else {
7760 /* Write */
7761 if (ri->type & ARM_CP_CONST) {
7762 /* If not forbidden by access permissions, treat as WI */
7763 return 0;
7766 if (is64) {
7767 TCGv_i32 tmplo, tmphi;
7768 TCGv_i64 tmp64 = tcg_temp_new_i64();
7769 tmplo = load_reg(s, rt);
7770 tmphi = load_reg(s, rt2);
7771 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7772 tcg_temp_free_i32(tmplo);
7773 tcg_temp_free_i32(tmphi);
7774 if (ri->writefn) {
7775 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7776 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7777 tcg_temp_free_ptr(tmpptr);
7778 } else {
7779 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7781 tcg_temp_free_i64(tmp64);
7782 } else {
7783 if (ri->writefn) {
7784 TCGv_i32 tmp;
7785 TCGv_ptr tmpptr;
7786 tmp = load_reg(s, rt);
7787 tmpptr = tcg_const_ptr(ri);
7788 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7789 tcg_temp_free_ptr(tmpptr);
7790 tcg_temp_free_i32(tmp);
7791 } else {
7792 TCGv_i32 tmp = load_reg(s, rt);
7793 store_cpu_offset(tmp, ri->fieldoffset);
7798 if ((s->base.tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7799 /* I/O operations must end the TB here (whether read or write) */
7800 gen_io_end();
7801 gen_lookup_tb(s);
7802 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7803 /* We default to ending the TB on a coprocessor register write,
7804 * but allow this to be suppressed by the register definition
7805 * (usually only necessary to work around guest bugs).
7807 gen_lookup_tb(s);
7810 return 0;
7813 /* Unknown register; this might be a guest error or a QEMU
7814 * unimplemented feature.
7816 if (is64) {
7817 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7818 "64 bit system register cp:%d opc1: %d crm:%d "
7819 "(%s)\n",
7820 isread ? "read" : "write", cpnum, opc1, crm,
7821 s->ns ? "non-secure" : "secure");
7822 } else {
7823 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7824 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7825 "(%s)\n",
7826 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7827 s->ns ? "non-secure" : "secure");
7830 return 1;
7834 /* Store a 64-bit value to a register pair. Clobbers val. */
7835 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7837 TCGv_i32 tmp;
7838 tmp = tcg_temp_new_i32();
7839 tcg_gen_extrl_i64_i32(tmp, val);
7840 store_reg(s, rlow, tmp);
7841 tmp = tcg_temp_new_i32();
7842 tcg_gen_shri_i64(val, val, 32);
7843 tcg_gen_extrl_i64_i32(tmp, val);
7844 store_reg(s, rhigh, tmp);
7847 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7848 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7850 TCGv_i64 tmp;
7851 TCGv_i32 tmp2;
7853 /* Load value and extend to 64 bits. */
7854 tmp = tcg_temp_new_i64();
7855 tmp2 = load_reg(s, rlow);
7856 tcg_gen_extu_i32_i64(tmp, tmp2);
7857 tcg_temp_free_i32(tmp2);
7858 tcg_gen_add_i64(val, val, tmp);
7859 tcg_temp_free_i64(tmp);
7862 /* load and add a 64-bit value from a register pair. */
7863 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7865 TCGv_i64 tmp;
7866 TCGv_i32 tmpl;
7867 TCGv_i32 tmph;
7869 /* Load 64-bit value rd:rn. */
7870 tmpl = load_reg(s, rlow);
7871 tmph = load_reg(s, rhigh);
7872 tmp = tcg_temp_new_i64();
7873 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7874 tcg_temp_free_i32(tmpl);
7875 tcg_temp_free_i32(tmph);
7876 tcg_gen_add_i64(val, val, tmp);
7877 tcg_temp_free_i64(tmp);
7880 /* Set N and Z flags from hi|lo. */
7881 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7883 tcg_gen_mov_i32(cpu_NF, hi);
7884 tcg_gen_or_i32(cpu_ZF, lo, hi);
7887 /* Load/Store exclusive instructions are implemented by remembering
7888 the value/address loaded, and seeing if these are the same
7889 when the store is performed. This should be sufficient to implement
7890 the architecturally mandated semantics, and avoids having to monitor
7891 regular stores. The compare vs the remembered value is done during
7892 the cmpxchg operation, but we must compare the addresses manually. */
7893 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7894 TCGv_i32 addr, int size)
7896 TCGv_i32 tmp = tcg_temp_new_i32();
7897 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7899 s->is_ldex = true;
7901 if (size == 3) {
7902 TCGv_i32 tmp2 = tcg_temp_new_i32();
7903 TCGv_i64 t64 = tcg_temp_new_i64();
7905 gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
7906 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7907 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7908 tcg_temp_free_i64(t64);
7910 store_reg(s, rt2, tmp2);
7911 } else {
7912 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7913 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7916 store_reg(s, rt, tmp);
7917 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7920 static void gen_clrex(DisasContext *s)
7922 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7925 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7926 TCGv_i32 addr, int size)
7928 TCGv_i32 t0, t1, t2;
7929 TCGv_i64 extaddr;
7930 TCGv taddr;
7931 TCGLabel *done_label;
7932 TCGLabel *fail_label;
7933 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7935 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7936 [addr] = {Rt};
7937 {Rd} = 0;
7938 } else {
7939 {Rd} = 1;
7940 } */
7941 fail_label = gen_new_label();
7942 done_label = gen_new_label();
7943 extaddr = tcg_temp_new_i64();
7944 tcg_gen_extu_i32_i64(extaddr, addr);
7945 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7946 tcg_temp_free_i64(extaddr);
7948 taddr = gen_aa32_addr(s, addr, opc);
7949 t0 = tcg_temp_new_i32();
7950 t1 = load_reg(s, rt);
7951 if (size == 3) {
7952 TCGv_i64 o64 = tcg_temp_new_i64();
7953 TCGv_i64 n64 = tcg_temp_new_i64();
7955 t2 = load_reg(s, rt2);
7956 tcg_gen_concat_i32_i64(n64, t1, t2);
7957 tcg_temp_free_i32(t2);
7958 gen_aa32_frob64(s, n64);
7960 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7961 get_mem_index(s), opc);
7962 tcg_temp_free_i64(n64);
7964 gen_aa32_frob64(s, o64);
7965 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7966 tcg_gen_extrl_i64_i32(t0, o64);
7968 tcg_temp_free_i64(o64);
7969 } else {
7970 t2 = tcg_temp_new_i32();
7971 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7972 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7973 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7974 tcg_temp_free_i32(t2);
7976 tcg_temp_free_i32(t1);
7977 tcg_temp_free(taddr);
7978 tcg_gen_mov_i32(cpu_R[rd], t0);
7979 tcg_temp_free_i32(t0);
7980 tcg_gen_br(done_label);
7982 gen_set_label(fail_label);
7983 tcg_gen_movi_i32(cpu_R[rd], 1);
7984 gen_set_label(done_label);
7985 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7988 /* gen_srs:
7989 * @env: CPUARMState
7990 * @s: DisasContext
7991 * @mode: mode field from insn (which stack to store to)
7992 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7993 * @writeback: true if writeback bit set
7995 * Generate code for the SRS (Store Return State) insn.
7997 static void gen_srs(DisasContext *s,
7998 uint32_t mode, uint32_t amode, bool writeback)
8000 int32_t offset;
8001 TCGv_i32 addr, tmp;
8002 bool undef = false;
8004 /* SRS is:
8005 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8006 * and specified mode is monitor mode
8007 * - UNDEFINED in Hyp mode
8008 * - UNPREDICTABLE in User or System mode
8009 * - UNPREDICTABLE if the specified mode is:
8010 * -- not implemented
8011 * -- not a valid mode number
8012 * -- a mode that's at a higher exception level
8013 * -- Monitor, if we are Non-secure
8014 * For the UNPREDICTABLE cases we choose to UNDEF.
8016 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8017 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8018 return;
8021 if (s->current_el == 0 || s->current_el == 2) {
8022 undef = true;
8025 switch (mode) {
8026 case ARM_CPU_MODE_USR:
8027 case ARM_CPU_MODE_FIQ:
8028 case ARM_CPU_MODE_IRQ:
8029 case ARM_CPU_MODE_SVC:
8030 case ARM_CPU_MODE_ABT:
8031 case ARM_CPU_MODE_UND:
8032 case ARM_CPU_MODE_SYS:
8033 break;
8034 case ARM_CPU_MODE_HYP:
8035 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8036 undef = true;
8038 break;
8039 case ARM_CPU_MODE_MON:
8040 /* No need to check specifically for "are we non-secure" because
8041 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8042 * so if this isn't EL3 then we must be non-secure.
8044 if (s->current_el != 3) {
8045 undef = true;
8047 break;
8048 default:
8049 undef = true;
8052 if (undef) {
8053 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8054 default_exception_el(s));
8055 return;
8058 addr = tcg_temp_new_i32();
8059 tmp = tcg_const_i32(mode);
8060 /* get_r13_banked() will raise an exception if called from System mode */
8061 gen_set_condexec(s);
8062 gen_set_pc_im(s, s->pc - 4);
8063 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8064 tcg_temp_free_i32(tmp);
8065 switch (amode) {
8066 case 0: /* DA */
8067 offset = -4;
8068 break;
8069 case 1: /* IA */
8070 offset = 0;
8071 break;
8072 case 2: /* DB */
8073 offset = -8;
8074 break;
8075 case 3: /* IB */
8076 offset = 4;
8077 break;
8078 default:
8079 abort();
8081 tcg_gen_addi_i32(addr, addr, offset);
8082 tmp = load_reg(s, 14);
8083 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8084 tcg_temp_free_i32(tmp);
8085 tmp = load_cpu_field(spsr);
8086 tcg_gen_addi_i32(addr, addr, 4);
8087 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8088 tcg_temp_free_i32(tmp);
8089 if (writeback) {
8090 switch (amode) {
8091 case 0:
8092 offset = -8;
8093 break;
8094 case 1:
8095 offset = 4;
8096 break;
8097 case 2:
8098 offset = -4;
8099 break;
8100 case 3:
8101 offset = 0;
8102 break;
8103 default:
8104 abort();
8106 tcg_gen_addi_i32(addr, addr, offset);
8107 tmp = tcg_const_i32(mode);
8108 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8109 tcg_temp_free_i32(tmp);
8111 tcg_temp_free_i32(addr);
8112 s->base.is_jmp = DISAS_UPDATE;
8115 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8117 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8118 TCGv_i32 tmp;
8119 TCGv_i32 tmp2;
8120 TCGv_i32 tmp3;
8121 TCGv_i32 addr;
8122 TCGv_i64 tmp64;
8124 /* M variants do not implement ARM mode; this must raise the INVSTATE
8125 * UsageFault exception.
8127 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8128 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8129 default_exception_el(s));
8130 return;
8132 cond = insn >> 28;
8133 if (cond == 0xf){
8134 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8135 * choose to UNDEF. In ARMv5 and above the space is used
8136 * for miscellaneous unconditional instructions.
8138 ARCH(5);
8140 /* Unconditional instructions. */
8141 if (((insn >> 25) & 7) == 1) {
8142 /* NEON Data processing. */
8143 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8144 goto illegal_op;
8147 if (disas_neon_data_insn(s, insn)) {
8148 goto illegal_op;
8150 return;
8152 if ((insn & 0x0f100000) == 0x04000000) {
8153 /* NEON load/store. */
8154 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8155 goto illegal_op;
8158 if (disas_neon_ls_insn(s, insn)) {
8159 goto illegal_op;
8161 return;
8163 if ((insn & 0x0f000e10) == 0x0e000a00) {
8164 /* VFP. */
8165 if (disas_vfp_insn(s, insn)) {
8166 goto illegal_op;
8168 return;
8170 if (((insn & 0x0f30f000) == 0x0510f000) ||
8171 ((insn & 0x0f30f010) == 0x0710f000)) {
8172 if ((insn & (1 << 22)) == 0) {
8173 /* PLDW; v7MP */
8174 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8175 goto illegal_op;
8178 /* Otherwise PLD; v5TE+ */
8179 ARCH(5TE);
8180 return;
8182 if (((insn & 0x0f70f000) == 0x0450f000) ||
8183 ((insn & 0x0f70f010) == 0x0650f000)) {
8184 ARCH(7);
8185 return; /* PLI; V7 */
8187 if (((insn & 0x0f700000) == 0x04100000) ||
8188 ((insn & 0x0f700010) == 0x06100000)) {
8189 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8190 goto illegal_op;
8192 return; /* v7MP: Unallocated memory hint: must NOP */
8195 if ((insn & 0x0ffffdff) == 0x01010000) {
8196 ARCH(6);
8197 /* setend */
8198 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8199 gen_helper_setend(cpu_env);
8200 s->base.is_jmp = DISAS_UPDATE;
8202 return;
8203 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8204 switch ((insn >> 4) & 0xf) {
8205 case 1: /* clrex */
8206 ARCH(6K);
8207 gen_clrex(s);
8208 return;
8209 case 4: /* dsb */
8210 case 5: /* dmb */
8211 ARCH(7);
8212 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8213 return;
8214 case 6: /* isb */
8215 /* We need to break the TB after this insn to execute
8216 * self-modifying code correctly and also to take
8217 * any pending interrupts immediately.
8219 gen_goto_tb(s, 0, s->pc & ~1);
8220 return;
8221 default:
8222 goto illegal_op;
8224 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8225 /* srs */
8226 ARCH(6);
8227 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8228 return;
8229 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8230 /* rfe */
8231 int32_t offset;
8232 if (IS_USER(s))
8233 goto illegal_op;
8234 ARCH(6);
8235 rn = (insn >> 16) & 0xf;
8236 addr = load_reg(s, rn);
8237 i = (insn >> 23) & 3;
8238 switch (i) {
8239 case 0: offset = -4; break; /* DA */
8240 case 1: offset = 0; break; /* IA */
8241 case 2: offset = -8; break; /* DB */
8242 case 3: offset = 4; break; /* IB */
8243 default: abort();
8245 if (offset)
8246 tcg_gen_addi_i32(addr, addr, offset);
8247 /* Load PC into tmp and CPSR into tmp2. */
8248 tmp = tcg_temp_new_i32();
8249 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8250 tcg_gen_addi_i32(addr, addr, 4);
8251 tmp2 = tcg_temp_new_i32();
8252 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8253 if (insn & (1 << 21)) {
8254 /* Base writeback. */
8255 switch (i) {
8256 case 0: offset = -8; break;
8257 case 1: offset = 4; break;
8258 case 2: offset = -4; break;
8259 case 3: offset = 0; break;
8260 default: abort();
8262 if (offset)
8263 tcg_gen_addi_i32(addr, addr, offset);
8264 store_reg(s, rn, addr);
8265 } else {
8266 tcg_temp_free_i32(addr);
8268 gen_rfe(s, tmp, tmp2);
8269 return;
8270 } else if ((insn & 0x0e000000) == 0x0a000000) {
8271 /* branch link and change to thumb (blx <offset>) */
8272 int32_t offset;
8274 val = (uint32_t)s->pc;
8275 tmp = tcg_temp_new_i32();
8276 tcg_gen_movi_i32(tmp, val);
8277 store_reg(s, 14, tmp);
8278 /* Sign-extend the 24-bit offset */
8279 offset = (((int32_t)insn) << 8) >> 8;
8280 /* offset * 4 + bit24 * 2 + (thumb bit) */
8281 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8282 /* pipeline offset */
8283 val += 4;
8284 /* protected by ARCH(5); above, near the start of uncond block */
8285 gen_bx_im(s, val);
8286 return;
8287 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8288 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8289 /* iWMMXt register transfer. */
8290 if (extract32(s->c15_cpar, 1, 1)) {
8291 if (!disas_iwmmxt_insn(s, insn)) {
8292 return;
8296 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8297 /* Coprocessor double register transfer. */
8298 ARCH(5TE);
8299 } else if ((insn & 0x0f000010) == 0x0e000010) {
8300 /* Additional coprocessor register transfer. */
8301 } else if ((insn & 0x0ff10020) == 0x01000000) {
8302 uint32_t mask;
8303 uint32_t val;
8304 /* cps (privileged) */
8305 if (IS_USER(s))
8306 return;
8307 mask = val = 0;
8308 if (insn & (1 << 19)) {
8309 if (insn & (1 << 8))
8310 mask |= CPSR_A;
8311 if (insn & (1 << 7))
8312 mask |= CPSR_I;
8313 if (insn & (1 << 6))
8314 mask |= CPSR_F;
8315 if (insn & (1 << 18))
8316 val |= mask;
8318 if (insn & (1 << 17)) {
8319 mask |= CPSR_M;
8320 val |= (insn & 0x1f);
8322 if (mask) {
8323 gen_set_psr_im(s, mask, 0, val);
8325 return;
8327 goto illegal_op;
8329 if (cond != 0xe) {
8330 /* if not always execute, we generate a conditional jump to
8331 next instruction */
8332 s->condlabel = gen_new_label();
8333 arm_gen_test_cc(cond ^ 1, s->condlabel);
8334 s->condjmp = 1;
8336 if ((insn & 0x0f900000) == 0x03000000) {
8337 if ((insn & (1 << 21)) == 0) {
8338 ARCH(6T2);
8339 rd = (insn >> 12) & 0xf;
8340 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8341 if ((insn & (1 << 22)) == 0) {
8342 /* MOVW */
8343 tmp = tcg_temp_new_i32();
8344 tcg_gen_movi_i32(tmp, val);
8345 } else {
8346 /* MOVT */
8347 tmp = load_reg(s, rd);
8348 tcg_gen_ext16u_i32(tmp, tmp);
8349 tcg_gen_ori_i32(tmp, tmp, val << 16);
8351 store_reg(s, rd, tmp);
8352 } else {
8353 if (((insn >> 12) & 0xf) != 0xf)
8354 goto illegal_op;
8355 if (((insn >> 16) & 0xf) == 0) {
8356 gen_nop_hint(s, insn & 0xff);
8357 } else {
8358 /* CPSR = immediate */
8359 val = insn & 0xff;
8360 shift = ((insn >> 8) & 0xf) * 2;
8361 if (shift)
8362 val = (val >> shift) | (val << (32 - shift));
8363 i = ((insn & (1 << 22)) != 0);
8364 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8365 i, val)) {
8366 goto illegal_op;
8370 } else if ((insn & 0x0f900000) == 0x01000000
8371 && (insn & 0x00000090) != 0x00000090) {
8372 /* miscellaneous instructions */
8373 op1 = (insn >> 21) & 3;
8374 sh = (insn >> 4) & 0xf;
8375 rm = insn & 0xf;
8376 switch (sh) {
8377 case 0x0: /* MSR, MRS */
8378 if (insn & (1 << 9)) {
8379 /* MSR (banked) and MRS (banked) */
8380 int sysm = extract32(insn, 16, 4) |
8381 (extract32(insn, 8, 1) << 4);
8382 int r = extract32(insn, 22, 1);
8384 if (op1 & 1) {
8385 /* MSR (banked) */
8386 gen_msr_banked(s, r, sysm, rm);
8387 } else {
8388 /* MRS (banked) */
8389 int rd = extract32(insn, 12, 4);
8391 gen_mrs_banked(s, r, sysm, rd);
8393 break;
8396 /* MSR, MRS (for PSRs) */
8397 if (op1 & 1) {
8398 /* PSR = reg */
8399 tmp = load_reg(s, rm);
8400 i = ((op1 & 2) != 0);
8401 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8402 goto illegal_op;
8403 } else {
8404 /* reg = PSR */
8405 rd = (insn >> 12) & 0xf;
8406 if (op1 & 2) {
8407 if (IS_USER(s))
8408 goto illegal_op;
8409 tmp = load_cpu_field(spsr);
8410 } else {
8411 tmp = tcg_temp_new_i32();
8412 gen_helper_cpsr_read(tmp, cpu_env);
8414 store_reg(s, rd, tmp);
8416 break;
8417 case 0x1:
8418 if (op1 == 1) {
8419 /* branch/exchange thumb (bx). */
8420 ARCH(4T);
8421 tmp = load_reg(s, rm);
8422 gen_bx(s, tmp);
8423 } else if (op1 == 3) {
8424 /* clz */
8425 ARCH(5);
8426 rd = (insn >> 12) & 0xf;
8427 tmp = load_reg(s, rm);
8428 tcg_gen_clzi_i32(tmp, tmp, 32);
8429 store_reg(s, rd, tmp);
8430 } else {
8431 goto illegal_op;
8433 break;
8434 case 0x2:
8435 if (op1 == 1) {
8436 ARCH(5J); /* bxj */
8437 /* Trivial implementation equivalent to bx. */
8438 tmp = load_reg(s, rm);
8439 gen_bx(s, tmp);
8440 } else {
8441 goto illegal_op;
8443 break;
8444 case 0x3:
8445 if (op1 != 1)
8446 goto illegal_op;
8448 ARCH(5);
8449 /* branch link/exchange thumb (blx) */
8450 tmp = load_reg(s, rm);
8451 tmp2 = tcg_temp_new_i32();
8452 tcg_gen_movi_i32(tmp2, s->pc);
8453 store_reg(s, 14, tmp2);
8454 gen_bx(s, tmp);
8455 break;
8456 case 0x4:
8458 /* crc32/crc32c */
8459 uint32_t c = extract32(insn, 8, 4);
8461 /* Check this CPU supports ARMv8 CRC instructions.
8462 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8463 * Bits 8, 10 and 11 should be zero.
8465 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8466 (c & 0xd) != 0) {
8467 goto illegal_op;
8470 rn = extract32(insn, 16, 4);
8471 rd = extract32(insn, 12, 4);
8473 tmp = load_reg(s, rn);
8474 tmp2 = load_reg(s, rm);
8475 if (op1 == 0) {
8476 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8477 } else if (op1 == 1) {
8478 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8480 tmp3 = tcg_const_i32(1 << op1);
8481 if (c & 0x2) {
8482 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8483 } else {
8484 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8486 tcg_temp_free_i32(tmp2);
8487 tcg_temp_free_i32(tmp3);
8488 store_reg(s, rd, tmp);
8489 break;
8491 case 0x5: /* saturating add/subtract */
8492 ARCH(5TE);
8493 rd = (insn >> 12) & 0xf;
8494 rn = (insn >> 16) & 0xf;
8495 tmp = load_reg(s, rm);
8496 tmp2 = load_reg(s, rn);
8497 if (op1 & 2)
8498 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8499 if (op1 & 1)
8500 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8501 else
8502 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8503 tcg_temp_free_i32(tmp2);
8504 store_reg(s, rd, tmp);
8505 break;
8506 case 7:
8508 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8509 switch (op1) {
8510 case 0:
8511 /* HLT */
8512 gen_hlt(s, imm16);
8513 break;
8514 case 1:
8515 /* bkpt */
8516 ARCH(5);
8517 gen_exception_insn(s, 4, EXCP_BKPT,
8518 syn_aa32_bkpt(imm16, false),
8519 default_exception_el(s));
8520 break;
8521 case 2:
8522 /* Hypervisor call (v7) */
8523 ARCH(7);
8524 if (IS_USER(s)) {
8525 goto illegal_op;
8527 gen_hvc(s, imm16);
8528 break;
8529 case 3:
8530 /* Secure monitor call (v6+) */
8531 ARCH(6K);
8532 if (IS_USER(s)) {
8533 goto illegal_op;
8535 gen_smc(s);
8536 break;
8537 default:
8538 g_assert_not_reached();
8540 break;
8542 case 0x8: /* signed multiply */
8543 case 0xa:
8544 case 0xc:
8545 case 0xe:
8546 ARCH(5TE);
8547 rs = (insn >> 8) & 0xf;
8548 rn = (insn >> 12) & 0xf;
8549 rd = (insn >> 16) & 0xf;
8550 if (op1 == 1) {
8551 /* (32 * 16) >> 16 */
8552 tmp = load_reg(s, rm);
8553 tmp2 = load_reg(s, rs);
8554 if (sh & 4)
8555 tcg_gen_sari_i32(tmp2, tmp2, 16);
8556 else
8557 gen_sxth(tmp2);
8558 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8559 tcg_gen_shri_i64(tmp64, tmp64, 16);
8560 tmp = tcg_temp_new_i32();
8561 tcg_gen_extrl_i64_i32(tmp, tmp64);
8562 tcg_temp_free_i64(tmp64);
8563 if ((sh & 2) == 0) {
8564 tmp2 = load_reg(s, rn);
8565 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8566 tcg_temp_free_i32(tmp2);
8568 store_reg(s, rd, tmp);
8569 } else {
8570 /* 16 * 16 */
8571 tmp = load_reg(s, rm);
8572 tmp2 = load_reg(s, rs);
8573 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8574 tcg_temp_free_i32(tmp2);
8575 if (op1 == 2) {
8576 tmp64 = tcg_temp_new_i64();
8577 tcg_gen_ext_i32_i64(tmp64, tmp);
8578 tcg_temp_free_i32(tmp);
8579 gen_addq(s, tmp64, rn, rd);
8580 gen_storeq_reg(s, rn, rd, tmp64);
8581 tcg_temp_free_i64(tmp64);
8582 } else {
8583 if (op1 == 0) {
8584 tmp2 = load_reg(s, rn);
8585 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8586 tcg_temp_free_i32(tmp2);
8588 store_reg(s, rd, tmp);
8591 break;
8592 default:
8593 goto illegal_op;
8595 } else if (((insn & 0x0e000000) == 0 &&
8596 (insn & 0x00000090) != 0x90) ||
8597 ((insn & 0x0e000000) == (1 << 25))) {
8598 int set_cc, logic_cc, shiftop;
8600 op1 = (insn >> 21) & 0xf;
8601 set_cc = (insn >> 20) & 1;
8602 logic_cc = table_logic_cc[op1] & set_cc;
8604 /* data processing instruction */
8605 if (insn & (1 << 25)) {
8606 /* immediate operand */
8607 val = insn & 0xff;
8608 shift = ((insn >> 8) & 0xf) * 2;
8609 if (shift) {
8610 val = (val >> shift) | (val << (32 - shift));
8612 tmp2 = tcg_temp_new_i32();
8613 tcg_gen_movi_i32(tmp2, val);
8614 if (logic_cc && shift) {
8615 gen_set_CF_bit31(tmp2);
8617 } else {
8618 /* register */
8619 rm = (insn) & 0xf;
8620 tmp2 = load_reg(s, rm);
8621 shiftop = (insn >> 5) & 3;
8622 if (!(insn & (1 << 4))) {
8623 shift = (insn >> 7) & 0x1f;
8624 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8625 } else {
8626 rs = (insn >> 8) & 0xf;
8627 tmp = load_reg(s, rs);
8628 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8631 if (op1 != 0x0f && op1 != 0x0d) {
8632 rn = (insn >> 16) & 0xf;
8633 tmp = load_reg(s, rn);
8634 } else {
8635 TCGV_UNUSED_I32(tmp);
8637 rd = (insn >> 12) & 0xf;
8638 switch(op1) {
8639 case 0x00:
8640 tcg_gen_and_i32(tmp, tmp, tmp2);
8641 if (logic_cc) {
8642 gen_logic_CC(tmp);
8644 store_reg_bx(s, rd, tmp);
8645 break;
8646 case 0x01:
8647 tcg_gen_xor_i32(tmp, tmp, tmp2);
8648 if (logic_cc) {
8649 gen_logic_CC(tmp);
8651 store_reg_bx(s, rd, tmp);
8652 break;
8653 case 0x02:
8654 if (set_cc && rd == 15) {
8655 /* SUBS r15, ... is used for exception return. */
8656 if (IS_USER(s)) {
8657 goto illegal_op;
8659 gen_sub_CC(tmp, tmp, tmp2);
8660 gen_exception_return(s, tmp);
8661 } else {
8662 if (set_cc) {
8663 gen_sub_CC(tmp, tmp, tmp2);
8664 } else {
8665 tcg_gen_sub_i32(tmp, tmp, tmp2);
8667 store_reg_bx(s, rd, tmp);
8669 break;
8670 case 0x03:
8671 if (set_cc) {
8672 gen_sub_CC(tmp, tmp2, tmp);
8673 } else {
8674 tcg_gen_sub_i32(tmp, tmp2, tmp);
8676 store_reg_bx(s, rd, tmp);
8677 break;
8678 case 0x04:
8679 if (set_cc) {
8680 gen_add_CC(tmp, tmp, tmp2);
8681 } else {
8682 tcg_gen_add_i32(tmp, tmp, tmp2);
8684 store_reg_bx(s, rd, tmp);
8685 break;
8686 case 0x05:
8687 if (set_cc) {
8688 gen_adc_CC(tmp, tmp, tmp2);
8689 } else {
8690 gen_add_carry(tmp, tmp, tmp2);
8692 store_reg_bx(s, rd, tmp);
8693 break;
8694 case 0x06:
8695 if (set_cc) {
8696 gen_sbc_CC(tmp, tmp, tmp2);
8697 } else {
8698 gen_sub_carry(tmp, tmp, tmp2);
8700 store_reg_bx(s, rd, tmp);
8701 break;
8702 case 0x07:
8703 if (set_cc) {
8704 gen_sbc_CC(tmp, tmp2, tmp);
8705 } else {
8706 gen_sub_carry(tmp, tmp2, tmp);
8708 store_reg_bx(s, rd, tmp);
8709 break;
8710 case 0x08:
8711 if (set_cc) {
8712 tcg_gen_and_i32(tmp, tmp, tmp2);
8713 gen_logic_CC(tmp);
8715 tcg_temp_free_i32(tmp);
8716 break;
8717 case 0x09:
8718 if (set_cc) {
8719 tcg_gen_xor_i32(tmp, tmp, tmp2);
8720 gen_logic_CC(tmp);
8722 tcg_temp_free_i32(tmp);
8723 break;
8724 case 0x0a:
8725 if (set_cc) {
8726 gen_sub_CC(tmp, tmp, tmp2);
8728 tcg_temp_free_i32(tmp);
8729 break;
8730 case 0x0b:
8731 if (set_cc) {
8732 gen_add_CC(tmp, tmp, tmp2);
8734 tcg_temp_free_i32(tmp);
8735 break;
8736 case 0x0c:
8737 tcg_gen_or_i32(tmp, tmp, tmp2);
8738 if (logic_cc) {
8739 gen_logic_CC(tmp);
8741 store_reg_bx(s, rd, tmp);
8742 break;
8743 case 0x0d:
8744 if (logic_cc && rd == 15) {
8745 /* MOVS r15, ... is used for exception return. */
8746 if (IS_USER(s)) {
8747 goto illegal_op;
8749 gen_exception_return(s, tmp2);
8750 } else {
8751 if (logic_cc) {
8752 gen_logic_CC(tmp2);
8754 store_reg_bx(s, rd, tmp2);
8756 break;
8757 case 0x0e:
8758 tcg_gen_andc_i32(tmp, tmp, tmp2);
8759 if (logic_cc) {
8760 gen_logic_CC(tmp);
8762 store_reg_bx(s, rd, tmp);
8763 break;
8764 default:
8765 case 0x0f:
8766 tcg_gen_not_i32(tmp2, tmp2);
8767 if (logic_cc) {
8768 gen_logic_CC(tmp2);
8770 store_reg_bx(s, rd, tmp2);
8771 break;
8773 if (op1 != 0x0f && op1 != 0x0d) {
8774 tcg_temp_free_i32(tmp2);
8776 } else {
8777 /* other instructions */
8778 op1 = (insn >> 24) & 0xf;
8779 switch(op1) {
8780 case 0x0:
8781 case 0x1:
8782 /* multiplies, extra load/stores */
8783 sh = (insn >> 5) & 3;
8784 if (sh == 0) {
8785 if (op1 == 0x0) {
8786 rd = (insn >> 16) & 0xf;
8787 rn = (insn >> 12) & 0xf;
8788 rs = (insn >> 8) & 0xf;
8789 rm = (insn) & 0xf;
8790 op1 = (insn >> 20) & 0xf;
8791 switch (op1) {
8792 case 0: case 1: case 2: case 3: case 6:
8793 /* 32 bit mul */
8794 tmp = load_reg(s, rs);
8795 tmp2 = load_reg(s, rm);
8796 tcg_gen_mul_i32(tmp, tmp, tmp2);
8797 tcg_temp_free_i32(tmp2);
8798 if (insn & (1 << 22)) {
8799 /* Subtract (mls) */
8800 ARCH(6T2);
8801 tmp2 = load_reg(s, rn);
8802 tcg_gen_sub_i32(tmp, tmp2, tmp);
8803 tcg_temp_free_i32(tmp2);
8804 } else if (insn & (1 << 21)) {
8805 /* Add */
8806 tmp2 = load_reg(s, rn);
8807 tcg_gen_add_i32(tmp, tmp, tmp2);
8808 tcg_temp_free_i32(tmp2);
8810 if (insn & (1 << 20))
8811 gen_logic_CC(tmp);
8812 store_reg(s, rd, tmp);
8813 break;
8814 case 4:
8815 /* 64 bit mul double accumulate (UMAAL) */
8816 ARCH(6);
8817 tmp = load_reg(s, rs);
8818 tmp2 = load_reg(s, rm);
8819 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8820 gen_addq_lo(s, tmp64, rn);
8821 gen_addq_lo(s, tmp64, rd);
8822 gen_storeq_reg(s, rn, rd, tmp64);
8823 tcg_temp_free_i64(tmp64);
8824 break;
8825 case 8: case 9: case 10: case 11:
8826 case 12: case 13: case 14: case 15:
8827 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8828 tmp = load_reg(s, rs);
8829 tmp2 = load_reg(s, rm);
8830 if (insn & (1 << 22)) {
8831 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8832 } else {
8833 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8835 if (insn & (1 << 21)) { /* mult accumulate */
8836 TCGv_i32 al = load_reg(s, rn);
8837 TCGv_i32 ah = load_reg(s, rd);
8838 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8839 tcg_temp_free_i32(al);
8840 tcg_temp_free_i32(ah);
8842 if (insn & (1 << 20)) {
8843 gen_logicq_cc(tmp, tmp2);
8845 store_reg(s, rn, tmp);
8846 store_reg(s, rd, tmp2);
8847 break;
8848 default:
8849 goto illegal_op;
8851 } else {
8852 rn = (insn >> 16) & 0xf;
8853 rd = (insn >> 12) & 0xf;
8854 if (insn & (1 << 23)) {
8855 /* load/store exclusive */
8856 int op2 = (insn >> 8) & 3;
8857 op1 = (insn >> 21) & 0x3;
8859 switch (op2) {
8860 case 0: /* lda/stl */
8861 if (op1 == 1) {
8862 goto illegal_op;
8864 ARCH(8);
8865 break;
8866 case 1: /* reserved */
8867 goto illegal_op;
8868 case 2: /* ldaex/stlex */
8869 ARCH(8);
8870 break;
8871 case 3: /* ldrex/strex */
8872 if (op1) {
8873 ARCH(6K);
8874 } else {
8875 ARCH(6);
8877 break;
8880 addr = tcg_temp_local_new_i32();
8881 load_reg_var(s, addr, rn);
8883 /* Since the emulation does not have barriers,
8884 the acquire/release semantics need no special
8885 handling */
8886 if (op2 == 0) {
8887 if (insn & (1 << 20)) {
8888 tmp = tcg_temp_new_i32();
8889 switch (op1) {
8890 case 0: /* lda */
8891 gen_aa32_ld32u_iss(s, tmp, addr,
8892 get_mem_index(s),
8893 rd | ISSIsAcqRel);
8894 break;
8895 case 2: /* ldab */
8896 gen_aa32_ld8u_iss(s, tmp, addr,
8897 get_mem_index(s),
8898 rd | ISSIsAcqRel);
8899 break;
8900 case 3: /* ldah */
8901 gen_aa32_ld16u_iss(s, tmp, addr,
8902 get_mem_index(s),
8903 rd | ISSIsAcqRel);
8904 break;
8905 default:
8906 abort();
8908 store_reg(s, rd, tmp);
8909 } else {
8910 rm = insn & 0xf;
8911 tmp = load_reg(s, rm);
8912 switch (op1) {
8913 case 0: /* stl */
8914 gen_aa32_st32_iss(s, tmp, addr,
8915 get_mem_index(s),
8916 rm | ISSIsAcqRel);
8917 break;
8918 case 2: /* stlb */
8919 gen_aa32_st8_iss(s, tmp, addr,
8920 get_mem_index(s),
8921 rm | ISSIsAcqRel);
8922 break;
8923 case 3: /* stlh */
8924 gen_aa32_st16_iss(s, tmp, addr,
8925 get_mem_index(s),
8926 rm | ISSIsAcqRel);
8927 break;
8928 default:
8929 abort();
8931 tcg_temp_free_i32(tmp);
8933 } else if (insn & (1 << 20)) {
8934 switch (op1) {
8935 case 0: /* ldrex */
8936 gen_load_exclusive(s, rd, 15, addr, 2);
8937 break;
8938 case 1: /* ldrexd */
8939 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8940 break;
8941 case 2: /* ldrexb */
8942 gen_load_exclusive(s, rd, 15, addr, 0);
8943 break;
8944 case 3: /* ldrexh */
8945 gen_load_exclusive(s, rd, 15, addr, 1);
8946 break;
8947 default:
8948 abort();
8950 } else {
8951 rm = insn & 0xf;
8952 switch (op1) {
8953 case 0: /* strex */
8954 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8955 break;
8956 case 1: /* strexd */
8957 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8958 break;
8959 case 2: /* strexb */
8960 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8961 break;
8962 case 3: /* strexh */
8963 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8964 break;
8965 default:
8966 abort();
8969 tcg_temp_free_i32(addr);
8970 } else {
8971 TCGv taddr;
8972 TCGMemOp opc = s->be_data;
8974 /* SWP instruction */
8975 rm = (insn) & 0xf;
8977 if (insn & (1 << 22)) {
8978 opc |= MO_UB;
8979 } else {
8980 opc |= MO_UL | MO_ALIGN;
8983 addr = load_reg(s, rn);
8984 taddr = gen_aa32_addr(s, addr, opc);
8985 tcg_temp_free_i32(addr);
8987 tmp = load_reg(s, rm);
8988 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8989 get_mem_index(s), opc);
8990 tcg_temp_free(taddr);
8991 store_reg(s, rd, tmp);
8994 } else {
8995 int address_offset;
8996 bool load = insn & (1 << 20);
8997 bool wbit = insn & (1 << 21);
8998 bool pbit = insn & (1 << 24);
8999 bool doubleword = false;
9000 ISSInfo issinfo;
9002 /* Misc load/store */
9003 rn = (insn >> 16) & 0xf;
9004 rd = (insn >> 12) & 0xf;
9006 /* ISS not valid if writeback */
9007 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9009 if (!load && (sh & 2)) {
9010 /* doubleword */
9011 ARCH(5TE);
9012 if (rd & 1) {
9013 /* UNPREDICTABLE; we choose to UNDEF */
9014 goto illegal_op;
9016 load = (sh & 1) == 0;
9017 doubleword = true;
9020 addr = load_reg(s, rn);
9021 if (pbit) {
9022 gen_add_datah_offset(s, insn, 0, addr);
9024 address_offset = 0;
9026 if (doubleword) {
9027 if (!load) {
9028 /* store */
9029 tmp = load_reg(s, rd);
9030 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9031 tcg_temp_free_i32(tmp);
9032 tcg_gen_addi_i32(addr, addr, 4);
9033 tmp = load_reg(s, rd + 1);
9034 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9035 tcg_temp_free_i32(tmp);
9036 } else {
9037 /* load */
9038 tmp = tcg_temp_new_i32();
9039 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9040 store_reg(s, rd, tmp);
9041 tcg_gen_addi_i32(addr, addr, 4);
9042 tmp = tcg_temp_new_i32();
9043 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9044 rd++;
9046 address_offset = -4;
9047 } else if (load) {
9048 /* load */
9049 tmp = tcg_temp_new_i32();
9050 switch (sh) {
9051 case 1:
9052 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9053 issinfo);
9054 break;
9055 case 2:
9056 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9057 issinfo);
9058 break;
9059 default:
9060 case 3:
9061 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9062 issinfo);
9063 break;
9065 } else {
9066 /* store */
9067 tmp = load_reg(s, rd);
9068 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9069 tcg_temp_free_i32(tmp);
9071 /* Perform base writeback before the loaded value to
9072 ensure correct behavior with overlapping index registers.
9073 ldrd with base writeback is undefined if the
9074 destination and index registers overlap. */
9075 if (!pbit) {
9076 gen_add_datah_offset(s, insn, address_offset, addr);
9077 store_reg(s, rn, addr);
9078 } else if (wbit) {
9079 if (address_offset)
9080 tcg_gen_addi_i32(addr, addr, address_offset);
9081 store_reg(s, rn, addr);
9082 } else {
9083 tcg_temp_free_i32(addr);
9085 if (load) {
9086 /* Complete the load. */
9087 store_reg(s, rd, tmp);
9090 break;
9091 case 0x4:
9092 case 0x5:
9093 goto do_ldst;
9094 case 0x6:
9095 case 0x7:
9096 if (insn & (1 << 4)) {
9097 ARCH(6);
9098 /* Armv6 Media instructions. */
9099 rm = insn & 0xf;
9100 rn = (insn >> 16) & 0xf;
9101 rd = (insn >> 12) & 0xf;
9102 rs = (insn >> 8) & 0xf;
9103 switch ((insn >> 23) & 3) {
9104 case 0: /* Parallel add/subtract. */
9105 op1 = (insn >> 20) & 7;
9106 tmp = load_reg(s, rn);
9107 tmp2 = load_reg(s, rm);
9108 sh = (insn >> 5) & 7;
9109 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9110 goto illegal_op;
9111 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9112 tcg_temp_free_i32(tmp2);
9113 store_reg(s, rd, tmp);
9114 break;
9115 case 1:
9116 if ((insn & 0x00700020) == 0) {
9117 /* Halfword pack. */
9118 tmp = load_reg(s, rn);
9119 tmp2 = load_reg(s, rm);
9120 shift = (insn >> 7) & 0x1f;
9121 if (insn & (1 << 6)) {
9122 /* pkhtb */
9123 if (shift == 0)
9124 shift = 31;
9125 tcg_gen_sari_i32(tmp2, tmp2, shift);
9126 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9127 tcg_gen_ext16u_i32(tmp2, tmp2);
9128 } else {
9129 /* pkhbt */
9130 if (shift)
9131 tcg_gen_shli_i32(tmp2, tmp2, shift);
9132 tcg_gen_ext16u_i32(tmp, tmp);
9133 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9135 tcg_gen_or_i32(tmp, tmp, tmp2);
9136 tcg_temp_free_i32(tmp2);
9137 store_reg(s, rd, tmp);
9138 } else if ((insn & 0x00200020) == 0x00200000) {
9139 /* [us]sat */
9140 tmp = load_reg(s, rm);
9141 shift = (insn >> 7) & 0x1f;
9142 if (insn & (1 << 6)) {
9143 if (shift == 0)
9144 shift = 31;
9145 tcg_gen_sari_i32(tmp, tmp, shift);
9146 } else {
9147 tcg_gen_shli_i32(tmp, tmp, shift);
9149 sh = (insn >> 16) & 0x1f;
9150 tmp2 = tcg_const_i32(sh);
9151 if (insn & (1 << 22))
9152 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9153 else
9154 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9155 tcg_temp_free_i32(tmp2);
9156 store_reg(s, rd, tmp);
9157 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9158 /* [us]sat16 */
9159 tmp = load_reg(s, rm);
9160 sh = (insn >> 16) & 0x1f;
9161 tmp2 = tcg_const_i32(sh);
9162 if (insn & (1 << 22))
9163 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9164 else
9165 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9166 tcg_temp_free_i32(tmp2);
9167 store_reg(s, rd, tmp);
9168 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9169 /* Select bytes. */
9170 tmp = load_reg(s, rn);
9171 tmp2 = load_reg(s, rm);
9172 tmp3 = tcg_temp_new_i32();
9173 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9174 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9175 tcg_temp_free_i32(tmp3);
9176 tcg_temp_free_i32(tmp2);
9177 store_reg(s, rd, tmp);
9178 } else if ((insn & 0x000003e0) == 0x00000060) {
9179 tmp = load_reg(s, rm);
9180 shift = (insn >> 10) & 3;
9181 /* ??? In many cases it's not necessary to do a
9182 rotate, a shift is sufficient. */
9183 if (shift != 0)
9184 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9185 op1 = (insn >> 20) & 7;
9186 switch (op1) {
9187 case 0: gen_sxtb16(tmp); break;
9188 case 2: gen_sxtb(tmp); break;
9189 case 3: gen_sxth(tmp); break;
9190 case 4: gen_uxtb16(tmp); break;
9191 case 6: gen_uxtb(tmp); break;
9192 case 7: gen_uxth(tmp); break;
9193 default: goto illegal_op;
9195 if (rn != 15) {
9196 tmp2 = load_reg(s, rn);
9197 if ((op1 & 3) == 0) {
9198 gen_add16(tmp, tmp2);
9199 } else {
9200 tcg_gen_add_i32(tmp, tmp, tmp2);
9201 tcg_temp_free_i32(tmp2);
9204 store_reg(s, rd, tmp);
9205 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9206 /* rev */
9207 tmp = load_reg(s, rm);
9208 if (insn & (1 << 22)) {
9209 if (insn & (1 << 7)) {
9210 gen_revsh(tmp);
9211 } else {
9212 ARCH(6T2);
9213 gen_helper_rbit(tmp, tmp);
9215 } else {
9216 if (insn & (1 << 7))
9217 gen_rev16(tmp);
9218 else
9219 tcg_gen_bswap32_i32(tmp, tmp);
9221 store_reg(s, rd, tmp);
9222 } else {
9223 goto illegal_op;
9225 break;
9226 case 2: /* Multiplies (Type 3). */
9227 switch ((insn >> 20) & 0x7) {
9228 case 5:
9229 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9230 /* op2 not 00x or 11x : UNDEF */
9231 goto illegal_op;
9233 /* Signed multiply most significant [accumulate].
9234 (SMMUL, SMMLA, SMMLS) */
9235 tmp = load_reg(s, rm);
9236 tmp2 = load_reg(s, rs);
9237 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9239 if (rd != 15) {
9240 tmp = load_reg(s, rd);
9241 if (insn & (1 << 6)) {
9242 tmp64 = gen_subq_msw(tmp64, tmp);
9243 } else {
9244 tmp64 = gen_addq_msw(tmp64, tmp);
9247 if (insn & (1 << 5)) {
9248 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9250 tcg_gen_shri_i64(tmp64, tmp64, 32);
9251 tmp = tcg_temp_new_i32();
9252 tcg_gen_extrl_i64_i32(tmp, tmp64);
9253 tcg_temp_free_i64(tmp64);
9254 store_reg(s, rn, tmp);
9255 break;
9256 case 0:
9257 case 4:
9258 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9259 if (insn & (1 << 7)) {
9260 goto illegal_op;
9262 tmp = load_reg(s, rm);
9263 tmp2 = load_reg(s, rs);
9264 if (insn & (1 << 5))
9265 gen_swap_half(tmp2);
9266 gen_smul_dual(tmp, tmp2);
9267 if (insn & (1 << 22)) {
9268 /* smlald, smlsld */
9269 TCGv_i64 tmp64_2;
9271 tmp64 = tcg_temp_new_i64();
9272 tmp64_2 = tcg_temp_new_i64();
9273 tcg_gen_ext_i32_i64(tmp64, tmp);
9274 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9275 tcg_temp_free_i32(tmp);
9276 tcg_temp_free_i32(tmp2);
9277 if (insn & (1 << 6)) {
9278 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9279 } else {
9280 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9282 tcg_temp_free_i64(tmp64_2);
9283 gen_addq(s, tmp64, rd, rn);
9284 gen_storeq_reg(s, rd, rn, tmp64);
9285 tcg_temp_free_i64(tmp64);
9286 } else {
9287 /* smuad, smusd, smlad, smlsd */
9288 if (insn & (1 << 6)) {
9289 /* This subtraction cannot overflow. */
9290 tcg_gen_sub_i32(tmp, tmp, tmp2);
9291 } else {
9292 /* This addition cannot overflow 32 bits;
9293 * however it may overflow considered as a
9294 * signed operation, in which case we must set
9295 * the Q flag.
9297 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9299 tcg_temp_free_i32(tmp2);
9300 if (rd != 15)
9302 tmp2 = load_reg(s, rd);
9303 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9304 tcg_temp_free_i32(tmp2);
9306 store_reg(s, rn, tmp);
9308 break;
9309 case 1:
9310 case 3:
9311 /* SDIV, UDIV */
9312 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9313 goto illegal_op;
9315 if (((insn >> 5) & 7) || (rd != 15)) {
9316 goto illegal_op;
9318 tmp = load_reg(s, rm);
9319 tmp2 = load_reg(s, rs);
9320 if (insn & (1 << 21)) {
9321 gen_helper_udiv(tmp, tmp, tmp2);
9322 } else {
9323 gen_helper_sdiv(tmp, tmp, tmp2);
9325 tcg_temp_free_i32(tmp2);
9326 store_reg(s, rn, tmp);
9327 break;
9328 default:
9329 goto illegal_op;
9331 break;
9332 case 3:
9333 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9334 switch (op1) {
9335 case 0: /* Unsigned sum of absolute differences. */
9336 ARCH(6);
9337 tmp = load_reg(s, rm);
9338 tmp2 = load_reg(s, rs);
9339 gen_helper_usad8(tmp, tmp, tmp2);
9340 tcg_temp_free_i32(tmp2);
9341 if (rd != 15) {
9342 tmp2 = load_reg(s, rd);
9343 tcg_gen_add_i32(tmp, tmp, tmp2);
9344 tcg_temp_free_i32(tmp2);
9346 store_reg(s, rn, tmp);
9347 break;
9348 case 0x20: case 0x24: case 0x28: case 0x2c:
9349 /* Bitfield insert/clear. */
9350 ARCH(6T2);
9351 shift = (insn >> 7) & 0x1f;
9352 i = (insn >> 16) & 0x1f;
9353 if (i < shift) {
9354 /* UNPREDICTABLE; we choose to UNDEF */
9355 goto illegal_op;
9357 i = i + 1 - shift;
9358 if (rm == 15) {
9359 tmp = tcg_temp_new_i32();
9360 tcg_gen_movi_i32(tmp, 0);
9361 } else {
9362 tmp = load_reg(s, rm);
9364 if (i != 32) {
9365 tmp2 = load_reg(s, rd);
9366 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9367 tcg_temp_free_i32(tmp2);
9369 store_reg(s, rd, tmp);
9370 break;
9371 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9372 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9373 ARCH(6T2);
9374 tmp = load_reg(s, rm);
9375 shift = (insn >> 7) & 0x1f;
9376 i = ((insn >> 16) & 0x1f) + 1;
9377 if (shift + i > 32)
9378 goto illegal_op;
9379 if (i < 32) {
9380 if (op1 & 0x20) {
9381 tcg_gen_extract_i32(tmp, tmp, shift, i);
9382 } else {
9383 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9386 store_reg(s, rd, tmp);
9387 break;
9388 default:
9389 goto illegal_op;
9391 break;
9393 break;
9395 do_ldst:
9396 /* Check for undefined extension instructions
9397 * per the ARM Bible IE:
9398 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9400 sh = (0xf << 20) | (0xf << 4);
9401 if (op1 == 0x7 && ((insn & sh) == sh))
9403 goto illegal_op;
9405 /* load/store byte/word */
9406 rn = (insn >> 16) & 0xf;
9407 rd = (insn >> 12) & 0xf;
9408 tmp2 = load_reg(s, rn);
9409 if ((insn & 0x01200000) == 0x00200000) {
9410 /* ldrt/strt */
9411 i = get_a32_user_mem_index(s);
9412 } else {
9413 i = get_mem_index(s);
9415 if (insn & (1 << 24))
9416 gen_add_data_offset(s, insn, tmp2);
9417 if (insn & (1 << 20)) {
9418 /* load */
9419 tmp = tcg_temp_new_i32();
9420 if (insn & (1 << 22)) {
9421 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9422 } else {
9423 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9425 } else {
9426 /* store */
9427 tmp = load_reg(s, rd);
9428 if (insn & (1 << 22)) {
9429 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9430 } else {
9431 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9433 tcg_temp_free_i32(tmp);
9435 if (!(insn & (1 << 24))) {
9436 gen_add_data_offset(s, insn, tmp2);
9437 store_reg(s, rn, tmp2);
9438 } else if (insn & (1 << 21)) {
9439 store_reg(s, rn, tmp2);
9440 } else {
9441 tcg_temp_free_i32(tmp2);
9443 if (insn & (1 << 20)) {
9444 /* Complete the load. */
9445 store_reg_from_load(s, rd, tmp);
9447 break;
9448 case 0x08:
9449 case 0x09:
9451 int j, n, loaded_base;
9452 bool exc_return = false;
9453 bool is_load = extract32(insn, 20, 1);
9454 bool user = false;
9455 TCGv_i32 loaded_var;
9456 /* load/store multiple words */
9457 /* XXX: store correct base if write back */
9458 if (insn & (1 << 22)) {
9459 /* LDM (user), LDM (exception return) and STM (user) */
9460 if (IS_USER(s))
9461 goto illegal_op; /* only usable in supervisor mode */
9463 if (is_load && extract32(insn, 15, 1)) {
9464 exc_return = true;
9465 } else {
9466 user = true;
9469 rn = (insn >> 16) & 0xf;
9470 addr = load_reg(s, rn);
9472 /* compute total size */
9473 loaded_base = 0;
9474 TCGV_UNUSED_I32(loaded_var);
9475 n = 0;
9476 for(i=0;i<16;i++) {
9477 if (insn & (1 << i))
9478 n++;
9480 /* XXX: test invalid n == 0 case ? */
9481 if (insn & (1 << 23)) {
9482 if (insn & (1 << 24)) {
9483 /* pre increment */
9484 tcg_gen_addi_i32(addr, addr, 4);
9485 } else {
9486 /* post increment */
9488 } else {
9489 if (insn & (1 << 24)) {
9490 /* pre decrement */
9491 tcg_gen_addi_i32(addr, addr, -(n * 4));
9492 } else {
9493 /* post decrement */
9494 if (n != 1)
9495 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9498 j = 0;
9499 for(i=0;i<16;i++) {
9500 if (insn & (1 << i)) {
9501 if (is_load) {
9502 /* load */
9503 tmp = tcg_temp_new_i32();
9504 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9505 if (user) {
9506 tmp2 = tcg_const_i32(i);
9507 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9508 tcg_temp_free_i32(tmp2);
9509 tcg_temp_free_i32(tmp);
9510 } else if (i == rn) {
9511 loaded_var = tmp;
9512 loaded_base = 1;
9513 } else if (rn == 15 && exc_return) {
9514 store_pc_exc_ret(s, tmp);
9515 } else {
9516 store_reg_from_load(s, i, tmp);
9518 } else {
9519 /* store */
9520 if (i == 15) {
9521 /* special case: r15 = PC + 8 */
9522 val = (long)s->pc + 4;
9523 tmp = tcg_temp_new_i32();
9524 tcg_gen_movi_i32(tmp, val);
9525 } else if (user) {
9526 tmp = tcg_temp_new_i32();
9527 tmp2 = tcg_const_i32(i);
9528 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9529 tcg_temp_free_i32(tmp2);
9530 } else {
9531 tmp = load_reg(s, i);
9533 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9534 tcg_temp_free_i32(tmp);
9536 j++;
9537 /* no need to add after the last transfer */
9538 if (j != n)
9539 tcg_gen_addi_i32(addr, addr, 4);
9542 if (insn & (1 << 21)) {
9543 /* write back */
9544 if (insn & (1 << 23)) {
9545 if (insn & (1 << 24)) {
9546 /* pre increment */
9547 } else {
9548 /* post increment */
9549 tcg_gen_addi_i32(addr, addr, 4);
9551 } else {
9552 if (insn & (1 << 24)) {
9553 /* pre decrement */
9554 if (n != 1)
9555 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9556 } else {
9557 /* post decrement */
9558 tcg_gen_addi_i32(addr, addr, -(n * 4));
9561 store_reg(s, rn, addr);
9562 } else {
9563 tcg_temp_free_i32(addr);
9565 if (loaded_base) {
9566 store_reg(s, rn, loaded_var);
9568 if (exc_return) {
9569 /* Restore CPSR from SPSR. */
9570 tmp = load_cpu_field(spsr);
9571 gen_helper_cpsr_write_eret(cpu_env, tmp);
9572 tcg_temp_free_i32(tmp);
9573 /* Must exit loop to check un-masked IRQs */
9574 s->base.is_jmp = DISAS_EXIT;
9577 break;
9578 case 0xa:
9579 case 0xb:
9581 int32_t offset;
9583 /* branch (and link) */
9584 val = (int32_t)s->pc;
9585 if (insn & (1 << 24)) {
9586 tmp = tcg_temp_new_i32();
9587 tcg_gen_movi_i32(tmp, val);
9588 store_reg(s, 14, tmp);
9590 offset = sextract32(insn << 2, 0, 26);
9591 val += offset + 4;
9592 gen_jmp(s, val);
9594 break;
9595 case 0xc:
9596 case 0xd:
9597 case 0xe:
9598 if (((insn >> 8) & 0xe) == 10) {
9599 /* VFP. */
9600 if (disas_vfp_insn(s, insn)) {
9601 goto illegal_op;
9603 } else if (disas_coproc_insn(s, insn)) {
9604 /* Coprocessor. */
9605 goto illegal_op;
9607 break;
9608 case 0xf:
9609 /* swi */
9610 gen_set_pc_im(s, s->pc);
9611 s->svc_imm = extract32(insn, 0, 24);
9612 s->base.is_jmp = DISAS_SWI;
9613 break;
9614 default:
9615 illegal_op:
9616 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9617 default_exception_el(s));
9618 break;
9623 /* Return true if this is a Thumb-2 logical op. */
9624 static int
9625 thumb2_logic_op(int op)
9627 return (op < 8);
9630 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9631 then set condition code flags based on the result of the operation.
9632 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9633 to the high bit of T1.
9634 Returns zero if the opcode is valid. */
9636 static int
9637 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9638 TCGv_i32 t0, TCGv_i32 t1)
9640 int logic_cc;
9642 logic_cc = 0;
9643 switch (op) {
9644 case 0: /* and */
9645 tcg_gen_and_i32(t0, t0, t1);
9646 logic_cc = conds;
9647 break;
9648 case 1: /* bic */
9649 tcg_gen_andc_i32(t0, t0, t1);
9650 logic_cc = conds;
9651 break;
9652 case 2: /* orr */
9653 tcg_gen_or_i32(t0, t0, t1);
9654 logic_cc = conds;
9655 break;
9656 case 3: /* orn */
9657 tcg_gen_orc_i32(t0, t0, t1);
9658 logic_cc = conds;
9659 break;
9660 case 4: /* eor */
9661 tcg_gen_xor_i32(t0, t0, t1);
9662 logic_cc = conds;
9663 break;
9664 case 8: /* add */
9665 if (conds)
9666 gen_add_CC(t0, t0, t1);
9667 else
9668 tcg_gen_add_i32(t0, t0, t1);
9669 break;
9670 case 10: /* adc */
9671 if (conds)
9672 gen_adc_CC(t0, t0, t1);
9673 else
9674 gen_adc(t0, t1);
9675 break;
9676 case 11: /* sbc */
9677 if (conds) {
9678 gen_sbc_CC(t0, t0, t1);
9679 } else {
9680 gen_sub_carry(t0, t0, t1);
9682 break;
9683 case 13: /* sub */
9684 if (conds)
9685 gen_sub_CC(t0, t0, t1);
9686 else
9687 tcg_gen_sub_i32(t0, t0, t1);
9688 break;
9689 case 14: /* rsb */
9690 if (conds)
9691 gen_sub_CC(t0, t1, t0);
9692 else
9693 tcg_gen_sub_i32(t0, t1, t0);
9694 break;
9695 default: /* 5, 6, 7, 9, 12, 15. */
9696 return 1;
9698 if (logic_cc) {
9699 gen_logic_CC(t0);
9700 if (shifter_out)
9701 gen_set_CF_bit31(t1);
9703 return 0;
9706 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9707 is not legal. */
9708 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9710 uint32_t insn, imm, shift, offset;
9711 uint32_t rd, rn, rm, rs;
9712 TCGv_i32 tmp;
9713 TCGv_i32 tmp2;
9714 TCGv_i32 tmp3;
9715 TCGv_i32 addr;
9716 TCGv_i64 tmp64;
9717 int op;
9718 int shiftop;
9719 int conds;
9720 int logic_cc;
9722 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
9723 /* Thumb-1 cores may need to treat bl and blx as a pair of
9724 16-bit instructions to get correct prefetch abort behavior. */
9725 insn = insn_hw1;
9726 if ((insn & (1 << 12)) == 0) {
9727 ARCH(5);
9728 /* Second half of blx. */
9729 offset = ((insn & 0x7ff) << 1);
9730 tmp = load_reg(s, 14);
9731 tcg_gen_addi_i32(tmp, tmp, offset);
9732 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9734 tmp2 = tcg_temp_new_i32();
9735 tcg_gen_movi_i32(tmp2, s->pc | 1);
9736 store_reg(s, 14, tmp2);
9737 gen_bx(s, tmp);
9738 return 0;
9740 if (insn & (1 << 11)) {
9741 /* Second half of bl. */
9742 offset = ((insn & 0x7ff) << 1) | 1;
9743 tmp = load_reg(s, 14);
9744 tcg_gen_addi_i32(tmp, tmp, offset);
9746 tmp2 = tcg_temp_new_i32();
9747 tcg_gen_movi_i32(tmp2, s->pc | 1);
9748 store_reg(s, 14, tmp2);
9749 gen_bx(s, tmp);
9750 return 0;
9752 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9753 /* Instruction spans a page boundary. Implement it as two
9754 16-bit instructions in case the second half causes an
9755 prefetch abort. */
9756 offset = ((int32_t)insn << 21) >> 9;
9757 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9758 return 0;
9760 /* Fall through to 32-bit decode. */
9763 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9764 s->pc += 2;
9765 insn |= (uint32_t)insn_hw1 << 16;
9767 if ((insn & 0xf800e800) != 0xf000e800) {
9768 ARCH(6T2);
9771 rn = (insn >> 16) & 0xf;
9772 rs = (insn >> 12) & 0xf;
9773 rd = (insn >> 8) & 0xf;
9774 rm = insn & 0xf;
9775 switch ((insn >> 25) & 0xf) {
9776 case 0: case 1: case 2: case 3:
9777 /* 16-bit instructions. Should never happen. */
9778 abort();
9779 case 4:
9780 if (insn & (1 << 22)) {
9781 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9782 * - load/store doubleword, load/store exclusive, ldacq/strel,
9783 * table branch.
9785 if (insn & 0x01200000) {
9786 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9787 * - load/store dual (post-indexed)
9788 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9789 * - load/store dual (literal and immediate)
9790 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9791 * - load/store dual (pre-indexed)
9793 if (rn == 15) {
9794 if (insn & (1 << 21)) {
9795 /* UNPREDICTABLE */
9796 goto illegal_op;
9798 addr = tcg_temp_new_i32();
9799 tcg_gen_movi_i32(addr, s->pc & ~3);
9800 } else {
9801 addr = load_reg(s, rn);
9803 offset = (insn & 0xff) * 4;
9804 if ((insn & (1 << 23)) == 0)
9805 offset = -offset;
9806 if (insn & (1 << 24)) {
9807 tcg_gen_addi_i32(addr, addr, offset);
9808 offset = 0;
9810 if (insn & (1 << 20)) {
9811 /* ldrd */
9812 tmp = tcg_temp_new_i32();
9813 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9814 store_reg(s, rs, tmp);
9815 tcg_gen_addi_i32(addr, addr, 4);
9816 tmp = tcg_temp_new_i32();
9817 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9818 store_reg(s, rd, tmp);
9819 } else {
9820 /* strd */
9821 tmp = load_reg(s, rs);
9822 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9823 tcg_temp_free_i32(tmp);
9824 tcg_gen_addi_i32(addr, addr, 4);
9825 tmp = load_reg(s, rd);
9826 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9827 tcg_temp_free_i32(tmp);
9829 if (insn & (1 << 21)) {
9830 /* Base writeback. */
9831 tcg_gen_addi_i32(addr, addr, offset - 4);
9832 store_reg(s, rn, addr);
9833 } else {
9834 tcg_temp_free_i32(addr);
9836 } else if ((insn & (1 << 23)) == 0) {
9837 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9838 * - load/store exclusive word
9840 if (rs == 15) {
9841 goto illegal_op;
9843 addr = tcg_temp_local_new_i32();
9844 load_reg_var(s, addr, rn);
9845 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9846 if (insn & (1 << 20)) {
9847 gen_load_exclusive(s, rs, 15, addr, 2);
9848 } else {
9849 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9851 tcg_temp_free_i32(addr);
9852 } else if ((insn & (7 << 5)) == 0) {
9853 /* Table Branch. */
9854 if (rn == 15) {
9855 addr = tcg_temp_new_i32();
9856 tcg_gen_movi_i32(addr, s->pc);
9857 } else {
9858 addr = load_reg(s, rn);
9860 tmp = load_reg(s, rm);
9861 tcg_gen_add_i32(addr, addr, tmp);
9862 if (insn & (1 << 4)) {
9863 /* tbh */
9864 tcg_gen_add_i32(addr, addr, tmp);
9865 tcg_temp_free_i32(tmp);
9866 tmp = tcg_temp_new_i32();
9867 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9868 } else { /* tbb */
9869 tcg_temp_free_i32(tmp);
9870 tmp = tcg_temp_new_i32();
9871 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9873 tcg_temp_free_i32(addr);
9874 tcg_gen_shli_i32(tmp, tmp, 1);
9875 tcg_gen_addi_i32(tmp, tmp, s->pc);
9876 store_reg(s, 15, tmp);
9877 } else {
9878 int op2 = (insn >> 6) & 0x3;
9879 op = (insn >> 4) & 0x3;
9880 switch (op2) {
9881 case 0:
9882 goto illegal_op;
9883 case 1:
9884 /* Load/store exclusive byte/halfword/doubleword */
9885 if (op == 2) {
9886 goto illegal_op;
9888 ARCH(7);
9889 break;
9890 case 2:
9891 /* Load-acquire/store-release */
9892 if (op == 3) {
9893 goto illegal_op;
9895 /* Fall through */
9896 case 3:
9897 /* Load-acquire/store-release exclusive */
9898 ARCH(8);
9899 break;
9901 addr = tcg_temp_local_new_i32();
9902 load_reg_var(s, addr, rn);
9903 if (!(op2 & 1)) {
9904 if (insn & (1 << 20)) {
9905 tmp = tcg_temp_new_i32();
9906 switch (op) {
9907 case 0: /* ldab */
9908 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9909 rs | ISSIsAcqRel);
9910 break;
9911 case 1: /* ldah */
9912 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9913 rs | ISSIsAcqRel);
9914 break;
9915 case 2: /* lda */
9916 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9917 rs | ISSIsAcqRel);
9918 break;
9919 default:
9920 abort();
9922 store_reg(s, rs, tmp);
9923 } else {
9924 tmp = load_reg(s, rs);
9925 switch (op) {
9926 case 0: /* stlb */
9927 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9928 rs | ISSIsAcqRel);
9929 break;
9930 case 1: /* stlh */
9931 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9932 rs | ISSIsAcqRel);
9933 break;
9934 case 2: /* stl */
9935 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9936 rs | ISSIsAcqRel);
9937 break;
9938 default:
9939 abort();
9941 tcg_temp_free_i32(tmp);
9943 } else if (insn & (1 << 20)) {
9944 gen_load_exclusive(s, rs, rd, addr, op);
9945 } else {
9946 gen_store_exclusive(s, rm, rs, rd, addr, op);
9948 tcg_temp_free_i32(addr);
9950 } else {
9951 /* Load/store multiple, RFE, SRS. */
9952 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9953 /* RFE, SRS: not available in user mode or on M profile */
9954 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9955 goto illegal_op;
9957 if (insn & (1 << 20)) {
9958 /* rfe */
9959 addr = load_reg(s, rn);
9960 if ((insn & (1 << 24)) == 0)
9961 tcg_gen_addi_i32(addr, addr, -8);
9962 /* Load PC into tmp and CPSR into tmp2. */
9963 tmp = tcg_temp_new_i32();
9964 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9965 tcg_gen_addi_i32(addr, addr, 4);
9966 tmp2 = tcg_temp_new_i32();
9967 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9968 if (insn & (1 << 21)) {
9969 /* Base writeback. */
9970 if (insn & (1 << 24)) {
9971 tcg_gen_addi_i32(addr, addr, 4);
9972 } else {
9973 tcg_gen_addi_i32(addr, addr, -4);
9975 store_reg(s, rn, addr);
9976 } else {
9977 tcg_temp_free_i32(addr);
9979 gen_rfe(s, tmp, tmp2);
9980 } else {
9981 /* srs */
9982 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9983 insn & (1 << 21));
9985 } else {
9986 int i, loaded_base = 0;
9987 TCGv_i32 loaded_var;
9988 /* Load/store multiple. */
9989 addr = load_reg(s, rn);
9990 offset = 0;
9991 for (i = 0; i < 16; i++) {
9992 if (insn & (1 << i))
9993 offset += 4;
9995 if (insn & (1 << 24)) {
9996 tcg_gen_addi_i32(addr, addr, -offset);
9999 TCGV_UNUSED_I32(loaded_var);
10000 for (i = 0; i < 16; i++) {
10001 if ((insn & (1 << i)) == 0)
10002 continue;
10003 if (insn & (1 << 20)) {
10004 /* Load. */
10005 tmp = tcg_temp_new_i32();
10006 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10007 if (i == 15) {
10008 gen_bx_excret(s, tmp);
10009 } else if (i == rn) {
10010 loaded_var = tmp;
10011 loaded_base = 1;
10012 } else {
10013 store_reg(s, i, tmp);
10015 } else {
10016 /* Store. */
10017 tmp = load_reg(s, i);
10018 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10019 tcg_temp_free_i32(tmp);
10021 tcg_gen_addi_i32(addr, addr, 4);
10023 if (loaded_base) {
10024 store_reg(s, rn, loaded_var);
10026 if (insn & (1 << 21)) {
10027 /* Base register writeback. */
10028 if (insn & (1 << 24)) {
10029 tcg_gen_addi_i32(addr, addr, -offset);
10031 /* Fault if writeback register is in register list. */
10032 if (insn & (1 << rn))
10033 goto illegal_op;
10034 store_reg(s, rn, addr);
10035 } else {
10036 tcg_temp_free_i32(addr);
10040 break;
10041 case 5:
10043 op = (insn >> 21) & 0xf;
10044 if (op == 6) {
10045 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10046 goto illegal_op;
10048 /* Halfword pack. */
10049 tmp = load_reg(s, rn);
10050 tmp2 = load_reg(s, rm);
10051 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10052 if (insn & (1 << 5)) {
10053 /* pkhtb */
10054 if (shift == 0)
10055 shift = 31;
10056 tcg_gen_sari_i32(tmp2, tmp2, shift);
10057 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10058 tcg_gen_ext16u_i32(tmp2, tmp2);
10059 } else {
10060 /* pkhbt */
10061 if (shift)
10062 tcg_gen_shli_i32(tmp2, tmp2, shift);
10063 tcg_gen_ext16u_i32(tmp, tmp);
10064 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10066 tcg_gen_or_i32(tmp, tmp, tmp2);
10067 tcg_temp_free_i32(tmp2);
10068 store_reg(s, rd, tmp);
10069 } else {
10070 /* Data processing register constant shift. */
10071 if (rn == 15) {
10072 tmp = tcg_temp_new_i32();
10073 tcg_gen_movi_i32(tmp, 0);
10074 } else {
10075 tmp = load_reg(s, rn);
10077 tmp2 = load_reg(s, rm);
10079 shiftop = (insn >> 4) & 3;
10080 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10081 conds = (insn & (1 << 20)) != 0;
10082 logic_cc = (conds && thumb2_logic_op(op));
10083 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10084 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10085 goto illegal_op;
10086 tcg_temp_free_i32(tmp2);
10087 if (rd != 15) {
10088 store_reg(s, rd, tmp);
10089 } else {
10090 tcg_temp_free_i32(tmp);
10093 break;
10094 case 13: /* Misc data processing. */
10095 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10096 if (op < 4 && (insn & 0xf000) != 0xf000)
10097 goto illegal_op;
10098 switch (op) {
10099 case 0: /* Register controlled shift. */
10100 tmp = load_reg(s, rn);
10101 tmp2 = load_reg(s, rm);
10102 if ((insn & 0x70) != 0)
10103 goto illegal_op;
10104 op = (insn >> 21) & 3;
10105 logic_cc = (insn & (1 << 20)) != 0;
10106 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10107 if (logic_cc)
10108 gen_logic_CC(tmp);
10109 store_reg(s, rd, tmp);
10110 break;
10111 case 1: /* Sign/zero extend. */
10112 op = (insn >> 20) & 7;
10113 switch (op) {
10114 case 0: /* SXTAH, SXTH */
10115 case 1: /* UXTAH, UXTH */
10116 case 4: /* SXTAB, SXTB */
10117 case 5: /* UXTAB, UXTB */
10118 break;
10119 case 2: /* SXTAB16, SXTB16 */
10120 case 3: /* UXTAB16, UXTB16 */
10121 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10122 goto illegal_op;
10124 break;
10125 default:
10126 goto illegal_op;
10128 if (rn != 15) {
10129 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10130 goto illegal_op;
10133 tmp = load_reg(s, rm);
10134 shift = (insn >> 4) & 3;
10135 /* ??? In many cases it's not necessary to do a
10136 rotate, a shift is sufficient. */
10137 if (shift != 0)
10138 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10139 op = (insn >> 20) & 7;
10140 switch (op) {
10141 case 0: gen_sxth(tmp); break;
10142 case 1: gen_uxth(tmp); break;
10143 case 2: gen_sxtb16(tmp); break;
10144 case 3: gen_uxtb16(tmp); break;
10145 case 4: gen_sxtb(tmp); break;
10146 case 5: gen_uxtb(tmp); break;
10147 default:
10148 g_assert_not_reached();
10150 if (rn != 15) {
10151 tmp2 = load_reg(s, rn);
10152 if ((op >> 1) == 1) {
10153 gen_add16(tmp, tmp2);
10154 } else {
10155 tcg_gen_add_i32(tmp, tmp, tmp2);
10156 tcg_temp_free_i32(tmp2);
10159 store_reg(s, rd, tmp);
10160 break;
10161 case 2: /* SIMD add/subtract. */
10162 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10163 goto illegal_op;
10165 op = (insn >> 20) & 7;
10166 shift = (insn >> 4) & 7;
10167 if ((op & 3) == 3 || (shift & 3) == 3)
10168 goto illegal_op;
10169 tmp = load_reg(s, rn);
10170 tmp2 = load_reg(s, rm);
10171 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10172 tcg_temp_free_i32(tmp2);
10173 store_reg(s, rd, tmp);
10174 break;
10175 case 3: /* Other data processing. */
10176 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10177 if (op < 4) {
10178 /* Saturating add/subtract. */
10179 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10180 goto illegal_op;
10182 tmp = load_reg(s, rn);
10183 tmp2 = load_reg(s, rm);
10184 if (op & 1)
10185 gen_helper_double_saturate(tmp, cpu_env, tmp);
10186 if (op & 2)
10187 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10188 else
10189 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10190 tcg_temp_free_i32(tmp2);
10191 } else {
10192 switch (op) {
10193 case 0x0a: /* rbit */
10194 case 0x08: /* rev */
10195 case 0x09: /* rev16 */
10196 case 0x0b: /* revsh */
10197 case 0x18: /* clz */
10198 break;
10199 case 0x10: /* sel */
10200 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10201 goto illegal_op;
10203 break;
10204 case 0x20: /* crc32/crc32c */
10205 case 0x21:
10206 case 0x22:
10207 case 0x28:
10208 case 0x29:
10209 case 0x2a:
10210 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10211 goto illegal_op;
10213 break;
10214 default:
10215 goto illegal_op;
10217 tmp = load_reg(s, rn);
10218 switch (op) {
10219 case 0x0a: /* rbit */
10220 gen_helper_rbit(tmp, tmp);
10221 break;
10222 case 0x08: /* rev */
10223 tcg_gen_bswap32_i32(tmp, tmp);
10224 break;
10225 case 0x09: /* rev16 */
10226 gen_rev16(tmp);
10227 break;
10228 case 0x0b: /* revsh */
10229 gen_revsh(tmp);
10230 break;
10231 case 0x10: /* sel */
10232 tmp2 = load_reg(s, rm);
10233 tmp3 = tcg_temp_new_i32();
10234 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10235 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10236 tcg_temp_free_i32(tmp3);
10237 tcg_temp_free_i32(tmp2);
10238 break;
10239 case 0x18: /* clz */
10240 tcg_gen_clzi_i32(tmp, tmp, 32);
10241 break;
10242 case 0x20:
10243 case 0x21:
10244 case 0x22:
10245 case 0x28:
10246 case 0x29:
10247 case 0x2a:
10249 /* crc32/crc32c */
10250 uint32_t sz = op & 0x3;
10251 uint32_t c = op & 0x8;
10253 tmp2 = load_reg(s, rm);
10254 if (sz == 0) {
10255 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10256 } else if (sz == 1) {
10257 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10259 tmp3 = tcg_const_i32(1 << sz);
10260 if (c) {
10261 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10262 } else {
10263 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10265 tcg_temp_free_i32(tmp2);
10266 tcg_temp_free_i32(tmp3);
10267 break;
10269 default:
10270 g_assert_not_reached();
10273 store_reg(s, rd, tmp);
10274 break;
10275 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10276 switch ((insn >> 20) & 7) {
10277 case 0: /* 32 x 32 -> 32 */
10278 case 7: /* Unsigned sum of absolute differences. */
10279 break;
10280 case 1: /* 16 x 16 -> 32 */
10281 case 2: /* Dual multiply add. */
10282 case 3: /* 32 * 16 -> 32msb */
10283 case 4: /* Dual multiply subtract. */
10284 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10285 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10286 goto illegal_op;
10288 break;
10290 op = (insn >> 4) & 0xf;
10291 tmp = load_reg(s, rn);
10292 tmp2 = load_reg(s, rm);
10293 switch ((insn >> 20) & 7) {
10294 case 0: /* 32 x 32 -> 32 */
10295 tcg_gen_mul_i32(tmp, tmp, tmp2);
10296 tcg_temp_free_i32(tmp2);
10297 if (rs != 15) {
10298 tmp2 = load_reg(s, rs);
10299 if (op)
10300 tcg_gen_sub_i32(tmp, tmp2, tmp);
10301 else
10302 tcg_gen_add_i32(tmp, tmp, tmp2);
10303 tcg_temp_free_i32(tmp2);
10305 break;
10306 case 1: /* 16 x 16 -> 32 */
10307 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10308 tcg_temp_free_i32(tmp2);
10309 if (rs != 15) {
10310 tmp2 = load_reg(s, rs);
10311 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10312 tcg_temp_free_i32(tmp2);
10314 break;
10315 case 2: /* Dual multiply add. */
10316 case 4: /* Dual multiply subtract. */
10317 if (op)
10318 gen_swap_half(tmp2);
10319 gen_smul_dual(tmp, tmp2);
10320 if (insn & (1 << 22)) {
10321 /* This subtraction cannot overflow. */
10322 tcg_gen_sub_i32(tmp, tmp, tmp2);
10323 } else {
10324 /* This addition cannot overflow 32 bits;
10325 * however it may overflow considered as a signed
10326 * operation, in which case we must set the Q flag.
10328 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10330 tcg_temp_free_i32(tmp2);
10331 if (rs != 15)
10333 tmp2 = load_reg(s, rs);
10334 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10335 tcg_temp_free_i32(tmp2);
10337 break;
10338 case 3: /* 32 * 16 -> 32msb */
10339 if (op)
10340 tcg_gen_sari_i32(tmp2, tmp2, 16);
10341 else
10342 gen_sxth(tmp2);
10343 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10344 tcg_gen_shri_i64(tmp64, tmp64, 16);
10345 tmp = tcg_temp_new_i32();
10346 tcg_gen_extrl_i64_i32(tmp, tmp64);
10347 tcg_temp_free_i64(tmp64);
10348 if (rs != 15)
10350 tmp2 = load_reg(s, rs);
10351 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10352 tcg_temp_free_i32(tmp2);
10354 break;
10355 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10356 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10357 if (rs != 15) {
10358 tmp = load_reg(s, rs);
10359 if (insn & (1 << 20)) {
10360 tmp64 = gen_addq_msw(tmp64, tmp);
10361 } else {
10362 tmp64 = gen_subq_msw(tmp64, tmp);
10365 if (insn & (1 << 4)) {
10366 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10368 tcg_gen_shri_i64(tmp64, tmp64, 32);
10369 tmp = tcg_temp_new_i32();
10370 tcg_gen_extrl_i64_i32(tmp, tmp64);
10371 tcg_temp_free_i64(tmp64);
10372 break;
10373 case 7: /* Unsigned sum of absolute differences. */
10374 gen_helper_usad8(tmp, tmp, tmp2);
10375 tcg_temp_free_i32(tmp2);
10376 if (rs != 15) {
10377 tmp2 = load_reg(s, rs);
10378 tcg_gen_add_i32(tmp, tmp, tmp2);
10379 tcg_temp_free_i32(tmp2);
10381 break;
10383 store_reg(s, rd, tmp);
10384 break;
10385 case 6: case 7: /* 64-bit multiply, Divide. */
10386 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10387 tmp = load_reg(s, rn);
10388 tmp2 = load_reg(s, rm);
10389 if ((op & 0x50) == 0x10) {
10390 /* sdiv, udiv */
10391 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10392 goto illegal_op;
10394 if (op & 0x20)
10395 gen_helper_udiv(tmp, tmp, tmp2);
10396 else
10397 gen_helper_sdiv(tmp, tmp, tmp2);
10398 tcg_temp_free_i32(tmp2);
10399 store_reg(s, rd, tmp);
10400 } else if ((op & 0xe) == 0xc) {
10401 /* Dual multiply accumulate long. */
10402 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10403 tcg_temp_free_i32(tmp);
10404 tcg_temp_free_i32(tmp2);
10405 goto illegal_op;
10407 if (op & 1)
10408 gen_swap_half(tmp2);
10409 gen_smul_dual(tmp, tmp2);
10410 if (op & 0x10) {
10411 tcg_gen_sub_i32(tmp, tmp, tmp2);
10412 } else {
10413 tcg_gen_add_i32(tmp, tmp, tmp2);
10415 tcg_temp_free_i32(tmp2);
10416 /* BUGFIX */
10417 tmp64 = tcg_temp_new_i64();
10418 tcg_gen_ext_i32_i64(tmp64, tmp);
10419 tcg_temp_free_i32(tmp);
10420 gen_addq(s, tmp64, rs, rd);
10421 gen_storeq_reg(s, rs, rd, tmp64);
10422 tcg_temp_free_i64(tmp64);
10423 } else {
10424 if (op & 0x20) {
10425 /* Unsigned 64-bit multiply */
10426 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10427 } else {
10428 if (op & 8) {
10429 /* smlalxy */
10430 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10431 tcg_temp_free_i32(tmp2);
10432 tcg_temp_free_i32(tmp);
10433 goto illegal_op;
10435 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10436 tcg_temp_free_i32(tmp2);
10437 tmp64 = tcg_temp_new_i64();
10438 tcg_gen_ext_i32_i64(tmp64, tmp);
10439 tcg_temp_free_i32(tmp);
10440 } else {
10441 /* Signed 64-bit multiply */
10442 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10445 if (op & 4) {
10446 /* umaal */
10447 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10448 tcg_temp_free_i64(tmp64);
10449 goto illegal_op;
10451 gen_addq_lo(s, tmp64, rs);
10452 gen_addq_lo(s, tmp64, rd);
10453 } else if (op & 0x40) {
10454 /* 64-bit accumulate. */
10455 gen_addq(s, tmp64, rs, rd);
10457 gen_storeq_reg(s, rs, rd, tmp64);
10458 tcg_temp_free_i64(tmp64);
10460 break;
10462 break;
10463 case 6: case 7: case 14: case 15:
10464 /* Coprocessor. */
10465 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10466 /* We don't currently implement M profile FP support,
10467 * so this entire space should give a NOCP fault.
10469 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10470 default_exception_el(s));
10471 break;
10473 if (((insn >> 24) & 3) == 3) {
10474 /* Translate into the equivalent ARM encoding. */
10475 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10476 if (disas_neon_data_insn(s, insn)) {
10477 goto illegal_op;
10479 } else if (((insn >> 8) & 0xe) == 10) {
10480 if (disas_vfp_insn(s, insn)) {
10481 goto illegal_op;
10483 } else {
10484 if (insn & (1 << 28))
10485 goto illegal_op;
10486 if (disas_coproc_insn(s, insn)) {
10487 goto illegal_op;
10490 break;
10491 case 8: case 9: case 10: case 11:
10492 if (insn & (1 << 15)) {
10493 /* Branches, misc control. */
10494 if (insn & 0x5000) {
10495 /* Unconditional branch. */
10496 /* signextend(hw1[10:0]) -> offset[:12]. */
10497 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10498 /* hw1[10:0] -> offset[11:1]. */
10499 offset |= (insn & 0x7ff) << 1;
10500 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10501 offset[24:22] already have the same value because of the
10502 sign extension above. */
10503 offset ^= ((~insn) & (1 << 13)) << 10;
10504 offset ^= ((~insn) & (1 << 11)) << 11;
10506 if (insn & (1 << 14)) {
10507 /* Branch and link. */
10508 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10511 offset += s->pc;
10512 if (insn & (1 << 12)) {
10513 /* b/bl */
10514 gen_jmp(s, offset);
10515 } else {
10516 /* blx */
10517 offset &= ~(uint32_t)2;
10518 /* thumb2 bx, no need to check */
10519 gen_bx_im(s, offset);
10521 } else if (((insn >> 23) & 7) == 7) {
10522 /* Misc control */
10523 if (insn & (1 << 13))
10524 goto illegal_op;
10526 if (insn & (1 << 26)) {
10527 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10528 goto illegal_op;
10530 if (!(insn & (1 << 20))) {
10531 /* Hypervisor call (v7) */
10532 int imm16 = extract32(insn, 16, 4) << 12
10533 | extract32(insn, 0, 12);
10534 ARCH(7);
10535 if (IS_USER(s)) {
10536 goto illegal_op;
10538 gen_hvc(s, imm16);
10539 } else {
10540 /* Secure monitor call (v6+) */
10541 ARCH(6K);
10542 if (IS_USER(s)) {
10543 goto illegal_op;
10545 gen_smc(s);
10547 } else {
10548 op = (insn >> 20) & 7;
10549 switch (op) {
10550 case 0: /* msr cpsr. */
10551 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10552 tmp = load_reg(s, rn);
10553 /* the constant is the mask and SYSm fields */
10554 addr = tcg_const_i32(insn & 0xfff);
10555 gen_helper_v7m_msr(cpu_env, addr, tmp);
10556 tcg_temp_free_i32(addr);
10557 tcg_temp_free_i32(tmp);
10558 gen_lookup_tb(s);
10559 break;
10561 /* fall through */
10562 case 1: /* msr spsr. */
10563 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10564 goto illegal_op;
10567 if (extract32(insn, 5, 1)) {
10568 /* MSR (banked) */
10569 int sysm = extract32(insn, 8, 4) |
10570 (extract32(insn, 4, 1) << 4);
10571 int r = op & 1;
10573 gen_msr_banked(s, r, sysm, rm);
10574 break;
10577 /* MSR (for PSRs) */
10578 tmp = load_reg(s, rn);
10579 if (gen_set_psr(s,
10580 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10581 op == 1, tmp))
10582 goto illegal_op;
10583 break;
10584 case 2: /* cps, nop-hint. */
10585 if (((insn >> 8) & 7) == 0) {
10586 gen_nop_hint(s, insn & 0xff);
10588 /* Implemented as NOP in user mode. */
10589 if (IS_USER(s))
10590 break;
10591 offset = 0;
10592 imm = 0;
10593 if (insn & (1 << 10)) {
10594 if (insn & (1 << 7))
10595 offset |= CPSR_A;
10596 if (insn & (1 << 6))
10597 offset |= CPSR_I;
10598 if (insn & (1 << 5))
10599 offset |= CPSR_F;
10600 if (insn & (1 << 9))
10601 imm = CPSR_A | CPSR_I | CPSR_F;
10603 if (insn & (1 << 8)) {
10604 offset |= 0x1f;
10605 imm |= (insn & 0x1f);
10607 if (offset) {
10608 gen_set_psr_im(s, offset, 0, imm);
10610 break;
10611 case 3: /* Special control operations. */
10612 ARCH(7);
10613 op = (insn >> 4) & 0xf;
10614 switch (op) {
10615 case 2: /* clrex */
10616 gen_clrex(s);
10617 break;
10618 case 4: /* dsb */
10619 case 5: /* dmb */
10620 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10621 break;
10622 case 6: /* isb */
10623 /* We need to break the TB after this insn
10624 * to execute self-modifying code correctly
10625 * and also to take any pending interrupts
10626 * immediately.
10628 gen_goto_tb(s, 0, s->pc & ~1);
10629 break;
10630 default:
10631 goto illegal_op;
10633 break;
10634 case 4: /* bxj */
10635 /* Trivial implementation equivalent to bx.
10636 * This instruction doesn't exist at all for M-profile.
10638 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10639 goto illegal_op;
10641 tmp = load_reg(s, rn);
10642 gen_bx(s, tmp);
10643 break;
10644 case 5: /* Exception return. */
10645 if (IS_USER(s)) {
10646 goto illegal_op;
10648 if (rn != 14 || rd != 15) {
10649 goto illegal_op;
10651 tmp = load_reg(s, rn);
10652 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10653 gen_exception_return(s, tmp);
10654 break;
10655 case 6: /* MRS */
10656 if (extract32(insn, 5, 1) &&
10657 !arm_dc_feature(s, ARM_FEATURE_M)) {
10658 /* MRS (banked) */
10659 int sysm = extract32(insn, 16, 4) |
10660 (extract32(insn, 4, 1) << 4);
10662 gen_mrs_banked(s, 0, sysm, rd);
10663 break;
10666 if (extract32(insn, 16, 4) != 0xf) {
10667 goto illegal_op;
10669 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10670 extract32(insn, 0, 8) != 0) {
10671 goto illegal_op;
10674 /* mrs cpsr */
10675 tmp = tcg_temp_new_i32();
10676 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10677 addr = tcg_const_i32(insn & 0xff);
10678 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10679 tcg_temp_free_i32(addr);
10680 } else {
10681 gen_helper_cpsr_read(tmp, cpu_env);
10683 store_reg(s, rd, tmp);
10684 break;
10685 case 7: /* MRS */
10686 if (extract32(insn, 5, 1) &&
10687 !arm_dc_feature(s, ARM_FEATURE_M)) {
10688 /* MRS (banked) */
10689 int sysm = extract32(insn, 16, 4) |
10690 (extract32(insn, 4, 1) << 4);
10692 gen_mrs_banked(s, 1, sysm, rd);
10693 break;
10696 /* mrs spsr. */
10697 /* Not accessible in user mode. */
10698 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10699 goto illegal_op;
10702 if (extract32(insn, 16, 4) != 0xf ||
10703 extract32(insn, 0, 8) != 0) {
10704 goto illegal_op;
10707 tmp = load_cpu_field(spsr);
10708 store_reg(s, rd, tmp);
10709 break;
10712 } else {
10713 /* Conditional branch. */
10714 op = (insn >> 22) & 0xf;
10715 /* Generate a conditional jump to next instruction. */
10716 s->condlabel = gen_new_label();
10717 arm_gen_test_cc(op ^ 1, s->condlabel);
10718 s->condjmp = 1;
10720 /* offset[11:1] = insn[10:0] */
10721 offset = (insn & 0x7ff) << 1;
10722 /* offset[17:12] = insn[21:16]. */
10723 offset |= (insn & 0x003f0000) >> 4;
10724 /* offset[31:20] = insn[26]. */
10725 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10726 /* offset[18] = insn[13]. */
10727 offset |= (insn & (1 << 13)) << 5;
10728 /* offset[19] = insn[11]. */
10729 offset |= (insn & (1 << 11)) << 8;
10731 /* jump to the offset */
10732 gen_jmp(s, s->pc + offset);
10734 } else {
10735 /* Data processing immediate. */
10736 if (insn & (1 << 25)) {
10737 if (insn & (1 << 24)) {
10738 if (insn & (1 << 20))
10739 goto illegal_op;
10740 /* Bitfield/Saturate. */
10741 op = (insn >> 21) & 7;
10742 imm = insn & 0x1f;
10743 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10744 if (rn == 15) {
10745 tmp = tcg_temp_new_i32();
10746 tcg_gen_movi_i32(tmp, 0);
10747 } else {
10748 tmp = load_reg(s, rn);
10750 switch (op) {
10751 case 2: /* Signed bitfield extract. */
10752 imm++;
10753 if (shift + imm > 32)
10754 goto illegal_op;
10755 if (imm < 32) {
10756 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10758 break;
10759 case 6: /* Unsigned bitfield extract. */
10760 imm++;
10761 if (shift + imm > 32)
10762 goto illegal_op;
10763 if (imm < 32) {
10764 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10766 break;
10767 case 3: /* Bitfield insert/clear. */
10768 if (imm < shift)
10769 goto illegal_op;
10770 imm = imm + 1 - shift;
10771 if (imm != 32) {
10772 tmp2 = load_reg(s, rd);
10773 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10774 tcg_temp_free_i32(tmp2);
10776 break;
10777 case 7:
10778 goto illegal_op;
10779 default: /* Saturate. */
10780 if (shift) {
10781 if (op & 1)
10782 tcg_gen_sari_i32(tmp, tmp, shift);
10783 else
10784 tcg_gen_shli_i32(tmp, tmp, shift);
10786 tmp2 = tcg_const_i32(imm);
10787 if (op & 4) {
10788 /* Unsigned. */
10789 if ((op & 1) && shift == 0) {
10790 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10791 tcg_temp_free_i32(tmp);
10792 tcg_temp_free_i32(tmp2);
10793 goto illegal_op;
10795 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10796 } else {
10797 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10799 } else {
10800 /* Signed. */
10801 if ((op & 1) && shift == 0) {
10802 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10803 tcg_temp_free_i32(tmp);
10804 tcg_temp_free_i32(tmp2);
10805 goto illegal_op;
10807 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10808 } else {
10809 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10812 tcg_temp_free_i32(tmp2);
10813 break;
10815 store_reg(s, rd, tmp);
10816 } else {
10817 imm = ((insn & 0x04000000) >> 15)
10818 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10819 if (insn & (1 << 22)) {
10820 /* 16-bit immediate. */
10821 imm |= (insn >> 4) & 0xf000;
10822 if (insn & (1 << 23)) {
10823 /* movt */
10824 tmp = load_reg(s, rd);
10825 tcg_gen_ext16u_i32(tmp, tmp);
10826 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10827 } else {
10828 /* movw */
10829 tmp = tcg_temp_new_i32();
10830 tcg_gen_movi_i32(tmp, imm);
10832 } else {
10833 /* Add/sub 12-bit immediate. */
10834 if (rn == 15) {
10835 offset = s->pc & ~(uint32_t)3;
10836 if (insn & (1 << 23))
10837 offset -= imm;
10838 else
10839 offset += imm;
10840 tmp = tcg_temp_new_i32();
10841 tcg_gen_movi_i32(tmp, offset);
10842 } else {
10843 tmp = load_reg(s, rn);
10844 if (insn & (1 << 23))
10845 tcg_gen_subi_i32(tmp, tmp, imm);
10846 else
10847 tcg_gen_addi_i32(tmp, tmp, imm);
10850 store_reg(s, rd, tmp);
10852 } else {
10853 int shifter_out = 0;
10854 /* modified 12-bit immediate. */
10855 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10856 imm = (insn & 0xff);
10857 switch (shift) {
10858 case 0: /* XY */
10859 /* Nothing to do. */
10860 break;
10861 case 1: /* 00XY00XY */
10862 imm |= imm << 16;
10863 break;
10864 case 2: /* XY00XY00 */
10865 imm |= imm << 16;
10866 imm <<= 8;
10867 break;
10868 case 3: /* XYXYXYXY */
10869 imm |= imm << 16;
10870 imm |= imm << 8;
10871 break;
10872 default: /* Rotated constant. */
10873 shift = (shift << 1) | (imm >> 7);
10874 imm |= 0x80;
10875 imm = imm << (32 - shift);
10876 shifter_out = 1;
10877 break;
10879 tmp2 = tcg_temp_new_i32();
10880 tcg_gen_movi_i32(tmp2, imm);
10881 rn = (insn >> 16) & 0xf;
10882 if (rn == 15) {
10883 tmp = tcg_temp_new_i32();
10884 tcg_gen_movi_i32(tmp, 0);
10885 } else {
10886 tmp = load_reg(s, rn);
10888 op = (insn >> 21) & 0xf;
10889 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10890 shifter_out, tmp, tmp2))
10891 goto illegal_op;
10892 tcg_temp_free_i32(tmp2);
10893 rd = (insn >> 8) & 0xf;
10894 if (rd != 15) {
10895 store_reg(s, rd, tmp);
10896 } else {
10897 tcg_temp_free_i32(tmp);
10901 break;
10902 case 12: /* Load/store single data item. */
10904 int postinc = 0;
10905 int writeback = 0;
10906 int memidx;
10907 ISSInfo issinfo;
10909 if ((insn & 0x01100000) == 0x01000000) {
10910 if (disas_neon_ls_insn(s, insn)) {
10911 goto illegal_op;
10913 break;
10915 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10916 if (rs == 15) {
10917 if (!(insn & (1 << 20))) {
10918 goto illegal_op;
10920 if (op != 2) {
10921 /* Byte or halfword load space with dest == r15 : memory hints.
10922 * Catch them early so we don't emit pointless addressing code.
10923 * This space is a mix of:
10924 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10925 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10926 * cores)
10927 * unallocated hints, which must be treated as NOPs
10928 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10929 * which is easiest for the decoding logic
10930 * Some space which must UNDEF
10932 int op1 = (insn >> 23) & 3;
10933 int op2 = (insn >> 6) & 0x3f;
10934 if (op & 2) {
10935 goto illegal_op;
10937 if (rn == 15) {
10938 /* UNPREDICTABLE, unallocated hint or
10939 * PLD/PLDW/PLI (literal)
10941 return 0;
10943 if (op1 & 1) {
10944 return 0; /* PLD/PLDW/PLI or unallocated hint */
10946 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10947 return 0; /* PLD/PLDW/PLI or unallocated hint */
10949 /* UNDEF space, or an UNPREDICTABLE */
10950 return 1;
10953 memidx = get_mem_index(s);
10954 if (rn == 15) {
10955 addr = tcg_temp_new_i32();
10956 /* PC relative. */
10957 /* s->pc has already been incremented by 4. */
10958 imm = s->pc & 0xfffffffc;
10959 if (insn & (1 << 23))
10960 imm += insn & 0xfff;
10961 else
10962 imm -= insn & 0xfff;
10963 tcg_gen_movi_i32(addr, imm);
10964 } else {
10965 addr = load_reg(s, rn);
10966 if (insn & (1 << 23)) {
10967 /* Positive offset. */
10968 imm = insn & 0xfff;
10969 tcg_gen_addi_i32(addr, addr, imm);
10970 } else {
10971 imm = insn & 0xff;
10972 switch ((insn >> 8) & 0xf) {
10973 case 0x0: /* Shifted Register. */
10974 shift = (insn >> 4) & 0xf;
10975 if (shift > 3) {
10976 tcg_temp_free_i32(addr);
10977 goto illegal_op;
10979 tmp = load_reg(s, rm);
10980 if (shift)
10981 tcg_gen_shli_i32(tmp, tmp, shift);
10982 tcg_gen_add_i32(addr, addr, tmp);
10983 tcg_temp_free_i32(tmp);
10984 break;
10985 case 0xc: /* Negative offset. */
10986 tcg_gen_addi_i32(addr, addr, -imm);
10987 break;
10988 case 0xe: /* User privilege. */
10989 tcg_gen_addi_i32(addr, addr, imm);
10990 memidx = get_a32_user_mem_index(s);
10991 break;
10992 case 0x9: /* Post-decrement. */
10993 imm = -imm;
10994 /* Fall through. */
10995 case 0xb: /* Post-increment. */
10996 postinc = 1;
10997 writeback = 1;
10998 break;
10999 case 0xd: /* Pre-decrement. */
11000 imm = -imm;
11001 /* Fall through. */
11002 case 0xf: /* Pre-increment. */
11003 tcg_gen_addi_i32(addr, addr, imm);
11004 writeback = 1;
11005 break;
11006 default:
11007 tcg_temp_free_i32(addr);
11008 goto illegal_op;
11013 issinfo = writeback ? ISSInvalid : rs;
11015 if (insn & (1 << 20)) {
11016 /* Load. */
11017 tmp = tcg_temp_new_i32();
11018 switch (op) {
11019 case 0:
11020 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11021 break;
11022 case 4:
11023 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11024 break;
11025 case 1:
11026 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11027 break;
11028 case 5:
11029 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11030 break;
11031 case 2:
11032 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11033 break;
11034 default:
11035 tcg_temp_free_i32(tmp);
11036 tcg_temp_free_i32(addr);
11037 goto illegal_op;
11039 if (rs == 15) {
11040 gen_bx_excret(s, tmp);
11041 } else {
11042 store_reg(s, rs, tmp);
11044 } else {
11045 /* Store. */
11046 tmp = load_reg(s, rs);
11047 switch (op) {
11048 case 0:
11049 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11050 break;
11051 case 1:
11052 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11053 break;
11054 case 2:
11055 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11056 break;
11057 default:
11058 tcg_temp_free_i32(tmp);
11059 tcg_temp_free_i32(addr);
11060 goto illegal_op;
11062 tcg_temp_free_i32(tmp);
11064 if (postinc)
11065 tcg_gen_addi_i32(addr, addr, imm);
11066 if (writeback) {
11067 store_reg(s, rn, addr);
11068 } else {
11069 tcg_temp_free_i32(addr);
11072 break;
11073 default:
11074 goto illegal_op;
11076 return 0;
11077 illegal_op:
11078 return 1;
11081 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
11083 uint32_t val, insn, op, rm, rn, rd, shift, cond;
11084 int32_t offset;
11085 int i;
11086 TCGv_i32 tmp;
11087 TCGv_i32 tmp2;
11088 TCGv_i32 addr;
11090 if (s->condexec_mask) {
11091 cond = s->condexec_cond;
11092 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
11093 s->condlabel = gen_new_label();
11094 arm_gen_test_cc(cond ^ 1, s->condlabel);
11095 s->condjmp = 1;
11099 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11100 s->pc += 2;
11102 switch (insn >> 12) {
11103 case 0: case 1:
11105 rd = insn & 7;
11106 op = (insn >> 11) & 3;
11107 if (op == 3) {
11108 /* add/subtract */
11109 rn = (insn >> 3) & 7;
11110 tmp = load_reg(s, rn);
11111 if (insn & (1 << 10)) {
11112 /* immediate */
11113 tmp2 = tcg_temp_new_i32();
11114 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11115 } else {
11116 /* reg */
11117 rm = (insn >> 6) & 7;
11118 tmp2 = load_reg(s, rm);
11120 if (insn & (1 << 9)) {
11121 if (s->condexec_mask)
11122 tcg_gen_sub_i32(tmp, tmp, tmp2);
11123 else
11124 gen_sub_CC(tmp, tmp, tmp2);
11125 } else {
11126 if (s->condexec_mask)
11127 tcg_gen_add_i32(tmp, tmp, tmp2);
11128 else
11129 gen_add_CC(tmp, tmp, tmp2);
11131 tcg_temp_free_i32(tmp2);
11132 store_reg(s, rd, tmp);
11133 } else {
11134 /* shift immediate */
11135 rm = (insn >> 3) & 7;
11136 shift = (insn >> 6) & 0x1f;
11137 tmp = load_reg(s, rm);
11138 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11139 if (!s->condexec_mask)
11140 gen_logic_CC(tmp);
11141 store_reg(s, rd, tmp);
11143 break;
11144 case 2: case 3:
11145 /* arithmetic large immediate */
11146 op = (insn >> 11) & 3;
11147 rd = (insn >> 8) & 0x7;
11148 if (op == 0) { /* mov */
11149 tmp = tcg_temp_new_i32();
11150 tcg_gen_movi_i32(tmp, insn & 0xff);
11151 if (!s->condexec_mask)
11152 gen_logic_CC(tmp);
11153 store_reg(s, rd, tmp);
11154 } else {
11155 tmp = load_reg(s, rd);
11156 tmp2 = tcg_temp_new_i32();
11157 tcg_gen_movi_i32(tmp2, insn & 0xff);
11158 switch (op) {
11159 case 1: /* cmp */
11160 gen_sub_CC(tmp, tmp, tmp2);
11161 tcg_temp_free_i32(tmp);
11162 tcg_temp_free_i32(tmp2);
11163 break;
11164 case 2: /* add */
11165 if (s->condexec_mask)
11166 tcg_gen_add_i32(tmp, tmp, tmp2);
11167 else
11168 gen_add_CC(tmp, tmp, tmp2);
11169 tcg_temp_free_i32(tmp2);
11170 store_reg(s, rd, tmp);
11171 break;
11172 case 3: /* sub */
11173 if (s->condexec_mask)
11174 tcg_gen_sub_i32(tmp, tmp, tmp2);
11175 else
11176 gen_sub_CC(tmp, tmp, tmp2);
11177 tcg_temp_free_i32(tmp2);
11178 store_reg(s, rd, tmp);
11179 break;
11182 break;
11183 case 4:
11184 if (insn & (1 << 11)) {
11185 rd = (insn >> 8) & 7;
11186 /* load pc-relative. Bit 1 of PC is ignored. */
11187 val = s->pc + 2 + ((insn & 0xff) * 4);
11188 val &= ~(uint32_t)2;
11189 addr = tcg_temp_new_i32();
11190 tcg_gen_movi_i32(addr, val);
11191 tmp = tcg_temp_new_i32();
11192 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11193 rd | ISSIs16Bit);
11194 tcg_temp_free_i32(addr);
11195 store_reg(s, rd, tmp);
11196 break;
11198 if (insn & (1 << 10)) {
11199 /* 0b0100_01xx_xxxx_xxxx
11200 * - data processing extended, branch and exchange
11202 rd = (insn & 7) | ((insn >> 4) & 8);
11203 rm = (insn >> 3) & 0xf;
11204 op = (insn >> 8) & 3;
11205 switch (op) {
11206 case 0: /* add */
11207 tmp = load_reg(s, rd);
11208 tmp2 = load_reg(s, rm);
11209 tcg_gen_add_i32(tmp, tmp, tmp2);
11210 tcg_temp_free_i32(tmp2);
11211 store_reg(s, rd, tmp);
11212 break;
11213 case 1: /* cmp */
11214 tmp = load_reg(s, rd);
11215 tmp2 = load_reg(s, rm);
11216 gen_sub_CC(tmp, tmp, tmp2);
11217 tcg_temp_free_i32(tmp2);
11218 tcg_temp_free_i32(tmp);
11219 break;
11220 case 2: /* mov/cpy */
11221 tmp = load_reg(s, rm);
11222 store_reg(s, rd, tmp);
11223 break;
11224 case 3:
11226 /* 0b0100_0111_xxxx_xxxx
11227 * - branch [and link] exchange thumb register
11229 bool link = insn & (1 << 7);
11231 if (insn & 3) {
11232 goto undef;
11234 if (link) {
11235 ARCH(5);
11237 if ((insn & 4)) {
11238 /* BXNS/BLXNS: only exists for v8M with the
11239 * security extensions, and always UNDEF if NonSecure.
11240 * We don't implement these in the user-only mode
11241 * either (in theory you can use them from Secure User
11242 * mode but they are too tied in to system emulation.)
11244 if (!s->v8m_secure || IS_USER_ONLY) {
11245 goto undef;
11247 if (link) {
11248 gen_blxns(s, rm);
11249 } else {
11250 gen_bxns(s, rm);
11252 break;
11254 /* BLX/BX */
11255 tmp = load_reg(s, rm);
11256 if (link) {
11257 val = (uint32_t)s->pc | 1;
11258 tmp2 = tcg_temp_new_i32();
11259 tcg_gen_movi_i32(tmp2, val);
11260 store_reg(s, 14, tmp2);
11261 gen_bx(s, tmp);
11262 } else {
11263 /* Only BX works as exception-return, not BLX */
11264 gen_bx_excret(s, tmp);
11266 break;
11269 break;
11272 /* data processing register */
11273 rd = insn & 7;
11274 rm = (insn >> 3) & 7;
11275 op = (insn >> 6) & 0xf;
11276 if (op == 2 || op == 3 || op == 4 || op == 7) {
11277 /* the shift/rotate ops want the operands backwards */
11278 val = rm;
11279 rm = rd;
11280 rd = val;
11281 val = 1;
11282 } else {
11283 val = 0;
11286 if (op == 9) { /* neg */
11287 tmp = tcg_temp_new_i32();
11288 tcg_gen_movi_i32(tmp, 0);
11289 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11290 tmp = load_reg(s, rd);
11291 } else {
11292 TCGV_UNUSED_I32(tmp);
11295 tmp2 = load_reg(s, rm);
11296 switch (op) {
11297 case 0x0: /* and */
11298 tcg_gen_and_i32(tmp, tmp, tmp2);
11299 if (!s->condexec_mask)
11300 gen_logic_CC(tmp);
11301 break;
11302 case 0x1: /* eor */
11303 tcg_gen_xor_i32(tmp, tmp, tmp2);
11304 if (!s->condexec_mask)
11305 gen_logic_CC(tmp);
11306 break;
11307 case 0x2: /* lsl */
11308 if (s->condexec_mask) {
11309 gen_shl(tmp2, tmp2, tmp);
11310 } else {
11311 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11312 gen_logic_CC(tmp2);
11314 break;
11315 case 0x3: /* lsr */
11316 if (s->condexec_mask) {
11317 gen_shr(tmp2, tmp2, tmp);
11318 } else {
11319 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11320 gen_logic_CC(tmp2);
11322 break;
11323 case 0x4: /* asr */
11324 if (s->condexec_mask) {
11325 gen_sar(tmp2, tmp2, tmp);
11326 } else {
11327 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11328 gen_logic_CC(tmp2);
11330 break;
11331 case 0x5: /* adc */
11332 if (s->condexec_mask) {
11333 gen_adc(tmp, tmp2);
11334 } else {
11335 gen_adc_CC(tmp, tmp, tmp2);
11337 break;
11338 case 0x6: /* sbc */
11339 if (s->condexec_mask) {
11340 gen_sub_carry(tmp, tmp, tmp2);
11341 } else {
11342 gen_sbc_CC(tmp, tmp, tmp2);
11344 break;
11345 case 0x7: /* ror */
11346 if (s->condexec_mask) {
11347 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11348 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11349 } else {
11350 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11351 gen_logic_CC(tmp2);
11353 break;
11354 case 0x8: /* tst */
11355 tcg_gen_and_i32(tmp, tmp, tmp2);
11356 gen_logic_CC(tmp);
11357 rd = 16;
11358 break;
11359 case 0x9: /* neg */
11360 if (s->condexec_mask)
11361 tcg_gen_neg_i32(tmp, tmp2);
11362 else
11363 gen_sub_CC(tmp, tmp, tmp2);
11364 break;
11365 case 0xa: /* cmp */
11366 gen_sub_CC(tmp, tmp, tmp2);
11367 rd = 16;
11368 break;
11369 case 0xb: /* cmn */
11370 gen_add_CC(tmp, tmp, tmp2);
11371 rd = 16;
11372 break;
11373 case 0xc: /* orr */
11374 tcg_gen_or_i32(tmp, tmp, tmp2);
11375 if (!s->condexec_mask)
11376 gen_logic_CC(tmp);
11377 break;
11378 case 0xd: /* mul */
11379 tcg_gen_mul_i32(tmp, tmp, tmp2);
11380 if (!s->condexec_mask)
11381 gen_logic_CC(tmp);
11382 break;
11383 case 0xe: /* bic */
11384 tcg_gen_andc_i32(tmp, tmp, tmp2);
11385 if (!s->condexec_mask)
11386 gen_logic_CC(tmp);
11387 break;
11388 case 0xf: /* mvn */
11389 tcg_gen_not_i32(tmp2, tmp2);
11390 if (!s->condexec_mask)
11391 gen_logic_CC(tmp2);
11392 val = 1;
11393 rm = rd;
11394 break;
11396 if (rd != 16) {
11397 if (val) {
11398 store_reg(s, rm, tmp2);
11399 if (op != 0xf)
11400 tcg_temp_free_i32(tmp);
11401 } else {
11402 store_reg(s, rd, tmp);
11403 tcg_temp_free_i32(tmp2);
11405 } else {
11406 tcg_temp_free_i32(tmp);
11407 tcg_temp_free_i32(tmp2);
11409 break;
11411 case 5:
11412 /* load/store register offset. */
11413 rd = insn & 7;
11414 rn = (insn >> 3) & 7;
11415 rm = (insn >> 6) & 7;
11416 op = (insn >> 9) & 7;
11417 addr = load_reg(s, rn);
11418 tmp = load_reg(s, rm);
11419 tcg_gen_add_i32(addr, addr, tmp);
11420 tcg_temp_free_i32(tmp);
11422 if (op < 3) { /* store */
11423 tmp = load_reg(s, rd);
11424 } else {
11425 tmp = tcg_temp_new_i32();
11428 switch (op) {
11429 case 0: /* str */
11430 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11431 break;
11432 case 1: /* strh */
11433 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11434 break;
11435 case 2: /* strb */
11436 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11437 break;
11438 case 3: /* ldrsb */
11439 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11440 break;
11441 case 4: /* ldr */
11442 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11443 break;
11444 case 5: /* ldrh */
11445 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11446 break;
11447 case 6: /* ldrb */
11448 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11449 break;
11450 case 7: /* ldrsh */
11451 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11452 break;
11454 if (op >= 3) { /* load */
11455 store_reg(s, rd, tmp);
11456 } else {
11457 tcg_temp_free_i32(tmp);
11459 tcg_temp_free_i32(addr);
11460 break;
11462 case 6:
11463 /* load/store word immediate offset */
11464 rd = insn & 7;
11465 rn = (insn >> 3) & 7;
11466 addr = load_reg(s, rn);
11467 val = (insn >> 4) & 0x7c;
11468 tcg_gen_addi_i32(addr, addr, val);
11470 if (insn & (1 << 11)) {
11471 /* load */
11472 tmp = tcg_temp_new_i32();
11473 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11474 store_reg(s, rd, tmp);
11475 } else {
11476 /* store */
11477 tmp = load_reg(s, rd);
11478 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11479 tcg_temp_free_i32(tmp);
11481 tcg_temp_free_i32(addr);
11482 break;
11484 case 7:
11485 /* load/store byte immediate offset */
11486 rd = insn & 7;
11487 rn = (insn >> 3) & 7;
11488 addr = load_reg(s, rn);
11489 val = (insn >> 6) & 0x1f;
11490 tcg_gen_addi_i32(addr, addr, val);
11492 if (insn & (1 << 11)) {
11493 /* load */
11494 tmp = tcg_temp_new_i32();
11495 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11496 store_reg(s, rd, tmp);
11497 } else {
11498 /* store */
11499 tmp = load_reg(s, rd);
11500 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11501 tcg_temp_free_i32(tmp);
11503 tcg_temp_free_i32(addr);
11504 break;
11506 case 8:
11507 /* load/store halfword immediate offset */
11508 rd = insn & 7;
11509 rn = (insn >> 3) & 7;
11510 addr = load_reg(s, rn);
11511 val = (insn >> 5) & 0x3e;
11512 tcg_gen_addi_i32(addr, addr, val);
11514 if (insn & (1 << 11)) {
11515 /* load */
11516 tmp = tcg_temp_new_i32();
11517 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11518 store_reg(s, rd, tmp);
11519 } else {
11520 /* store */
11521 tmp = load_reg(s, rd);
11522 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11523 tcg_temp_free_i32(tmp);
11525 tcg_temp_free_i32(addr);
11526 break;
11528 case 9:
11529 /* load/store from stack */
11530 rd = (insn >> 8) & 7;
11531 addr = load_reg(s, 13);
11532 val = (insn & 0xff) * 4;
11533 tcg_gen_addi_i32(addr, addr, val);
11535 if (insn & (1 << 11)) {
11536 /* load */
11537 tmp = tcg_temp_new_i32();
11538 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11539 store_reg(s, rd, tmp);
11540 } else {
11541 /* store */
11542 tmp = load_reg(s, rd);
11543 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11544 tcg_temp_free_i32(tmp);
11546 tcg_temp_free_i32(addr);
11547 break;
11549 case 10:
11550 /* add to high reg */
11551 rd = (insn >> 8) & 7;
11552 if (insn & (1 << 11)) {
11553 /* SP */
11554 tmp = load_reg(s, 13);
11555 } else {
11556 /* PC. bit 1 is ignored. */
11557 tmp = tcg_temp_new_i32();
11558 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11560 val = (insn & 0xff) * 4;
11561 tcg_gen_addi_i32(tmp, tmp, val);
11562 store_reg(s, rd, tmp);
11563 break;
11565 case 11:
11566 /* misc */
11567 op = (insn >> 8) & 0xf;
11568 switch (op) {
11569 case 0:
11570 /* adjust stack pointer */
11571 tmp = load_reg(s, 13);
11572 val = (insn & 0x7f) * 4;
11573 if (insn & (1 << 7))
11574 val = -(int32_t)val;
11575 tcg_gen_addi_i32(tmp, tmp, val);
11576 store_reg(s, 13, tmp);
11577 break;
11579 case 2: /* sign/zero extend. */
11580 ARCH(6);
11581 rd = insn & 7;
11582 rm = (insn >> 3) & 7;
11583 tmp = load_reg(s, rm);
11584 switch ((insn >> 6) & 3) {
11585 case 0: gen_sxth(tmp); break;
11586 case 1: gen_sxtb(tmp); break;
11587 case 2: gen_uxth(tmp); break;
11588 case 3: gen_uxtb(tmp); break;
11590 store_reg(s, rd, tmp);
11591 break;
11592 case 4: case 5: case 0xc: case 0xd:
11593 /* push/pop */
11594 addr = load_reg(s, 13);
11595 if (insn & (1 << 8))
11596 offset = 4;
11597 else
11598 offset = 0;
11599 for (i = 0; i < 8; i++) {
11600 if (insn & (1 << i))
11601 offset += 4;
11603 if ((insn & (1 << 11)) == 0) {
11604 tcg_gen_addi_i32(addr, addr, -offset);
11606 for (i = 0; i < 8; i++) {
11607 if (insn & (1 << i)) {
11608 if (insn & (1 << 11)) {
11609 /* pop */
11610 tmp = tcg_temp_new_i32();
11611 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11612 store_reg(s, i, tmp);
11613 } else {
11614 /* push */
11615 tmp = load_reg(s, i);
11616 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11617 tcg_temp_free_i32(tmp);
11619 /* advance to the next address. */
11620 tcg_gen_addi_i32(addr, addr, 4);
11623 TCGV_UNUSED_I32(tmp);
11624 if (insn & (1 << 8)) {
11625 if (insn & (1 << 11)) {
11626 /* pop pc */
11627 tmp = tcg_temp_new_i32();
11628 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11629 /* don't set the pc until the rest of the instruction
11630 has completed */
11631 } else {
11632 /* push lr */
11633 tmp = load_reg(s, 14);
11634 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11635 tcg_temp_free_i32(tmp);
11637 tcg_gen_addi_i32(addr, addr, 4);
11639 if ((insn & (1 << 11)) == 0) {
11640 tcg_gen_addi_i32(addr, addr, -offset);
11642 /* write back the new stack pointer */
11643 store_reg(s, 13, addr);
11644 /* set the new PC value */
11645 if ((insn & 0x0900) == 0x0900) {
11646 store_reg_from_load(s, 15, tmp);
11648 break;
11650 case 1: case 3: case 9: case 11: /* czb */
11651 rm = insn & 7;
11652 tmp = load_reg(s, rm);
11653 s->condlabel = gen_new_label();
11654 s->condjmp = 1;
11655 if (insn & (1 << 11))
11656 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11657 else
11658 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11659 tcg_temp_free_i32(tmp);
11660 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11661 val = (uint32_t)s->pc + 2;
11662 val += offset;
11663 gen_jmp(s, val);
11664 break;
11666 case 15: /* IT, nop-hint. */
11667 if ((insn & 0xf) == 0) {
11668 gen_nop_hint(s, (insn >> 4) & 0xf);
11669 break;
11671 /* If Then. */
11672 s->condexec_cond = (insn >> 4) & 0xe;
11673 s->condexec_mask = insn & 0x1f;
11674 /* No actual code generated for this insn, just setup state. */
11675 break;
11677 case 0xe: /* bkpt */
11679 int imm8 = extract32(insn, 0, 8);
11680 ARCH(5);
11681 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11682 default_exception_el(s));
11683 break;
11686 case 0xa: /* rev, and hlt */
11688 int op1 = extract32(insn, 6, 2);
11690 if (op1 == 2) {
11691 /* HLT */
11692 int imm6 = extract32(insn, 0, 6);
11694 gen_hlt(s, imm6);
11695 break;
11698 /* Otherwise this is rev */
11699 ARCH(6);
11700 rn = (insn >> 3) & 0x7;
11701 rd = insn & 0x7;
11702 tmp = load_reg(s, rn);
11703 switch (op1) {
11704 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11705 case 1: gen_rev16(tmp); break;
11706 case 3: gen_revsh(tmp); break;
11707 default:
11708 g_assert_not_reached();
11710 store_reg(s, rd, tmp);
11711 break;
11714 case 6:
11715 switch ((insn >> 5) & 7) {
11716 case 2:
11717 /* setend */
11718 ARCH(6);
11719 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11720 gen_helper_setend(cpu_env);
11721 s->base.is_jmp = DISAS_UPDATE;
11723 break;
11724 case 3:
11725 /* cps */
11726 ARCH(6);
11727 if (IS_USER(s)) {
11728 break;
11730 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11731 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11732 /* FAULTMASK */
11733 if (insn & 1) {
11734 addr = tcg_const_i32(19);
11735 gen_helper_v7m_msr(cpu_env, addr, tmp);
11736 tcg_temp_free_i32(addr);
11738 /* PRIMASK */
11739 if (insn & 2) {
11740 addr = tcg_const_i32(16);
11741 gen_helper_v7m_msr(cpu_env, addr, tmp);
11742 tcg_temp_free_i32(addr);
11744 tcg_temp_free_i32(tmp);
11745 gen_lookup_tb(s);
11746 } else {
11747 if (insn & (1 << 4)) {
11748 shift = CPSR_A | CPSR_I | CPSR_F;
11749 } else {
11750 shift = 0;
11752 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11754 break;
11755 default:
11756 goto undef;
11758 break;
11760 default:
11761 goto undef;
11763 break;
11765 case 12:
11767 /* load/store multiple */
11768 TCGv_i32 loaded_var;
11769 TCGV_UNUSED_I32(loaded_var);
11770 rn = (insn >> 8) & 0x7;
11771 addr = load_reg(s, rn);
11772 for (i = 0; i < 8; i++) {
11773 if (insn & (1 << i)) {
11774 if (insn & (1 << 11)) {
11775 /* load */
11776 tmp = tcg_temp_new_i32();
11777 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11778 if (i == rn) {
11779 loaded_var = tmp;
11780 } else {
11781 store_reg(s, i, tmp);
11783 } else {
11784 /* store */
11785 tmp = load_reg(s, i);
11786 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11787 tcg_temp_free_i32(tmp);
11789 /* advance to the next address */
11790 tcg_gen_addi_i32(addr, addr, 4);
11793 if ((insn & (1 << rn)) == 0) {
11794 /* base reg not in list: base register writeback */
11795 store_reg(s, rn, addr);
11796 } else {
11797 /* base reg in list: if load, complete it now */
11798 if (insn & (1 << 11)) {
11799 store_reg(s, rn, loaded_var);
11801 tcg_temp_free_i32(addr);
11803 break;
11805 case 13:
11806 /* conditional branch or swi */
11807 cond = (insn >> 8) & 0xf;
11808 if (cond == 0xe)
11809 goto undef;
11811 if (cond == 0xf) {
11812 /* swi */
11813 gen_set_pc_im(s, s->pc);
11814 s->svc_imm = extract32(insn, 0, 8);
11815 s->base.is_jmp = DISAS_SWI;
11816 break;
11818 /* generate a conditional jump to next instruction */
11819 s->condlabel = gen_new_label();
11820 arm_gen_test_cc(cond ^ 1, s->condlabel);
11821 s->condjmp = 1;
11823 /* jump to the offset */
11824 val = (uint32_t)s->pc + 2;
11825 offset = ((int32_t)insn << 24) >> 24;
11826 val += offset << 1;
11827 gen_jmp(s, val);
11828 break;
11830 case 14:
11831 if (insn & (1 << 11)) {
11832 if (disas_thumb2_insn(env, s, insn))
11833 goto undef32;
11834 break;
11836 /* unconditional branch */
11837 val = (uint32_t)s->pc;
11838 offset = ((int32_t)insn << 21) >> 21;
11839 val += (offset << 1) + 2;
11840 gen_jmp(s, val);
11841 break;
11843 case 15:
11844 if (disas_thumb2_insn(env, s, insn))
11845 goto undef32;
11846 break;
11848 return;
11849 undef32:
11850 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11851 default_exception_el(s));
11852 return;
11853 illegal_op:
11854 undef:
11855 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11856 default_exception_el(s));
11859 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11861 /* Return true if the insn at dc->pc might cross a page boundary.
11862 * (False positives are OK, false negatives are not.)
11864 uint16_t insn;
11866 if ((s->pc & 3) == 0) {
11867 /* At a 4-aligned address we can't be crossing a page */
11868 return false;
11871 /* This must be a Thumb insn */
11872 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11874 if ((insn >> 11) >= 0x1d) {
11875 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11876 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11877 * end up actually treating this as two 16-bit insns (see the
11878 * code at the start of disas_thumb2_insn()) but we don't bother
11879 * to check for that as it is unlikely, and false positives here
11880 * are harmless.
11882 return true;
11884 /* Definitely a 16-bit insn, can't be crossing a page. */
11885 return false;
11888 static int arm_tr_init_disas_context(DisasContextBase *dcbase,
11889 CPUState *cs, int max_insns)
11891 DisasContext *dc = container_of(dcbase, DisasContext, base);
11892 CPUARMState *env = cs->env_ptr;
11893 ARMCPU *cpu = arm_env_get_cpu(env);
11895 dc->pc = dc->base.pc_first;
11896 dc->condjmp = 0;
11898 dc->aarch64 = 0;
11899 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11900 * there is no secure EL1, so we route exceptions to EL3.
11902 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11903 !arm_el_is_aa64(env, 3);
11904 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
11905 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
11906 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
11907 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
11908 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
11909 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
11910 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11911 #if !defined(CONFIG_USER_ONLY)
11912 dc->user = (dc->current_el == 0);
11913 #endif
11914 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
11915 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
11916 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
11917 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
11918 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
11919 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
11920 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
11921 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11922 regime_is_secure(env, dc->mmu_idx);
11923 dc->cp_regs = cpu->cp_regs;
11924 dc->features = env->features;
11926 /* Single step state. The code-generation logic here is:
11927 * SS_ACTIVE == 0:
11928 * generate code with no special handling for single-stepping (except
11929 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11930 * this happens anyway because those changes are all system register or
11931 * PSTATE writes).
11932 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11933 * emit code for one insn
11934 * emit code to clear PSTATE.SS
11935 * emit code to generate software step exception for completed step
11936 * end TB (as usual for having generated an exception)
11937 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11938 * emit code to generate a software step exception
11939 * end the TB
11941 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
11942 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
11943 dc->is_ldex = false;
11944 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11946 dc->next_page_start =
11947 (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11949 /* If architectural single step active, limit to 1. */
11950 if (is_singlestepping(dc)) {
11951 max_insns = 1;
11954 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11955 to those left on the page. */
11956 if (!dc->thumb) {
11957 int bound = (dc->next_page_start - dc->base.pc_first) / 4;
11958 max_insns = MIN(max_insns, bound);
11961 cpu_F0s = tcg_temp_new_i32();
11962 cpu_F1s = tcg_temp_new_i32();
11963 cpu_F0d = tcg_temp_new_i64();
11964 cpu_F1d = tcg_temp_new_i64();
11965 cpu_V0 = cpu_F0d;
11966 cpu_V1 = cpu_F1d;
11967 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11968 cpu_M0 = tcg_temp_new_i64();
11970 return max_insns;
11973 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11975 DisasContext *dc = container_of(dcbase, DisasContext, base);
11977 /* A note on handling of the condexec (IT) bits:
11979 * We want to avoid the overhead of having to write the updated condexec
11980 * bits back to the CPUARMState for every instruction in an IT block. So:
11981 * (1) if the condexec bits are not already zero then we write
11982 * zero back into the CPUARMState now. This avoids complications trying
11983 * to do it at the end of the block. (For example if we don't do this
11984 * it's hard to identify whether we can safely skip writing condexec
11985 * at the end of the TB, which we definitely want to do for the case
11986 * where a TB doesn't do anything with the IT state at all.)
11987 * (2) if we are going to leave the TB then we call gen_set_condexec()
11988 * which will write the correct value into CPUARMState if zero is wrong.
11989 * This is done both for leaving the TB at the end, and for leaving
11990 * it because of an exception we know will happen, which is done in
11991 * gen_exception_insn(). The latter is necessary because we need to
11992 * leave the TB with the PC/IT state just prior to execution of the
11993 * instruction which caused the exception.
11994 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11995 * then the CPUARMState will be wrong and we need to reset it.
11996 * This is handled in the same way as restoration of the
11997 * PC in these situations; we save the value of the condexec bits
11998 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11999 * then uses this to restore them after an exception.
12001 * Note that there are no instructions which can read the condexec
12002 * bits, and none which can write non-static values to them, so
12003 * we don't need to care about whether CPUARMState is correct in the
12004 * middle of a TB.
12007 /* Reset the conditional execution bits immediately. This avoids
12008 complications trying to do it at the end of the block. */
12009 if (dc->condexec_mask || dc->condexec_cond) {
12010 TCGv_i32 tmp = tcg_temp_new_i32();
12011 tcg_gen_movi_i32(tmp, 0);
12012 store_cpu_field(tmp, condexec_bits);
12014 tcg_clear_temp_count();
12017 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12019 DisasContext *dc = container_of(dcbase, DisasContext, base);
12021 dc->insn_start_idx = tcg_op_buf_count();
12022 tcg_gen_insn_start(dc->pc,
12023 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12027 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12028 const CPUBreakpoint *bp)
12030 DisasContext *dc = container_of(dcbase, DisasContext, base);
12032 if (bp->flags & BP_CPU) {
12033 gen_set_condexec(dc);
12034 gen_set_pc_im(dc, dc->pc);
12035 gen_helper_check_breakpoints(cpu_env);
12036 /* End the TB early; it's likely not going to be executed */
12037 dc->base.is_jmp = DISAS_TOO_MANY;
12038 } else {
12039 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12040 /* The address covered by the breakpoint must be
12041 included in [tb->pc, tb->pc + tb->size) in order
12042 to for it to be properly cleared -- thus we
12043 increment the PC here so that the logic setting
12044 tb->size below does the right thing. */
12045 /* TODO: Advance PC by correct instruction length to
12046 * avoid disassembler error messages */
12047 dc->pc += 2;
12048 dc->base.is_jmp = DISAS_NORETURN;
12051 return true;
12054 static bool arm_pre_translate_insn(DisasContext *dc)
12056 #ifdef CONFIG_USER_ONLY
12057 /* Intercept jump to the magic kernel page. */
12058 if (dc->pc >= 0xffff0000) {
12059 /* We always get here via a jump, so know we are not in a
12060 conditional execution block. */
12061 gen_exception_internal(EXCP_KERNEL_TRAP);
12062 dc->base.is_jmp = DISAS_NORETURN;
12063 return true;
12065 #endif
12067 if (dc->ss_active && !dc->pstate_ss) {
12068 /* Singlestep state is Active-pending.
12069 * If we're in this state at the start of a TB then either
12070 * a) we just took an exception to an EL which is being debugged
12071 * and this is the first insn in the exception handler
12072 * b) debug exceptions were masked and we just unmasked them
12073 * without changing EL (eg by clearing PSTATE.D)
12074 * In either case we're going to take a swstep exception in the
12075 * "did not step an insn" case, and so the syndrome ISV and EX
12076 * bits should be zero.
12078 assert(dc->base.num_insns == 1);
12079 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12080 default_exception_el(dc));
12081 dc->base.is_jmp = DISAS_NORETURN;
12082 return true;
12085 return false;
12088 static void arm_post_translate_insn(DisasContext *dc)
12090 if (dc->condjmp && !dc->base.is_jmp) {
12091 gen_set_label(dc->condlabel);
12092 dc->condjmp = 0;
12094 dc->base.pc_next = dc->pc;
12095 translator_loop_temp_check(&dc->base);
12098 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12100 DisasContext *dc = container_of(dcbase, DisasContext, base);
12101 CPUARMState *env = cpu->env_ptr;
12102 unsigned int insn;
12104 if (arm_pre_translate_insn(dc)) {
12105 return;
12108 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12109 dc->pc += 4;
12110 disas_arm_insn(dc, insn);
12112 arm_post_translate_insn(dc);
12114 /* ARM is a fixed-length ISA. We performed the cross-page check
12115 in init_disas_context by adjusting max_insns. */
12118 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12120 DisasContext *dc = container_of(dcbase, DisasContext, base);
12121 CPUARMState *env = cpu->env_ptr;
12123 if (arm_pre_translate_insn(dc)) {
12124 return;
12127 disas_thumb_insn(env, dc);
12129 /* Advance the Thumb condexec condition. */
12130 if (dc->condexec_mask) {
12131 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12132 ((dc->condexec_mask >> 4) & 1));
12133 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12134 if (dc->condexec_mask == 0) {
12135 dc->condexec_cond = 0;
12139 arm_post_translate_insn(dc);
12141 /* Thumb is a variable-length ISA. Stop translation when the next insn
12142 * will touch a new page. This ensures that prefetch aborts occur at
12143 * the right place.
12145 * We want to stop the TB if the next insn starts in a new page,
12146 * or if it spans between this page and the next. This means that
12147 * if we're looking at the last halfword in the page we need to
12148 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12149 * or a 32-bit Thumb insn (which won't).
12150 * This is to avoid generating a silly TB with a single 16-bit insn
12151 * in it at the end of this page (which would execute correctly
12152 * but isn't very efficient).
12154 if (dc->base.is_jmp == DISAS_NEXT
12155 && (dc->pc >= dc->next_page_start
12156 || (dc->pc >= dc->next_page_start - 3
12157 && insn_crosses_page(env, dc)))) {
12158 dc->base.is_jmp = DISAS_TOO_MANY;
12162 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12164 DisasContext *dc = container_of(dcbase, DisasContext, base);
12166 if (dc->base.tb->cflags & CF_LAST_IO && dc->condjmp) {
12167 /* FIXME: This can theoretically happen with self-modifying code. */
12168 cpu_abort(cpu, "IO on conditional branch instruction");
12171 /* At this stage dc->condjmp will only be set when the skipped
12172 instruction was a conditional branch or trap, and the PC has
12173 already been written. */
12174 gen_set_condexec(dc);
12175 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12176 /* Exception return branches need some special case code at the
12177 * end of the TB, which is complex enough that it has to
12178 * handle the single-step vs not and the condition-failed
12179 * insn codepath itself.
12181 gen_bx_excret_final_code(dc);
12182 } else if (unlikely(is_singlestepping(dc))) {
12183 /* Unconditional and "condition passed" instruction codepath. */
12184 switch (dc->base.is_jmp) {
12185 case DISAS_SWI:
12186 gen_ss_advance(dc);
12187 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12188 default_exception_el(dc));
12189 break;
12190 case DISAS_HVC:
12191 gen_ss_advance(dc);
12192 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12193 break;
12194 case DISAS_SMC:
12195 gen_ss_advance(dc);
12196 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12197 break;
12198 case DISAS_NEXT:
12199 case DISAS_TOO_MANY:
12200 case DISAS_UPDATE:
12201 gen_set_pc_im(dc, dc->pc);
12202 /* fall through */
12203 default:
12204 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12205 gen_singlestep_exception(dc);
12206 break;
12207 case DISAS_NORETURN:
12208 break;
12210 } else {
12211 /* While branches must always occur at the end of an IT block,
12212 there are a few other things that can cause us to terminate
12213 the TB in the middle of an IT block:
12214 - Exception generating instructions (bkpt, swi, undefined).
12215 - Page boundaries.
12216 - Hardware watchpoints.
12217 Hardware breakpoints have already been handled and skip this code.
12219 switch(dc->base.is_jmp) {
12220 case DISAS_NEXT:
12221 case DISAS_TOO_MANY:
12222 gen_goto_tb(dc, 1, dc->pc);
12223 break;
12224 case DISAS_JUMP:
12225 gen_goto_ptr();
12226 break;
12227 case DISAS_UPDATE:
12228 gen_set_pc_im(dc, dc->pc);
12229 /* fall through */
12230 default:
12231 /* indicate that the hash table must be used to find the next TB */
12232 tcg_gen_exit_tb(0);
12233 break;
12234 case DISAS_NORETURN:
12235 /* nothing more to generate */
12236 break;
12237 case DISAS_WFI:
12238 gen_helper_wfi(cpu_env);
12239 /* The helper doesn't necessarily throw an exception, but we
12240 * must go back to the main loop to check for interrupts anyway.
12242 tcg_gen_exit_tb(0);
12243 break;
12244 case DISAS_WFE:
12245 gen_helper_wfe(cpu_env);
12246 break;
12247 case DISAS_YIELD:
12248 gen_helper_yield(cpu_env);
12249 break;
12250 case DISAS_SWI:
12251 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12252 default_exception_el(dc));
12253 break;
12254 case DISAS_HVC:
12255 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12256 break;
12257 case DISAS_SMC:
12258 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12259 break;
12263 if (dc->condjmp) {
12264 /* "Condition failed" instruction codepath for the branch/trap insn */
12265 gen_set_label(dc->condlabel);
12266 gen_set_condexec(dc);
12267 if (unlikely(is_singlestepping(dc))) {
12268 gen_set_pc_im(dc, dc->pc);
12269 gen_singlestep_exception(dc);
12270 } else {
12271 gen_goto_tb(dc, 1, dc->pc);
12275 /* Functions above can change dc->pc, so re-align db->pc_next */
12276 dc->base.pc_next = dc->pc;
12279 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12281 DisasContext *dc = container_of(dcbase, DisasContext, base);
12283 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12284 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size,
12285 dc->thumb | (dc->sctlr_b << 1));
12288 static const TranslatorOps arm_translator_ops = {
12289 .init_disas_context = arm_tr_init_disas_context,
12290 .tb_start = arm_tr_tb_start,
12291 .insn_start = arm_tr_insn_start,
12292 .breakpoint_check = arm_tr_breakpoint_check,
12293 .translate_insn = arm_tr_translate_insn,
12294 .tb_stop = arm_tr_tb_stop,
12295 .disas_log = arm_tr_disas_log,
12298 static const TranslatorOps thumb_translator_ops = {
12299 .init_disas_context = arm_tr_init_disas_context,
12300 .tb_start = arm_tr_tb_start,
12301 .insn_start = arm_tr_insn_start,
12302 .breakpoint_check = arm_tr_breakpoint_check,
12303 .translate_insn = thumb_tr_translate_insn,
12304 .tb_stop = arm_tr_tb_stop,
12305 .disas_log = arm_tr_disas_log,
12308 /* generate intermediate code for basic block 'tb'. */
12309 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12311 DisasContext dc;
12312 const TranslatorOps *ops = &arm_translator_ops;
12314 if (ARM_TBFLAG_THUMB(tb->flags)) {
12315 ops = &thumb_translator_ops;
12317 #ifdef TARGET_AARCH64
12318 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12319 ops = &aarch64_translator_ops;
12321 #endif
12323 translator_loop(ops, &dc.base, cpu, tb);
12326 static const char *cpu_mode_names[16] = {
12327 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12328 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12331 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12332 int flags)
12334 ARMCPU *cpu = ARM_CPU(cs);
12335 CPUARMState *env = &cpu->env;
12336 int i;
12338 if (is_a64(env)) {
12339 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12340 return;
12343 for(i=0;i<16;i++) {
12344 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12345 if ((i % 4) == 3)
12346 cpu_fprintf(f, "\n");
12347 else
12348 cpu_fprintf(f, " ");
12351 if (arm_feature(env, ARM_FEATURE_M)) {
12352 uint32_t xpsr = xpsr_read(env);
12353 const char *mode;
12354 const char *ns_status = "";
12356 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12357 ns_status = env->v7m.secure ? "S " : "NS ";
12360 if (xpsr & XPSR_EXCP) {
12361 mode = "handler";
12362 } else {
12363 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12364 mode = "unpriv-thread";
12365 } else {
12366 mode = "priv-thread";
12370 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12371 xpsr,
12372 xpsr & XPSR_N ? 'N' : '-',
12373 xpsr & XPSR_Z ? 'Z' : '-',
12374 xpsr & XPSR_C ? 'C' : '-',
12375 xpsr & XPSR_V ? 'V' : '-',
12376 xpsr & XPSR_T ? 'T' : 'A',
12377 ns_status,
12378 mode);
12379 } else {
12380 uint32_t psr = cpsr_read(env);
12381 const char *ns_status = "";
12383 if (arm_feature(env, ARM_FEATURE_EL3) &&
12384 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12385 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12388 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12389 psr,
12390 psr & CPSR_N ? 'N' : '-',
12391 psr & CPSR_Z ? 'Z' : '-',
12392 psr & CPSR_C ? 'C' : '-',
12393 psr & CPSR_V ? 'V' : '-',
12394 psr & CPSR_T ? 'T' : 'A',
12395 ns_status,
12396 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12399 if (flags & CPU_DUMP_FPU) {
12400 int numvfpregs = 0;
12401 if (arm_feature(env, ARM_FEATURE_VFP)) {
12402 numvfpregs += 16;
12404 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12405 numvfpregs += 16;
12407 for (i = 0; i < numvfpregs; i++) {
12408 uint64_t v = float64_val(env->vfp.regs[i]);
12409 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12410 i * 2, (uint32_t)v,
12411 i * 2 + 1, (uint32_t)(v >> 32),
12412 i, v);
12414 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12418 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12419 target_ulong *data)
12421 if (is_a64(env)) {
12422 env->pc = data[0];
12423 env->condexec_bits = 0;
12424 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12425 } else {
12426 env->regs[15] = data[0];
12427 env->condexec_bits = data[1];
12428 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;