s390x: introduce 2.11 compat machine
[qemu.git] / target / arm / translate.c
blobd1a5f569985d51ba98f9dcd166a9c6890a5310dd
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "qemu/log.h"
29 #include "qemu/bitops.h"
30 #include "arm_ldst.h"
31 #include "exec/semihost.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
36 #include "trace-tcg.h"
37 #include "exec/log.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J 0
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) 1
57 #else
58 #define IS_USER(s) (s->user)
59 #endif
61 TCGv_env cpu_env;
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s, cpu_F1s;
71 static TCGv_i64 cpu_F0d, cpu_F1d;
73 #include "exec/gen-icount.h"
75 static const char *regnames[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* initialize TCG globals. */
80 void arm_translate_init(void)
82 int i;
84 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
85 tcg_ctx.tcg_env = cpu_env;
87 for (i = 0; i < 16; i++) {
88 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
89 offsetof(CPUARMState, regs[i]),
90 regnames[i]);
92 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
93 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
94 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
95 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
97 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
98 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
99 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
100 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 a64_translate_init();
105 /* Flags for the disas_set_da_iss info argument:
106 * lower bits hold the Rt register number, higher bits are flags.
108 typedef enum ISSInfo {
109 ISSNone = 0,
110 ISSRegMask = 0x1f,
111 ISSInvalid = (1 << 5),
112 ISSIsAcqRel = (1 << 6),
113 ISSIsWrite = (1 << 7),
114 ISSIs16Bit = (1 << 8),
115 } ISSInfo;
117 /* Save the syndrome information for a Data Abort */
118 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
120 uint32_t syn;
121 int sas = memop & MO_SIZE;
122 bool sse = memop & MO_SIGN;
123 bool is_acqrel = issinfo & ISSIsAcqRel;
124 bool is_write = issinfo & ISSIsWrite;
125 bool is_16bit = issinfo & ISSIs16Bit;
126 int srt = issinfo & ISSRegMask;
128 if (issinfo & ISSInvalid) {
129 /* Some callsites want to conditionally provide ISS info,
130 * eg "only if this was not a writeback"
132 return;
135 if (srt == 15) {
136 /* For AArch32, insns where the src/dest is R15 never generate
137 * ISS information. Catching that here saves checking at all
138 * the call sites.
140 return;
143 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
144 0, 0, 0, is_write, 0, is_16bit);
145 disas_set_insn_syndrome(s, syn);
148 static inline int get_a32_user_mem_index(DisasContext *s)
150 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
151 * insns:
152 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
153 * otherwise, access as if at PL0.
155 switch (s->mmu_idx) {
156 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
157 case ARMMMUIdx_S12NSE0:
158 case ARMMMUIdx_S12NSE1:
159 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
160 case ARMMMUIdx_S1E3:
161 case ARMMMUIdx_S1SE0:
162 case ARMMMUIdx_S1SE1:
163 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
164 case ARMMMUIdx_MUser:
165 case ARMMMUIdx_MPriv:
166 case ARMMMUIdx_MNegPri:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_S2NS:
169 default:
170 g_assert_not_reached();
174 static inline TCGv_i32 load_cpu_offset(int offset)
176 TCGv_i32 tmp = tcg_temp_new_i32();
177 tcg_gen_ld_i32(tmp, cpu_env, offset);
178 return tmp;
181 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
183 static inline void store_cpu_offset(TCGv_i32 var, int offset)
185 tcg_gen_st_i32(var, cpu_env, offset);
186 tcg_temp_free_i32(var);
189 #define store_cpu_field(var, name) \
190 store_cpu_offset(var, offsetof(CPUARMState, name))
192 /* Set a variable to the value of a CPU register. */
193 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
195 if (reg == 15) {
196 uint32_t addr;
197 /* normally, since we updated PC, we need only to add one insn */
198 if (s->thumb)
199 addr = (long)s->pc + 2;
200 else
201 addr = (long)s->pc + 4;
202 tcg_gen_movi_i32(var, addr);
203 } else {
204 tcg_gen_mov_i32(var, cpu_R[reg]);
208 /* Create a new temporary and set it to the value of a CPU register. */
209 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
211 TCGv_i32 tmp = tcg_temp_new_i32();
212 load_reg_var(s, tmp, reg);
213 return tmp;
216 /* Set a CPU register. The source must be a temporary and will be
217 marked as dead. */
218 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
220 if (reg == 15) {
221 /* In Thumb mode, we must ignore bit 0.
222 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
223 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
224 * We choose to ignore [1:0] in ARM mode for all architecture versions.
226 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
227 s->is_jmp = DISAS_JUMP;
229 tcg_gen_mov_i32(cpu_R[reg], var);
230 tcg_temp_free_i32(var);
233 /* Value extensions. */
234 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
235 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
236 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
237 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
239 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
240 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
243 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
245 TCGv_i32 tmp_mask = tcg_const_i32(mask);
246 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
247 tcg_temp_free_i32(tmp_mask);
249 /* Set NZCV flags from the high 4 bits of var. */
250 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
252 static void gen_exception_internal(int excp)
254 TCGv_i32 tcg_excp = tcg_const_i32(excp);
256 assert(excp_is_internal(excp));
257 gen_helper_exception_internal(cpu_env, tcg_excp);
258 tcg_temp_free_i32(tcg_excp);
261 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
263 TCGv_i32 tcg_excp = tcg_const_i32(excp);
264 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
265 TCGv_i32 tcg_el = tcg_const_i32(target_el);
267 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
268 tcg_syn, tcg_el);
270 tcg_temp_free_i32(tcg_el);
271 tcg_temp_free_i32(tcg_syn);
272 tcg_temp_free_i32(tcg_excp);
275 static void gen_ss_advance(DisasContext *s)
277 /* If the singlestep state is Active-not-pending, advance to
278 * Active-pending.
280 if (s->ss_active) {
281 s->pstate_ss = 0;
282 gen_helper_clear_pstate_ss(cpu_env);
286 static void gen_step_complete_exception(DisasContext *s)
288 /* We just completed step of an insn. Move from Active-not-pending
289 * to Active-pending, and then also take the swstep exception.
290 * This corresponds to making the (IMPDEF) choice to prioritize
291 * swstep exceptions over asynchronous exceptions taken to an exception
292 * level where debug is disabled. This choice has the advantage that
293 * we do not need to maintain internal state corresponding to the
294 * ISV/EX syndrome bits between completion of the step and generation
295 * of the exception, and our syndrome information is always correct.
297 gen_ss_advance(s);
298 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
299 default_exception_el(s));
300 s->is_jmp = DISAS_EXC;
303 static void gen_singlestep_exception(DisasContext *s)
305 /* Generate the right kind of exception for singlestep, which is
306 * either the architectural singlestep or EXCP_DEBUG for QEMU's
307 * gdb singlestepping.
309 if (s->ss_active) {
310 gen_step_complete_exception(s);
311 } else {
312 gen_exception_internal(EXCP_DEBUG);
316 static inline bool is_singlestepping(DisasContext *s)
318 /* Return true if we are singlestepping either because of
319 * architectural singlestep or QEMU gdbstub singlestep. This does
320 * not include the command line '-singlestep' mode which is rather
321 * misnamed as it only means "one instruction per TB" and doesn't
322 * affect the code we generate.
324 return s->singlestep_enabled || s->ss_active;
327 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
329 TCGv_i32 tmp1 = tcg_temp_new_i32();
330 TCGv_i32 tmp2 = tcg_temp_new_i32();
331 tcg_gen_ext16s_i32(tmp1, a);
332 tcg_gen_ext16s_i32(tmp2, b);
333 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
334 tcg_temp_free_i32(tmp2);
335 tcg_gen_sari_i32(a, a, 16);
336 tcg_gen_sari_i32(b, b, 16);
337 tcg_gen_mul_i32(b, b, a);
338 tcg_gen_mov_i32(a, tmp1);
339 tcg_temp_free_i32(tmp1);
342 /* Byteswap each halfword. */
343 static void gen_rev16(TCGv_i32 var)
345 TCGv_i32 tmp = tcg_temp_new_i32();
346 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
347 tcg_gen_shri_i32(tmp, var, 8);
348 tcg_gen_and_i32(tmp, tmp, mask);
349 tcg_gen_and_i32(var, var, mask);
350 tcg_gen_shli_i32(var, var, 8);
351 tcg_gen_or_i32(var, var, tmp);
352 tcg_temp_free_i32(mask);
353 tcg_temp_free_i32(tmp);
356 /* Byteswap low halfword and sign extend. */
357 static void gen_revsh(TCGv_i32 var)
359 tcg_gen_ext16u_i32(var, var);
360 tcg_gen_bswap16_i32(var, var);
361 tcg_gen_ext16s_i32(var, var);
364 /* Return (b << 32) + a. Mark inputs as dead */
365 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
367 TCGv_i64 tmp64 = tcg_temp_new_i64();
369 tcg_gen_extu_i32_i64(tmp64, b);
370 tcg_temp_free_i32(b);
371 tcg_gen_shli_i64(tmp64, tmp64, 32);
372 tcg_gen_add_i64(a, tmp64, a);
374 tcg_temp_free_i64(tmp64);
375 return a;
378 /* Return (b << 32) - a. Mark inputs as dead. */
379 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
381 TCGv_i64 tmp64 = tcg_temp_new_i64();
383 tcg_gen_extu_i32_i64(tmp64, b);
384 tcg_temp_free_i32(b);
385 tcg_gen_shli_i64(tmp64, tmp64, 32);
386 tcg_gen_sub_i64(a, tmp64, a);
388 tcg_temp_free_i64(tmp64);
389 return a;
392 /* 32x32->64 multiply. Marks inputs as dead. */
393 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
395 TCGv_i32 lo = tcg_temp_new_i32();
396 TCGv_i32 hi = tcg_temp_new_i32();
397 TCGv_i64 ret;
399 tcg_gen_mulu2_i32(lo, hi, a, b);
400 tcg_temp_free_i32(a);
401 tcg_temp_free_i32(b);
403 ret = tcg_temp_new_i64();
404 tcg_gen_concat_i32_i64(ret, lo, hi);
405 tcg_temp_free_i32(lo);
406 tcg_temp_free_i32(hi);
408 return ret;
411 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
413 TCGv_i32 lo = tcg_temp_new_i32();
414 TCGv_i32 hi = tcg_temp_new_i32();
415 TCGv_i64 ret;
417 tcg_gen_muls2_i32(lo, hi, a, b);
418 tcg_temp_free_i32(a);
419 tcg_temp_free_i32(b);
421 ret = tcg_temp_new_i64();
422 tcg_gen_concat_i32_i64(ret, lo, hi);
423 tcg_temp_free_i32(lo);
424 tcg_temp_free_i32(hi);
426 return ret;
429 /* Swap low and high halfwords. */
430 static void gen_swap_half(TCGv_i32 var)
432 TCGv_i32 tmp = tcg_temp_new_i32();
433 tcg_gen_shri_i32(tmp, var, 16);
434 tcg_gen_shli_i32(var, var, 16);
435 tcg_gen_or_i32(var, var, tmp);
436 tcg_temp_free_i32(tmp);
439 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
440 tmp = (t0 ^ t1) & 0x8000;
441 t0 &= ~0x8000;
442 t1 &= ~0x8000;
443 t0 = (t0 + t1) ^ tmp;
446 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
448 TCGv_i32 tmp = tcg_temp_new_i32();
449 tcg_gen_xor_i32(tmp, t0, t1);
450 tcg_gen_andi_i32(tmp, tmp, 0x8000);
451 tcg_gen_andi_i32(t0, t0, ~0x8000);
452 tcg_gen_andi_i32(t1, t1, ~0x8000);
453 tcg_gen_add_i32(t0, t0, t1);
454 tcg_gen_xor_i32(t0, t0, tmp);
455 tcg_temp_free_i32(tmp);
456 tcg_temp_free_i32(t1);
459 /* Set CF to the top bit of var. */
460 static void gen_set_CF_bit31(TCGv_i32 var)
462 tcg_gen_shri_i32(cpu_CF, var, 31);
465 /* Set N and Z flags from var. */
466 static inline void gen_logic_CC(TCGv_i32 var)
468 tcg_gen_mov_i32(cpu_NF, var);
469 tcg_gen_mov_i32(cpu_ZF, var);
472 /* T0 += T1 + CF. */
473 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
475 tcg_gen_add_i32(t0, t0, t1);
476 tcg_gen_add_i32(t0, t0, cpu_CF);
479 /* dest = T0 + T1 + CF. */
480 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
482 tcg_gen_add_i32(dest, t0, t1);
483 tcg_gen_add_i32(dest, dest, cpu_CF);
486 /* dest = T0 - T1 + CF - 1. */
487 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
489 tcg_gen_sub_i32(dest, t0, t1);
490 tcg_gen_add_i32(dest, dest, cpu_CF);
491 tcg_gen_subi_i32(dest, dest, 1);
494 /* dest = T0 + T1. Compute C, N, V and Z flags */
495 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
497 TCGv_i32 tmp = tcg_temp_new_i32();
498 tcg_gen_movi_i32(tmp, 0);
499 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
500 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
501 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
502 tcg_gen_xor_i32(tmp, t0, t1);
503 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
504 tcg_temp_free_i32(tmp);
505 tcg_gen_mov_i32(dest, cpu_NF);
508 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
509 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
511 TCGv_i32 tmp = tcg_temp_new_i32();
512 if (TCG_TARGET_HAS_add2_i32) {
513 tcg_gen_movi_i32(tmp, 0);
514 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
515 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
516 } else {
517 TCGv_i64 q0 = tcg_temp_new_i64();
518 TCGv_i64 q1 = tcg_temp_new_i64();
519 tcg_gen_extu_i32_i64(q0, t0);
520 tcg_gen_extu_i32_i64(q1, t1);
521 tcg_gen_add_i64(q0, q0, q1);
522 tcg_gen_extu_i32_i64(q1, cpu_CF);
523 tcg_gen_add_i64(q0, q0, q1);
524 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
525 tcg_temp_free_i64(q0);
526 tcg_temp_free_i64(q1);
528 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
529 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
530 tcg_gen_xor_i32(tmp, t0, t1);
531 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
532 tcg_temp_free_i32(tmp);
533 tcg_gen_mov_i32(dest, cpu_NF);
536 /* dest = T0 - T1. Compute C, N, V and Z flags */
537 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
539 TCGv_i32 tmp;
540 tcg_gen_sub_i32(cpu_NF, t0, t1);
541 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
542 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
543 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
544 tmp = tcg_temp_new_i32();
545 tcg_gen_xor_i32(tmp, t0, t1);
546 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
547 tcg_temp_free_i32(tmp);
548 tcg_gen_mov_i32(dest, cpu_NF);
551 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
552 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
554 TCGv_i32 tmp = tcg_temp_new_i32();
555 tcg_gen_not_i32(tmp, t1);
556 gen_adc_CC(dest, t0, tmp);
557 tcg_temp_free_i32(tmp);
560 #define GEN_SHIFT(name) \
561 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
563 TCGv_i32 tmp1, tmp2, tmp3; \
564 tmp1 = tcg_temp_new_i32(); \
565 tcg_gen_andi_i32(tmp1, t1, 0xff); \
566 tmp2 = tcg_const_i32(0); \
567 tmp3 = tcg_const_i32(0x1f); \
568 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
569 tcg_temp_free_i32(tmp3); \
570 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
571 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
572 tcg_temp_free_i32(tmp2); \
573 tcg_temp_free_i32(tmp1); \
575 GEN_SHIFT(shl)
576 GEN_SHIFT(shr)
577 #undef GEN_SHIFT
579 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
581 TCGv_i32 tmp1, tmp2;
582 tmp1 = tcg_temp_new_i32();
583 tcg_gen_andi_i32(tmp1, t1, 0xff);
584 tmp2 = tcg_const_i32(0x1f);
585 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
586 tcg_temp_free_i32(tmp2);
587 tcg_gen_sar_i32(dest, t0, tmp1);
588 tcg_temp_free_i32(tmp1);
591 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
593 TCGv_i32 c0 = tcg_const_i32(0);
594 TCGv_i32 tmp = tcg_temp_new_i32();
595 tcg_gen_neg_i32(tmp, src);
596 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
597 tcg_temp_free_i32(c0);
598 tcg_temp_free_i32(tmp);
601 static void shifter_out_im(TCGv_i32 var, int shift)
603 if (shift == 0) {
604 tcg_gen_andi_i32(cpu_CF, var, 1);
605 } else {
606 tcg_gen_shri_i32(cpu_CF, var, shift);
607 if (shift != 31) {
608 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
613 /* Shift by immediate. Includes special handling for shift == 0. */
614 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
615 int shift, int flags)
617 switch (shiftop) {
618 case 0: /* LSL */
619 if (shift != 0) {
620 if (flags)
621 shifter_out_im(var, 32 - shift);
622 tcg_gen_shli_i32(var, var, shift);
624 break;
625 case 1: /* LSR */
626 if (shift == 0) {
627 if (flags) {
628 tcg_gen_shri_i32(cpu_CF, var, 31);
630 tcg_gen_movi_i32(var, 0);
631 } else {
632 if (flags)
633 shifter_out_im(var, shift - 1);
634 tcg_gen_shri_i32(var, var, shift);
636 break;
637 case 2: /* ASR */
638 if (shift == 0)
639 shift = 32;
640 if (flags)
641 shifter_out_im(var, shift - 1);
642 if (shift == 32)
643 shift = 31;
644 tcg_gen_sari_i32(var, var, shift);
645 break;
646 case 3: /* ROR/RRX */
647 if (shift != 0) {
648 if (flags)
649 shifter_out_im(var, shift - 1);
650 tcg_gen_rotri_i32(var, var, shift); break;
651 } else {
652 TCGv_i32 tmp = tcg_temp_new_i32();
653 tcg_gen_shli_i32(tmp, cpu_CF, 31);
654 if (flags)
655 shifter_out_im(var, 0);
656 tcg_gen_shri_i32(var, var, 1);
657 tcg_gen_or_i32(var, var, tmp);
658 tcg_temp_free_i32(tmp);
663 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
664 TCGv_i32 shift, int flags)
666 if (flags) {
667 switch (shiftop) {
668 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
669 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
670 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
671 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
673 } else {
674 switch (shiftop) {
675 case 0:
676 gen_shl(var, var, shift);
677 break;
678 case 1:
679 gen_shr(var, var, shift);
680 break;
681 case 2:
682 gen_sar(var, var, shift);
683 break;
684 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
685 tcg_gen_rotr_i32(var, var, shift); break;
688 tcg_temp_free_i32(shift);
691 #define PAS_OP(pfx) \
692 switch (op2) { \
693 case 0: gen_pas_helper(glue(pfx,add16)); break; \
694 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
695 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
696 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
697 case 4: gen_pas_helper(glue(pfx,add8)); break; \
698 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
700 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
702 TCGv_ptr tmp;
704 switch (op1) {
705 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
706 case 1:
707 tmp = tcg_temp_new_ptr();
708 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
709 PAS_OP(s)
710 tcg_temp_free_ptr(tmp);
711 break;
712 case 5:
713 tmp = tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
715 PAS_OP(u)
716 tcg_temp_free_ptr(tmp);
717 break;
718 #undef gen_pas_helper
719 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
720 case 2:
721 PAS_OP(q);
722 break;
723 case 3:
724 PAS_OP(sh);
725 break;
726 case 6:
727 PAS_OP(uq);
728 break;
729 case 7:
730 PAS_OP(uh);
731 break;
732 #undef gen_pas_helper
735 #undef PAS_OP
737 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
738 #define PAS_OP(pfx) \
739 switch (op1) { \
740 case 0: gen_pas_helper(glue(pfx,add8)); break; \
741 case 1: gen_pas_helper(glue(pfx,add16)); break; \
742 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
743 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
744 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
745 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
747 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
749 TCGv_ptr tmp;
751 switch (op2) {
752 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
753 case 0:
754 tmp = tcg_temp_new_ptr();
755 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
756 PAS_OP(s)
757 tcg_temp_free_ptr(tmp);
758 break;
759 case 4:
760 tmp = tcg_temp_new_ptr();
761 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
762 PAS_OP(u)
763 tcg_temp_free_ptr(tmp);
764 break;
765 #undef gen_pas_helper
766 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
767 case 1:
768 PAS_OP(q);
769 break;
770 case 2:
771 PAS_OP(sh);
772 break;
773 case 5:
774 PAS_OP(uq);
775 break;
776 case 6:
777 PAS_OP(uh);
778 break;
779 #undef gen_pas_helper
782 #undef PAS_OP
785 * Generate a conditional based on ARM condition code cc.
786 * This is common between ARM and Aarch64 targets.
788 void arm_test_cc(DisasCompare *cmp, int cc)
790 TCGv_i32 value;
791 TCGCond cond;
792 bool global = true;
794 switch (cc) {
795 case 0: /* eq: Z */
796 case 1: /* ne: !Z */
797 cond = TCG_COND_EQ;
798 value = cpu_ZF;
799 break;
801 case 2: /* cs: C */
802 case 3: /* cc: !C */
803 cond = TCG_COND_NE;
804 value = cpu_CF;
805 break;
807 case 4: /* mi: N */
808 case 5: /* pl: !N */
809 cond = TCG_COND_LT;
810 value = cpu_NF;
811 break;
813 case 6: /* vs: V */
814 case 7: /* vc: !V */
815 cond = TCG_COND_LT;
816 value = cpu_VF;
817 break;
819 case 8: /* hi: C && !Z */
820 case 9: /* ls: !C || Z -> !(C && !Z) */
821 cond = TCG_COND_NE;
822 value = tcg_temp_new_i32();
823 global = false;
824 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
825 ZF is non-zero for !Z; so AND the two subexpressions. */
826 tcg_gen_neg_i32(value, cpu_CF);
827 tcg_gen_and_i32(value, value, cpu_ZF);
828 break;
830 case 10: /* ge: N == V -> N ^ V == 0 */
831 case 11: /* lt: N != V -> N ^ V != 0 */
832 /* Since we're only interested in the sign bit, == 0 is >= 0. */
833 cond = TCG_COND_GE;
834 value = tcg_temp_new_i32();
835 global = false;
836 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
837 break;
839 case 12: /* gt: !Z && N == V */
840 case 13: /* le: Z || N != V */
841 cond = TCG_COND_NE;
842 value = tcg_temp_new_i32();
843 global = false;
844 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
845 * the sign bit then AND with ZF to yield the result. */
846 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
847 tcg_gen_sari_i32(value, value, 31);
848 tcg_gen_andc_i32(value, cpu_ZF, value);
849 break;
851 case 14: /* always */
852 case 15: /* always */
853 /* Use the ALWAYS condition, which will fold early.
854 * It doesn't matter what we use for the value. */
855 cond = TCG_COND_ALWAYS;
856 value = cpu_ZF;
857 goto no_invert;
859 default:
860 fprintf(stderr, "Bad condition code 0x%x\n", cc);
861 abort();
864 if (cc & 1) {
865 cond = tcg_invert_cond(cond);
868 no_invert:
869 cmp->cond = cond;
870 cmp->value = value;
871 cmp->value_global = global;
874 void arm_free_cc(DisasCompare *cmp)
876 if (!cmp->value_global) {
877 tcg_temp_free_i32(cmp->value);
881 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
883 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
886 void arm_gen_test_cc(int cc, TCGLabel *label)
888 DisasCompare cmp;
889 arm_test_cc(&cmp, cc);
890 arm_jump_cc(&cmp, label);
891 arm_free_cc(&cmp);
894 static const uint8_t table_logic_cc[16] = {
895 1, /* and */
896 1, /* xor */
897 0, /* sub */
898 0, /* rsb */
899 0, /* add */
900 0, /* adc */
901 0, /* sbc */
902 0, /* rsc */
903 1, /* andl */
904 1, /* xorl */
905 0, /* cmp */
906 0, /* cmn */
907 1, /* orr */
908 1, /* mov */
909 1, /* bic */
910 1, /* mvn */
913 static inline void gen_set_condexec(DisasContext *s)
915 if (s->condexec_mask) {
916 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
917 TCGv_i32 tmp = tcg_temp_new_i32();
918 tcg_gen_movi_i32(tmp, val);
919 store_cpu_field(tmp, condexec_bits);
923 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
925 tcg_gen_movi_i32(cpu_R[15], val);
928 /* Set PC and Thumb state from an immediate address. */
929 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
931 TCGv_i32 tmp;
933 s->is_jmp = DISAS_JUMP;
934 if (s->thumb != (addr & 1)) {
935 tmp = tcg_temp_new_i32();
936 tcg_gen_movi_i32(tmp, addr & 1);
937 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
938 tcg_temp_free_i32(tmp);
940 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
943 /* Set PC and Thumb state from var. var is marked as dead. */
944 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
946 s->is_jmp = DISAS_JUMP;
947 tcg_gen_andi_i32(cpu_R[15], var, ~1);
948 tcg_gen_andi_i32(var, var, 1);
949 store_cpu_field(var, thumb);
952 /* Set PC and Thumb state from var. var is marked as dead.
953 * For M-profile CPUs, include logic to detect exception-return
954 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
955 * and BX reg, and no others, and happens only for code in Handler mode.
957 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
959 /* Generate the same code here as for a simple bx, but flag via
960 * s->is_jmp that we need to do the rest of the work later.
962 gen_bx(s, var);
963 if (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M)) {
964 s->is_jmp = DISAS_BX_EXCRET;
968 static inline void gen_bx_excret_final_code(DisasContext *s)
970 /* Generate the code to finish possible exception return and end the TB */
971 TCGLabel *excret_label = gen_new_label();
973 /* Is the new PC value in the magic range indicating exception return? */
974 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], 0xff000000, excret_label);
975 /* No: end the TB as we would for a DISAS_JMP */
976 if (is_singlestepping(s)) {
977 gen_singlestep_exception(s);
978 } else {
979 tcg_gen_exit_tb(0);
981 gen_set_label(excret_label);
982 /* Yes: this is an exception return.
983 * At this point in runtime env->regs[15] and env->thumb will hold
984 * the exception-return magic number, which do_v7m_exception_exit()
985 * will read. Nothing else will be able to see those values because
986 * the cpu-exec main loop guarantees that we will always go straight
987 * from raising the exception to the exception-handling code.
989 * gen_ss_advance(s) does nothing on M profile currently but
990 * calling it is conceptually the right thing as we have executed
991 * this instruction (compare SWI, HVC, SMC handling).
993 gen_ss_advance(s);
994 gen_exception_internal(EXCP_EXCEPTION_EXIT);
997 /* Variant of store_reg which uses branch&exchange logic when storing
998 to r15 in ARM architecture v7 and above. The source must be a temporary
999 and will be marked as dead. */
1000 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1002 if (reg == 15 && ENABLE_ARCH_7) {
1003 gen_bx(s, var);
1004 } else {
1005 store_reg(s, reg, var);
1009 /* Variant of store_reg which uses branch&exchange logic when storing
1010 * to r15 in ARM architecture v5T and above. This is used for storing
1011 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1012 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1013 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1015 if (reg == 15 && ENABLE_ARCH_5) {
1016 gen_bx_excret(s, var);
1017 } else {
1018 store_reg(s, reg, var);
1022 #ifdef CONFIG_USER_ONLY
1023 #define IS_USER_ONLY 1
1024 #else
1025 #define IS_USER_ONLY 0
1026 #endif
1028 /* Abstractions of "generate code to do a guest load/store for
1029 * AArch32", where a vaddr is always 32 bits (and is zero
1030 * extended if we're a 64 bit core) and data is also
1031 * 32 bits unless specifically doing a 64 bit access.
1032 * These functions work like tcg_gen_qemu_{ld,st}* except
1033 * that the address argument is TCGv_i32 rather than TCGv.
1036 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1038 TCGv addr = tcg_temp_new();
1039 tcg_gen_extu_i32_tl(addr, a32);
1041 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1042 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1043 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1045 return addr;
1048 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1049 int index, TCGMemOp opc)
1051 TCGv addr = gen_aa32_addr(s, a32, opc);
1052 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1053 tcg_temp_free(addr);
1056 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1057 int index, TCGMemOp opc)
1059 TCGv addr = gen_aa32_addr(s, a32, opc);
1060 tcg_gen_qemu_st_i32(val, addr, index, opc);
1061 tcg_temp_free(addr);
1064 #define DO_GEN_LD(SUFF, OPC) \
1065 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1066 TCGv_i32 a32, int index) \
1068 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1070 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1071 TCGv_i32 val, \
1072 TCGv_i32 a32, int index, \
1073 ISSInfo issinfo) \
1075 gen_aa32_ld##SUFF(s, val, a32, index); \
1076 disas_set_da_iss(s, OPC, issinfo); \
1079 #define DO_GEN_ST(SUFF, OPC) \
1080 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1081 TCGv_i32 a32, int index) \
1083 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1085 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1086 TCGv_i32 val, \
1087 TCGv_i32 a32, int index, \
1088 ISSInfo issinfo) \
1090 gen_aa32_st##SUFF(s, val, a32, index); \
1091 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1094 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1096 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1097 if (!IS_USER_ONLY && s->sctlr_b) {
1098 tcg_gen_rotri_i64(val, val, 32);
1102 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1103 int index, TCGMemOp opc)
1105 TCGv addr = gen_aa32_addr(s, a32, opc);
1106 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1107 gen_aa32_frob64(s, val);
1108 tcg_temp_free(addr);
1111 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1112 TCGv_i32 a32, int index)
1114 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1117 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1118 int index, TCGMemOp opc)
1120 TCGv addr = gen_aa32_addr(s, a32, opc);
1122 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1123 if (!IS_USER_ONLY && s->sctlr_b) {
1124 TCGv_i64 tmp = tcg_temp_new_i64();
1125 tcg_gen_rotri_i64(tmp, val, 32);
1126 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1127 tcg_temp_free_i64(tmp);
1128 } else {
1129 tcg_gen_qemu_st_i64(val, addr, index, opc);
1131 tcg_temp_free(addr);
1134 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1135 TCGv_i32 a32, int index)
1137 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1140 DO_GEN_LD(8s, MO_SB)
1141 DO_GEN_LD(8u, MO_UB)
1142 DO_GEN_LD(16s, MO_SW)
1143 DO_GEN_LD(16u, MO_UW)
1144 DO_GEN_LD(32u, MO_UL)
1145 DO_GEN_ST(8, MO_UB)
1146 DO_GEN_ST(16, MO_UW)
1147 DO_GEN_ST(32, MO_UL)
1149 static inline void gen_hvc(DisasContext *s, int imm16)
1151 /* The pre HVC helper handles cases when HVC gets trapped
1152 * as an undefined insn by runtime configuration (ie before
1153 * the insn really executes).
1155 gen_set_pc_im(s, s->pc - 4);
1156 gen_helper_pre_hvc(cpu_env);
1157 /* Otherwise we will treat this as a real exception which
1158 * happens after execution of the insn. (The distinction matters
1159 * for the PC value reported to the exception handler and also
1160 * for single stepping.)
1162 s->svc_imm = imm16;
1163 gen_set_pc_im(s, s->pc);
1164 s->is_jmp = DISAS_HVC;
1167 static inline void gen_smc(DisasContext *s)
1169 /* As with HVC, we may take an exception either before or after
1170 * the insn executes.
1172 TCGv_i32 tmp;
1174 gen_set_pc_im(s, s->pc - 4);
1175 tmp = tcg_const_i32(syn_aa32_smc());
1176 gen_helper_pre_smc(cpu_env, tmp);
1177 tcg_temp_free_i32(tmp);
1178 gen_set_pc_im(s, s->pc);
1179 s->is_jmp = DISAS_SMC;
1182 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1184 gen_set_condexec(s);
1185 gen_set_pc_im(s, s->pc - offset);
1186 gen_exception_internal(excp);
1187 s->is_jmp = DISAS_EXC;
1190 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1191 int syn, uint32_t target_el)
1193 gen_set_condexec(s);
1194 gen_set_pc_im(s, s->pc - offset);
1195 gen_exception(excp, syn, target_el);
1196 s->is_jmp = DISAS_EXC;
1199 /* Force a TB lookup after an instruction that changes the CPU state. */
1200 static inline void gen_lookup_tb(DisasContext *s)
1202 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1203 s->is_jmp = DISAS_EXIT;
1206 static inline void gen_hlt(DisasContext *s, int imm)
1208 /* HLT. This has two purposes.
1209 * Architecturally, it is an external halting debug instruction.
1210 * Since QEMU doesn't implement external debug, we treat this as
1211 * it is required for halting debug disabled: it will UNDEF.
1212 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1213 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1214 * must trigger semihosting even for ARMv7 and earlier, where
1215 * HLT was an undefined encoding.
1216 * In system mode, we don't allow userspace access to
1217 * semihosting, to provide some semblance of security
1218 * (and for consistency with our 32-bit semihosting).
1220 if (semihosting_enabled() &&
1221 #ifndef CONFIG_USER_ONLY
1222 s->current_el != 0 &&
1223 #endif
1224 (imm == (s->thumb ? 0x3c : 0xf000))) {
1225 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1226 return;
1229 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1230 default_exception_el(s));
1233 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1234 TCGv_i32 var)
1236 int val, rm, shift, shiftop;
1237 TCGv_i32 offset;
1239 if (!(insn & (1 << 25))) {
1240 /* immediate */
1241 val = insn & 0xfff;
1242 if (!(insn & (1 << 23)))
1243 val = -val;
1244 if (val != 0)
1245 tcg_gen_addi_i32(var, var, val);
1246 } else {
1247 /* shift/register */
1248 rm = (insn) & 0xf;
1249 shift = (insn >> 7) & 0x1f;
1250 shiftop = (insn >> 5) & 3;
1251 offset = load_reg(s, rm);
1252 gen_arm_shift_im(offset, shiftop, shift, 0);
1253 if (!(insn & (1 << 23)))
1254 tcg_gen_sub_i32(var, var, offset);
1255 else
1256 tcg_gen_add_i32(var, var, offset);
1257 tcg_temp_free_i32(offset);
1261 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1262 int extra, TCGv_i32 var)
1264 int val, rm;
1265 TCGv_i32 offset;
1267 if (insn & (1 << 22)) {
1268 /* immediate */
1269 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1270 if (!(insn & (1 << 23)))
1271 val = -val;
1272 val += extra;
1273 if (val != 0)
1274 tcg_gen_addi_i32(var, var, val);
1275 } else {
1276 /* register */
1277 if (extra)
1278 tcg_gen_addi_i32(var, var, extra);
1279 rm = (insn) & 0xf;
1280 offset = load_reg(s, rm);
1281 if (!(insn & (1 << 23)))
1282 tcg_gen_sub_i32(var, var, offset);
1283 else
1284 tcg_gen_add_i32(var, var, offset);
1285 tcg_temp_free_i32(offset);
1289 static TCGv_ptr get_fpstatus_ptr(int neon)
1291 TCGv_ptr statusptr = tcg_temp_new_ptr();
1292 int offset;
1293 if (neon) {
1294 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1295 } else {
1296 offset = offsetof(CPUARMState, vfp.fp_status);
1298 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1299 return statusptr;
1302 #define VFP_OP2(name) \
1303 static inline void gen_vfp_##name(int dp) \
1305 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1306 if (dp) { \
1307 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1308 } else { \
1309 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1311 tcg_temp_free_ptr(fpst); \
1314 VFP_OP2(add)
1315 VFP_OP2(sub)
1316 VFP_OP2(mul)
1317 VFP_OP2(div)
1319 #undef VFP_OP2
1321 static inline void gen_vfp_F1_mul(int dp)
1323 /* Like gen_vfp_mul() but put result in F1 */
1324 TCGv_ptr fpst = get_fpstatus_ptr(0);
1325 if (dp) {
1326 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1327 } else {
1328 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1330 tcg_temp_free_ptr(fpst);
1333 static inline void gen_vfp_F1_neg(int dp)
1335 /* Like gen_vfp_neg() but put result in F1 */
1336 if (dp) {
1337 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1338 } else {
1339 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1343 static inline void gen_vfp_abs(int dp)
1345 if (dp)
1346 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1347 else
1348 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1351 static inline void gen_vfp_neg(int dp)
1353 if (dp)
1354 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1355 else
1356 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1359 static inline void gen_vfp_sqrt(int dp)
1361 if (dp)
1362 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1363 else
1364 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1367 static inline void gen_vfp_cmp(int dp)
1369 if (dp)
1370 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1371 else
1372 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1375 static inline void gen_vfp_cmpe(int dp)
1377 if (dp)
1378 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1379 else
1380 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1383 static inline void gen_vfp_F1_ld0(int dp)
1385 if (dp)
1386 tcg_gen_movi_i64(cpu_F1d, 0);
1387 else
1388 tcg_gen_movi_i32(cpu_F1s, 0);
1391 #define VFP_GEN_ITOF(name) \
1392 static inline void gen_vfp_##name(int dp, int neon) \
1394 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1395 if (dp) { \
1396 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1397 } else { \
1398 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1400 tcg_temp_free_ptr(statusptr); \
1403 VFP_GEN_ITOF(uito)
1404 VFP_GEN_ITOF(sito)
1405 #undef VFP_GEN_ITOF
1407 #define VFP_GEN_FTOI(name) \
1408 static inline void gen_vfp_##name(int dp, int neon) \
1410 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1411 if (dp) { \
1412 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1413 } else { \
1414 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1416 tcg_temp_free_ptr(statusptr); \
1419 VFP_GEN_FTOI(toui)
1420 VFP_GEN_FTOI(touiz)
1421 VFP_GEN_FTOI(tosi)
1422 VFP_GEN_FTOI(tosiz)
1423 #undef VFP_GEN_FTOI
1425 #define VFP_GEN_FIX(name, round) \
1426 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1428 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1429 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1430 if (dp) { \
1431 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1432 statusptr); \
1433 } else { \
1434 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1435 statusptr); \
1437 tcg_temp_free_i32(tmp_shift); \
1438 tcg_temp_free_ptr(statusptr); \
1440 VFP_GEN_FIX(tosh, _round_to_zero)
1441 VFP_GEN_FIX(tosl, _round_to_zero)
1442 VFP_GEN_FIX(touh, _round_to_zero)
1443 VFP_GEN_FIX(toul, _round_to_zero)
1444 VFP_GEN_FIX(shto, )
1445 VFP_GEN_FIX(slto, )
1446 VFP_GEN_FIX(uhto, )
1447 VFP_GEN_FIX(ulto, )
1448 #undef VFP_GEN_FIX
1450 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1452 if (dp) {
1453 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1454 } else {
1455 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1459 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1461 if (dp) {
1462 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1463 } else {
1464 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1468 static inline long
1469 vfp_reg_offset (int dp, int reg)
1471 if (dp)
1472 return offsetof(CPUARMState, vfp.regs[reg]);
1473 else if (reg & 1) {
1474 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1475 + offsetof(CPU_DoubleU, l.upper);
1476 } else {
1477 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1478 + offsetof(CPU_DoubleU, l.lower);
1482 /* Return the offset of a 32-bit piece of a NEON register.
1483 zero is the least significant end of the register. */
1484 static inline long
1485 neon_reg_offset (int reg, int n)
1487 int sreg;
1488 sreg = reg * 2 + n;
1489 return vfp_reg_offset(0, sreg);
1492 static TCGv_i32 neon_load_reg(int reg, int pass)
1494 TCGv_i32 tmp = tcg_temp_new_i32();
1495 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1496 return tmp;
1499 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1501 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1502 tcg_temp_free_i32(var);
1505 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1507 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1510 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1512 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1515 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1516 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1517 #define tcg_gen_st_f32 tcg_gen_st_i32
1518 #define tcg_gen_st_f64 tcg_gen_st_i64
1520 static inline void gen_mov_F0_vreg(int dp, int reg)
1522 if (dp)
1523 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1524 else
1525 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1528 static inline void gen_mov_F1_vreg(int dp, int reg)
1530 if (dp)
1531 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1532 else
1533 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1536 static inline void gen_mov_vreg_F0(int dp, int reg)
1538 if (dp)
1539 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1540 else
1541 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1544 #define ARM_CP_RW_BIT (1 << 20)
1546 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1548 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1551 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1553 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1556 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1558 TCGv_i32 var = tcg_temp_new_i32();
1559 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1560 return var;
1563 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1565 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1566 tcg_temp_free_i32(var);
1569 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1571 iwmmxt_store_reg(cpu_M0, rn);
1574 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1576 iwmmxt_load_reg(cpu_M0, rn);
1579 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1581 iwmmxt_load_reg(cpu_V1, rn);
1582 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1585 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1587 iwmmxt_load_reg(cpu_V1, rn);
1588 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1591 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1593 iwmmxt_load_reg(cpu_V1, rn);
1594 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1597 #define IWMMXT_OP(name) \
1598 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1600 iwmmxt_load_reg(cpu_V1, rn); \
1601 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1604 #define IWMMXT_OP_ENV(name) \
1605 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1607 iwmmxt_load_reg(cpu_V1, rn); \
1608 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1611 #define IWMMXT_OP_ENV_SIZE(name) \
1612 IWMMXT_OP_ENV(name##b) \
1613 IWMMXT_OP_ENV(name##w) \
1614 IWMMXT_OP_ENV(name##l)
1616 #define IWMMXT_OP_ENV1(name) \
1617 static inline void gen_op_iwmmxt_##name##_M0(void) \
1619 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1622 IWMMXT_OP(maddsq)
1623 IWMMXT_OP(madduq)
1624 IWMMXT_OP(sadb)
1625 IWMMXT_OP(sadw)
1626 IWMMXT_OP(mulslw)
1627 IWMMXT_OP(mulshw)
1628 IWMMXT_OP(mululw)
1629 IWMMXT_OP(muluhw)
1630 IWMMXT_OP(macsw)
1631 IWMMXT_OP(macuw)
1633 IWMMXT_OP_ENV_SIZE(unpackl)
1634 IWMMXT_OP_ENV_SIZE(unpackh)
1636 IWMMXT_OP_ENV1(unpacklub)
1637 IWMMXT_OP_ENV1(unpackluw)
1638 IWMMXT_OP_ENV1(unpacklul)
1639 IWMMXT_OP_ENV1(unpackhub)
1640 IWMMXT_OP_ENV1(unpackhuw)
1641 IWMMXT_OP_ENV1(unpackhul)
1642 IWMMXT_OP_ENV1(unpacklsb)
1643 IWMMXT_OP_ENV1(unpacklsw)
1644 IWMMXT_OP_ENV1(unpacklsl)
1645 IWMMXT_OP_ENV1(unpackhsb)
1646 IWMMXT_OP_ENV1(unpackhsw)
1647 IWMMXT_OP_ENV1(unpackhsl)
1649 IWMMXT_OP_ENV_SIZE(cmpeq)
1650 IWMMXT_OP_ENV_SIZE(cmpgtu)
1651 IWMMXT_OP_ENV_SIZE(cmpgts)
1653 IWMMXT_OP_ENV_SIZE(mins)
1654 IWMMXT_OP_ENV_SIZE(minu)
1655 IWMMXT_OP_ENV_SIZE(maxs)
1656 IWMMXT_OP_ENV_SIZE(maxu)
1658 IWMMXT_OP_ENV_SIZE(subn)
1659 IWMMXT_OP_ENV_SIZE(addn)
1660 IWMMXT_OP_ENV_SIZE(subu)
1661 IWMMXT_OP_ENV_SIZE(addu)
1662 IWMMXT_OP_ENV_SIZE(subs)
1663 IWMMXT_OP_ENV_SIZE(adds)
1665 IWMMXT_OP_ENV(avgb0)
1666 IWMMXT_OP_ENV(avgb1)
1667 IWMMXT_OP_ENV(avgw0)
1668 IWMMXT_OP_ENV(avgw1)
1670 IWMMXT_OP_ENV(packuw)
1671 IWMMXT_OP_ENV(packul)
1672 IWMMXT_OP_ENV(packuq)
1673 IWMMXT_OP_ENV(packsw)
1674 IWMMXT_OP_ENV(packsl)
1675 IWMMXT_OP_ENV(packsq)
1677 static void gen_op_iwmmxt_set_mup(void)
1679 TCGv_i32 tmp;
1680 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1681 tcg_gen_ori_i32(tmp, tmp, 2);
1682 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1685 static void gen_op_iwmmxt_set_cup(void)
1687 TCGv_i32 tmp;
1688 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1689 tcg_gen_ori_i32(tmp, tmp, 1);
1690 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1693 static void gen_op_iwmmxt_setpsr_nz(void)
1695 TCGv_i32 tmp = tcg_temp_new_i32();
1696 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1697 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1700 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1702 iwmmxt_load_reg(cpu_V1, rn);
1703 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1704 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1707 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1708 TCGv_i32 dest)
1710 int rd;
1711 uint32_t offset;
1712 TCGv_i32 tmp;
1714 rd = (insn >> 16) & 0xf;
1715 tmp = load_reg(s, rd);
1717 offset = (insn & 0xff) << ((insn >> 7) & 2);
1718 if (insn & (1 << 24)) {
1719 /* Pre indexed */
1720 if (insn & (1 << 23))
1721 tcg_gen_addi_i32(tmp, tmp, offset);
1722 else
1723 tcg_gen_addi_i32(tmp, tmp, -offset);
1724 tcg_gen_mov_i32(dest, tmp);
1725 if (insn & (1 << 21))
1726 store_reg(s, rd, tmp);
1727 else
1728 tcg_temp_free_i32(tmp);
1729 } else if (insn & (1 << 21)) {
1730 /* Post indexed */
1731 tcg_gen_mov_i32(dest, tmp);
1732 if (insn & (1 << 23))
1733 tcg_gen_addi_i32(tmp, tmp, offset);
1734 else
1735 tcg_gen_addi_i32(tmp, tmp, -offset);
1736 store_reg(s, rd, tmp);
1737 } else if (!(insn & (1 << 23)))
1738 return 1;
1739 return 0;
1742 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1744 int rd = (insn >> 0) & 0xf;
1745 TCGv_i32 tmp;
1747 if (insn & (1 << 8)) {
1748 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1749 return 1;
1750 } else {
1751 tmp = iwmmxt_load_creg(rd);
1753 } else {
1754 tmp = tcg_temp_new_i32();
1755 iwmmxt_load_reg(cpu_V0, rd);
1756 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1758 tcg_gen_andi_i32(tmp, tmp, mask);
1759 tcg_gen_mov_i32(dest, tmp);
1760 tcg_temp_free_i32(tmp);
1761 return 0;
1764 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1765 (ie. an undefined instruction). */
1766 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1768 int rd, wrd;
1769 int rdhi, rdlo, rd0, rd1, i;
1770 TCGv_i32 addr;
1771 TCGv_i32 tmp, tmp2, tmp3;
1773 if ((insn & 0x0e000e00) == 0x0c000000) {
1774 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1775 wrd = insn & 0xf;
1776 rdlo = (insn >> 12) & 0xf;
1777 rdhi = (insn >> 16) & 0xf;
1778 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1779 iwmmxt_load_reg(cpu_V0, wrd);
1780 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1781 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1782 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1783 } else { /* TMCRR */
1784 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1785 iwmmxt_store_reg(cpu_V0, wrd);
1786 gen_op_iwmmxt_set_mup();
1788 return 0;
1791 wrd = (insn >> 12) & 0xf;
1792 addr = tcg_temp_new_i32();
1793 if (gen_iwmmxt_address(s, insn, addr)) {
1794 tcg_temp_free_i32(addr);
1795 return 1;
1797 if (insn & ARM_CP_RW_BIT) {
1798 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1799 tmp = tcg_temp_new_i32();
1800 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1801 iwmmxt_store_creg(wrd, tmp);
1802 } else {
1803 i = 1;
1804 if (insn & (1 << 8)) {
1805 if (insn & (1 << 22)) { /* WLDRD */
1806 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1807 i = 0;
1808 } else { /* WLDRW wRd */
1809 tmp = tcg_temp_new_i32();
1810 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1812 } else {
1813 tmp = tcg_temp_new_i32();
1814 if (insn & (1 << 22)) { /* WLDRH */
1815 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1816 } else { /* WLDRB */
1817 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1820 if (i) {
1821 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1822 tcg_temp_free_i32(tmp);
1824 gen_op_iwmmxt_movq_wRn_M0(wrd);
1826 } else {
1827 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1828 tmp = iwmmxt_load_creg(wrd);
1829 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1830 } else {
1831 gen_op_iwmmxt_movq_M0_wRn(wrd);
1832 tmp = tcg_temp_new_i32();
1833 if (insn & (1 << 8)) {
1834 if (insn & (1 << 22)) { /* WSTRD */
1835 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1836 } else { /* WSTRW wRd */
1837 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1838 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1840 } else {
1841 if (insn & (1 << 22)) { /* WSTRH */
1842 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1843 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1844 } else { /* WSTRB */
1845 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1846 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1850 tcg_temp_free_i32(tmp);
1852 tcg_temp_free_i32(addr);
1853 return 0;
1856 if ((insn & 0x0f000000) != 0x0e000000)
1857 return 1;
1859 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1860 case 0x000: /* WOR */
1861 wrd = (insn >> 12) & 0xf;
1862 rd0 = (insn >> 0) & 0xf;
1863 rd1 = (insn >> 16) & 0xf;
1864 gen_op_iwmmxt_movq_M0_wRn(rd0);
1865 gen_op_iwmmxt_orq_M0_wRn(rd1);
1866 gen_op_iwmmxt_setpsr_nz();
1867 gen_op_iwmmxt_movq_wRn_M0(wrd);
1868 gen_op_iwmmxt_set_mup();
1869 gen_op_iwmmxt_set_cup();
1870 break;
1871 case 0x011: /* TMCR */
1872 if (insn & 0xf)
1873 return 1;
1874 rd = (insn >> 12) & 0xf;
1875 wrd = (insn >> 16) & 0xf;
1876 switch (wrd) {
1877 case ARM_IWMMXT_wCID:
1878 case ARM_IWMMXT_wCASF:
1879 break;
1880 case ARM_IWMMXT_wCon:
1881 gen_op_iwmmxt_set_cup();
1882 /* Fall through. */
1883 case ARM_IWMMXT_wCSSF:
1884 tmp = iwmmxt_load_creg(wrd);
1885 tmp2 = load_reg(s, rd);
1886 tcg_gen_andc_i32(tmp, tmp, tmp2);
1887 tcg_temp_free_i32(tmp2);
1888 iwmmxt_store_creg(wrd, tmp);
1889 break;
1890 case ARM_IWMMXT_wCGR0:
1891 case ARM_IWMMXT_wCGR1:
1892 case ARM_IWMMXT_wCGR2:
1893 case ARM_IWMMXT_wCGR3:
1894 gen_op_iwmmxt_set_cup();
1895 tmp = load_reg(s, rd);
1896 iwmmxt_store_creg(wrd, tmp);
1897 break;
1898 default:
1899 return 1;
1901 break;
1902 case 0x100: /* WXOR */
1903 wrd = (insn >> 12) & 0xf;
1904 rd0 = (insn >> 0) & 0xf;
1905 rd1 = (insn >> 16) & 0xf;
1906 gen_op_iwmmxt_movq_M0_wRn(rd0);
1907 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1908 gen_op_iwmmxt_setpsr_nz();
1909 gen_op_iwmmxt_movq_wRn_M0(wrd);
1910 gen_op_iwmmxt_set_mup();
1911 gen_op_iwmmxt_set_cup();
1912 break;
1913 case 0x111: /* TMRC */
1914 if (insn & 0xf)
1915 return 1;
1916 rd = (insn >> 12) & 0xf;
1917 wrd = (insn >> 16) & 0xf;
1918 tmp = iwmmxt_load_creg(wrd);
1919 store_reg(s, rd, tmp);
1920 break;
1921 case 0x300: /* WANDN */
1922 wrd = (insn >> 12) & 0xf;
1923 rd0 = (insn >> 0) & 0xf;
1924 rd1 = (insn >> 16) & 0xf;
1925 gen_op_iwmmxt_movq_M0_wRn(rd0);
1926 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1927 gen_op_iwmmxt_andq_M0_wRn(rd1);
1928 gen_op_iwmmxt_setpsr_nz();
1929 gen_op_iwmmxt_movq_wRn_M0(wrd);
1930 gen_op_iwmmxt_set_mup();
1931 gen_op_iwmmxt_set_cup();
1932 break;
1933 case 0x200: /* WAND */
1934 wrd = (insn >> 12) & 0xf;
1935 rd0 = (insn >> 0) & 0xf;
1936 rd1 = (insn >> 16) & 0xf;
1937 gen_op_iwmmxt_movq_M0_wRn(rd0);
1938 gen_op_iwmmxt_andq_M0_wRn(rd1);
1939 gen_op_iwmmxt_setpsr_nz();
1940 gen_op_iwmmxt_movq_wRn_M0(wrd);
1941 gen_op_iwmmxt_set_mup();
1942 gen_op_iwmmxt_set_cup();
1943 break;
1944 case 0x810: case 0xa10: /* WMADD */
1945 wrd = (insn >> 12) & 0xf;
1946 rd0 = (insn >> 0) & 0xf;
1947 rd1 = (insn >> 16) & 0xf;
1948 gen_op_iwmmxt_movq_M0_wRn(rd0);
1949 if (insn & (1 << 21))
1950 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1951 else
1952 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1953 gen_op_iwmmxt_movq_wRn_M0(wrd);
1954 gen_op_iwmmxt_set_mup();
1955 break;
1956 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1957 wrd = (insn >> 12) & 0xf;
1958 rd0 = (insn >> 16) & 0xf;
1959 rd1 = (insn >> 0) & 0xf;
1960 gen_op_iwmmxt_movq_M0_wRn(rd0);
1961 switch ((insn >> 22) & 3) {
1962 case 0:
1963 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1964 break;
1965 case 1:
1966 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1967 break;
1968 case 2:
1969 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1970 break;
1971 case 3:
1972 return 1;
1974 gen_op_iwmmxt_movq_wRn_M0(wrd);
1975 gen_op_iwmmxt_set_mup();
1976 gen_op_iwmmxt_set_cup();
1977 break;
1978 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1979 wrd = (insn >> 12) & 0xf;
1980 rd0 = (insn >> 16) & 0xf;
1981 rd1 = (insn >> 0) & 0xf;
1982 gen_op_iwmmxt_movq_M0_wRn(rd0);
1983 switch ((insn >> 22) & 3) {
1984 case 0:
1985 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1986 break;
1987 case 1:
1988 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1989 break;
1990 case 2:
1991 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1992 break;
1993 case 3:
1994 return 1;
1996 gen_op_iwmmxt_movq_wRn_M0(wrd);
1997 gen_op_iwmmxt_set_mup();
1998 gen_op_iwmmxt_set_cup();
1999 break;
2000 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2001 wrd = (insn >> 12) & 0xf;
2002 rd0 = (insn >> 16) & 0xf;
2003 rd1 = (insn >> 0) & 0xf;
2004 gen_op_iwmmxt_movq_M0_wRn(rd0);
2005 if (insn & (1 << 22))
2006 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2007 else
2008 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2009 if (!(insn & (1 << 20)))
2010 gen_op_iwmmxt_addl_M0_wRn(wrd);
2011 gen_op_iwmmxt_movq_wRn_M0(wrd);
2012 gen_op_iwmmxt_set_mup();
2013 break;
2014 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2015 wrd = (insn >> 12) & 0xf;
2016 rd0 = (insn >> 16) & 0xf;
2017 rd1 = (insn >> 0) & 0xf;
2018 gen_op_iwmmxt_movq_M0_wRn(rd0);
2019 if (insn & (1 << 21)) {
2020 if (insn & (1 << 20))
2021 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2022 else
2023 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2024 } else {
2025 if (insn & (1 << 20))
2026 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2027 else
2028 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2030 gen_op_iwmmxt_movq_wRn_M0(wrd);
2031 gen_op_iwmmxt_set_mup();
2032 break;
2033 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2034 wrd = (insn >> 12) & 0xf;
2035 rd0 = (insn >> 16) & 0xf;
2036 rd1 = (insn >> 0) & 0xf;
2037 gen_op_iwmmxt_movq_M0_wRn(rd0);
2038 if (insn & (1 << 21))
2039 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2040 else
2041 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2042 if (!(insn & (1 << 20))) {
2043 iwmmxt_load_reg(cpu_V1, wrd);
2044 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2046 gen_op_iwmmxt_movq_wRn_M0(wrd);
2047 gen_op_iwmmxt_set_mup();
2048 break;
2049 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2050 wrd = (insn >> 12) & 0xf;
2051 rd0 = (insn >> 16) & 0xf;
2052 rd1 = (insn >> 0) & 0xf;
2053 gen_op_iwmmxt_movq_M0_wRn(rd0);
2054 switch ((insn >> 22) & 3) {
2055 case 0:
2056 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2057 break;
2058 case 1:
2059 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2060 break;
2061 case 2:
2062 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2063 break;
2064 case 3:
2065 return 1;
2067 gen_op_iwmmxt_movq_wRn_M0(wrd);
2068 gen_op_iwmmxt_set_mup();
2069 gen_op_iwmmxt_set_cup();
2070 break;
2071 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2072 wrd = (insn >> 12) & 0xf;
2073 rd0 = (insn >> 16) & 0xf;
2074 rd1 = (insn >> 0) & 0xf;
2075 gen_op_iwmmxt_movq_M0_wRn(rd0);
2076 if (insn & (1 << 22)) {
2077 if (insn & (1 << 20))
2078 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2079 else
2080 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2081 } else {
2082 if (insn & (1 << 20))
2083 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2084 else
2085 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2087 gen_op_iwmmxt_movq_wRn_M0(wrd);
2088 gen_op_iwmmxt_set_mup();
2089 gen_op_iwmmxt_set_cup();
2090 break;
2091 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2092 wrd = (insn >> 12) & 0xf;
2093 rd0 = (insn >> 16) & 0xf;
2094 rd1 = (insn >> 0) & 0xf;
2095 gen_op_iwmmxt_movq_M0_wRn(rd0);
2096 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2097 tcg_gen_andi_i32(tmp, tmp, 7);
2098 iwmmxt_load_reg(cpu_V1, rd1);
2099 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2100 tcg_temp_free_i32(tmp);
2101 gen_op_iwmmxt_movq_wRn_M0(wrd);
2102 gen_op_iwmmxt_set_mup();
2103 break;
2104 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2105 if (((insn >> 6) & 3) == 3)
2106 return 1;
2107 rd = (insn >> 12) & 0xf;
2108 wrd = (insn >> 16) & 0xf;
2109 tmp = load_reg(s, rd);
2110 gen_op_iwmmxt_movq_M0_wRn(wrd);
2111 switch ((insn >> 6) & 3) {
2112 case 0:
2113 tmp2 = tcg_const_i32(0xff);
2114 tmp3 = tcg_const_i32((insn & 7) << 3);
2115 break;
2116 case 1:
2117 tmp2 = tcg_const_i32(0xffff);
2118 tmp3 = tcg_const_i32((insn & 3) << 4);
2119 break;
2120 case 2:
2121 tmp2 = tcg_const_i32(0xffffffff);
2122 tmp3 = tcg_const_i32((insn & 1) << 5);
2123 break;
2124 default:
2125 TCGV_UNUSED_I32(tmp2);
2126 TCGV_UNUSED_I32(tmp3);
2128 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2129 tcg_temp_free_i32(tmp3);
2130 tcg_temp_free_i32(tmp2);
2131 tcg_temp_free_i32(tmp);
2132 gen_op_iwmmxt_movq_wRn_M0(wrd);
2133 gen_op_iwmmxt_set_mup();
2134 break;
2135 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2136 rd = (insn >> 12) & 0xf;
2137 wrd = (insn >> 16) & 0xf;
2138 if (rd == 15 || ((insn >> 22) & 3) == 3)
2139 return 1;
2140 gen_op_iwmmxt_movq_M0_wRn(wrd);
2141 tmp = tcg_temp_new_i32();
2142 switch ((insn >> 22) & 3) {
2143 case 0:
2144 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2145 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2146 if (insn & 8) {
2147 tcg_gen_ext8s_i32(tmp, tmp);
2148 } else {
2149 tcg_gen_andi_i32(tmp, tmp, 0xff);
2151 break;
2152 case 1:
2153 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2154 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2155 if (insn & 8) {
2156 tcg_gen_ext16s_i32(tmp, tmp);
2157 } else {
2158 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2160 break;
2161 case 2:
2162 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2163 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2164 break;
2166 store_reg(s, rd, tmp);
2167 break;
2168 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2169 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2170 return 1;
2171 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2172 switch ((insn >> 22) & 3) {
2173 case 0:
2174 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2175 break;
2176 case 1:
2177 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2178 break;
2179 case 2:
2180 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2181 break;
2183 tcg_gen_shli_i32(tmp, tmp, 28);
2184 gen_set_nzcv(tmp);
2185 tcg_temp_free_i32(tmp);
2186 break;
2187 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2188 if (((insn >> 6) & 3) == 3)
2189 return 1;
2190 rd = (insn >> 12) & 0xf;
2191 wrd = (insn >> 16) & 0xf;
2192 tmp = load_reg(s, rd);
2193 switch ((insn >> 6) & 3) {
2194 case 0:
2195 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2196 break;
2197 case 1:
2198 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2199 break;
2200 case 2:
2201 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2202 break;
2204 tcg_temp_free_i32(tmp);
2205 gen_op_iwmmxt_movq_wRn_M0(wrd);
2206 gen_op_iwmmxt_set_mup();
2207 break;
2208 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2209 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2210 return 1;
2211 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2212 tmp2 = tcg_temp_new_i32();
2213 tcg_gen_mov_i32(tmp2, tmp);
2214 switch ((insn >> 22) & 3) {
2215 case 0:
2216 for (i = 0; i < 7; i ++) {
2217 tcg_gen_shli_i32(tmp2, tmp2, 4);
2218 tcg_gen_and_i32(tmp, tmp, tmp2);
2220 break;
2221 case 1:
2222 for (i = 0; i < 3; i ++) {
2223 tcg_gen_shli_i32(tmp2, tmp2, 8);
2224 tcg_gen_and_i32(tmp, tmp, tmp2);
2226 break;
2227 case 2:
2228 tcg_gen_shli_i32(tmp2, tmp2, 16);
2229 tcg_gen_and_i32(tmp, tmp, tmp2);
2230 break;
2232 gen_set_nzcv(tmp);
2233 tcg_temp_free_i32(tmp2);
2234 tcg_temp_free_i32(tmp);
2235 break;
2236 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2237 wrd = (insn >> 12) & 0xf;
2238 rd0 = (insn >> 16) & 0xf;
2239 gen_op_iwmmxt_movq_M0_wRn(rd0);
2240 switch ((insn >> 22) & 3) {
2241 case 0:
2242 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2243 break;
2244 case 1:
2245 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2246 break;
2247 case 2:
2248 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2249 break;
2250 case 3:
2251 return 1;
2253 gen_op_iwmmxt_movq_wRn_M0(wrd);
2254 gen_op_iwmmxt_set_mup();
2255 break;
2256 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2257 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2258 return 1;
2259 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2260 tmp2 = tcg_temp_new_i32();
2261 tcg_gen_mov_i32(tmp2, tmp);
2262 switch ((insn >> 22) & 3) {
2263 case 0:
2264 for (i = 0; i < 7; i ++) {
2265 tcg_gen_shli_i32(tmp2, tmp2, 4);
2266 tcg_gen_or_i32(tmp, tmp, tmp2);
2268 break;
2269 case 1:
2270 for (i = 0; i < 3; i ++) {
2271 tcg_gen_shli_i32(tmp2, tmp2, 8);
2272 tcg_gen_or_i32(tmp, tmp, tmp2);
2274 break;
2275 case 2:
2276 tcg_gen_shli_i32(tmp2, tmp2, 16);
2277 tcg_gen_or_i32(tmp, tmp, tmp2);
2278 break;
2280 gen_set_nzcv(tmp);
2281 tcg_temp_free_i32(tmp2);
2282 tcg_temp_free_i32(tmp);
2283 break;
2284 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2285 rd = (insn >> 12) & 0xf;
2286 rd0 = (insn >> 16) & 0xf;
2287 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2288 return 1;
2289 gen_op_iwmmxt_movq_M0_wRn(rd0);
2290 tmp = tcg_temp_new_i32();
2291 switch ((insn >> 22) & 3) {
2292 case 0:
2293 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2294 break;
2295 case 1:
2296 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2297 break;
2298 case 2:
2299 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2300 break;
2302 store_reg(s, rd, tmp);
2303 break;
2304 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2305 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2306 wrd = (insn >> 12) & 0xf;
2307 rd0 = (insn >> 16) & 0xf;
2308 rd1 = (insn >> 0) & 0xf;
2309 gen_op_iwmmxt_movq_M0_wRn(rd0);
2310 switch ((insn >> 22) & 3) {
2311 case 0:
2312 if (insn & (1 << 21))
2313 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2314 else
2315 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2316 break;
2317 case 1:
2318 if (insn & (1 << 21))
2319 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2320 else
2321 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2322 break;
2323 case 2:
2324 if (insn & (1 << 21))
2325 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2326 else
2327 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2328 break;
2329 case 3:
2330 return 1;
2332 gen_op_iwmmxt_movq_wRn_M0(wrd);
2333 gen_op_iwmmxt_set_mup();
2334 gen_op_iwmmxt_set_cup();
2335 break;
2336 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2337 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2338 wrd = (insn >> 12) & 0xf;
2339 rd0 = (insn >> 16) & 0xf;
2340 gen_op_iwmmxt_movq_M0_wRn(rd0);
2341 switch ((insn >> 22) & 3) {
2342 case 0:
2343 if (insn & (1 << 21))
2344 gen_op_iwmmxt_unpacklsb_M0();
2345 else
2346 gen_op_iwmmxt_unpacklub_M0();
2347 break;
2348 case 1:
2349 if (insn & (1 << 21))
2350 gen_op_iwmmxt_unpacklsw_M0();
2351 else
2352 gen_op_iwmmxt_unpackluw_M0();
2353 break;
2354 case 2:
2355 if (insn & (1 << 21))
2356 gen_op_iwmmxt_unpacklsl_M0();
2357 else
2358 gen_op_iwmmxt_unpacklul_M0();
2359 break;
2360 case 3:
2361 return 1;
2363 gen_op_iwmmxt_movq_wRn_M0(wrd);
2364 gen_op_iwmmxt_set_mup();
2365 gen_op_iwmmxt_set_cup();
2366 break;
2367 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2368 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2369 wrd = (insn >> 12) & 0xf;
2370 rd0 = (insn >> 16) & 0xf;
2371 gen_op_iwmmxt_movq_M0_wRn(rd0);
2372 switch ((insn >> 22) & 3) {
2373 case 0:
2374 if (insn & (1 << 21))
2375 gen_op_iwmmxt_unpackhsb_M0();
2376 else
2377 gen_op_iwmmxt_unpackhub_M0();
2378 break;
2379 case 1:
2380 if (insn & (1 << 21))
2381 gen_op_iwmmxt_unpackhsw_M0();
2382 else
2383 gen_op_iwmmxt_unpackhuw_M0();
2384 break;
2385 case 2:
2386 if (insn & (1 << 21))
2387 gen_op_iwmmxt_unpackhsl_M0();
2388 else
2389 gen_op_iwmmxt_unpackhul_M0();
2390 break;
2391 case 3:
2392 return 1;
2394 gen_op_iwmmxt_movq_wRn_M0(wrd);
2395 gen_op_iwmmxt_set_mup();
2396 gen_op_iwmmxt_set_cup();
2397 break;
2398 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2399 case 0x214: case 0x614: case 0xa14: case 0xe14:
2400 if (((insn >> 22) & 3) == 0)
2401 return 1;
2402 wrd = (insn >> 12) & 0xf;
2403 rd0 = (insn >> 16) & 0xf;
2404 gen_op_iwmmxt_movq_M0_wRn(rd0);
2405 tmp = tcg_temp_new_i32();
2406 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2407 tcg_temp_free_i32(tmp);
2408 return 1;
2410 switch ((insn >> 22) & 3) {
2411 case 1:
2412 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2413 break;
2414 case 2:
2415 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2416 break;
2417 case 3:
2418 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2419 break;
2421 tcg_temp_free_i32(tmp);
2422 gen_op_iwmmxt_movq_wRn_M0(wrd);
2423 gen_op_iwmmxt_set_mup();
2424 gen_op_iwmmxt_set_cup();
2425 break;
2426 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2427 case 0x014: case 0x414: case 0x814: case 0xc14:
2428 if (((insn >> 22) & 3) == 0)
2429 return 1;
2430 wrd = (insn >> 12) & 0xf;
2431 rd0 = (insn >> 16) & 0xf;
2432 gen_op_iwmmxt_movq_M0_wRn(rd0);
2433 tmp = tcg_temp_new_i32();
2434 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2435 tcg_temp_free_i32(tmp);
2436 return 1;
2438 switch ((insn >> 22) & 3) {
2439 case 1:
2440 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2441 break;
2442 case 2:
2443 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2444 break;
2445 case 3:
2446 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2447 break;
2449 tcg_temp_free_i32(tmp);
2450 gen_op_iwmmxt_movq_wRn_M0(wrd);
2451 gen_op_iwmmxt_set_mup();
2452 gen_op_iwmmxt_set_cup();
2453 break;
2454 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2455 case 0x114: case 0x514: case 0x914: case 0xd14:
2456 if (((insn >> 22) & 3) == 0)
2457 return 1;
2458 wrd = (insn >> 12) & 0xf;
2459 rd0 = (insn >> 16) & 0xf;
2460 gen_op_iwmmxt_movq_M0_wRn(rd0);
2461 tmp = tcg_temp_new_i32();
2462 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2463 tcg_temp_free_i32(tmp);
2464 return 1;
2466 switch ((insn >> 22) & 3) {
2467 case 1:
2468 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2469 break;
2470 case 2:
2471 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2472 break;
2473 case 3:
2474 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2475 break;
2477 tcg_temp_free_i32(tmp);
2478 gen_op_iwmmxt_movq_wRn_M0(wrd);
2479 gen_op_iwmmxt_set_mup();
2480 gen_op_iwmmxt_set_cup();
2481 break;
2482 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2483 case 0x314: case 0x714: case 0xb14: case 0xf14:
2484 if (((insn >> 22) & 3) == 0)
2485 return 1;
2486 wrd = (insn >> 12) & 0xf;
2487 rd0 = (insn >> 16) & 0xf;
2488 gen_op_iwmmxt_movq_M0_wRn(rd0);
2489 tmp = tcg_temp_new_i32();
2490 switch ((insn >> 22) & 3) {
2491 case 1:
2492 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2493 tcg_temp_free_i32(tmp);
2494 return 1;
2496 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2497 break;
2498 case 2:
2499 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2500 tcg_temp_free_i32(tmp);
2501 return 1;
2503 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2504 break;
2505 case 3:
2506 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2507 tcg_temp_free_i32(tmp);
2508 return 1;
2510 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2511 break;
2513 tcg_temp_free_i32(tmp);
2514 gen_op_iwmmxt_movq_wRn_M0(wrd);
2515 gen_op_iwmmxt_set_mup();
2516 gen_op_iwmmxt_set_cup();
2517 break;
2518 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2519 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2520 wrd = (insn >> 12) & 0xf;
2521 rd0 = (insn >> 16) & 0xf;
2522 rd1 = (insn >> 0) & 0xf;
2523 gen_op_iwmmxt_movq_M0_wRn(rd0);
2524 switch ((insn >> 22) & 3) {
2525 case 0:
2526 if (insn & (1 << 21))
2527 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2528 else
2529 gen_op_iwmmxt_minub_M0_wRn(rd1);
2530 break;
2531 case 1:
2532 if (insn & (1 << 21))
2533 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2534 else
2535 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2536 break;
2537 case 2:
2538 if (insn & (1 << 21))
2539 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2540 else
2541 gen_op_iwmmxt_minul_M0_wRn(rd1);
2542 break;
2543 case 3:
2544 return 1;
2546 gen_op_iwmmxt_movq_wRn_M0(wrd);
2547 gen_op_iwmmxt_set_mup();
2548 break;
2549 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2550 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2551 wrd = (insn >> 12) & 0xf;
2552 rd0 = (insn >> 16) & 0xf;
2553 rd1 = (insn >> 0) & 0xf;
2554 gen_op_iwmmxt_movq_M0_wRn(rd0);
2555 switch ((insn >> 22) & 3) {
2556 case 0:
2557 if (insn & (1 << 21))
2558 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2559 else
2560 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2561 break;
2562 case 1:
2563 if (insn & (1 << 21))
2564 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2565 else
2566 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2567 break;
2568 case 2:
2569 if (insn & (1 << 21))
2570 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2571 else
2572 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2573 break;
2574 case 3:
2575 return 1;
2577 gen_op_iwmmxt_movq_wRn_M0(wrd);
2578 gen_op_iwmmxt_set_mup();
2579 break;
2580 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2581 case 0x402: case 0x502: case 0x602: case 0x702:
2582 wrd = (insn >> 12) & 0xf;
2583 rd0 = (insn >> 16) & 0xf;
2584 rd1 = (insn >> 0) & 0xf;
2585 gen_op_iwmmxt_movq_M0_wRn(rd0);
2586 tmp = tcg_const_i32((insn >> 20) & 3);
2587 iwmmxt_load_reg(cpu_V1, rd1);
2588 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2589 tcg_temp_free_i32(tmp);
2590 gen_op_iwmmxt_movq_wRn_M0(wrd);
2591 gen_op_iwmmxt_set_mup();
2592 break;
2593 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2594 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2595 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2596 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2597 wrd = (insn >> 12) & 0xf;
2598 rd0 = (insn >> 16) & 0xf;
2599 rd1 = (insn >> 0) & 0xf;
2600 gen_op_iwmmxt_movq_M0_wRn(rd0);
2601 switch ((insn >> 20) & 0xf) {
2602 case 0x0:
2603 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2604 break;
2605 case 0x1:
2606 gen_op_iwmmxt_subub_M0_wRn(rd1);
2607 break;
2608 case 0x3:
2609 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2610 break;
2611 case 0x4:
2612 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2613 break;
2614 case 0x5:
2615 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2616 break;
2617 case 0x7:
2618 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2619 break;
2620 case 0x8:
2621 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2622 break;
2623 case 0x9:
2624 gen_op_iwmmxt_subul_M0_wRn(rd1);
2625 break;
2626 case 0xb:
2627 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2628 break;
2629 default:
2630 return 1;
2632 gen_op_iwmmxt_movq_wRn_M0(wrd);
2633 gen_op_iwmmxt_set_mup();
2634 gen_op_iwmmxt_set_cup();
2635 break;
2636 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2637 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2638 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2639 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2640 wrd = (insn >> 12) & 0xf;
2641 rd0 = (insn >> 16) & 0xf;
2642 gen_op_iwmmxt_movq_M0_wRn(rd0);
2643 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2644 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2645 tcg_temp_free_i32(tmp);
2646 gen_op_iwmmxt_movq_wRn_M0(wrd);
2647 gen_op_iwmmxt_set_mup();
2648 gen_op_iwmmxt_set_cup();
2649 break;
2650 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2651 case 0x418: case 0x518: case 0x618: case 0x718:
2652 case 0x818: case 0x918: case 0xa18: case 0xb18:
2653 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2654 wrd = (insn >> 12) & 0xf;
2655 rd0 = (insn >> 16) & 0xf;
2656 rd1 = (insn >> 0) & 0xf;
2657 gen_op_iwmmxt_movq_M0_wRn(rd0);
2658 switch ((insn >> 20) & 0xf) {
2659 case 0x0:
2660 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2661 break;
2662 case 0x1:
2663 gen_op_iwmmxt_addub_M0_wRn(rd1);
2664 break;
2665 case 0x3:
2666 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2667 break;
2668 case 0x4:
2669 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2670 break;
2671 case 0x5:
2672 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2673 break;
2674 case 0x7:
2675 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2676 break;
2677 case 0x8:
2678 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2679 break;
2680 case 0x9:
2681 gen_op_iwmmxt_addul_M0_wRn(rd1);
2682 break;
2683 case 0xb:
2684 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2685 break;
2686 default:
2687 return 1;
2689 gen_op_iwmmxt_movq_wRn_M0(wrd);
2690 gen_op_iwmmxt_set_mup();
2691 gen_op_iwmmxt_set_cup();
2692 break;
2693 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2694 case 0x408: case 0x508: case 0x608: case 0x708:
2695 case 0x808: case 0x908: case 0xa08: case 0xb08:
2696 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2697 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2698 return 1;
2699 wrd = (insn >> 12) & 0xf;
2700 rd0 = (insn >> 16) & 0xf;
2701 rd1 = (insn >> 0) & 0xf;
2702 gen_op_iwmmxt_movq_M0_wRn(rd0);
2703 switch ((insn >> 22) & 3) {
2704 case 1:
2705 if (insn & (1 << 21))
2706 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2707 else
2708 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2709 break;
2710 case 2:
2711 if (insn & (1 << 21))
2712 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2713 else
2714 gen_op_iwmmxt_packul_M0_wRn(rd1);
2715 break;
2716 case 3:
2717 if (insn & (1 << 21))
2718 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2719 else
2720 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2721 break;
2723 gen_op_iwmmxt_movq_wRn_M0(wrd);
2724 gen_op_iwmmxt_set_mup();
2725 gen_op_iwmmxt_set_cup();
2726 break;
2727 case 0x201: case 0x203: case 0x205: case 0x207:
2728 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2729 case 0x211: case 0x213: case 0x215: case 0x217:
2730 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2731 wrd = (insn >> 5) & 0xf;
2732 rd0 = (insn >> 12) & 0xf;
2733 rd1 = (insn >> 0) & 0xf;
2734 if (rd0 == 0xf || rd1 == 0xf)
2735 return 1;
2736 gen_op_iwmmxt_movq_M0_wRn(wrd);
2737 tmp = load_reg(s, rd0);
2738 tmp2 = load_reg(s, rd1);
2739 switch ((insn >> 16) & 0xf) {
2740 case 0x0: /* TMIA */
2741 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2742 break;
2743 case 0x8: /* TMIAPH */
2744 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2745 break;
2746 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2747 if (insn & (1 << 16))
2748 tcg_gen_shri_i32(tmp, tmp, 16);
2749 if (insn & (1 << 17))
2750 tcg_gen_shri_i32(tmp2, tmp2, 16);
2751 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2752 break;
2753 default:
2754 tcg_temp_free_i32(tmp2);
2755 tcg_temp_free_i32(tmp);
2756 return 1;
2758 tcg_temp_free_i32(tmp2);
2759 tcg_temp_free_i32(tmp);
2760 gen_op_iwmmxt_movq_wRn_M0(wrd);
2761 gen_op_iwmmxt_set_mup();
2762 break;
2763 default:
2764 return 1;
2767 return 0;
2770 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2771 (ie. an undefined instruction). */
2772 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2774 int acc, rd0, rd1, rdhi, rdlo;
2775 TCGv_i32 tmp, tmp2;
2777 if ((insn & 0x0ff00f10) == 0x0e200010) {
2778 /* Multiply with Internal Accumulate Format */
2779 rd0 = (insn >> 12) & 0xf;
2780 rd1 = insn & 0xf;
2781 acc = (insn >> 5) & 7;
2783 if (acc != 0)
2784 return 1;
2786 tmp = load_reg(s, rd0);
2787 tmp2 = load_reg(s, rd1);
2788 switch ((insn >> 16) & 0xf) {
2789 case 0x0: /* MIA */
2790 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2791 break;
2792 case 0x8: /* MIAPH */
2793 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2794 break;
2795 case 0xc: /* MIABB */
2796 case 0xd: /* MIABT */
2797 case 0xe: /* MIATB */
2798 case 0xf: /* MIATT */
2799 if (insn & (1 << 16))
2800 tcg_gen_shri_i32(tmp, tmp, 16);
2801 if (insn & (1 << 17))
2802 tcg_gen_shri_i32(tmp2, tmp2, 16);
2803 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2804 break;
2805 default:
2806 return 1;
2808 tcg_temp_free_i32(tmp2);
2809 tcg_temp_free_i32(tmp);
2811 gen_op_iwmmxt_movq_wRn_M0(acc);
2812 return 0;
2815 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2816 /* Internal Accumulator Access Format */
2817 rdhi = (insn >> 16) & 0xf;
2818 rdlo = (insn >> 12) & 0xf;
2819 acc = insn & 7;
2821 if (acc != 0)
2822 return 1;
2824 if (insn & ARM_CP_RW_BIT) { /* MRA */
2825 iwmmxt_load_reg(cpu_V0, acc);
2826 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2827 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2828 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2829 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2830 } else { /* MAR */
2831 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2832 iwmmxt_store_reg(cpu_V0, acc);
2834 return 0;
2837 return 1;
2840 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2841 #define VFP_SREG(insn, bigbit, smallbit) \
2842 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2843 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2844 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2845 reg = (((insn) >> (bigbit)) & 0x0f) \
2846 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2847 } else { \
2848 if (insn & (1 << (smallbit))) \
2849 return 1; \
2850 reg = ((insn) >> (bigbit)) & 0x0f; \
2851 }} while (0)
2853 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2854 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2855 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2856 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2857 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2858 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2860 /* Move between integer and VFP cores. */
2861 static TCGv_i32 gen_vfp_mrs(void)
2863 TCGv_i32 tmp = tcg_temp_new_i32();
2864 tcg_gen_mov_i32(tmp, cpu_F0s);
2865 return tmp;
2868 static void gen_vfp_msr(TCGv_i32 tmp)
2870 tcg_gen_mov_i32(cpu_F0s, tmp);
2871 tcg_temp_free_i32(tmp);
2874 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2876 TCGv_i32 tmp = tcg_temp_new_i32();
2877 if (shift)
2878 tcg_gen_shri_i32(var, var, shift);
2879 tcg_gen_ext8u_i32(var, var);
2880 tcg_gen_shli_i32(tmp, var, 8);
2881 tcg_gen_or_i32(var, var, tmp);
2882 tcg_gen_shli_i32(tmp, var, 16);
2883 tcg_gen_or_i32(var, var, tmp);
2884 tcg_temp_free_i32(tmp);
2887 static void gen_neon_dup_low16(TCGv_i32 var)
2889 TCGv_i32 tmp = tcg_temp_new_i32();
2890 tcg_gen_ext16u_i32(var, var);
2891 tcg_gen_shli_i32(tmp, var, 16);
2892 tcg_gen_or_i32(var, var, tmp);
2893 tcg_temp_free_i32(tmp);
2896 static void gen_neon_dup_high16(TCGv_i32 var)
2898 TCGv_i32 tmp = tcg_temp_new_i32();
2899 tcg_gen_andi_i32(var, var, 0xffff0000);
2900 tcg_gen_shri_i32(tmp, var, 16);
2901 tcg_gen_or_i32(var, var, tmp);
2902 tcg_temp_free_i32(tmp);
2905 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2907 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2908 TCGv_i32 tmp = tcg_temp_new_i32();
2909 switch (size) {
2910 case 0:
2911 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2912 gen_neon_dup_u8(tmp, 0);
2913 break;
2914 case 1:
2915 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2916 gen_neon_dup_low16(tmp);
2917 break;
2918 case 2:
2919 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2920 break;
2921 default: /* Avoid compiler warnings. */
2922 abort();
2924 return tmp;
2927 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2928 uint32_t dp)
2930 uint32_t cc = extract32(insn, 20, 2);
2932 if (dp) {
2933 TCGv_i64 frn, frm, dest;
2934 TCGv_i64 tmp, zero, zf, nf, vf;
2936 zero = tcg_const_i64(0);
2938 frn = tcg_temp_new_i64();
2939 frm = tcg_temp_new_i64();
2940 dest = tcg_temp_new_i64();
2942 zf = tcg_temp_new_i64();
2943 nf = tcg_temp_new_i64();
2944 vf = tcg_temp_new_i64();
2946 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2947 tcg_gen_ext_i32_i64(nf, cpu_NF);
2948 tcg_gen_ext_i32_i64(vf, cpu_VF);
2950 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2951 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2952 switch (cc) {
2953 case 0: /* eq: Z */
2954 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2955 frn, frm);
2956 break;
2957 case 1: /* vs: V */
2958 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2959 frn, frm);
2960 break;
2961 case 2: /* ge: N == V -> N ^ V == 0 */
2962 tmp = tcg_temp_new_i64();
2963 tcg_gen_xor_i64(tmp, vf, nf);
2964 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2965 frn, frm);
2966 tcg_temp_free_i64(tmp);
2967 break;
2968 case 3: /* gt: !Z && N == V */
2969 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2970 frn, frm);
2971 tmp = tcg_temp_new_i64();
2972 tcg_gen_xor_i64(tmp, vf, nf);
2973 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2974 dest, frm);
2975 tcg_temp_free_i64(tmp);
2976 break;
2978 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2979 tcg_temp_free_i64(frn);
2980 tcg_temp_free_i64(frm);
2981 tcg_temp_free_i64(dest);
2983 tcg_temp_free_i64(zf);
2984 tcg_temp_free_i64(nf);
2985 tcg_temp_free_i64(vf);
2987 tcg_temp_free_i64(zero);
2988 } else {
2989 TCGv_i32 frn, frm, dest;
2990 TCGv_i32 tmp, zero;
2992 zero = tcg_const_i32(0);
2994 frn = tcg_temp_new_i32();
2995 frm = tcg_temp_new_i32();
2996 dest = tcg_temp_new_i32();
2997 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2998 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2999 switch (cc) {
3000 case 0: /* eq: Z */
3001 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3002 frn, frm);
3003 break;
3004 case 1: /* vs: V */
3005 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3006 frn, frm);
3007 break;
3008 case 2: /* ge: N == V -> N ^ V == 0 */
3009 tmp = tcg_temp_new_i32();
3010 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3011 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3012 frn, frm);
3013 tcg_temp_free_i32(tmp);
3014 break;
3015 case 3: /* gt: !Z && N == V */
3016 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3017 frn, frm);
3018 tmp = tcg_temp_new_i32();
3019 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3020 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3021 dest, frm);
3022 tcg_temp_free_i32(tmp);
3023 break;
3025 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3026 tcg_temp_free_i32(frn);
3027 tcg_temp_free_i32(frm);
3028 tcg_temp_free_i32(dest);
3030 tcg_temp_free_i32(zero);
3033 return 0;
3036 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3037 uint32_t rm, uint32_t dp)
3039 uint32_t vmin = extract32(insn, 6, 1);
3040 TCGv_ptr fpst = get_fpstatus_ptr(0);
3042 if (dp) {
3043 TCGv_i64 frn, frm, dest;
3045 frn = tcg_temp_new_i64();
3046 frm = tcg_temp_new_i64();
3047 dest = tcg_temp_new_i64();
3049 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3050 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3051 if (vmin) {
3052 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3053 } else {
3054 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3056 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3057 tcg_temp_free_i64(frn);
3058 tcg_temp_free_i64(frm);
3059 tcg_temp_free_i64(dest);
3060 } else {
3061 TCGv_i32 frn, frm, dest;
3063 frn = tcg_temp_new_i32();
3064 frm = tcg_temp_new_i32();
3065 dest = tcg_temp_new_i32();
3067 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3068 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3069 if (vmin) {
3070 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3071 } else {
3072 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3074 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3075 tcg_temp_free_i32(frn);
3076 tcg_temp_free_i32(frm);
3077 tcg_temp_free_i32(dest);
3080 tcg_temp_free_ptr(fpst);
3081 return 0;
3084 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3085 int rounding)
3087 TCGv_ptr fpst = get_fpstatus_ptr(0);
3088 TCGv_i32 tcg_rmode;
3090 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3091 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3093 if (dp) {
3094 TCGv_i64 tcg_op;
3095 TCGv_i64 tcg_res;
3096 tcg_op = tcg_temp_new_i64();
3097 tcg_res = tcg_temp_new_i64();
3098 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3099 gen_helper_rintd(tcg_res, tcg_op, fpst);
3100 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3101 tcg_temp_free_i64(tcg_op);
3102 tcg_temp_free_i64(tcg_res);
3103 } else {
3104 TCGv_i32 tcg_op;
3105 TCGv_i32 tcg_res;
3106 tcg_op = tcg_temp_new_i32();
3107 tcg_res = tcg_temp_new_i32();
3108 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3109 gen_helper_rints(tcg_res, tcg_op, fpst);
3110 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3111 tcg_temp_free_i32(tcg_op);
3112 tcg_temp_free_i32(tcg_res);
3115 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3116 tcg_temp_free_i32(tcg_rmode);
3118 tcg_temp_free_ptr(fpst);
3119 return 0;
3122 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3123 int rounding)
3125 bool is_signed = extract32(insn, 7, 1);
3126 TCGv_ptr fpst = get_fpstatus_ptr(0);
3127 TCGv_i32 tcg_rmode, tcg_shift;
3129 tcg_shift = tcg_const_i32(0);
3131 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3132 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3134 if (dp) {
3135 TCGv_i64 tcg_double, tcg_res;
3136 TCGv_i32 tcg_tmp;
3137 /* Rd is encoded as a single precision register even when the source
3138 * is double precision.
3140 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3141 tcg_double = tcg_temp_new_i64();
3142 tcg_res = tcg_temp_new_i64();
3143 tcg_tmp = tcg_temp_new_i32();
3144 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3145 if (is_signed) {
3146 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3147 } else {
3148 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3150 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3151 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3152 tcg_temp_free_i32(tcg_tmp);
3153 tcg_temp_free_i64(tcg_res);
3154 tcg_temp_free_i64(tcg_double);
3155 } else {
3156 TCGv_i32 tcg_single, tcg_res;
3157 tcg_single = tcg_temp_new_i32();
3158 tcg_res = tcg_temp_new_i32();
3159 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3160 if (is_signed) {
3161 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3162 } else {
3163 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3165 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3166 tcg_temp_free_i32(tcg_res);
3167 tcg_temp_free_i32(tcg_single);
3170 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3171 tcg_temp_free_i32(tcg_rmode);
3173 tcg_temp_free_i32(tcg_shift);
3175 tcg_temp_free_ptr(fpst);
3177 return 0;
3180 /* Table for converting the most common AArch32 encoding of
3181 * rounding mode to arm_fprounding order (which matches the
3182 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3184 static const uint8_t fp_decode_rm[] = {
3185 FPROUNDING_TIEAWAY,
3186 FPROUNDING_TIEEVEN,
3187 FPROUNDING_POSINF,
3188 FPROUNDING_NEGINF,
3191 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3193 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3195 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3196 return 1;
3199 if (dp) {
3200 VFP_DREG_D(rd, insn);
3201 VFP_DREG_N(rn, insn);
3202 VFP_DREG_M(rm, insn);
3203 } else {
3204 rd = VFP_SREG_D(insn);
3205 rn = VFP_SREG_N(insn);
3206 rm = VFP_SREG_M(insn);
3209 if ((insn & 0x0f800e50) == 0x0e000a00) {
3210 return handle_vsel(insn, rd, rn, rm, dp);
3211 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3212 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3213 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3214 /* VRINTA, VRINTN, VRINTP, VRINTM */
3215 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3216 return handle_vrint(insn, rd, rm, dp, rounding);
3217 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3218 /* VCVTA, VCVTN, VCVTP, VCVTM */
3219 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3220 return handle_vcvt(insn, rd, rm, dp, rounding);
3222 return 1;
3225 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3226 (ie. an undefined instruction). */
3227 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3229 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3230 int dp, veclen;
3231 TCGv_i32 addr;
3232 TCGv_i32 tmp;
3233 TCGv_i32 tmp2;
3235 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3236 return 1;
3239 /* FIXME: this access check should not take precedence over UNDEF
3240 * for invalid encodings; we will generate incorrect syndrome information
3241 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3243 if (s->fp_excp_el) {
3244 gen_exception_insn(s, 4, EXCP_UDEF,
3245 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3246 return 0;
3249 if (!s->vfp_enabled) {
3250 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3251 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3252 return 1;
3253 rn = (insn >> 16) & 0xf;
3254 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3255 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3256 return 1;
3260 if (extract32(insn, 28, 4) == 0xf) {
3261 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3262 * only used in v8 and above.
3264 return disas_vfp_v8_insn(s, insn);
3267 dp = ((insn & 0xf00) == 0xb00);
3268 switch ((insn >> 24) & 0xf) {
3269 case 0xe:
3270 if (insn & (1 << 4)) {
3271 /* single register transfer */
3272 rd = (insn >> 12) & 0xf;
3273 if (dp) {
3274 int size;
3275 int pass;
3277 VFP_DREG_N(rn, insn);
3278 if (insn & 0xf)
3279 return 1;
3280 if (insn & 0x00c00060
3281 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3282 return 1;
3285 pass = (insn >> 21) & 1;
3286 if (insn & (1 << 22)) {
3287 size = 0;
3288 offset = ((insn >> 5) & 3) * 8;
3289 } else if (insn & (1 << 5)) {
3290 size = 1;
3291 offset = (insn & (1 << 6)) ? 16 : 0;
3292 } else {
3293 size = 2;
3294 offset = 0;
3296 if (insn & ARM_CP_RW_BIT) {
3297 /* vfp->arm */
3298 tmp = neon_load_reg(rn, pass);
3299 switch (size) {
3300 case 0:
3301 if (offset)
3302 tcg_gen_shri_i32(tmp, tmp, offset);
3303 if (insn & (1 << 23))
3304 gen_uxtb(tmp);
3305 else
3306 gen_sxtb(tmp);
3307 break;
3308 case 1:
3309 if (insn & (1 << 23)) {
3310 if (offset) {
3311 tcg_gen_shri_i32(tmp, tmp, 16);
3312 } else {
3313 gen_uxth(tmp);
3315 } else {
3316 if (offset) {
3317 tcg_gen_sari_i32(tmp, tmp, 16);
3318 } else {
3319 gen_sxth(tmp);
3322 break;
3323 case 2:
3324 break;
3326 store_reg(s, rd, tmp);
3327 } else {
3328 /* arm->vfp */
3329 tmp = load_reg(s, rd);
3330 if (insn & (1 << 23)) {
3331 /* VDUP */
3332 if (size == 0) {
3333 gen_neon_dup_u8(tmp, 0);
3334 } else if (size == 1) {
3335 gen_neon_dup_low16(tmp);
3337 for (n = 0; n <= pass * 2; n++) {
3338 tmp2 = tcg_temp_new_i32();
3339 tcg_gen_mov_i32(tmp2, tmp);
3340 neon_store_reg(rn, n, tmp2);
3342 neon_store_reg(rn, n, tmp);
3343 } else {
3344 /* VMOV */
3345 switch (size) {
3346 case 0:
3347 tmp2 = neon_load_reg(rn, pass);
3348 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3349 tcg_temp_free_i32(tmp2);
3350 break;
3351 case 1:
3352 tmp2 = neon_load_reg(rn, pass);
3353 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3354 tcg_temp_free_i32(tmp2);
3355 break;
3356 case 2:
3357 break;
3359 neon_store_reg(rn, pass, tmp);
3362 } else { /* !dp */
3363 if ((insn & 0x6f) != 0x00)
3364 return 1;
3365 rn = VFP_SREG_N(insn);
3366 if (insn & ARM_CP_RW_BIT) {
3367 /* vfp->arm */
3368 if (insn & (1 << 21)) {
3369 /* system register */
3370 rn >>= 1;
3372 switch (rn) {
3373 case ARM_VFP_FPSID:
3374 /* VFP2 allows access to FSID from userspace.
3375 VFP3 restricts all id registers to privileged
3376 accesses. */
3377 if (IS_USER(s)
3378 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3379 return 1;
3381 tmp = load_cpu_field(vfp.xregs[rn]);
3382 break;
3383 case ARM_VFP_FPEXC:
3384 if (IS_USER(s))
3385 return 1;
3386 tmp = load_cpu_field(vfp.xregs[rn]);
3387 break;
3388 case ARM_VFP_FPINST:
3389 case ARM_VFP_FPINST2:
3390 /* Not present in VFP3. */
3391 if (IS_USER(s)
3392 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3393 return 1;
3395 tmp = load_cpu_field(vfp.xregs[rn]);
3396 break;
3397 case ARM_VFP_FPSCR:
3398 if (rd == 15) {
3399 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3400 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3401 } else {
3402 tmp = tcg_temp_new_i32();
3403 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3405 break;
3406 case ARM_VFP_MVFR2:
3407 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3408 return 1;
3410 /* fall through */
3411 case ARM_VFP_MVFR0:
3412 case ARM_VFP_MVFR1:
3413 if (IS_USER(s)
3414 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3415 return 1;
3417 tmp = load_cpu_field(vfp.xregs[rn]);
3418 break;
3419 default:
3420 return 1;
3422 } else {
3423 gen_mov_F0_vreg(0, rn);
3424 tmp = gen_vfp_mrs();
3426 if (rd == 15) {
3427 /* Set the 4 flag bits in the CPSR. */
3428 gen_set_nzcv(tmp);
3429 tcg_temp_free_i32(tmp);
3430 } else {
3431 store_reg(s, rd, tmp);
3433 } else {
3434 /* arm->vfp */
3435 if (insn & (1 << 21)) {
3436 rn >>= 1;
3437 /* system register */
3438 switch (rn) {
3439 case ARM_VFP_FPSID:
3440 case ARM_VFP_MVFR0:
3441 case ARM_VFP_MVFR1:
3442 /* Writes are ignored. */
3443 break;
3444 case ARM_VFP_FPSCR:
3445 tmp = load_reg(s, rd);
3446 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3447 tcg_temp_free_i32(tmp);
3448 gen_lookup_tb(s);
3449 break;
3450 case ARM_VFP_FPEXC:
3451 if (IS_USER(s))
3452 return 1;
3453 /* TODO: VFP subarchitecture support.
3454 * For now, keep the EN bit only */
3455 tmp = load_reg(s, rd);
3456 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3457 store_cpu_field(tmp, vfp.xregs[rn]);
3458 gen_lookup_tb(s);
3459 break;
3460 case ARM_VFP_FPINST:
3461 case ARM_VFP_FPINST2:
3462 if (IS_USER(s)) {
3463 return 1;
3465 tmp = load_reg(s, rd);
3466 store_cpu_field(tmp, vfp.xregs[rn]);
3467 break;
3468 default:
3469 return 1;
3471 } else {
3472 tmp = load_reg(s, rd);
3473 gen_vfp_msr(tmp);
3474 gen_mov_vreg_F0(0, rn);
3478 } else {
3479 /* data processing */
3480 /* The opcode is in bits 23, 21, 20 and 6. */
3481 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3482 if (dp) {
3483 if (op == 15) {
3484 /* rn is opcode */
3485 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3486 } else {
3487 /* rn is register number */
3488 VFP_DREG_N(rn, insn);
3491 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3492 ((rn & 0x1e) == 0x6))) {
3493 /* Integer or single/half precision destination. */
3494 rd = VFP_SREG_D(insn);
3495 } else {
3496 VFP_DREG_D(rd, insn);
3498 if (op == 15 &&
3499 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3500 ((rn & 0x1e) == 0x4))) {
3501 /* VCVT from int or half precision is always from S reg
3502 * regardless of dp bit. VCVT with immediate frac_bits
3503 * has same format as SREG_M.
3505 rm = VFP_SREG_M(insn);
3506 } else {
3507 VFP_DREG_M(rm, insn);
3509 } else {
3510 rn = VFP_SREG_N(insn);
3511 if (op == 15 && rn == 15) {
3512 /* Double precision destination. */
3513 VFP_DREG_D(rd, insn);
3514 } else {
3515 rd = VFP_SREG_D(insn);
3517 /* NB that we implicitly rely on the encoding for the frac_bits
3518 * in VCVT of fixed to float being the same as that of an SREG_M
3520 rm = VFP_SREG_M(insn);
3523 veclen = s->vec_len;
3524 if (op == 15 && rn > 3)
3525 veclen = 0;
3527 /* Shut up compiler warnings. */
3528 delta_m = 0;
3529 delta_d = 0;
3530 bank_mask = 0;
3532 if (veclen > 0) {
3533 if (dp)
3534 bank_mask = 0xc;
3535 else
3536 bank_mask = 0x18;
3538 /* Figure out what type of vector operation this is. */
3539 if ((rd & bank_mask) == 0) {
3540 /* scalar */
3541 veclen = 0;
3542 } else {
3543 if (dp)
3544 delta_d = (s->vec_stride >> 1) + 1;
3545 else
3546 delta_d = s->vec_stride + 1;
3548 if ((rm & bank_mask) == 0) {
3549 /* mixed scalar/vector */
3550 delta_m = 0;
3551 } else {
3552 /* vector */
3553 delta_m = delta_d;
3558 /* Load the initial operands. */
3559 if (op == 15) {
3560 switch (rn) {
3561 case 16:
3562 case 17:
3563 /* Integer source */
3564 gen_mov_F0_vreg(0, rm);
3565 break;
3566 case 8:
3567 case 9:
3568 /* Compare */
3569 gen_mov_F0_vreg(dp, rd);
3570 gen_mov_F1_vreg(dp, rm);
3571 break;
3572 case 10:
3573 case 11:
3574 /* Compare with zero */
3575 gen_mov_F0_vreg(dp, rd);
3576 gen_vfp_F1_ld0(dp);
3577 break;
3578 case 20:
3579 case 21:
3580 case 22:
3581 case 23:
3582 case 28:
3583 case 29:
3584 case 30:
3585 case 31:
3586 /* Source and destination the same. */
3587 gen_mov_F0_vreg(dp, rd);
3588 break;
3589 case 4:
3590 case 5:
3591 case 6:
3592 case 7:
3593 /* VCVTB, VCVTT: only present with the halfprec extension
3594 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3595 * (we choose to UNDEF)
3597 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3598 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3599 return 1;
3601 if (!extract32(rn, 1, 1)) {
3602 /* Half precision source. */
3603 gen_mov_F0_vreg(0, rm);
3604 break;
3606 /* Otherwise fall through */
3607 default:
3608 /* One source operand. */
3609 gen_mov_F0_vreg(dp, rm);
3610 break;
3612 } else {
3613 /* Two source operands. */
3614 gen_mov_F0_vreg(dp, rn);
3615 gen_mov_F1_vreg(dp, rm);
3618 for (;;) {
3619 /* Perform the calculation. */
3620 switch (op) {
3621 case 0: /* VMLA: fd + (fn * fm) */
3622 /* Note that order of inputs to the add matters for NaNs */
3623 gen_vfp_F1_mul(dp);
3624 gen_mov_F0_vreg(dp, rd);
3625 gen_vfp_add(dp);
3626 break;
3627 case 1: /* VMLS: fd + -(fn * fm) */
3628 gen_vfp_mul(dp);
3629 gen_vfp_F1_neg(dp);
3630 gen_mov_F0_vreg(dp, rd);
3631 gen_vfp_add(dp);
3632 break;
3633 case 2: /* VNMLS: -fd + (fn * fm) */
3634 /* Note that it isn't valid to replace (-A + B) with (B - A)
3635 * or similar plausible looking simplifications
3636 * because this will give wrong results for NaNs.
3638 gen_vfp_F1_mul(dp);
3639 gen_mov_F0_vreg(dp, rd);
3640 gen_vfp_neg(dp);
3641 gen_vfp_add(dp);
3642 break;
3643 case 3: /* VNMLA: -fd + -(fn * fm) */
3644 gen_vfp_mul(dp);
3645 gen_vfp_F1_neg(dp);
3646 gen_mov_F0_vreg(dp, rd);
3647 gen_vfp_neg(dp);
3648 gen_vfp_add(dp);
3649 break;
3650 case 4: /* mul: fn * fm */
3651 gen_vfp_mul(dp);
3652 break;
3653 case 5: /* nmul: -(fn * fm) */
3654 gen_vfp_mul(dp);
3655 gen_vfp_neg(dp);
3656 break;
3657 case 6: /* add: fn + fm */
3658 gen_vfp_add(dp);
3659 break;
3660 case 7: /* sub: fn - fm */
3661 gen_vfp_sub(dp);
3662 break;
3663 case 8: /* div: fn / fm */
3664 gen_vfp_div(dp);
3665 break;
3666 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3667 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3668 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3669 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3670 /* These are fused multiply-add, and must be done as one
3671 * floating point operation with no rounding between the
3672 * multiplication and addition steps.
3673 * NB that doing the negations here as separate steps is
3674 * correct : an input NaN should come out with its sign bit
3675 * flipped if it is a negated-input.
3677 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3678 return 1;
3680 if (dp) {
3681 TCGv_ptr fpst;
3682 TCGv_i64 frd;
3683 if (op & 1) {
3684 /* VFNMS, VFMS */
3685 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3687 frd = tcg_temp_new_i64();
3688 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3689 if (op & 2) {
3690 /* VFNMA, VFNMS */
3691 gen_helper_vfp_negd(frd, frd);
3693 fpst = get_fpstatus_ptr(0);
3694 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3695 cpu_F1d, frd, fpst);
3696 tcg_temp_free_ptr(fpst);
3697 tcg_temp_free_i64(frd);
3698 } else {
3699 TCGv_ptr fpst;
3700 TCGv_i32 frd;
3701 if (op & 1) {
3702 /* VFNMS, VFMS */
3703 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3705 frd = tcg_temp_new_i32();
3706 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3707 if (op & 2) {
3708 gen_helper_vfp_negs(frd, frd);
3710 fpst = get_fpstatus_ptr(0);
3711 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3712 cpu_F1s, frd, fpst);
3713 tcg_temp_free_ptr(fpst);
3714 tcg_temp_free_i32(frd);
3716 break;
3717 case 14: /* fconst */
3718 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3719 return 1;
3722 n = (insn << 12) & 0x80000000;
3723 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3724 if (dp) {
3725 if (i & 0x40)
3726 i |= 0x3f80;
3727 else
3728 i |= 0x4000;
3729 n |= i << 16;
3730 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3731 } else {
3732 if (i & 0x40)
3733 i |= 0x780;
3734 else
3735 i |= 0x800;
3736 n |= i << 19;
3737 tcg_gen_movi_i32(cpu_F0s, n);
3739 break;
3740 case 15: /* extension space */
3741 switch (rn) {
3742 case 0: /* cpy */
3743 /* no-op */
3744 break;
3745 case 1: /* abs */
3746 gen_vfp_abs(dp);
3747 break;
3748 case 2: /* neg */
3749 gen_vfp_neg(dp);
3750 break;
3751 case 3: /* sqrt */
3752 gen_vfp_sqrt(dp);
3753 break;
3754 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3755 tmp = gen_vfp_mrs();
3756 tcg_gen_ext16u_i32(tmp, tmp);
3757 if (dp) {
3758 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3759 cpu_env);
3760 } else {
3761 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3762 cpu_env);
3764 tcg_temp_free_i32(tmp);
3765 break;
3766 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3767 tmp = gen_vfp_mrs();
3768 tcg_gen_shri_i32(tmp, tmp, 16);
3769 if (dp) {
3770 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3771 cpu_env);
3772 } else {
3773 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3774 cpu_env);
3776 tcg_temp_free_i32(tmp);
3777 break;
3778 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3779 tmp = tcg_temp_new_i32();
3780 if (dp) {
3781 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3782 cpu_env);
3783 } else {
3784 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3785 cpu_env);
3787 gen_mov_F0_vreg(0, rd);
3788 tmp2 = gen_vfp_mrs();
3789 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3790 tcg_gen_or_i32(tmp, tmp, tmp2);
3791 tcg_temp_free_i32(tmp2);
3792 gen_vfp_msr(tmp);
3793 break;
3794 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3795 tmp = tcg_temp_new_i32();
3796 if (dp) {
3797 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3798 cpu_env);
3799 } else {
3800 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3801 cpu_env);
3803 tcg_gen_shli_i32(tmp, tmp, 16);
3804 gen_mov_F0_vreg(0, rd);
3805 tmp2 = gen_vfp_mrs();
3806 tcg_gen_ext16u_i32(tmp2, tmp2);
3807 tcg_gen_or_i32(tmp, tmp, tmp2);
3808 tcg_temp_free_i32(tmp2);
3809 gen_vfp_msr(tmp);
3810 break;
3811 case 8: /* cmp */
3812 gen_vfp_cmp(dp);
3813 break;
3814 case 9: /* cmpe */
3815 gen_vfp_cmpe(dp);
3816 break;
3817 case 10: /* cmpz */
3818 gen_vfp_cmp(dp);
3819 break;
3820 case 11: /* cmpez */
3821 gen_vfp_F1_ld0(dp);
3822 gen_vfp_cmpe(dp);
3823 break;
3824 case 12: /* vrintr */
3826 TCGv_ptr fpst = get_fpstatus_ptr(0);
3827 if (dp) {
3828 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3829 } else {
3830 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3832 tcg_temp_free_ptr(fpst);
3833 break;
3835 case 13: /* vrintz */
3837 TCGv_ptr fpst = get_fpstatus_ptr(0);
3838 TCGv_i32 tcg_rmode;
3839 tcg_rmode = tcg_const_i32(float_round_to_zero);
3840 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3841 if (dp) {
3842 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3843 } else {
3844 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3846 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3847 tcg_temp_free_i32(tcg_rmode);
3848 tcg_temp_free_ptr(fpst);
3849 break;
3851 case 14: /* vrintx */
3853 TCGv_ptr fpst = get_fpstatus_ptr(0);
3854 if (dp) {
3855 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3856 } else {
3857 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3859 tcg_temp_free_ptr(fpst);
3860 break;
3862 case 15: /* single<->double conversion */
3863 if (dp)
3864 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3865 else
3866 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3867 break;
3868 case 16: /* fuito */
3869 gen_vfp_uito(dp, 0);
3870 break;
3871 case 17: /* fsito */
3872 gen_vfp_sito(dp, 0);
3873 break;
3874 case 20: /* fshto */
3875 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3876 return 1;
3878 gen_vfp_shto(dp, 16 - rm, 0);
3879 break;
3880 case 21: /* fslto */
3881 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3882 return 1;
3884 gen_vfp_slto(dp, 32 - rm, 0);
3885 break;
3886 case 22: /* fuhto */
3887 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3888 return 1;
3890 gen_vfp_uhto(dp, 16 - rm, 0);
3891 break;
3892 case 23: /* fulto */
3893 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3894 return 1;
3896 gen_vfp_ulto(dp, 32 - rm, 0);
3897 break;
3898 case 24: /* ftoui */
3899 gen_vfp_toui(dp, 0);
3900 break;
3901 case 25: /* ftouiz */
3902 gen_vfp_touiz(dp, 0);
3903 break;
3904 case 26: /* ftosi */
3905 gen_vfp_tosi(dp, 0);
3906 break;
3907 case 27: /* ftosiz */
3908 gen_vfp_tosiz(dp, 0);
3909 break;
3910 case 28: /* ftosh */
3911 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3912 return 1;
3914 gen_vfp_tosh(dp, 16 - rm, 0);
3915 break;
3916 case 29: /* ftosl */
3917 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3918 return 1;
3920 gen_vfp_tosl(dp, 32 - rm, 0);
3921 break;
3922 case 30: /* ftouh */
3923 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3924 return 1;
3926 gen_vfp_touh(dp, 16 - rm, 0);
3927 break;
3928 case 31: /* ftoul */
3929 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3930 return 1;
3932 gen_vfp_toul(dp, 32 - rm, 0);
3933 break;
3934 default: /* undefined */
3935 return 1;
3937 break;
3938 default: /* undefined */
3939 return 1;
3942 /* Write back the result. */
3943 if (op == 15 && (rn >= 8 && rn <= 11)) {
3944 /* Comparison, do nothing. */
3945 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3946 (rn & 0x1e) == 0x6)) {
3947 /* VCVT double to int: always integer result.
3948 * VCVT double to half precision is always a single
3949 * precision result.
3951 gen_mov_vreg_F0(0, rd);
3952 } else if (op == 15 && rn == 15) {
3953 /* conversion */
3954 gen_mov_vreg_F0(!dp, rd);
3955 } else {
3956 gen_mov_vreg_F0(dp, rd);
3959 /* break out of the loop if we have finished */
3960 if (veclen == 0)
3961 break;
3963 if (op == 15 && delta_m == 0) {
3964 /* single source one-many */
3965 while (veclen--) {
3966 rd = ((rd + delta_d) & (bank_mask - 1))
3967 | (rd & bank_mask);
3968 gen_mov_vreg_F0(dp, rd);
3970 break;
3972 /* Setup the next operands. */
3973 veclen--;
3974 rd = ((rd + delta_d) & (bank_mask - 1))
3975 | (rd & bank_mask);
3977 if (op == 15) {
3978 /* One source operand. */
3979 rm = ((rm + delta_m) & (bank_mask - 1))
3980 | (rm & bank_mask);
3981 gen_mov_F0_vreg(dp, rm);
3982 } else {
3983 /* Two source operands. */
3984 rn = ((rn + delta_d) & (bank_mask - 1))
3985 | (rn & bank_mask);
3986 gen_mov_F0_vreg(dp, rn);
3987 if (delta_m) {
3988 rm = ((rm + delta_m) & (bank_mask - 1))
3989 | (rm & bank_mask);
3990 gen_mov_F1_vreg(dp, rm);
3995 break;
3996 case 0xc:
3997 case 0xd:
3998 if ((insn & 0x03e00000) == 0x00400000) {
3999 /* two-register transfer */
4000 rn = (insn >> 16) & 0xf;
4001 rd = (insn >> 12) & 0xf;
4002 if (dp) {
4003 VFP_DREG_M(rm, insn);
4004 } else {
4005 rm = VFP_SREG_M(insn);
4008 if (insn & ARM_CP_RW_BIT) {
4009 /* vfp->arm */
4010 if (dp) {
4011 gen_mov_F0_vreg(0, rm * 2);
4012 tmp = gen_vfp_mrs();
4013 store_reg(s, rd, tmp);
4014 gen_mov_F0_vreg(0, rm * 2 + 1);
4015 tmp = gen_vfp_mrs();
4016 store_reg(s, rn, tmp);
4017 } else {
4018 gen_mov_F0_vreg(0, rm);
4019 tmp = gen_vfp_mrs();
4020 store_reg(s, rd, tmp);
4021 gen_mov_F0_vreg(0, rm + 1);
4022 tmp = gen_vfp_mrs();
4023 store_reg(s, rn, tmp);
4025 } else {
4026 /* arm->vfp */
4027 if (dp) {
4028 tmp = load_reg(s, rd);
4029 gen_vfp_msr(tmp);
4030 gen_mov_vreg_F0(0, rm * 2);
4031 tmp = load_reg(s, rn);
4032 gen_vfp_msr(tmp);
4033 gen_mov_vreg_F0(0, rm * 2 + 1);
4034 } else {
4035 tmp = load_reg(s, rd);
4036 gen_vfp_msr(tmp);
4037 gen_mov_vreg_F0(0, rm);
4038 tmp = load_reg(s, rn);
4039 gen_vfp_msr(tmp);
4040 gen_mov_vreg_F0(0, rm + 1);
4043 } else {
4044 /* Load/store */
4045 rn = (insn >> 16) & 0xf;
4046 if (dp)
4047 VFP_DREG_D(rd, insn);
4048 else
4049 rd = VFP_SREG_D(insn);
4050 if ((insn & 0x01200000) == 0x01000000) {
4051 /* Single load/store */
4052 offset = (insn & 0xff) << 2;
4053 if ((insn & (1 << 23)) == 0)
4054 offset = -offset;
4055 if (s->thumb && rn == 15) {
4056 /* This is actually UNPREDICTABLE */
4057 addr = tcg_temp_new_i32();
4058 tcg_gen_movi_i32(addr, s->pc & ~2);
4059 } else {
4060 addr = load_reg(s, rn);
4062 tcg_gen_addi_i32(addr, addr, offset);
4063 if (insn & (1 << 20)) {
4064 gen_vfp_ld(s, dp, addr);
4065 gen_mov_vreg_F0(dp, rd);
4066 } else {
4067 gen_mov_F0_vreg(dp, rd);
4068 gen_vfp_st(s, dp, addr);
4070 tcg_temp_free_i32(addr);
4071 } else {
4072 /* load/store multiple */
4073 int w = insn & (1 << 21);
4074 if (dp)
4075 n = (insn >> 1) & 0x7f;
4076 else
4077 n = insn & 0xff;
4079 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4080 /* P == U , W == 1 => UNDEF */
4081 return 1;
4083 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4084 /* UNPREDICTABLE cases for bad immediates: we choose to
4085 * UNDEF to avoid generating huge numbers of TCG ops
4087 return 1;
4089 if (rn == 15 && w) {
4090 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4091 return 1;
4094 if (s->thumb && rn == 15) {
4095 /* This is actually UNPREDICTABLE */
4096 addr = tcg_temp_new_i32();
4097 tcg_gen_movi_i32(addr, s->pc & ~2);
4098 } else {
4099 addr = load_reg(s, rn);
4101 if (insn & (1 << 24)) /* pre-decrement */
4102 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4104 if (dp)
4105 offset = 8;
4106 else
4107 offset = 4;
4108 for (i = 0; i < n; i++) {
4109 if (insn & ARM_CP_RW_BIT) {
4110 /* load */
4111 gen_vfp_ld(s, dp, addr);
4112 gen_mov_vreg_F0(dp, rd + i);
4113 } else {
4114 /* store */
4115 gen_mov_F0_vreg(dp, rd + i);
4116 gen_vfp_st(s, dp, addr);
4118 tcg_gen_addi_i32(addr, addr, offset);
4120 if (w) {
4121 /* writeback */
4122 if (insn & (1 << 24))
4123 offset = -offset * n;
4124 else if (dp && (insn & 1))
4125 offset = 4;
4126 else
4127 offset = 0;
4129 if (offset != 0)
4130 tcg_gen_addi_i32(addr, addr, offset);
4131 store_reg(s, rn, addr);
4132 } else {
4133 tcg_temp_free_i32(addr);
4137 break;
4138 default:
4139 /* Should never happen. */
4140 return 1;
4142 return 0;
4145 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4147 #ifndef CONFIG_USER_ONLY
4148 return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4149 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4150 #else
4151 return true;
4152 #endif
4155 static void gen_goto_ptr(void)
4157 TCGv addr = tcg_temp_new();
4158 tcg_gen_extu_i32_tl(addr, cpu_R[15]);
4159 tcg_gen_lookup_and_goto_ptr(addr);
4160 tcg_temp_free(addr);
4163 /* This will end the TB but doesn't guarantee we'll return to
4164 * cpu_loop_exec. Any live exit_requests will be processed as we
4165 * enter the next TB.
4167 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4169 if (use_goto_tb(s, dest)) {
4170 tcg_gen_goto_tb(n);
4171 gen_set_pc_im(s, dest);
4172 tcg_gen_exit_tb((uintptr_t)s->tb + n);
4173 } else {
4174 gen_set_pc_im(s, dest);
4175 gen_goto_ptr();
4177 s->is_jmp = DISAS_TB_JUMP;
4180 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4182 if (unlikely(is_singlestepping(s))) {
4183 /* An indirect jump so that we still trigger the debug exception. */
4184 if (s->thumb)
4185 dest |= 1;
4186 gen_bx_im(s, dest);
4187 } else {
4188 gen_goto_tb(s, 0, dest);
4192 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4194 if (x)
4195 tcg_gen_sari_i32(t0, t0, 16);
4196 else
4197 gen_sxth(t0);
4198 if (y)
4199 tcg_gen_sari_i32(t1, t1, 16);
4200 else
4201 gen_sxth(t1);
4202 tcg_gen_mul_i32(t0, t0, t1);
4205 /* Return the mask of PSR bits set by a MSR instruction. */
4206 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4208 uint32_t mask;
4210 mask = 0;
4211 if (flags & (1 << 0))
4212 mask |= 0xff;
4213 if (flags & (1 << 1))
4214 mask |= 0xff00;
4215 if (flags & (1 << 2))
4216 mask |= 0xff0000;
4217 if (flags & (1 << 3))
4218 mask |= 0xff000000;
4220 /* Mask out undefined bits. */
4221 mask &= ~CPSR_RESERVED;
4222 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4223 mask &= ~CPSR_T;
4225 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4226 mask &= ~CPSR_Q; /* V5TE in reality*/
4228 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4229 mask &= ~(CPSR_E | CPSR_GE);
4231 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4232 mask &= ~CPSR_IT;
4234 /* Mask out execution state and reserved bits. */
4235 if (!spsr) {
4236 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4238 /* Mask out privileged bits. */
4239 if (IS_USER(s))
4240 mask &= CPSR_USER;
4241 return mask;
4244 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4245 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4247 TCGv_i32 tmp;
4248 if (spsr) {
4249 /* ??? This is also undefined in system mode. */
4250 if (IS_USER(s))
4251 return 1;
4253 tmp = load_cpu_field(spsr);
4254 tcg_gen_andi_i32(tmp, tmp, ~mask);
4255 tcg_gen_andi_i32(t0, t0, mask);
4256 tcg_gen_or_i32(tmp, tmp, t0);
4257 store_cpu_field(tmp, spsr);
4258 } else {
4259 gen_set_cpsr(t0, mask);
4261 tcg_temp_free_i32(t0);
4262 gen_lookup_tb(s);
4263 return 0;
4266 /* Returns nonzero if access to the PSR is not permitted. */
4267 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4269 TCGv_i32 tmp;
4270 tmp = tcg_temp_new_i32();
4271 tcg_gen_movi_i32(tmp, val);
4272 return gen_set_psr(s, mask, spsr, tmp);
4275 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4276 int *tgtmode, int *regno)
4278 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4279 * the target mode and register number, and identify the various
4280 * unpredictable cases.
4281 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4282 * + executed in user mode
4283 * + using R15 as the src/dest register
4284 * + accessing an unimplemented register
4285 * + accessing a register that's inaccessible at current PL/security state*
4286 * + accessing a register that you could access with a different insn
4287 * We choose to UNDEF in all these cases.
4288 * Since we don't know which of the various AArch32 modes we are in
4289 * we have to defer some checks to runtime.
4290 * Accesses to Monitor mode registers from Secure EL1 (which implies
4291 * that EL3 is AArch64) must trap to EL3.
4293 * If the access checks fail this function will emit code to take
4294 * an exception and return false. Otherwise it will return true,
4295 * and set *tgtmode and *regno appropriately.
4297 int exc_target = default_exception_el(s);
4299 /* These instructions are present only in ARMv8, or in ARMv7 with the
4300 * Virtualization Extensions.
4302 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4303 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4304 goto undef;
4307 if (IS_USER(s) || rn == 15) {
4308 goto undef;
4311 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4312 * of registers into (r, sysm).
4314 if (r) {
4315 /* SPSRs for other modes */
4316 switch (sysm) {
4317 case 0xe: /* SPSR_fiq */
4318 *tgtmode = ARM_CPU_MODE_FIQ;
4319 break;
4320 case 0x10: /* SPSR_irq */
4321 *tgtmode = ARM_CPU_MODE_IRQ;
4322 break;
4323 case 0x12: /* SPSR_svc */
4324 *tgtmode = ARM_CPU_MODE_SVC;
4325 break;
4326 case 0x14: /* SPSR_abt */
4327 *tgtmode = ARM_CPU_MODE_ABT;
4328 break;
4329 case 0x16: /* SPSR_und */
4330 *tgtmode = ARM_CPU_MODE_UND;
4331 break;
4332 case 0x1c: /* SPSR_mon */
4333 *tgtmode = ARM_CPU_MODE_MON;
4334 break;
4335 case 0x1e: /* SPSR_hyp */
4336 *tgtmode = ARM_CPU_MODE_HYP;
4337 break;
4338 default: /* unallocated */
4339 goto undef;
4341 /* We arbitrarily assign SPSR a register number of 16. */
4342 *regno = 16;
4343 } else {
4344 /* general purpose registers for other modes */
4345 switch (sysm) {
4346 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4347 *tgtmode = ARM_CPU_MODE_USR;
4348 *regno = sysm + 8;
4349 break;
4350 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4351 *tgtmode = ARM_CPU_MODE_FIQ;
4352 *regno = sysm;
4353 break;
4354 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4355 *tgtmode = ARM_CPU_MODE_IRQ;
4356 *regno = sysm & 1 ? 13 : 14;
4357 break;
4358 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4359 *tgtmode = ARM_CPU_MODE_SVC;
4360 *regno = sysm & 1 ? 13 : 14;
4361 break;
4362 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4363 *tgtmode = ARM_CPU_MODE_ABT;
4364 *regno = sysm & 1 ? 13 : 14;
4365 break;
4366 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4367 *tgtmode = ARM_CPU_MODE_UND;
4368 *regno = sysm & 1 ? 13 : 14;
4369 break;
4370 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4371 *tgtmode = ARM_CPU_MODE_MON;
4372 *regno = sysm & 1 ? 13 : 14;
4373 break;
4374 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4375 *tgtmode = ARM_CPU_MODE_HYP;
4376 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4377 *regno = sysm & 1 ? 13 : 17;
4378 break;
4379 default: /* unallocated */
4380 goto undef;
4384 /* Catch the 'accessing inaccessible register' cases we can detect
4385 * at translate time.
4387 switch (*tgtmode) {
4388 case ARM_CPU_MODE_MON:
4389 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4390 goto undef;
4392 if (s->current_el == 1) {
4393 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4394 * then accesses to Mon registers trap to EL3
4396 exc_target = 3;
4397 goto undef;
4399 break;
4400 case ARM_CPU_MODE_HYP:
4401 /* Note that we can forbid accesses from EL2 here because they
4402 * must be from Hyp mode itself
4404 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4405 goto undef;
4407 break;
4408 default:
4409 break;
4412 return true;
4414 undef:
4415 /* If we get here then some access check did not pass */
4416 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4417 return false;
4420 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4422 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4423 int tgtmode = 0, regno = 0;
4425 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4426 return;
4429 /* Sync state because msr_banked() can raise exceptions */
4430 gen_set_condexec(s);
4431 gen_set_pc_im(s, s->pc - 4);
4432 tcg_reg = load_reg(s, rn);
4433 tcg_tgtmode = tcg_const_i32(tgtmode);
4434 tcg_regno = tcg_const_i32(regno);
4435 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4436 tcg_temp_free_i32(tcg_tgtmode);
4437 tcg_temp_free_i32(tcg_regno);
4438 tcg_temp_free_i32(tcg_reg);
4439 s->is_jmp = DISAS_UPDATE;
4442 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4444 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4445 int tgtmode = 0, regno = 0;
4447 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4448 return;
4451 /* Sync state because mrs_banked() can raise exceptions */
4452 gen_set_condexec(s);
4453 gen_set_pc_im(s, s->pc - 4);
4454 tcg_reg = tcg_temp_new_i32();
4455 tcg_tgtmode = tcg_const_i32(tgtmode);
4456 tcg_regno = tcg_const_i32(regno);
4457 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4458 tcg_temp_free_i32(tcg_tgtmode);
4459 tcg_temp_free_i32(tcg_regno);
4460 store_reg(s, rn, tcg_reg);
4461 s->is_jmp = DISAS_UPDATE;
4464 /* Store value to PC as for an exception return (ie don't
4465 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4466 * will do the masking based on the new value of the Thumb bit.
4468 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4470 tcg_gen_mov_i32(cpu_R[15], pc);
4471 tcg_temp_free_i32(pc);
4474 /* Generate a v6 exception return. Marks both values as dead. */
4475 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4477 store_pc_exc_ret(s, pc);
4478 /* The cpsr_write_eret helper will mask the low bits of PC
4479 * appropriately depending on the new Thumb bit, so it must
4480 * be called after storing the new PC.
4482 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4483 tcg_temp_free_i32(cpsr);
4484 /* Must exit loop to check un-masked IRQs */
4485 s->is_jmp = DISAS_EXIT;
4488 /* Generate an old-style exception return. Marks pc as dead. */
4489 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4491 gen_rfe(s, pc, load_cpu_field(spsr));
4495 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4496 * only call the helper when running single threaded TCG code to ensure
4497 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4498 * just skip this instruction. Currently the SEV/SEVL instructions
4499 * which are *one* of many ways to wake the CPU from WFE are not
4500 * implemented so we can't sleep like WFI does.
4502 static void gen_nop_hint(DisasContext *s, int val)
4504 switch (val) {
4505 case 1: /* yield */
4506 if (!parallel_cpus) {
4507 gen_set_pc_im(s, s->pc);
4508 s->is_jmp = DISAS_YIELD;
4510 break;
4511 case 3: /* wfi */
4512 gen_set_pc_im(s, s->pc);
4513 s->is_jmp = DISAS_WFI;
4514 break;
4515 case 2: /* wfe */
4516 if (!parallel_cpus) {
4517 gen_set_pc_im(s, s->pc);
4518 s->is_jmp = DISAS_WFE;
4520 break;
4521 case 4: /* sev */
4522 case 5: /* sevl */
4523 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4524 default: /* nop */
4525 break;
4529 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4531 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4533 switch (size) {
4534 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4535 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4536 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4537 default: abort();
4541 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4543 switch (size) {
4544 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4545 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4546 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4547 default: return;
4551 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4552 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4553 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4554 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4555 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4557 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4558 switch ((size << 1) | u) { \
4559 case 0: \
4560 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4561 break; \
4562 case 1: \
4563 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4564 break; \
4565 case 2: \
4566 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4567 break; \
4568 case 3: \
4569 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4570 break; \
4571 case 4: \
4572 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4573 break; \
4574 case 5: \
4575 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4576 break; \
4577 default: return 1; \
4578 }} while (0)
4580 #define GEN_NEON_INTEGER_OP(name) do { \
4581 switch ((size << 1) | u) { \
4582 case 0: \
4583 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4584 break; \
4585 case 1: \
4586 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4587 break; \
4588 case 2: \
4589 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4590 break; \
4591 case 3: \
4592 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4593 break; \
4594 case 4: \
4595 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4596 break; \
4597 case 5: \
4598 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4599 break; \
4600 default: return 1; \
4601 }} while (0)
4603 static TCGv_i32 neon_load_scratch(int scratch)
4605 TCGv_i32 tmp = tcg_temp_new_i32();
4606 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4607 return tmp;
4610 static void neon_store_scratch(int scratch, TCGv_i32 var)
4612 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4613 tcg_temp_free_i32(var);
4616 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4618 TCGv_i32 tmp;
4619 if (size == 1) {
4620 tmp = neon_load_reg(reg & 7, reg >> 4);
4621 if (reg & 8) {
4622 gen_neon_dup_high16(tmp);
4623 } else {
4624 gen_neon_dup_low16(tmp);
4626 } else {
4627 tmp = neon_load_reg(reg & 15, reg >> 4);
4629 return tmp;
4632 static int gen_neon_unzip(int rd, int rm, int size, int q)
4634 TCGv_i32 tmp, tmp2;
4635 if (!q && size == 2) {
4636 return 1;
4638 tmp = tcg_const_i32(rd);
4639 tmp2 = tcg_const_i32(rm);
4640 if (q) {
4641 switch (size) {
4642 case 0:
4643 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4644 break;
4645 case 1:
4646 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4647 break;
4648 case 2:
4649 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4650 break;
4651 default:
4652 abort();
4654 } else {
4655 switch (size) {
4656 case 0:
4657 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4658 break;
4659 case 1:
4660 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4661 break;
4662 default:
4663 abort();
4666 tcg_temp_free_i32(tmp);
4667 tcg_temp_free_i32(tmp2);
4668 return 0;
4671 static int gen_neon_zip(int rd, int rm, int size, int q)
4673 TCGv_i32 tmp, tmp2;
4674 if (!q && size == 2) {
4675 return 1;
4677 tmp = tcg_const_i32(rd);
4678 tmp2 = tcg_const_i32(rm);
4679 if (q) {
4680 switch (size) {
4681 case 0:
4682 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4683 break;
4684 case 1:
4685 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4686 break;
4687 case 2:
4688 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4689 break;
4690 default:
4691 abort();
4693 } else {
4694 switch (size) {
4695 case 0:
4696 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4697 break;
4698 case 1:
4699 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4700 break;
4701 default:
4702 abort();
4705 tcg_temp_free_i32(tmp);
4706 tcg_temp_free_i32(tmp2);
4707 return 0;
4710 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4712 TCGv_i32 rd, tmp;
4714 rd = tcg_temp_new_i32();
4715 tmp = tcg_temp_new_i32();
4717 tcg_gen_shli_i32(rd, t0, 8);
4718 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4719 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4720 tcg_gen_or_i32(rd, rd, tmp);
4722 tcg_gen_shri_i32(t1, t1, 8);
4723 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4724 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4725 tcg_gen_or_i32(t1, t1, tmp);
4726 tcg_gen_mov_i32(t0, rd);
4728 tcg_temp_free_i32(tmp);
4729 tcg_temp_free_i32(rd);
4732 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4734 TCGv_i32 rd, tmp;
4736 rd = tcg_temp_new_i32();
4737 tmp = tcg_temp_new_i32();
4739 tcg_gen_shli_i32(rd, t0, 16);
4740 tcg_gen_andi_i32(tmp, t1, 0xffff);
4741 tcg_gen_or_i32(rd, rd, tmp);
4742 tcg_gen_shri_i32(t1, t1, 16);
4743 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4744 tcg_gen_or_i32(t1, t1, tmp);
4745 tcg_gen_mov_i32(t0, rd);
4747 tcg_temp_free_i32(tmp);
4748 tcg_temp_free_i32(rd);
4752 static struct {
4753 int nregs;
4754 int interleave;
4755 int spacing;
4756 } neon_ls_element_type[11] = {
4757 {4, 4, 1},
4758 {4, 4, 2},
4759 {4, 1, 1},
4760 {4, 2, 1},
4761 {3, 3, 1},
4762 {3, 3, 2},
4763 {3, 1, 1},
4764 {1, 1, 1},
4765 {2, 2, 1},
4766 {2, 2, 2},
4767 {2, 1, 1}
4770 /* Translate a NEON load/store element instruction. Return nonzero if the
4771 instruction is invalid. */
4772 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4774 int rd, rn, rm;
4775 int op;
4776 int nregs;
4777 int interleave;
4778 int spacing;
4779 int stride;
4780 int size;
4781 int reg;
4782 int pass;
4783 int load;
4784 int shift;
4785 int n;
4786 TCGv_i32 addr;
4787 TCGv_i32 tmp;
4788 TCGv_i32 tmp2;
4789 TCGv_i64 tmp64;
4791 /* FIXME: this access check should not take precedence over UNDEF
4792 * for invalid encodings; we will generate incorrect syndrome information
4793 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4795 if (s->fp_excp_el) {
4796 gen_exception_insn(s, 4, EXCP_UDEF,
4797 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4798 return 0;
4801 if (!s->vfp_enabled)
4802 return 1;
4803 VFP_DREG_D(rd, insn);
4804 rn = (insn >> 16) & 0xf;
4805 rm = insn & 0xf;
4806 load = (insn & (1 << 21)) != 0;
4807 if ((insn & (1 << 23)) == 0) {
4808 /* Load store all elements. */
4809 op = (insn >> 8) & 0xf;
4810 size = (insn >> 6) & 3;
4811 if (op > 10)
4812 return 1;
4813 /* Catch UNDEF cases for bad values of align field */
4814 switch (op & 0xc) {
4815 case 4:
4816 if (((insn >> 5) & 1) == 1) {
4817 return 1;
4819 break;
4820 case 8:
4821 if (((insn >> 4) & 3) == 3) {
4822 return 1;
4824 break;
4825 default:
4826 break;
4828 nregs = neon_ls_element_type[op].nregs;
4829 interleave = neon_ls_element_type[op].interleave;
4830 spacing = neon_ls_element_type[op].spacing;
4831 if (size == 3 && (interleave | spacing) != 1)
4832 return 1;
4833 addr = tcg_temp_new_i32();
4834 load_reg_var(s, addr, rn);
4835 stride = (1 << size) * interleave;
4836 for (reg = 0; reg < nregs; reg++) {
4837 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4838 load_reg_var(s, addr, rn);
4839 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4840 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4841 load_reg_var(s, addr, rn);
4842 tcg_gen_addi_i32(addr, addr, 1 << size);
4844 if (size == 3) {
4845 tmp64 = tcg_temp_new_i64();
4846 if (load) {
4847 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4848 neon_store_reg64(tmp64, rd);
4849 } else {
4850 neon_load_reg64(tmp64, rd);
4851 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4853 tcg_temp_free_i64(tmp64);
4854 tcg_gen_addi_i32(addr, addr, stride);
4855 } else {
4856 for (pass = 0; pass < 2; pass++) {
4857 if (size == 2) {
4858 if (load) {
4859 tmp = tcg_temp_new_i32();
4860 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4861 neon_store_reg(rd, pass, tmp);
4862 } else {
4863 tmp = neon_load_reg(rd, pass);
4864 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4865 tcg_temp_free_i32(tmp);
4867 tcg_gen_addi_i32(addr, addr, stride);
4868 } else if (size == 1) {
4869 if (load) {
4870 tmp = tcg_temp_new_i32();
4871 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4872 tcg_gen_addi_i32(addr, addr, stride);
4873 tmp2 = tcg_temp_new_i32();
4874 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4875 tcg_gen_addi_i32(addr, addr, stride);
4876 tcg_gen_shli_i32(tmp2, tmp2, 16);
4877 tcg_gen_or_i32(tmp, tmp, tmp2);
4878 tcg_temp_free_i32(tmp2);
4879 neon_store_reg(rd, pass, tmp);
4880 } else {
4881 tmp = neon_load_reg(rd, pass);
4882 tmp2 = tcg_temp_new_i32();
4883 tcg_gen_shri_i32(tmp2, tmp, 16);
4884 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4885 tcg_temp_free_i32(tmp);
4886 tcg_gen_addi_i32(addr, addr, stride);
4887 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4888 tcg_temp_free_i32(tmp2);
4889 tcg_gen_addi_i32(addr, addr, stride);
4891 } else /* size == 0 */ {
4892 if (load) {
4893 TCGV_UNUSED_I32(tmp2);
4894 for (n = 0; n < 4; n++) {
4895 tmp = tcg_temp_new_i32();
4896 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4897 tcg_gen_addi_i32(addr, addr, stride);
4898 if (n == 0) {
4899 tmp2 = tmp;
4900 } else {
4901 tcg_gen_shli_i32(tmp, tmp, n * 8);
4902 tcg_gen_or_i32(tmp2, tmp2, tmp);
4903 tcg_temp_free_i32(tmp);
4906 neon_store_reg(rd, pass, tmp2);
4907 } else {
4908 tmp2 = neon_load_reg(rd, pass);
4909 for (n = 0; n < 4; n++) {
4910 tmp = tcg_temp_new_i32();
4911 if (n == 0) {
4912 tcg_gen_mov_i32(tmp, tmp2);
4913 } else {
4914 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4916 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4917 tcg_temp_free_i32(tmp);
4918 tcg_gen_addi_i32(addr, addr, stride);
4920 tcg_temp_free_i32(tmp2);
4925 rd += spacing;
4927 tcg_temp_free_i32(addr);
4928 stride = nregs * 8;
4929 } else {
4930 size = (insn >> 10) & 3;
4931 if (size == 3) {
4932 /* Load single element to all lanes. */
4933 int a = (insn >> 4) & 1;
4934 if (!load) {
4935 return 1;
4937 size = (insn >> 6) & 3;
4938 nregs = ((insn >> 8) & 3) + 1;
4940 if (size == 3) {
4941 if (nregs != 4 || a == 0) {
4942 return 1;
4944 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4945 size = 2;
4947 if (nregs == 1 && a == 1 && size == 0) {
4948 return 1;
4950 if (nregs == 3 && a == 1) {
4951 return 1;
4953 addr = tcg_temp_new_i32();
4954 load_reg_var(s, addr, rn);
4955 if (nregs == 1) {
4956 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4957 tmp = gen_load_and_replicate(s, addr, size);
4958 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4959 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4960 if (insn & (1 << 5)) {
4961 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4962 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4964 tcg_temp_free_i32(tmp);
4965 } else {
4966 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4967 stride = (insn & (1 << 5)) ? 2 : 1;
4968 for (reg = 0; reg < nregs; reg++) {
4969 tmp = gen_load_and_replicate(s, addr, size);
4970 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4971 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4972 tcg_temp_free_i32(tmp);
4973 tcg_gen_addi_i32(addr, addr, 1 << size);
4974 rd += stride;
4977 tcg_temp_free_i32(addr);
4978 stride = (1 << size) * nregs;
4979 } else {
4980 /* Single element. */
4981 int idx = (insn >> 4) & 0xf;
4982 pass = (insn >> 7) & 1;
4983 switch (size) {
4984 case 0:
4985 shift = ((insn >> 5) & 3) * 8;
4986 stride = 1;
4987 break;
4988 case 1:
4989 shift = ((insn >> 6) & 1) * 16;
4990 stride = (insn & (1 << 5)) ? 2 : 1;
4991 break;
4992 case 2:
4993 shift = 0;
4994 stride = (insn & (1 << 6)) ? 2 : 1;
4995 break;
4996 default:
4997 abort();
4999 nregs = ((insn >> 8) & 3) + 1;
5000 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5001 switch (nregs) {
5002 case 1:
5003 if (((idx & (1 << size)) != 0) ||
5004 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5005 return 1;
5007 break;
5008 case 3:
5009 if ((idx & 1) != 0) {
5010 return 1;
5012 /* fall through */
5013 case 2:
5014 if (size == 2 && (idx & 2) != 0) {
5015 return 1;
5017 break;
5018 case 4:
5019 if ((size == 2) && ((idx & 3) == 3)) {
5020 return 1;
5022 break;
5023 default:
5024 abort();
5026 if ((rd + stride * (nregs - 1)) > 31) {
5027 /* Attempts to write off the end of the register file
5028 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5029 * the neon_load_reg() would write off the end of the array.
5031 return 1;
5033 addr = tcg_temp_new_i32();
5034 load_reg_var(s, addr, rn);
5035 for (reg = 0; reg < nregs; reg++) {
5036 if (load) {
5037 tmp = tcg_temp_new_i32();
5038 switch (size) {
5039 case 0:
5040 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5041 break;
5042 case 1:
5043 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5044 break;
5045 case 2:
5046 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5047 break;
5048 default: /* Avoid compiler warnings. */
5049 abort();
5051 if (size != 2) {
5052 tmp2 = neon_load_reg(rd, pass);
5053 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5054 shift, size ? 16 : 8);
5055 tcg_temp_free_i32(tmp2);
5057 neon_store_reg(rd, pass, tmp);
5058 } else { /* Store */
5059 tmp = neon_load_reg(rd, pass);
5060 if (shift)
5061 tcg_gen_shri_i32(tmp, tmp, shift);
5062 switch (size) {
5063 case 0:
5064 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5065 break;
5066 case 1:
5067 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5068 break;
5069 case 2:
5070 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5071 break;
5073 tcg_temp_free_i32(tmp);
5075 rd += stride;
5076 tcg_gen_addi_i32(addr, addr, 1 << size);
5078 tcg_temp_free_i32(addr);
5079 stride = nregs * (1 << size);
5082 if (rm != 15) {
5083 TCGv_i32 base;
5085 base = load_reg(s, rn);
5086 if (rm == 13) {
5087 tcg_gen_addi_i32(base, base, stride);
5088 } else {
5089 TCGv_i32 index;
5090 index = load_reg(s, rm);
5091 tcg_gen_add_i32(base, base, index);
5092 tcg_temp_free_i32(index);
5094 store_reg(s, rn, base);
5096 return 0;
5099 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5100 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5102 tcg_gen_and_i32(t, t, c);
5103 tcg_gen_andc_i32(f, f, c);
5104 tcg_gen_or_i32(dest, t, f);
5107 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5109 switch (size) {
5110 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5111 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5112 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5113 default: abort();
5117 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5119 switch (size) {
5120 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5121 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5122 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5123 default: abort();
5127 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5129 switch (size) {
5130 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5131 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5132 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5133 default: abort();
5137 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5139 switch (size) {
5140 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5141 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5142 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5143 default: abort();
5147 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5148 int q, int u)
5150 if (q) {
5151 if (u) {
5152 switch (size) {
5153 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5154 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5155 default: abort();
5157 } else {
5158 switch (size) {
5159 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5160 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5161 default: abort();
5164 } else {
5165 if (u) {
5166 switch (size) {
5167 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5168 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5169 default: abort();
5171 } else {
5172 switch (size) {
5173 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5174 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5175 default: abort();
5181 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5183 if (u) {
5184 switch (size) {
5185 case 0: gen_helper_neon_widen_u8(dest, src); break;
5186 case 1: gen_helper_neon_widen_u16(dest, src); break;
5187 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5188 default: abort();
5190 } else {
5191 switch (size) {
5192 case 0: gen_helper_neon_widen_s8(dest, src); break;
5193 case 1: gen_helper_neon_widen_s16(dest, src); break;
5194 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5195 default: abort();
5198 tcg_temp_free_i32(src);
5201 static inline void gen_neon_addl(int size)
5203 switch (size) {
5204 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5205 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5206 case 2: tcg_gen_add_i64(CPU_V001); break;
5207 default: abort();
5211 static inline void gen_neon_subl(int size)
5213 switch (size) {
5214 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5215 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5216 case 2: tcg_gen_sub_i64(CPU_V001); break;
5217 default: abort();
5221 static inline void gen_neon_negl(TCGv_i64 var, int size)
5223 switch (size) {
5224 case 0: gen_helper_neon_negl_u16(var, var); break;
5225 case 1: gen_helper_neon_negl_u32(var, var); break;
5226 case 2:
5227 tcg_gen_neg_i64(var, var);
5228 break;
5229 default: abort();
5233 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5235 switch (size) {
5236 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5237 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5238 default: abort();
5242 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5243 int size, int u)
5245 TCGv_i64 tmp;
5247 switch ((size << 1) | u) {
5248 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5249 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5250 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5251 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5252 case 4:
5253 tmp = gen_muls_i64_i32(a, b);
5254 tcg_gen_mov_i64(dest, tmp);
5255 tcg_temp_free_i64(tmp);
5256 break;
5257 case 5:
5258 tmp = gen_mulu_i64_i32(a, b);
5259 tcg_gen_mov_i64(dest, tmp);
5260 tcg_temp_free_i64(tmp);
5261 break;
5262 default: abort();
5265 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5266 Don't forget to clean them now. */
5267 if (size < 2) {
5268 tcg_temp_free_i32(a);
5269 tcg_temp_free_i32(b);
5273 static void gen_neon_narrow_op(int op, int u, int size,
5274 TCGv_i32 dest, TCGv_i64 src)
5276 if (op) {
5277 if (u) {
5278 gen_neon_unarrow_sats(size, dest, src);
5279 } else {
5280 gen_neon_narrow(size, dest, src);
5282 } else {
5283 if (u) {
5284 gen_neon_narrow_satu(size, dest, src);
5285 } else {
5286 gen_neon_narrow_sats(size, dest, src);
5291 /* Symbolic constants for op fields for Neon 3-register same-length.
5292 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5293 * table A7-9.
5295 #define NEON_3R_VHADD 0
5296 #define NEON_3R_VQADD 1
5297 #define NEON_3R_VRHADD 2
5298 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5299 #define NEON_3R_VHSUB 4
5300 #define NEON_3R_VQSUB 5
5301 #define NEON_3R_VCGT 6
5302 #define NEON_3R_VCGE 7
5303 #define NEON_3R_VSHL 8
5304 #define NEON_3R_VQSHL 9
5305 #define NEON_3R_VRSHL 10
5306 #define NEON_3R_VQRSHL 11
5307 #define NEON_3R_VMAX 12
5308 #define NEON_3R_VMIN 13
5309 #define NEON_3R_VABD 14
5310 #define NEON_3R_VABA 15
5311 #define NEON_3R_VADD_VSUB 16
5312 #define NEON_3R_VTST_VCEQ 17
5313 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5314 #define NEON_3R_VMUL 19
5315 #define NEON_3R_VPMAX 20
5316 #define NEON_3R_VPMIN 21
5317 #define NEON_3R_VQDMULH_VQRDMULH 22
5318 #define NEON_3R_VPADD 23
5319 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5320 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5321 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5322 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5323 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5324 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5325 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5326 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5328 static const uint8_t neon_3r_sizes[] = {
5329 [NEON_3R_VHADD] = 0x7,
5330 [NEON_3R_VQADD] = 0xf,
5331 [NEON_3R_VRHADD] = 0x7,
5332 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5333 [NEON_3R_VHSUB] = 0x7,
5334 [NEON_3R_VQSUB] = 0xf,
5335 [NEON_3R_VCGT] = 0x7,
5336 [NEON_3R_VCGE] = 0x7,
5337 [NEON_3R_VSHL] = 0xf,
5338 [NEON_3R_VQSHL] = 0xf,
5339 [NEON_3R_VRSHL] = 0xf,
5340 [NEON_3R_VQRSHL] = 0xf,
5341 [NEON_3R_VMAX] = 0x7,
5342 [NEON_3R_VMIN] = 0x7,
5343 [NEON_3R_VABD] = 0x7,
5344 [NEON_3R_VABA] = 0x7,
5345 [NEON_3R_VADD_VSUB] = 0xf,
5346 [NEON_3R_VTST_VCEQ] = 0x7,
5347 [NEON_3R_VML] = 0x7,
5348 [NEON_3R_VMUL] = 0x7,
5349 [NEON_3R_VPMAX] = 0x7,
5350 [NEON_3R_VPMIN] = 0x7,
5351 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5352 [NEON_3R_VPADD] = 0x7,
5353 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5354 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5355 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5356 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5357 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5358 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5359 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5360 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5363 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5364 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5365 * table A7-13.
5367 #define NEON_2RM_VREV64 0
5368 #define NEON_2RM_VREV32 1
5369 #define NEON_2RM_VREV16 2
5370 #define NEON_2RM_VPADDL 4
5371 #define NEON_2RM_VPADDL_U 5
5372 #define NEON_2RM_AESE 6 /* Includes AESD */
5373 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5374 #define NEON_2RM_VCLS 8
5375 #define NEON_2RM_VCLZ 9
5376 #define NEON_2RM_VCNT 10
5377 #define NEON_2RM_VMVN 11
5378 #define NEON_2RM_VPADAL 12
5379 #define NEON_2RM_VPADAL_U 13
5380 #define NEON_2RM_VQABS 14
5381 #define NEON_2RM_VQNEG 15
5382 #define NEON_2RM_VCGT0 16
5383 #define NEON_2RM_VCGE0 17
5384 #define NEON_2RM_VCEQ0 18
5385 #define NEON_2RM_VCLE0 19
5386 #define NEON_2RM_VCLT0 20
5387 #define NEON_2RM_SHA1H 21
5388 #define NEON_2RM_VABS 22
5389 #define NEON_2RM_VNEG 23
5390 #define NEON_2RM_VCGT0_F 24
5391 #define NEON_2RM_VCGE0_F 25
5392 #define NEON_2RM_VCEQ0_F 26
5393 #define NEON_2RM_VCLE0_F 27
5394 #define NEON_2RM_VCLT0_F 28
5395 #define NEON_2RM_VABS_F 30
5396 #define NEON_2RM_VNEG_F 31
5397 #define NEON_2RM_VSWP 32
5398 #define NEON_2RM_VTRN 33
5399 #define NEON_2RM_VUZP 34
5400 #define NEON_2RM_VZIP 35
5401 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5402 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5403 #define NEON_2RM_VSHLL 38
5404 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5405 #define NEON_2RM_VRINTN 40
5406 #define NEON_2RM_VRINTX 41
5407 #define NEON_2RM_VRINTA 42
5408 #define NEON_2RM_VRINTZ 43
5409 #define NEON_2RM_VCVT_F16_F32 44
5410 #define NEON_2RM_VRINTM 45
5411 #define NEON_2RM_VCVT_F32_F16 46
5412 #define NEON_2RM_VRINTP 47
5413 #define NEON_2RM_VCVTAU 48
5414 #define NEON_2RM_VCVTAS 49
5415 #define NEON_2RM_VCVTNU 50
5416 #define NEON_2RM_VCVTNS 51
5417 #define NEON_2RM_VCVTPU 52
5418 #define NEON_2RM_VCVTPS 53
5419 #define NEON_2RM_VCVTMU 54
5420 #define NEON_2RM_VCVTMS 55
5421 #define NEON_2RM_VRECPE 56
5422 #define NEON_2RM_VRSQRTE 57
5423 #define NEON_2RM_VRECPE_F 58
5424 #define NEON_2RM_VRSQRTE_F 59
5425 #define NEON_2RM_VCVT_FS 60
5426 #define NEON_2RM_VCVT_FU 61
5427 #define NEON_2RM_VCVT_SF 62
5428 #define NEON_2RM_VCVT_UF 63
5430 static int neon_2rm_is_float_op(int op)
5432 /* Return true if this neon 2reg-misc op is float-to-float */
5433 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5434 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5435 op == NEON_2RM_VRINTM ||
5436 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5437 op >= NEON_2RM_VRECPE_F);
5440 static bool neon_2rm_is_v8_op(int op)
5442 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5443 switch (op) {
5444 case NEON_2RM_VRINTN:
5445 case NEON_2RM_VRINTA:
5446 case NEON_2RM_VRINTM:
5447 case NEON_2RM_VRINTP:
5448 case NEON_2RM_VRINTZ:
5449 case NEON_2RM_VRINTX:
5450 case NEON_2RM_VCVTAU:
5451 case NEON_2RM_VCVTAS:
5452 case NEON_2RM_VCVTNU:
5453 case NEON_2RM_VCVTNS:
5454 case NEON_2RM_VCVTPU:
5455 case NEON_2RM_VCVTPS:
5456 case NEON_2RM_VCVTMU:
5457 case NEON_2RM_VCVTMS:
5458 return true;
5459 default:
5460 return false;
5464 /* Each entry in this array has bit n set if the insn allows
5465 * size value n (otherwise it will UNDEF). Since unallocated
5466 * op values will have no bits set they always UNDEF.
5468 static const uint8_t neon_2rm_sizes[] = {
5469 [NEON_2RM_VREV64] = 0x7,
5470 [NEON_2RM_VREV32] = 0x3,
5471 [NEON_2RM_VREV16] = 0x1,
5472 [NEON_2RM_VPADDL] = 0x7,
5473 [NEON_2RM_VPADDL_U] = 0x7,
5474 [NEON_2RM_AESE] = 0x1,
5475 [NEON_2RM_AESMC] = 0x1,
5476 [NEON_2RM_VCLS] = 0x7,
5477 [NEON_2RM_VCLZ] = 0x7,
5478 [NEON_2RM_VCNT] = 0x1,
5479 [NEON_2RM_VMVN] = 0x1,
5480 [NEON_2RM_VPADAL] = 0x7,
5481 [NEON_2RM_VPADAL_U] = 0x7,
5482 [NEON_2RM_VQABS] = 0x7,
5483 [NEON_2RM_VQNEG] = 0x7,
5484 [NEON_2RM_VCGT0] = 0x7,
5485 [NEON_2RM_VCGE0] = 0x7,
5486 [NEON_2RM_VCEQ0] = 0x7,
5487 [NEON_2RM_VCLE0] = 0x7,
5488 [NEON_2RM_VCLT0] = 0x7,
5489 [NEON_2RM_SHA1H] = 0x4,
5490 [NEON_2RM_VABS] = 0x7,
5491 [NEON_2RM_VNEG] = 0x7,
5492 [NEON_2RM_VCGT0_F] = 0x4,
5493 [NEON_2RM_VCGE0_F] = 0x4,
5494 [NEON_2RM_VCEQ0_F] = 0x4,
5495 [NEON_2RM_VCLE0_F] = 0x4,
5496 [NEON_2RM_VCLT0_F] = 0x4,
5497 [NEON_2RM_VABS_F] = 0x4,
5498 [NEON_2RM_VNEG_F] = 0x4,
5499 [NEON_2RM_VSWP] = 0x1,
5500 [NEON_2RM_VTRN] = 0x7,
5501 [NEON_2RM_VUZP] = 0x7,
5502 [NEON_2RM_VZIP] = 0x7,
5503 [NEON_2RM_VMOVN] = 0x7,
5504 [NEON_2RM_VQMOVN] = 0x7,
5505 [NEON_2RM_VSHLL] = 0x7,
5506 [NEON_2RM_SHA1SU1] = 0x4,
5507 [NEON_2RM_VRINTN] = 0x4,
5508 [NEON_2RM_VRINTX] = 0x4,
5509 [NEON_2RM_VRINTA] = 0x4,
5510 [NEON_2RM_VRINTZ] = 0x4,
5511 [NEON_2RM_VCVT_F16_F32] = 0x2,
5512 [NEON_2RM_VRINTM] = 0x4,
5513 [NEON_2RM_VCVT_F32_F16] = 0x2,
5514 [NEON_2RM_VRINTP] = 0x4,
5515 [NEON_2RM_VCVTAU] = 0x4,
5516 [NEON_2RM_VCVTAS] = 0x4,
5517 [NEON_2RM_VCVTNU] = 0x4,
5518 [NEON_2RM_VCVTNS] = 0x4,
5519 [NEON_2RM_VCVTPU] = 0x4,
5520 [NEON_2RM_VCVTPS] = 0x4,
5521 [NEON_2RM_VCVTMU] = 0x4,
5522 [NEON_2RM_VCVTMS] = 0x4,
5523 [NEON_2RM_VRECPE] = 0x4,
5524 [NEON_2RM_VRSQRTE] = 0x4,
5525 [NEON_2RM_VRECPE_F] = 0x4,
5526 [NEON_2RM_VRSQRTE_F] = 0x4,
5527 [NEON_2RM_VCVT_FS] = 0x4,
5528 [NEON_2RM_VCVT_FU] = 0x4,
5529 [NEON_2RM_VCVT_SF] = 0x4,
5530 [NEON_2RM_VCVT_UF] = 0x4,
5533 /* Translate a NEON data processing instruction. Return nonzero if the
5534 instruction is invalid.
5535 We process data in a mixture of 32-bit and 64-bit chunks.
5536 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5538 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5540 int op;
5541 int q;
5542 int rd, rn, rm;
5543 int size;
5544 int shift;
5545 int pass;
5546 int count;
5547 int pairwise;
5548 int u;
5549 uint32_t imm, mask;
5550 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5551 TCGv_i64 tmp64;
5553 /* FIXME: this access check should not take precedence over UNDEF
5554 * for invalid encodings; we will generate incorrect syndrome information
5555 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5557 if (s->fp_excp_el) {
5558 gen_exception_insn(s, 4, EXCP_UDEF,
5559 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5560 return 0;
5563 if (!s->vfp_enabled)
5564 return 1;
5565 q = (insn & (1 << 6)) != 0;
5566 u = (insn >> 24) & 1;
5567 VFP_DREG_D(rd, insn);
5568 VFP_DREG_N(rn, insn);
5569 VFP_DREG_M(rm, insn);
5570 size = (insn >> 20) & 3;
5571 if ((insn & (1 << 23)) == 0) {
5572 /* Three register same length. */
5573 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5574 /* Catch invalid op and bad size combinations: UNDEF */
5575 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5576 return 1;
5578 /* All insns of this form UNDEF for either this condition or the
5579 * superset of cases "Q==1"; we catch the latter later.
5581 if (q && ((rd | rn | rm) & 1)) {
5582 return 1;
5585 * The SHA-1/SHA-256 3-register instructions require special treatment
5586 * here, as their size field is overloaded as an op type selector, and
5587 * they all consume their input in a single pass.
5589 if (op == NEON_3R_SHA) {
5590 if (!q) {
5591 return 1;
5593 if (!u) { /* SHA-1 */
5594 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5595 return 1;
5597 tmp = tcg_const_i32(rd);
5598 tmp2 = tcg_const_i32(rn);
5599 tmp3 = tcg_const_i32(rm);
5600 tmp4 = tcg_const_i32(size);
5601 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5602 tcg_temp_free_i32(tmp4);
5603 } else { /* SHA-256 */
5604 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5605 return 1;
5607 tmp = tcg_const_i32(rd);
5608 tmp2 = tcg_const_i32(rn);
5609 tmp3 = tcg_const_i32(rm);
5610 switch (size) {
5611 case 0:
5612 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5613 break;
5614 case 1:
5615 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5616 break;
5617 case 2:
5618 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5619 break;
5622 tcg_temp_free_i32(tmp);
5623 tcg_temp_free_i32(tmp2);
5624 tcg_temp_free_i32(tmp3);
5625 return 0;
5627 if (size == 3 && op != NEON_3R_LOGIC) {
5628 /* 64-bit element instructions. */
5629 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5630 neon_load_reg64(cpu_V0, rn + pass);
5631 neon_load_reg64(cpu_V1, rm + pass);
5632 switch (op) {
5633 case NEON_3R_VQADD:
5634 if (u) {
5635 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5636 cpu_V0, cpu_V1);
5637 } else {
5638 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5639 cpu_V0, cpu_V1);
5641 break;
5642 case NEON_3R_VQSUB:
5643 if (u) {
5644 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5645 cpu_V0, cpu_V1);
5646 } else {
5647 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5648 cpu_V0, cpu_V1);
5650 break;
5651 case NEON_3R_VSHL:
5652 if (u) {
5653 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5654 } else {
5655 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5657 break;
5658 case NEON_3R_VQSHL:
5659 if (u) {
5660 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5661 cpu_V1, cpu_V0);
5662 } else {
5663 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5664 cpu_V1, cpu_V0);
5666 break;
5667 case NEON_3R_VRSHL:
5668 if (u) {
5669 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5670 } else {
5671 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5673 break;
5674 case NEON_3R_VQRSHL:
5675 if (u) {
5676 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5677 cpu_V1, cpu_V0);
5678 } else {
5679 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5680 cpu_V1, cpu_V0);
5682 break;
5683 case NEON_3R_VADD_VSUB:
5684 if (u) {
5685 tcg_gen_sub_i64(CPU_V001);
5686 } else {
5687 tcg_gen_add_i64(CPU_V001);
5689 break;
5690 default:
5691 abort();
5693 neon_store_reg64(cpu_V0, rd + pass);
5695 return 0;
5697 pairwise = 0;
5698 switch (op) {
5699 case NEON_3R_VSHL:
5700 case NEON_3R_VQSHL:
5701 case NEON_3R_VRSHL:
5702 case NEON_3R_VQRSHL:
5704 int rtmp;
5705 /* Shift instruction operands are reversed. */
5706 rtmp = rn;
5707 rn = rm;
5708 rm = rtmp;
5710 break;
5711 case NEON_3R_VPADD:
5712 if (u) {
5713 return 1;
5715 /* Fall through */
5716 case NEON_3R_VPMAX:
5717 case NEON_3R_VPMIN:
5718 pairwise = 1;
5719 break;
5720 case NEON_3R_FLOAT_ARITH:
5721 pairwise = (u && size < 2); /* if VPADD (float) */
5722 break;
5723 case NEON_3R_FLOAT_MINMAX:
5724 pairwise = u; /* if VPMIN/VPMAX (float) */
5725 break;
5726 case NEON_3R_FLOAT_CMP:
5727 if (!u && size) {
5728 /* no encoding for U=0 C=1x */
5729 return 1;
5731 break;
5732 case NEON_3R_FLOAT_ACMP:
5733 if (!u) {
5734 return 1;
5736 break;
5737 case NEON_3R_FLOAT_MISC:
5738 /* VMAXNM/VMINNM in ARMv8 */
5739 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5740 return 1;
5742 break;
5743 case NEON_3R_VMUL:
5744 if (u && (size != 0)) {
5745 /* UNDEF on invalid size for polynomial subcase */
5746 return 1;
5748 break;
5749 case NEON_3R_VFM:
5750 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5751 return 1;
5753 break;
5754 default:
5755 break;
5758 if (pairwise && q) {
5759 /* All the pairwise insns UNDEF if Q is set */
5760 return 1;
5763 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5765 if (pairwise) {
5766 /* Pairwise. */
5767 if (pass < 1) {
5768 tmp = neon_load_reg(rn, 0);
5769 tmp2 = neon_load_reg(rn, 1);
5770 } else {
5771 tmp = neon_load_reg(rm, 0);
5772 tmp2 = neon_load_reg(rm, 1);
5774 } else {
5775 /* Elementwise. */
5776 tmp = neon_load_reg(rn, pass);
5777 tmp2 = neon_load_reg(rm, pass);
5779 switch (op) {
5780 case NEON_3R_VHADD:
5781 GEN_NEON_INTEGER_OP(hadd);
5782 break;
5783 case NEON_3R_VQADD:
5784 GEN_NEON_INTEGER_OP_ENV(qadd);
5785 break;
5786 case NEON_3R_VRHADD:
5787 GEN_NEON_INTEGER_OP(rhadd);
5788 break;
5789 case NEON_3R_LOGIC: /* Logic ops. */
5790 switch ((u << 2) | size) {
5791 case 0: /* VAND */
5792 tcg_gen_and_i32(tmp, tmp, tmp2);
5793 break;
5794 case 1: /* BIC */
5795 tcg_gen_andc_i32(tmp, tmp, tmp2);
5796 break;
5797 case 2: /* VORR */
5798 tcg_gen_or_i32(tmp, tmp, tmp2);
5799 break;
5800 case 3: /* VORN */
5801 tcg_gen_orc_i32(tmp, tmp, tmp2);
5802 break;
5803 case 4: /* VEOR */
5804 tcg_gen_xor_i32(tmp, tmp, tmp2);
5805 break;
5806 case 5: /* VBSL */
5807 tmp3 = neon_load_reg(rd, pass);
5808 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5809 tcg_temp_free_i32(tmp3);
5810 break;
5811 case 6: /* VBIT */
5812 tmp3 = neon_load_reg(rd, pass);
5813 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5814 tcg_temp_free_i32(tmp3);
5815 break;
5816 case 7: /* VBIF */
5817 tmp3 = neon_load_reg(rd, pass);
5818 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5819 tcg_temp_free_i32(tmp3);
5820 break;
5822 break;
5823 case NEON_3R_VHSUB:
5824 GEN_NEON_INTEGER_OP(hsub);
5825 break;
5826 case NEON_3R_VQSUB:
5827 GEN_NEON_INTEGER_OP_ENV(qsub);
5828 break;
5829 case NEON_3R_VCGT:
5830 GEN_NEON_INTEGER_OP(cgt);
5831 break;
5832 case NEON_3R_VCGE:
5833 GEN_NEON_INTEGER_OP(cge);
5834 break;
5835 case NEON_3R_VSHL:
5836 GEN_NEON_INTEGER_OP(shl);
5837 break;
5838 case NEON_3R_VQSHL:
5839 GEN_NEON_INTEGER_OP_ENV(qshl);
5840 break;
5841 case NEON_3R_VRSHL:
5842 GEN_NEON_INTEGER_OP(rshl);
5843 break;
5844 case NEON_3R_VQRSHL:
5845 GEN_NEON_INTEGER_OP_ENV(qrshl);
5846 break;
5847 case NEON_3R_VMAX:
5848 GEN_NEON_INTEGER_OP(max);
5849 break;
5850 case NEON_3R_VMIN:
5851 GEN_NEON_INTEGER_OP(min);
5852 break;
5853 case NEON_3R_VABD:
5854 GEN_NEON_INTEGER_OP(abd);
5855 break;
5856 case NEON_3R_VABA:
5857 GEN_NEON_INTEGER_OP(abd);
5858 tcg_temp_free_i32(tmp2);
5859 tmp2 = neon_load_reg(rd, pass);
5860 gen_neon_add(size, tmp, tmp2);
5861 break;
5862 case NEON_3R_VADD_VSUB:
5863 if (!u) { /* VADD */
5864 gen_neon_add(size, tmp, tmp2);
5865 } else { /* VSUB */
5866 switch (size) {
5867 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5868 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5869 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5870 default: abort();
5873 break;
5874 case NEON_3R_VTST_VCEQ:
5875 if (!u) { /* VTST */
5876 switch (size) {
5877 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5878 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5879 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5880 default: abort();
5882 } else { /* VCEQ */
5883 switch (size) {
5884 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5885 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5886 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5887 default: abort();
5890 break;
5891 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5892 switch (size) {
5893 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5894 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5895 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5896 default: abort();
5898 tcg_temp_free_i32(tmp2);
5899 tmp2 = neon_load_reg(rd, pass);
5900 if (u) { /* VMLS */
5901 gen_neon_rsb(size, tmp, tmp2);
5902 } else { /* VMLA */
5903 gen_neon_add(size, tmp, tmp2);
5905 break;
5906 case NEON_3R_VMUL:
5907 if (u) { /* polynomial */
5908 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5909 } else { /* Integer */
5910 switch (size) {
5911 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5912 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5913 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5914 default: abort();
5917 break;
5918 case NEON_3R_VPMAX:
5919 GEN_NEON_INTEGER_OP(pmax);
5920 break;
5921 case NEON_3R_VPMIN:
5922 GEN_NEON_INTEGER_OP(pmin);
5923 break;
5924 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5925 if (!u) { /* VQDMULH */
5926 switch (size) {
5927 case 1:
5928 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5929 break;
5930 case 2:
5931 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5932 break;
5933 default: abort();
5935 } else { /* VQRDMULH */
5936 switch (size) {
5937 case 1:
5938 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5939 break;
5940 case 2:
5941 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5942 break;
5943 default: abort();
5946 break;
5947 case NEON_3R_VPADD:
5948 switch (size) {
5949 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5950 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5951 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5952 default: abort();
5954 break;
5955 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5957 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5958 switch ((u << 2) | size) {
5959 case 0: /* VADD */
5960 case 4: /* VPADD */
5961 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5962 break;
5963 case 2: /* VSUB */
5964 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5965 break;
5966 case 6: /* VABD */
5967 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5968 break;
5969 default:
5970 abort();
5972 tcg_temp_free_ptr(fpstatus);
5973 break;
5975 case NEON_3R_FLOAT_MULTIPLY:
5977 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5978 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5979 if (!u) {
5980 tcg_temp_free_i32(tmp2);
5981 tmp2 = neon_load_reg(rd, pass);
5982 if (size == 0) {
5983 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5984 } else {
5985 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5988 tcg_temp_free_ptr(fpstatus);
5989 break;
5991 case NEON_3R_FLOAT_CMP:
5993 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5994 if (!u) {
5995 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5996 } else {
5997 if (size == 0) {
5998 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5999 } else {
6000 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6003 tcg_temp_free_ptr(fpstatus);
6004 break;
6006 case NEON_3R_FLOAT_ACMP:
6008 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6009 if (size == 0) {
6010 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6011 } else {
6012 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6014 tcg_temp_free_ptr(fpstatus);
6015 break;
6017 case NEON_3R_FLOAT_MINMAX:
6019 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6020 if (size == 0) {
6021 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6022 } else {
6023 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6025 tcg_temp_free_ptr(fpstatus);
6026 break;
6028 case NEON_3R_FLOAT_MISC:
6029 if (u) {
6030 /* VMAXNM/VMINNM */
6031 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6032 if (size == 0) {
6033 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6034 } else {
6035 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6037 tcg_temp_free_ptr(fpstatus);
6038 } else {
6039 if (size == 0) {
6040 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6041 } else {
6042 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6045 break;
6046 case NEON_3R_VFM:
6048 /* VFMA, VFMS: fused multiply-add */
6049 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6050 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6051 if (size) {
6052 /* VFMS */
6053 gen_helper_vfp_negs(tmp, tmp);
6055 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6056 tcg_temp_free_i32(tmp3);
6057 tcg_temp_free_ptr(fpstatus);
6058 break;
6060 default:
6061 abort();
6063 tcg_temp_free_i32(tmp2);
6065 /* Save the result. For elementwise operations we can put it
6066 straight into the destination register. For pairwise operations
6067 we have to be careful to avoid clobbering the source operands. */
6068 if (pairwise && rd == rm) {
6069 neon_store_scratch(pass, tmp);
6070 } else {
6071 neon_store_reg(rd, pass, tmp);
6074 } /* for pass */
6075 if (pairwise && rd == rm) {
6076 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6077 tmp = neon_load_scratch(pass);
6078 neon_store_reg(rd, pass, tmp);
6081 /* End of 3 register same size operations. */
6082 } else if (insn & (1 << 4)) {
6083 if ((insn & 0x00380080) != 0) {
6084 /* Two registers and shift. */
6085 op = (insn >> 8) & 0xf;
6086 if (insn & (1 << 7)) {
6087 /* 64-bit shift. */
6088 if (op > 7) {
6089 return 1;
6091 size = 3;
6092 } else {
6093 size = 2;
6094 while ((insn & (1 << (size + 19))) == 0)
6095 size--;
6097 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6098 /* To avoid excessive duplication of ops we implement shift
6099 by immediate using the variable shift operations. */
6100 if (op < 8) {
6101 /* Shift by immediate:
6102 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6103 if (q && ((rd | rm) & 1)) {
6104 return 1;
6106 if (!u && (op == 4 || op == 6)) {
6107 return 1;
6109 /* Right shifts are encoded as N - shift, where N is the
6110 element size in bits. */
6111 if (op <= 4)
6112 shift = shift - (1 << (size + 3));
6113 if (size == 3) {
6114 count = q + 1;
6115 } else {
6116 count = q ? 4: 2;
6118 switch (size) {
6119 case 0:
6120 imm = (uint8_t) shift;
6121 imm |= imm << 8;
6122 imm |= imm << 16;
6123 break;
6124 case 1:
6125 imm = (uint16_t) shift;
6126 imm |= imm << 16;
6127 break;
6128 case 2:
6129 case 3:
6130 imm = shift;
6131 break;
6132 default:
6133 abort();
6136 for (pass = 0; pass < count; pass++) {
6137 if (size == 3) {
6138 neon_load_reg64(cpu_V0, rm + pass);
6139 tcg_gen_movi_i64(cpu_V1, imm);
6140 switch (op) {
6141 case 0: /* VSHR */
6142 case 1: /* VSRA */
6143 if (u)
6144 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6145 else
6146 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6147 break;
6148 case 2: /* VRSHR */
6149 case 3: /* VRSRA */
6150 if (u)
6151 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6152 else
6153 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6154 break;
6155 case 4: /* VSRI */
6156 case 5: /* VSHL, VSLI */
6157 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6158 break;
6159 case 6: /* VQSHLU */
6160 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6161 cpu_V0, cpu_V1);
6162 break;
6163 case 7: /* VQSHL */
6164 if (u) {
6165 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6166 cpu_V0, cpu_V1);
6167 } else {
6168 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6169 cpu_V0, cpu_V1);
6171 break;
6173 if (op == 1 || op == 3) {
6174 /* Accumulate. */
6175 neon_load_reg64(cpu_V1, rd + pass);
6176 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6177 } else if (op == 4 || (op == 5 && u)) {
6178 /* Insert */
6179 neon_load_reg64(cpu_V1, rd + pass);
6180 uint64_t mask;
6181 if (shift < -63 || shift > 63) {
6182 mask = 0;
6183 } else {
6184 if (op == 4) {
6185 mask = 0xffffffffffffffffull >> -shift;
6186 } else {
6187 mask = 0xffffffffffffffffull << shift;
6190 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6191 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6193 neon_store_reg64(cpu_V0, rd + pass);
6194 } else { /* size < 3 */
6195 /* Operands in T0 and T1. */
6196 tmp = neon_load_reg(rm, pass);
6197 tmp2 = tcg_temp_new_i32();
6198 tcg_gen_movi_i32(tmp2, imm);
6199 switch (op) {
6200 case 0: /* VSHR */
6201 case 1: /* VSRA */
6202 GEN_NEON_INTEGER_OP(shl);
6203 break;
6204 case 2: /* VRSHR */
6205 case 3: /* VRSRA */
6206 GEN_NEON_INTEGER_OP(rshl);
6207 break;
6208 case 4: /* VSRI */
6209 case 5: /* VSHL, VSLI */
6210 switch (size) {
6211 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6212 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6213 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6214 default: abort();
6216 break;
6217 case 6: /* VQSHLU */
6218 switch (size) {
6219 case 0:
6220 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6221 tmp, tmp2);
6222 break;
6223 case 1:
6224 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6225 tmp, tmp2);
6226 break;
6227 case 2:
6228 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6229 tmp, tmp2);
6230 break;
6231 default:
6232 abort();
6234 break;
6235 case 7: /* VQSHL */
6236 GEN_NEON_INTEGER_OP_ENV(qshl);
6237 break;
6239 tcg_temp_free_i32(tmp2);
6241 if (op == 1 || op == 3) {
6242 /* Accumulate. */
6243 tmp2 = neon_load_reg(rd, pass);
6244 gen_neon_add(size, tmp, tmp2);
6245 tcg_temp_free_i32(tmp2);
6246 } else if (op == 4 || (op == 5 && u)) {
6247 /* Insert */
6248 switch (size) {
6249 case 0:
6250 if (op == 4)
6251 mask = 0xff >> -shift;
6252 else
6253 mask = (uint8_t)(0xff << shift);
6254 mask |= mask << 8;
6255 mask |= mask << 16;
6256 break;
6257 case 1:
6258 if (op == 4)
6259 mask = 0xffff >> -shift;
6260 else
6261 mask = (uint16_t)(0xffff << shift);
6262 mask |= mask << 16;
6263 break;
6264 case 2:
6265 if (shift < -31 || shift > 31) {
6266 mask = 0;
6267 } else {
6268 if (op == 4)
6269 mask = 0xffffffffu >> -shift;
6270 else
6271 mask = 0xffffffffu << shift;
6273 break;
6274 default:
6275 abort();
6277 tmp2 = neon_load_reg(rd, pass);
6278 tcg_gen_andi_i32(tmp, tmp, mask);
6279 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6280 tcg_gen_or_i32(tmp, tmp, tmp2);
6281 tcg_temp_free_i32(tmp2);
6283 neon_store_reg(rd, pass, tmp);
6285 } /* for pass */
6286 } else if (op < 10) {
6287 /* Shift by immediate and narrow:
6288 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6289 int input_unsigned = (op == 8) ? !u : u;
6290 if (rm & 1) {
6291 return 1;
6293 shift = shift - (1 << (size + 3));
6294 size++;
6295 if (size == 3) {
6296 tmp64 = tcg_const_i64(shift);
6297 neon_load_reg64(cpu_V0, rm);
6298 neon_load_reg64(cpu_V1, rm + 1);
6299 for (pass = 0; pass < 2; pass++) {
6300 TCGv_i64 in;
6301 if (pass == 0) {
6302 in = cpu_V0;
6303 } else {
6304 in = cpu_V1;
6306 if (q) {
6307 if (input_unsigned) {
6308 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6309 } else {
6310 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6312 } else {
6313 if (input_unsigned) {
6314 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6315 } else {
6316 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6319 tmp = tcg_temp_new_i32();
6320 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6321 neon_store_reg(rd, pass, tmp);
6322 } /* for pass */
6323 tcg_temp_free_i64(tmp64);
6324 } else {
6325 if (size == 1) {
6326 imm = (uint16_t)shift;
6327 imm |= imm << 16;
6328 } else {
6329 /* size == 2 */
6330 imm = (uint32_t)shift;
6332 tmp2 = tcg_const_i32(imm);
6333 tmp4 = neon_load_reg(rm + 1, 0);
6334 tmp5 = neon_load_reg(rm + 1, 1);
6335 for (pass = 0; pass < 2; pass++) {
6336 if (pass == 0) {
6337 tmp = neon_load_reg(rm, 0);
6338 } else {
6339 tmp = tmp4;
6341 gen_neon_shift_narrow(size, tmp, tmp2, q,
6342 input_unsigned);
6343 if (pass == 0) {
6344 tmp3 = neon_load_reg(rm, 1);
6345 } else {
6346 tmp3 = tmp5;
6348 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6349 input_unsigned);
6350 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6351 tcg_temp_free_i32(tmp);
6352 tcg_temp_free_i32(tmp3);
6353 tmp = tcg_temp_new_i32();
6354 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6355 neon_store_reg(rd, pass, tmp);
6356 } /* for pass */
6357 tcg_temp_free_i32(tmp2);
6359 } else if (op == 10) {
6360 /* VSHLL, VMOVL */
6361 if (q || (rd & 1)) {
6362 return 1;
6364 tmp = neon_load_reg(rm, 0);
6365 tmp2 = neon_load_reg(rm, 1);
6366 for (pass = 0; pass < 2; pass++) {
6367 if (pass == 1)
6368 tmp = tmp2;
6370 gen_neon_widen(cpu_V0, tmp, size, u);
6372 if (shift != 0) {
6373 /* The shift is less than the width of the source
6374 type, so we can just shift the whole register. */
6375 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6376 /* Widen the result of shift: we need to clear
6377 * the potential overflow bits resulting from
6378 * left bits of the narrow input appearing as
6379 * right bits of left the neighbour narrow
6380 * input. */
6381 if (size < 2 || !u) {
6382 uint64_t imm64;
6383 if (size == 0) {
6384 imm = (0xffu >> (8 - shift));
6385 imm |= imm << 16;
6386 } else if (size == 1) {
6387 imm = 0xffff >> (16 - shift);
6388 } else {
6389 /* size == 2 */
6390 imm = 0xffffffff >> (32 - shift);
6392 if (size < 2) {
6393 imm64 = imm | (((uint64_t)imm) << 32);
6394 } else {
6395 imm64 = imm;
6397 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6400 neon_store_reg64(cpu_V0, rd + pass);
6402 } else if (op >= 14) {
6403 /* VCVT fixed-point. */
6404 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6405 return 1;
6407 /* We have already masked out the must-be-1 top bit of imm6,
6408 * hence this 32-shift where the ARM ARM has 64-imm6.
6410 shift = 32 - shift;
6411 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6412 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6413 if (!(op & 1)) {
6414 if (u)
6415 gen_vfp_ulto(0, shift, 1);
6416 else
6417 gen_vfp_slto(0, shift, 1);
6418 } else {
6419 if (u)
6420 gen_vfp_toul(0, shift, 1);
6421 else
6422 gen_vfp_tosl(0, shift, 1);
6424 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6426 } else {
6427 return 1;
6429 } else { /* (insn & 0x00380080) == 0 */
6430 int invert;
6431 if (q && (rd & 1)) {
6432 return 1;
6435 op = (insn >> 8) & 0xf;
6436 /* One register and immediate. */
6437 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6438 invert = (insn & (1 << 5)) != 0;
6439 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6440 * We choose to not special-case this and will behave as if a
6441 * valid constant encoding of 0 had been given.
6443 switch (op) {
6444 case 0: case 1:
6445 /* no-op */
6446 break;
6447 case 2: case 3:
6448 imm <<= 8;
6449 break;
6450 case 4: case 5:
6451 imm <<= 16;
6452 break;
6453 case 6: case 7:
6454 imm <<= 24;
6455 break;
6456 case 8: case 9:
6457 imm |= imm << 16;
6458 break;
6459 case 10: case 11:
6460 imm = (imm << 8) | (imm << 24);
6461 break;
6462 case 12:
6463 imm = (imm << 8) | 0xff;
6464 break;
6465 case 13:
6466 imm = (imm << 16) | 0xffff;
6467 break;
6468 case 14:
6469 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6470 if (invert)
6471 imm = ~imm;
6472 break;
6473 case 15:
6474 if (invert) {
6475 return 1;
6477 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6478 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6479 break;
6481 if (invert)
6482 imm = ~imm;
6484 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6485 if (op & 1 && op < 12) {
6486 tmp = neon_load_reg(rd, pass);
6487 if (invert) {
6488 /* The immediate value has already been inverted, so
6489 BIC becomes AND. */
6490 tcg_gen_andi_i32(tmp, tmp, imm);
6491 } else {
6492 tcg_gen_ori_i32(tmp, tmp, imm);
6494 } else {
6495 /* VMOV, VMVN. */
6496 tmp = tcg_temp_new_i32();
6497 if (op == 14 && invert) {
6498 int n;
6499 uint32_t val;
6500 val = 0;
6501 for (n = 0; n < 4; n++) {
6502 if (imm & (1 << (n + (pass & 1) * 4)))
6503 val |= 0xff << (n * 8);
6505 tcg_gen_movi_i32(tmp, val);
6506 } else {
6507 tcg_gen_movi_i32(tmp, imm);
6510 neon_store_reg(rd, pass, tmp);
6513 } else { /* (insn & 0x00800010 == 0x00800000) */
6514 if (size != 3) {
6515 op = (insn >> 8) & 0xf;
6516 if ((insn & (1 << 6)) == 0) {
6517 /* Three registers of different lengths. */
6518 int src1_wide;
6519 int src2_wide;
6520 int prewiden;
6521 /* undefreq: bit 0 : UNDEF if size == 0
6522 * bit 1 : UNDEF if size == 1
6523 * bit 2 : UNDEF if size == 2
6524 * bit 3 : UNDEF if U == 1
6525 * Note that [2:0] set implies 'always UNDEF'
6527 int undefreq;
6528 /* prewiden, src1_wide, src2_wide, undefreq */
6529 static const int neon_3reg_wide[16][4] = {
6530 {1, 0, 0, 0}, /* VADDL */
6531 {1, 1, 0, 0}, /* VADDW */
6532 {1, 0, 0, 0}, /* VSUBL */
6533 {1, 1, 0, 0}, /* VSUBW */
6534 {0, 1, 1, 0}, /* VADDHN */
6535 {0, 0, 0, 0}, /* VABAL */
6536 {0, 1, 1, 0}, /* VSUBHN */
6537 {0, 0, 0, 0}, /* VABDL */
6538 {0, 0, 0, 0}, /* VMLAL */
6539 {0, 0, 0, 9}, /* VQDMLAL */
6540 {0, 0, 0, 0}, /* VMLSL */
6541 {0, 0, 0, 9}, /* VQDMLSL */
6542 {0, 0, 0, 0}, /* Integer VMULL */
6543 {0, 0, 0, 1}, /* VQDMULL */
6544 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6545 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6548 prewiden = neon_3reg_wide[op][0];
6549 src1_wide = neon_3reg_wide[op][1];
6550 src2_wide = neon_3reg_wide[op][2];
6551 undefreq = neon_3reg_wide[op][3];
6553 if ((undefreq & (1 << size)) ||
6554 ((undefreq & 8) && u)) {
6555 return 1;
6557 if ((src1_wide && (rn & 1)) ||
6558 (src2_wide && (rm & 1)) ||
6559 (!src2_wide && (rd & 1))) {
6560 return 1;
6563 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6564 * outside the loop below as it only performs a single pass.
6566 if (op == 14 && size == 2) {
6567 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6569 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6570 return 1;
6572 tcg_rn = tcg_temp_new_i64();
6573 tcg_rm = tcg_temp_new_i64();
6574 tcg_rd = tcg_temp_new_i64();
6575 neon_load_reg64(tcg_rn, rn);
6576 neon_load_reg64(tcg_rm, rm);
6577 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6578 neon_store_reg64(tcg_rd, rd);
6579 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6580 neon_store_reg64(tcg_rd, rd + 1);
6581 tcg_temp_free_i64(tcg_rn);
6582 tcg_temp_free_i64(tcg_rm);
6583 tcg_temp_free_i64(tcg_rd);
6584 return 0;
6587 /* Avoid overlapping operands. Wide source operands are
6588 always aligned so will never overlap with wide
6589 destinations in problematic ways. */
6590 if (rd == rm && !src2_wide) {
6591 tmp = neon_load_reg(rm, 1);
6592 neon_store_scratch(2, tmp);
6593 } else if (rd == rn && !src1_wide) {
6594 tmp = neon_load_reg(rn, 1);
6595 neon_store_scratch(2, tmp);
6597 TCGV_UNUSED_I32(tmp3);
6598 for (pass = 0; pass < 2; pass++) {
6599 if (src1_wide) {
6600 neon_load_reg64(cpu_V0, rn + pass);
6601 TCGV_UNUSED_I32(tmp);
6602 } else {
6603 if (pass == 1 && rd == rn) {
6604 tmp = neon_load_scratch(2);
6605 } else {
6606 tmp = neon_load_reg(rn, pass);
6608 if (prewiden) {
6609 gen_neon_widen(cpu_V0, tmp, size, u);
6612 if (src2_wide) {
6613 neon_load_reg64(cpu_V1, rm + pass);
6614 TCGV_UNUSED_I32(tmp2);
6615 } else {
6616 if (pass == 1 && rd == rm) {
6617 tmp2 = neon_load_scratch(2);
6618 } else {
6619 tmp2 = neon_load_reg(rm, pass);
6621 if (prewiden) {
6622 gen_neon_widen(cpu_V1, tmp2, size, u);
6625 switch (op) {
6626 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6627 gen_neon_addl(size);
6628 break;
6629 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6630 gen_neon_subl(size);
6631 break;
6632 case 5: case 7: /* VABAL, VABDL */
6633 switch ((size << 1) | u) {
6634 case 0:
6635 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6636 break;
6637 case 1:
6638 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6639 break;
6640 case 2:
6641 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6642 break;
6643 case 3:
6644 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6645 break;
6646 case 4:
6647 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6648 break;
6649 case 5:
6650 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6651 break;
6652 default: abort();
6654 tcg_temp_free_i32(tmp2);
6655 tcg_temp_free_i32(tmp);
6656 break;
6657 case 8: case 9: case 10: case 11: case 12: case 13:
6658 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6659 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6660 break;
6661 case 14: /* Polynomial VMULL */
6662 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6663 tcg_temp_free_i32(tmp2);
6664 tcg_temp_free_i32(tmp);
6665 break;
6666 default: /* 15 is RESERVED: caught earlier */
6667 abort();
6669 if (op == 13) {
6670 /* VQDMULL */
6671 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6672 neon_store_reg64(cpu_V0, rd + pass);
6673 } else if (op == 5 || (op >= 8 && op <= 11)) {
6674 /* Accumulate. */
6675 neon_load_reg64(cpu_V1, rd + pass);
6676 switch (op) {
6677 case 10: /* VMLSL */
6678 gen_neon_negl(cpu_V0, size);
6679 /* Fall through */
6680 case 5: case 8: /* VABAL, VMLAL */
6681 gen_neon_addl(size);
6682 break;
6683 case 9: case 11: /* VQDMLAL, VQDMLSL */
6684 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6685 if (op == 11) {
6686 gen_neon_negl(cpu_V0, size);
6688 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6689 break;
6690 default:
6691 abort();
6693 neon_store_reg64(cpu_V0, rd + pass);
6694 } else if (op == 4 || op == 6) {
6695 /* Narrowing operation. */
6696 tmp = tcg_temp_new_i32();
6697 if (!u) {
6698 switch (size) {
6699 case 0:
6700 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6701 break;
6702 case 1:
6703 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6704 break;
6705 case 2:
6706 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6707 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6708 break;
6709 default: abort();
6711 } else {
6712 switch (size) {
6713 case 0:
6714 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6715 break;
6716 case 1:
6717 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6718 break;
6719 case 2:
6720 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6721 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6722 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6723 break;
6724 default: abort();
6727 if (pass == 0) {
6728 tmp3 = tmp;
6729 } else {
6730 neon_store_reg(rd, 0, tmp3);
6731 neon_store_reg(rd, 1, tmp);
6733 } else {
6734 /* Write back the result. */
6735 neon_store_reg64(cpu_V0, rd + pass);
6738 } else {
6739 /* Two registers and a scalar. NB that for ops of this form
6740 * the ARM ARM labels bit 24 as Q, but it is in our variable
6741 * 'u', not 'q'.
6743 if (size == 0) {
6744 return 1;
6746 switch (op) {
6747 case 1: /* Float VMLA scalar */
6748 case 5: /* Floating point VMLS scalar */
6749 case 9: /* Floating point VMUL scalar */
6750 if (size == 1) {
6751 return 1;
6753 /* fall through */
6754 case 0: /* Integer VMLA scalar */
6755 case 4: /* Integer VMLS scalar */
6756 case 8: /* Integer VMUL scalar */
6757 case 12: /* VQDMULH scalar */
6758 case 13: /* VQRDMULH scalar */
6759 if (u && ((rd | rn) & 1)) {
6760 return 1;
6762 tmp = neon_get_scalar(size, rm);
6763 neon_store_scratch(0, tmp);
6764 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6765 tmp = neon_load_scratch(0);
6766 tmp2 = neon_load_reg(rn, pass);
6767 if (op == 12) {
6768 if (size == 1) {
6769 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6770 } else {
6771 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6773 } else if (op == 13) {
6774 if (size == 1) {
6775 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6776 } else {
6777 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6779 } else if (op & 1) {
6780 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6781 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6782 tcg_temp_free_ptr(fpstatus);
6783 } else {
6784 switch (size) {
6785 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6786 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6787 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6788 default: abort();
6791 tcg_temp_free_i32(tmp2);
6792 if (op < 8) {
6793 /* Accumulate. */
6794 tmp2 = neon_load_reg(rd, pass);
6795 switch (op) {
6796 case 0:
6797 gen_neon_add(size, tmp, tmp2);
6798 break;
6799 case 1:
6801 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6802 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6803 tcg_temp_free_ptr(fpstatus);
6804 break;
6806 case 4:
6807 gen_neon_rsb(size, tmp, tmp2);
6808 break;
6809 case 5:
6811 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6812 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6813 tcg_temp_free_ptr(fpstatus);
6814 break;
6816 default:
6817 abort();
6819 tcg_temp_free_i32(tmp2);
6821 neon_store_reg(rd, pass, tmp);
6823 break;
6824 case 3: /* VQDMLAL scalar */
6825 case 7: /* VQDMLSL scalar */
6826 case 11: /* VQDMULL scalar */
6827 if (u == 1) {
6828 return 1;
6830 /* fall through */
6831 case 2: /* VMLAL sclar */
6832 case 6: /* VMLSL scalar */
6833 case 10: /* VMULL scalar */
6834 if (rd & 1) {
6835 return 1;
6837 tmp2 = neon_get_scalar(size, rm);
6838 /* We need a copy of tmp2 because gen_neon_mull
6839 * deletes it during pass 0. */
6840 tmp4 = tcg_temp_new_i32();
6841 tcg_gen_mov_i32(tmp4, tmp2);
6842 tmp3 = neon_load_reg(rn, 1);
6844 for (pass = 0; pass < 2; pass++) {
6845 if (pass == 0) {
6846 tmp = neon_load_reg(rn, 0);
6847 } else {
6848 tmp = tmp3;
6849 tmp2 = tmp4;
6851 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6852 if (op != 11) {
6853 neon_load_reg64(cpu_V1, rd + pass);
6855 switch (op) {
6856 case 6:
6857 gen_neon_negl(cpu_V0, size);
6858 /* Fall through */
6859 case 2:
6860 gen_neon_addl(size);
6861 break;
6862 case 3: case 7:
6863 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6864 if (op == 7) {
6865 gen_neon_negl(cpu_V0, size);
6867 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6868 break;
6869 case 10:
6870 /* no-op */
6871 break;
6872 case 11:
6873 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6874 break;
6875 default:
6876 abort();
6878 neon_store_reg64(cpu_V0, rd + pass);
6882 break;
6883 default: /* 14 and 15 are RESERVED */
6884 return 1;
6887 } else { /* size == 3 */
6888 if (!u) {
6889 /* Extract. */
6890 imm = (insn >> 8) & 0xf;
6892 if (imm > 7 && !q)
6893 return 1;
6895 if (q && ((rd | rn | rm) & 1)) {
6896 return 1;
6899 if (imm == 0) {
6900 neon_load_reg64(cpu_V0, rn);
6901 if (q) {
6902 neon_load_reg64(cpu_V1, rn + 1);
6904 } else if (imm == 8) {
6905 neon_load_reg64(cpu_V0, rn + 1);
6906 if (q) {
6907 neon_load_reg64(cpu_V1, rm);
6909 } else if (q) {
6910 tmp64 = tcg_temp_new_i64();
6911 if (imm < 8) {
6912 neon_load_reg64(cpu_V0, rn);
6913 neon_load_reg64(tmp64, rn + 1);
6914 } else {
6915 neon_load_reg64(cpu_V0, rn + 1);
6916 neon_load_reg64(tmp64, rm);
6918 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6919 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6920 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6921 if (imm < 8) {
6922 neon_load_reg64(cpu_V1, rm);
6923 } else {
6924 neon_load_reg64(cpu_V1, rm + 1);
6925 imm -= 8;
6927 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6928 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6929 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6930 tcg_temp_free_i64(tmp64);
6931 } else {
6932 /* BUGFIX */
6933 neon_load_reg64(cpu_V0, rn);
6934 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6935 neon_load_reg64(cpu_V1, rm);
6936 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6937 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6939 neon_store_reg64(cpu_V0, rd);
6940 if (q) {
6941 neon_store_reg64(cpu_V1, rd + 1);
6943 } else if ((insn & (1 << 11)) == 0) {
6944 /* Two register misc. */
6945 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6946 size = (insn >> 18) & 3;
6947 /* UNDEF for unknown op values and bad op-size combinations */
6948 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6949 return 1;
6951 if (neon_2rm_is_v8_op(op) &&
6952 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6953 return 1;
6955 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6956 q && ((rm | rd) & 1)) {
6957 return 1;
6959 switch (op) {
6960 case NEON_2RM_VREV64:
6961 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6962 tmp = neon_load_reg(rm, pass * 2);
6963 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6964 switch (size) {
6965 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6966 case 1: gen_swap_half(tmp); break;
6967 case 2: /* no-op */ break;
6968 default: abort();
6970 neon_store_reg(rd, pass * 2 + 1, tmp);
6971 if (size == 2) {
6972 neon_store_reg(rd, pass * 2, tmp2);
6973 } else {
6974 switch (size) {
6975 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6976 case 1: gen_swap_half(tmp2); break;
6977 default: abort();
6979 neon_store_reg(rd, pass * 2, tmp2);
6982 break;
6983 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6984 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6985 for (pass = 0; pass < q + 1; pass++) {
6986 tmp = neon_load_reg(rm, pass * 2);
6987 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6988 tmp = neon_load_reg(rm, pass * 2 + 1);
6989 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6990 switch (size) {
6991 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6992 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6993 case 2: tcg_gen_add_i64(CPU_V001); break;
6994 default: abort();
6996 if (op >= NEON_2RM_VPADAL) {
6997 /* Accumulate. */
6998 neon_load_reg64(cpu_V1, rd + pass);
6999 gen_neon_addl(size);
7001 neon_store_reg64(cpu_V0, rd + pass);
7003 break;
7004 case NEON_2RM_VTRN:
7005 if (size == 2) {
7006 int n;
7007 for (n = 0; n < (q ? 4 : 2); n += 2) {
7008 tmp = neon_load_reg(rm, n);
7009 tmp2 = neon_load_reg(rd, n + 1);
7010 neon_store_reg(rm, n, tmp2);
7011 neon_store_reg(rd, n + 1, tmp);
7013 } else {
7014 goto elementwise;
7016 break;
7017 case NEON_2RM_VUZP:
7018 if (gen_neon_unzip(rd, rm, size, q)) {
7019 return 1;
7021 break;
7022 case NEON_2RM_VZIP:
7023 if (gen_neon_zip(rd, rm, size, q)) {
7024 return 1;
7026 break;
7027 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7028 /* also VQMOVUN; op field and mnemonics don't line up */
7029 if (rm & 1) {
7030 return 1;
7032 TCGV_UNUSED_I32(tmp2);
7033 for (pass = 0; pass < 2; pass++) {
7034 neon_load_reg64(cpu_V0, rm + pass);
7035 tmp = tcg_temp_new_i32();
7036 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7037 tmp, cpu_V0);
7038 if (pass == 0) {
7039 tmp2 = tmp;
7040 } else {
7041 neon_store_reg(rd, 0, tmp2);
7042 neon_store_reg(rd, 1, tmp);
7045 break;
7046 case NEON_2RM_VSHLL:
7047 if (q || (rd & 1)) {
7048 return 1;
7050 tmp = neon_load_reg(rm, 0);
7051 tmp2 = neon_load_reg(rm, 1);
7052 for (pass = 0; pass < 2; pass++) {
7053 if (pass == 1)
7054 tmp = tmp2;
7055 gen_neon_widen(cpu_V0, tmp, size, 1);
7056 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7057 neon_store_reg64(cpu_V0, rd + pass);
7059 break;
7060 case NEON_2RM_VCVT_F16_F32:
7061 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7062 q || (rm & 1)) {
7063 return 1;
7065 tmp = tcg_temp_new_i32();
7066 tmp2 = tcg_temp_new_i32();
7067 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7068 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7069 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7070 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7071 tcg_gen_shli_i32(tmp2, tmp2, 16);
7072 tcg_gen_or_i32(tmp2, tmp2, tmp);
7073 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7074 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7075 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7076 neon_store_reg(rd, 0, tmp2);
7077 tmp2 = tcg_temp_new_i32();
7078 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7079 tcg_gen_shli_i32(tmp2, tmp2, 16);
7080 tcg_gen_or_i32(tmp2, tmp2, tmp);
7081 neon_store_reg(rd, 1, tmp2);
7082 tcg_temp_free_i32(tmp);
7083 break;
7084 case NEON_2RM_VCVT_F32_F16:
7085 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7086 q || (rd & 1)) {
7087 return 1;
7089 tmp3 = tcg_temp_new_i32();
7090 tmp = neon_load_reg(rm, 0);
7091 tmp2 = neon_load_reg(rm, 1);
7092 tcg_gen_ext16u_i32(tmp3, tmp);
7093 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7094 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7095 tcg_gen_shri_i32(tmp3, tmp, 16);
7096 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7097 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7098 tcg_temp_free_i32(tmp);
7099 tcg_gen_ext16u_i32(tmp3, tmp2);
7100 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7101 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7102 tcg_gen_shri_i32(tmp3, tmp2, 16);
7103 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7104 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7105 tcg_temp_free_i32(tmp2);
7106 tcg_temp_free_i32(tmp3);
7107 break;
7108 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7109 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7110 || ((rm | rd) & 1)) {
7111 return 1;
7113 tmp = tcg_const_i32(rd);
7114 tmp2 = tcg_const_i32(rm);
7116 /* Bit 6 is the lowest opcode bit; it distinguishes between
7117 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7119 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7121 if (op == NEON_2RM_AESE) {
7122 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
7123 } else {
7124 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
7126 tcg_temp_free_i32(tmp);
7127 tcg_temp_free_i32(tmp2);
7128 tcg_temp_free_i32(tmp3);
7129 break;
7130 case NEON_2RM_SHA1H:
7131 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7132 || ((rm | rd) & 1)) {
7133 return 1;
7135 tmp = tcg_const_i32(rd);
7136 tmp2 = tcg_const_i32(rm);
7138 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
7140 tcg_temp_free_i32(tmp);
7141 tcg_temp_free_i32(tmp2);
7142 break;
7143 case NEON_2RM_SHA1SU1:
7144 if ((rm | rd) & 1) {
7145 return 1;
7147 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7148 if (q) {
7149 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7150 return 1;
7152 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7153 return 1;
7155 tmp = tcg_const_i32(rd);
7156 tmp2 = tcg_const_i32(rm);
7157 if (q) {
7158 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7159 } else {
7160 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7162 tcg_temp_free_i32(tmp);
7163 tcg_temp_free_i32(tmp2);
7164 break;
7165 default:
7166 elementwise:
7167 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7168 if (neon_2rm_is_float_op(op)) {
7169 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7170 neon_reg_offset(rm, pass));
7171 TCGV_UNUSED_I32(tmp);
7172 } else {
7173 tmp = neon_load_reg(rm, pass);
7175 switch (op) {
7176 case NEON_2RM_VREV32:
7177 switch (size) {
7178 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7179 case 1: gen_swap_half(tmp); break;
7180 default: abort();
7182 break;
7183 case NEON_2RM_VREV16:
7184 gen_rev16(tmp);
7185 break;
7186 case NEON_2RM_VCLS:
7187 switch (size) {
7188 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7189 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7190 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7191 default: abort();
7193 break;
7194 case NEON_2RM_VCLZ:
7195 switch (size) {
7196 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7197 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7198 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7199 default: abort();
7201 break;
7202 case NEON_2RM_VCNT:
7203 gen_helper_neon_cnt_u8(tmp, tmp);
7204 break;
7205 case NEON_2RM_VMVN:
7206 tcg_gen_not_i32(tmp, tmp);
7207 break;
7208 case NEON_2RM_VQABS:
7209 switch (size) {
7210 case 0:
7211 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7212 break;
7213 case 1:
7214 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7215 break;
7216 case 2:
7217 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7218 break;
7219 default: abort();
7221 break;
7222 case NEON_2RM_VQNEG:
7223 switch (size) {
7224 case 0:
7225 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7226 break;
7227 case 1:
7228 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7229 break;
7230 case 2:
7231 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7232 break;
7233 default: abort();
7235 break;
7236 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7237 tmp2 = tcg_const_i32(0);
7238 switch(size) {
7239 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7240 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7241 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7242 default: abort();
7244 tcg_temp_free_i32(tmp2);
7245 if (op == NEON_2RM_VCLE0) {
7246 tcg_gen_not_i32(tmp, tmp);
7248 break;
7249 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7250 tmp2 = tcg_const_i32(0);
7251 switch(size) {
7252 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7253 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7254 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7255 default: abort();
7257 tcg_temp_free_i32(tmp2);
7258 if (op == NEON_2RM_VCLT0) {
7259 tcg_gen_not_i32(tmp, tmp);
7261 break;
7262 case NEON_2RM_VCEQ0:
7263 tmp2 = tcg_const_i32(0);
7264 switch(size) {
7265 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7266 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7267 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7268 default: abort();
7270 tcg_temp_free_i32(tmp2);
7271 break;
7272 case NEON_2RM_VABS:
7273 switch(size) {
7274 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7275 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7276 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7277 default: abort();
7279 break;
7280 case NEON_2RM_VNEG:
7281 tmp2 = tcg_const_i32(0);
7282 gen_neon_rsb(size, tmp, tmp2);
7283 tcg_temp_free_i32(tmp2);
7284 break;
7285 case NEON_2RM_VCGT0_F:
7287 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7288 tmp2 = tcg_const_i32(0);
7289 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7290 tcg_temp_free_i32(tmp2);
7291 tcg_temp_free_ptr(fpstatus);
7292 break;
7294 case NEON_2RM_VCGE0_F:
7296 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7297 tmp2 = tcg_const_i32(0);
7298 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7299 tcg_temp_free_i32(tmp2);
7300 tcg_temp_free_ptr(fpstatus);
7301 break;
7303 case NEON_2RM_VCEQ0_F:
7305 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7306 tmp2 = tcg_const_i32(0);
7307 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7308 tcg_temp_free_i32(tmp2);
7309 tcg_temp_free_ptr(fpstatus);
7310 break;
7312 case NEON_2RM_VCLE0_F:
7314 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7315 tmp2 = tcg_const_i32(0);
7316 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7317 tcg_temp_free_i32(tmp2);
7318 tcg_temp_free_ptr(fpstatus);
7319 break;
7321 case NEON_2RM_VCLT0_F:
7323 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7324 tmp2 = tcg_const_i32(0);
7325 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7326 tcg_temp_free_i32(tmp2);
7327 tcg_temp_free_ptr(fpstatus);
7328 break;
7330 case NEON_2RM_VABS_F:
7331 gen_vfp_abs(0);
7332 break;
7333 case NEON_2RM_VNEG_F:
7334 gen_vfp_neg(0);
7335 break;
7336 case NEON_2RM_VSWP:
7337 tmp2 = neon_load_reg(rd, pass);
7338 neon_store_reg(rm, pass, tmp2);
7339 break;
7340 case NEON_2RM_VTRN:
7341 tmp2 = neon_load_reg(rd, pass);
7342 switch (size) {
7343 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7344 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7345 default: abort();
7347 neon_store_reg(rm, pass, tmp2);
7348 break;
7349 case NEON_2RM_VRINTN:
7350 case NEON_2RM_VRINTA:
7351 case NEON_2RM_VRINTM:
7352 case NEON_2RM_VRINTP:
7353 case NEON_2RM_VRINTZ:
7355 TCGv_i32 tcg_rmode;
7356 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7357 int rmode;
7359 if (op == NEON_2RM_VRINTZ) {
7360 rmode = FPROUNDING_ZERO;
7361 } else {
7362 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7365 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7366 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7367 cpu_env);
7368 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7369 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7370 cpu_env);
7371 tcg_temp_free_ptr(fpstatus);
7372 tcg_temp_free_i32(tcg_rmode);
7373 break;
7375 case NEON_2RM_VRINTX:
7377 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7378 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7379 tcg_temp_free_ptr(fpstatus);
7380 break;
7382 case NEON_2RM_VCVTAU:
7383 case NEON_2RM_VCVTAS:
7384 case NEON_2RM_VCVTNU:
7385 case NEON_2RM_VCVTNS:
7386 case NEON_2RM_VCVTPU:
7387 case NEON_2RM_VCVTPS:
7388 case NEON_2RM_VCVTMU:
7389 case NEON_2RM_VCVTMS:
7391 bool is_signed = !extract32(insn, 7, 1);
7392 TCGv_ptr fpst = get_fpstatus_ptr(1);
7393 TCGv_i32 tcg_rmode, tcg_shift;
7394 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7396 tcg_shift = tcg_const_i32(0);
7397 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7398 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7399 cpu_env);
7401 if (is_signed) {
7402 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7403 tcg_shift, fpst);
7404 } else {
7405 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7406 tcg_shift, fpst);
7409 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7410 cpu_env);
7411 tcg_temp_free_i32(tcg_rmode);
7412 tcg_temp_free_i32(tcg_shift);
7413 tcg_temp_free_ptr(fpst);
7414 break;
7416 case NEON_2RM_VRECPE:
7418 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7419 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7420 tcg_temp_free_ptr(fpstatus);
7421 break;
7423 case NEON_2RM_VRSQRTE:
7425 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7426 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7427 tcg_temp_free_ptr(fpstatus);
7428 break;
7430 case NEON_2RM_VRECPE_F:
7432 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7433 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7434 tcg_temp_free_ptr(fpstatus);
7435 break;
7437 case NEON_2RM_VRSQRTE_F:
7439 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7440 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7441 tcg_temp_free_ptr(fpstatus);
7442 break;
7444 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7445 gen_vfp_sito(0, 1);
7446 break;
7447 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7448 gen_vfp_uito(0, 1);
7449 break;
7450 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7451 gen_vfp_tosiz(0, 1);
7452 break;
7453 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7454 gen_vfp_touiz(0, 1);
7455 break;
7456 default:
7457 /* Reserved op values were caught by the
7458 * neon_2rm_sizes[] check earlier.
7460 abort();
7462 if (neon_2rm_is_float_op(op)) {
7463 tcg_gen_st_f32(cpu_F0s, cpu_env,
7464 neon_reg_offset(rd, pass));
7465 } else {
7466 neon_store_reg(rd, pass, tmp);
7469 break;
7471 } else if ((insn & (1 << 10)) == 0) {
7472 /* VTBL, VTBX. */
7473 int n = ((insn >> 8) & 3) + 1;
7474 if ((rn + n) > 32) {
7475 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7476 * helper function running off the end of the register file.
7478 return 1;
7480 n <<= 3;
7481 if (insn & (1 << 6)) {
7482 tmp = neon_load_reg(rd, 0);
7483 } else {
7484 tmp = tcg_temp_new_i32();
7485 tcg_gen_movi_i32(tmp, 0);
7487 tmp2 = neon_load_reg(rm, 0);
7488 tmp4 = tcg_const_i32(rn);
7489 tmp5 = tcg_const_i32(n);
7490 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7491 tcg_temp_free_i32(tmp);
7492 if (insn & (1 << 6)) {
7493 tmp = neon_load_reg(rd, 1);
7494 } else {
7495 tmp = tcg_temp_new_i32();
7496 tcg_gen_movi_i32(tmp, 0);
7498 tmp3 = neon_load_reg(rm, 1);
7499 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7500 tcg_temp_free_i32(tmp5);
7501 tcg_temp_free_i32(tmp4);
7502 neon_store_reg(rd, 0, tmp2);
7503 neon_store_reg(rd, 1, tmp3);
7504 tcg_temp_free_i32(tmp);
7505 } else if ((insn & 0x380) == 0) {
7506 /* VDUP */
7507 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7508 return 1;
7510 if (insn & (1 << 19)) {
7511 tmp = neon_load_reg(rm, 1);
7512 } else {
7513 tmp = neon_load_reg(rm, 0);
7515 if (insn & (1 << 16)) {
7516 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7517 } else if (insn & (1 << 17)) {
7518 if ((insn >> 18) & 1)
7519 gen_neon_dup_high16(tmp);
7520 else
7521 gen_neon_dup_low16(tmp);
7523 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7524 tmp2 = tcg_temp_new_i32();
7525 tcg_gen_mov_i32(tmp2, tmp);
7526 neon_store_reg(rd, pass, tmp2);
7528 tcg_temp_free_i32(tmp);
7529 } else {
7530 return 1;
7534 return 0;
7537 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7539 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7540 const ARMCPRegInfo *ri;
7542 cpnum = (insn >> 8) & 0xf;
7544 /* First check for coprocessor space used for XScale/iwMMXt insns */
7545 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7546 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7547 return 1;
7549 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7550 return disas_iwmmxt_insn(s, insn);
7551 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7552 return disas_dsp_insn(s, insn);
7554 return 1;
7557 /* Otherwise treat as a generic register access */
7558 is64 = (insn & (1 << 25)) == 0;
7559 if (!is64 && ((insn & (1 << 4)) == 0)) {
7560 /* cdp */
7561 return 1;
7564 crm = insn & 0xf;
7565 if (is64) {
7566 crn = 0;
7567 opc1 = (insn >> 4) & 0xf;
7568 opc2 = 0;
7569 rt2 = (insn >> 16) & 0xf;
7570 } else {
7571 crn = (insn >> 16) & 0xf;
7572 opc1 = (insn >> 21) & 7;
7573 opc2 = (insn >> 5) & 7;
7574 rt2 = 0;
7576 isread = (insn >> 20) & 1;
7577 rt = (insn >> 12) & 0xf;
7579 ri = get_arm_cp_reginfo(s->cp_regs,
7580 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7581 if (ri) {
7582 /* Check access permissions */
7583 if (!cp_access_ok(s->current_el, ri, isread)) {
7584 return 1;
7587 if (ri->accessfn ||
7588 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7589 /* Emit code to perform further access permissions checks at
7590 * runtime; this may result in an exception.
7591 * Note that on XScale all cp0..c13 registers do an access check
7592 * call in order to handle c15_cpar.
7594 TCGv_ptr tmpptr;
7595 TCGv_i32 tcg_syn, tcg_isread;
7596 uint32_t syndrome;
7598 /* Note that since we are an implementation which takes an
7599 * exception on a trapped conditional instruction only if the
7600 * instruction passes its condition code check, we can take
7601 * advantage of the clause in the ARM ARM that allows us to set
7602 * the COND field in the instruction to 0xE in all cases.
7603 * We could fish the actual condition out of the insn (ARM)
7604 * or the condexec bits (Thumb) but it isn't necessary.
7606 switch (cpnum) {
7607 case 14:
7608 if (is64) {
7609 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7610 isread, false);
7611 } else {
7612 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7613 rt, isread, false);
7615 break;
7616 case 15:
7617 if (is64) {
7618 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7619 isread, false);
7620 } else {
7621 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7622 rt, isread, false);
7624 break;
7625 default:
7626 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7627 * so this can only happen if this is an ARMv7 or earlier CPU,
7628 * in which case the syndrome information won't actually be
7629 * guest visible.
7631 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7632 syndrome = syn_uncategorized();
7633 break;
7636 gen_set_condexec(s);
7637 gen_set_pc_im(s, s->pc - 4);
7638 tmpptr = tcg_const_ptr(ri);
7639 tcg_syn = tcg_const_i32(syndrome);
7640 tcg_isread = tcg_const_i32(isread);
7641 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7642 tcg_isread);
7643 tcg_temp_free_ptr(tmpptr);
7644 tcg_temp_free_i32(tcg_syn);
7645 tcg_temp_free_i32(tcg_isread);
7648 /* Handle special cases first */
7649 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7650 case ARM_CP_NOP:
7651 return 0;
7652 case ARM_CP_WFI:
7653 if (isread) {
7654 return 1;
7656 gen_set_pc_im(s, s->pc);
7657 s->is_jmp = DISAS_WFI;
7658 return 0;
7659 default:
7660 break;
7663 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7664 gen_io_start();
7667 if (isread) {
7668 /* Read */
7669 if (is64) {
7670 TCGv_i64 tmp64;
7671 TCGv_i32 tmp;
7672 if (ri->type & ARM_CP_CONST) {
7673 tmp64 = tcg_const_i64(ri->resetvalue);
7674 } else if (ri->readfn) {
7675 TCGv_ptr tmpptr;
7676 tmp64 = tcg_temp_new_i64();
7677 tmpptr = tcg_const_ptr(ri);
7678 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7679 tcg_temp_free_ptr(tmpptr);
7680 } else {
7681 tmp64 = tcg_temp_new_i64();
7682 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7684 tmp = tcg_temp_new_i32();
7685 tcg_gen_extrl_i64_i32(tmp, tmp64);
7686 store_reg(s, rt, tmp);
7687 tcg_gen_shri_i64(tmp64, tmp64, 32);
7688 tmp = tcg_temp_new_i32();
7689 tcg_gen_extrl_i64_i32(tmp, tmp64);
7690 tcg_temp_free_i64(tmp64);
7691 store_reg(s, rt2, tmp);
7692 } else {
7693 TCGv_i32 tmp;
7694 if (ri->type & ARM_CP_CONST) {
7695 tmp = tcg_const_i32(ri->resetvalue);
7696 } else if (ri->readfn) {
7697 TCGv_ptr tmpptr;
7698 tmp = tcg_temp_new_i32();
7699 tmpptr = tcg_const_ptr(ri);
7700 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7701 tcg_temp_free_ptr(tmpptr);
7702 } else {
7703 tmp = load_cpu_offset(ri->fieldoffset);
7705 if (rt == 15) {
7706 /* Destination register of r15 for 32 bit loads sets
7707 * the condition codes from the high 4 bits of the value
7709 gen_set_nzcv(tmp);
7710 tcg_temp_free_i32(tmp);
7711 } else {
7712 store_reg(s, rt, tmp);
7715 } else {
7716 /* Write */
7717 if (ri->type & ARM_CP_CONST) {
7718 /* If not forbidden by access permissions, treat as WI */
7719 return 0;
7722 if (is64) {
7723 TCGv_i32 tmplo, tmphi;
7724 TCGv_i64 tmp64 = tcg_temp_new_i64();
7725 tmplo = load_reg(s, rt);
7726 tmphi = load_reg(s, rt2);
7727 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7728 tcg_temp_free_i32(tmplo);
7729 tcg_temp_free_i32(tmphi);
7730 if (ri->writefn) {
7731 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7732 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7733 tcg_temp_free_ptr(tmpptr);
7734 } else {
7735 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7737 tcg_temp_free_i64(tmp64);
7738 } else {
7739 if (ri->writefn) {
7740 TCGv_i32 tmp;
7741 TCGv_ptr tmpptr;
7742 tmp = load_reg(s, rt);
7743 tmpptr = tcg_const_ptr(ri);
7744 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7745 tcg_temp_free_ptr(tmpptr);
7746 tcg_temp_free_i32(tmp);
7747 } else {
7748 TCGv_i32 tmp = load_reg(s, rt);
7749 store_cpu_offset(tmp, ri->fieldoffset);
7754 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7755 /* I/O operations must end the TB here (whether read or write) */
7756 gen_io_end();
7757 gen_lookup_tb(s);
7758 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7759 /* We default to ending the TB on a coprocessor register write,
7760 * but allow this to be suppressed by the register definition
7761 * (usually only necessary to work around guest bugs).
7763 gen_lookup_tb(s);
7766 return 0;
7769 /* Unknown register; this might be a guest error or a QEMU
7770 * unimplemented feature.
7772 if (is64) {
7773 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7774 "64 bit system register cp:%d opc1: %d crm:%d "
7775 "(%s)\n",
7776 isread ? "read" : "write", cpnum, opc1, crm,
7777 s->ns ? "non-secure" : "secure");
7778 } else {
7779 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7780 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7781 "(%s)\n",
7782 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7783 s->ns ? "non-secure" : "secure");
7786 return 1;
7790 /* Store a 64-bit value to a register pair. Clobbers val. */
7791 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7793 TCGv_i32 tmp;
7794 tmp = tcg_temp_new_i32();
7795 tcg_gen_extrl_i64_i32(tmp, val);
7796 store_reg(s, rlow, tmp);
7797 tmp = tcg_temp_new_i32();
7798 tcg_gen_shri_i64(val, val, 32);
7799 tcg_gen_extrl_i64_i32(tmp, val);
7800 store_reg(s, rhigh, tmp);
7803 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7804 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7806 TCGv_i64 tmp;
7807 TCGv_i32 tmp2;
7809 /* Load value and extend to 64 bits. */
7810 tmp = tcg_temp_new_i64();
7811 tmp2 = load_reg(s, rlow);
7812 tcg_gen_extu_i32_i64(tmp, tmp2);
7813 tcg_temp_free_i32(tmp2);
7814 tcg_gen_add_i64(val, val, tmp);
7815 tcg_temp_free_i64(tmp);
7818 /* load and add a 64-bit value from a register pair. */
7819 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7821 TCGv_i64 tmp;
7822 TCGv_i32 tmpl;
7823 TCGv_i32 tmph;
7825 /* Load 64-bit value rd:rn. */
7826 tmpl = load_reg(s, rlow);
7827 tmph = load_reg(s, rhigh);
7828 tmp = tcg_temp_new_i64();
7829 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7830 tcg_temp_free_i32(tmpl);
7831 tcg_temp_free_i32(tmph);
7832 tcg_gen_add_i64(val, val, tmp);
7833 tcg_temp_free_i64(tmp);
7836 /* Set N and Z flags from hi|lo. */
7837 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7839 tcg_gen_mov_i32(cpu_NF, hi);
7840 tcg_gen_or_i32(cpu_ZF, lo, hi);
7843 /* Load/Store exclusive instructions are implemented by remembering
7844 the value/address loaded, and seeing if these are the same
7845 when the store is performed. This should be sufficient to implement
7846 the architecturally mandated semantics, and avoids having to monitor
7847 regular stores. The compare vs the remembered value is done during
7848 the cmpxchg operation, but we must compare the addresses manually. */
7849 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7850 TCGv_i32 addr, int size)
7852 TCGv_i32 tmp = tcg_temp_new_i32();
7853 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7855 s->is_ldex = true;
7857 if (size == 3) {
7858 TCGv_i32 tmp2 = tcg_temp_new_i32();
7859 TCGv_i64 t64 = tcg_temp_new_i64();
7861 gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
7862 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7863 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7864 tcg_temp_free_i64(t64);
7866 store_reg(s, rt2, tmp2);
7867 } else {
7868 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7869 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7872 store_reg(s, rt, tmp);
7873 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7876 static void gen_clrex(DisasContext *s)
7878 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7881 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7882 TCGv_i32 addr, int size)
7884 TCGv_i32 t0, t1, t2;
7885 TCGv_i64 extaddr;
7886 TCGv taddr;
7887 TCGLabel *done_label;
7888 TCGLabel *fail_label;
7889 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7891 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7892 [addr] = {Rt};
7893 {Rd} = 0;
7894 } else {
7895 {Rd} = 1;
7896 } */
7897 fail_label = gen_new_label();
7898 done_label = gen_new_label();
7899 extaddr = tcg_temp_new_i64();
7900 tcg_gen_extu_i32_i64(extaddr, addr);
7901 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7902 tcg_temp_free_i64(extaddr);
7904 taddr = gen_aa32_addr(s, addr, opc);
7905 t0 = tcg_temp_new_i32();
7906 t1 = load_reg(s, rt);
7907 if (size == 3) {
7908 TCGv_i64 o64 = tcg_temp_new_i64();
7909 TCGv_i64 n64 = tcg_temp_new_i64();
7911 t2 = load_reg(s, rt2);
7912 tcg_gen_concat_i32_i64(n64, t1, t2);
7913 tcg_temp_free_i32(t2);
7914 gen_aa32_frob64(s, n64);
7916 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7917 get_mem_index(s), opc);
7918 tcg_temp_free_i64(n64);
7920 gen_aa32_frob64(s, o64);
7921 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7922 tcg_gen_extrl_i64_i32(t0, o64);
7924 tcg_temp_free_i64(o64);
7925 } else {
7926 t2 = tcg_temp_new_i32();
7927 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7928 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7929 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7930 tcg_temp_free_i32(t2);
7932 tcg_temp_free_i32(t1);
7933 tcg_temp_free(taddr);
7934 tcg_gen_mov_i32(cpu_R[rd], t0);
7935 tcg_temp_free_i32(t0);
7936 tcg_gen_br(done_label);
7938 gen_set_label(fail_label);
7939 tcg_gen_movi_i32(cpu_R[rd], 1);
7940 gen_set_label(done_label);
7941 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7944 /* gen_srs:
7945 * @env: CPUARMState
7946 * @s: DisasContext
7947 * @mode: mode field from insn (which stack to store to)
7948 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7949 * @writeback: true if writeback bit set
7951 * Generate code for the SRS (Store Return State) insn.
7953 static void gen_srs(DisasContext *s,
7954 uint32_t mode, uint32_t amode, bool writeback)
7956 int32_t offset;
7957 TCGv_i32 addr, tmp;
7958 bool undef = false;
7960 /* SRS is:
7961 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7962 * and specified mode is monitor mode
7963 * - UNDEFINED in Hyp mode
7964 * - UNPREDICTABLE in User or System mode
7965 * - UNPREDICTABLE if the specified mode is:
7966 * -- not implemented
7967 * -- not a valid mode number
7968 * -- a mode that's at a higher exception level
7969 * -- Monitor, if we are Non-secure
7970 * For the UNPREDICTABLE cases we choose to UNDEF.
7972 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7973 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7974 return;
7977 if (s->current_el == 0 || s->current_el == 2) {
7978 undef = true;
7981 switch (mode) {
7982 case ARM_CPU_MODE_USR:
7983 case ARM_CPU_MODE_FIQ:
7984 case ARM_CPU_MODE_IRQ:
7985 case ARM_CPU_MODE_SVC:
7986 case ARM_CPU_MODE_ABT:
7987 case ARM_CPU_MODE_UND:
7988 case ARM_CPU_MODE_SYS:
7989 break;
7990 case ARM_CPU_MODE_HYP:
7991 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7992 undef = true;
7994 break;
7995 case ARM_CPU_MODE_MON:
7996 /* No need to check specifically for "are we non-secure" because
7997 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7998 * so if this isn't EL3 then we must be non-secure.
8000 if (s->current_el != 3) {
8001 undef = true;
8003 break;
8004 default:
8005 undef = true;
8008 if (undef) {
8009 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8010 default_exception_el(s));
8011 return;
8014 addr = tcg_temp_new_i32();
8015 tmp = tcg_const_i32(mode);
8016 /* get_r13_banked() will raise an exception if called from System mode */
8017 gen_set_condexec(s);
8018 gen_set_pc_im(s, s->pc - 4);
8019 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8020 tcg_temp_free_i32(tmp);
8021 switch (amode) {
8022 case 0: /* DA */
8023 offset = -4;
8024 break;
8025 case 1: /* IA */
8026 offset = 0;
8027 break;
8028 case 2: /* DB */
8029 offset = -8;
8030 break;
8031 case 3: /* IB */
8032 offset = 4;
8033 break;
8034 default:
8035 abort();
8037 tcg_gen_addi_i32(addr, addr, offset);
8038 tmp = load_reg(s, 14);
8039 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8040 tcg_temp_free_i32(tmp);
8041 tmp = load_cpu_field(spsr);
8042 tcg_gen_addi_i32(addr, addr, 4);
8043 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8044 tcg_temp_free_i32(tmp);
8045 if (writeback) {
8046 switch (amode) {
8047 case 0:
8048 offset = -8;
8049 break;
8050 case 1:
8051 offset = 4;
8052 break;
8053 case 2:
8054 offset = -4;
8055 break;
8056 case 3:
8057 offset = 0;
8058 break;
8059 default:
8060 abort();
8062 tcg_gen_addi_i32(addr, addr, offset);
8063 tmp = tcg_const_i32(mode);
8064 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8065 tcg_temp_free_i32(tmp);
8067 tcg_temp_free_i32(addr);
8068 s->is_jmp = DISAS_UPDATE;
8071 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8073 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8074 TCGv_i32 tmp;
8075 TCGv_i32 tmp2;
8076 TCGv_i32 tmp3;
8077 TCGv_i32 addr;
8078 TCGv_i64 tmp64;
8080 /* M variants do not implement ARM mode; this must raise the INVSTATE
8081 * UsageFault exception.
8083 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8084 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8085 default_exception_el(s));
8086 return;
8088 cond = insn >> 28;
8089 if (cond == 0xf){
8090 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8091 * choose to UNDEF. In ARMv5 and above the space is used
8092 * for miscellaneous unconditional instructions.
8094 ARCH(5);
8096 /* Unconditional instructions. */
8097 if (((insn >> 25) & 7) == 1) {
8098 /* NEON Data processing. */
8099 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8100 goto illegal_op;
8103 if (disas_neon_data_insn(s, insn)) {
8104 goto illegal_op;
8106 return;
8108 if ((insn & 0x0f100000) == 0x04000000) {
8109 /* NEON load/store. */
8110 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8111 goto illegal_op;
8114 if (disas_neon_ls_insn(s, insn)) {
8115 goto illegal_op;
8117 return;
8119 if ((insn & 0x0f000e10) == 0x0e000a00) {
8120 /* VFP. */
8121 if (disas_vfp_insn(s, insn)) {
8122 goto illegal_op;
8124 return;
8126 if (((insn & 0x0f30f000) == 0x0510f000) ||
8127 ((insn & 0x0f30f010) == 0x0710f000)) {
8128 if ((insn & (1 << 22)) == 0) {
8129 /* PLDW; v7MP */
8130 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8131 goto illegal_op;
8134 /* Otherwise PLD; v5TE+ */
8135 ARCH(5TE);
8136 return;
8138 if (((insn & 0x0f70f000) == 0x0450f000) ||
8139 ((insn & 0x0f70f010) == 0x0650f000)) {
8140 ARCH(7);
8141 return; /* PLI; V7 */
8143 if (((insn & 0x0f700000) == 0x04100000) ||
8144 ((insn & 0x0f700010) == 0x06100000)) {
8145 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8146 goto illegal_op;
8148 return; /* v7MP: Unallocated memory hint: must NOP */
8151 if ((insn & 0x0ffffdff) == 0x01010000) {
8152 ARCH(6);
8153 /* setend */
8154 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8155 gen_helper_setend(cpu_env);
8156 s->is_jmp = DISAS_UPDATE;
8158 return;
8159 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8160 switch ((insn >> 4) & 0xf) {
8161 case 1: /* clrex */
8162 ARCH(6K);
8163 gen_clrex(s);
8164 return;
8165 case 4: /* dsb */
8166 case 5: /* dmb */
8167 ARCH(7);
8168 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8169 return;
8170 case 6: /* isb */
8171 /* We need to break the TB after this insn to execute
8172 * self-modifying code correctly and also to take
8173 * any pending interrupts immediately.
8175 gen_goto_tb(s, 0, s->pc & ~1);
8176 return;
8177 default:
8178 goto illegal_op;
8180 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8181 /* srs */
8182 ARCH(6);
8183 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8184 return;
8185 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8186 /* rfe */
8187 int32_t offset;
8188 if (IS_USER(s))
8189 goto illegal_op;
8190 ARCH(6);
8191 rn = (insn >> 16) & 0xf;
8192 addr = load_reg(s, rn);
8193 i = (insn >> 23) & 3;
8194 switch (i) {
8195 case 0: offset = -4; break; /* DA */
8196 case 1: offset = 0; break; /* IA */
8197 case 2: offset = -8; break; /* DB */
8198 case 3: offset = 4; break; /* IB */
8199 default: abort();
8201 if (offset)
8202 tcg_gen_addi_i32(addr, addr, offset);
8203 /* Load PC into tmp and CPSR into tmp2. */
8204 tmp = tcg_temp_new_i32();
8205 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8206 tcg_gen_addi_i32(addr, addr, 4);
8207 tmp2 = tcg_temp_new_i32();
8208 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8209 if (insn & (1 << 21)) {
8210 /* Base writeback. */
8211 switch (i) {
8212 case 0: offset = -8; break;
8213 case 1: offset = 4; break;
8214 case 2: offset = -4; break;
8215 case 3: offset = 0; break;
8216 default: abort();
8218 if (offset)
8219 tcg_gen_addi_i32(addr, addr, offset);
8220 store_reg(s, rn, addr);
8221 } else {
8222 tcg_temp_free_i32(addr);
8224 gen_rfe(s, tmp, tmp2);
8225 return;
8226 } else if ((insn & 0x0e000000) == 0x0a000000) {
8227 /* branch link and change to thumb (blx <offset>) */
8228 int32_t offset;
8230 val = (uint32_t)s->pc;
8231 tmp = tcg_temp_new_i32();
8232 tcg_gen_movi_i32(tmp, val);
8233 store_reg(s, 14, tmp);
8234 /* Sign-extend the 24-bit offset */
8235 offset = (((int32_t)insn) << 8) >> 8;
8236 /* offset * 4 + bit24 * 2 + (thumb bit) */
8237 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8238 /* pipeline offset */
8239 val += 4;
8240 /* protected by ARCH(5); above, near the start of uncond block */
8241 gen_bx_im(s, val);
8242 return;
8243 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8244 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8245 /* iWMMXt register transfer. */
8246 if (extract32(s->c15_cpar, 1, 1)) {
8247 if (!disas_iwmmxt_insn(s, insn)) {
8248 return;
8252 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8253 /* Coprocessor double register transfer. */
8254 ARCH(5TE);
8255 } else if ((insn & 0x0f000010) == 0x0e000010) {
8256 /* Additional coprocessor register transfer. */
8257 } else if ((insn & 0x0ff10020) == 0x01000000) {
8258 uint32_t mask;
8259 uint32_t val;
8260 /* cps (privileged) */
8261 if (IS_USER(s))
8262 return;
8263 mask = val = 0;
8264 if (insn & (1 << 19)) {
8265 if (insn & (1 << 8))
8266 mask |= CPSR_A;
8267 if (insn & (1 << 7))
8268 mask |= CPSR_I;
8269 if (insn & (1 << 6))
8270 mask |= CPSR_F;
8271 if (insn & (1 << 18))
8272 val |= mask;
8274 if (insn & (1 << 17)) {
8275 mask |= CPSR_M;
8276 val |= (insn & 0x1f);
8278 if (mask) {
8279 gen_set_psr_im(s, mask, 0, val);
8281 return;
8283 goto illegal_op;
8285 if (cond != 0xe) {
8286 /* if not always execute, we generate a conditional jump to
8287 next instruction */
8288 s->condlabel = gen_new_label();
8289 arm_gen_test_cc(cond ^ 1, s->condlabel);
8290 s->condjmp = 1;
8292 if ((insn & 0x0f900000) == 0x03000000) {
8293 if ((insn & (1 << 21)) == 0) {
8294 ARCH(6T2);
8295 rd = (insn >> 12) & 0xf;
8296 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8297 if ((insn & (1 << 22)) == 0) {
8298 /* MOVW */
8299 tmp = tcg_temp_new_i32();
8300 tcg_gen_movi_i32(tmp, val);
8301 } else {
8302 /* MOVT */
8303 tmp = load_reg(s, rd);
8304 tcg_gen_ext16u_i32(tmp, tmp);
8305 tcg_gen_ori_i32(tmp, tmp, val << 16);
8307 store_reg(s, rd, tmp);
8308 } else {
8309 if (((insn >> 12) & 0xf) != 0xf)
8310 goto illegal_op;
8311 if (((insn >> 16) & 0xf) == 0) {
8312 gen_nop_hint(s, insn & 0xff);
8313 } else {
8314 /* CPSR = immediate */
8315 val = insn & 0xff;
8316 shift = ((insn >> 8) & 0xf) * 2;
8317 if (shift)
8318 val = (val >> shift) | (val << (32 - shift));
8319 i = ((insn & (1 << 22)) != 0);
8320 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8321 i, val)) {
8322 goto illegal_op;
8326 } else if ((insn & 0x0f900000) == 0x01000000
8327 && (insn & 0x00000090) != 0x00000090) {
8328 /* miscellaneous instructions */
8329 op1 = (insn >> 21) & 3;
8330 sh = (insn >> 4) & 0xf;
8331 rm = insn & 0xf;
8332 switch (sh) {
8333 case 0x0: /* MSR, MRS */
8334 if (insn & (1 << 9)) {
8335 /* MSR (banked) and MRS (banked) */
8336 int sysm = extract32(insn, 16, 4) |
8337 (extract32(insn, 8, 1) << 4);
8338 int r = extract32(insn, 22, 1);
8340 if (op1 & 1) {
8341 /* MSR (banked) */
8342 gen_msr_banked(s, r, sysm, rm);
8343 } else {
8344 /* MRS (banked) */
8345 int rd = extract32(insn, 12, 4);
8347 gen_mrs_banked(s, r, sysm, rd);
8349 break;
8352 /* MSR, MRS (for PSRs) */
8353 if (op1 & 1) {
8354 /* PSR = reg */
8355 tmp = load_reg(s, rm);
8356 i = ((op1 & 2) != 0);
8357 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8358 goto illegal_op;
8359 } else {
8360 /* reg = PSR */
8361 rd = (insn >> 12) & 0xf;
8362 if (op1 & 2) {
8363 if (IS_USER(s))
8364 goto illegal_op;
8365 tmp = load_cpu_field(spsr);
8366 } else {
8367 tmp = tcg_temp_new_i32();
8368 gen_helper_cpsr_read(tmp, cpu_env);
8370 store_reg(s, rd, tmp);
8372 break;
8373 case 0x1:
8374 if (op1 == 1) {
8375 /* branch/exchange thumb (bx). */
8376 ARCH(4T);
8377 tmp = load_reg(s, rm);
8378 gen_bx(s, tmp);
8379 } else if (op1 == 3) {
8380 /* clz */
8381 ARCH(5);
8382 rd = (insn >> 12) & 0xf;
8383 tmp = load_reg(s, rm);
8384 tcg_gen_clzi_i32(tmp, tmp, 32);
8385 store_reg(s, rd, tmp);
8386 } else {
8387 goto illegal_op;
8389 break;
8390 case 0x2:
8391 if (op1 == 1) {
8392 ARCH(5J); /* bxj */
8393 /* Trivial implementation equivalent to bx. */
8394 tmp = load_reg(s, rm);
8395 gen_bx(s, tmp);
8396 } else {
8397 goto illegal_op;
8399 break;
8400 case 0x3:
8401 if (op1 != 1)
8402 goto illegal_op;
8404 ARCH(5);
8405 /* branch link/exchange thumb (blx) */
8406 tmp = load_reg(s, rm);
8407 tmp2 = tcg_temp_new_i32();
8408 tcg_gen_movi_i32(tmp2, s->pc);
8409 store_reg(s, 14, tmp2);
8410 gen_bx(s, tmp);
8411 break;
8412 case 0x4:
8414 /* crc32/crc32c */
8415 uint32_t c = extract32(insn, 8, 4);
8417 /* Check this CPU supports ARMv8 CRC instructions.
8418 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8419 * Bits 8, 10 and 11 should be zero.
8421 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8422 (c & 0xd) != 0) {
8423 goto illegal_op;
8426 rn = extract32(insn, 16, 4);
8427 rd = extract32(insn, 12, 4);
8429 tmp = load_reg(s, rn);
8430 tmp2 = load_reg(s, rm);
8431 if (op1 == 0) {
8432 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8433 } else if (op1 == 1) {
8434 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8436 tmp3 = tcg_const_i32(1 << op1);
8437 if (c & 0x2) {
8438 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8439 } else {
8440 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8442 tcg_temp_free_i32(tmp2);
8443 tcg_temp_free_i32(tmp3);
8444 store_reg(s, rd, tmp);
8445 break;
8447 case 0x5: /* saturating add/subtract */
8448 ARCH(5TE);
8449 rd = (insn >> 12) & 0xf;
8450 rn = (insn >> 16) & 0xf;
8451 tmp = load_reg(s, rm);
8452 tmp2 = load_reg(s, rn);
8453 if (op1 & 2)
8454 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8455 if (op1 & 1)
8456 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8457 else
8458 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8459 tcg_temp_free_i32(tmp2);
8460 store_reg(s, rd, tmp);
8461 break;
8462 case 7:
8464 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8465 switch (op1) {
8466 case 0:
8467 /* HLT */
8468 gen_hlt(s, imm16);
8469 break;
8470 case 1:
8471 /* bkpt */
8472 ARCH(5);
8473 gen_exception_insn(s, 4, EXCP_BKPT,
8474 syn_aa32_bkpt(imm16, false),
8475 default_exception_el(s));
8476 break;
8477 case 2:
8478 /* Hypervisor call (v7) */
8479 ARCH(7);
8480 if (IS_USER(s)) {
8481 goto illegal_op;
8483 gen_hvc(s, imm16);
8484 break;
8485 case 3:
8486 /* Secure monitor call (v6+) */
8487 ARCH(6K);
8488 if (IS_USER(s)) {
8489 goto illegal_op;
8491 gen_smc(s);
8492 break;
8493 default:
8494 g_assert_not_reached();
8496 break;
8498 case 0x8: /* signed multiply */
8499 case 0xa:
8500 case 0xc:
8501 case 0xe:
8502 ARCH(5TE);
8503 rs = (insn >> 8) & 0xf;
8504 rn = (insn >> 12) & 0xf;
8505 rd = (insn >> 16) & 0xf;
8506 if (op1 == 1) {
8507 /* (32 * 16) >> 16 */
8508 tmp = load_reg(s, rm);
8509 tmp2 = load_reg(s, rs);
8510 if (sh & 4)
8511 tcg_gen_sari_i32(tmp2, tmp2, 16);
8512 else
8513 gen_sxth(tmp2);
8514 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8515 tcg_gen_shri_i64(tmp64, tmp64, 16);
8516 tmp = tcg_temp_new_i32();
8517 tcg_gen_extrl_i64_i32(tmp, tmp64);
8518 tcg_temp_free_i64(tmp64);
8519 if ((sh & 2) == 0) {
8520 tmp2 = load_reg(s, rn);
8521 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8522 tcg_temp_free_i32(tmp2);
8524 store_reg(s, rd, tmp);
8525 } else {
8526 /* 16 * 16 */
8527 tmp = load_reg(s, rm);
8528 tmp2 = load_reg(s, rs);
8529 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8530 tcg_temp_free_i32(tmp2);
8531 if (op1 == 2) {
8532 tmp64 = tcg_temp_new_i64();
8533 tcg_gen_ext_i32_i64(tmp64, tmp);
8534 tcg_temp_free_i32(tmp);
8535 gen_addq(s, tmp64, rn, rd);
8536 gen_storeq_reg(s, rn, rd, tmp64);
8537 tcg_temp_free_i64(tmp64);
8538 } else {
8539 if (op1 == 0) {
8540 tmp2 = load_reg(s, rn);
8541 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8542 tcg_temp_free_i32(tmp2);
8544 store_reg(s, rd, tmp);
8547 break;
8548 default:
8549 goto illegal_op;
8551 } else if (((insn & 0x0e000000) == 0 &&
8552 (insn & 0x00000090) != 0x90) ||
8553 ((insn & 0x0e000000) == (1 << 25))) {
8554 int set_cc, logic_cc, shiftop;
8556 op1 = (insn >> 21) & 0xf;
8557 set_cc = (insn >> 20) & 1;
8558 logic_cc = table_logic_cc[op1] & set_cc;
8560 /* data processing instruction */
8561 if (insn & (1 << 25)) {
8562 /* immediate operand */
8563 val = insn & 0xff;
8564 shift = ((insn >> 8) & 0xf) * 2;
8565 if (shift) {
8566 val = (val >> shift) | (val << (32 - shift));
8568 tmp2 = tcg_temp_new_i32();
8569 tcg_gen_movi_i32(tmp2, val);
8570 if (logic_cc && shift) {
8571 gen_set_CF_bit31(tmp2);
8573 } else {
8574 /* register */
8575 rm = (insn) & 0xf;
8576 tmp2 = load_reg(s, rm);
8577 shiftop = (insn >> 5) & 3;
8578 if (!(insn & (1 << 4))) {
8579 shift = (insn >> 7) & 0x1f;
8580 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8581 } else {
8582 rs = (insn >> 8) & 0xf;
8583 tmp = load_reg(s, rs);
8584 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8587 if (op1 != 0x0f && op1 != 0x0d) {
8588 rn = (insn >> 16) & 0xf;
8589 tmp = load_reg(s, rn);
8590 } else {
8591 TCGV_UNUSED_I32(tmp);
8593 rd = (insn >> 12) & 0xf;
8594 switch(op1) {
8595 case 0x00:
8596 tcg_gen_and_i32(tmp, tmp, tmp2);
8597 if (logic_cc) {
8598 gen_logic_CC(tmp);
8600 store_reg_bx(s, rd, tmp);
8601 break;
8602 case 0x01:
8603 tcg_gen_xor_i32(tmp, tmp, tmp2);
8604 if (logic_cc) {
8605 gen_logic_CC(tmp);
8607 store_reg_bx(s, rd, tmp);
8608 break;
8609 case 0x02:
8610 if (set_cc && rd == 15) {
8611 /* SUBS r15, ... is used for exception return. */
8612 if (IS_USER(s)) {
8613 goto illegal_op;
8615 gen_sub_CC(tmp, tmp, tmp2);
8616 gen_exception_return(s, tmp);
8617 } else {
8618 if (set_cc) {
8619 gen_sub_CC(tmp, tmp, tmp2);
8620 } else {
8621 tcg_gen_sub_i32(tmp, tmp, tmp2);
8623 store_reg_bx(s, rd, tmp);
8625 break;
8626 case 0x03:
8627 if (set_cc) {
8628 gen_sub_CC(tmp, tmp2, tmp);
8629 } else {
8630 tcg_gen_sub_i32(tmp, tmp2, tmp);
8632 store_reg_bx(s, rd, tmp);
8633 break;
8634 case 0x04:
8635 if (set_cc) {
8636 gen_add_CC(tmp, tmp, tmp2);
8637 } else {
8638 tcg_gen_add_i32(tmp, tmp, tmp2);
8640 store_reg_bx(s, rd, tmp);
8641 break;
8642 case 0x05:
8643 if (set_cc) {
8644 gen_adc_CC(tmp, tmp, tmp2);
8645 } else {
8646 gen_add_carry(tmp, tmp, tmp2);
8648 store_reg_bx(s, rd, tmp);
8649 break;
8650 case 0x06:
8651 if (set_cc) {
8652 gen_sbc_CC(tmp, tmp, tmp2);
8653 } else {
8654 gen_sub_carry(tmp, tmp, tmp2);
8656 store_reg_bx(s, rd, tmp);
8657 break;
8658 case 0x07:
8659 if (set_cc) {
8660 gen_sbc_CC(tmp, tmp2, tmp);
8661 } else {
8662 gen_sub_carry(tmp, tmp2, tmp);
8664 store_reg_bx(s, rd, tmp);
8665 break;
8666 case 0x08:
8667 if (set_cc) {
8668 tcg_gen_and_i32(tmp, tmp, tmp2);
8669 gen_logic_CC(tmp);
8671 tcg_temp_free_i32(tmp);
8672 break;
8673 case 0x09:
8674 if (set_cc) {
8675 tcg_gen_xor_i32(tmp, tmp, tmp2);
8676 gen_logic_CC(tmp);
8678 tcg_temp_free_i32(tmp);
8679 break;
8680 case 0x0a:
8681 if (set_cc) {
8682 gen_sub_CC(tmp, tmp, tmp2);
8684 tcg_temp_free_i32(tmp);
8685 break;
8686 case 0x0b:
8687 if (set_cc) {
8688 gen_add_CC(tmp, tmp, tmp2);
8690 tcg_temp_free_i32(tmp);
8691 break;
8692 case 0x0c:
8693 tcg_gen_or_i32(tmp, tmp, tmp2);
8694 if (logic_cc) {
8695 gen_logic_CC(tmp);
8697 store_reg_bx(s, rd, tmp);
8698 break;
8699 case 0x0d:
8700 if (logic_cc && rd == 15) {
8701 /* MOVS r15, ... is used for exception return. */
8702 if (IS_USER(s)) {
8703 goto illegal_op;
8705 gen_exception_return(s, tmp2);
8706 } else {
8707 if (logic_cc) {
8708 gen_logic_CC(tmp2);
8710 store_reg_bx(s, rd, tmp2);
8712 break;
8713 case 0x0e:
8714 tcg_gen_andc_i32(tmp, tmp, tmp2);
8715 if (logic_cc) {
8716 gen_logic_CC(tmp);
8718 store_reg_bx(s, rd, tmp);
8719 break;
8720 default:
8721 case 0x0f:
8722 tcg_gen_not_i32(tmp2, tmp2);
8723 if (logic_cc) {
8724 gen_logic_CC(tmp2);
8726 store_reg_bx(s, rd, tmp2);
8727 break;
8729 if (op1 != 0x0f && op1 != 0x0d) {
8730 tcg_temp_free_i32(tmp2);
8732 } else {
8733 /* other instructions */
8734 op1 = (insn >> 24) & 0xf;
8735 switch(op1) {
8736 case 0x0:
8737 case 0x1:
8738 /* multiplies, extra load/stores */
8739 sh = (insn >> 5) & 3;
8740 if (sh == 0) {
8741 if (op1 == 0x0) {
8742 rd = (insn >> 16) & 0xf;
8743 rn = (insn >> 12) & 0xf;
8744 rs = (insn >> 8) & 0xf;
8745 rm = (insn) & 0xf;
8746 op1 = (insn >> 20) & 0xf;
8747 switch (op1) {
8748 case 0: case 1: case 2: case 3: case 6:
8749 /* 32 bit mul */
8750 tmp = load_reg(s, rs);
8751 tmp2 = load_reg(s, rm);
8752 tcg_gen_mul_i32(tmp, tmp, tmp2);
8753 tcg_temp_free_i32(tmp2);
8754 if (insn & (1 << 22)) {
8755 /* Subtract (mls) */
8756 ARCH(6T2);
8757 tmp2 = load_reg(s, rn);
8758 tcg_gen_sub_i32(tmp, tmp2, tmp);
8759 tcg_temp_free_i32(tmp2);
8760 } else if (insn & (1 << 21)) {
8761 /* Add */
8762 tmp2 = load_reg(s, rn);
8763 tcg_gen_add_i32(tmp, tmp, tmp2);
8764 tcg_temp_free_i32(tmp2);
8766 if (insn & (1 << 20))
8767 gen_logic_CC(tmp);
8768 store_reg(s, rd, tmp);
8769 break;
8770 case 4:
8771 /* 64 bit mul double accumulate (UMAAL) */
8772 ARCH(6);
8773 tmp = load_reg(s, rs);
8774 tmp2 = load_reg(s, rm);
8775 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8776 gen_addq_lo(s, tmp64, rn);
8777 gen_addq_lo(s, tmp64, rd);
8778 gen_storeq_reg(s, rn, rd, tmp64);
8779 tcg_temp_free_i64(tmp64);
8780 break;
8781 case 8: case 9: case 10: case 11:
8782 case 12: case 13: case 14: case 15:
8783 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8784 tmp = load_reg(s, rs);
8785 tmp2 = load_reg(s, rm);
8786 if (insn & (1 << 22)) {
8787 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8788 } else {
8789 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8791 if (insn & (1 << 21)) { /* mult accumulate */
8792 TCGv_i32 al = load_reg(s, rn);
8793 TCGv_i32 ah = load_reg(s, rd);
8794 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8795 tcg_temp_free_i32(al);
8796 tcg_temp_free_i32(ah);
8798 if (insn & (1 << 20)) {
8799 gen_logicq_cc(tmp, tmp2);
8801 store_reg(s, rn, tmp);
8802 store_reg(s, rd, tmp2);
8803 break;
8804 default:
8805 goto illegal_op;
8807 } else {
8808 rn = (insn >> 16) & 0xf;
8809 rd = (insn >> 12) & 0xf;
8810 if (insn & (1 << 23)) {
8811 /* load/store exclusive */
8812 int op2 = (insn >> 8) & 3;
8813 op1 = (insn >> 21) & 0x3;
8815 switch (op2) {
8816 case 0: /* lda/stl */
8817 if (op1 == 1) {
8818 goto illegal_op;
8820 ARCH(8);
8821 break;
8822 case 1: /* reserved */
8823 goto illegal_op;
8824 case 2: /* ldaex/stlex */
8825 ARCH(8);
8826 break;
8827 case 3: /* ldrex/strex */
8828 if (op1) {
8829 ARCH(6K);
8830 } else {
8831 ARCH(6);
8833 break;
8836 addr = tcg_temp_local_new_i32();
8837 load_reg_var(s, addr, rn);
8839 /* Since the emulation does not have barriers,
8840 the acquire/release semantics need no special
8841 handling */
8842 if (op2 == 0) {
8843 if (insn & (1 << 20)) {
8844 tmp = tcg_temp_new_i32();
8845 switch (op1) {
8846 case 0: /* lda */
8847 gen_aa32_ld32u_iss(s, tmp, addr,
8848 get_mem_index(s),
8849 rd | ISSIsAcqRel);
8850 break;
8851 case 2: /* ldab */
8852 gen_aa32_ld8u_iss(s, tmp, addr,
8853 get_mem_index(s),
8854 rd | ISSIsAcqRel);
8855 break;
8856 case 3: /* ldah */
8857 gen_aa32_ld16u_iss(s, tmp, addr,
8858 get_mem_index(s),
8859 rd | ISSIsAcqRel);
8860 break;
8861 default:
8862 abort();
8864 store_reg(s, rd, tmp);
8865 } else {
8866 rm = insn & 0xf;
8867 tmp = load_reg(s, rm);
8868 switch (op1) {
8869 case 0: /* stl */
8870 gen_aa32_st32_iss(s, tmp, addr,
8871 get_mem_index(s),
8872 rm | ISSIsAcqRel);
8873 break;
8874 case 2: /* stlb */
8875 gen_aa32_st8_iss(s, tmp, addr,
8876 get_mem_index(s),
8877 rm | ISSIsAcqRel);
8878 break;
8879 case 3: /* stlh */
8880 gen_aa32_st16_iss(s, tmp, addr,
8881 get_mem_index(s),
8882 rm | ISSIsAcqRel);
8883 break;
8884 default:
8885 abort();
8887 tcg_temp_free_i32(tmp);
8889 } else if (insn & (1 << 20)) {
8890 switch (op1) {
8891 case 0: /* ldrex */
8892 gen_load_exclusive(s, rd, 15, addr, 2);
8893 break;
8894 case 1: /* ldrexd */
8895 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8896 break;
8897 case 2: /* ldrexb */
8898 gen_load_exclusive(s, rd, 15, addr, 0);
8899 break;
8900 case 3: /* ldrexh */
8901 gen_load_exclusive(s, rd, 15, addr, 1);
8902 break;
8903 default:
8904 abort();
8906 } else {
8907 rm = insn & 0xf;
8908 switch (op1) {
8909 case 0: /* strex */
8910 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8911 break;
8912 case 1: /* strexd */
8913 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8914 break;
8915 case 2: /* strexb */
8916 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8917 break;
8918 case 3: /* strexh */
8919 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8920 break;
8921 default:
8922 abort();
8925 tcg_temp_free_i32(addr);
8926 } else {
8927 TCGv taddr;
8928 TCGMemOp opc = s->be_data;
8930 /* SWP instruction */
8931 rm = (insn) & 0xf;
8933 if (insn & (1 << 22)) {
8934 opc |= MO_UB;
8935 } else {
8936 opc |= MO_UL | MO_ALIGN;
8939 addr = load_reg(s, rn);
8940 taddr = gen_aa32_addr(s, addr, opc);
8941 tcg_temp_free_i32(addr);
8943 tmp = load_reg(s, rm);
8944 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8945 get_mem_index(s), opc);
8946 tcg_temp_free(taddr);
8947 store_reg(s, rd, tmp);
8950 } else {
8951 int address_offset;
8952 bool load = insn & (1 << 20);
8953 bool wbit = insn & (1 << 21);
8954 bool pbit = insn & (1 << 24);
8955 bool doubleword = false;
8956 ISSInfo issinfo;
8958 /* Misc load/store */
8959 rn = (insn >> 16) & 0xf;
8960 rd = (insn >> 12) & 0xf;
8962 /* ISS not valid if writeback */
8963 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8965 if (!load && (sh & 2)) {
8966 /* doubleword */
8967 ARCH(5TE);
8968 if (rd & 1) {
8969 /* UNPREDICTABLE; we choose to UNDEF */
8970 goto illegal_op;
8972 load = (sh & 1) == 0;
8973 doubleword = true;
8976 addr = load_reg(s, rn);
8977 if (pbit) {
8978 gen_add_datah_offset(s, insn, 0, addr);
8980 address_offset = 0;
8982 if (doubleword) {
8983 if (!load) {
8984 /* store */
8985 tmp = load_reg(s, rd);
8986 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8987 tcg_temp_free_i32(tmp);
8988 tcg_gen_addi_i32(addr, addr, 4);
8989 tmp = load_reg(s, rd + 1);
8990 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8991 tcg_temp_free_i32(tmp);
8992 } else {
8993 /* load */
8994 tmp = tcg_temp_new_i32();
8995 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8996 store_reg(s, rd, tmp);
8997 tcg_gen_addi_i32(addr, addr, 4);
8998 tmp = tcg_temp_new_i32();
8999 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9000 rd++;
9002 address_offset = -4;
9003 } else if (load) {
9004 /* load */
9005 tmp = tcg_temp_new_i32();
9006 switch (sh) {
9007 case 1:
9008 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9009 issinfo);
9010 break;
9011 case 2:
9012 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9013 issinfo);
9014 break;
9015 default:
9016 case 3:
9017 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9018 issinfo);
9019 break;
9021 } else {
9022 /* store */
9023 tmp = load_reg(s, rd);
9024 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9025 tcg_temp_free_i32(tmp);
9027 /* Perform base writeback before the loaded value to
9028 ensure correct behavior with overlapping index registers.
9029 ldrd with base writeback is undefined if the
9030 destination and index registers overlap. */
9031 if (!pbit) {
9032 gen_add_datah_offset(s, insn, address_offset, addr);
9033 store_reg(s, rn, addr);
9034 } else if (wbit) {
9035 if (address_offset)
9036 tcg_gen_addi_i32(addr, addr, address_offset);
9037 store_reg(s, rn, addr);
9038 } else {
9039 tcg_temp_free_i32(addr);
9041 if (load) {
9042 /* Complete the load. */
9043 store_reg(s, rd, tmp);
9046 break;
9047 case 0x4:
9048 case 0x5:
9049 goto do_ldst;
9050 case 0x6:
9051 case 0x7:
9052 if (insn & (1 << 4)) {
9053 ARCH(6);
9054 /* Armv6 Media instructions. */
9055 rm = insn & 0xf;
9056 rn = (insn >> 16) & 0xf;
9057 rd = (insn >> 12) & 0xf;
9058 rs = (insn >> 8) & 0xf;
9059 switch ((insn >> 23) & 3) {
9060 case 0: /* Parallel add/subtract. */
9061 op1 = (insn >> 20) & 7;
9062 tmp = load_reg(s, rn);
9063 tmp2 = load_reg(s, rm);
9064 sh = (insn >> 5) & 7;
9065 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9066 goto illegal_op;
9067 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9068 tcg_temp_free_i32(tmp2);
9069 store_reg(s, rd, tmp);
9070 break;
9071 case 1:
9072 if ((insn & 0x00700020) == 0) {
9073 /* Halfword pack. */
9074 tmp = load_reg(s, rn);
9075 tmp2 = load_reg(s, rm);
9076 shift = (insn >> 7) & 0x1f;
9077 if (insn & (1 << 6)) {
9078 /* pkhtb */
9079 if (shift == 0)
9080 shift = 31;
9081 tcg_gen_sari_i32(tmp2, tmp2, shift);
9082 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9083 tcg_gen_ext16u_i32(tmp2, tmp2);
9084 } else {
9085 /* pkhbt */
9086 if (shift)
9087 tcg_gen_shli_i32(tmp2, tmp2, shift);
9088 tcg_gen_ext16u_i32(tmp, tmp);
9089 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9091 tcg_gen_or_i32(tmp, tmp, tmp2);
9092 tcg_temp_free_i32(tmp2);
9093 store_reg(s, rd, tmp);
9094 } else if ((insn & 0x00200020) == 0x00200000) {
9095 /* [us]sat */
9096 tmp = load_reg(s, rm);
9097 shift = (insn >> 7) & 0x1f;
9098 if (insn & (1 << 6)) {
9099 if (shift == 0)
9100 shift = 31;
9101 tcg_gen_sari_i32(tmp, tmp, shift);
9102 } else {
9103 tcg_gen_shli_i32(tmp, tmp, shift);
9105 sh = (insn >> 16) & 0x1f;
9106 tmp2 = tcg_const_i32(sh);
9107 if (insn & (1 << 22))
9108 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9109 else
9110 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9111 tcg_temp_free_i32(tmp2);
9112 store_reg(s, rd, tmp);
9113 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9114 /* [us]sat16 */
9115 tmp = load_reg(s, rm);
9116 sh = (insn >> 16) & 0x1f;
9117 tmp2 = tcg_const_i32(sh);
9118 if (insn & (1 << 22))
9119 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9120 else
9121 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9122 tcg_temp_free_i32(tmp2);
9123 store_reg(s, rd, tmp);
9124 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9125 /* Select bytes. */
9126 tmp = load_reg(s, rn);
9127 tmp2 = load_reg(s, rm);
9128 tmp3 = tcg_temp_new_i32();
9129 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9130 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9131 tcg_temp_free_i32(tmp3);
9132 tcg_temp_free_i32(tmp2);
9133 store_reg(s, rd, tmp);
9134 } else if ((insn & 0x000003e0) == 0x00000060) {
9135 tmp = load_reg(s, rm);
9136 shift = (insn >> 10) & 3;
9137 /* ??? In many cases it's not necessary to do a
9138 rotate, a shift is sufficient. */
9139 if (shift != 0)
9140 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9141 op1 = (insn >> 20) & 7;
9142 switch (op1) {
9143 case 0: gen_sxtb16(tmp); break;
9144 case 2: gen_sxtb(tmp); break;
9145 case 3: gen_sxth(tmp); break;
9146 case 4: gen_uxtb16(tmp); break;
9147 case 6: gen_uxtb(tmp); break;
9148 case 7: gen_uxth(tmp); break;
9149 default: goto illegal_op;
9151 if (rn != 15) {
9152 tmp2 = load_reg(s, rn);
9153 if ((op1 & 3) == 0) {
9154 gen_add16(tmp, tmp2);
9155 } else {
9156 tcg_gen_add_i32(tmp, tmp, tmp2);
9157 tcg_temp_free_i32(tmp2);
9160 store_reg(s, rd, tmp);
9161 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9162 /* rev */
9163 tmp = load_reg(s, rm);
9164 if (insn & (1 << 22)) {
9165 if (insn & (1 << 7)) {
9166 gen_revsh(tmp);
9167 } else {
9168 ARCH(6T2);
9169 gen_helper_rbit(tmp, tmp);
9171 } else {
9172 if (insn & (1 << 7))
9173 gen_rev16(tmp);
9174 else
9175 tcg_gen_bswap32_i32(tmp, tmp);
9177 store_reg(s, rd, tmp);
9178 } else {
9179 goto illegal_op;
9181 break;
9182 case 2: /* Multiplies (Type 3). */
9183 switch ((insn >> 20) & 0x7) {
9184 case 5:
9185 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9186 /* op2 not 00x or 11x : UNDEF */
9187 goto illegal_op;
9189 /* Signed multiply most significant [accumulate].
9190 (SMMUL, SMMLA, SMMLS) */
9191 tmp = load_reg(s, rm);
9192 tmp2 = load_reg(s, rs);
9193 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9195 if (rd != 15) {
9196 tmp = load_reg(s, rd);
9197 if (insn & (1 << 6)) {
9198 tmp64 = gen_subq_msw(tmp64, tmp);
9199 } else {
9200 tmp64 = gen_addq_msw(tmp64, tmp);
9203 if (insn & (1 << 5)) {
9204 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9206 tcg_gen_shri_i64(tmp64, tmp64, 32);
9207 tmp = tcg_temp_new_i32();
9208 tcg_gen_extrl_i64_i32(tmp, tmp64);
9209 tcg_temp_free_i64(tmp64);
9210 store_reg(s, rn, tmp);
9211 break;
9212 case 0:
9213 case 4:
9214 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9215 if (insn & (1 << 7)) {
9216 goto illegal_op;
9218 tmp = load_reg(s, rm);
9219 tmp2 = load_reg(s, rs);
9220 if (insn & (1 << 5))
9221 gen_swap_half(tmp2);
9222 gen_smul_dual(tmp, tmp2);
9223 if (insn & (1 << 22)) {
9224 /* smlald, smlsld */
9225 TCGv_i64 tmp64_2;
9227 tmp64 = tcg_temp_new_i64();
9228 tmp64_2 = tcg_temp_new_i64();
9229 tcg_gen_ext_i32_i64(tmp64, tmp);
9230 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9231 tcg_temp_free_i32(tmp);
9232 tcg_temp_free_i32(tmp2);
9233 if (insn & (1 << 6)) {
9234 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9235 } else {
9236 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9238 tcg_temp_free_i64(tmp64_2);
9239 gen_addq(s, tmp64, rd, rn);
9240 gen_storeq_reg(s, rd, rn, tmp64);
9241 tcg_temp_free_i64(tmp64);
9242 } else {
9243 /* smuad, smusd, smlad, smlsd */
9244 if (insn & (1 << 6)) {
9245 /* This subtraction cannot overflow. */
9246 tcg_gen_sub_i32(tmp, tmp, tmp2);
9247 } else {
9248 /* This addition cannot overflow 32 bits;
9249 * however it may overflow considered as a
9250 * signed operation, in which case we must set
9251 * the Q flag.
9253 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9255 tcg_temp_free_i32(tmp2);
9256 if (rd != 15)
9258 tmp2 = load_reg(s, rd);
9259 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9260 tcg_temp_free_i32(tmp2);
9262 store_reg(s, rn, tmp);
9264 break;
9265 case 1:
9266 case 3:
9267 /* SDIV, UDIV */
9268 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9269 goto illegal_op;
9271 if (((insn >> 5) & 7) || (rd != 15)) {
9272 goto illegal_op;
9274 tmp = load_reg(s, rm);
9275 tmp2 = load_reg(s, rs);
9276 if (insn & (1 << 21)) {
9277 gen_helper_udiv(tmp, tmp, tmp2);
9278 } else {
9279 gen_helper_sdiv(tmp, tmp, tmp2);
9281 tcg_temp_free_i32(tmp2);
9282 store_reg(s, rn, tmp);
9283 break;
9284 default:
9285 goto illegal_op;
9287 break;
9288 case 3:
9289 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9290 switch (op1) {
9291 case 0: /* Unsigned sum of absolute differences. */
9292 ARCH(6);
9293 tmp = load_reg(s, rm);
9294 tmp2 = load_reg(s, rs);
9295 gen_helper_usad8(tmp, tmp, tmp2);
9296 tcg_temp_free_i32(tmp2);
9297 if (rd != 15) {
9298 tmp2 = load_reg(s, rd);
9299 tcg_gen_add_i32(tmp, tmp, tmp2);
9300 tcg_temp_free_i32(tmp2);
9302 store_reg(s, rn, tmp);
9303 break;
9304 case 0x20: case 0x24: case 0x28: case 0x2c:
9305 /* Bitfield insert/clear. */
9306 ARCH(6T2);
9307 shift = (insn >> 7) & 0x1f;
9308 i = (insn >> 16) & 0x1f;
9309 if (i < shift) {
9310 /* UNPREDICTABLE; we choose to UNDEF */
9311 goto illegal_op;
9313 i = i + 1 - shift;
9314 if (rm == 15) {
9315 tmp = tcg_temp_new_i32();
9316 tcg_gen_movi_i32(tmp, 0);
9317 } else {
9318 tmp = load_reg(s, rm);
9320 if (i != 32) {
9321 tmp2 = load_reg(s, rd);
9322 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9323 tcg_temp_free_i32(tmp2);
9325 store_reg(s, rd, tmp);
9326 break;
9327 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9328 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9329 ARCH(6T2);
9330 tmp = load_reg(s, rm);
9331 shift = (insn >> 7) & 0x1f;
9332 i = ((insn >> 16) & 0x1f) + 1;
9333 if (shift + i > 32)
9334 goto illegal_op;
9335 if (i < 32) {
9336 if (op1 & 0x20) {
9337 tcg_gen_extract_i32(tmp, tmp, shift, i);
9338 } else {
9339 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9342 store_reg(s, rd, tmp);
9343 break;
9344 default:
9345 goto illegal_op;
9347 break;
9349 break;
9351 do_ldst:
9352 /* Check for undefined extension instructions
9353 * per the ARM Bible IE:
9354 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9356 sh = (0xf << 20) | (0xf << 4);
9357 if (op1 == 0x7 && ((insn & sh) == sh))
9359 goto illegal_op;
9361 /* load/store byte/word */
9362 rn = (insn >> 16) & 0xf;
9363 rd = (insn >> 12) & 0xf;
9364 tmp2 = load_reg(s, rn);
9365 if ((insn & 0x01200000) == 0x00200000) {
9366 /* ldrt/strt */
9367 i = get_a32_user_mem_index(s);
9368 } else {
9369 i = get_mem_index(s);
9371 if (insn & (1 << 24))
9372 gen_add_data_offset(s, insn, tmp2);
9373 if (insn & (1 << 20)) {
9374 /* load */
9375 tmp = tcg_temp_new_i32();
9376 if (insn & (1 << 22)) {
9377 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9378 } else {
9379 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9381 } else {
9382 /* store */
9383 tmp = load_reg(s, rd);
9384 if (insn & (1 << 22)) {
9385 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9386 } else {
9387 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9389 tcg_temp_free_i32(tmp);
9391 if (!(insn & (1 << 24))) {
9392 gen_add_data_offset(s, insn, tmp2);
9393 store_reg(s, rn, tmp2);
9394 } else if (insn & (1 << 21)) {
9395 store_reg(s, rn, tmp2);
9396 } else {
9397 tcg_temp_free_i32(tmp2);
9399 if (insn & (1 << 20)) {
9400 /* Complete the load. */
9401 store_reg_from_load(s, rd, tmp);
9403 break;
9404 case 0x08:
9405 case 0x09:
9407 int j, n, loaded_base;
9408 bool exc_return = false;
9409 bool is_load = extract32(insn, 20, 1);
9410 bool user = false;
9411 TCGv_i32 loaded_var;
9412 /* load/store multiple words */
9413 /* XXX: store correct base if write back */
9414 if (insn & (1 << 22)) {
9415 /* LDM (user), LDM (exception return) and STM (user) */
9416 if (IS_USER(s))
9417 goto illegal_op; /* only usable in supervisor mode */
9419 if (is_load && extract32(insn, 15, 1)) {
9420 exc_return = true;
9421 } else {
9422 user = true;
9425 rn = (insn >> 16) & 0xf;
9426 addr = load_reg(s, rn);
9428 /* compute total size */
9429 loaded_base = 0;
9430 TCGV_UNUSED_I32(loaded_var);
9431 n = 0;
9432 for(i=0;i<16;i++) {
9433 if (insn & (1 << i))
9434 n++;
9436 /* XXX: test invalid n == 0 case ? */
9437 if (insn & (1 << 23)) {
9438 if (insn & (1 << 24)) {
9439 /* pre increment */
9440 tcg_gen_addi_i32(addr, addr, 4);
9441 } else {
9442 /* post increment */
9444 } else {
9445 if (insn & (1 << 24)) {
9446 /* pre decrement */
9447 tcg_gen_addi_i32(addr, addr, -(n * 4));
9448 } else {
9449 /* post decrement */
9450 if (n != 1)
9451 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9454 j = 0;
9455 for(i=0;i<16;i++) {
9456 if (insn & (1 << i)) {
9457 if (is_load) {
9458 /* load */
9459 tmp = tcg_temp_new_i32();
9460 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9461 if (user) {
9462 tmp2 = tcg_const_i32(i);
9463 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9464 tcg_temp_free_i32(tmp2);
9465 tcg_temp_free_i32(tmp);
9466 } else if (i == rn) {
9467 loaded_var = tmp;
9468 loaded_base = 1;
9469 } else if (rn == 15 && exc_return) {
9470 store_pc_exc_ret(s, tmp);
9471 } else {
9472 store_reg_from_load(s, i, tmp);
9474 } else {
9475 /* store */
9476 if (i == 15) {
9477 /* special case: r15 = PC + 8 */
9478 val = (long)s->pc + 4;
9479 tmp = tcg_temp_new_i32();
9480 tcg_gen_movi_i32(tmp, val);
9481 } else if (user) {
9482 tmp = tcg_temp_new_i32();
9483 tmp2 = tcg_const_i32(i);
9484 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9485 tcg_temp_free_i32(tmp2);
9486 } else {
9487 tmp = load_reg(s, i);
9489 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9490 tcg_temp_free_i32(tmp);
9492 j++;
9493 /* no need to add after the last transfer */
9494 if (j != n)
9495 tcg_gen_addi_i32(addr, addr, 4);
9498 if (insn & (1 << 21)) {
9499 /* write back */
9500 if (insn & (1 << 23)) {
9501 if (insn & (1 << 24)) {
9502 /* pre increment */
9503 } else {
9504 /* post increment */
9505 tcg_gen_addi_i32(addr, addr, 4);
9507 } else {
9508 if (insn & (1 << 24)) {
9509 /* pre decrement */
9510 if (n != 1)
9511 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9512 } else {
9513 /* post decrement */
9514 tcg_gen_addi_i32(addr, addr, -(n * 4));
9517 store_reg(s, rn, addr);
9518 } else {
9519 tcg_temp_free_i32(addr);
9521 if (loaded_base) {
9522 store_reg(s, rn, loaded_var);
9524 if (exc_return) {
9525 /* Restore CPSR from SPSR. */
9526 tmp = load_cpu_field(spsr);
9527 gen_helper_cpsr_write_eret(cpu_env, tmp);
9528 tcg_temp_free_i32(tmp);
9529 /* Must exit loop to check un-masked IRQs */
9530 s->is_jmp = DISAS_EXIT;
9533 break;
9534 case 0xa:
9535 case 0xb:
9537 int32_t offset;
9539 /* branch (and link) */
9540 val = (int32_t)s->pc;
9541 if (insn & (1 << 24)) {
9542 tmp = tcg_temp_new_i32();
9543 tcg_gen_movi_i32(tmp, val);
9544 store_reg(s, 14, tmp);
9546 offset = sextract32(insn << 2, 0, 26);
9547 val += offset + 4;
9548 gen_jmp(s, val);
9550 break;
9551 case 0xc:
9552 case 0xd:
9553 case 0xe:
9554 if (((insn >> 8) & 0xe) == 10) {
9555 /* VFP. */
9556 if (disas_vfp_insn(s, insn)) {
9557 goto illegal_op;
9559 } else if (disas_coproc_insn(s, insn)) {
9560 /* Coprocessor. */
9561 goto illegal_op;
9563 break;
9564 case 0xf:
9565 /* swi */
9566 gen_set_pc_im(s, s->pc);
9567 s->svc_imm = extract32(insn, 0, 24);
9568 s->is_jmp = DISAS_SWI;
9569 break;
9570 default:
9571 illegal_op:
9572 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9573 default_exception_el(s));
9574 break;
9579 /* Return true if this is a Thumb-2 logical op. */
9580 static int
9581 thumb2_logic_op(int op)
9583 return (op < 8);
9586 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9587 then set condition code flags based on the result of the operation.
9588 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9589 to the high bit of T1.
9590 Returns zero if the opcode is valid. */
9592 static int
9593 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9594 TCGv_i32 t0, TCGv_i32 t1)
9596 int logic_cc;
9598 logic_cc = 0;
9599 switch (op) {
9600 case 0: /* and */
9601 tcg_gen_and_i32(t0, t0, t1);
9602 logic_cc = conds;
9603 break;
9604 case 1: /* bic */
9605 tcg_gen_andc_i32(t0, t0, t1);
9606 logic_cc = conds;
9607 break;
9608 case 2: /* orr */
9609 tcg_gen_or_i32(t0, t0, t1);
9610 logic_cc = conds;
9611 break;
9612 case 3: /* orn */
9613 tcg_gen_orc_i32(t0, t0, t1);
9614 logic_cc = conds;
9615 break;
9616 case 4: /* eor */
9617 tcg_gen_xor_i32(t0, t0, t1);
9618 logic_cc = conds;
9619 break;
9620 case 8: /* add */
9621 if (conds)
9622 gen_add_CC(t0, t0, t1);
9623 else
9624 tcg_gen_add_i32(t0, t0, t1);
9625 break;
9626 case 10: /* adc */
9627 if (conds)
9628 gen_adc_CC(t0, t0, t1);
9629 else
9630 gen_adc(t0, t1);
9631 break;
9632 case 11: /* sbc */
9633 if (conds) {
9634 gen_sbc_CC(t0, t0, t1);
9635 } else {
9636 gen_sub_carry(t0, t0, t1);
9638 break;
9639 case 13: /* sub */
9640 if (conds)
9641 gen_sub_CC(t0, t0, t1);
9642 else
9643 tcg_gen_sub_i32(t0, t0, t1);
9644 break;
9645 case 14: /* rsb */
9646 if (conds)
9647 gen_sub_CC(t0, t1, t0);
9648 else
9649 tcg_gen_sub_i32(t0, t1, t0);
9650 break;
9651 default: /* 5, 6, 7, 9, 12, 15. */
9652 return 1;
9654 if (logic_cc) {
9655 gen_logic_CC(t0);
9656 if (shifter_out)
9657 gen_set_CF_bit31(t1);
9659 return 0;
9662 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9663 is not legal. */
9664 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9666 uint32_t insn, imm, shift, offset;
9667 uint32_t rd, rn, rm, rs;
9668 TCGv_i32 tmp;
9669 TCGv_i32 tmp2;
9670 TCGv_i32 tmp3;
9671 TCGv_i32 addr;
9672 TCGv_i64 tmp64;
9673 int op;
9674 int shiftop;
9675 int conds;
9676 int logic_cc;
9678 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9679 || arm_dc_feature(s, ARM_FEATURE_M))) {
9680 /* Thumb-1 cores may need to treat bl and blx as a pair of
9681 16-bit instructions to get correct prefetch abort behavior. */
9682 insn = insn_hw1;
9683 if ((insn & (1 << 12)) == 0) {
9684 ARCH(5);
9685 /* Second half of blx. */
9686 offset = ((insn & 0x7ff) << 1);
9687 tmp = load_reg(s, 14);
9688 tcg_gen_addi_i32(tmp, tmp, offset);
9689 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9691 tmp2 = tcg_temp_new_i32();
9692 tcg_gen_movi_i32(tmp2, s->pc | 1);
9693 store_reg(s, 14, tmp2);
9694 gen_bx(s, tmp);
9695 return 0;
9697 if (insn & (1 << 11)) {
9698 /* Second half of bl. */
9699 offset = ((insn & 0x7ff) << 1) | 1;
9700 tmp = load_reg(s, 14);
9701 tcg_gen_addi_i32(tmp, tmp, offset);
9703 tmp2 = tcg_temp_new_i32();
9704 tcg_gen_movi_i32(tmp2, s->pc | 1);
9705 store_reg(s, 14, tmp2);
9706 gen_bx(s, tmp);
9707 return 0;
9709 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9710 /* Instruction spans a page boundary. Implement it as two
9711 16-bit instructions in case the second half causes an
9712 prefetch abort. */
9713 offset = ((int32_t)insn << 21) >> 9;
9714 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9715 return 0;
9717 /* Fall through to 32-bit decode. */
9720 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9721 s->pc += 2;
9722 insn |= (uint32_t)insn_hw1 << 16;
9724 if ((insn & 0xf800e800) != 0xf000e800) {
9725 ARCH(6T2);
9728 rn = (insn >> 16) & 0xf;
9729 rs = (insn >> 12) & 0xf;
9730 rd = (insn >> 8) & 0xf;
9731 rm = insn & 0xf;
9732 switch ((insn >> 25) & 0xf) {
9733 case 0: case 1: case 2: case 3:
9734 /* 16-bit instructions. Should never happen. */
9735 abort();
9736 case 4:
9737 if (insn & (1 << 22)) {
9738 /* Other load/store, table branch. */
9739 if (insn & 0x01200000) {
9740 /* Load/store doubleword. */
9741 if (rn == 15) {
9742 addr = tcg_temp_new_i32();
9743 tcg_gen_movi_i32(addr, s->pc & ~3);
9744 } else {
9745 addr = load_reg(s, rn);
9747 offset = (insn & 0xff) * 4;
9748 if ((insn & (1 << 23)) == 0)
9749 offset = -offset;
9750 if (insn & (1 << 24)) {
9751 tcg_gen_addi_i32(addr, addr, offset);
9752 offset = 0;
9754 if (insn & (1 << 20)) {
9755 /* ldrd */
9756 tmp = tcg_temp_new_i32();
9757 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9758 store_reg(s, rs, tmp);
9759 tcg_gen_addi_i32(addr, addr, 4);
9760 tmp = tcg_temp_new_i32();
9761 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9762 store_reg(s, rd, tmp);
9763 } else {
9764 /* strd */
9765 tmp = load_reg(s, rs);
9766 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9767 tcg_temp_free_i32(tmp);
9768 tcg_gen_addi_i32(addr, addr, 4);
9769 tmp = load_reg(s, rd);
9770 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9771 tcg_temp_free_i32(tmp);
9773 if (insn & (1 << 21)) {
9774 /* Base writeback. */
9775 if (rn == 15)
9776 goto illegal_op;
9777 tcg_gen_addi_i32(addr, addr, offset - 4);
9778 store_reg(s, rn, addr);
9779 } else {
9780 tcg_temp_free_i32(addr);
9782 } else if ((insn & (1 << 23)) == 0) {
9783 /* Load/store exclusive word. */
9784 addr = tcg_temp_local_new_i32();
9785 load_reg_var(s, addr, rn);
9786 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9787 if (insn & (1 << 20)) {
9788 gen_load_exclusive(s, rs, 15, addr, 2);
9789 } else {
9790 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9792 tcg_temp_free_i32(addr);
9793 } else if ((insn & (7 << 5)) == 0) {
9794 /* Table Branch. */
9795 if (rn == 15) {
9796 addr = tcg_temp_new_i32();
9797 tcg_gen_movi_i32(addr, s->pc);
9798 } else {
9799 addr = load_reg(s, rn);
9801 tmp = load_reg(s, rm);
9802 tcg_gen_add_i32(addr, addr, tmp);
9803 if (insn & (1 << 4)) {
9804 /* tbh */
9805 tcg_gen_add_i32(addr, addr, tmp);
9806 tcg_temp_free_i32(tmp);
9807 tmp = tcg_temp_new_i32();
9808 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9809 } else { /* tbb */
9810 tcg_temp_free_i32(tmp);
9811 tmp = tcg_temp_new_i32();
9812 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9814 tcg_temp_free_i32(addr);
9815 tcg_gen_shli_i32(tmp, tmp, 1);
9816 tcg_gen_addi_i32(tmp, tmp, s->pc);
9817 store_reg(s, 15, tmp);
9818 } else {
9819 int op2 = (insn >> 6) & 0x3;
9820 op = (insn >> 4) & 0x3;
9821 switch (op2) {
9822 case 0:
9823 goto illegal_op;
9824 case 1:
9825 /* Load/store exclusive byte/halfword/doubleword */
9826 if (op == 2) {
9827 goto illegal_op;
9829 ARCH(7);
9830 break;
9831 case 2:
9832 /* Load-acquire/store-release */
9833 if (op == 3) {
9834 goto illegal_op;
9836 /* Fall through */
9837 case 3:
9838 /* Load-acquire/store-release exclusive */
9839 ARCH(8);
9840 break;
9842 addr = tcg_temp_local_new_i32();
9843 load_reg_var(s, addr, rn);
9844 if (!(op2 & 1)) {
9845 if (insn & (1 << 20)) {
9846 tmp = tcg_temp_new_i32();
9847 switch (op) {
9848 case 0: /* ldab */
9849 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9850 rs | ISSIsAcqRel);
9851 break;
9852 case 1: /* ldah */
9853 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9854 rs | ISSIsAcqRel);
9855 break;
9856 case 2: /* lda */
9857 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9858 rs | ISSIsAcqRel);
9859 break;
9860 default:
9861 abort();
9863 store_reg(s, rs, tmp);
9864 } else {
9865 tmp = load_reg(s, rs);
9866 switch (op) {
9867 case 0: /* stlb */
9868 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9869 rs | ISSIsAcqRel);
9870 break;
9871 case 1: /* stlh */
9872 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9873 rs | ISSIsAcqRel);
9874 break;
9875 case 2: /* stl */
9876 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9877 rs | ISSIsAcqRel);
9878 break;
9879 default:
9880 abort();
9882 tcg_temp_free_i32(tmp);
9884 } else if (insn & (1 << 20)) {
9885 gen_load_exclusive(s, rs, rd, addr, op);
9886 } else {
9887 gen_store_exclusive(s, rm, rs, rd, addr, op);
9889 tcg_temp_free_i32(addr);
9891 } else {
9892 /* Load/store multiple, RFE, SRS. */
9893 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9894 /* RFE, SRS: not available in user mode or on M profile */
9895 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9896 goto illegal_op;
9898 if (insn & (1 << 20)) {
9899 /* rfe */
9900 addr = load_reg(s, rn);
9901 if ((insn & (1 << 24)) == 0)
9902 tcg_gen_addi_i32(addr, addr, -8);
9903 /* Load PC into tmp and CPSR into tmp2. */
9904 tmp = tcg_temp_new_i32();
9905 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9906 tcg_gen_addi_i32(addr, addr, 4);
9907 tmp2 = tcg_temp_new_i32();
9908 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9909 if (insn & (1 << 21)) {
9910 /* Base writeback. */
9911 if (insn & (1 << 24)) {
9912 tcg_gen_addi_i32(addr, addr, 4);
9913 } else {
9914 tcg_gen_addi_i32(addr, addr, -4);
9916 store_reg(s, rn, addr);
9917 } else {
9918 tcg_temp_free_i32(addr);
9920 gen_rfe(s, tmp, tmp2);
9921 } else {
9922 /* srs */
9923 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9924 insn & (1 << 21));
9926 } else {
9927 int i, loaded_base = 0;
9928 TCGv_i32 loaded_var;
9929 /* Load/store multiple. */
9930 addr = load_reg(s, rn);
9931 offset = 0;
9932 for (i = 0; i < 16; i++) {
9933 if (insn & (1 << i))
9934 offset += 4;
9936 if (insn & (1 << 24)) {
9937 tcg_gen_addi_i32(addr, addr, -offset);
9940 TCGV_UNUSED_I32(loaded_var);
9941 for (i = 0; i < 16; i++) {
9942 if ((insn & (1 << i)) == 0)
9943 continue;
9944 if (insn & (1 << 20)) {
9945 /* Load. */
9946 tmp = tcg_temp_new_i32();
9947 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9948 if (i == 15) {
9949 gen_bx_excret(s, tmp);
9950 } else if (i == rn) {
9951 loaded_var = tmp;
9952 loaded_base = 1;
9953 } else {
9954 store_reg(s, i, tmp);
9956 } else {
9957 /* Store. */
9958 tmp = load_reg(s, i);
9959 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9960 tcg_temp_free_i32(tmp);
9962 tcg_gen_addi_i32(addr, addr, 4);
9964 if (loaded_base) {
9965 store_reg(s, rn, loaded_var);
9967 if (insn & (1 << 21)) {
9968 /* Base register writeback. */
9969 if (insn & (1 << 24)) {
9970 tcg_gen_addi_i32(addr, addr, -offset);
9972 /* Fault if writeback register is in register list. */
9973 if (insn & (1 << rn))
9974 goto illegal_op;
9975 store_reg(s, rn, addr);
9976 } else {
9977 tcg_temp_free_i32(addr);
9981 break;
9982 case 5:
9984 op = (insn >> 21) & 0xf;
9985 if (op == 6) {
9986 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9987 goto illegal_op;
9989 /* Halfword pack. */
9990 tmp = load_reg(s, rn);
9991 tmp2 = load_reg(s, rm);
9992 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9993 if (insn & (1 << 5)) {
9994 /* pkhtb */
9995 if (shift == 0)
9996 shift = 31;
9997 tcg_gen_sari_i32(tmp2, tmp2, shift);
9998 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9999 tcg_gen_ext16u_i32(tmp2, tmp2);
10000 } else {
10001 /* pkhbt */
10002 if (shift)
10003 tcg_gen_shli_i32(tmp2, tmp2, shift);
10004 tcg_gen_ext16u_i32(tmp, tmp);
10005 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10007 tcg_gen_or_i32(tmp, tmp, tmp2);
10008 tcg_temp_free_i32(tmp2);
10009 store_reg(s, rd, tmp);
10010 } else {
10011 /* Data processing register constant shift. */
10012 if (rn == 15) {
10013 tmp = tcg_temp_new_i32();
10014 tcg_gen_movi_i32(tmp, 0);
10015 } else {
10016 tmp = load_reg(s, rn);
10018 tmp2 = load_reg(s, rm);
10020 shiftop = (insn >> 4) & 3;
10021 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10022 conds = (insn & (1 << 20)) != 0;
10023 logic_cc = (conds && thumb2_logic_op(op));
10024 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10025 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10026 goto illegal_op;
10027 tcg_temp_free_i32(tmp2);
10028 if (rd != 15) {
10029 store_reg(s, rd, tmp);
10030 } else {
10031 tcg_temp_free_i32(tmp);
10034 break;
10035 case 13: /* Misc data processing. */
10036 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10037 if (op < 4 && (insn & 0xf000) != 0xf000)
10038 goto illegal_op;
10039 switch (op) {
10040 case 0: /* Register controlled shift. */
10041 tmp = load_reg(s, rn);
10042 tmp2 = load_reg(s, rm);
10043 if ((insn & 0x70) != 0)
10044 goto illegal_op;
10045 op = (insn >> 21) & 3;
10046 logic_cc = (insn & (1 << 20)) != 0;
10047 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10048 if (logic_cc)
10049 gen_logic_CC(tmp);
10050 store_reg(s, rd, tmp);
10051 break;
10052 case 1: /* Sign/zero extend. */
10053 op = (insn >> 20) & 7;
10054 switch (op) {
10055 case 0: /* SXTAH, SXTH */
10056 case 1: /* UXTAH, UXTH */
10057 case 4: /* SXTAB, SXTB */
10058 case 5: /* UXTAB, UXTB */
10059 break;
10060 case 2: /* SXTAB16, SXTB16 */
10061 case 3: /* UXTAB16, UXTB16 */
10062 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10063 goto illegal_op;
10065 break;
10066 default:
10067 goto illegal_op;
10069 if (rn != 15) {
10070 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10071 goto illegal_op;
10074 tmp = load_reg(s, rm);
10075 shift = (insn >> 4) & 3;
10076 /* ??? In many cases it's not necessary to do a
10077 rotate, a shift is sufficient. */
10078 if (shift != 0)
10079 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10080 op = (insn >> 20) & 7;
10081 switch (op) {
10082 case 0: gen_sxth(tmp); break;
10083 case 1: gen_uxth(tmp); break;
10084 case 2: gen_sxtb16(tmp); break;
10085 case 3: gen_uxtb16(tmp); break;
10086 case 4: gen_sxtb(tmp); break;
10087 case 5: gen_uxtb(tmp); break;
10088 default:
10089 g_assert_not_reached();
10091 if (rn != 15) {
10092 tmp2 = load_reg(s, rn);
10093 if ((op >> 1) == 1) {
10094 gen_add16(tmp, tmp2);
10095 } else {
10096 tcg_gen_add_i32(tmp, tmp, tmp2);
10097 tcg_temp_free_i32(tmp2);
10100 store_reg(s, rd, tmp);
10101 break;
10102 case 2: /* SIMD add/subtract. */
10103 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10104 goto illegal_op;
10106 op = (insn >> 20) & 7;
10107 shift = (insn >> 4) & 7;
10108 if ((op & 3) == 3 || (shift & 3) == 3)
10109 goto illegal_op;
10110 tmp = load_reg(s, rn);
10111 tmp2 = load_reg(s, rm);
10112 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10113 tcg_temp_free_i32(tmp2);
10114 store_reg(s, rd, tmp);
10115 break;
10116 case 3: /* Other data processing. */
10117 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10118 if (op < 4) {
10119 /* Saturating add/subtract. */
10120 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10121 goto illegal_op;
10123 tmp = load_reg(s, rn);
10124 tmp2 = load_reg(s, rm);
10125 if (op & 1)
10126 gen_helper_double_saturate(tmp, cpu_env, tmp);
10127 if (op & 2)
10128 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10129 else
10130 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10131 tcg_temp_free_i32(tmp2);
10132 } else {
10133 switch (op) {
10134 case 0x0a: /* rbit */
10135 case 0x08: /* rev */
10136 case 0x09: /* rev16 */
10137 case 0x0b: /* revsh */
10138 case 0x18: /* clz */
10139 break;
10140 case 0x10: /* sel */
10141 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10142 goto illegal_op;
10144 break;
10145 case 0x20: /* crc32/crc32c */
10146 case 0x21:
10147 case 0x22:
10148 case 0x28:
10149 case 0x29:
10150 case 0x2a:
10151 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10152 goto illegal_op;
10154 break;
10155 default:
10156 goto illegal_op;
10158 tmp = load_reg(s, rn);
10159 switch (op) {
10160 case 0x0a: /* rbit */
10161 gen_helper_rbit(tmp, tmp);
10162 break;
10163 case 0x08: /* rev */
10164 tcg_gen_bswap32_i32(tmp, tmp);
10165 break;
10166 case 0x09: /* rev16 */
10167 gen_rev16(tmp);
10168 break;
10169 case 0x0b: /* revsh */
10170 gen_revsh(tmp);
10171 break;
10172 case 0x10: /* sel */
10173 tmp2 = load_reg(s, rm);
10174 tmp3 = tcg_temp_new_i32();
10175 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10176 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10177 tcg_temp_free_i32(tmp3);
10178 tcg_temp_free_i32(tmp2);
10179 break;
10180 case 0x18: /* clz */
10181 tcg_gen_clzi_i32(tmp, tmp, 32);
10182 break;
10183 case 0x20:
10184 case 0x21:
10185 case 0x22:
10186 case 0x28:
10187 case 0x29:
10188 case 0x2a:
10190 /* crc32/crc32c */
10191 uint32_t sz = op & 0x3;
10192 uint32_t c = op & 0x8;
10194 tmp2 = load_reg(s, rm);
10195 if (sz == 0) {
10196 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10197 } else if (sz == 1) {
10198 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10200 tmp3 = tcg_const_i32(1 << sz);
10201 if (c) {
10202 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10203 } else {
10204 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10206 tcg_temp_free_i32(tmp2);
10207 tcg_temp_free_i32(tmp3);
10208 break;
10210 default:
10211 g_assert_not_reached();
10214 store_reg(s, rd, tmp);
10215 break;
10216 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10217 switch ((insn >> 20) & 7) {
10218 case 0: /* 32 x 32 -> 32 */
10219 case 7: /* Unsigned sum of absolute differences. */
10220 break;
10221 case 1: /* 16 x 16 -> 32 */
10222 case 2: /* Dual multiply add. */
10223 case 3: /* 32 * 16 -> 32msb */
10224 case 4: /* Dual multiply subtract. */
10225 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10226 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10227 goto illegal_op;
10229 break;
10231 op = (insn >> 4) & 0xf;
10232 tmp = load_reg(s, rn);
10233 tmp2 = load_reg(s, rm);
10234 switch ((insn >> 20) & 7) {
10235 case 0: /* 32 x 32 -> 32 */
10236 tcg_gen_mul_i32(tmp, tmp, tmp2);
10237 tcg_temp_free_i32(tmp2);
10238 if (rs != 15) {
10239 tmp2 = load_reg(s, rs);
10240 if (op)
10241 tcg_gen_sub_i32(tmp, tmp2, tmp);
10242 else
10243 tcg_gen_add_i32(tmp, tmp, tmp2);
10244 tcg_temp_free_i32(tmp2);
10246 break;
10247 case 1: /* 16 x 16 -> 32 */
10248 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10249 tcg_temp_free_i32(tmp2);
10250 if (rs != 15) {
10251 tmp2 = load_reg(s, rs);
10252 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10253 tcg_temp_free_i32(tmp2);
10255 break;
10256 case 2: /* Dual multiply add. */
10257 case 4: /* Dual multiply subtract. */
10258 if (op)
10259 gen_swap_half(tmp2);
10260 gen_smul_dual(tmp, tmp2);
10261 if (insn & (1 << 22)) {
10262 /* This subtraction cannot overflow. */
10263 tcg_gen_sub_i32(tmp, tmp, tmp2);
10264 } else {
10265 /* This addition cannot overflow 32 bits;
10266 * however it may overflow considered as a signed
10267 * operation, in which case we must set the Q flag.
10269 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10271 tcg_temp_free_i32(tmp2);
10272 if (rs != 15)
10274 tmp2 = load_reg(s, rs);
10275 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10276 tcg_temp_free_i32(tmp2);
10278 break;
10279 case 3: /* 32 * 16 -> 32msb */
10280 if (op)
10281 tcg_gen_sari_i32(tmp2, tmp2, 16);
10282 else
10283 gen_sxth(tmp2);
10284 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10285 tcg_gen_shri_i64(tmp64, tmp64, 16);
10286 tmp = tcg_temp_new_i32();
10287 tcg_gen_extrl_i64_i32(tmp, tmp64);
10288 tcg_temp_free_i64(tmp64);
10289 if (rs != 15)
10291 tmp2 = load_reg(s, rs);
10292 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10293 tcg_temp_free_i32(tmp2);
10295 break;
10296 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10297 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10298 if (rs != 15) {
10299 tmp = load_reg(s, rs);
10300 if (insn & (1 << 20)) {
10301 tmp64 = gen_addq_msw(tmp64, tmp);
10302 } else {
10303 tmp64 = gen_subq_msw(tmp64, tmp);
10306 if (insn & (1 << 4)) {
10307 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10309 tcg_gen_shri_i64(tmp64, tmp64, 32);
10310 tmp = tcg_temp_new_i32();
10311 tcg_gen_extrl_i64_i32(tmp, tmp64);
10312 tcg_temp_free_i64(tmp64);
10313 break;
10314 case 7: /* Unsigned sum of absolute differences. */
10315 gen_helper_usad8(tmp, tmp, tmp2);
10316 tcg_temp_free_i32(tmp2);
10317 if (rs != 15) {
10318 tmp2 = load_reg(s, rs);
10319 tcg_gen_add_i32(tmp, tmp, tmp2);
10320 tcg_temp_free_i32(tmp2);
10322 break;
10324 store_reg(s, rd, tmp);
10325 break;
10326 case 6: case 7: /* 64-bit multiply, Divide. */
10327 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10328 tmp = load_reg(s, rn);
10329 tmp2 = load_reg(s, rm);
10330 if ((op & 0x50) == 0x10) {
10331 /* sdiv, udiv */
10332 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10333 goto illegal_op;
10335 if (op & 0x20)
10336 gen_helper_udiv(tmp, tmp, tmp2);
10337 else
10338 gen_helper_sdiv(tmp, tmp, tmp2);
10339 tcg_temp_free_i32(tmp2);
10340 store_reg(s, rd, tmp);
10341 } else if ((op & 0xe) == 0xc) {
10342 /* Dual multiply accumulate long. */
10343 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10344 tcg_temp_free_i32(tmp);
10345 tcg_temp_free_i32(tmp2);
10346 goto illegal_op;
10348 if (op & 1)
10349 gen_swap_half(tmp2);
10350 gen_smul_dual(tmp, tmp2);
10351 if (op & 0x10) {
10352 tcg_gen_sub_i32(tmp, tmp, tmp2);
10353 } else {
10354 tcg_gen_add_i32(tmp, tmp, tmp2);
10356 tcg_temp_free_i32(tmp2);
10357 /* BUGFIX */
10358 tmp64 = tcg_temp_new_i64();
10359 tcg_gen_ext_i32_i64(tmp64, tmp);
10360 tcg_temp_free_i32(tmp);
10361 gen_addq(s, tmp64, rs, rd);
10362 gen_storeq_reg(s, rs, rd, tmp64);
10363 tcg_temp_free_i64(tmp64);
10364 } else {
10365 if (op & 0x20) {
10366 /* Unsigned 64-bit multiply */
10367 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10368 } else {
10369 if (op & 8) {
10370 /* smlalxy */
10371 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10372 tcg_temp_free_i32(tmp2);
10373 tcg_temp_free_i32(tmp);
10374 goto illegal_op;
10376 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10377 tcg_temp_free_i32(tmp2);
10378 tmp64 = tcg_temp_new_i64();
10379 tcg_gen_ext_i32_i64(tmp64, tmp);
10380 tcg_temp_free_i32(tmp);
10381 } else {
10382 /* Signed 64-bit multiply */
10383 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10386 if (op & 4) {
10387 /* umaal */
10388 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10389 tcg_temp_free_i64(tmp64);
10390 goto illegal_op;
10392 gen_addq_lo(s, tmp64, rs);
10393 gen_addq_lo(s, tmp64, rd);
10394 } else if (op & 0x40) {
10395 /* 64-bit accumulate. */
10396 gen_addq(s, tmp64, rs, rd);
10398 gen_storeq_reg(s, rs, rd, tmp64);
10399 tcg_temp_free_i64(tmp64);
10401 break;
10403 break;
10404 case 6: case 7: case 14: case 15:
10405 /* Coprocessor. */
10406 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10407 /* We don't currently implement M profile FP support,
10408 * so this entire space should give a NOCP fault.
10410 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10411 default_exception_el(s));
10412 break;
10414 if (((insn >> 24) & 3) == 3) {
10415 /* Translate into the equivalent ARM encoding. */
10416 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10417 if (disas_neon_data_insn(s, insn)) {
10418 goto illegal_op;
10420 } else if (((insn >> 8) & 0xe) == 10) {
10421 if (disas_vfp_insn(s, insn)) {
10422 goto illegal_op;
10424 } else {
10425 if (insn & (1 << 28))
10426 goto illegal_op;
10427 if (disas_coproc_insn(s, insn)) {
10428 goto illegal_op;
10431 break;
10432 case 8: case 9: case 10: case 11:
10433 if (insn & (1 << 15)) {
10434 /* Branches, misc control. */
10435 if (insn & 0x5000) {
10436 /* Unconditional branch. */
10437 /* signextend(hw1[10:0]) -> offset[:12]. */
10438 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10439 /* hw1[10:0] -> offset[11:1]. */
10440 offset |= (insn & 0x7ff) << 1;
10441 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10442 offset[24:22] already have the same value because of the
10443 sign extension above. */
10444 offset ^= ((~insn) & (1 << 13)) << 10;
10445 offset ^= ((~insn) & (1 << 11)) << 11;
10447 if (insn & (1 << 14)) {
10448 /* Branch and link. */
10449 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10452 offset += s->pc;
10453 if (insn & (1 << 12)) {
10454 /* b/bl */
10455 gen_jmp(s, offset);
10456 } else {
10457 /* blx */
10458 offset &= ~(uint32_t)2;
10459 /* thumb2 bx, no need to check */
10460 gen_bx_im(s, offset);
10462 } else if (((insn >> 23) & 7) == 7) {
10463 /* Misc control */
10464 if (insn & (1 << 13))
10465 goto illegal_op;
10467 if (insn & (1 << 26)) {
10468 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10469 goto illegal_op;
10471 if (!(insn & (1 << 20))) {
10472 /* Hypervisor call (v7) */
10473 int imm16 = extract32(insn, 16, 4) << 12
10474 | extract32(insn, 0, 12);
10475 ARCH(7);
10476 if (IS_USER(s)) {
10477 goto illegal_op;
10479 gen_hvc(s, imm16);
10480 } else {
10481 /* Secure monitor call (v6+) */
10482 ARCH(6K);
10483 if (IS_USER(s)) {
10484 goto illegal_op;
10486 gen_smc(s);
10488 } else {
10489 op = (insn >> 20) & 7;
10490 switch (op) {
10491 case 0: /* msr cpsr. */
10492 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10493 tmp = load_reg(s, rn);
10494 /* the constant is the mask and SYSm fields */
10495 addr = tcg_const_i32(insn & 0xfff);
10496 gen_helper_v7m_msr(cpu_env, addr, tmp);
10497 tcg_temp_free_i32(addr);
10498 tcg_temp_free_i32(tmp);
10499 gen_lookup_tb(s);
10500 break;
10502 /* fall through */
10503 case 1: /* msr spsr. */
10504 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10505 goto illegal_op;
10508 if (extract32(insn, 5, 1)) {
10509 /* MSR (banked) */
10510 int sysm = extract32(insn, 8, 4) |
10511 (extract32(insn, 4, 1) << 4);
10512 int r = op & 1;
10514 gen_msr_banked(s, r, sysm, rm);
10515 break;
10518 /* MSR (for PSRs) */
10519 tmp = load_reg(s, rn);
10520 if (gen_set_psr(s,
10521 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10522 op == 1, tmp))
10523 goto illegal_op;
10524 break;
10525 case 2: /* cps, nop-hint. */
10526 if (((insn >> 8) & 7) == 0) {
10527 gen_nop_hint(s, insn & 0xff);
10529 /* Implemented as NOP in user mode. */
10530 if (IS_USER(s))
10531 break;
10532 offset = 0;
10533 imm = 0;
10534 if (insn & (1 << 10)) {
10535 if (insn & (1 << 7))
10536 offset |= CPSR_A;
10537 if (insn & (1 << 6))
10538 offset |= CPSR_I;
10539 if (insn & (1 << 5))
10540 offset |= CPSR_F;
10541 if (insn & (1 << 9))
10542 imm = CPSR_A | CPSR_I | CPSR_F;
10544 if (insn & (1 << 8)) {
10545 offset |= 0x1f;
10546 imm |= (insn & 0x1f);
10548 if (offset) {
10549 gen_set_psr_im(s, offset, 0, imm);
10551 break;
10552 case 3: /* Special control operations. */
10553 ARCH(7);
10554 op = (insn >> 4) & 0xf;
10555 switch (op) {
10556 case 2: /* clrex */
10557 gen_clrex(s);
10558 break;
10559 case 4: /* dsb */
10560 case 5: /* dmb */
10561 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10562 break;
10563 case 6: /* isb */
10564 /* We need to break the TB after this insn
10565 * to execute self-modifying code correctly
10566 * and also to take any pending interrupts
10567 * immediately.
10569 gen_goto_tb(s, 0, s->pc & ~1);
10570 break;
10571 default:
10572 goto illegal_op;
10574 break;
10575 case 4: /* bxj */
10576 /* Trivial implementation equivalent to bx.
10577 * This instruction doesn't exist at all for M-profile.
10579 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10580 goto illegal_op;
10582 tmp = load_reg(s, rn);
10583 gen_bx(s, tmp);
10584 break;
10585 case 5: /* Exception return. */
10586 if (IS_USER(s)) {
10587 goto illegal_op;
10589 if (rn != 14 || rd != 15) {
10590 goto illegal_op;
10592 tmp = load_reg(s, rn);
10593 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10594 gen_exception_return(s, tmp);
10595 break;
10596 case 6: /* MRS */
10597 if (extract32(insn, 5, 1) &&
10598 !arm_dc_feature(s, ARM_FEATURE_M)) {
10599 /* MRS (banked) */
10600 int sysm = extract32(insn, 16, 4) |
10601 (extract32(insn, 4, 1) << 4);
10603 gen_mrs_banked(s, 0, sysm, rd);
10604 break;
10607 if (extract32(insn, 16, 4) != 0xf) {
10608 goto illegal_op;
10610 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10611 extract32(insn, 0, 8) != 0) {
10612 goto illegal_op;
10615 /* mrs cpsr */
10616 tmp = tcg_temp_new_i32();
10617 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10618 addr = tcg_const_i32(insn & 0xff);
10619 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10620 tcg_temp_free_i32(addr);
10621 } else {
10622 gen_helper_cpsr_read(tmp, cpu_env);
10624 store_reg(s, rd, tmp);
10625 break;
10626 case 7: /* MRS */
10627 if (extract32(insn, 5, 1) &&
10628 !arm_dc_feature(s, ARM_FEATURE_M)) {
10629 /* MRS (banked) */
10630 int sysm = extract32(insn, 16, 4) |
10631 (extract32(insn, 4, 1) << 4);
10633 gen_mrs_banked(s, 1, sysm, rd);
10634 break;
10637 /* mrs spsr. */
10638 /* Not accessible in user mode. */
10639 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10640 goto illegal_op;
10643 if (extract32(insn, 16, 4) != 0xf ||
10644 extract32(insn, 0, 8) != 0) {
10645 goto illegal_op;
10648 tmp = load_cpu_field(spsr);
10649 store_reg(s, rd, tmp);
10650 break;
10653 } else {
10654 /* Conditional branch. */
10655 op = (insn >> 22) & 0xf;
10656 /* Generate a conditional jump to next instruction. */
10657 s->condlabel = gen_new_label();
10658 arm_gen_test_cc(op ^ 1, s->condlabel);
10659 s->condjmp = 1;
10661 /* offset[11:1] = insn[10:0] */
10662 offset = (insn & 0x7ff) << 1;
10663 /* offset[17:12] = insn[21:16]. */
10664 offset |= (insn & 0x003f0000) >> 4;
10665 /* offset[31:20] = insn[26]. */
10666 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10667 /* offset[18] = insn[13]. */
10668 offset |= (insn & (1 << 13)) << 5;
10669 /* offset[19] = insn[11]. */
10670 offset |= (insn & (1 << 11)) << 8;
10672 /* jump to the offset */
10673 gen_jmp(s, s->pc + offset);
10675 } else {
10676 /* Data processing immediate. */
10677 if (insn & (1 << 25)) {
10678 if (insn & (1 << 24)) {
10679 if (insn & (1 << 20))
10680 goto illegal_op;
10681 /* Bitfield/Saturate. */
10682 op = (insn >> 21) & 7;
10683 imm = insn & 0x1f;
10684 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10685 if (rn == 15) {
10686 tmp = tcg_temp_new_i32();
10687 tcg_gen_movi_i32(tmp, 0);
10688 } else {
10689 tmp = load_reg(s, rn);
10691 switch (op) {
10692 case 2: /* Signed bitfield extract. */
10693 imm++;
10694 if (shift + imm > 32)
10695 goto illegal_op;
10696 if (imm < 32) {
10697 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10699 break;
10700 case 6: /* Unsigned bitfield extract. */
10701 imm++;
10702 if (shift + imm > 32)
10703 goto illegal_op;
10704 if (imm < 32) {
10705 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10707 break;
10708 case 3: /* Bitfield insert/clear. */
10709 if (imm < shift)
10710 goto illegal_op;
10711 imm = imm + 1 - shift;
10712 if (imm != 32) {
10713 tmp2 = load_reg(s, rd);
10714 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10715 tcg_temp_free_i32(tmp2);
10717 break;
10718 case 7:
10719 goto illegal_op;
10720 default: /* Saturate. */
10721 if (shift) {
10722 if (op & 1)
10723 tcg_gen_sari_i32(tmp, tmp, shift);
10724 else
10725 tcg_gen_shli_i32(tmp, tmp, shift);
10727 tmp2 = tcg_const_i32(imm);
10728 if (op & 4) {
10729 /* Unsigned. */
10730 if ((op & 1) && shift == 0) {
10731 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10732 tcg_temp_free_i32(tmp);
10733 tcg_temp_free_i32(tmp2);
10734 goto illegal_op;
10736 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10737 } else {
10738 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10740 } else {
10741 /* Signed. */
10742 if ((op & 1) && shift == 0) {
10743 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10744 tcg_temp_free_i32(tmp);
10745 tcg_temp_free_i32(tmp2);
10746 goto illegal_op;
10748 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10749 } else {
10750 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10753 tcg_temp_free_i32(tmp2);
10754 break;
10756 store_reg(s, rd, tmp);
10757 } else {
10758 imm = ((insn & 0x04000000) >> 15)
10759 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10760 if (insn & (1 << 22)) {
10761 /* 16-bit immediate. */
10762 imm |= (insn >> 4) & 0xf000;
10763 if (insn & (1 << 23)) {
10764 /* movt */
10765 tmp = load_reg(s, rd);
10766 tcg_gen_ext16u_i32(tmp, tmp);
10767 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10768 } else {
10769 /* movw */
10770 tmp = tcg_temp_new_i32();
10771 tcg_gen_movi_i32(tmp, imm);
10773 } else {
10774 /* Add/sub 12-bit immediate. */
10775 if (rn == 15) {
10776 offset = s->pc & ~(uint32_t)3;
10777 if (insn & (1 << 23))
10778 offset -= imm;
10779 else
10780 offset += imm;
10781 tmp = tcg_temp_new_i32();
10782 tcg_gen_movi_i32(tmp, offset);
10783 } else {
10784 tmp = load_reg(s, rn);
10785 if (insn & (1 << 23))
10786 tcg_gen_subi_i32(tmp, tmp, imm);
10787 else
10788 tcg_gen_addi_i32(tmp, tmp, imm);
10791 store_reg(s, rd, tmp);
10793 } else {
10794 int shifter_out = 0;
10795 /* modified 12-bit immediate. */
10796 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10797 imm = (insn & 0xff);
10798 switch (shift) {
10799 case 0: /* XY */
10800 /* Nothing to do. */
10801 break;
10802 case 1: /* 00XY00XY */
10803 imm |= imm << 16;
10804 break;
10805 case 2: /* XY00XY00 */
10806 imm |= imm << 16;
10807 imm <<= 8;
10808 break;
10809 case 3: /* XYXYXYXY */
10810 imm |= imm << 16;
10811 imm |= imm << 8;
10812 break;
10813 default: /* Rotated constant. */
10814 shift = (shift << 1) | (imm >> 7);
10815 imm |= 0x80;
10816 imm = imm << (32 - shift);
10817 shifter_out = 1;
10818 break;
10820 tmp2 = tcg_temp_new_i32();
10821 tcg_gen_movi_i32(tmp2, imm);
10822 rn = (insn >> 16) & 0xf;
10823 if (rn == 15) {
10824 tmp = tcg_temp_new_i32();
10825 tcg_gen_movi_i32(tmp, 0);
10826 } else {
10827 tmp = load_reg(s, rn);
10829 op = (insn >> 21) & 0xf;
10830 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10831 shifter_out, tmp, tmp2))
10832 goto illegal_op;
10833 tcg_temp_free_i32(tmp2);
10834 rd = (insn >> 8) & 0xf;
10835 if (rd != 15) {
10836 store_reg(s, rd, tmp);
10837 } else {
10838 tcg_temp_free_i32(tmp);
10842 break;
10843 case 12: /* Load/store single data item. */
10845 int postinc = 0;
10846 int writeback = 0;
10847 int memidx;
10848 ISSInfo issinfo;
10850 if ((insn & 0x01100000) == 0x01000000) {
10851 if (disas_neon_ls_insn(s, insn)) {
10852 goto illegal_op;
10854 break;
10856 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10857 if (rs == 15) {
10858 if (!(insn & (1 << 20))) {
10859 goto illegal_op;
10861 if (op != 2) {
10862 /* Byte or halfword load space with dest == r15 : memory hints.
10863 * Catch them early so we don't emit pointless addressing code.
10864 * This space is a mix of:
10865 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10866 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10867 * cores)
10868 * unallocated hints, which must be treated as NOPs
10869 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10870 * which is easiest for the decoding logic
10871 * Some space which must UNDEF
10873 int op1 = (insn >> 23) & 3;
10874 int op2 = (insn >> 6) & 0x3f;
10875 if (op & 2) {
10876 goto illegal_op;
10878 if (rn == 15) {
10879 /* UNPREDICTABLE, unallocated hint or
10880 * PLD/PLDW/PLI (literal)
10882 return 0;
10884 if (op1 & 1) {
10885 return 0; /* PLD/PLDW/PLI or unallocated hint */
10887 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10888 return 0; /* PLD/PLDW/PLI or unallocated hint */
10890 /* UNDEF space, or an UNPREDICTABLE */
10891 return 1;
10894 memidx = get_mem_index(s);
10895 if (rn == 15) {
10896 addr = tcg_temp_new_i32();
10897 /* PC relative. */
10898 /* s->pc has already been incremented by 4. */
10899 imm = s->pc & 0xfffffffc;
10900 if (insn & (1 << 23))
10901 imm += insn & 0xfff;
10902 else
10903 imm -= insn & 0xfff;
10904 tcg_gen_movi_i32(addr, imm);
10905 } else {
10906 addr = load_reg(s, rn);
10907 if (insn & (1 << 23)) {
10908 /* Positive offset. */
10909 imm = insn & 0xfff;
10910 tcg_gen_addi_i32(addr, addr, imm);
10911 } else {
10912 imm = insn & 0xff;
10913 switch ((insn >> 8) & 0xf) {
10914 case 0x0: /* Shifted Register. */
10915 shift = (insn >> 4) & 0xf;
10916 if (shift > 3) {
10917 tcg_temp_free_i32(addr);
10918 goto illegal_op;
10920 tmp = load_reg(s, rm);
10921 if (shift)
10922 tcg_gen_shli_i32(tmp, tmp, shift);
10923 tcg_gen_add_i32(addr, addr, tmp);
10924 tcg_temp_free_i32(tmp);
10925 break;
10926 case 0xc: /* Negative offset. */
10927 tcg_gen_addi_i32(addr, addr, -imm);
10928 break;
10929 case 0xe: /* User privilege. */
10930 tcg_gen_addi_i32(addr, addr, imm);
10931 memidx = get_a32_user_mem_index(s);
10932 break;
10933 case 0x9: /* Post-decrement. */
10934 imm = -imm;
10935 /* Fall through. */
10936 case 0xb: /* Post-increment. */
10937 postinc = 1;
10938 writeback = 1;
10939 break;
10940 case 0xd: /* Pre-decrement. */
10941 imm = -imm;
10942 /* Fall through. */
10943 case 0xf: /* Pre-increment. */
10944 tcg_gen_addi_i32(addr, addr, imm);
10945 writeback = 1;
10946 break;
10947 default:
10948 tcg_temp_free_i32(addr);
10949 goto illegal_op;
10954 issinfo = writeback ? ISSInvalid : rs;
10956 if (insn & (1 << 20)) {
10957 /* Load. */
10958 tmp = tcg_temp_new_i32();
10959 switch (op) {
10960 case 0:
10961 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10962 break;
10963 case 4:
10964 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10965 break;
10966 case 1:
10967 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10968 break;
10969 case 5:
10970 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10971 break;
10972 case 2:
10973 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10974 break;
10975 default:
10976 tcg_temp_free_i32(tmp);
10977 tcg_temp_free_i32(addr);
10978 goto illegal_op;
10980 if (rs == 15) {
10981 gen_bx_excret(s, tmp);
10982 } else {
10983 store_reg(s, rs, tmp);
10985 } else {
10986 /* Store. */
10987 tmp = load_reg(s, rs);
10988 switch (op) {
10989 case 0:
10990 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10991 break;
10992 case 1:
10993 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10994 break;
10995 case 2:
10996 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10997 break;
10998 default:
10999 tcg_temp_free_i32(tmp);
11000 tcg_temp_free_i32(addr);
11001 goto illegal_op;
11003 tcg_temp_free_i32(tmp);
11005 if (postinc)
11006 tcg_gen_addi_i32(addr, addr, imm);
11007 if (writeback) {
11008 store_reg(s, rn, addr);
11009 } else {
11010 tcg_temp_free_i32(addr);
11013 break;
11014 default:
11015 goto illegal_op;
11017 return 0;
11018 illegal_op:
11019 return 1;
11022 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
11024 uint32_t val, insn, op, rm, rn, rd, shift, cond;
11025 int32_t offset;
11026 int i;
11027 TCGv_i32 tmp;
11028 TCGv_i32 tmp2;
11029 TCGv_i32 addr;
11031 if (s->condexec_mask) {
11032 cond = s->condexec_cond;
11033 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
11034 s->condlabel = gen_new_label();
11035 arm_gen_test_cc(cond ^ 1, s->condlabel);
11036 s->condjmp = 1;
11040 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11041 s->pc += 2;
11043 switch (insn >> 12) {
11044 case 0: case 1:
11046 rd = insn & 7;
11047 op = (insn >> 11) & 3;
11048 if (op == 3) {
11049 /* add/subtract */
11050 rn = (insn >> 3) & 7;
11051 tmp = load_reg(s, rn);
11052 if (insn & (1 << 10)) {
11053 /* immediate */
11054 tmp2 = tcg_temp_new_i32();
11055 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11056 } else {
11057 /* reg */
11058 rm = (insn >> 6) & 7;
11059 tmp2 = load_reg(s, rm);
11061 if (insn & (1 << 9)) {
11062 if (s->condexec_mask)
11063 tcg_gen_sub_i32(tmp, tmp, tmp2);
11064 else
11065 gen_sub_CC(tmp, tmp, tmp2);
11066 } else {
11067 if (s->condexec_mask)
11068 tcg_gen_add_i32(tmp, tmp, tmp2);
11069 else
11070 gen_add_CC(tmp, tmp, tmp2);
11072 tcg_temp_free_i32(tmp2);
11073 store_reg(s, rd, tmp);
11074 } else {
11075 /* shift immediate */
11076 rm = (insn >> 3) & 7;
11077 shift = (insn >> 6) & 0x1f;
11078 tmp = load_reg(s, rm);
11079 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11080 if (!s->condexec_mask)
11081 gen_logic_CC(tmp);
11082 store_reg(s, rd, tmp);
11084 break;
11085 case 2: case 3:
11086 /* arithmetic large immediate */
11087 op = (insn >> 11) & 3;
11088 rd = (insn >> 8) & 0x7;
11089 if (op == 0) { /* mov */
11090 tmp = tcg_temp_new_i32();
11091 tcg_gen_movi_i32(tmp, insn & 0xff);
11092 if (!s->condexec_mask)
11093 gen_logic_CC(tmp);
11094 store_reg(s, rd, tmp);
11095 } else {
11096 tmp = load_reg(s, rd);
11097 tmp2 = tcg_temp_new_i32();
11098 tcg_gen_movi_i32(tmp2, insn & 0xff);
11099 switch (op) {
11100 case 1: /* cmp */
11101 gen_sub_CC(tmp, tmp, tmp2);
11102 tcg_temp_free_i32(tmp);
11103 tcg_temp_free_i32(tmp2);
11104 break;
11105 case 2: /* add */
11106 if (s->condexec_mask)
11107 tcg_gen_add_i32(tmp, tmp, tmp2);
11108 else
11109 gen_add_CC(tmp, tmp, tmp2);
11110 tcg_temp_free_i32(tmp2);
11111 store_reg(s, rd, tmp);
11112 break;
11113 case 3: /* sub */
11114 if (s->condexec_mask)
11115 tcg_gen_sub_i32(tmp, tmp, tmp2);
11116 else
11117 gen_sub_CC(tmp, tmp, tmp2);
11118 tcg_temp_free_i32(tmp2);
11119 store_reg(s, rd, tmp);
11120 break;
11123 break;
11124 case 4:
11125 if (insn & (1 << 11)) {
11126 rd = (insn >> 8) & 7;
11127 /* load pc-relative. Bit 1 of PC is ignored. */
11128 val = s->pc + 2 + ((insn & 0xff) * 4);
11129 val &= ~(uint32_t)2;
11130 addr = tcg_temp_new_i32();
11131 tcg_gen_movi_i32(addr, val);
11132 tmp = tcg_temp_new_i32();
11133 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11134 rd | ISSIs16Bit);
11135 tcg_temp_free_i32(addr);
11136 store_reg(s, rd, tmp);
11137 break;
11139 if (insn & (1 << 10)) {
11140 /* data processing extended or blx */
11141 rd = (insn & 7) | ((insn >> 4) & 8);
11142 rm = (insn >> 3) & 0xf;
11143 op = (insn >> 8) & 3;
11144 switch (op) {
11145 case 0: /* add */
11146 tmp = load_reg(s, rd);
11147 tmp2 = load_reg(s, rm);
11148 tcg_gen_add_i32(tmp, tmp, tmp2);
11149 tcg_temp_free_i32(tmp2);
11150 store_reg(s, rd, tmp);
11151 break;
11152 case 1: /* cmp */
11153 tmp = load_reg(s, rd);
11154 tmp2 = load_reg(s, rm);
11155 gen_sub_CC(tmp, tmp, tmp2);
11156 tcg_temp_free_i32(tmp2);
11157 tcg_temp_free_i32(tmp);
11158 break;
11159 case 2: /* mov/cpy */
11160 tmp = load_reg(s, rm);
11161 store_reg(s, rd, tmp);
11162 break;
11163 case 3:/* branch [and link] exchange thumb register */
11164 tmp = load_reg(s, rm);
11165 if (insn & (1 << 7)) {
11166 ARCH(5);
11167 val = (uint32_t)s->pc | 1;
11168 tmp2 = tcg_temp_new_i32();
11169 tcg_gen_movi_i32(tmp2, val);
11170 store_reg(s, 14, tmp2);
11171 gen_bx(s, tmp);
11172 } else {
11173 /* Only BX works as exception-return, not BLX */
11174 gen_bx_excret(s, tmp);
11176 break;
11178 break;
11181 /* data processing register */
11182 rd = insn & 7;
11183 rm = (insn >> 3) & 7;
11184 op = (insn >> 6) & 0xf;
11185 if (op == 2 || op == 3 || op == 4 || op == 7) {
11186 /* the shift/rotate ops want the operands backwards */
11187 val = rm;
11188 rm = rd;
11189 rd = val;
11190 val = 1;
11191 } else {
11192 val = 0;
11195 if (op == 9) { /* neg */
11196 tmp = tcg_temp_new_i32();
11197 tcg_gen_movi_i32(tmp, 0);
11198 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11199 tmp = load_reg(s, rd);
11200 } else {
11201 TCGV_UNUSED_I32(tmp);
11204 tmp2 = load_reg(s, rm);
11205 switch (op) {
11206 case 0x0: /* and */
11207 tcg_gen_and_i32(tmp, tmp, tmp2);
11208 if (!s->condexec_mask)
11209 gen_logic_CC(tmp);
11210 break;
11211 case 0x1: /* eor */
11212 tcg_gen_xor_i32(tmp, tmp, tmp2);
11213 if (!s->condexec_mask)
11214 gen_logic_CC(tmp);
11215 break;
11216 case 0x2: /* lsl */
11217 if (s->condexec_mask) {
11218 gen_shl(tmp2, tmp2, tmp);
11219 } else {
11220 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11221 gen_logic_CC(tmp2);
11223 break;
11224 case 0x3: /* lsr */
11225 if (s->condexec_mask) {
11226 gen_shr(tmp2, tmp2, tmp);
11227 } else {
11228 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11229 gen_logic_CC(tmp2);
11231 break;
11232 case 0x4: /* asr */
11233 if (s->condexec_mask) {
11234 gen_sar(tmp2, tmp2, tmp);
11235 } else {
11236 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11237 gen_logic_CC(tmp2);
11239 break;
11240 case 0x5: /* adc */
11241 if (s->condexec_mask) {
11242 gen_adc(tmp, tmp2);
11243 } else {
11244 gen_adc_CC(tmp, tmp, tmp2);
11246 break;
11247 case 0x6: /* sbc */
11248 if (s->condexec_mask) {
11249 gen_sub_carry(tmp, tmp, tmp2);
11250 } else {
11251 gen_sbc_CC(tmp, tmp, tmp2);
11253 break;
11254 case 0x7: /* ror */
11255 if (s->condexec_mask) {
11256 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11257 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11258 } else {
11259 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11260 gen_logic_CC(tmp2);
11262 break;
11263 case 0x8: /* tst */
11264 tcg_gen_and_i32(tmp, tmp, tmp2);
11265 gen_logic_CC(tmp);
11266 rd = 16;
11267 break;
11268 case 0x9: /* neg */
11269 if (s->condexec_mask)
11270 tcg_gen_neg_i32(tmp, tmp2);
11271 else
11272 gen_sub_CC(tmp, tmp, tmp2);
11273 break;
11274 case 0xa: /* cmp */
11275 gen_sub_CC(tmp, tmp, tmp2);
11276 rd = 16;
11277 break;
11278 case 0xb: /* cmn */
11279 gen_add_CC(tmp, tmp, tmp2);
11280 rd = 16;
11281 break;
11282 case 0xc: /* orr */
11283 tcg_gen_or_i32(tmp, tmp, tmp2);
11284 if (!s->condexec_mask)
11285 gen_logic_CC(tmp);
11286 break;
11287 case 0xd: /* mul */
11288 tcg_gen_mul_i32(tmp, tmp, tmp2);
11289 if (!s->condexec_mask)
11290 gen_logic_CC(tmp);
11291 break;
11292 case 0xe: /* bic */
11293 tcg_gen_andc_i32(tmp, tmp, tmp2);
11294 if (!s->condexec_mask)
11295 gen_logic_CC(tmp);
11296 break;
11297 case 0xf: /* mvn */
11298 tcg_gen_not_i32(tmp2, tmp2);
11299 if (!s->condexec_mask)
11300 gen_logic_CC(tmp2);
11301 val = 1;
11302 rm = rd;
11303 break;
11305 if (rd != 16) {
11306 if (val) {
11307 store_reg(s, rm, tmp2);
11308 if (op != 0xf)
11309 tcg_temp_free_i32(tmp);
11310 } else {
11311 store_reg(s, rd, tmp);
11312 tcg_temp_free_i32(tmp2);
11314 } else {
11315 tcg_temp_free_i32(tmp);
11316 tcg_temp_free_i32(tmp2);
11318 break;
11320 case 5:
11321 /* load/store register offset. */
11322 rd = insn & 7;
11323 rn = (insn >> 3) & 7;
11324 rm = (insn >> 6) & 7;
11325 op = (insn >> 9) & 7;
11326 addr = load_reg(s, rn);
11327 tmp = load_reg(s, rm);
11328 tcg_gen_add_i32(addr, addr, tmp);
11329 tcg_temp_free_i32(tmp);
11331 if (op < 3) { /* store */
11332 tmp = load_reg(s, rd);
11333 } else {
11334 tmp = tcg_temp_new_i32();
11337 switch (op) {
11338 case 0: /* str */
11339 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11340 break;
11341 case 1: /* strh */
11342 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11343 break;
11344 case 2: /* strb */
11345 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11346 break;
11347 case 3: /* ldrsb */
11348 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11349 break;
11350 case 4: /* ldr */
11351 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11352 break;
11353 case 5: /* ldrh */
11354 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11355 break;
11356 case 6: /* ldrb */
11357 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11358 break;
11359 case 7: /* ldrsh */
11360 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11361 break;
11363 if (op >= 3) { /* load */
11364 store_reg(s, rd, tmp);
11365 } else {
11366 tcg_temp_free_i32(tmp);
11368 tcg_temp_free_i32(addr);
11369 break;
11371 case 6:
11372 /* load/store word immediate offset */
11373 rd = insn & 7;
11374 rn = (insn >> 3) & 7;
11375 addr = load_reg(s, rn);
11376 val = (insn >> 4) & 0x7c;
11377 tcg_gen_addi_i32(addr, addr, val);
11379 if (insn & (1 << 11)) {
11380 /* load */
11381 tmp = tcg_temp_new_i32();
11382 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11383 store_reg(s, rd, tmp);
11384 } else {
11385 /* store */
11386 tmp = load_reg(s, rd);
11387 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11388 tcg_temp_free_i32(tmp);
11390 tcg_temp_free_i32(addr);
11391 break;
11393 case 7:
11394 /* load/store byte immediate offset */
11395 rd = insn & 7;
11396 rn = (insn >> 3) & 7;
11397 addr = load_reg(s, rn);
11398 val = (insn >> 6) & 0x1f;
11399 tcg_gen_addi_i32(addr, addr, val);
11401 if (insn & (1 << 11)) {
11402 /* load */
11403 tmp = tcg_temp_new_i32();
11404 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11405 store_reg(s, rd, tmp);
11406 } else {
11407 /* store */
11408 tmp = load_reg(s, rd);
11409 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11410 tcg_temp_free_i32(tmp);
11412 tcg_temp_free_i32(addr);
11413 break;
11415 case 8:
11416 /* load/store halfword immediate offset */
11417 rd = insn & 7;
11418 rn = (insn >> 3) & 7;
11419 addr = load_reg(s, rn);
11420 val = (insn >> 5) & 0x3e;
11421 tcg_gen_addi_i32(addr, addr, val);
11423 if (insn & (1 << 11)) {
11424 /* load */
11425 tmp = tcg_temp_new_i32();
11426 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11427 store_reg(s, rd, tmp);
11428 } else {
11429 /* store */
11430 tmp = load_reg(s, rd);
11431 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11432 tcg_temp_free_i32(tmp);
11434 tcg_temp_free_i32(addr);
11435 break;
11437 case 9:
11438 /* load/store from stack */
11439 rd = (insn >> 8) & 7;
11440 addr = load_reg(s, 13);
11441 val = (insn & 0xff) * 4;
11442 tcg_gen_addi_i32(addr, addr, val);
11444 if (insn & (1 << 11)) {
11445 /* load */
11446 tmp = tcg_temp_new_i32();
11447 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11448 store_reg(s, rd, tmp);
11449 } else {
11450 /* store */
11451 tmp = load_reg(s, rd);
11452 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11453 tcg_temp_free_i32(tmp);
11455 tcg_temp_free_i32(addr);
11456 break;
11458 case 10:
11459 /* add to high reg */
11460 rd = (insn >> 8) & 7;
11461 if (insn & (1 << 11)) {
11462 /* SP */
11463 tmp = load_reg(s, 13);
11464 } else {
11465 /* PC. bit 1 is ignored. */
11466 tmp = tcg_temp_new_i32();
11467 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11469 val = (insn & 0xff) * 4;
11470 tcg_gen_addi_i32(tmp, tmp, val);
11471 store_reg(s, rd, tmp);
11472 break;
11474 case 11:
11475 /* misc */
11476 op = (insn >> 8) & 0xf;
11477 switch (op) {
11478 case 0:
11479 /* adjust stack pointer */
11480 tmp = load_reg(s, 13);
11481 val = (insn & 0x7f) * 4;
11482 if (insn & (1 << 7))
11483 val = -(int32_t)val;
11484 tcg_gen_addi_i32(tmp, tmp, val);
11485 store_reg(s, 13, tmp);
11486 break;
11488 case 2: /* sign/zero extend. */
11489 ARCH(6);
11490 rd = insn & 7;
11491 rm = (insn >> 3) & 7;
11492 tmp = load_reg(s, rm);
11493 switch ((insn >> 6) & 3) {
11494 case 0: gen_sxth(tmp); break;
11495 case 1: gen_sxtb(tmp); break;
11496 case 2: gen_uxth(tmp); break;
11497 case 3: gen_uxtb(tmp); break;
11499 store_reg(s, rd, tmp);
11500 break;
11501 case 4: case 5: case 0xc: case 0xd:
11502 /* push/pop */
11503 addr = load_reg(s, 13);
11504 if (insn & (1 << 8))
11505 offset = 4;
11506 else
11507 offset = 0;
11508 for (i = 0; i < 8; i++) {
11509 if (insn & (1 << i))
11510 offset += 4;
11512 if ((insn & (1 << 11)) == 0) {
11513 tcg_gen_addi_i32(addr, addr, -offset);
11515 for (i = 0; i < 8; i++) {
11516 if (insn & (1 << i)) {
11517 if (insn & (1 << 11)) {
11518 /* pop */
11519 tmp = tcg_temp_new_i32();
11520 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11521 store_reg(s, i, tmp);
11522 } else {
11523 /* push */
11524 tmp = load_reg(s, i);
11525 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11526 tcg_temp_free_i32(tmp);
11528 /* advance to the next address. */
11529 tcg_gen_addi_i32(addr, addr, 4);
11532 TCGV_UNUSED_I32(tmp);
11533 if (insn & (1 << 8)) {
11534 if (insn & (1 << 11)) {
11535 /* pop pc */
11536 tmp = tcg_temp_new_i32();
11537 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11538 /* don't set the pc until the rest of the instruction
11539 has completed */
11540 } else {
11541 /* push lr */
11542 tmp = load_reg(s, 14);
11543 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11544 tcg_temp_free_i32(tmp);
11546 tcg_gen_addi_i32(addr, addr, 4);
11548 if ((insn & (1 << 11)) == 0) {
11549 tcg_gen_addi_i32(addr, addr, -offset);
11551 /* write back the new stack pointer */
11552 store_reg(s, 13, addr);
11553 /* set the new PC value */
11554 if ((insn & 0x0900) == 0x0900) {
11555 store_reg_from_load(s, 15, tmp);
11557 break;
11559 case 1: case 3: case 9: case 11: /* czb */
11560 rm = insn & 7;
11561 tmp = load_reg(s, rm);
11562 s->condlabel = gen_new_label();
11563 s->condjmp = 1;
11564 if (insn & (1 << 11))
11565 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11566 else
11567 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11568 tcg_temp_free_i32(tmp);
11569 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11570 val = (uint32_t)s->pc + 2;
11571 val += offset;
11572 gen_jmp(s, val);
11573 break;
11575 case 15: /* IT, nop-hint. */
11576 if ((insn & 0xf) == 0) {
11577 gen_nop_hint(s, (insn >> 4) & 0xf);
11578 break;
11580 /* If Then. */
11581 s->condexec_cond = (insn >> 4) & 0xe;
11582 s->condexec_mask = insn & 0x1f;
11583 /* No actual code generated for this insn, just setup state. */
11584 break;
11586 case 0xe: /* bkpt */
11588 int imm8 = extract32(insn, 0, 8);
11589 ARCH(5);
11590 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11591 default_exception_el(s));
11592 break;
11595 case 0xa: /* rev, and hlt */
11597 int op1 = extract32(insn, 6, 2);
11599 if (op1 == 2) {
11600 /* HLT */
11601 int imm6 = extract32(insn, 0, 6);
11603 gen_hlt(s, imm6);
11604 break;
11607 /* Otherwise this is rev */
11608 ARCH(6);
11609 rn = (insn >> 3) & 0x7;
11610 rd = insn & 0x7;
11611 tmp = load_reg(s, rn);
11612 switch (op1) {
11613 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11614 case 1: gen_rev16(tmp); break;
11615 case 3: gen_revsh(tmp); break;
11616 default:
11617 g_assert_not_reached();
11619 store_reg(s, rd, tmp);
11620 break;
11623 case 6:
11624 switch ((insn >> 5) & 7) {
11625 case 2:
11626 /* setend */
11627 ARCH(6);
11628 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11629 gen_helper_setend(cpu_env);
11630 s->is_jmp = DISAS_UPDATE;
11632 break;
11633 case 3:
11634 /* cps */
11635 ARCH(6);
11636 if (IS_USER(s)) {
11637 break;
11639 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11640 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11641 /* FAULTMASK */
11642 if (insn & 1) {
11643 addr = tcg_const_i32(19);
11644 gen_helper_v7m_msr(cpu_env, addr, tmp);
11645 tcg_temp_free_i32(addr);
11647 /* PRIMASK */
11648 if (insn & 2) {
11649 addr = tcg_const_i32(16);
11650 gen_helper_v7m_msr(cpu_env, addr, tmp);
11651 tcg_temp_free_i32(addr);
11653 tcg_temp_free_i32(tmp);
11654 gen_lookup_tb(s);
11655 } else {
11656 if (insn & (1 << 4)) {
11657 shift = CPSR_A | CPSR_I | CPSR_F;
11658 } else {
11659 shift = 0;
11661 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11663 break;
11664 default:
11665 goto undef;
11667 break;
11669 default:
11670 goto undef;
11672 break;
11674 case 12:
11676 /* load/store multiple */
11677 TCGv_i32 loaded_var;
11678 TCGV_UNUSED_I32(loaded_var);
11679 rn = (insn >> 8) & 0x7;
11680 addr = load_reg(s, rn);
11681 for (i = 0; i < 8; i++) {
11682 if (insn & (1 << i)) {
11683 if (insn & (1 << 11)) {
11684 /* load */
11685 tmp = tcg_temp_new_i32();
11686 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11687 if (i == rn) {
11688 loaded_var = tmp;
11689 } else {
11690 store_reg(s, i, tmp);
11692 } else {
11693 /* store */
11694 tmp = load_reg(s, i);
11695 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11696 tcg_temp_free_i32(tmp);
11698 /* advance to the next address */
11699 tcg_gen_addi_i32(addr, addr, 4);
11702 if ((insn & (1 << rn)) == 0) {
11703 /* base reg not in list: base register writeback */
11704 store_reg(s, rn, addr);
11705 } else {
11706 /* base reg in list: if load, complete it now */
11707 if (insn & (1 << 11)) {
11708 store_reg(s, rn, loaded_var);
11710 tcg_temp_free_i32(addr);
11712 break;
11714 case 13:
11715 /* conditional branch or swi */
11716 cond = (insn >> 8) & 0xf;
11717 if (cond == 0xe)
11718 goto undef;
11720 if (cond == 0xf) {
11721 /* swi */
11722 gen_set_pc_im(s, s->pc);
11723 s->svc_imm = extract32(insn, 0, 8);
11724 s->is_jmp = DISAS_SWI;
11725 break;
11727 /* generate a conditional jump to next instruction */
11728 s->condlabel = gen_new_label();
11729 arm_gen_test_cc(cond ^ 1, s->condlabel);
11730 s->condjmp = 1;
11732 /* jump to the offset */
11733 val = (uint32_t)s->pc + 2;
11734 offset = ((int32_t)insn << 24) >> 24;
11735 val += offset << 1;
11736 gen_jmp(s, val);
11737 break;
11739 case 14:
11740 if (insn & (1 << 11)) {
11741 if (disas_thumb2_insn(env, s, insn))
11742 goto undef32;
11743 break;
11745 /* unconditional branch */
11746 val = (uint32_t)s->pc;
11747 offset = ((int32_t)insn << 21) >> 21;
11748 val += (offset << 1) + 2;
11749 gen_jmp(s, val);
11750 break;
11752 case 15:
11753 if (disas_thumb2_insn(env, s, insn))
11754 goto undef32;
11755 break;
11757 return;
11758 undef32:
11759 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11760 default_exception_el(s));
11761 return;
11762 illegal_op:
11763 undef:
11764 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11765 default_exception_el(s));
11768 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11770 /* Return true if the insn at dc->pc might cross a page boundary.
11771 * (False positives are OK, false negatives are not.)
11773 uint16_t insn;
11775 if ((s->pc & 3) == 0) {
11776 /* At a 4-aligned address we can't be crossing a page */
11777 return false;
11780 /* This must be a Thumb insn */
11781 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11783 if ((insn >> 11) >= 0x1d) {
11784 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11785 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11786 * end up actually treating this as two 16-bit insns (see the
11787 * code at the start of disas_thumb2_insn()) but we don't bother
11788 * to check for that as it is unlikely, and false positives here
11789 * are harmless.
11791 return true;
11793 /* Definitely a 16-bit insn, can't be crossing a page. */
11794 return false;
11797 /* generate intermediate code for basic block 'tb'. */
11798 void gen_intermediate_code(CPUState *cs, TranslationBlock *tb)
11800 CPUARMState *env = cs->env_ptr;
11801 ARMCPU *cpu = arm_env_get_cpu(env);
11802 DisasContext dc1, *dc = &dc1;
11803 target_ulong pc_start;
11804 target_ulong next_page_start;
11805 int num_insns;
11806 int max_insns;
11807 bool end_of_page;
11809 /* generate intermediate code */
11811 /* The A64 decoder has its own top level loop, because it doesn't need
11812 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11814 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11815 gen_intermediate_code_a64(cs, tb);
11816 return;
11819 pc_start = tb->pc;
11821 dc->tb = tb;
11823 dc->is_jmp = DISAS_NEXT;
11824 dc->pc = pc_start;
11825 dc->singlestep_enabled = cs->singlestep_enabled;
11826 dc->condjmp = 0;
11828 dc->aarch64 = 0;
11829 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11830 * there is no secure EL1, so we route exceptions to EL3.
11832 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11833 !arm_el_is_aa64(env, 3);
11834 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11835 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11836 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11837 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11838 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11839 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(tb->flags));
11840 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11841 #if !defined(CONFIG_USER_ONLY)
11842 dc->user = (dc->current_el == 0);
11843 #endif
11844 dc->ns = ARM_TBFLAG_NS(tb->flags);
11845 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11846 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11847 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11848 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11849 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11850 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(tb->flags);
11851 dc->cp_regs = cpu->cp_regs;
11852 dc->features = env->features;
11854 /* Single step state. The code-generation logic here is:
11855 * SS_ACTIVE == 0:
11856 * generate code with no special handling for single-stepping (except
11857 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11858 * this happens anyway because those changes are all system register or
11859 * PSTATE writes).
11860 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11861 * emit code for one insn
11862 * emit code to clear PSTATE.SS
11863 * emit code to generate software step exception for completed step
11864 * end TB (as usual for having generated an exception)
11865 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11866 * emit code to generate a software step exception
11867 * end the TB
11869 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11870 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11871 dc->is_ldex = false;
11872 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11874 cpu_F0s = tcg_temp_new_i32();
11875 cpu_F1s = tcg_temp_new_i32();
11876 cpu_F0d = tcg_temp_new_i64();
11877 cpu_F1d = tcg_temp_new_i64();
11878 cpu_V0 = cpu_F0d;
11879 cpu_V1 = cpu_F1d;
11880 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11881 cpu_M0 = tcg_temp_new_i64();
11882 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11883 num_insns = 0;
11884 max_insns = tb->cflags & CF_COUNT_MASK;
11885 if (max_insns == 0) {
11886 max_insns = CF_COUNT_MASK;
11888 if (max_insns > TCG_MAX_INSNS) {
11889 max_insns = TCG_MAX_INSNS;
11892 gen_tb_start(tb);
11894 tcg_clear_temp_count();
11896 /* A note on handling of the condexec (IT) bits:
11898 * We want to avoid the overhead of having to write the updated condexec
11899 * bits back to the CPUARMState for every instruction in an IT block. So:
11900 * (1) if the condexec bits are not already zero then we write
11901 * zero back into the CPUARMState now. This avoids complications trying
11902 * to do it at the end of the block. (For example if we don't do this
11903 * it's hard to identify whether we can safely skip writing condexec
11904 * at the end of the TB, which we definitely want to do for the case
11905 * where a TB doesn't do anything with the IT state at all.)
11906 * (2) if we are going to leave the TB then we call gen_set_condexec()
11907 * which will write the correct value into CPUARMState if zero is wrong.
11908 * This is done both for leaving the TB at the end, and for leaving
11909 * it because of an exception we know will happen, which is done in
11910 * gen_exception_insn(). The latter is necessary because we need to
11911 * leave the TB with the PC/IT state just prior to execution of the
11912 * instruction which caused the exception.
11913 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11914 * then the CPUARMState will be wrong and we need to reset it.
11915 * This is handled in the same way as restoration of the
11916 * PC in these situations; we save the value of the condexec bits
11917 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11918 * then uses this to restore them after an exception.
11920 * Note that there are no instructions which can read the condexec
11921 * bits, and none which can write non-static values to them, so
11922 * we don't need to care about whether CPUARMState is correct in the
11923 * middle of a TB.
11926 /* Reset the conditional execution bits immediately. This avoids
11927 complications trying to do it at the end of the block. */
11928 if (dc->condexec_mask || dc->condexec_cond)
11930 TCGv_i32 tmp = tcg_temp_new_i32();
11931 tcg_gen_movi_i32(tmp, 0);
11932 store_cpu_field(tmp, condexec_bits);
11934 do {
11935 dc->insn_start_idx = tcg_op_buf_count();
11936 tcg_gen_insn_start(dc->pc,
11937 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11939 num_insns++;
11941 #ifdef CONFIG_USER_ONLY
11942 /* Intercept jump to the magic kernel page. */
11943 if (dc->pc >= 0xffff0000) {
11944 /* We always get here via a jump, so know we are not in a
11945 conditional execution block. */
11946 gen_exception_internal(EXCP_KERNEL_TRAP);
11947 dc->is_jmp = DISAS_EXC;
11948 break;
11950 #endif
11952 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11953 CPUBreakpoint *bp;
11954 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11955 if (bp->pc == dc->pc) {
11956 if (bp->flags & BP_CPU) {
11957 gen_set_condexec(dc);
11958 gen_set_pc_im(dc, dc->pc);
11959 gen_helper_check_breakpoints(cpu_env);
11960 /* End the TB early; it's likely not going to be executed */
11961 dc->is_jmp = DISAS_UPDATE;
11962 } else {
11963 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11964 /* The address covered by the breakpoint must be
11965 included in [tb->pc, tb->pc + tb->size) in order
11966 to for it to be properly cleared -- thus we
11967 increment the PC here so that the logic setting
11968 tb->size below does the right thing. */
11969 /* TODO: Advance PC by correct instruction length to
11970 * avoid disassembler error messages */
11971 dc->pc += 2;
11972 goto done_generating;
11974 break;
11979 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11980 gen_io_start();
11983 if (dc->ss_active && !dc->pstate_ss) {
11984 /* Singlestep state is Active-pending.
11985 * If we're in this state at the start of a TB then either
11986 * a) we just took an exception to an EL which is being debugged
11987 * and this is the first insn in the exception handler
11988 * b) debug exceptions were masked and we just unmasked them
11989 * without changing EL (eg by clearing PSTATE.D)
11990 * In either case we're going to take a swstep exception in the
11991 * "did not step an insn" case, and so the syndrome ISV and EX
11992 * bits should be zero.
11994 assert(num_insns == 1);
11995 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11996 default_exception_el(dc));
11997 goto done_generating;
12000 if (dc->thumb) {
12001 disas_thumb_insn(env, dc);
12002 if (dc->condexec_mask) {
12003 dc->condexec_cond = (dc->condexec_cond & 0xe)
12004 | ((dc->condexec_mask >> 4) & 1);
12005 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12006 if (dc->condexec_mask == 0) {
12007 dc->condexec_cond = 0;
12010 } else {
12011 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12012 dc->pc += 4;
12013 disas_arm_insn(dc, insn);
12016 if (dc->condjmp && !dc->is_jmp) {
12017 gen_set_label(dc->condlabel);
12018 dc->condjmp = 0;
12021 if (tcg_check_temp_count()) {
12022 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
12023 dc->pc);
12026 /* Translation stops when a conditional branch is encountered.
12027 * Otherwise the subsequent code could get translated several times.
12028 * Also stop translation when a page boundary is reached. This
12029 * ensures prefetch aborts occur at the right place. */
12031 /* We want to stop the TB if the next insn starts in a new page,
12032 * or if it spans between this page and the next. This means that
12033 * if we're looking at the last halfword in the page we need to
12034 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12035 * or a 32-bit Thumb insn (which won't).
12036 * This is to avoid generating a silly TB with a single 16-bit insn
12037 * in it at the end of this page (which would execute correctly
12038 * but isn't very efficient).
12040 end_of_page = (dc->pc >= next_page_start) ||
12041 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
12043 } while (!dc->is_jmp && !tcg_op_buf_full() &&
12044 !is_singlestepping(dc) &&
12045 !singlestep &&
12046 !end_of_page &&
12047 num_insns < max_insns);
12049 if (tb->cflags & CF_LAST_IO) {
12050 if (dc->condjmp) {
12051 /* FIXME: This can theoretically happen with self-modifying
12052 code. */
12053 cpu_abort(cs, "IO on conditional branch instruction");
12055 gen_io_end();
12058 /* At this stage dc->condjmp will only be set when the skipped
12059 instruction was a conditional branch or trap, and the PC has
12060 already been written. */
12061 gen_set_condexec(dc);
12062 if (dc->is_jmp == DISAS_BX_EXCRET) {
12063 /* Exception return branches need some special case code at the
12064 * end of the TB, which is complex enough that it has to
12065 * handle the single-step vs not and the condition-failed
12066 * insn codepath itself.
12068 gen_bx_excret_final_code(dc);
12069 } else if (unlikely(is_singlestepping(dc))) {
12070 /* Unconditional and "condition passed" instruction codepath. */
12071 switch (dc->is_jmp) {
12072 case DISAS_SWI:
12073 gen_ss_advance(dc);
12074 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12075 default_exception_el(dc));
12076 break;
12077 case DISAS_HVC:
12078 gen_ss_advance(dc);
12079 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12080 break;
12081 case DISAS_SMC:
12082 gen_ss_advance(dc);
12083 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12084 break;
12085 case DISAS_NEXT:
12086 case DISAS_UPDATE:
12087 gen_set_pc_im(dc, dc->pc);
12088 /* fall through */
12089 default:
12090 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12091 gen_singlestep_exception(dc);
12093 } else {
12094 /* While branches must always occur at the end of an IT block,
12095 there are a few other things that can cause us to terminate
12096 the TB in the middle of an IT block:
12097 - Exception generating instructions (bkpt, swi, undefined).
12098 - Page boundaries.
12099 - Hardware watchpoints.
12100 Hardware breakpoints have already been handled and skip this code.
12102 switch(dc->is_jmp) {
12103 case DISAS_NEXT:
12104 gen_goto_tb(dc, 1, dc->pc);
12105 break;
12106 case DISAS_JUMP:
12107 gen_goto_ptr();
12108 break;
12109 case DISAS_UPDATE:
12110 gen_set_pc_im(dc, dc->pc);
12111 /* fall through */
12112 default:
12113 /* indicate that the hash table must be used to find the next TB */
12114 tcg_gen_exit_tb(0);
12115 break;
12116 case DISAS_TB_JUMP:
12117 case DISAS_EXC:
12118 /* nothing more to generate */
12119 break;
12120 case DISAS_WFI:
12121 gen_helper_wfi(cpu_env);
12122 /* The helper doesn't necessarily throw an exception, but we
12123 * must go back to the main loop to check for interrupts anyway.
12125 tcg_gen_exit_tb(0);
12126 break;
12127 case DISAS_WFE:
12128 gen_helper_wfe(cpu_env);
12129 break;
12130 case DISAS_YIELD:
12131 gen_helper_yield(cpu_env);
12132 break;
12133 case DISAS_SWI:
12134 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12135 default_exception_el(dc));
12136 break;
12137 case DISAS_HVC:
12138 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12139 break;
12140 case DISAS_SMC:
12141 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12142 break;
12146 if (dc->condjmp) {
12147 /* "Condition failed" instruction codepath for the branch/trap insn */
12148 gen_set_label(dc->condlabel);
12149 gen_set_condexec(dc);
12150 if (unlikely(is_singlestepping(dc))) {
12151 gen_set_pc_im(dc, dc->pc);
12152 gen_singlestep_exception(dc);
12153 } else {
12154 gen_goto_tb(dc, 1, dc->pc);
12158 done_generating:
12159 gen_tb_end(tb, num_insns);
12161 #ifdef DEBUG_DISAS
12162 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
12163 qemu_log_in_addr_range(pc_start)) {
12164 qemu_log_lock();
12165 qemu_log("----------------\n");
12166 qemu_log("IN: %s\n", lookup_symbol(pc_start));
12167 log_target_disas(cs, pc_start, dc->pc - pc_start,
12168 dc->thumb | (dc->sctlr_b << 1));
12169 qemu_log("\n");
12170 qemu_log_unlock();
12172 #endif
12173 tb->size = dc->pc - pc_start;
12174 tb->icount = num_insns;
12177 static const char *cpu_mode_names[16] = {
12178 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12179 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12182 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12183 int flags)
12185 ARMCPU *cpu = ARM_CPU(cs);
12186 CPUARMState *env = &cpu->env;
12187 int i;
12188 uint32_t psr;
12189 const char *ns_status;
12191 if (is_a64(env)) {
12192 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12193 return;
12196 for(i=0;i<16;i++) {
12197 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12198 if ((i % 4) == 3)
12199 cpu_fprintf(f, "\n");
12200 else
12201 cpu_fprintf(f, " ");
12203 psr = cpsr_read(env);
12205 if (arm_feature(env, ARM_FEATURE_EL3) &&
12206 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12207 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12208 } else {
12209 ns_status = "";
12212 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12213 psr,
12214 psr & (1 << 31) ? 'N' : '-',
12215 psr & (1 << 30) ? 'Z' : '-',
12216 psr & (1 << 29) ? 'C' : '-',
12217 psr & (1 << 28) ? 'V' : '-',
12218 psr & CPSR_T ? 'T' : 'A',
12219 ns_status,
12220 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12222 if (flags & CPU_DUMP_FPU) {
12223 int numvfpregs = 0;
12224 if (arm_feature(env, ARM_FEATURE_VFP)) {
12225 numvfpregs += 16;
12227 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12228 numvfpregs += 16;
12230 for (i = 0; i < numvfpregs; i++) {
12231 uint64_t v = float64_val(env->vfp.regs[i]);
12232 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12233 i * 2, (uint32_t)v,
12234 i * 2 + 1, (uint32_t)(v >> 32),
12235 i, v);
12237 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12241 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12242 target_ulong *data)
12244 if (is_a64(env)) {
12245 env->pc = data[0];
12246 env->condexec_bits = 0;
12247 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12248 } else {
12249 env->regs[15] = data[0];
12250 env->condexec_bits = data[1];
12251 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;