target/arm: Implement secure function return
[qemu.git] / target / arm / translate.c
blob5c6f9fea1ba3e3a506388c5190791fea90f4ecde
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 || arm_dc_feature(s, ARM_FEATURE_M))) {
9724 /* Thumb-1 cores may need to treat bl and blx as a pair of
9725 16-bit instructions to get correct prefetch abort behavior. */
9726 insn = insn_hw1;
9727 if ((insn & (1 << 12)) == 0) {
9728 ARCH(5);
9729 /* Second half of blx. */
9730 offset = ((insn & 0x7ff) << 1);
9731 tmp = load_reg(s, 14);
9732 tcg_gen_addi_i32(tmp, tmp, offset);
9733 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9735 tmp2 = tcg_temp_new_i32();
9736 tcg_gen_movi_i32(tmp2, s->pc | 1);
9737 store_reg(s, 14, tmp2);
9738 gen_bx(s, tmp);
9739 return 0;
9741 if (insn & (1 << 11)) {
9742 /* Second half of bl. */
9743 offset = ((insn & 0x7ff) << 1) | 1;
9744 tmp = load_reg(s, 14);
9745 tcg_gen_addi_i32(tmp, tmp, offset);
9747 tmp2 = tcg_temp_new_i32();
9748 tcg_gen_movi_i32(tmp2, s->pc | 1);
9749 store_reg(s, 14, tmp2);
9750 gen_bx(s, tmp);
9751 return 0;
9753 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9754 /* Instruction spans a page boundary. Implement it as two
9755 16-bit instructions in case the second half causes an
9756 prefetch abort. */
9757 offset = ((int32_t)insn << 21) >> 9;
9758 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9759 return 0;
9761 /* Fall through to 32-bit decode. */
9764 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9765 s->pc += 2;
9766 insn |= (uint32_t)insn_hw1 << 16;
9768 if ((insn & 0xf800e800) != 0xf000e800) {
9769 ARCH(6T2);
9772 rn = (insn >> 16) & 0xf;
9773 rs = (insn >> 12) & 0xf;
9774 rd = (insn >> 8) & 0xf;
9775 rm = insn & 0xf;
9776 switch ((insn >> 25) & 0xf) {
9777 case 0: case 1: case 2: case 3:
9778 /* 16-bit instructions. Should never happen. */
9779 abort();
9780 case 4:
9781 if (insn & (1 << 22)) {
9782 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9783 * - load/store doubleword, load/store exclusive, ldacq/strel,
9784 * table branch.
9786 if (insn & 0x01200000) {
9787 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9788 * - load/store dual (post-indexed)
9789 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9790 * - load/store dual (literal and immediate)
9791 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9792 * - load/store dual (pre-indexed)
9794 if (rn == 15) {
9795 if (insn & (1 << 21)) {
9796 /* UNPREDICTABLE */
9797 goto illegal_op;
9799 addr = tcg_temp_new_i32();
9800 tcg_gen_movi_i32(addr, s->pc & ~3);
9801 } else {
9802 addr = load_reg(s, rn);
9804 offset = (insn & 0xff) * 4;
9805 if ((insn & (1 << 23)) == 0)
9806 offset = -offset;
9807 if (insn & (1 << 24)) {
9808 tcg_gen_addi_i32(addr, addr, offset);
9809 offset = 0;
9811 if (insn & (1 << 20)) {
9812 /* ldrd */
9813 tmp = tcg_temp_new_i32();
9814 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9815 store_reg(s, rs, tmp);
9816 tcg_gen_addi_i32(addr, addr, 4);
9817 tmp = tcg_temp_new_i32();
9818 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9819 store_reg(s, rd, tmp);
9820 } else {
9821 /* strd */
9822 tmp = load_reg(s, rs);
9823 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9824 tcg_temp_free_i32(tmp);
9825 tcg_gen_addi_i32(addr, addr, 4);
9826 tmp = load_reg(s, rd);
9827 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9828 tcg_temp_free_i32(tmp);
9830 if (insn & (1 << 21)) {
9831 /* Base writeback. */
9832 tcg_gen_addi_i32(addr, addr, offset - 4);
9833 store_reg(s, rn, addr);
9834 } else {
9835 tcg_temp_free_i32(addr);
9837 } else if ((insn & (1 << 23)) == 0) {
9838 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9839 * - load/store exclusive word
9841 if (rs == 15) {
9842 goto illegal_op;
9844 addr = tcg_temp_local_new_i32();
9845 load_reg_var(s, addr, rn);
9846 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9847 if (insn & (1 << 20)) {
9848 gen_load_exclusive(s, rs, 15, addr, 2);
9849 } else {
9850 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9852 tcg_temp_free_i32(addr);
9853 } else if ((insn & (7 << 5)) == 0) {
9854 /* Table Branch. */
9855 if (rn == 15) {
9856 addr = tcg_temp_new_i32();
9857 tcg_gen_movi_i32(addr, s->pc);
9858 } else {
9859 addr = load_reg(s, rn);
9861 tmp = load_reg(s, rm);
9862 tcg_gen_add_i32(addr, addr, tmp);
9863 if (insn & (1 << 4)) {
9864 /* tbh */
9865 tcg_gen_add_i32(addr, addr, tmp);
9866 tcg_temp_free_i32(tmp);
9867 tmp = tcg_temp_new_i32();
9868 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9869 } else { /* tbb */
9870 tcg_temp_free_i32(tmp);
9871 tmp = tcg_temp_new_i32();
9872 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9874 tcg_temp_free_i32(addr);
9875 tcg_gen_shli_i32(tmp, tmp, 1);
9876 tcg_gen_addi_i32(tmp, tmp, s->pc);
9877 store_reg(s, 15, tmp);
9878 } else {
9879 int op2 = (insn >> 6) & 0x3;
9880 op = (insn >> 4) & 0x3;
9881 switch (op2) {
9882 case 0:
9883 goto illegal_op;
9884 case 1:
9885 /* Load/store exclusive byte/halfword/doubleword */
9886 if (op == 2) {
9887 goto illegal_op;
9889 ARCH(7);
9890 break;
9891 case 2:
9892 /* Load-acquire/store-release */
9893 if (op == 3) {
9894 goto illegal_op;
9896 /* Fall through */
9897 case 3:
9898 /* Load-acquire/store-release exclusive */
9899 ARCH(8);
9900 break;
9902 addr = tcg_temp_local_new_i32();
9903 load_reg_var(s, addr, rn);
9904 if (!(op2 & 1)) {
9905 if (insn & (1 << 20)) {
9906 tmp = tcg_temp_new_i32();
9907 switch (op) {
9908 case 0: /* ldab */
9909 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9910 rs | ISSIsAcqRel);
9911 break;
9912 case 1: /* ldah */
9913 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9914 rs | ISSIsAcqRel);
9915 break;
9916 case 2: /* lda */
9917 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9918 rs | ISSIsAcqRel);
9919 break;
9920 default:
9921 abort();
9923 store_reg(s, rs, tmp);
9924 } else {
9925 tmp = load_reg(s, rs);
9926 switch (op) {
9927 case 0: /* stlb */
9928 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9929 rs | ISSIsAcqRel);
9930 break;
9931 case 1: /* stlh */
9932 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9933 rs | ISSIsAcqRel);
9934 break;
9935 case 2: /* stl */
9936 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9937 rs | ISSIsAcqRel);
9938 break;
9939 default:
9940 abort();
9942 tcg_temp_free_i32(tmp);
9944 } else if (insn & (1 << 20)) {
9945 gen_load_exclusive(s, rs, rd, addr, op);
9946 } else {
9947 gen_store_exclusive(s, rm, rs, rd, addr, op);
9949 tcg_temp_free_i32(addr);
9951 } else {
9952 /* Load/store multiple, RFE, SRS. */
9953 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9954 /* RFE, SRS: not available in user mode or on M profile */
9955 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9956 goto illegal_op;
9958 if (insn & (1 << 20)) {
9959 /* rfe */
9960 addr = load_reg(s, rn);
9961 if ((insn & (1 << 24)) == 0)
9962 tcg_gen_addi_i32(addr, addr, -8);
9963 /* Load PC into tmp and CPSR into tmp2. */
9964 tmp = tcg_temp_new_i32();
9965 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9966 tcg_gen_addi_i32(addr, addr, 4);
9967 tmp2 = tcg_temp_new_i32();
9968 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9969 if (insn & (1 << 21)) {
9970 /* Base writeback. */
9971 if (insn & (1 << 24)) {
9972 tcg_gen_addi_i32(addr, addr, 4);
9973 } else {
9974 tcg_gen_addi_i32(addr, addr, -4);
9976 store_reg(s, rn, addr);
9977 } else {
9978 tcg_temp_free_i32(addr);
9980 gen_rfe(s, tmp, tmp2);
9981 } else {
9982 /* srs */
9983 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9984 insn & (1 << 21));
9986 } else {
9987 int i, loaded_base = 0;
9988 TCGv_i32 loaded_var;
9989 /* Load/store multiple. */
9990 addr = load_reg(s, rn);
9991 offset = 0;
9992 for (i = 0; i < 16; i++) {
9993 if (insn & (1 << i))
9994 offset += 4;
9996 if (insn & (1 << 24)) {
9997 tcg_gen_addi_i32(addr, addr, -offset);
10000 TCGV_UNUSED_I32(loaded_var);
10001 for (i = 0; i < 16; i++) {
10002 if ((insn & (1 << i)) == 0)
10003 continue;
10004 if (insn & (1 << 20)) {
10005 /* Load. */
10006 tmp = tcg_temp_new_i32();
10007 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10008 if (i == 15) {
10009 gen_bx_excret(s, tmp);
10010 } else if (i == rn) {
10011 loaded_var = tmp;
10012 loaded_base = 1;
10013 } else {
10014 store_reg(s, i, tmp);
10016 } else {
10017 /* Store. */
10018 tmp = load_reg(s, i);
10019 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10020 tcg_temp_free_i32(tmp);
10022 tcg_gen_addi_i32(addr, addr, 4);
10024 if (loaded_base) {
10025 store_reg(s, rn, loaded_var);
10027 if (insn & (1 << 21)) {
10028 /* Base register writeback. */
10029 if (insn & (1 << 24)) {
10030 tcg_gen_addi_i32(addr, addr, -offset);
10032 /* Fault if writeback register is in register list. */
10033 if (insn & (1 << rn))
10034 goto illegal_op;
10035 store_reg(s, rn, addr);
10036 } else {
10037 tcg_temp_free_i32(addr);
10041 break;
10042 case 5:
10044 op = (insn >> 21) & 0xf;
10045 if (op == 6) {
10046 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10047 goto illegal_op;
10049 /* Halfword pack. */
10050 tmp = load_reg(s, rn);
10051 tmp2 = load_reg(s, rm);
10052 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10053 if (insn & (1 << 5)) {
10054 /* pkhtb */
10055 if (shift == 0)
10056 shift = 31;
10057 tcg_gen_sari_i32(tmp2, tmp2, shift);
10058 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10059 tcg_gen_ext16u_i32(tmp2, tmp2);
10060 } else {
10061 /* pkhbt */
10062 if (shift)
10063 tcg_gen_shli_i32(tmp2, tmp2, shift);
10064 tcg_gen_ext16u_i32(tmp, tmp);
10065 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10067 tcg_gen_or_i32(tmp, tmp, tmp2);
10068 tcg_temp_free_i32(tmp2);
10069 store_reg(s, rd, tmp);
10070 } else {
10071 /* Data processing register constant shift. */
10072 if (rn == 15) {
10073 tmp = tcg_temp_new_i32();
10074 tcg_gen_movi_i32(tmp, 0);
10075 } else {
10076 tmp = load_reg(s, rn);
10078 tmp2 = load_reg(s, rm);
10080 shiftop = (insn >> 4) & 3;
10081 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10082 conds = (insn & (1 << 20)) != 0;
10083 logic_cc = (conds && thumb2_logic_op(op));
10084 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10085 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10086 goto illegal_op;
10087 tcg_temp_free_i32(tmp2);
10088 if (rd != 15) {
10089 store_reg(s, rd, tmp);
10090 } else {
10091 tcg_temp_free_i32(tmp);
10094 break;
10095 case 13: /* Misc data processing. */
10096 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10097 if (op < 4 && (insn & 0xf000) != 0xf000)
10098 goto illegal_op;
10099 switch (op) {
10100 case 0: /* Register controlled shift. */
10101 tmp = load_reg(s, rn);
10102 tmp2 = load_reg(s, rm);
10103 if ((insn & 0x70) != 0)
10104 goto illegal_op;
10105 op = (insn >> 21) & 3;
10106 logic_cc = (insn & (1 << 20)) != 0;
10107 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10108 if (logic_cc)
10109 gen_logic_CC(tmp);
10110 store_reg(s, rd, tmp);
10111 break;
10112 case 1: /* Sign/zero extend. */
10113 op = (insn >> 20) & 7;
10114 switch (op) {
10115 case 0: /* SXTAH, SXTH */
10116 case 1: /* UXTAH, UXTH */
10117 case 4: /* SXTAB, SXTB */
10118 case 5: /* UXTAB, UXTB */
10119 break;
10120 case 2: /* SXTAB16, SXTB16 */
10121 case 3: /* UXTAB16, UXTB16 */
10122 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10123 goto illegal_op;
10125 break;
10126 default:
10127 goto illegal_op;
10129 if (rn != 15) {
10130 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10131 goto illegal_op;
10134 tmp = load_reg(s, rm);
10135 shift = (insn >> 4) & 3;
10136 /* ??? In many cases it's not necessary to do a
10137 rotate, a shift is sufficient. */
10138 if (shift != 0)
10139 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10140 op = (insn >> 20) & 7;
10141 switch (op) {
10142 case 0: gen_sxth(tmp); break;
10143 case 1: gen_uxth(tmp); break;
10144 case 2: gen_sxtb16(tmp); break;
10145 case 3: gen_uxtb16(tmp); break;
10146 case 4: gen_sxtb(tmp); break;
10147 case 5: gen_uxtb(tmp); break;
10148 default:
10149 g_assert_not_reached();
10151 if (rn != 15) {
10152 tmp2 = load_reg(s, rn);
10153 if ((op >> 1) == 1) {
10154 gen_add16(tmp, tmp2);
10155 } else {
10156 tcg_gen_add_i32(tmp, tmp, tmp2);
10157 tcg_temp_free_i32(tmp2);
10160 store_reg(s, rd, tmp);
10161 break;
10162 case 2: /* SIMD add/subtract. */
10163 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10164 goto illegal_op;
10166 op = (insn >> 20) & 7;
10167 shift = (insn >> 4) & 7;
10168 if ((op & 3) == 3 || (shift & 3) == 3)
10169 goto illegal_op;
10170 tmp = load_reg(s, rn);
10171 tmp2 = load_reg(s, rm);
10172 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10173 tcg_temp_free_i32(tmp2);
10174 store_reg(s, rd, tmp);
10175 break;
10176 case 3: /* Other data processing. */
10177 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10178 if (op < 4) {
10179 /* Saturating add/subtract. */
10180 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10181 goto illegal_op;
10183 tmp = load_reg(s, rn);
10184 tmp2 = load_reg(s, rm);
10185 if (op & 1)
10186 gen_helper_double_saturate(tmp, cpu_env, tmp);
10187 if (op & 2)
10188 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10189 else
10190 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10191 tcg_temp_free_i32(tmp2);
10192 } else {
10193 switch (op) {
10194 case 0x0a: /* rbit */
10195 case 0x08: /* rev */
10196 case 0x09: /* rev16 */
10197 case 0x0b: /* revsh */
10198 case 0x18: /* clz */
10199 break;
10200 case 0x10: /* sel */
10201 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10202 goto illegal_op;
10204 break;
10205 case 0x20: /* crc32/crc32c */
10206 case 0x21:
10207 case 0x22:
10208 case 0x28:
10209 case 0x29:
10210 case 0x2a:
10211 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10212 goto illegal_op;
10214 break;
10215 default:
10216 goto illegal_op;
10218 tmp = load_reg(s, rn);
10219 switch (op) {
10220 case 0x0a: /* rbit */
10221 gen_helper_rbit(tmp, tmp);
10222 break;
10223 case 0x08: /* rev */
10224 tcg_gen_bswap32_i32(tmp, tmp);
10225 break;
10226 case 0x09: /* rev16 */
10227 gen_rev16(tmp);
10228 break;
10229 case 0x0b: /* revsh */
10230 gen_revsh(tmp);
10231 break;
10232 case 0x10: /* sel */
10233 tmp2 = load_reg(s, rm);
10234 tmp3 = tcg_temp_new_i32();
10235 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10236 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10237 tcg_temp_free_i32(tmp3);
10238 tcg_temp_free_i32(tmp2);
10239 break;
10240 case 0x18: /* clz */
10241 tcg_gen_clzi_i32(tmp, tmp, 32);
10242 break;
10243 case 0x20:
10244 case 0x21:
10245 case 0x22:
10246 case 0x28:
10247 case 0x29:
10248 case 0x2a:
10250 /* crc32/crc32c */
10251 uint32_t sz = op & 0x3;
10252 uint32_t c = op & 0x8;
10254 tmp2 = load_reg(s, rm);
10255 if (sz == 0) {
10256 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10257 } else if (sz == 1) {
10258 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10260 tmp3 = tcg_const_i32(1 << sz);
10261 if (c) {
10262 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10263 } else {
10264 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10266 tcg_temp_free_i32(tmp2);
10267 tcg_temp_free_i32(tmp3);
10268 break;
10270 default:
10271 g_assert_not_reached();
10274 store_reg(s, rd, tmp);
10275 break;
10276 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10277 switch ((insn >> 20) & 7) {
10278 case 0: /* 32 x 32 -> 32 */
10279 case 7: /* Unsigned sum of absolute differences. */
10280 break;
10281 case 1: /* 16 x 16 -> 32 */
10282 case 2: /* Dual multiply add. */
10283 case 3: /* 32 * 16 -> 32msb */
10284 case 4: /* Dual multiply subtract. */
10285 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10286 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10287 goto illegal_op;
10289 break;
10291 op = (insn >> 4) & 0xf;
10292 tmp = load_reg(s, rn);
10293 tmp2 = load_reg(s, rm);
10294 switch ((insn >> 20) & 7) {
10295 case 0: /* 32 x 32 -> 32 */
10296 tcg_gen_mul_i32(tmp, tmp, tmp2);
10297 tcg_temp_free_i32(tmp2);
10298 if (rs != 15) {
10299 tmp2 = load_reg(s, rs);
10300 if (op)
10301 tcg_gen_sub_i32(tmp, tmp2, tmp);
10302 else
10303 tcg_gen_add_i32(tmp, tmp, tmp2);
10304 tcg_temp_free_i32(tmp2);
10306 break;
10307 case 1: /* 16 x 16 -> 32 */
10308 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10309 tcg_temp_free_i32(tmp2);
10310 if (rs != 15) {
10311 tmp2 = load_reg(s, rs);
10312 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10313 tcg_temp_free_i32(tmp2);
10315 break;
10316 case 2: /* Dual multiply add. */
10317 case 4: /* Dual multiply subtract. */
10318 if (op)
10319 gen_swap_half(tmp2);
10320 gen_smul_dual(tmp, tmp2);
10321 if (insn & (1 << 22)) {
10322 /* This subtraction cannot overflow. */
10323 tcg_gen_sub_i32(tmp, tmp, tmp2);
10324 } else {
10325 /* This addition cannot overflow 32 bits;
10326 * however it may overflow considered as a signed
10327 * operation, in which case we must set the Q flag.
10329 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10331 tcg_temp_free_i32(tmp2);
10332 if (rs != 15)
10334 tmp2 = load_reg(s, rs);
10335 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10336 tcg_temp_free_i32(tmp2);
10338 break;
10339 case 3: /* 32 * 16 -> 32msb */
10340 if (op)
10341 tcg_gen_sari_i32(tmp2, tmp2, 16);
10342 else
10343 gen_sxth(tmp2);
10344 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10345 tcg_gen_shri_i64(tmp64, tmp64, 16);
10346 tmp = tcg_temp_new_i32();
10347 tcg_gen_extrl_i64_i32(tmp, tmp64);
10348 tcg_temp_free_i64(tmp64);
10349 if (rs != 15)
10351 tmp2 = load_reg(s, rs);
10352 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10353 tcg_temp_free_i32(tmp2);
10355 break;
10356 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10357 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10358 if (rs != 15) {
10359 tmp = load_reg(s, rs);
10360 if (insn & (1 << 20)) {
10361 tmp64 = gen_addq_msw(tmp64, tmp);
10362 } else {
10363 tmp64 = gen_subq_msw(tmp64, tmp);
10366 if (insn & (1 << 4)) {
10367 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10369 tcg_gen_shri_i64(tmp64, tmp64, 32);
10370 tmp = tcg_temp_new_i32();
10371 tcg_gen_extrl_i64_i32(tmp, tmp64);
10372 tcg_temp_free_i64(tmp64);
10373 break;
10374 case 7: /* Unsigned sum of absolute differences. */
10375 gen_helper_usad8(tmp, tmp, tmp2);
10376 tcg_temp_free_i32(tmp2);
10377 if (rs != 15) {
10378 tmp2 = load_reg(s, rs);
10379 tcg_gen_add_i32(tmp, tmp, tmp2);
10380 tcg_temp_free_i32(tmp2);
10382 break;
10384 store_reg(s, rd, tmp);
10385 break;
10386 case 6: case 7: /* 64-bit multiply, Divide. */
10387 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10388 tmp = load_reg(s, rn);
10389 tmp2 = load_reg(s, rm);
10390 if ((op & 0x50) == 0x10) {
10391 /* sdiv, udiv */
10392 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10393 goto illegal_op;
10395 if (op & 0x20)
10396 gen_helper_udiv(tmp, tmp, tmp2);
10397 else
10398 gen_helper_sdiv(tmp, tmp, tmp2);
10399 tcg_temp_free_i32(tmp2);
10400 store_reg(s, rd, tmp);
10401 } else if ((op & 0xe) == 0xc) {
10402 /* Dual multiply accumulate long. */
10403 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10404 tcg_temp_free_i32(tmp);
10405 tcg_temp_free_i32(tmp2);
10406 goto illegal_op;
10408 if (op & 1)
10409 gen_swap_half(tmp2);
10410 gen_smul_dual(tmp, tmp2);
10411 if (op & 0x10) {
10412 tcg_gen_sub_i32(tmp, tmp, tmp2);
10413 } else {
10414 tcg_gen_add_i32(tmp, tmp, tmp2);
10416 tcg_temp_free_i32(tmp2);
10417 /* BUGFIX */
10418 tmp64 = tcg_temp_new_i64();
10419 tcg_gen_ext_i32_i64(tmp64, tmp);
10420 tcg_temp_free_i32(tmp);
10421 gen_addq(s, tmp64, rs, rd);
10422 gen_storeq_reg(s, rs, rd, tmp64);
10423 tcg_temp_free_i64(tmp64);
10424 } else {
10425 if (op & 0x20) {
10426 /* Unsigned 64-bit multiply */
10427 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10428 } else {
10429 if (op & 8) {
10430 /* smlalxy */
10431 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10432 tcg_temp_free_i32(tmp2);
10433 tcg_temp_free_i32(tmp);
10434 goto illegal_op;
10436 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10437 tcg_temp_free_i32(tmp2);
10438 tmp64 = tcg_temp_new_i64();
10439 tcg_gen_ext_i32_i64(tmp64, tmp);
10440 tcg_temp_free_i32(tmp);
10441 } else {
10442 /* Signed 64-bit multiply */
10443 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10446 if (op & 4) {
10447 /* umaal */
10448 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10449 tcg_temp_free_i64(tmp64);
10450 goto illegal_op;
10452 gen_addq_lo(s, tmp64, rs);
10453 gen_addq_lo(s, tmp64, rd);
10454 } else if (op & 0x40) {
10455 /* 64-bit accumulate. */
10456 gen_addq(s, tmp64, rs, rd);
10458 gen_storeq_reg(s, rs, rd, tmp64);
10459 tcg_temp_free_i64(tmp64);
10461 break;
10463 break;
10464 case 6: case 7: case 14: case 15:
10465 /* Coprocessor. */
10466 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10467 /* We don't currently implement M profile FP support,
10468 * so this entire space should give a NOCP fault.
10470 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10471 default_exception_el(s));
10472 break;
10474 if (((insn >> 24) & 3) == 3) {
10475 /* Translate into the equivalent ARM encoding. */
10476 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10477 if (disas_neon_data_insn(s, insn)) {
10478 goto illegal_op;
10480 } else if (((insn >> 8) & 0xe) == 10) {
10481 if (disas_vfp_insn(s, insn)) {
10482 goto illegal_op;
10484 } else {
10485 if (insn & (1 << 28))
10486 goto illegal_op;
10487 if (disas_coproc_insn(s, insn)) {
10488 goto illegal_op;
10491 break;
10492 case 8: case 9: case 10: case 11:
10493 if (insn & (1 << 15)) {
10494 /* Branches, misc control. */
10495 if (insn & 0x5000) {
10496 /* Unconditional branch. */
10497 /* signextend(hw1[10:0]) -> offset[:12]. */
10498 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10499 /* hw1[10:0] -> offset[11:1]. */
10500 offset |= (insn & 0x7ff) << 1;
10501 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10502 offset[24:22] already have the same value because of the
10503 sign extension above. */
10504 offset ^= ((~insn) & (1 << 13)) << 10;
10505 offset ^= ((~insn) & (1 << 11)) << 11;
10507 if (insn & (1 << 14)) {
10508 /* Branch and link. */
10509 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10512 offset += s->pc;
10513 if (insn & (1 << 12)) {
10514 /* b/bl */
10515 gen_jmp(s, offset);
10516 } else {
10517 /* blx */
10518 offset &= ~(uint32_t)2;
10519 /* thumb2 bx, no need to check */
10520 gen_bx_im(s, offset);
10522 } else if (((insn >> 23) & 7) == 7) {
10523 /* Misc control */
10524 if (insn & (1 << 13))
10525 goto illegal_op;
10527 if (insn & (1 << 26)) {
10528 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10529 goto illegal_op;
10531 if (!(insn & (1 << 20))) {
10532 /* Hypervisor call (v7) */
10533 int imm16 = extract32(insn, 16, 4) << 12
10534 | extract32(insn, 0, 12);
10535 ARCH(7);
10536 if (IS_USER(s)) {
10537 goto illegal_op;
10539 gen_hvc(s, imm16);
10540 } else {
10541 /* Secure monitor call (v6+) */
10542 ARCH(6K);
10543 if (IS_USER(s)) {
10544 goto illegal_op;
10546 gen_smc(s);
10548 } else {
10549 op = (insn >> 20) & 7;
10550 switch (op) {
10551 case 0: /* msr cpsr. */
10552 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10553 tmp = load_reg(s, rn);
10554 /* the constant is the mask and SYSm fields */
10555 addr = tcg_const_i32(insn & 0xfff);
10556 gen_helper_v7m_msr(cpu_env, addr, tmp);
10557 tcg_temp_free_i32(addr);
10558 tcg_temp_free_i32(tmp);
10559 gen_lookup_tb(s);
10560 break;
10562 /* fall through */
10563 case 1: /* msr spsr. */
10564 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10565 goto illegal_op;
10568 if (extract32(insn, 5, 1)) {
10569 /* MSR (banked) */
10570 int sysm = extract32(insn, 8, 4) |
10571 (extract32(insn, 4, 1) << 4);
10572 int r = op & 1;
10574 gen_msr_banked(s, r, sysm, rm);
10575 break;
10578 /* MSR (for PSRs) */
10579 tmp = load_reg(s, rn);
10580 if (gen_set_psr(s,
10581 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10582 op == 1, tmp))
10583 goto illegal_op;
10584 break;
10585 case 2: /* cps, nop-hint. */
10586 if (((insn >> 8) & 7) == 0) {
10587 gen_nop_hint(s, insn & 0xff);
10589 /* Implemented as NOP in user mode. */
10590 if (IS_USER(s))
10591 break;
10592 offset = 0;
10593 imm = 0;
10594 if (insn & (1 << 10)) {
10595 if (insn & (1 << 7))
10596 offset |= CPSR_A;
10597 if (insn & (1 << 6))
10598 offset |= CPSR_I;
10599 if (insn & (1 << 5))
10600 offset |= CPSR_F;
10601 if (insn & (1 << 9))
10602 imm = CPSR_A | CPSR_I | CPSR_F;
10604 if (insn & (1 << 8)) {
10605 offset |= 0x1f;
10606 imm |= (insn & 0x1f);
10608 if (offset) {
10609 gen_set_psr_im(s, offset, 0, imm);
10611 break;
10612 case 3: /* Special control operations. */
10613 ARCH(7);
10614 op = (insn >> 4) & 0xf;
10615 switch (op) {
10616 case 2: /* clrex */
10617 gen_clrex(s);
10618 break;
10619 case 4: /* dsb */
10620 case 5: /* dmb */
10621 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10622 break;
10623 case 6: /* isb */
10624 /* We need to break the TB after this insn
10625 * to execute self-modifying code correctly
10626 * and also to take any pending interrupts
10627 * immediately.
10629 gen_goto_tb(s, 0, s->pc & ~1);
10630 break;
10631 default:
10632 goto illegal_op;
10634 break;
10635 case 4: /* bxj */
10636 /* Trivial implementation equivalent to bx.
10637 * This instruction doesn't exist at all for M-profile.
10639 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10640 goto illegal_op;
10642 tmp = load_reg(s, rn);
10643 gen_bx(s, tmp);
10644 break;
10645 case 5: /* Exception return. */
10646 if (IS_USER(s)) {
10647 goto illegal_op;
10649 if (rn != 14 || rd != 15) {
10650 goto illegal_op;
10652 tmp = load_reg(s, rn);
10653 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10654 gen_exception_return(s, tmp);
10655 break;
10656 case 6: /* MRS */
10657 if (extract32(insn, 5, 1) &&
10658 !arm_dc_feature(s, ARM_FEATURE_M)) {
10659 /* MRS (banked) */
10660 int sysm = extract32(insn, 16, 4) |
10661 (extract32(insn, 4, 1) << 4);
10663 gen_mrs_banked(s, 0, sysm, rd);
10664 break;
10667 if (extract32(insn, 16, 4) != 0xf) {
10668 goto illegal_op;
10670 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10671 extract32(insn, 0, 8) != 0) {
10672 goto illegal_op;
10675 /* mrs cpsr */
10676 tmp = tcg_temp_new_i32();
10677 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10678 addr = tcg_const_i32(insn & 0xff);
10679 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10680 tcg_temp_free_i32(addr);
10681 } else {
10682 gen_helper_cpsr_read(tmp, cpu_env);
10684 store_reg(s, rd, tmp);
10685 break;
10686 case 7: /* MRS */
10687 if (extract32(insn, 5, 1) &&
10688 !arm_dc_feature(s, ARM_FEATURE_M)) {
10689 /* MRS (banked) */
10690 int sysm = extract32(insn, 16, 4) |
10691 (extract32(insn, 4, 1) << 4);
10693 gen_mrs_banked(s, 1, sysm, rd);
10694 break;
10697 /* mrs spsr. */
10698 /* Not accessible in user mode. */
10699 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10700 goto illegal_op;
10703 if (extract32(insn, 16, 4) != 0xf ||
10704 extract32(insn, 0, 8) != 0) {
10705 goto illegal_op;
10708 tmp = load_cpu_field(spsr);
10709 store_reg(s, rd, tmp);
10710 break;
10713 } else {
10714 /* Conditional branch. */
10715 op = (insn >> 22) & 0xf;
10716 /* Generate a conditional jump to next instruction. */
10717 s->condlabel = gen_new_label();
10718 arm_gen_test_cc(op ^ 1, s->condlabel);
10719 s->condjmp = 1;
10721 /* offset[11:1] = insn[10:0] */
10722 offset = (insn & 0x7ff) << 1;
10723 /* offset[17:12] = insn[21:16]. */
10724 offset |= (insn & 0x003f0000) >> 4;
10725 /* offset[31:20] = insn[26]. */
10726 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10727 /* offset[18] = insn[13]. */
10728 offset |= (insn & (1 << 13)) << 5;
10729 /* offset[19] = insn[11]. */
10730 offset |= (insn & (1 << 11)) << 8;
10732 /* jump to the offset */
10733 gen_jmp(s, s->pc + offset);
10735 } else {
10736 /* Data processing immediate. */
10737 if (insn & (1 << 25)) {
10738 if (insn & (1 << 24)) {
10739 if (insn & (1 << 20))
10740 goto illegal_op;
10741 /* Bitfield/Saturate. */
10742 op = (insn >> 21) & 7;
10743 imm = insn & 0x1f;
10744 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10745 if (rn == 15) {
10746 tmp = tcg_temp_new_i32();
10747 tcg_gen_movi_i32(tmp, 0);
10748 } else {
10749 tmp = load_reg(s, rn);
10751 switch (op) {
10752 case 2: /* Signed bitfield extract. */
10753 imm++;
10754 if (shift + imm > 32)
10755 goto illegal_op;
10756 if (imm < 32) {
10757 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10759 break;
10760 case 6: /* Unsigned bitfield extract. */
10761 imm++;
10762 if (shift + imm > 32)
10763 goto illegal_op;
10764 if (imm < 32) {
10765 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10767 break;
10768 case 3: /* Bitfield insert/clear. */
10769 if (imm < shift)
10770 goto illegal_op;
10771 imm = imm + 1 - shift;
10772 if (imm != 32) {
10773 tmp2 = load_reg(s, rd);
10774 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10775 tcg_temp_free_i32(tmp2);
10777 break;
10778 case 7:
10779 goto illegal_op;
10780 default: /* Saturate. */
10781 if (shift) {
10782 if (op & 1)
10783 tcg_gen_sari_i32(tmp, tmp, shift);
10784 else
10785 tcg_gen_shli_i32(tmp, tmp, shift);
10787 tmp2 = tcg_const_i32(imm);
10788 if (op & 4) {
10789 /* Unsigned. */
10790 if ((op & 1) && shift == 0) {
10791 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10792 tcg_temp_free_i32(tmp);
10793 tcg_temp_free_i32(tmp2);
10794 goto illegal_op;
10796 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10797 } else {
10798 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10800 } else {
10801 /* Signed. */
10802 if ((op & 1) && shift == 0) {
10803 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10804 tcg_temp_free_i32(tmp);
10805 tcg_temp_free_i32(tmp2);
10806 goto illegal_op;
10808 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10809 } else {
10810 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10813 tcg_temp_free_i32(tmp2);
10814 break;
10816 store_reg(s, rd, tmp);
10817 } else {
10818 imm = ((insn & 0x04000000) >> 15)
10819 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10820 if (insn & (1 << 22)) {
10821 /* 16-bit immediate. */
10822 imm |= (insn >> 4) & 0xf000;
10823 if (insn & (1 << 23)) {
10824 /* movt */
10825 tmp = load_reg(s, rd);
10826 tcg_gen_ext16u_i32(tmp, tmp);
10827 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10828 } else {
10829 /* movw */
10830 tmp = tcg_temp_new_i32();
10831 tcg_gen_movi_i32(tmp, imm);
10833 } else {
10834 /* Add/sub 12-bit immediate. */
10835 if (rn == 15) {
10836 offset = s->pc & ~(uint32_t)3;
10837 if (insn & (1 << 23))
10838 offset -= imm;
10839 else
10840 offset += imm;
10841 tmp = tcg_temp_new_i32();
10842 tcg_gen_movi_i32(tmp, offset);
10843 } else {
10844 tmp = load_reg(s, rn);
10845 if (insn & (1 << 23))
10846 tcg_gen_subi_i32(tmp, tmp, imm);
10847 else
10848 tcg_gen_addi_i32(tmp, tmp, imm);
10851 store_reg(s, rd, tmp);
10853 } else {
10854 int shifter_out = 0;
10855 /* modified 12-bit immediate. */
10856 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10857 imm = (insn & 0xff);
10858 switch (shift) {
10859 case 0: /* XY */
10860 /* Nothing to do. */
10861 break;
10862 case 1: /* 00XY00XY */
10863 imm |= imm << 16;
10864 break;
10865 case 2: /* XY00XY00 */
10866 imm |= imm << 16;
10867 imm <<= 8;
10868 break;
10869 case 3: /* XYXYXYXY */
10870 imm |= imm << 16;
10871 imm |= imm << 8;
10872 break;
10873 default: /* Rotated constant. */
10874 shift = (shift << 1) | (imm >> 7);
10875 imm |= 0x80;
10876 imm = imm << (32 - shift);
10877 shifter_out = 1;
10878 break;
10880 tmp2 = tcg_temp_new_i32();
10881 tcg_gen_movi_i32(tmp2, imm);
10882 rn = (insn >> 16) & 0xf;
10883 if (rn == 15) {
10884 tmp = tcg_temp_new_i32();
10885 tcg_gen_movi_i32(tmp, 0);
10886 } else {
10887 tmp = load_reg(s, rn);
10889 op = (insn >> 21) & 0xf;
10890 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10891 shifter_out, tmp, tmp2))
10892 goto illegal_op;
10893 tcg_temp_free_i32(tmp2);
10894 rd = (insn >> 8) & 0xf;
10895 if (rd != 15) {
10896 store_reg(s, rd, tmp);
10897 } else {
10898 tcg_temp_free_i32(tmp);
10902 break;
10903 case 12: /* Load/store single data item. */
10905 int postinc = 0;
10906 int writeback = 0;
10907 int memidx;
10908 ISSInfo issinfo;
10910 if ((insn & 0x01100000) == 0x01000000) {
10911 if (disas_neon_ls_insn(s, insn)) {
10912 goto illegal_op;
10914 break;
10916 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10917 if (rs == 15) {
10918 if (!(insn & (1 << 20))) {
10919 goto illegal_op;
10921 if (op != 2) {
10922 /* Byte or halfword load space with dest == r15 : memory hints.
10923 * Catch them early so we don't emit pointless addressing code.
10924 * This space is a mix of:
10925 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10926 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10927 * cores)
10928 * unallocated hints, which must be treated as NOPs
10929 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10930 * which is easiest for the decoding logic
10931 * Some space which must UNDEF
10933 int op1 = (insn >> 23) & 3;
10934 int op2 = (insn >> 6) & 0x3f;
10935 if (op & 2) {
10936 goto illegal_op;
10938 if (rn == 15) {
10939 /* UNPREDICTABLE, unallocated hint or
10940 * PLD/PLDW/PLI (literal)
10942 return 0;
10944 if (op1 & 1) {
10945 return 0; /* PLD/PLDW/PLI or unallocated hint */
10947 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10948 return 0; /* PLD/PLDW/PLI or unallocated hint */
10950 /* UNDEF space, or an UNPREDICTABLE */
10951 return 1;
10954 memidx = get_mem_index(s);
10955 if (rn == 15) {
10956 addr = tcg_temp_new_i32();
10957 /* PC relative. */
10958 /* s->pc has already been incremented by 4. */
10959 imm = s->pc & 0xfffffffc;
10960 if (insn & (1 << 23))
10961 imm += insn & 0xfff;
10962 else
10963 imm -= insn & 0xfff;
10964 tcg_gen_movi_i32(addr, imm);
10965 } else {
10966 addr = load_reg(s, rn);
10967 if (insn & (1 << 23)) {
10968 /* Positive offset. */
10969 imm = insn & 0xfff;
10970 tcg_gen_addi_i32(addr, addr, imm);
10971 } else {
10972 imm = insn & 0xff;
10973 switch ((insn >> 8) & 0xf) {
10974 case 0x0: /* Shifted Register. */
10975 shift = (insn >> 4) & 0xf;
10976 if (shift > 3) {
10977 tcg_temp_free_i32(addr);
10978 goto illegal_op;
10980 tmp = load_reg(s, rm);
10981 if (shift)
10982 tcg_gen_shli_i32(tmp, tmp, shift);
10983 tcg_gen_add_i32(addr, addr, tmp);
10984 tcg_temp_free_i32(tmp);
10985 break;
10986 case 0xc: /* Negative offset. */
10987 tcg_gen_addi_i32(addr, addr, -imm);
10988 break;
10989 case 0xe: /* User privilege. */
10990 tcg_gen_addi_i32(addr, addr, imm);
10991 memidx = get_a32_user_mem_index(s);
10992 break;
10993 case 0x9: /* Post-decrement. */
10994 imm = -imm;
10995 /* Fall through. */
10996 case 0xb: /* Post-increment. */
10997 postinc = 1;
10998 writeback = 1;
10999 break;
11000 case 0xd: /* Pre-decrement. */
11001 imm = -imm;
11002 /* Fall through. */
11003 case 0xf: /* Pre-increment. */
11004 tcg_gen_addi_i32(addr, addr, imm);
11005 writeback = 1;
11006 break;
11007 default:
11008 tcg_temp_free_i32(addr);
11009 goto illegal_op;
11014 issinfo = writeback ? ISSInvalid : rs;
11016 if (insn & (1 << 20)) {
11017 /* Load. */
11018 tmp = tcg_temp_new_i32();
11019 switch (op) {
11020 case 0:
11021 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11022 break;
11023 case 4:
11024 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11025 break;
11026 case 1:
11027 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11028 break;
11029 case 5:
11030 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11031 break;
11032 case 2:
11033 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11034 break;
11035 default:
11036 tcg_temp_free_i32(tmp);
11037 tcg_temp_free_i32(addr);
11038 goto illegal_op;
11040 if (rs == 15) {
11041 gen_bx_excret(s, tmp);
11042 } else {
11043 store_reg(s, rs, tmp);
11045 } else {
11046 /* Store. */
11047 tmp = load_reg(s, rs);
11048 switch (op) {
11049 case 0:
11050 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11051 break;
11052 case 1:
11053 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11054 break;
11055 case 2:
11056 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11057 break;
11058 default:
11059 tcg_temp_free_i32(tmp);
11060 tcg_temp_free_i32(addr);
11061 goto illegal_op;
11063 tcg_temp_free_i32(tmp);
11065 if (postinc)
11066 tcg_gen_addi_i32(addr, addr, imm);
11067 if (writeback) {
11068 store_reg(s, rn, addr);
11069 } else {
11070 tcg_temp_free_i32(addr);
11073 break;
11074 default:
11075 goto illegal_op;
11077 return 0;
11078 illegal_op:
11079 return 1;
11082 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
11084 uint32_t val, insn, op, rm, rn, rd, shift, cond;
11085 int32_t offset;
11086 int i;
11087 TCGv_i32 tmp;
11088 TCGv_i32 tmp2;
11089 TCGv_i32 addr;
11091 if (s->condexec_mask) {
11092 cond = s->condexec_cond;
11093 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
11094 s->condlabel = gen_new_label();
11095 arm_gen_test_cc(cond ^ 1, s->condlabel);
11096 s->condjmp = 1;
11100 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11101 s->pc += 2;
11103 switch (insn >> 12) {
11104 case 0: case 1:
11106 rd = insn & 7;
11107 op = (insn >> 11) & 3;
11108 if (op == 3) {
11109 /* add/subtract */
11110 rn = (insn >> 3) & 7;
11111 tmp = load_reg(s, rn);
11112 if (insn & (1 << 10)) {
11113 /* immediate */
11114 tmp2 = tcg_temp_new_i32();
11115 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11116 } else {
11117 /* reg */
11118 rm = (insn >> 6) & 7;
11119 tmp2 = load_reg(s, rm);
11121 if (insn & (1 << 9)) {
11122 if (s->condexec_mask)
11123 tcg_gen_sub_i32(tmp, tmp, tmp2);
11124 else
11125 gen_sub_CC(tmp, tmp, tmp2);
11126 } else {
11127 if (s->condexec_mask)
11128 tcg_gen_add_i32(tmp, tmp, tmp2);
11129 else
11130 gen_add_CC(tmp, tmp, tmp2);
11132 tcg_temp_free_i32(tmp2);
11133 store_reg(s, rd, tmp);
11134 } else {
11135 /* shift immediate */
11136 rm = (insn >> 3) & 7;
11137 shift = (insn >> 6) & 0x1f;
11138 tmp = load_reg(s, rm);
11139 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11140 if (!s->condexec_mask)
11141 gen_logic_CC(tmp);
11142 store_reg(s, rd, tmp);
11144 break;
11145 case 2: case 3:
11146 /* arithmetic large immediate */
11147 op = (insn >> 11) & 3;
11148 rd = (insn >> 8) & 0x7;
11149 if (op == 0) { /* mov */
11150 tmp = tcg_temp_new_i32();
11151 tcg_gen_movi_i32(tmp, insn & 0xff);
11152 if (!s->condexec_mask)
11153 gen_logic_CC(tmp);
11154 store_reg(s, rd, tmp);
11155 } else {
11156 tmp = load_reg(s, rd);
11157 tmp2 = tcg_temp_new_i32();
11158 tcg_gen_movi_i32(tmp2, insn & 0xff);
11159 switch (op) {
11160 case 1: /* cmp */
11161 gen_sub_CC(tmp, tmp, tmp2);
11162 tcg_temp_free_i32(tmp);
11163 tcg_temp_free_i32(tmp2);
11164 break;
11165 case 2: /* add */
11166 if (s->condexec_mask)
11167 tcg_gen_add_i32(tmp, tmp, tmp2);
11168 else
11169 gen_add_CC(tmp, tmp, tmp2);
11170 tcg_temp_free_i32(tmp2);
11171 store_reg(s, rd, tmp);
11172 break;
11173 case 3: /* sub */
11174 if (s->condexec_mask)
11175 tcg_gen_sub_i32(tmp, tmp, tmp2);
11176 else
11177 gen_sub_CC(tmp, tmp, tmp2);
11178 tcg_temp_free_i32(tmp2);
11179 store_reg(s, rd, tmp);
11180 break;
11183 break;
11184 case 4:
11185 if (insn & (1 << 11)) {
11186 rd = (insn >> 8) & 7;
11187 /* load pc-relative. Bit 1 of PC is ignored. */
11188 val = s->pc + 2 + ((insn & 0xff) * 4);
11189 val &= ~(uint32_t)2;
11190 addr = tcg_temp_new_i32();
11191 tcg_gen_movi_i32(addr, val);
11192 tmp = tcg_temp_new_i32();
11193 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11194 rd | ISSIs16Bit);
11195 tcg_temp_free_i32(addr);
11196 store_reg(s, rd, tmp);
11197 break;
11199 if (insn & (1 << 10)) {
11200 /* 0b0100_01xx_xxxx_xxxx
11201 * - data processing extended, branch and exchange
11203 rd = (insn & 7) | ((insn >> 4) & 8);
11204 rm = (insn >> 3) & 0xf;
11205 op = (insn >> 8) & 3;
11206 switch (op) {
11207 case 0: /* add */
11208 tmp = load_reg(s, rd);
11209 tmp2 = load_reg(s, rm);
11210 tcg_gen_add_i32(tmp, tmp, tmp2);
11211 tcg_temp_free_i32(tmp2);
11212 store_reg(s, rd, tmp);
11213 break;
11214 case 1: /* cmp */
11215 tmp = load_reg(s, rd);
11216 tmp2 = load_reg(s, rm);
11217 gen_sub_CC(tmp, tmp, tmp2);
11218 tcg_temp_free_i32(tmp2);
11219 tcg_temp_free_i32(tmp);
11220 break;
11221 case 2: /* mov/cpy */
11222 tmp = load_reg(s, rm);
11223 store_reg(s, rd, tmp);
11224 break;
11225 case 3:
11227 /* 0b0100_0111_xxxx_xxxx
11228 * - branch [and link] exchange thumb register
11230 bool link = insn & (1 << 7);
11232 if (insn & 3) {
11233 goto undef;
11235 if (link) {
11236 ARCH(5);
11238 if ((insn & 4)) {
11239 /* BXNS/BLXNS: only exists for v8M with the
11240 * security extensions, and always UNDEF if NonSecure.
11241 * We don't implement these in the user-only mode
11242 * either (in theory you can use them from Secure User
11243 * mode but they are too tied in to system emulation.)
11245 if (!s->v8m_secure || IS_USER_ONLY) {
11246 goto undef;
11248 if (link) {
11249 gen_blxns(s, rm);
11250 } else {
11251 gen_bxns(s, rm);
11253 break;
11255 /* BLX/BX */
11256 tmp = load_reg(s, rm);
11257 if (link) {
11258 val = (uint32_t)s->pc | 1;
11259 tmp2 = tcg_temp_new_i32();
11260 tcg_gen_movi_i32(tmp2, val);
11261 store_reg(s, 14, tmp2);
11262 gen_bx(s, tmp);
11263 } else {
11264 /* Only BX works as exception-return, not BLX */
11265 gen_bx_excret(s, tmp);
11267 break;
11270 break;
11273 /* data processing register */
11274 rd = insn & 7;
11275 rm = (insn >> 3) & 7;
11276 op = (insn >> 6) & 0xf;
11277 if (op == 2 || op == 3 || op == 4 || op == 7) {
11278 /* the shift/rotate ops want the operands backwards */
11279 val = rm;
11280 rm = rd;
11281 rd = val;
11282 val = 1;
11283 } else {
11284 val = 0;
11287 if (op == 9) { /* neg */
11288 tmp = tcg_temp_new_i32();
11289 tcg_gen_movi_i32(tmp, 0);
11290 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11291 tmp = load_reg(s, rd);
11292 } else {
11293 TCGV_UNUSED_I32(tmp);
11296 tmp2 = load_reg(s, rm);
11297 switch (op) {
11298 case 0x0: /* and */
11299 tcg_gen_and_i32(tmp, tmp, tmp2);
11300 if (!s->condexec_mask)
11301 gen_logic_CC(tmp);
11302 break;
11303 case 0x1: /* eor */
11304 tcg_gen_xor_i32(tmp, tmp, tmp2);
11305 if (!s->condexec_mask)
11306 gen_logic_CC(tmp);
11307 break;
11308 case 0x2: /* lsl */
11309 if (s->condexec_mask) {
11310 gen_shl(tmp2, tmp2, tmp);
11311 } else {
11312 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11313 gen_logic_CC(tmp2);
11315 break;
11316 case 0x3: /* lsr */
11317 if (s->condexec_mask) {
11318 gen_shr(tmp2, tmp2, tmp);
11319 } else {
11320 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11321 gen_logic_CC(tmp2);
11323 break;
11324 case 0x4: /* asr */
11325 if (s->condexec_mask) {
11326 gen_sar(tmp2, tmp2, tmp);
11327 } else {
11328 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11329 gen_logic_CC(tmp2);
11331 break;
11332 case 0x5: /* adc */
11333 if (s->condexec_mask) {
11334 gen_adc(tmp, tmp2);
11335 } else {
11336 gen_adc_CC(tmp, tmp, tmp2);
11338 break;
11339 case 0x6: /* sbc */
11340 if (s->condexec_mask) {
11341 gen_sub_carry(tmp, tmp, tmp2);
11342 } else {
11343 gen_sbc_CC(tmp, tmp, tmp2);
11345 break;
11346 case 0x7: /* ror */
11347 if (s->condexec_mask) {
11348 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11349 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11350 } else {
11351 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11352 gen_logic_CC(tmp2);
11354 break;
11355 case 0x8: /* tst */
11356 tcg_gen_and_i32(tmp, tmp, tmp2);
11357 gen_logic_CC(tmp);
11358 rd = 16;
11359 break;
11360 case 0x9: /* neg */
11361 if (s->condexec_mask)
11362 tcg_gen_neg_i32(tmp, tmp2);
11363 else
11364 gen_sub_CC(tmp, tmp, tmp2);
11365 break;
11366 case 0xa: /* cmp */
11367 gen_sub_CC(tmp, tmp, tmp2);
11368 rd = 16;
11369 break;
11370 case 0xb: /* cmn */
11371 gen_add_CC(tmp, tmp, tmp2);
11372 rd = 16;
11373 break;
11374 case 0xc: /* orr */
11375 tcg_gen_or_i32(tmp, tmp, tmp2);
11376 if (!s->condexec_mask)
11377 gen_logic_CC(tmp);
11378 break;
11379 case 0xd: /* mul */
11380 tcg_gen_mul_i32(tmp, tmp, tmp2);
11381 if (!s->condexec_mask)
11382 gen_logic_CC(tmp);
11383 break;
11384 case 0xe: /* bic */
11385 tcg_gen_andc_i32(tmp, tmp, tmp2);
11386 if (!s->condexec_mask)
11387 gen_logic_CC(tmp);
11388 break;
11389 case 0xf: /* mvn */
11390 tcg_gen_not_i32(tmp2, tmp2);
11391 if (!s->condexec_mask)
11392 gen_logic_CC(tmp2);
11393 val = 1;
11394 rm = rd;
11395 break;
11397 if (rd != 16) {
11398 if (val) {
11399 store_reg(s, rm, tmp2);
11400 if (op != 0xf)
11401 tcg_temp_free_i32(tmp);
11402 } else {
11403 store_reg(s, rd, tmp);
11404 tcg_temp_free_i32(tmp2);
11406 } else {
11407 tcg_temp_free_i32(tmp);
11408 tcg_temp_free_i32(tmp2);
11410 break;
11412 case 5:
11413 /* load/store register offset. */
11414 rd = insn & 7;
11415 rn = (insn >> 3) & 7;
11416 rm = (insn >> 6) & 7;
11417 op = (insn >> 9) & 7;
11418 addr = load_reg(s, rn);
11419 tmp = load_reg(s, rm);
11420 tcg_gen_add_i32(addr, addr, tmp);
11421 tcg_temp_free_i32(tmp);
11423 if (op < 3) { /* store */
11424 tmp = load_reg(s, rd);
11425 } else {
11426 tmp = tcg_temp_new_i32();
11429 switch (op) {
11430 case 0: /* str */
11431 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11432 break;
11433 case 1: /* strh */
11434 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11435 break;
11436 case 2: /* strb */
11437 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11438 break;
11439 case 3: /* ldrsb */
11440 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11441 break;
11442 case 4: /* ldr */
11443 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11444 break;
11445 case 5: /* ldrh */
11446 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11447 break;
11448 case 6: /* ldrb */
11449 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11450 break;
11451 case 7: /* ldrsh */
11452 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11453 break;
11455 if (op >= 3) { /* load */
11456 store_reg(s, rd, tmp);
11457 } else {
11458 tcg_temp_free_i32(tmp);
11460 tcg_temp_free_i32(addr);
11461 break;
11463 case 6:
11464 /* load/store word immediate offset */
11465 rd = insn & 7;
11466 rn = (insn >> 3) & 7;
11467 addr = load_reg(s, rn);
11468 val = (insn >> 4) & 0x7c;
11469 tcg_gen_addi_i32(addr, addr, val);
11471 if (insn & (1 << 11)) {
11472 /* load */
11473 tmp = tcg_temp_new_i32();
11474 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11475 store_reg(s, rd, tmp);
11476 } else {
11477 /* store */
11478 tmp = load_reg(s, rd);
11479 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11480 tcg_temp_free_i32(tmp);
11482 tcg_temp_free_i32(addr);
11483 break;
11485 case 7:
11486 /* load/store byte immediate offset */
11487 rd = insn & 7;
11488 rn = (insn >> 3) & 7;
11489 addr = load_reg(s, rn);
11490 val = (insn >> 6) & 0x1f;
11491 tcg_gen_addi_i32(addr, addr, val);
11493 if (insn & (1 << 11)) {
11494 /* load */
11495 tmp = tcg_temp_new_i32();
11496 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11497 store_reg(s, rd, tmp);
11498 } else {
11499 /* store */
11500 tmp = load_reg(s, rd);
11501 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11502 tcg_temp_free_i32(tmp);
11504 tcg_temp_free_i32(addr);
11505 break;
11507 case 8:
11508 /* load/store halfword immediate offset */
11509 rd = insn & 7;
11510 rn = (insn >> 3) & 7;
11511 addr = load_reg(s, rn);
11512 val = (insn >> 5) & 0x3e;
11513 tcg_gen_addi_i32(addr, addr, val);
11515 if (insn & (1 << 11)) {
11516 /* load */
11517 tmp = tcg_temp_new_i32();
11518 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11519 store_reg(s, rd, tmp);
11520 } else {
11521 /* store */
11522 tmp = load_reg(s, rd);
11523 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11524 tcg_temp_free_i32(tmp);
11526 tcg_temp_free_i32(addr);
11527 break;
11529 case 9:
11530 /* load/store from stack */
11531 rd = (insn >> 8) & 7;
11532 addr = load_reg(s, 13);
11533 val = (insn & 0xff) * 4;
11534 tcg_gen_addi_i32(addr, addr, val);
11536 if (insn & (1 << 11)) {
11537 /* load */
11538 tmp = tcg_temp_new_i32();
11539 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11540 store_reg(s, rd, tmp);
11541 } else {
11542 /* store */
11543 tmp = load_reg(s, rd);
11544 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11545 tcg_temp_free_i32(tmp);
11547 tcg_temp_free_i32(addr);
11548 break;
11550 case 10:
11551 /* add to high reg */
11552 rd = (insn >> 8) & 7;
11553 if (insn & (1 << 11)) {
11554 /* SP */
11555 tmp = load_reg(s, 13);
11556 } else {
11557 /* PC. bit 1 is ignored. */
11558 tmp = tcg_temp_new_i32();
11559 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11561 val = (insn & 0xff) * 4;
11562 tcg_gen_addi_i32(tmp, tmp, val);
11563 store_reg(s, rd, tmp);
11564 break;
11566 case 11:
11567 /* misc */
11568 op = (insn >> 8) & 0xf;
11569 switch (op) {
11570 case 0:
11571 /* adjust stack pointer */
11572 tmp = load_reg(s, 13);
11573 val = (insn & 0x7f) * 4;
11574 if (insn & (1 << 7))
11575 val = -(int32_t)val;
11576 tcg_gen_addi_i32(tmp, tmp, val);
11577 store_reg(s, 13, tmp);
11578 break;
11580 case 2: /* sign/zero extend. */
11581 ARCH(6);
11582 rd = insn & 7;
11583 rm = (insn >> 3) & 7;
11584 tmp = load_reg(s, rm);
11585 switch ((insn >> 6) & 3) {
11586 case 0: gen_sxth(tmp); break;
11587 case 1: gen_sxtb(tmp); break;
11588 case 2: gen_uxth(tmp); break;
11589 case 3: gen_uxtb(tmp); break;
11591 store_reg(s, rd, tmp);
11592 break;
11593 case 4: case 5: case 0xc: case 0xd:
11594 /* push/pop */
11595 addr = load_reg(s, 13);
11596 if (insn & (1 << 8))
11597 offset = 4;
11598 else
11599 offset = 0;
11600 for (i = 0; i < 8; i++) {
11601 if (insn & (1 << i))
11602 offset += 4;
11604 if ((insn & (1 << 11)) == 0) {
11605 tcg_gen_addi_i32(addr, addr, -offset);
11607 for (i = 0; i < 8; i++) {
11608 if (insn & (1 << i)) {
11609 if (insn & (1 << 11)) {
11610 /* pop */
11611 tmp = tcg_temp_new_i32();
11612 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11613 store_reg(s, i, tmp);
11614 } else {
11615 /* push */
11616 tmp = load_reg(s, i);
11617 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11618 tcg_temp_free_i32(tmp);
11620 /* advance to the next address. */
11621 tcg_gen_addi_i32(addr, addr, 4);
11624 TCGV_UNUSED_I32(tmp);
11625 if (insn & (1 << 8)) {
11626 if (insn & (1 << 11)) {
11627 /* pop pc */
11628 tmp = tcg_temp_new_i32();
11629 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11630 /* don't set the pc until the rest of the instruction
11631 has completed */
11632 } else {
11633 /* push lr */
11634 tmp = load_reg(s, 14);
11635 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11636 tcg_temp_free_i32(tmp);
11638 tcg_gen_addi_i32(addr, addr, 4);
11640 if ((insn & (1 << 11)) == 0) {
11641 tcg_gen_addi_i32(addr, addr, -offset);
11643 /* write back the new stack pointer */
11644 store_reg(s, 13, addr);
11645 /* set the new PC value */
11646 if ((insn & 0x0900) == 0x0900) {
11647 store_reg_from_load(s, 15, tmp);
11649 break;
11651 case 1: case 3: case 9: case 11: /* czb */
11652 rm = insn & 7;
11653 tmp = load_reg(s, rm);
11654 s->condlabel = gen_new_label();
11655 s->condjmp = 1;
11656 if (insn & (1 << 11))
11657 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11658 else
11659 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11660 tcg_temp_free_i32(tmp);
11661 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11662 val = (uint32_t)s->pc + 2;
11663 val += offset;
11664 gen_jmp(s, val);
11665 break;
11667 case 15: /* IT, nop-hint. */
11668 if ((insn & 0xf) == 0) {
11669 gen_nop_hint(s, (insn >> 4) & 0xf);
11670 break;
11672 /* If Then. */
11673 s->condexec_cond = (insn >> 4) & 0xe;
11674 s->condexec_mask = insn & 0x1f;
11675 /* No actual code generated for this insn, just setup state. */
11676 break;
11678 case 0xe: /* bkpt */
11680 int imm8 = extract32(insn, 0, 8);
11681 ARCH(5);
11682 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11683 default_exception_el(s));
11684 break;
11687 case 0xa: /* rev, and hlt */
11689 int op1 = extract32(insn, 6, 2);
11691 if (op1 == 2) {
11692 /* HLT */
11693 int imm6 = extract32(insn, 0, 6);
11695 gen_hlt(s, imm6);
11696 break;
11699 /* Otherwise this is rev */
11700 ARCH(6);
11701 rn = (insn >> 3) & 0x7;
11702 rd = insn & 0x7;
11703 tmp = load_reg(s, rn);
11704 switch (op1) {
11705 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11706 case 1: gen_rev16(tmp); break;
11707 case 3: gen_revsh(tmp); break;
11708 default:
11709 g_assert_not_reached();
11711 store_reg(s, rd, tmp);
11712 break;
11715 case 6:
11716 switch ((insn >> 5) & 7) {
11717 case 2:
11718 /* setend */
11719 ARCH(6);
11720 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11721 gen_helper_setend(cpu_env);
11722 s->base.is_jmp = DISAS_UPDATE;
11724 break;
11725 case 3:
11726 /* cps */
11727 ARCH(6);
11728 if (IS_USER(s)) {
11729 break;
11731 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11732 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11733 /* FAULTMASK */
11734 if (insn & 1) {
11735 addr = tcg_const_i32(19);
11736 gen_helper_v7m_msr(cpu_env, addr, tmp);
11737 tcg_temp_free_i32(addr);
11739 /* PRIMASK */
11740 if (insn & 2) {
11741 addr = tcg_const_i32(16);
11742 gen_helper_v7m_msr(cpu_env, addr, tmp);
11743 tcg_temp_free_i32(addr);
11745 tcg_temp_free_i32(tmp);
11746 gen_lookup_tb(s);
11747 } else {
11748 if (insn & (1 << 4)) {
11749 shift = CPSR_A | CPSR_I | CPSR_F;
11750 } else {
11751 shift = 0;
11753 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11755 break;
11756 default:
11757 goto undef;
11759 break;
11761 default:
11762 goto undef;
11764 break;
11766 case 12:
11768 /* load/store multiple */
11769 TCGv_i32 loaded_var;
11770 TCGV_UNUSED_I32(loaded_var);
11771 rn = (insn >> 8) & 0x7;
11772 addr = load_reg(s, rn);
11773 for (i = 0; i < 8; i++) {
11774 if (insn & (1 << i)) {
11775 if (insn & (1 << 11)) {
11776 /* load */
11777 tmp = tcg_temp_new_i32();
11778 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11779 if (i == rn) {
11780 loaded_var = tmp;
11781 } else {
11782 store_reg(s, i, tmp);
11784 } else {
11785 /* store */
11786 tmp = load_reg(s, i);
11787 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11788 tcg_temp_free_i32(tmp);
11790 /* advance to the next address */
11791 tcg_gen_addi_i32(addr, addr, 4);
11794 if ((insn & (1 << rn)) == 0) {
11795 /* base reg not in list: base register writeback */
11796 store_reg(s, rn, addr);
11797 } else {
11798 /* base reg in list: if load, complete it now */
11799 if (insn & (1 << 11)) {
11800 store_reg(s, rn, loaded_var);
11802 tcg_temp_free_i32(addr);
11804 break;
11806 case 13:
11807 /* conditional branch or swi */
11808 cond = (insn >> 8) & 0xf;
11809 if (cond == 0xe)
11810 goto undef;
11812 if (cond == 0xf) {
11813 /* swi */
11814 gen_set_pc_im(s, s->pc);
11815 s->svc_imm = extract32(insn, 0, 8);
11816 s->base.is_jmp = DISAS_SWI;
11817 break;
11819 /* generate a conditional jump to next instruction */
11820 s->condlabel = gen_new_label();
11821 arm_gen_test_cc(cond ^ 1, s->condlabel);
11822 s->condjmp = 1;
11824 /* jump to the offset */
11825 val = (uint32_t)s->pc + 2;
11826 offset = ((int32_t)insn << 24) >> 24;
11827 val += offset << 1;
11828 gen_jmp(s, val);
11829 break;
11831 case 14:
11832 if (insn & (1 << 11)) {
11833 if (disas_thumb2_insn(env, s, insn))
11834 goto undef32;
11835 break;
11837 /* unconditional branch */
11838 val = (uint32_t)s->pc;
11839 offset = ((int32_t)insn << 21) >> 21;
11840 val += (offset << 1) + 2;
11841 gen_jmp(s, val);
11842 break;
11844 case 15:
11845 if (disas_thumb2_insn(env, s, insn))
11846 goto undef32;
11847 break;
11849 return;
11850 undef32:
11851 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11852 default_exception_el(s));
11853 return;
11854 illegal_op:
11855 undef:
11856 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11857 default_exception_el(s));
11860 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11862 /* Return true if the insn at dc->pc might cross a page boundary.
11863 * (False positives are OK, false negatives are not.)
11865 uint16_t insn;
11867 if ((s->pc & 3) == 0) {
11868 /* At a 4-aligned address we can't be crossing a page */
11869 return false;
11872 /* This must be a Thumb insn */
11873 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11875 if ((insn >> 11) >= 0x1d) {
11876 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11877 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11878 * end up actually treating this as two 16-bit insns (see the
11879 * code at the start of disas_thumb2_insn()) but we don't bother
11880 * to check for that as it is unlikely, and false positives here
11881 * are harmless.
11883 return true;
11885 /* Definitely a 16-bit insn, can't be crossing a page. */
11886 return false;
11889 static int arm_tr_init_disas_context(DisasContextBase *dcbase,
11890 CPUState *cs, int max_insns)
11892 DisasContext *dc = container_of(dcbase, DisasContext, base);
11893 CPUARMState *env = cs->env_ptr;
11894 ARMCPU *cpu = arm_env_get_cpu(env);
11896 dc->pc = dc->base.pc_first;
11897 dc->condjmp = 0;
11899 dc->aarch64 = 0;
11900 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11901 * there is no secure EL1, so we route exceptions to EL3.
11903 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11904 !arm_el_is_aa64(env, 3);
11905 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
11906 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
11907 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
11908 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
11909 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
11910 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
11911 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11912 #if !defined(CONFIG_USER_ONLY)
11913 dc->user = (dc->current_el == 0);
11914 #endif
11915 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
11916 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
11917 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
11918 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
11919 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
11920 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
11921 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
11922 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11923 regime_is_secure(env, dc->mmu_idx);
11924 dc->cp_regs = cpu->cp_regs;
11925 dc->features = env->features;
11927 /* Single step state. The code-generation logic here is:
11928 * SS_ACTIVE == 0:
11929 * generate code with no special handling for single-stepping (except
11930 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11931 * this happens anyway because those changes are all system register or
11932 * PSTATE writes).
11933 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11934 * emit code for one insn
11935 * emit code to clear PSTATE.SS
11936 * emit code to generate software step exception for completed step
11937 * end TB (as usual for having generated an exception)
11938 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11939 * emit code to generate a software step exception
11940 * end the TB
11942 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
11943 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
11944 dc->is_ldex = false;
11945 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11947 dc->next_page_start =
11948 (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11950 /* If architectural single step active, limit to 1. */
11951 if (is_singlestepping(dc)) {
11952 max_insns = 1;
11955 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11956 to those left on the page. */
11957 if (!dc->thumb) {
11958 int bound = (dc->next_page_start - dc->base.pc_first) / 4;
11959 max_insns = MIN(max_insns, bound);
11962 cpu_F0s = tcg_temp_new_i32();
11963 cpu_F1s = tcg_temp_new_i32();
11964 cpu_F0d = tcg_temp_new_i64();
11965 cpu_F1d = tcg_temp_new_i64();
11966 cpu_V0 = cpu_F0d;
11967 cpu_V1 = cpu_F1d;
11968 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11969 cpu_M0 = tcg_temp_new_i64();
11971 return max_insns;
11974 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11976 DisasContext *dc = container_of(dcbase, DisasContext, base);
11978 /* A note on handling of the condexec (IT) bits:
11980 * We want to avoid the overhead of having to write the updated condexec
11981 * bits back to the CPUARMState for every instruction in an IT block. So:
11982 * (1) if the condexec bits are not already zero then we write
11983 * zero back into the CPUARMState now. This avoids complications trying
11984 * to do it at the end of the block. (For example if we don't do this
11985 * it's hard to identify whether we can safely skip writing condexec
11986 * at the end of the TB, which we definitely want to do for the case
11987 * where a TB doesn't do anything with the IT state at all.)
11988 * (2) if we are going to leave the TB then we call gen_set_condexec()
11989 * which will write the correct value into CPUARMState if zero is wrong.
11990 * This is done both for leaving the TB at the end, and for leaving
11991 * it because of an exception we know will happen, which is done in
11992 * gen_exception_insn(). The latter is necessary because we need to
11993 * leave the TB with the PC/IT state just prior to execution of the
11994 * instruction which caused the exception.
11995 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11996 * then the CPUARMState will be wrong and we need to reset it.
11997 * This is handled in the same way as restoration of the
11998 * PC in these situations; we save the value of the condexec bits
11999 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12000 * then uses this to restore them after an exception.
12002 * Note that there are no instructions which can read the condexec
12003 * bits, and none which can write non-static values to them, so
12004 * we don't need to care about whether CPUARMState is correct in the
12005 * middle of a TB.
12008 /* Reset the conditional execution bits immediately. This avoids
12009 complications trying to do it at the end of the block. */
12010 if (dc->condexec_mask || dc->condexec_cond) {
12011 TCGv_i32 tmp = tcg_temp_new_i32();
12012 tcg_gen_movi_i32(tmp, 0);
12013 store_cpu_field(tmp, condexec_bits);
12015 tcg_clear_temp_count();
12018 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12020 DisasContext *dc = container_of(dcbase, DisasContext, base);
12022 dc->insn_start_idx = tcg_op_buf_count();
12023 tcg_gen_insn_start(dc->pc,
12024 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12028 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12029 const CPUBreakpoint *bp)
12031 DisasContext *dc = container_of(dcbase, DisasContext, base);
12033 if (bp->flags & BP_CPU) {
12034 gen_set_condexec(dc);
12035 gen_set_pc_im(dc, dc->pc);
12036 gen_helper_check_breakpoints(cpu_env);
12037 /* End the TB early; it's likely not going to be executed */
12038 dc->base.is_jmp = DISAS_TOO_MANY;
12039 } else {
12040 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12041 /* The address covered by the breakpoint must be
12042 included in [tb->pc, tb->pc + tb->size) in order
12043 to for it to be properly cleared -- thus we
12044 increment the PC here so that the logic setting
12045 tb->size below does the right thing. */
12046 /* TODO: Advance PC by correct instruction length to
12047 * avoid disassembler error messages */
12048 dc->pc += 2;
12049 dc->base.is_jmp = DISAS_NORETURN;
12052 return true;
12055 static bool arm_pre_translate_insn(DisasContext *dc)
12057 #ifdef CONFIG_USER_ONLY
12058 /* Intercept jump to the magic kernel page. */
12059 if (dc->pc >= 0xffff0000) {
12060 /* We always get here via a jump, so know we are not in a
12061 conditional execution block. */
12062 gen_exception_internal(EXCP_KERNEL_TRAP);
12063 dc->base.is_jmp = DISAS_NORETURN;
12064 return true;
12066 #endif
12068 if (dc->ss_active && !dc->pstate_ss) {
12069 /* Singlestep state is Active-pending.
12070 * If we're in this state at the start of a TB then either
12071 * a) we just took an exception to an EL which is being debugged
12072 * and this is the first insn in the exception handler
12073 * b) debug exceptions were masked and we just unmasked them
12074 * without changing EL (eg by clearing PSTATE.D)
12075 * In either case we're going to take a swstep exception in the
12076 * "did not step an insn" case, and so the syndrome ISV and EX
12077 * bits should be zero.
12079 assert(dc->base.num_insns == 1);
12080 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12081 default_exception_el(dc));
12082 dc->base.is_jmp = DISAS_NORETURN;
12083 return true;
12086 return false;
12089 static void arm_post_translate_insn(DisasContext *dc)
12091 if (dc->condjmp && !dc->base.is_jmp) {
12092 gen_set_label(dc->condlabel);
12093 dc->condjmp = 0;
12095 dc->base.pc_next = dc->pc;
12096 translator_loop_temp_check(&dc->base);
12099 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12101 DisasContext *dc = container_of(dcbase, DisasContext, base);
12102 CPUARMState *env = cpu->env_ptr;
12103 unsigned int insn;
12105 if (arm_pre_translate_insn(dc)) {
12106 return;
12109 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12110 dc->pc += 4;
12111 disas_arm_insn(dc, insn);
12113 arm_post_translate_insn(dc);
12115 /* ARM is a fixed-length ISA. We performed the cross-page check
12116 in init_disas_context by adjusting max_insns. */
12119 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12121 DisasContext *dc = container_of(dcbase, DisasContext, base);
12122 CPUARMState *env = cpu->env_ptr;
12124 if (arm_pre_translate_insn(dc)) {
12125 return;
12128 disas_thumb_insn(env, dc);
12130 /* Advance the Thumb condexec condition. */
12131 if (dc->condexec_mask) {
12132 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12133 ((dc->condexec_mask >> 4) & 1));
12134 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12135 if (dc->condexec_mask == 0) {
12136 dc->condexec_cond = 0;
12140 arm_post_translate_insn(dc);
12142 /* Thumb is a variable-length ISA. Stop translation when the next insn
12143 * will touch a new page. This ensures that prefetch aborts occur at
12144 * the right place.
12146 * We want to stop the TB if the next insn starts in a new page,
12147 * or if it spans between this page and the next. This means that
12148 * if we're looking at the last halfword in the page we need to
12149 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12150 * or a 32-bit Thumb insn (which won't).
12151 * This is to avoid generating a silly TB with a single 16-bit insn
12152 * in it at the end of this page (which would execute correctly
12153 * but isn't very efficient).
12155 if (dc->base.is_jmp == DISAS_NEXT
12156 && (dc->pc >= dc->next_page_start
12157 || (dc->pc >= dc->next_page_start - 3
12158 && insn_crosses_page(env, dc)))) {
12159 dc->base.is_jmp = DISAS_TOO_MANY;
12163 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12165 DisasContext *dc = container_of(dcbase, DisasContext, base);
12167 if (dc->base.tb->cflags & CF_LAST_IO && dc->condjmp) {
12168 /* FIXME: This can theoretically happen with self-modifying code. */
12169 cpu_abort(cpu, "IO on conditional branch instruction");
12172 /* At this stage dc->condjmp will only be set when the skipped
12173 instruction was a conditional branch or trap, and the PC has
12174 already been written. */
12175 gen_set_condexec(dc);
12176 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12177 /* Exception return branches need some special case code at the
12178 * end of the TB, which is complex enough that it has to
12179 * handle the single-step vs not and the condition-failed
12180 * insn codepath itself.
12182 gen_bx_excret_final_code(dc);
12183 } else if (unlikely(is_singlestepping(dc))) {
12184 /* Unconditional and "condition passed" instruction codepath. */
12185 switch (dc->base.is_jmp) {
12186 case DISAS_SWI:
12187 gen_ss_advance(dc);
12188 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12189 default_exception_el(dc));
12190 break;
12191 case DISAS_HVC:
12192 gen_ss_advance(dc);
12193 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12194 break;
12195 case DISAS_SMC:
12196 gen_ss_advance(dc);
12197 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12198 break;
12199 case DISAS_NEXT:
12200 case DISAS_TOO_MANY:
12201 case DISAS_UPDATE:
12202 gen_set_pc_im(dc, dc->pc);
12203 /* fall through */
12204 default:
12205 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12206 gen_singlestep_exception(dc);
12207 break;
12208 case DISAS_NORETURN:
12209 break;
12211 } else {
12212 /* While branches must always occur at the end of an IT block,
12213 there are a few other things that can cause us to terminate
12214 the TB in the middle of an IT block:
12215 - Exception generating instructions (bkpt, swi, undefined).
12216 - Page boundaries.
12217 - Hardware watchpoints.
12218 Hardware breakpoints have already been handled and skip this code.
12220 switch(dc->base.is_jmp) {
12221 case DISAS_NEXT:
12222 case DISAS_TOO_MANY:
12223 gen_goto_tb(dc, 1, dc->pc);
12224 break;
12225 case DISAS_JUMP:
12226 gen_goto_ptr();
12227 break;
12228 case DISAS_UPDATE:
12229 gen_set_pc_im(dc, dc->pc);
12230 /* fall through */
12231 default:
12232 /* indicate that the hash table must be used to find the next TB */
12233 tcg_gen_exit_tb(0);
12234 break;
12235 case DISAS_NORETURN:
12236 /* nothing more to generate */
12237 break;
12238 case DISAS_WFI:
12239 gen_helper_wfi(cpu_env);
12240 /* The helper doesn't necessarily throw an exception, but we
12241 * must go back to the main loop to check for interrupts anyway.
12243 tcg_gen_exit_tb(0);
12244 break;
12245 case DISAS_WFE:
12246 gen_helper_wfe(cpu_env);
12247 break;
12248 case DISAS_YIELD:
12249 gen_helper_yield(cpu_env);
12250 break;
12251 case DISAS_SWI:
12252 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12253 default_exception_el(dc));
12254 break;
12255 case DISAS_HVC:
12256 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12257 break;
12258 case DISAS_SMC:
12259 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12260 break;
12264 if (dc->condjmp) {
12265 /* "Condition failed" instruction codepath for the branch/trap insn */
12266 gen_set_label(dc->condlabel);
12267 gen_set_condexec(dc);
12268 if (unlikely(is_singlestepping(dc))) {
12269 gen_set_pc_im(dc, dc->pc);
12270 gen_singlestep_exception(dc);
12271 } else {
12272 gen_goto_tb(dc, 1, dc->pc);
12276 /* Functions above can change dc->pc, so re-align db->pc_next */
12277 dc->base.pc_next = dc->pc;
12280 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12282 DisasContext *dc = container_of(dcbase, DisasContext, base);
12284 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12285 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size,
12286 dc->thumb | (dc->sctlr_b << 1));
12289 static const TranslatorOps arm_translator_ops = {
12290 .init_disas_context = arm_tr_init_disas_context,
12291 .tb_start = arm_tr_tb_start,
12292 .insn_start = arm_tr_insn_start,
12293 .breakpoint_check = arm_tr_breakpoint_check,
12294 .translate_insn = arm_tr_translate_insn,
12295 .tb_stop = arm_tr_tb_stop,
12296 .disas_log = arm_tr_disas_log,
12299 static const TranslatorOps thumb_translator_ops = {
12300 .init_disas_context = arm_tr_init_disas_context,
12301 .tb_start = arm_tr_tb_start,
12302 .insn_start = arm_tr_insn_start,
12303 .breakpoint_check = arm_tr_breakpoint_check,
12304 .translate_insn = thumb_tr_translate_insn,
12305 .tb_stop = arm_tr_tb_stop,
12306 .disas_log = arm_tr_disas_log,
12309 /* generate intermediate code for basic block 'tb'. */
12310 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12312 DisasContext dc;
12313 const TranslatorOps *ops = &arm_translator_ops;
12315 if (ARM_TBFLAG_THUMB(tb->flags)) {
12316 ops = &thumb_translator_ops;
12318 #ifdef TARGET_AARCH64
12319 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12320 ops = &aarch64_translator_ops;
12322 #endif
12324 translator_loop(ops, &dc.base, cpu, tb);
12327 static const char *cpu_mode_names[16] = {
12328 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12329 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12332 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12333 int flags)
12335 ARMCPU *cpu = ARM_CPU(cs);
12336 CPUARMState *env = &cpu->env;
12337 int i;
12339 if (is_a64(env)) {
12340 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12341 return;
12344 for(i=0;i<16;i++) {
12345 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12346 if ((i % 4) == 3)
12347 cpu_fprintf(f, "\n");
12348 else
12349 cpu_fprintf(f, " ");
12352 if (arm_feature(env, ARM_FEATURE_M)) {
12353 uint32_t xpsr = xpsr_read(env);
12354 const char *mode;
12355 const char *ns_status = "";
12357 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12358 ns_status = env->v7m.secure ? "S " : "NS ";
12361 if (xpsr & XPSR_EXCP) {
12362 mode = "handler";
12363 } else {
12364 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12365 mode = "unpriv-thread";
12366 } else {
12367 mode = "priv-thread";
12371 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12372 xpsr,
12373 xpsr & XPSR_N ? 'N' : '-',
12374 xpsr & XPSR_Z ? 'Z' : '-',
12375 xpsr & XPSR_C ? 'C' : '-',
12376 xpsr & XPSR_V ? 'V' : '-',
12377 xpsr & XPSR_T ? 'T' : 'A',
12378 ns_status,
12379 mode);
12380 } else {
12381 uint32_t psr = cpsr_read(env);
12382 const char *ns_status = "";
12384 if (arm_feature(env, ARM_FEATURE_EL3) &&
12385 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12386 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12389 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12390 psr,
12391 psr & CPSR_N ? 'N' : '-',
12392 psr & CPSR_Z ? 'Z' : '-',
12393 psr & CPSR_C ? 'C' : '-',
12394 psr & CPSR_V ? 'V' : '-',
12395 psr & CPSR_T ? 'T' : 'A',
12396 ns_status,
12397 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12400 if (flags & CPU_DUMP_FPU) {
12401 int numvfpregs = 0;
12402 if (arm_feature(env, ARM_FEATURE_VFP)) {
12403 numvfpregs += 16;
12405 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12406 numvfpregs += 16;
12408 for (i = 0; i < numvfpregs; i++) {
12409 uint64_t v = float64_val(env->vfp.regs[i]);
12410 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12411 i * 2, (uint32_t)v,
12412 i * 2 + 1, (uint32_t)(v >> 32),
12413 i, v);
12415 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12419 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12420 target_ulong *data)
12422 if (is_a64(env)) {
12423 env->pc = data[0];
12424 env->condexec_bits = 0;
12425 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12426 } else {
12427 env->regs[15] = data[0];
12428 env->condexec_bits = data[1];
12429 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;