target/arm: Allow ARMv6-M Thumb2 instructions
[qemu/kevin.git] / target / arm / translate.c
blobf405c82fb24047d7617db8abf619241482da88ae
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 "tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "exec/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
38 #include "exec/log.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
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 /* Function prototypes for gen_ functions calling Neon helpers. */
80 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
81 TCGv_i32, TCGv_i32);
83 /* initialize TCG globals. */
84 void arm_translate_init(void)
86 int i;
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
90 offsetof(CPUARMState, regs[i]),
91 regnames[i]);
93 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
103 a64_translate_init();
106 /* Flags for the disas_set_da_iss info argument:
107 * lower bits hold the Rt register number, higher bits are flags.
109 typedef enum ISSInfo {
110 ISSNone = 0,
111 ISSRegMask = 0x1f,
112 ISSInvalid = (1 << 5),
113 ISSIsAcqRel = (1 << 6),
114 ISSIsWrite = (1 << 7),
115 ISSIs16Bit = (1 << 8),
116 } ISSInfo;
118 /* Save the syndrome information for a Data Abort */
119 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
121 uint32_t syn;
122 int sas = memop & MO_SIZE;
123 bool sse = memop & MO_SIGN;
124 bool is_acqrel = issinfo & ISSIsAcqRel;
125 bool is_write = issinfo & ISSIsWrite;
126 bool is_16bit = issinfo & ISSIs16Bit;
127 int srt = issinfo & ISSRegMask;
129 if (issinfo & ISSInvalid) {
130 /* Some callsites want to conditionally provide ISS info,
131 * eg "only if this was not a writeback"
133 return;
136 if (srt == 15) {
137 /* For AArch32, insns where the src/dest is R15 never generate
138 * ISS information. Catching that here saves checking at all
139 * the call sites.
141 return;
144 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
145 0, 0, 0, is_write, 0, is_16bit);
146 disas_set_insn_syndrome(s, syn);
149 static inline int get_a32_user_mem_index(DisasContext *s)
151 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
152 * insns:
153 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
154 * otherwise, access as if at PL0.
156 switch (s->mmu_idx) {
157 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
158 case ARMMMUIdx_S12NSE0:
159 case ARMMMUIdx_S12NSE1:
160 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
161 case ARMMMUIdx_S1E3:
162 case ARMMMUIdx_S1SE0:
163 case ARMMMUIdx_S1SE1:
164 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
165 case ARMMMUIdx_MUser:
166 case ARMMMUIdx_MPriv:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_MUserNegPri:
169 case ARMMMUIdx_MPrivNegPri:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
171 case ARMMMUIdx_MSUser:
172 case ARMMMUIdx_MSPriv:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
174 case ARMMMUIdx_MSUserNegPri:
175 case ARMMMUIdx_MSPrivNegPri:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
177 case ARMMMUIdx_S2NS:
178 default:
179 g_assert_not_reached();
183 static inline TCGv_i32 load_cpu_offset(int offset)
185 TCGv_i32 tmp = tcg_temp_new_i32();
186 tcg_gen_ld_i32(tmp, cpu_env, offset);
187 return tmp;
190 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
192 static inline void store_cpu_offset(TCGv_i32 var, int offset)
194 tcg_gen_st_i32(var, cpu_env, offset);
195 tcg_temp_free_i32(var);
198 #define store_cpu_field(var, name) \
199 store_cpu_offset(var, offsetof(CPUARMState, name))
201 /* Set a variable to the value of a CPU register. */
202 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
204 if (reg == 15) {
205 uint32_t addr;
206 /* normally, since we updated PC, we need only to add one insn */
207 if (s->thumb)
208 addr = (long)s->pc + 2;
209 else
210 addr = (long)s->pc + 4;
211 tcg_gen_movi_i32(var, addr);
212 } else {
213 tcg_gen_mov_i32(var, cpu_R[reg]);
217 /* Create a new temporary and set it to the value of a CPU register. */
218 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
220 TCGv_i32 tmp = tcg_temp_new_i32();
221 load_reg_var(s, tmp, reg);
222 return tmp;
225 /* Set a CPU register. The source must be a temporary and will be
226 marked as dead. */
227 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
229 if (reg == 15) {
230 /* In Thumb mode, we must ignore bit 0.
231 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
232 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
233 * We choose to ignore [1:0] in ARM mode for all architecture versions.
235 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
236 s->base.is_jmp = DISAS_JUMP;
238 tcg_gen_mov_i32(cpu_R[reg], var);
239 tcg_temp_free_i32(var);
242 /* Value extensions. */
243 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
244 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
245 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
246 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
248 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
249 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
252 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
254 TCGv_i32 tmp_mask = tcg_const_i32(mask);
255 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
256 tcg_temp_free_i32(tmp_mask);
258 /* Set NZCV flags from the high 4 bits of var. */
259 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
261 static void gen_exception_internal(int excp)
263 TCGv_i32 tcg_excp = tcg_const_i32(excp);
265 assert(excp_is_internal(excp));
266 gen_helper_exception_internal(cpu_env, tcg_excp);
267 tcg_temp_free_i32(tcg_excp);
270 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
272 TCGv_i32 tcg_excp = tcg_const_i32(excp);
273 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
274 TCGv_i32 tcg_el = tcg_const_i32(target_el);
276 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
277 tcg_syn, tcg_el);
279 tcg_temp_free_i32(tcg_el);
280 tcg_temp_free_i32(tcg_syn);
281 tcg_temp_free_i32(tcg_excp);
284 static void gen_ss_advance(DisasContext *s)
286 /* If the singlestep state is Active-not-pending, advance to
287 * Active-pending.
289 if (s->ss_active) {
290 s->pstate_ss = 0;
291 gen_helper_clear_pstate_ss(cpu_env);
295 static void gen_step_complete_exception(DisasContext *s)
297 /* We just completed step of an insn. Move from Active-not-pending
298 * to Active-pending, and then also take the swstep exception.
299 * This corresponds to making the (IMPDEF) choice to prioritize
300 * swstep exceptions over asynchronous exceptions taken to an exception
301 * level where debug is disabled. This choice has the advantage that
302 * we do not need to maintain internal state corresponding to the
303 * ISV/EX syndrome bits between completion of the step and generation
304 * of the exception, and our syndrome information is always correct.
306 gen_ss_advance(s);
307 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
308 default_exception_el(s));
309 s->base.is_jmp = DISAS_NORETURN;
312 static void gen_singlestep_exception(DisasContext *s)
314 /* Generate the right kind of exception for singlestep, which is
315 * either the architectural singlestep or EXCP_DEBUG for QEMU's
316 * gdb singlestepping.
318 if (s->ss_active) {
319 gen_step_complete_exception(s);
320 } else {
321 gen_exception_internal(EXCP_DEBUG);
325 static inline bool is_singlestepping(DisasContext *s)
327 /* Return true if we are singlestepping either because of
328 * architectural singlestep or QEMU gdbstub singlestep. This does
329 * not include the command line '-singlestep' mode which is rather
330 * misnamed as it only means "one instruction per TB" and doesn't
331 * affect the code we generate.
333 return s->base.singlestep_enabled || s->ss_active;
336 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
338 TCGv_i32 tmp1 = tcg_temp_new_i32();
339 TCGv_i32 tmp2 = tcg_temp_new_i32();
340 tcg_gen_ext16s_i32(tmp1, a);
341 tcg_gen_ext16s_i32(tmp2, b);
342 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
343 tcg_temp_free_i32(tmp2);
344 tcg_gen_sari_i32(a, a, 16);
345 tcg_gen_sari_i32(b, b, 16);
346 tcg_gen_mul_i32(b, b, a);
347 tcg_gen_mov_i32(a, tmp1);
348 tcg_temp_free_i32(tmp1);
351 /* Byteswap each halfword. */
352 static void gen_rev16(TCGv_i32 var)
354 TCGv_i32 tmp = tcg_temp_new_i32();
355 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
356 tcg_gen_shri_i32(tmp, var, 8);
357 tcg_gen_and_i32(tmp, tmp, mask);
358 tcg_gen_and_i32(var, var, mask);
359 tcg_gen_shli_i32(var, var, 8);
360 tcg_gen_or_i32(var, var, tmp);
361 tcg_temp_free_i32(mask);
362 tcg_temp_free_i32(tmp);
365 /* Byteswap low halfword and sign extend. */
366 static void gen_revsh(TCGv_i32 var)
368 tcg_gen_ext16u_i32(var, var);
369 tcg_gen_bswap16_i32(var, var);
370 tcg_gen_ext16s_i32(var, var);
373 /* Return (b << 32) + a. Mark inputs as dead */
374 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
376 TCGv_i64 tmp64 = tcg_temp_new_i64();
378 tcg_gen_extu_i32_i64(tmp64, b);
379 tcg_temp_free_i32(b);
380 tcg_gen_shli_i64(tmp64, tmp64, 32);
381 tcg_gen_add_i64(a, tmp64, a);
383 tcg_temp_free_i64(tmp64);
384 return a;
387 /* Return (b << 32) - a. Mark inputs as dead. */
388 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
390 TCGv_i64 tmp64 = tcg_temp_new_i64();
392 tcg_gen_extu_i32_i64(tmp64, b);
393 tcg_temp_free_i32(b);
394 tcg_gen_shli_i64(tmp64, tmp64, 32);
395 tcg_gen_sub_i64(a, tmp64, a);
397 tcg_temp_free_i64(tmp64);
398 return a;
401 /* 32x32->64 multiply. Marks inputs as dead. */
402 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
404 TCGv_i32 lo = tcg_temp_new_i32();
405 TCGv_i32 hi = tcg_temp_new_i32();
406 TCGv_i64 ret;
408 tcg_gen_mulu2_i32(lo, hi, a, b);
409 tcg_temp_free_i32(a);
410 tcg_temp_free_i32(b);
412 ret = tcg_temp_new_i64();
413 tcg_gen_concat_i32_i64(ret, lo, hi);
414 tcg_temp_free_i32(lo);
415 tcg_temp_free_i32(hi);
417 return ret;
420 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
422 TCGv_i32 lo = tcg_temp_new_i32();
423 TCGv_i32 hi = tcg_temp_new_i32();
424 TCGv_i64 ret;
426 tcg_gen_muls2_i32(lo, hi, a, b);
427 tcg_temp_free_i32(a);
428 tcg_temp_free_i32(b);
430 ret = tcg_temp_new_i64();
431 tcg_gen_concat_i32_i64(ret, lo, hi);
432 tcg_temp_free_i32(lo);
433 tcg_temp_free_i32(hi);
435 return ret;
438 /* Swap low and high halfwords. */
439 static void gen_swap_half(TCGv_i32 var)
441 TCGv_i32 tmp = tcg_temp_new_i32();
442 tcg_gen_shri_i32(tmp, var, 16);
443 tcg_gen_shli_i32(var, var, 16);
444 tcg_gen_or_i32(var, var, tmp);
445 tcg_temp_free_i32(tmp);
448 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
449 tmp = (t0 ^ t1) & 0x8000;
450 t0 &= ~0x8000;
451 t1 &= ~0x8000;
452 t0 = (t0 + t1) ^ tmp;
455 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
457 TCGv_i32 tmp = tcg_temp_new_i32();
458 tcg_gen_xor_i32(tmp, t0, t1);
459 tcg_gen_andi_i32(tmp, tmp, 0x8000);
460 tcg_gen_andi_i32(t0, t0, ~0x8000);
461 tcg_gen_andi_i32(t1, t1, ~0x8000);
462 tcg_gen_add_i32(t0, t0, t1);
463 tcg_gen_xor_i32(t0, t0, tmp);
464 tcg_temp_free_i32(tmp);
465 tcg_temp_free_i32(t1);
468 /* Set CF to the top bit of var. */
469 static void gen_set_CF_bit31(TCGv_i32 var)
471 tcg_gen_shri_i32(cpu_CF, var, 31);
474 /* Set N and Z flags from var. */
475 static inline void gen_logic_CC(TCGv_i32 var)
477 tcg_gen_mov_i32(cpu_NF, var);
478 tcg_gen_mov_i32(cpu_ZF, var);
481 /* T0 += T1 + CF. */
482 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
484 tcg_gen_add_i32(t0, t0, t1);
485 tcg_gen_add_i32(t0, t0, cpu_CF);
488 /* dest = T0 + T1 + CF. */
489 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
491 tcg_gen_add_i32(dest, t0, t1);
492 tcg_gen_add_i32(dest, dest, cpu_CF);
495 /* dest = T0 - T1 + CF - 1. */
496 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
498 tcg_gen_sub_i32(dest, t0, t1);
499 tcg_gen_add_i32(dest, dest, cpu_CF);
500 tcg_gen_subi_i32(dest, dest, 1);
503 /* dest = T0 + T1. Compute C, N, V and Z flags */
504 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
506 TCGv_i32 tmp = tcg_temp_new_i32();
507 tcg_gen_movi_i32(tmp, 0);
508 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
509 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
510 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
511 tcg_gen_xor_i32(tmp, t0, t1);
512 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
513 tcg_temp_free_i32(tmp);
514 tcg_gen_mov_i32(dest, cpu_NF);
517 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
518 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
520 TCGv_i32 tmp = tcg_temp_new_i32();
521 if (TCG_TARGET_HAS_add2_i32) {
522 tcg_gen_movi_i32(tmp, 0);
523 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
524 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
525 } else {
526 TCGv_i64 q0 = tcg_temp_new_i64();
527 TCGv_i64 q1 = tcg_temp_new_i64();
528 tcg_gen_extu_i32_i64(q0, t0);
529 tcg_gen_extu_i32_i64(q1, t1);
530 tcg_gen_add_i64(q0, q0, q1);
531 tcg_gen_extu_i32_i64(q1, cpu_CF);
532 tcg_gen_add_i64(q0, q0, q1);
533 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
534 tcg_temp_free_i64(q0);
535 tcg_temp_free_i64(q1);
537 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
538 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
539 tcg_gen_xor_i32(tmp, t0, t1);
540 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
541 tcg_temp_free_i32(tmp);
542 tcg_gen_mov_i32(dest, cpu_NF);
545 /* dest = T0 - T1. Compute C, N, V and Z flags */
546 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
548 TCGv_i32 tmp;
549 tcg_gen_sub_i32(cpu_NF, t0, t1);
550 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
551 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
552 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
553 tmp = tcg_temp_new_i32();
554 tcg_gen_xor_i32(tmp, t0, t1);
555 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
556 tcg_temp_free_i32(tmp);
557 tcg_gen_mov_i32(dest, cpu_NF);
560 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
561 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
563 TCGv_i32 tmp = tcg_temp_new_i32();
564 tcg_gen_not_i32(tmp, t1);
565 gen_adc_CC(dest, t0, tmp);
566 tcg_temp_free_i32(tmp);
569 #define GEN_SHIFT(name) \
570 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
572 TCGv_i32 tmp1, tmp2, tmp3; \
573 tmp1 = tcg_temp_new_i32(); \
574 tcg_gen_andi_i32(tmp1, t1, 0xff); \
575 tmp2 = tcg_const_i32(0); \
576 tmp3 = tcg_const_i32(0x1f); \
577 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
578 tcg_temp_free_i32(tmp3); \
579 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
580 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
581 tcg_temp_free_i32(tmp2); \
582 tcg_temp_free_i32(tmp1); \
584 GEN_SHIFT(shl)
585 GEN_SHIFT(shr)
586 #undef GEN_SHIFT
588 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
590 TCGv_i32 tmp1, tmp2;
591 tmp1 = tcg_temp_new_i32();
592 tcg_gen_andi_i32(tmp1, t1, 0xff);
593 tmp2 = tcg_const_i32(0x1f);
594 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
595 tcg_temp_free_i32(tmp2);
596 tcg_gen_sar_i32(dest, t0, tmp1);
597 tcg_temp_free_i32(tmp1);
600 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
602 TCGv_i32 c0 = tcg_const_i32(0);
603 TCGv_i32 tmp = tcg_temp_new_i32();
604 tcg_gen_neg_i32(tmp, src);
605 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
606 tcg_temp_free_i32(c0);
607 tcg_temp_free_i32(tmp);
610 static void shifter_out_im(TCGv_i32 var, int shift)
612 if (shift == 0) {
613 tcg_gen_andi_i32(cpu_CF, var, 1);
614 } else {
615 tcg_gen_shri_i32(cpu_CF, var, shift);
616 if (shift != 31) {
617 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
622 /* Shift by immediate. Includes special handling for shift == 0. */
623 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
624 int shift, int flags)
626 switch (shiftop) {
627 case 0: /* LSL */
628 if (shift != 0) {
629 if (flags)
630 shifter_out_im(var, 32 - shift);
631 tcg_gen_shli_i32(var, var, shift);
633 break;
634 case 1: /* LSR */
635 if (shift == 0) {
636 if (flags) {
637 tcg_gen_shri_i32(cpu_CF, var, 31);
639 tcg_gen_movi_i32(var, 0);
640 } else {
641 if (flags)
642 shifter_out_im(var, shift - 1);
643 tcg_gen_shri_i32(var, var, shift);
645 break;
646 case 2: /* ASR */
647 if (shift == 0)
648 shift = 32;
649 if (flags)
650 shifter_out_im(var, shift - 1);
651 if (shift == 32)
652 shift = 31;
653 tcg_gen_sari_i32(var, var, shift);
654 break;
655 case 3: /* ROR/RRX */
656 if (shift != 0) {
657 if (flags)
658 shifter_out_im(var, shift - 1);
659 tcg_gen_rotri_i32(var, var, shift); break;
660 } else {
661 TCGv_i32 tmp = tcg_temp_new_i32();
662 tcg_gen_shli_i32(tmp, cpu_CF, 31);
663 if (flags)
664 shifter_out_im(var, 0);
665 tcg_gen_shri_i32(var, var, 1);
666 tcg_gen_or_i32(var, var, tmp);
667 tcg_temp_free_i32(tmp);
672 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
673 TCGv_i32 shift, int flags)
675 if (flags) {
676 switch (shiftop) {
677 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
678 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
679 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
680 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
682 } else {
683 switch (shiftop) {
684 case 0:
685 gen_shl(var, var, shift);
686 break;
687 case 1:
688 gen_shr(var, var, shift);
689 break;
690 case 2:
691 gen_sar(var, var, shift);
692 break;
693 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
694 tcg_gen_rotr_i32(var, var, shift); break;
697 tcg_temp_free_i32(shift);
700 #define PAS_OP(pfx) \
701 switch (op2) { \
702 case 0: gen_pas_helper(glue(pfx,add16)); break; \
703 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
704 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
705 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
706 case 4: gen_pas_helper(glue(pfx,add8)); break; \
707 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
709 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
711 TCGv_ptr tmp;
713 switch (op1) {
714 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
715 case 1:
716 tmp = tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
718 PAS_OP(s)
719 tcg_temp_free_ptr(tmp);
720 break;
721 case 5:
722 tmp = tcg_temp_new_ptr();
723 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
724 PAS_OP(u)
725 tcg_temp_free_ptr(tmp);
726 break;
727 #undef gen_pas_helper
728 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
729 case 2:
730 PAS_OP(q);
731 break;
732 case 3:
733 PAS_OP(sh);
734 break;
735 case 6:
736 PAS_OP(uq);
737 break;
738 case 7:
739 PAS_OP(uh);
740 break;
741 #undef gen_pas_helper
744 #undef PAS_OP
746 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
747 #define PAS_OP(pfx) \
748 switch (op1) { \
749 case 0: gen_pas_helper(glue(pfx,add8)); break; \
750 case 1: gen_pas_helper(glue(pfx,add16)); break; \
751 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
752 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
753 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
754 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
756 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
758 TCGv_ptr tmp;
760 switch (op2) {
761 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
762 case 0:
763 tmp = tcg_temp_new_ptr();
764 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
765 PAS_OP(s)
766 tcg_temp_free_ptr(tmp);
767 break;
768 case 4:
769 tmp = tcg_temp_new_ptr();
770 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
771 PAS_OP(u)
772 tcg_temp_free_ptr(tmp);
773 break;
774 #undef gen_pas_helper
775 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
776 case 1:
777 PAS_OP(q);
778 break;
779 case 2:
780 PAS_OP(sh);
781 break;
782 case 5:
783 PAS_OP(uq);
784 break;
785 case 6:
786 PAS_OP(uh);
787 break;
788 #undef gen_pas_helper
791 #undef PAS_OP
794 * Generate a conditional based on ARM condition code cc.
795 * This is common between ARM and Aarch64 targets.
797 void arm_test_cc(DisasCompare *cmp, int cc)
799 TCGv_i32 value;
800 TCGCond cond;
801 bool global = true;
803 switch (cc) {
804 case 0: /* eq: Z */
805 case 1: /* ne: !Z */
806 cond = TCG_COND_EQ;
807 value = cpu_ZF;
808 break;
810 case 2: /* cs: C */
811 case 3: /* cc: !C */
812 cond = TCG_COND_NE;
813 value = cpu_CF;
814 break;
816 case 4: /* mi: N */
817 case 5: /* pl: !N */
818 cond = TCG_COND_LT;
819 value = cpu_NF;
820 break;
822 case 6: /* vs: V */
823 case 7: /* vc: !V */
824 cond = TCG_COND_LT;
825 value = cpu_VF;
826 break;
828 case 8: /* hi: C && !Z */
829 case 9: /* ls: !C || Z -> !(C && !Z) */
830 cond = TCG_COND_NE;
831 value = tcg_temp_new_i32();
832 global = false;
833 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
834 ZF is non-zero for !Z; so AND the two subexpressions. */
835 tcg_gen_neg_i32(value, cpu_CF);
836 tcg_gen_and_i32(value, value, cpu_ZF);
837 break;
839 case 10: /* ge: N == V -> N ^ V == 0 */
840 case 11: /* lt: N != V -> N ^ V != 0 */
841 /* Since we're only interested in the sign bit, == 0 is >= 0. */
842 cond = TCG_COND_GE;
843 value = tcg_temp_new_i32();
844 global = false;
845 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
846 break;
848 case 12: /* gt: !Z && N == V */
849 case 13: /* le: Z || N != V */
850 cond = TCG_COND_NE;
851 value = tcg_temp_new_i32();
852 global = false;
853 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
854 * the sign bit then AND with ZF to yield the result. */
855 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
856 tcg_gen_sari_i32(value, value, 31);
857 tcg_gen_andc_i32(value, cpu_ZF, value);
858 break;
860 case 14: /* always */
861 case 15: /* always */
862 /* Use the ALWAYS condition, which will fold early.
863 * It doesn't matter what we use for the value. */
864 cond = TCG_COND_ALWAYS;
865 value = cpu_ZF;
866 goto no_invert;
868 default:
869 fprintf(stderr, "Bad condition code 0x%x\n", cc);
870 abort();
873 if (cc & 1) {
874 cond = tcg_invert_cond(cond);
877 no_invert:
878 cmp->cond = cond;
879 cmp->value = value;
880 cmp->value_global = global;
883 void arm_free_cc(DisasCompare *cmp)
885 if (!cmp->value_global) {
886 tcg_temp_free_i32(cmp->value);
890 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
892 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
895 void arm_gen_test_cc(int cc, TCGLabel *label)
897 DisasCompare cmp;
898 arm_test_cc(&cmp, cc);
899 arm_jump_cc(&cmp, label);
900 arm_free_cc(&cmp);
903 static const uint8_t table_logic_cc[16] = {
904 1, /* and */
905 1, /* xor */
906 0, /* sub */
907 0, /* rsb */
908 0, /* add */
909 0, /* adc */
910 0, /* sbc */
911 0, /* rsc */
912 1, /* andl */
913 1, /* xorl */
914 0, /* cmp */
915 0, /* cmn */
916 1, /* orr */
917 1, /* mov */
918 1, /* bic */
919 1, /* mvn */
922 static inline void gen_set_condexec(DisasContext *s)
924 if (s->condexec_mask) {
925 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
926 TCGv_i32 tmp = tcg_temp_new_i32();
927 tcg_gen_movi_i32(tmp, val);
928 store_cpu_field(tmp, condexec_bits);
932 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
934 tcg_gen_movi_i32(cpu_R[15], val);
937 /* Set PC and Thumb state from an immediate address. */
938 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
940 TCGv_i32 tmp;
942 s->base.is_jmp = DISAS_JUMP;
943 if (s->thumb != (addr & 1)) {
944 tmp = tcg_temp_new_i32();
945 tcg_gen_movi_i32(tmp, addr & 1);
946 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
947 tcg_temp_free_i32(tmp);
949 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
952 /* Set PC and Thumb state from var. var is marked as dead. */
953 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
955 s->base.is_jmp = DISAS_JUMP;
956 tcg_gen_andi_i32(cpu_R[15], var, ~1);
957 tcg_gen_andi_i32(var, var, 1);
958 store_cpu_field(var, thumb);
961 /* Set PC and Thumb state from var. var is marked as dead.
962 * For M-profile CPUs, include logic to detect exception-return
963 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
964 * and BX reg, and no others, and happens only for code in Handler mode.
966 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
968 /* Generate the same code here as for a simple bx, but flag via
969 * s->base.is_jmp that we need to do the rest of the work later.
971 gen_bx(s, var);
972 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
973 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
974 s->base.is_jmp = DISAS_BX_EXCRET;
978 static inline void gen_bx_excret_final_code(DisasContext *s)
980 /* Generate the code to finish possible exception return and end the TB */
981 TCGLabel *excret_label = gen_new_label();
982 uint32_t min_magic;
984 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
985 /* Covers FNC_RETURN and EXC_RETURN magic */
986 min_magic = FNC_RETURN_MIN_MAGIC;
987 } else {
988 /* EXC_RETURN magic only */
989 min_magic = EXC_RETURN_MIN_MAGIC;
992 /* Is the new PC value in the magic range indicating exception return? */
993 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
994 /* No: end the TB as we would for a DISAS_JMP */
995 if (is_singlestepping(s)) {
996 gen_singlestep_exception(s);
997 } else {
998 tcg_gen_exit_tb(NULL, 0);
1000 gen_set_label(excret_label);
1001 /* Yes: this is an exception return.
1002 * At this point in runtime env->regs[15] and env->thumb will hold
1003 * the exception-return magic number, which do_v7m_exception_exit()
1004 * will read. Nothing else will be able to see those values because
1005 * the cpu-exec main loop guarantees that we will always go straight
1006 * from raising the exception to the exception-handling code.
1008 * gen_ss_advance(s) does nothing on M profile currently but
1009 * calling it is conceptually the right thing as we have executed
1010 * this instruction (compare SWI, HVC, SMC handling).
1012 gen_ss_advance(s);
1013 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1016 static inline void gen_bxns(DisasContext *s, int rm)
1018 TCGv_i32 var = load_reg(s, rm);
1020 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1021 * we need to sync state before calling it, but:
1022 * - we don't need to do gen_set_pc_im() because the bxns helper will
1023 * always set the PC itself
1024 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1025 * unless it's outside an IT block or the last insn in an IT block,
1026 * so we know that condexec == 0 (already set at the top of the TB)
1027 * is correct in the non-UNPREDICTABLE cases, and we can choose
1028 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1030 gen_helper_v7m_bxns(cpu_env, var);
1031 tcg_temp_free_i32(var);
1032 s->base.is_jmp = DISAS_EXIT;
1035 static inline void gen_blxns(DisasContext *s, int rm)
1037 TCGv_i32 var = load_reg(s, rm);
1039 /* We don't need to sync condexec state, for the same reason as bxns.
1040 * We do however need to set the PC, because the blxns helper reads it.
1041 * The blxns helper may throw an exception.
1043 gen_set_pc_im(s, s->pc);
1044 gen_helper_v7m_blxns(cpu_env, var);
1045 tcg_temp_free_i32(var);
1046 s->base.is_jmp = DISAS_EXIT;
1049 /* Variant of store_reg which uses branch&exchange logic when storing
1050 to r15 in ARM architecture v7 and above. The source must be a temporary
1051 and will be marked as dead. */
1052 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1054 if (reg == 15 && ENABLE_ARCH_7) {
1055 gen_bx(s, var);
1056 } else {
1057 store_reg(s, reg, var);
1061 /* Variant of store_reg which uses branch&exchange logic when storing
1062 * to r15 in ARM architecture v5T and above. This is used for storing
1063 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1064 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1065 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1067 if (reg == 15 && ENABLE_ARCH_5) {
1068 gen_bx_excret(s, var);
1069 } else {
1070 store_reg(s, reg, var);
1074 #ifdef CONFIG_USER_ONLY
1075 #define IS_USER_ONLY 1
1076 #else
1077 #define IS_USER_ONLY 0
1078 #endif
1080 /* Abstractions of "generate code to do a guest load/store for
1081 * AArch32", where a vaddr is always 32 bits (and is zero
1082 * extended if we're a 64 bit core) and data is also
1083 * 32 bits unless specifically doing a 64 bit access.
1084 * These functions work like tcg_gen_qemu_{ld,st}* except
1085 * that the address argument is TCGv_i32 rather than TCGv.
1088 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1090 TCGv addr = tcg_temp_new();
1091 tcg_gen_extu_i32_tl(addr, a32);
1093 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1094 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1095 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1097 return addr;
1100 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1101 int index, TCGMemOp opc)
1103 TCGv addr = gen_aa32_addr(s, a32, opc);
1104 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1105 tcg_temp_free(addr);
1108 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1109 int index, TCGMemOp opc)
1111 TCGv addr = gen_aa32_addr(s, a32, opc);
1112 tcg_gen_qemu_st_i32(val, addr, index, opc);
1113 tcg_temp_free(addr);
1116 #define DO_GEN_LD(SUFF, OPC) \
1117 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1118 TCGv_i32 a32, int index) \
1120 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1122 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1123 TCGv_i32 val, \
1124 TCGv_i32 a32, int index, \
1125 ISSInfo issinfo) \
1127 gen_aa32_ld##SUFF(s, val, a32, index); \
1128 disas_set_da_iss(s, OPC, issinfo); \
1131 #define DO_GEN_ST(SUFF, OPC) \
1132 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1133 TCGv_i32 a32, int index) \
1135 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1137 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1138 TCGv_i32 val, \
1139 TCGv_i32 a32, int index, \
1140 ISSInfo issinfo) \
1142 gen_aa32_st##SUFF(s, val, a32, index); \
1143 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1146 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1148 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1149 if (!IS_USER_ONLY && s->sctlr_b) {
1150 tcg_gen_rotri_i64(val, val, 32);
1154 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1155 int index, TCGMemOp opc)
1157 TCGv addr = gen_aa32_addr(s, a32, opc);
1158 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1159 gen_aa32_frob64(s, val);
1160 tcg_temp_free(addr);
1163 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1164 TCGv_i32 a32, int index)
1166 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1169 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1170 int index, TCGMemOp opc)
1172 TCGv addr = gen_aa32_addr(s, a32, opc);
1174 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1175 if (!IS_USER_ONLY && s->sctlr_b) {
1176 TCGv_i64 tmp = tcg_temp_new_i64();
1177 tcg_gen_rotri_i64(tmp, val, 32);
1178 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1179 tcg_temp_free_i64(tmp);
1180 } else {
1181 tcg_gen_qemu_st_i64(val, addr, index, opc);
1183 tcg_temp_free(addr);
1186 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1187 TCGv_i32 a32, int index)
1189 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1192 DO_GEN_LD(8s, MO_SB)
1193 DO_GEN_LD(8u, MO_UB)
1194 DO_GEN_LD(16s, MO_SW)
1195 DO_GEN_LD(16u, MO_UW)
1196 DO_GEN_LD(32u, MO_UL)
1197 DO_GEN_ST(8, MO_UB)
1198 DO_GEN_ST(16, MO_UW)
1199 DO_GEN_ST(32, MO_UL)
1201 static inline void gen_hvc(DisasContext *s, int imm16)
1203 /* The pre HVC helper handles cases when HVC gets trapped
1204 * as an undefined insn by runtime configuration (ie before
1205 * the insn really executes).
1207 gen_set_pc_im(s, s->pc - 4);
1208 gen_helper_pre_hvc(cpu_env);
1209 /* Otherwise we will treat this as a real exception which
1210 * happens after execution of the insn. (The distinction matters
1211 * for the PC value reported to the exception handler and also
1212 * for single stepping.)
1214 s->svc_imm = imm16;
1215 gen_set_pc_im(s, s->pc);
1216 s->base.is_jmp = DISAS_HVC;
1219 static inline void gen_smc(DisasContext *s)
1221 /* As with HVC, we may take an exception either before or after
1222 * the insn executes.
1224 TCGv_i32 tmp;
1226 gen_set_pc_im(s, s->pc - 4);
1227 tmp = tcg_const_i32(syn_aa32_smc());
1228 gen_helper_pre_smc(cpu_env, tmp);
1229 tcg_temp_free_i32(tmp);
1230 gen_set_pc_im(s, s->pc);
1231 s->base.is_jmp = DISAS_SMC;
1234 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1236 gen_set_condexec(s);
1237 gen_set_pc_im(s, s->pc - offset);
1238 gen_exception_internal(excp);
1239 s->base.is_jmp = DISAS_NORETURN;
1242 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1243 int syn, uint32_t target_el)
1245 gen_set_condexec(s);
1246 gen_set_pc_im(s, s->pc - offset);
1247 gen_exception(excp, syn, target_el);
1248 s->base.is_jmp = DISAS_NORETURN;
1251 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1253 TCGv_i32 tcg_syn;
1255 gen_set_condexec(s);
1256 gen_set_pc_im(s, s->pc - offset);
1257 tcg_syn = tcg_const_i32(syn);
1258 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1259 tcg_temp_free_i32(tcg_syn);
1260 s->base.is_jmp = DISAS_NORETURN;
1263 /* Force a TB lookup after an instruction that changes the CPU state. */
1264 static inline void gen_lookup_tb(DisasContext *s)
1266 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1267 s->base.is_jmp = DISAS_EXIT;
1270 static inline void gen_hlt(DisasContext *s, int imm)
1272 /* HLT. This has two purposes.
1273 * Architecturally, it is an external halting debug instruction.
1274 * Since QEMU doesn't implement external debug, we treat this as
1275 * it is required for halting debug disabled: it will UNDEF.
1276 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1277 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1278 * must trigger semihosting even for ARMv7 and earlier, where
1279 * HLT was an undefined encoding.
1280 * In system mode, we don't allow userspace access to
1281 * semihosting, to provide some semblance of security
1282 * (and for consistency with our 32-bit semihosting).
1284 if (semihosting_enabled() &&
1285 #ifndef CONFIG_USER_ONLY
1286 s->current_el != 0 &&
1287 #endif
1288 (imm == (s->thumb ? 0x3c : 0xf000))) {
1289 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1290 return;
1293 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1294 default_exception_el(s));
1297 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1298 TCGv_i32 var)
1300 int val, rm, shift, shiftop;
1301 TCGv_i32 offset;
1303 if (!(insn & (1 << 25))) {
1304 /* immediate */
1305 val = insn & 0xfff;
1306 if (!(insn & (1 << 23)))
1307 val = -val;
1308 if (val != 0)
1309 tcg_gen_addi_i32(var, var, val);
1310 } else {
1311 /* shift/register */
1312 rm = (insn) & 0xf;
1313 shift = (insn >> 7) & 0x1f;
1314 shiftop = (insn >> 5) & 3;
1315 offset = load_reg(s, rm);
1316 gen_arm_shift_im(offset, shiftop, shift, 0);
1317 if (!(insn & (1 << 23)))
1318 tcg_gen_sub_i32(var, var, offset);
1319 else
1320 tcg_gen_add_i32(var, var, offset);
1321 tcg_temp_free_i32(offset);
1325 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1326 int extra, TCGv_i32 var)
1328 int val, rm;
1329 TCGv_i32 offset;
1331 if (insn & (1 << 22)) {
1332 /* immediate */
1333 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1334 if (!(insn & (1 << 23)))
1335 val = -val;
1336 val += extra;
1337 if (val != 0)
1338 tcg_gen_addi_i32(var, var, val);
1339 } else {
1340 /* register */
1341 if (extra)
1342 tcg_gen_addi_i32(var, var, extra);
1343 rm = (insn) & 0xf;
1344 offset = load_reg(s, rm);
1345 if (!(insn & (1 << 23)))
1346 tcg_gen_sub_i32(var, var, offset);
1347 else
1348 tcg_gen_add_i32(var, var, offset);
1349 tcg_temp_free_i32(offset);
1353 static TCGv_ptr get_fpstatus_ptr(int neon)
1355 TCGv_ptr statusptr = tcg_temp_new_ptr();
1356 int offset;
1357 if (neon) {
1358 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1359 } else {
1360 offset = offsetof(CPUARMState, vfp.fp_status);
1362 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1363 return statusptr;
1366 #define VFP_OP2(name) \
1367 static inline void gen_vfp_##name(int dp) \
1369 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1370 if (dp) { \
1371 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1372 } else { \
1373 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1375 tcg_temp_free_ptr(fpst); \
1378 VFP_OP2(add)
1379 VFP_OP2(sub)
1380 VFP_OP2(mul)
1381 VFP_OP2(div)
1383 #undef VFP_OP2
1385 static inline void gen_vfp_F1_mul(int dp)
1387 /* Like gen_vfp_mul() but put result in F1 */
1388 TCGv_ptr fpst = get_fpstatus_ptr(0);
1389 if (dp) {
1390 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1391 } else {
1392 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1394 tcg_temp_free_ptr(fpst);
1397 static inline void gen_vfp_F1_neg(int dp)
1399 /* Like gen_vfp_neg() but put result in F1 */
1400 if (dp) {
1401 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1402 } else {
1403 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1407 static inline void gen_vfp_abs(int dp)
1409 if (dp)
1410 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1411 else
1412 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1415 static inline void gen_vfp_neg(int dp)
1417 if (dp)
1418 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1419 else
1420 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1423 static inline void gen_vfp_sqrt(int dp)
1425 if (dp)
1426 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1427 else
1428 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1431 static inline void gen_vfp_cmp(int dp)
1433 if (dp)
1434 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1435 else
1436 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1439 static inline void gen_vfp_cmpe(int dp)
1441 if (dp)
1442 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1443 else
1444 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1447 static inline void gen_vfp_F1_ld0(int dp)
1449 if (dp)
1450 tcg_gen_movi_i64(cpu_F1d, 0);
1451 else
1452 tcg_gen_movi_i32(cpu_F1s, 0);
1455 #define VFP_GEN_ITOF(name) \
1456 static inline void gen_vfp_##name(int dp, int neon) \
1458 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1459 if (dp) { \
1460 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1461 } else { \
1462 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1464 tcg_temp_free_ptr(statusptr); \
1467 VFP_GEN_ITOF(uito)
1468 VFP_GEN_ITOF(sito)
1469 #undef VFP_GEN_ITOF
1471 #define VFP_GEN_FTOI(name) \
1472 static inline void gen_vfp_##name(int dp, int neon) \
1474 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1475 if (dp) { \
1476 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1477 } else { \
1478 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1480 tcg_temp_free_ptr(statusptr); \
1483 VFP_GEN_FTOI(toui)
1484 VFP_GEN_FTOI(touiz)
1485 VFP_GEN_FTOI(tosi)
1486 VFP_GEN_FTOI(tosiz)
1487 #undef VFP_GEN_FTOI
1489 #define VFP_GEN_FIX(name, round) \
1490 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1492 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1493 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1494 if (dp) { \
1495 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1496 statusptr); \
1497 } else { \
1498 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1499 statusptr); \
1501 tcg_temp_free_i32(tmp_shift); \
1502 tcg_temp_free_ptr(statusptr); \
1504 VFP_GEN_FIX(tosh, _round_to_zero)
1505 VFP_GEN_FIX(tosl, _round_to_zero)
1506 VFP_GEN_FIX(touh, _round_to_zero)
1507 VFP_GEN_FIX(toul, _round_to_zero)
1508 VFP_GEN_FIX(shto, )
1509 VFP_GEN_FIX(slto, )
1510 VFP_GEN_FIX(uhto, )
1511 VFP_GEN_FIX(ulto, )
1512 #undef VFP_GEN_FIX
1514 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1516 if (dp) {
1517 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1518 } else {
1519 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1523 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1525 if (dp) {
1526 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1527 } else {
1528 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1532 static inline long vfp_reg_offset(bool dp, unsigned reg)
1534 if (dp) {
1535 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1536 } else {
1537 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1538 if (reg & 1) {
1539 ofs += offsetof(CPU_DoubleU, l.upper);
1540 } else {
1541 ofs += offsetof(CPU_DoubleU, l.lower);
1543 return ofs;
1547 /* Return the offset of a 32-bit piece of a NEON register.
1548 zero is the least significant end of the register. */
1549 static inline long
1550 neon_reg_offset (int reg, int n)
1552 int sreg;
1553 sreg = reg * 2 + n;
1554 return vfp_reg_offset(0, sreg);
1557 static TCGv_i32 neon_load_reg(int reg, int pass)
1559 TCGv_i32 tmp = tcg_temp_new_i32();
1560 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1561 return tmp;
1564 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1566 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1567 tcg_temp_free_i32(var);
1570 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1572 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1575 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1577 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1580 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1582 TCGv_ptr ret = tcg_temp_new_ptr();
1583 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1584 return ret;
1587 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1588 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1589 #define tcg_gen_st_f32 tcg_gen_st_i32
1590 #define tcg_gen_st_f64 tcg_gen_st_i64
1592 static inline void gen_mov_F0_vreg(int dp, int reg)
1594 if (dp)
1595 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1596 else
1597 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1600 static inline void gen_mov_F1_vreg(int dp, int reg)
1602 if (dp)
1603 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1604 else
1605 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1608 static inline void gen_mov_vreg_F0(int dp, int reg)
1610 if (dp)
1611 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1612 else
1613 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1616 #define ARM_CP_RW_BIT (1 << 20)
1618 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1620 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1623 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1625 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1628 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1630 TCGv_i32 var = tcg_temp_new_i32();
1631 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1632 return var;
1635 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1637 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1638 tcg_temp_free_i32(var);
1641 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1643 iwmmxt_store_reg(cpu_M0, rn);
1646 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1648 iwmmxt_load_reg(cpu_M0, rn);
1651 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1653 iwmmxt_load_reg(cpu_V1, rn);
1654 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1657 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1659 iwmmxt_load_reg(cpu_V1, rn);
1660 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1663 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1665 iwmmxt_load_reg(cpu_V1, rn);
1666 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1669 #define IWMMXT_OP(name) \
1670 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1672 iwmmxt_load_reg(cpu_V1, rn); \
1673 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1676 #define IWMMXT_OP_ENV(name) \
1677 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1679 iwmmxt_load_reg(cpu_V1, rn); \
1680 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1683 #define IWMMXT_OP_ENV_SIZE(name) \
1684 IWMMXT_OP_ENV(name##b) \
1685 IWMMXT_OP_ENV(name##w) \
1686 IWMMXT_OP_ENV(name##l)
1688 #define IWMMXT_OP_ENV1(name) \
1689 static inline void gen_op_iwmmxt_##name##_M0(void) \
1691 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1694 IWMMXT_OP(maddsq)
1695 IWMMXT_OP(madduq)
1696 IWMMXT_OP(sadb)
1697 IWMMXT_OP(sadw)
1698 IWMMXT_OP(mulslw)
1699 IWMMXT_OP(mulshw)
1700 IWMMXT_OP(mululw)
1701 IWMMXT_OP(muluhw)
1702 IWMMXT_OP(macsw)
1703 IWMMXT_OP(macuw)
1705 IWMMXT_OP_ENV_SIZE(unpackl)
1706 IWMMXT_OP_ENV_SIZE(unpackh)
1708 IWMMXT_OP_ENV1(unpacklub)
1709 IWMMXT_OP_ENV1(unpackluw)
1710 IWMMXT_OP_ENV1(unpacklul)
1711 IWMMXT_OP_ENV1(unpackhub)
1712 IWMMXT_OP_ENV1(unpackhuw)
1713 IWMMXT_OP_ENV1(unpackhul)
1714 IWMMXT_OP_ENV1(unpacklsb)
1715 IWMMXT_OP_ENV1(unpacklsw)
1716 IWMMXT_OP_ENV1(unpacklsl)
1717 IWMMXT_OP_ENV1(unpackhsb)
1718 IWMMXT_OP_ENV1(unpackhsw)
1719 IWMMXT_OP_ENV1(unpackhsl)
1721 IWMMXT_OP_ENV_SIZE(cmpeq)
1722 IWMMXT_OP_ENV_SIZE(cmpgtu)
1723 IWMMXT_OP_ENV_SIZE(cmpgts)
1725 IWMMXT_OP_ENV_SIZE(mins)
1726 IWMMXT_OP_ENV_SIZE(minu)
1727 IWMMXT_OP_ENV_SIZE(maxs)
1728 IWMMXT_OP_ENV_SIZE(maxu)
1730 IWMMXT_OP_ENV_SIZE(subn)
1731 IWMMXT_OP_ENV_SIZE(addn)
1732 IWMMXT_OP_ENV_SIZE(subu)
1733 IWMMXT_OP_ENV_SIZE(addu)
1734 IWMMXT_OP_ENV_SIZE(subs)
1735 IWMMXT_OP_ENV_SIZE(adds)
1737 IWMMXT_OP_ENV(avgb0)
1738 IWMMXT_OP_ENV(avgb1)
1739 IWMMXT_OP_ENV(avgw0)
1740 IWMMXT_OP_ENV(avgw1)
1742 IWMMXT_OP_ENV(packuw)
1743 IWMMXT_OP_ENV(packul)
1744 IWMMXT_OP_ENV(packuq)
1745 IWMMXT_OP_ENV(packsw)
1746 IWMMXT_OP_ENV(packsl)
1747 IWMMXT_OP_ENV(packsq)
1749 static void gen_op_iwmmxt_set_mup(void)
1751 TCGv_i32 tmp;
1752 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1753 tcg_gen_ori_i32(tmp, tmp, 2);
1754 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1757 static void gen_op_iwmmxt_set_cup(void)
1759 TCGv_i32 tmp;
1760 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1761 tcg_gen_ori_i32(tmp, tmp, 1);
1762 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1765 static void gen_op_iwmmxt_setpsr_nz(void)
1767 TCGv_i32 tmp = tcg_temp_new_i32();
1768 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1769 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1772 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1774 iwmmxt_load_reg(cpu_V1, rn);
1775 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1776 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1779 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1780 TCGv_i32 dest)
1782 int rd;
1783 uint32_t offset;
1784 TCGv_i32 tmp;
1786 rd = (insn >> 16) & 0xf;
1787 tmp = load_reg(s, rd);
1789 offset = (insn & 0xff) << ((insn >> 7) & 2);
1790 if (insn & (1 << 24)) {
1791 /* Pre indexed */
1792 if (insn & (1 << 23))
1793 tcg_gen_addi_i32(tmp, tmp, offset);
1794 else
1795 tcg_gen_addi_i32(tmp, tmp, -offset);
1796 tcg_gen_mov_i32(dest, tmp);
1797 if (insn & (1 << 21))
1798 store_reg(s, rd, tmp);
1799 else
1800 tcg_temp_free_i32(tmp);
1801 } else if (insn & (1 << 21)) {
1802 /* Post indexed */
1803 tcg_gen_mov_i32(dest, tmp);
1804 if (insn & (1 << 23))
1805 tcg_gen_addi_i32(tmp, tmp, offset);
1806 else
1807 tcg_gen_addi_i32(tmp, tmp, -offset);
1808 store_reg(s, rd, tmp);
1809 } else if (!(insn & (1 << 23)))
1810 return 1;
1811 return 0;
1814 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1816 int rd = (insn >> 0) & 0xf;
1817 TCGv_i32 tmp;
1819 if (insn & (1 << 8)) {
1820 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1821 return 1;
1822 } else {
1823 tmp = iwmmxt_load_creg(rd);
1825 } else {
1826 tmp = tcg_temp_new_i32();
1827 iwmmxt_load_reg(cpu_V0, rd);
1828 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1830 tcg_gen_andi_i32(tmp, tmp, mask);
1831 tcg_gen_mov_i32(dest, tmp);
1832 tcg_temp_free_i32(tmp);
1833 return 0;
1836 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1837 (ie. an undefined instruction). */
1838 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1840 int rd, wrd;
1841 int rdhi, rdlo, rd0, rd1, i;
1842 TCGv_i32 addr;
1843 TCGv_i32 tmp, tmp2, tmp3;
1845 if ((insn & 0x0e000e00) == 0x0c000000) {
1846 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1847 wrd = insn & 0xf;
1848 rdlo = (insn >> 12) & 0xf;
1849 rdhi = (insn >> 16) & 0xf;
1850 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1851 iwmmxt_load_reg(cpu_V0, wrd);
1852 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1853 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1854 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1855 } else { /* TMCRR */
1856 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1857 iwmmxt_store_reg(cpu_V0, wrd);
1858 gen_op_iwmmxt_set_mup();
1860 return 0;
1863 wrd = (insn >> 12) & 0xf;
1864 addr = tcg_temp_new_i32();
1865 if (gen_iwmmxt_address(s, insn, addr)) {
1866 tcg_temp_free_i32(addr);
1867 return 1;
1869 if (insn & ARM_CP_RW_BIT) {
1870 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1871 tmp = tcg_temp_new_i32();
1872 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1873 iwmmxt_store_creg(wrd, tmp);
1874 } else {
1875 i = 1;
1876 if (insn & (1 << 8)) {
1877 if (insn & (1 << 22)) { /* WLDRD */
1878 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1879 i = 0;
1880 } else { /* WLDRW wRd */
1881 tmp = tcg_temp_new_i32();
1882 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1884 } else {
1885 tmp = tcg_temp_new_i32();
1886 if (insn & (1 << 22)) { /* WLDRH */
1887 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1888 } else { /* WLDRB */
1889 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1892 if (i) {
1893 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1894 tcg_temp_free_i32(tmp);
1896 gen_op_iwmmxt_movq_wRn_M0(wrd);
1898 } else {
1899 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1900 tmp = iwmmxt_load_creg(wrd);
1901 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1902 } else {
1903 gen_op_iwmmxt_movq_M0_wRn(wrd);
1904 tmp = tcg_temp_new_i32();
1905 if (insn & (1 << 8)) {
1906 if (insn & (1 << 22)) { /* WSTRD */
1907 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1908 } else { /* WSTRW wRd */
1909 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1910 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1912 } else {
1913 if (insn & (1 << 22)) { /* WSTRH */
1914 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1915 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1916 } else { /* WSTRB */
1917 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1918 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1922 tcg_temp_free_i32(tmp);
1924 tcg_temp_free_i32(addr);
1925 return 0;
1928 if ((insn & 0x0f000000) != 0x0e000000)
1929 return 1;
1931 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1932 case 0x000: /* WOR */
1933 wrd = (insn >> 12) & 0xf;
1934 rd0 = (insn >> 0) & 0xf;
1935 rd1 = (insn >> 16) & 0xf;
1936 gen_op_iwmmxt_movq_M0_wRn(rd0);
1937 gen_op_iwmmxt_orq_M0_wRn(rd1);
1938 gen_op_iwmmxt_setpsr_nz();
1939 gen_op_iwmmxt_movq_wRn_M0(wrd);
1940 gen_op_iwmmxt_set_mup();
1941 gen_op_iwmmxt_set_cup();
1942 break;
1943 case 0x011: /* TMCR */
1944 if (insn & 0xf)
1945 return 1;
1946 rd = (insn >> 12) & 0xf;
1947 wrd = (insn >> 16) & 0xf;
1948 switch (wrd) {
1949 case ARM_IWMMXT_wCID:
1950 case ARM_IWMMXT_wCASF:
1951 break;
1952 case ARM_IWMMXT_wCon:
1953 gen_op_iwmmxt_set_cup();
1954 /* Fall through. */
1955 case ARM_IWMMXT_wCSSF:
1956 tmp = iwmmxt_load_creg(wrd);
1957 tmp2 = load_reg(s, rd);
1958 tcg_gen_andc_i32(tmp, tmp, tmp2);
1959 tcg_temp_free_i32(tmp2);
1960 iwmmxt_store_creg(wrd, tmp);
1961 break;
1962 case ARM_IWMMXT_wCGR0:
1963 case ARM_IWMMXT_wCGR1:
1964 case ARM_IWMMXT_wCGR2:
1965 case ARM_IWMMXT_wCGR3:
1966 gen_op_iwmmxt_set_cup();
1967 tmp = load_reg(s, rd);
1968 iwmmxt_store_creg(wrd, tmp);
1969 break;
1970 default:
1971 return 1;
1973 break;
1974 case 0x100: /* WXOR */
1975 wrd = (insn >> 12) & 0xf;
1976 rd0 = (insn >> 0) & 0xf;
1977 rd1 = (insn >> 16) & 0xf;
1978 gen_op_iwmmxt_movq_M0_wRn(rd0);
1979 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1980 gen_op_iwmmxt_setpsr_nz();
1981 gen_op_iwmmxt_movq_wRn_M0(wrd);
1982 gen_op_iwmmxt_set_mup();
1983 gen_op_iwmmxt_set_cup();
1984 break;
1985 case 0x111: /* TMRC */
1986 if (insn & 0xf)
1987 return 1;
1988 rd = (insn >> 12) & 0xf;
1989 wrd = (insn >> 16) & 0xf;
1990 tmp = iwmmxt_load_creg(wrd);
1991 store_reg(s, rd, tmp);
1992 break;
1993 case 0x300: /* WANDN */
1994 wrd = (insn >> 12) & 0xf;
1995 rd0 = (insn >> 0) & 0xf;
1996 rd1 = (insn >> 16) & 0xf;
1997 gen_op_iwmmxt_movq_M0_wRn(rd0);
1998 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1999 gen_op_iwmmxt_andq_M0_wRn(rd1);
2000 gen_op_iwmmxt_setpsr_nz();
2001 gen_op_iwmmxt_movq_wRn_M0(wrd);
2002 gen_op_iwmmxt_set_mup();
2003 gen_op_iwmmxt_set_cup();
2004 break;
2005 case 0x200: /* WAND */
2006 wrd = (insn >> 12) & 0xf;
2007 rd0 = (insn >> 0) & 0xf;
2008 rd1 = (insn >> 16) & 0xf;
2009 gen_op_iwmmxt_movq_M0_wRn(rd0);
2010 gen_op_iwmmxt_andq_M0_wRn(rd1);
2011 gen_op_iwmmxt_setpsr_nz();
2012 gen_op_iwmmxt_movq_wRn_M0(wrd);
2013 gen_op_iwmmxt_set_mup();
2014 gen_op_iwmmxt_set_cup();
2015 break;
2016 case 0x810: case 0xa10: /* WMADD */
2017 wrd = (insn >> 12) & 0xf;
2018 rd0 = (insn >> 0) & 0xf;
2019 rd1 = (insn >> 16) & 0xf;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0);
2021 if (insn & (1 << 21))
2022 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2023 else
2024 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2025 gen_op_iwmmxt_movq_wRn_M0(wrd);
2026 gen_op_iwmmxt_set_mup();
2027 break;
2028 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2029 wrd = (insn >> 12) & 0xf;
2030 rd0 = (insn >> 16) & 0xf;
2031 rd1 = (insn >> 0) & 0xf;
2032 gen_op_iwmmxt_movq_M0_wRn(rd0);
2033 switch ((insn >> 22) & 3) {
2034 case 0:
2035 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2036 break;
2037 case 1:
2038 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2039 break;
2040 case 2:
2041 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2042 break;
2043 case 3:
2044 return 1;
2046 gen_op_iwmmxt_movq_wRn_M0(wrd);
2047 gen_op_iwmmxt_set_mup();
2048 gen_op_iwmmxt_set_cup();
2049 break;
2050 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2051 wrd = (insn >> 12) & 0xf;
2052 rd0 = (insn >> 16) & 0xf;
2053 rd1 = (insn >> 0) & 0xf;
2054 gen_op_iwmmxt_movq_M0_wRn(rd0);
2055 switch ((insn >> 22) & 3) {
2056 case 0:
2057 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2058 break;
2059 case 1:
2060 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2061 break;
2062 case 2:
2063 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2064 break;
2065 case 3:
2066 return 1;
2068 gen_op_iwmmxt_movq_wRn_M0(wrd);
2069 gen_op_iwmmxt_set_mup();
2070 gen_op_iwmmxt_set_cup();
2071 break;
2072 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2073 wrd = (insn >> 12) & 0xf;
2074 rd0 = (insn >> 16) & 0xf;
2075 rd1 = (insn >> 0) & 0xf;
2076 gen_op_iwmmxt_movq_M0_wRn(rd0);
2077 if (insn & (1 << 22))
2078 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2079 else
2080 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2081 if (!(insn & (1 << 20)))
2082 gen_op_iwmmxt_addl_M0_wRn(wrd);
2083 gen_op_iwmmxt_movq_wRn_M0(wrd);
2084 gen_op_iwmmxt_set_mup();
2085 break;
2086 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2087 wrd = (insn >> 12) & 0xf;
2088 rd0 = (insn >> 16) & 0xf;
2089 rd1 = (insn >> 0) & 0xf;
2090 gen_op_iwmmxt_movq_M0_wRn(rd0);
2091 if (insn & (1 << 21)) {
2092 if (insn & (1 << 20))
2093 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2094 else
2095 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2096 } else {
2097 if (insn & (1 << 20))
2098 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2099 else
2100 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2102 gen_op_iwmmxt_movq_wRn_M0(wrd);
2103 gen_op_iwmmxt_set_mup();
2104 break;
2105 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2106 wrd = (insn >> 12) & 0xf;
2107 rd0 = (insn >> 16) & 0xf;
2108 rd1 = (insn >> 0) & 0xf;
2109 gen_op_iwmmxt_movq_M0_wRn(rd0);
2110 if (insn & (1 << 21))
2111 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2112 else
2113 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2114 if (!(insn & (1 << 20))) {
2115 iwmmxt_load_reg(cpu_V1, wrd);
2116 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2118 gen_op_iwmmxt_movq_wRn_M0(wrd);
2119 gen_op_iwmmxt_set_mup();
2120 break;
2121 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2122 wrd = (insn >> 12) & 0xf;
2123 rd0 = (insn >> 16) & 0xf;
2124 rd1 = (insn >> 0) & 0xf;
2125 gen_op_iwmmxt_movq_M0_wRn(rd0);
2126 switch ((insn >> 22) & 3) {
2127 case 0:
2128 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2129 break;
2130 case 1:
2131 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2132 break;
2133 case 2:
2134 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2135 break;
2136 case 3:
2137 return 1;
2139 gen_op_iwmmxt_movq_wRn_M0(wrd);
2140 gen_op_iwmmxt_set_mup();
2141 gen_op_iwmmxt_set_cup();
2142 break;
2143 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2144 wrd = (insn >> 12) & 0xf;
2145 rd0 = (insn >> 16) & 0xf;
2146 rd1 = (insn >> 0) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0);
2148 if (insn & (1 << 22)) {
2149 if (insn & (1 << 20))
2150 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2151 else
2152 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2153 } else {
2154 if (insn & (1 << 20))
2155 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2156 else
2157 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2159 gen_op_iwmmxt_movq_wRn_M0(wrd);
2160 gen_op_iwmmxt_set_mup();
2161 gen_op_iwmmxt_set_cup();
2162 break;
2163 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2164 wrd = (insn >> 12) & 0xf;
2165 rd0 = (insn >> 16) & 0xf;
2166 rd1 = (insn >> 0) & 0xf;
2167 gen_op_iwmmxt_movq_M0_wRn(rd0);
2168 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2169 tcg_gen_andi_i32(tmp, tmp, 7);
2170 iwmmxt_load_reg(cpu_V1, rd1);
2171 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2172 tcg_temp_free_i32(tmp);
2173 gen_op_iwmmxt_movq_wRn_M0(wrd);
2174 gen_op_iwmmxt_set_mup();
2175 break;
2176 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2177 if (((insn >> 6) & 3) == 3)
2178 return 1;
2179 rd = (insn >> 12) & 0xf;
2180 wrd = (insn >> 16) & 0xf;
2181 tmp = load_reg(s, rd);
2182 gen_op_iwmmxt_movq_M0_wRn(wrd);
2183 switch ((insn >> 6) & 3) {
2184 case 0:
2185 tmp2 = tcg_const_i32(0xff);
2186 tmp3 = tcg_const_i32((insn & 7) << 3);
2187 break;
2188 case 1:
2189 tmp2 = tcg_const_i32(0xffff);
2190 tmp3 = tcg_const_i32((insn & 3) << 4);
2191 break;
2192 case 2:
2193 tmp2 = tcg_const_i32(0xffffffff);
2194 tmp3 = tcg_const_i32((insn & 1) << 5);
2195 break;
2196 default:
2197 tmp2 = NULL;
2198 tmp3 = NULL;
2200 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2201 tcg_temp_free_i32(tmp3);
2202 tcg_temp_free_i32(tmp2);
2203 tcg_temp_free_i32(tmp);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd);
2205 gen_op_iwmmxt_set_mup();
2206 break;
2207 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2208 rd = (insn >> 12) & 0xf;
2209 wrd = (insn >> 16) & 0xf;
2210 if (rd == 15 || ((insn >> 22) & 3) == 3)
2211 return 1;
2212 gen_op_iwmmxt_movq_M0_wRn(wrd);
2213 tmp = tcg_temp_new_i32();
2214 switch ((insn >> 22) & 3) {
2215 case 0:
2216 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2217 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2218 if (insn & 8) {
2219 tcg_gen_ext8s_i32(tmp, tmp);
2220 } else {
2221 tcg_gen_andi_i32(tmp, tmp, 0xff);
2223 break;
2224 case 1:
2225 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2226 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2227 if (insn & 8) {
2228 tcg_gen_ext16s_i32(tmp, tmp);
2229 } else {
2230 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2232 break;
2233 case 2:
2234 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2235 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2236 break;
2238 store_reg(s, rd, tmp);
2239 break;
2240 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2241 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2242 return 1;
2243 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2244 switch ((insn >> 22) & 3) {
2245 case 0:
2246 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2247 break;
2248 case 1:
2249 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2250 break;
2251 case 2:
2252 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2253 break;
2255 tcg_gen_shli_i32(tmp, tmp, 28);
2256 gen_set_nzcv(tmp);
2257 tcg_temp_free_i32(tmp);
2258 break;
2259 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2260 if (((insn >> 6) & 3) == 3)
2261 return 1;
2262 rd = (insn >> 12) & 0xf;
2263 wrd = (insn >> 16) & 0xf;
2264 tmp = load_reg(s, rd);
2265 switch ((insn >> 6) & 3) {
2266 case 0:
2267 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2268 break;
2269 case 1:
2270 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2271 break;
2272 case 2:
2273 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2274 break;
2276 tcg_temp_free_i32(tmp);
2277 gen_op_iwmmxt_movq_wRn_M0(wrd);
2278 gen_op_iwmmxt_set_mup();
2279 break;
2280 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2281 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2282 return 1;
2283 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2284 tmp2 = tcg_temp_new_i32();
2285 tcg_gen_mov_i32(tmp2, tmp);
2286 switch ((insn >> 22) & 3) {
2287 case 0:
2288 for (i = 0; i < 7; i ++) {
2289 tcg_gen_shli_i32(tmp2, tmp2, 4);
2290 tcg_gen_and_i32(tmp, tmp, tmp2);
2292 break;
2293 case 1:
2294 for (i = 0; i < 3; i ++) {
2295 tcg_gen_shli_i32(tmp2, tmp2, 8);
2296 tcg_gen_and_i32(tmp, tmp, tmp2);
2298 break;
2299 case 2:
2300 tcg_gen_shli_i32(tmp2, tmp2, 16);
2301 tcg_gen_and_i32(tmp, tmp, tmp2);
2302 break;
2304 gen_set_nzcv(tmp);
2305 tcg_temp_free_i32(tmp2);
2306 tcg_temp_free_i32(tmp);
2307 break;
2308 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2309 wrd = (insn >> 12) & 0xf;
2310 rd0 = (insn >> 16) & 0xf;
2311 gen_op_iwmmxt_movq_M0_wRn(rd0);
2312 switch ((insn >> 22) & 3) {
2313 case 0:
2314 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2315 break;
2316 case 1:
2317 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2318 break;
2319 case 2:
2320 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2321 break;
2322 case 3:
2323 return 1;
2325 gen_op_iwmmxt_movq_wRn_M0(wrd);
2326 gen_op_iwmmxt_set_mup();
2327 break;
2328 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2329 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2330 return 1;
2331 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2332 tmp2 = tcg_temp_new_i32();
2333 tcg_gen_mov_i32(tmp2, tmp);
2334 switch ((insn >> 22) & 3) {
2335 case 0:
2336 for (i = 0; i < 7; i ++) {
2337 tcg_gen_shli_i32(tmp2, tmp2, 4);
2338 tcg_gen_or_i32(tmp, tmp, tmp2);
2340 break;
2341 case 1:
2342 for (i = 0; i < 3; i ++) {
2343 tcg_gen_shli_i32(tmp2, tmp2, 8);
2344 tcg_gen_or_i32(tmp, tmp, tmp2);
2346 break;
2347 case 2:
2348 tcg_gen_shli_i32(tmp2, tmp2, 16);
2349 tcg_gen_or_i32(tmp, tmp, tmp2);
2350 break;
2352 gen_set_nzcv(tmp);
2353 tcg_temp_free_i32(tmp2);
2354 tcg_temp_free_i32(tmp);
2355 break;
2356 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2357 rd = (insn >> 12) & 0xf;
2358 rd0 = (insn >> 16) & 0xf;
2359 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2360 return 1;
2361 gen_op_iwmmxt_movq_M0_wRn(rd0);
2362 tmp = tcg_temp_new_i32();
2363 switch ((insn >> 22) & 3) {
2364 case 0:
2365 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2366 break;
2367 case 1:
2368 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2369 break;
2370 case 2:
2371 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2372 break;
2374 store_reg(s, rd, tmp);
2375 break;
2376 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2377 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2378 wrd = (insn >> 12) & 0xf;
2379 rd0 = (insn >> 16) & 0xf;
2380 rd1 = (insn >> 0) & 0xf;
2381 gen_op_iwmmxt_movq_M0_wRn(rd0);
2382 switch ((insn >> 22) & 3) {
2383 case 0:
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2386 else
2387 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2388 break;
2389 case 1:
2390 if (insn & (1 << 21))
2391 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2392 else
2393 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2394 break;
2395 case 2:
2396 if (insn & (1 << 21))
2397 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2398 else
2399 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2400 break;
2401 case 3:
2402 return 1;
2404 gen_op_iwmmxt_movq_wRn_M0(wrd);
2405 gen_op_iwmmxt_set_mup();
2406 gen_op_iwmmxt_set_cup();
2407 break;
2408 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2409 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2410 wrd = (insn >> 12) & 0xf;
2411 rd0 = (insn >> 16) & 0xf;
2412 gen_op_iwmmxt_movq_M0_wRn(rd0);
2413 switch ((insn >> 22) & 3) {
2414 case 0:
2415 if (insn & (1 << 21))
2416 gen_op_iwmmxt_unpacklsb_M0();
2417 else
2418 gen_op_iwmmxt_unpacklub_M0();
2419 break;
2420 case 1:
2421 if (insn & (1 << 21))
2422 gen_op_iwmmxt_unpacklsw_M0();
2423 else
2424 gen_op_iwmmxt_unpackluw_M0();
2425 break;
2426 case 2:
2427 if (insn & (1 << 21))
2428 gen_op_iwmmxt_unpacklsl_M0();
2429 else
2430 gen_op_iwmmxt_unpacklul_M0();
2431 break;
2432 case 3:
2433 return 1;
2435 gen_op_iwmmxt_movq_wRn_M0(wrd);
2436 gen_op_iwmmxt_set_mup();
2437 gen_op_iwmmxt_set_cup();
2438 break;
2439 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2440 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2441 wrd = (insn >> 12) & 0xf;
2442 rd0 = (insn >> 16) & 0xf;
2443 gen_op_iwmmxt_movq_M0_wRn(rd0);
2444 switch ((insn >> 22) & 3) {
2445 case 0:
2446 if (insn & (1 << 21))
2447 gen_op_iwmmxt_unpackhsb_M0();
2448 else
2449 gen_op_iwmmxt_unpackhub_M0();
2450 break;
2451 case 1:
2452 if (insn & (1 << 21))
2453 gen_op_iwmmxt_unpackhsw_M0();
2454 else
2455 gen_op_iwmmxt_unpackhuw_M0();
2456 break;
2457 case 2:
2458 if (insn & (1 << 21))
2459 gen_op_iwmmxt_unpackhsl_M0();
2460 else
2461 gen_op_iwmmxt_unpackhul_M0();
2462 break;
2463 case 3:
2464 return 1;
2466 gen_op_iwmmxt_movq_wRn_M0(wrd);
2467 gen_op_iwmmxt_set_mup();
2468 gen_op_iwmmxt_set_cup();
2469 break;
2470 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2471 case 0x214: case 0x614: case 0xa14: case 0xe14:
2472 if (((insn >> 22) & 3) == 0)
2473 return 1;
2474 wrd = (insn >> 12) & 0xf;
2475 rd0 = (insn >> 16) & 0xf;
2476 gen_op_iwmmxt_movq_M0_wRn(rd0);
2477 tmp = tcg_temp_new_i32();
2478 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2479 tcg_temp_free_i32(tmp);
2480 return 1;
2482 switch ((insn >> 22) & 3) {
2483 case 1:
2484 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2485 break;
2486 case 2:
2487 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2488 break;
2489 case 3:
2490 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2491 break;
2493 tcg_temp_free_i32(tmp);
2494 gen_op_iwmmxt_movq_wRn_M0(wrd);
2495 gen_op_iwmmxt_set_mup();
2496 gen_op_iwmmxt_set_cup();
2497 break;
2498 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2499 case 0x014: case 0x414: case 0x814: case 0xc14:
2500 if (((insn >> 22) & 3) == 0)
2501 return 1;
2502 wrd = (insn >> 12) & 0xf;
2503 rd0 = (insn >> 16) & 0xf;
2504 gen_op_iwmmxt_movq_M0_wRn(rd0);
2505 tmp = tcg_temp_new_i32();
2506 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2507 tcg_temp_free_i32(tmp);
2508 return 1;
2510 switch ((insn >> 22) & 3) {
2511 case 1:
2512 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2513 break;
2514 case 2:
2515 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2516 break;
2517 case 3:
2518 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2519 break;
2521 tcg_temp_free_i32(tmp);
2522 gen_op_iwmmxt_movq_wRn_M0(wrd);
2523 gen_op_iwmmxt_set_mup();
2524 gen_op_iwmmxt_set_cup();
2525 break;
2526 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2527 case 0x114: case 0x514: case 0x914: case 0xd14:
2528 if (((insn >> 22) & 3) == 0)
2529 return 1;
2530 wrd = (insn >> 12) & 0xf;
2531 rd0 = (insn >> 16) & 0xf;
2532 gen_op_iwmmxt_movq_M0_wRn(rd0);
2533 tmp = tcg_temp_new_i32();
2534 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2535 tcg_temp_free_i32(tmp);
2536 return 1;
2538 switch ((insn >> 22) & 3) {
2539 case 1:
2540 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2541 break;
2542 case 2:
2543 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2544 break;
2545 case 3:
2546 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2547 break;
2549 tcg_temp_free_i32(tmp);
2550 gen_op_iwmmxt_movq_wRn_M0(wrd);
2551 gen_op_iwmmxt_set_mup();
2552 gen_op_iwmmxt_set_cup();
2553 break;
2554 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2555 case 0x314: case 0x714: case 0xb14: case 0xf14:
2556 if (((insn >> 22) & 3) == 0)
2557 return 1;
2558 wrd = (insn >> 12) & 0xf;
2559 rd0 = (insn >> 16) & 0xf;
2560 gen_op_iwmmxt_movq_M0_wRn(rd0);
2561 tmp = tcg_temp_new_i32();
2562 switch ((insn >> 22) & 3) {
2563 case 1:
2564 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2565 tcg_temp_free_i32(tmp);
2566 return 1;
2568 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2569 break;
2570 case 2:
2571 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2572 tcg_temp_free_i32(tmp);
2573 return 1;
2575 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2576 break;
2577 case 3:
2578 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2579 tcg_temp_free_i32(tmp);
2580 return 1;
2582 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2583 break;
2585 tcg_temp_free_i32(tmp);
2586 gen_op_iwmmxt_movq_wRn_M0(wrd);
2587 gen_op_iwmmxt_set_mup();
2588 gen_op_iwmmxt_set_cup();
2589 break;
2590 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2591 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2592 wrd = (insn >> 12) & 0xf;
2593 rd0 = (insn >> 16) & 0xf;
2594 rd1 = (insn >> 0) & 0xf;
2595 gen_op_iwmmxt_movq_M0_wRn(rd0);
2596 switch ((insn >> 22) & 3) {
2597 case 0:
2598 if (insn & (1 << 21))
2599 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2600 else
2601 gen_op_iwmmxt_minub_M0_wRn(rd1);
2602 break;
2603 case 1:
2604 if (insn & (1 << 21))
2605 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2606 else
2607 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2608 break;
2609 case 2:
2610 if (insn & (1 << 21))
2611 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2612 else
2613 gen_op_iwmmxt_minul_M0_wRn(rd1);
2614 break;
2615 case 3:
2616 return 1;
2618 gen_op_iwmmxt_movq_wRn_M0(wrd);
2619 gen_op_iwmmxt_set_mup();
2620 break;
2621 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2622 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2623 wrd = (insn >> 12) & 0xf;
2624 rd0 = (insn >> 16) & 0xf;
2625 rd1 = (insn >> 0) & 0xf;
2626 gen_op_iwmmxt_movq_M0_wRn(rd0);
2627 switch ((insn >> 22) & 3) {
2628 case 0:
2629 if (insn & (1 << 21))
2630 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2631 else
2632 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2633 break;
2634 case 1:
2635 if (insn & (1 << 21))
2636 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2637 else
2638 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2639 break;
2640 case 2:
2641 if (insn & (1 << 21))
2642 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2643 else
2644 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2645 break;
2646 case 3:
2647 return 1;
2649 gen_op_iwmmxt_movq_wRn_M0(wrd);
2650 gen_op_iwmmxt_set_mup();
2651 break;
2652 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2653 case 0x402: case 0x502: case 0x602: case 0x702:
2654 wrd = (insn >> 12) & 0xf;
2655 rd0 = (insn >> 16) & 0xf;
2656 rd1 = (insn >> 0) & 0xf;
2657 gen_op_iwmmxt_movq_M0_wRn(rd0);
2658 tmp = tcg_const_i32((insn >> 20) & 3);
2659 iwmmxt_load_reg(cpu_V1, rd1);
2660 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2661 tcg_temp_free_i32(tmp);
2662 gen_op_iwmmxt_movq_wRn_M0(wrd);
2663 gen_op_iwmmxt_set_mup();
2664 break;
2665 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2666 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2667 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2668 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2669 wrd = (insn >> 12) & 0xf;
2670 rd0 = (insn >> 16) & 0xf;
2671 rd1 = (insn >> 0) & 0xf;
2672 gen_op_iwmmxt_movq_M0_wRn(rd0);
2673 switch ((insn >> 20) & 0xf) {
2674 case 0x0:
2675 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2676 break;
2677 case 0x1:
2678 gen_op_iwmmxt_subub_M0_wRn(rd1);
2679 break;
2680 case 0x3:
2681 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2682 break;
2683 case 0x4:
2684 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2685 break;
2686 case 0x5:
2687 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2688 break;
2689 case 0x7:
2690 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2691 break;
2692 case 0x8:
2693 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2694 break;
2695 case 0x9:
2696 gen_op_iwmmxt_subul_M0_wRn(rd1);
2697 break;
2698 case 0xb:
2699 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2700 break;
2701 default:
2702 return 1;
2704 gen_op_iwmmxt_movq_wRn_M0(wrd);
2705 gen_op_iwmmxt_set_mup();
2706 gen_op_iwmmxt_set_cup();
2707 break;
2708 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2709 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2710 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2711 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2712 wrd = (insn >> 12) & 0xf;
2713 rd0 = (insn >> 16) & 0xf;
2714 gen_op_iwmmxt_movq_M0_wRn(rd0);
2715 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2716 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2717 tcg_temp_free_i32(tmp);
2718 gen_op_iwmmxt_movq_wRn_M0(wrd);
2719 gen_op_iwmmxt_set_mup();
2720 gen_op_iwmmxt_set_cup();
2721 break;
2722 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2723 case 0x418: case 0x518: case 0x618: case 0x718:
2724 case 0x818: case 0x918: case 0xa18: case 0xb18:
2725 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2726 wrd = (insn >> 12) & 0xf;
2727 rd0 = (insn >> 16) & 0xf;
2728 rd1 = (insn >> 0) & 0xf;
2729 gen_op_iwmmxt_movq_M0_wRn(rd0);
2730 switch ((insn >> 20) & 0xf) {
2731 case 0x0:
2732 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2733 break;
2734 case 0x1:
2735 gen_op_iwmmxt_addub_M0_wRn(rd1);
2736 break;
2737 case 0x3:
2738 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2739 break;
2740 case 0x4:
2741 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2742 break;
2743 case 0x5:
2744 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2745 break;
2746 case 0x7:
2747 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2748 break;
2749 case 0x8:
2750 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2751 break;
2752 case 0x9:
2753 gen_op_iwmmxt_addul_M0_wRn(rd1);
2754 break;
2755 case 0xb:
2756 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2757 break;
2758 default:
2759 return 1;
2761 gen_op_iwmmxt_movq_wRn_M0(wrd);
2762 gen_op_iwmmxt_set_mup();
2763 gen_op_iwmmxt_set_cup();
2764 break;
2765 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2766 case 0x408: case 0x508: case 0x608: case 0x708:
2767 case 0x808: case 0x908: case 0xa08: case 0xb08:
2768 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2769 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2770 return 1;
2771 wrd = (insn >> 12) & 0xf;
2772 rd0 = (insn >> 16) & 0xf;
2773 rd1 = (insn >> 0) & 0xf;
2774 gen_op_iwmmxt_movq_M0_wRn(rd0);
2775 switch ((insn >> 22) & 3) {
2776 case 1:
2777 if (insn & (1 << 21))
2778 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2779 else
2780 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2781 break;
2782 case 2:
2783 if (insn & (1 << 21))
2784 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2785 else
2786 gen_op_iwmmxt_packul_M0_wRn(rd1);
2787 break;
2788 case 3:
2789 if (insn & (1 << 21))
2790 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2791 else
2792 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2793 break;
2795 gen_op_iwmmxt_movq_wRn_M0(wrd);
2796 gen_op_iwmmxt_set_mup();
2797 gen_op_iwmmxt_set_cup();
2798 break;
2799 case 0x201: case 0x203: case 0x205: case 0x207:
2800 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2801 case 0x211: case 0x213: case 0x215: case 0x217:
2802 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2803 wrd = (insn >> 5) & 0xf;
2804 rd0 = (insn >> 12) & 0xf;
2805 rd1 = (insn >> 0) & 0xf;
2806 if (rd0 == 0xf || rd1 == 0xf)
2807 return 1;
2808 gen_op_iwmmxt_movq_M0_wRn(wrd);
2809 tmp = load_reg(s, rd0);
2810 tmp2 = load_reg(s, rd1);
2811 switch ((insn >> 16) & 0xf) {
2812 case 0x0: /* TMIA */
2813 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2814 break;
2815 case 0x8: /* TMIAPH */
2816 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2817 break;
2818 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2819 if (insn & (1 << 16))
2820 tcg_gen_shri_i32(tmp, tmp, 16);
2821 if (insn & (1 << 17))
2822 tcg_gen_shri_i32(tmp2, tmp2, 16);
2823 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2824 break;
2825 default:
2826 tcg_temp_free_i32(tmp2);
2827 tcg_temp_free_i32(tmp);
2828 return 1;
2830 tcg_temp_free_i32(tmp2);
2831 tcg_temp_free_i32(tmp);
2832 gen_op_iwmmxt_movq_wRn_M0(wrd);
2833 gen_op_iwmmxt_set_mup();
2834 break;
2835 default:
2836 return 1;
2839 return 0;
2842 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2843 (ie. an undefined instruction). */
2844 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2846 int acc, rd0, rd1, rdhi, rdlo;
2847 TCGv_i32 tmp, tmp2;
2849 if ((insn & 0x0ff00f10) == 0x0e200010) {
2850 /* Multiply with Internal Accumulate Format */
2851 rd0 = (insn >> 12) & 0xf;
2852 rd1 = insn & 0xf;
2853 acc = (insn >> 5) & 7;
2855 if (acc != 0)
2856 return 1;
2858 tmp = load_reg(s, rd0);
2859 tmp2 = load_reg(s, rd1);
2860 switch ((insn >> 16) & 0xf) {
2861 case 0x0: /* MIA */
2862 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2863 break;
2864 case 0x8: /* MIAPH */
2865 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2866 break;
2867 case 0xc: /* MIABB */
2868 case 0xd: /* MIABT */
2869 case 0xe: /* MIATB */
2870 case 0xf: /* MIATT */
2871 if (insn & (1 << 16))
2872 tcg_gen_shri_i32(tmp, tmp, 16);
2873 if (insn & (1 << 17))
2874 tcg_gen_shri_i32(tmp2, tmp2, 16);
2875 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2876 break;
2877 default:
2878 return 1;
2880 tcg_temp_free_i32(tmp2);
2881 tcg_temp_free_i32(tmp);
2883 gen_op_iwmmxt_movq_wRn_M0(acc);
2884 return 0;
2887 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2888 /* Internal Accumulator Access Format */
2889 rdhi = (insn >> 16) & 0xf;
2890 rdlo = (insn >> 12) & 0xf;
2891 acc = insn & 7;
2893 if (acc != 0)
2894 return 1;
2896 if (insn & ARM_CP_RW_BIT) { /* MRA */
2897 iwmmxt_load_reg(cpu_V0, acc);
2898 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2899 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2900 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2901 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2902 } else { /* MAR */
2903 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2904 iwmmxt_store_reg(cpu_V0, acc);
2906 return 0;
2909 return 1;
2912 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2913 #define VFP_SREG(insn, bigbit, smallbit) \
2914 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2915 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2916 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2917 reg = (((insn) >> (bigbit)) & 0x0f) \
2918 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2919 } else { \
2920 if (insn & (1 << (smallbit))) \
2921 return 1; \
2922 reg = ((insn) >> (bigbit)) & 0x0f; \
2923 }} while (0)
2925 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2926 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2927 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2928 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2929 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2930 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2932 /* Move between integer and VFP cores. */
2933 static TCGv_i32 gen_vfp_mrs(void)
2935 TCGv_i32 tmp = tcg_temp_new_i32();
2936 tcg_gen_mov_i32(tmp, cpu_F0s);
2937 return tmp;
2940 static void gen_vfp_msr(TCGv_i32 tmp)
2942 tcg_gen_mov_i32(cpu_F0s, tmp);
2943 tcg_temp_free_i32(tmp);
2946 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2948 TCGv_i32 tmp = tcg_temp_new_i32();
2949 if (shift)
2950 tcg_gen_shri_i32(var, var, shift);
2951 tcg_gen_ext8u_i32(var, var);
2952 tcg_gen_shli_i32(tmp, var, 8);
2953 tcg_gen_or_i32(var, var, tmp);
2954 tcg_gen_shli_i32(tmp, var, 16);
2955 tcg_gen_or_i32(var, var, tmp);
2956 tcg_temp_free_i32(tmp);
2959 static void gen_neon_dup_low16(TCGv_i32 var)
2961 TCGv_i32 tmp = tcg_temp_new_i32();
2962 tcg_gen_ext16u_i32(var, var);
2963 tcg_gen_shli_i32(tmp, var, 16);
2964 tcg_gen_or_i32(var, var, tmp);
2965 tcg_temp_free_i32(tmp);
2968 static void gen_neon_dup_high16(TCGv_i32 var)
2970 TCGv_i32 tmp = tcg_temp_new_i32();
2971 tcg_gen_andi_i32(var, var, 0xffff0000);
2972 tcg_gen_shri_i32(tmp, var, 16);
2973 tcg_gen_or_i32(var, var, tmp);
2974 tcg_temp_free_i32(tmp);
2977 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2979 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2980 TCGv_i32 tmp = tcg_temp_new_i32();
2981 switch (size) {
2982 case 0:
2983 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2984 gen_neon_dup_u8(tmp, 0);
2985 break;
2986 case 1:
2987 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2988 gen_neon_dup_low16(tmp);
2989 break;
2990 case 2:
2991 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2992 break;
2993 default: /* Avoid compiler warnings. */
2994 abort();
2996 return tmp;
2999 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3000 uint32_t dp)
3002 uint32_t cc = extract32(insn, 20, 2);
3004 if (dp) {
3005 TCGv_i64 frn, frm, dest;
3006 TCGv_i64 tmp, zero, zf, nf, vf;
3008 zero = tcg_const_i64(0);
3010 frn = tcg_temp_new_i64();
3011 frm = tcg_temp_new_i64();
3012 dest = tcg_temp_new_i64();
3014 zf = tcg_temp_new_i64();
3015 nf = tcg_temp_new_i64();
3016 vf = tcg_temp_new_i64();
3018 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3019 tcg_gen_ext_i32_i64(nf, cpu_NF);
3020 tcg_gen_ext_i32_i64(vf, cpu_VF);
3022 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3023 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3024 switch (cc) {
3025 case 0: /* eq: Z */
3026 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3027 frn, frm);
3028 break;
3029 case 1: /* vs: V */
3030 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3031 frn, frm);
3032 break;
3033 case 2: /* ge: N == V -> N ^ V == 0 */
3034 tmp = tcg_temp_new_i64();
3035 tcg_gen_xor_i64(tmp, vf, nf);
3036 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3037 frn, frm);
3038 tcg_temp_free_i64(tmp);
3039 break;
3040 case 3: /* gt: !Z && N == V */
3041 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3042 frn, frm);
3043 tmp = tcg_temp_new_i64();
3044 tcg_gen_xor_i64(tmp, vf, nf);
3045 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3046 dest, frm);
3047 tcg_temp_free_i64(tmp);
3048 break;
3050 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3051 tcg_temp_free_i64(frn);
3052 tcg_temp_free_i64(frm);
3053 tcg_temp_free_i64(dest);
3055 tcg_temp_free_i64(zf);
3056 tcg_temp_free_i64(nf);
3057 tcg_temp_free_i64(vf);
3059 tcg_temp_free_i64(zero);
3060 } else {
3061 TCGv_i32 frn, frm, dest;
3062 TCGv_i32 tmp, zero;
3064 zero = tcg_const_i32(0);
3066 frn = tcg_temp_new_i32();
3067 frm = tcg_temp_new_i32();
3068 dest = tcg_temp_new_i32();
3069 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3070 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3071 switch (cc) {
3072 case 0: /* eq: Z */
3073 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3074 frn, frm);
3075 break;
3076 case 1: /* vs: V */
3077 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3078 frn, frm);
3079 break;
3080 case 2: /* ge: N == V -> N ^ V == 0 */
3081 tmp = tcg_temp_new_i32();
3082 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3083 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3084 frn, frm);
3085 tcg_temp_free_i32(tmp);
3086 break;
3087 case 3: /* gt: !Z && N == V */
3088 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3089 frn, frm);
3090 tmp = tcg_temp_new_i32();
3091 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3092 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3093 dest, frm);
3094 tcg_temp_free_i32(tmp);
3095 break;
3097 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3098 tcg_temp_free_i32(frn);
3099 tcg_temp_free_i32(frm);
3100 tcg_temp_free_i32(dest);
3102 tcg_temp_free_i32(zero);
3105 return 0;
3108 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3109 uint32_t rm, uint32_t dp)
3111 uint32_t vmin = extract32(insn, 6, 1);
3112 TCGv_ptr fpst = get_fpstatus_ptr(0);
3114 if (dp) {
3115 TCGv_i64 frn, frm, dest;
3117 frn = tcg_temp_new_i64();
3118 frm = tcg_temp_new_i64();
3119 dest = tcg_temp_new_i64();
3121 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3122 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3123 if (vmin) {
3124 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3125 } else {
3126 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3128 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3129 tcg_temp_free_i64(frn);
3130 tcg_temp_free_i64(frm);
3131 tcg_temp_free_i64(dest);
3132 } else {
3133 TCGv_i32 frn, frm, dest;
3135 frn = tcg_temp_new_i32();
3136 frm = tcg_temp_new_i32();
3137 dest = tcg_temp_new_i32();
3139 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3140 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3141 if (vmin) {
3142 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3143 } else {
3144 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3146 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3147 tcg_temp_free_i32(frn);
3148 tcg_temp_free_i32(frm);
3149 tcg_temp_free_i32(dest);
3152 tcg_temp_free_ptr(fpst);
3153 return 0;
3156 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3157 int rounding)
3159 TCGv_ptr fpst = get_fpstatus_ptr(0);
3160 TCGv_i32 tcg_rmode;
3162 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3163 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3165 if (dp) {
3166 TCGv_i64 tcg_op;
3167 TCGv_i64 tcg_res;
3168 tcg_op = tcg_temp_new_i64();
3169 tcg_res = tcg_temp_new_i64();
3170 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3171 gen_helper_rintd(tcg_res, tcg_op, fpst);
3172 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3173 tcg_temp_free_i64(tcg_op);
3174 tcg_temp_free_i64(tcg_res);
3175 } else {
3176 TCGv_i32 tcg_op;
3177 TCGv_i32 tcg_res;
3178 tcg_op = tcg_temp_new_i32();
3179 tcg_res = tcg_temp_new_i32();
3180 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3181 gen_helper_rints(tcg_res, tcg_op, fpst);
3182 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3183 tcg_temp_free_i32(tcg_op);
3184 tcg_temp_free_i32(tcg_res);
3187 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3188 tcg_temp_free_i32(tcg_rmode);
3190 tcg_temp_free_ptr(fpst);
3191 return 0;
3194 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3195 int rounding)
3197 bool is_signed = extract32(insn, 7, 1);
3198 TCGv_ptr fpst = get_fpstatus_ptr(0);
3199 TCGv_i32 tcg_rmode, tcg_shift;
3201 tcg_shift = tcg_const_i32(0);
3203 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3204 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3206 if (dp) {
3207 TCGv_i64 tcg_double, tcg_res;
3208 TCGv_i32 tcg_tmp;
3209 /* Rd is encoded as a single precision register even when the source
3210 * is double precision.
3212 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3213 tcg_double = tcg_temp_new_i64();
3214 tcg_res = tcg_temp_new_i64();
3215 tcg_tmp = tcg_temp_new_i32();
3216 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3217 if (is_signed) {
3218 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3219 } else {
3220 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3222 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3223 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3224 tcg_temp_free_i32(tcg_tmp);
3225 tcg_temp_free_i64(tcg_res);
3226 tcg_temp_free_i64(tcg_double);
3227 } else {
3228 TCGv_i32 tcg_single, tcg_res;
3229 tcg_single = tcg_temp_new_i32();
3230 tcg_res = tcg_temp_new_i32();
3231 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3232 if (is_signed) {
3233 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3234 } else {
3235 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3237 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3238 tcg_temp_free_i32(tcg_res);
3239 tcg_temp_free_i32(tcg_single);
3242 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3243 tcg_temp_free_i32(tcg_rmode);
3245 tcg_temp_free_i32(tcg_shift);
3247 tcg_temp_free_ptr(fpst);
3249 return 0;
3252 /* Table for converting the most common AArch32 encoding of
3253 * rounding mode to arm_fprounding order (which matches the
3254 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3256 static const uint8_t fp_decode_rm[] = {
3257 FPROUNDING_TIEAWAY,
3258 FPROUNDING_TIEEVEN,
3259 FPROUNDING_POSINF,
3260 FPROUNDING_NEGINF,
3263 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3265 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3267 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3268 return 1;
3271 if (dp) {
3272 VFP_DREG_D(rd, insn);
3273 VFP_DREG_N(rn, insn);
3274 VFP_DREG_M(rm, insn);
3275 } else {
3276 rd = VFP_SREG_D(insn);
3277 rn = VFP_SREG_N(insn);
3278 rm = VFP_SREG_M(insn);
3281 if ((insn & 0x0f800e50) == 0x0e000a00) {
3282 return handle_vsel(insn, rd, rn, rm, dp);
3283 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3284 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3285 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3286 /* VRINTA, VRINTN, VRINTP, VRINTM */
3287 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3288 return handle_vrint(insn, rd, rm, dp, rounding);
3289 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3290 /* VCVTA, VCVTN, VCVTP, VCVTM */
3291 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3292 return handle_vcvt(insn, rd, rm, dp, rounding);
3294 return 1;
3297 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3298 (ie. an undefined instruction). */
3299 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3301 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3302 int dp, veclen;
3303 TCGv_i32 addr;
3304 TCGv_i32 tmp;
3305 TCGv_i32 tmp2;
3307 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3308 return 1;
3311 /* FIXME: this access check should not take precedence over UNDEF
3312 * for invalid encodings; we will generate incorrect syndrome information
3313 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3315 if (s->fp_excp_el) {
3316 gen_exception_insn(s, 4, EXCP_UDEF,
3317 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3318 return 0;
3321 if (!s->vfp_enabled) {
3322 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3323 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3324 return 1;
3325 rn = (insn >> 16) & 0xf;
3326 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3327 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3328 return 1;
3332 if (extract32(insn, 28, 4) == 0xf) {
3333 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3334 * only used in v8 and above.
3336 return disas_vfp_v8_insn(s, insn);
3339 dp = ((insn & 0xf00) == 0xb00);
3340 switch ((insn >> 24) & 0xf) {
3341 case 0xe:
3342 if (insn & (1 << 4)) {
3343 /* single register transfer */
3344 rd = (insn >> 12) & 0xf;
3345 if (dp) {
3346 int size;
3347 int pass;
3349 VFP_DREG_N(rn, insn);
3350 if (insn & 0xf)
3351 return 1;
3352 if (insn & 0x00c00060
3353 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3354 return 1;
3357 pass = (insn >> 21) & 1;
3358 if (insn & (1 << 22)) {
3359 size = 0;
3360 offset = ((insn >> 5) & 3) * 8;
3361 } else if (insn & (1 << 5)) {
3362 size = 1;
3363 offset = (insn & (1 << 6)) ? 16 : 0;
3364 } else {
3365 size = 2;
3366 offset = 0;
3368 if (insn & ARM_CP_RW_BIT) {
3369 /* vfp->arm */
3370 tmp = neon_load_reg(rn, pass);
3371 switch (size) {
3372 case 0:
3373 if (offset)
3374 tcg_gen_shri_i32(tmp, tmp, offset);
3375 if (insn & (1 << 23))
3376 gen_uxtb(tmp);
3377 else
3378 gen_sxtb(tmp);
3379 break;
3380 case 1:
3381 if (insn & (1 << 23)) {
3382 if (offset) {
3383 tcg_gen_shri_i32(tmp, tmp, 16);
3384 } else {
3385 gen_uxth(tmp);
3387 } else {
3388 if (offset) {
3389 tcg_gen_sari_i32(tmp, tmp, 16);
3390 } else {
3391 gen_sxth(tmp);
3394 break;
3395 case 2:
3396 break;
3398 store_reg(s, rd, tmp);
3399 } else {
3400 /* arm->vfp */
3401 tmp = load_reg(s, rd);
3402 if (insn & (1 << 23)) {
3403 /* VDUP */
3404 if (size == 0) {
3405 gen_neon_dup_u8(tmp, 0);
3406 } else if (size == 1) {
3407 gen_neon_dup_low16(tmp);
3409 for (n = 0; n <= pass * 2; n++) {
3410 tmp2 = tcg_temp_new_i32();
3411 tcg_gen_mov_i32(tmp2, tmp);
3412 neon_store_reg(rn, n, tmp2);
3414 neon_store_reg(rn, n, tmp);
3415 } else {
3416 /* VMOV */
3417 switch (size) {
3418 case 0:
3419 tmp2 = neon_load_reg(rn, pass);
3420 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3421 tcg_temp_free_i32(tmp2);
3422 break;
3423 case 1:
3424 tmp2 = neon_load_reg(rn, pass);
3425 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3426 tcg_temp_free_i32(tmp2);
3427 break;
3428 case 2:
3429 break;
3431 neon_store_reg(rn, pass, tmp);
3434 } else { /* !dp */
3435 if ((insn & 0x6f) != 0x00)
3436 return 1;
3437 rn = VFP_SREG_N(insn);
3438 if (insn & ARM_CP_RW_BIT) {
3439 /* vfp->arm */
3440 if (insn & (1 << 21)) {
3441 /* system register */
3442 rn >>= 1;
3444 switch (rn) {
3445 case ARM_VFP_FPSID:
3446 /* VFP2 allows access to FSID from userspace.
3447 VFP3 restricts all id registers to privileged
3448 accesses. */
3449 if (IS_USER(s)
3450 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3451 return 1;
3453 tmp = load_cpu_field(vfp.xregs[rn]);
3454 break;
3455 case ARM_VFP_FPEXC:
3456 if (IS_USER(s))
3457 return 1;
3458 tmp = load_cpu_field(vfp.xregs[rn]);
3459 break;
3460 case ARM_VFP_FPINST:
3461 case ARM_VFP_FPINST2:
3462 /* Not present in VFP3. */
3463 if (IS_USER(s)
3464 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3465 return 1;
3467 tmp = load_cpu_field(vfp.xregs[rn]);
3468 break;
3469 case ARM_VFP_FPSCR:
3470 if (rd == 15) {
3471 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3472 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3473 } else {
3474 tmp = tcg_temp_new_i32();
3475 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3477 break;
3478 case ARM_VFP_MVFR2:
3479 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3480 return 1;
3482 /* fall through */
3483 case ARM_VFP_MVFR0:
3484 case ARM_VFP_MVFR1:
3485 if (IS_USER(s)
3486 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3487 return 1;
3489 tmp = load_cpu_field(vfp.xregs[rn]);
3490 break;
3491 default:
3492 return 1;
3494 } else {
3495 gen_mov_F0_vreg(0, rn);
3496 tmp = gen_vfp_mrs();
3498 if (rd == 15) {
3499 /* Set the 4 flag bits in the CPSR. */
3500 gen_set_nzcv(tmp);
3501 tcg_temp_free_i32(tmp);
3502 } else {
3503 store_reg(s, rd, tmp);
3505 } else {
3506 /* arm->vfp */
3507 if (insn & (1 << 21)) {
3508 rn >>= 1;
3509 /* system register */
3510 switch (rn) {
3511 case ARM_VFP_FPSID:
3512 case ARM_VFP_MVFR0:
3513 case ARM_VFP_MVFR1:
3514 /* Writes are ignored. */
3515 break;
3516 case ARM_VFP_FPSCR:
3517 tmp = load_reg(s, rd);
3518 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3519 tcg_temp_free_i32(tmp);
3520 gen_lookup_tb(s);
3521 break;
3522 case ARM_VFP_FPEXC:
3523 if (IS_USER(s))
3524 return 1;
3525 /* TODO: VFP subarchitecture support.
3526 * For now, keep the EN bit only */
3527 tmp = load_reg(s, rd);
3528 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3529 store_cpu_field(tmp, vfp.xregs[rn]);
3530 gen_lookup_tb(s);
3531 break;
3532 case ARM_VFP_FPINST:
3533 case ARM_VFP_FPINST2:
3534 if (IS_USER(s)) {
3535 return 1;
3537 tmp = load_reg(s, rd);
3538 store_cpu_field(tmp, vfp.xregs[rn]);
3539 break;
3540 default:
3541 return 1;
3543 } else {
3544 tmp = load_reg(s, rd);
3545 gen_vfp_msr(tmp);
3546 gen_mov_vreg_F0(0, rn);
3550 } else {
3551 /* data processing */
3552 /* The opcode is in bits 23, 21, 20 and 6. */
3553 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3554 if (dp) {
3555 if (op == 15) {
3556 /* rn is opcode */
3557 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3558 } else {
3559 /* rn is register number */
3560 VFP_DREG_N(rn, insn);
3563 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3564 ((rn & 0x1e) == 0x6))) {
3565 /* Integer or single/half precision destination. */
3566 rd = VFP_SREG_D(insn);
3567 } else {
3568 VFP_DREG_D(rd, insn);
3570 if (op == 15 &&
3571 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3572 ((rn & 0x1e) == 0x4))) {
3573 /* VCVT from int or half precision is always from S reg
3574 * regardless of dp bit. VCVT with immediate frac_bits
3575 * has same format as SREG_M.
3577 rm = VFP_SREG_M(insn);
3578 } else {
3579 VFP_DREG_M(rm, insn);
3581 } else {
3582 rn = VFP_SREG_N(insn);
3583 if (op == 15 && rn == 15) {
3584 /* Double precision destination. */
3585 VFP_DREG_D(rd, insn);
3586 } else {
3587 rd = VFP_SREG_D(insn);
3589 /* NB that we implicitly rely on the encoding for the frac_bits
3590 * in VCVT of fixed to float being the same as that of an SREG_M
3592 rm = VFP_SREG_M(insn);
3595 veclen = s->vec_len;
3596 if (op == 15 && rn > 3)
3597 veclen = 0;
3599 /* Shut up compiler warnings. */
3600 delta_m = 0;
3601 delta_d = 0;
3602 bank_mask = 0;
3604 if (veclen > 0) {
3605 if (dp)
3606 bank_mask = 0xc;
3607 else
3608 bank_mask = 0x18;
3610 /* Figure out what type of vector operation this is. */
3611 if ((rd & bank_mask) == 0) {
3612 /* scalar */
3613 veclen = 0;
3614 } else {
3615 if (dp)
3616 delta_d = (s->vec_stride >> 1) + 1;
3617 else
3618 delta_d = s->vec_stride + 1;
3620 if ((rm & bank_mask) == 0) {
3621 /* mixed scalar/vector */
3622 delta_m = 0;
3623 } else {
3624 /* vector */
3625 delta_m = delta_d;
3630 /* Load the initial operands. */
3631 if (op == 15) {
3632 switch (rn) {
3633 case 16:
3634 case 17:
3635 /* Integer source */
3636 gen_mov_F0_vreg(0, rm);
3637 break;
3638 case 8:
3639 case 9:
3640 /* Compare */
3641 gen_mov_F0_vreg(dp, rd);
3642 gen_mov_F1_vreg(dp, rm);
3643 break;
3644 case 10:
3645 case 11:
3646 /* Compare with zero */
3647 gen_mov_F0_vreg(dp, rd);
3648 gen_vfp_F1_ld0(dp);
3649 break;
3650 case 20:
3651 case 21:
3652 case 22:
3653 case 23:
3654 case 28:
3655 case 29:
3656 case 30:
3657 case 31:
3658 /* Source and destination the same. */
3659 gen_mov_F0_vreg(dp, rd);
3660 break;
3661 case 4:
3662 case 5:
3663 case 6:
3664 case 7:
3665 /* VCVTB, VCVTT: only present with the halfprec extension
3666 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3667 * (we choose to UNDEF)
3669 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3670 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3671 return 1;
3673 if (!extract32(rn, 1, 1)) {
3674 /* Half precision source. */
3675 gen_mov_F0_vreg(0, rm);
3676 break;
3678 /* Otherwise fall through */
3679 default:
3680 /* One source operand. */
3681 gen_mov_F0_vreg(dp, rm);
3682 break;
3684 } else {
3685 /* Two source operands. */
3686 gen_mov_F0_vreg(dp, rn);
3687 gen_mov_F1_vreg(dp, rm);
3690 for (;;) {
3691 /* Perform the calculation. */
3692 switch (op) {
3693 case 0: /* VMLA: fd + (fn * fm) */
3694 /* Note that order of inputs to the add matters for NaNs */
3695 gen_vfp_F1_mul(dp);
3696 gen_mov_F0_vreg(dp, rd);
3697 gen_vfp_add(dp);
3698 break;
3699 case 1: /* VMLS: fd + -(fn * fm) */
3700 gen_vfp_mul(dp);
3701 gen_vfp_F1_neg(dp);
3702 gen_mov_F0_vreg(dp, rd);
3703 gen_vfp_add(dp);
3704 break;
3705 case 2: /* VNMLS: -fd + (fn * fm) */
3706 /* Note that it isn't valid to replace (-A + B) with (B - A)
3707 * or similar plausible looking simplifications
3708 * because this will give wrong results for NaNs.
3710 gen_vfp_F1_mul(dp);
3711 gen_mov_F0_vreg(dp, rd);
3712 gen_vfp_neg(dp);
3713 gen_vfp_add(dp);
3714 break;
3715 case 3: /* VNMLA: -fd + -(fn * fm) */
3716 gen_vfp_mul(dp);
3717 gen_vfp_F1_neg(dp);
3718 gen_mov_F0_vreg(dp, rd);
3719 gen_vfp_neg(dp);
3720 gen_vfp_add(dp);
3721 break;
3722 case 4: /* mul: fn * fm */
3723 gen_vfp_mul(dp);
3724 break;
3725 case 5: /* nmul: -(fn * fm) */
3726 gen_vfp_mul(dp);
3727 gen_vfp_neg(dp);
3728 break;
3729 case 6: /* add: fn + fm */
3730 gen_vfp_add(dp);
3731 break;
3732 case 7: /* sub: fn - fm */
3733 gen_vfp_sub(dp);
3734 break;
3735 case 8: /* div: fn / fm */
3736 gen_vfp_div(dp);
3737 break;
3738 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3739 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3740 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3741 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3742 /* These are fused multiply-add, and must be done as one
3743 * floating point operation with no rounding between the
3744 * multiplication and addition steps.
3745 * NB that doing the negations here as separate steps is
3746 * correct : an input NaN should come out with its sign bit
3747 * flipped if it is a negated-input.
3749 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3750 return 1;
3752 if (dp) {
3753 TCGv_ptr fpst;
3754 TCGv_i64 frd;
3755 if (op & 1) {
3756 /* VFNMS, VFMS */
3757 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3759 frd = tcg_temp_new_i64();
3760 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3761 if (op & 2) {
3762 /* VFNMA, VFNMS */
3763 gen_helper_vfp_negd(frd, frd);
3765 fpst = get_fpstatus_ptr(0);
3766 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3767 cpu_F1d, frd, fpst);
3768 tcg_temp_free_ptr(fpst);
3769 tcg_temp_free_i64(frd);
3770 } else {
3771 TCGv_ptr fpst;
3772 TCGv_i32 frd;
3773 if (op & 1) {
3774 /* VFNMS, VFMS */
3775 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3777 frd = tcg_temp_new_i32();
3778 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3779 if (op & 2) {
3780 gen_helper_vfp_negs(frd, frd);
3782 fpst = get_fpstatus_ptr(0);
3783 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3784 cpu_F1s, frd, fpst);
3785 tcg_temp_free_ptr(fpst);
3786 tcg_temp_free_i32(frd);
3788 break;
3789 case 14: /* fconst */
3790 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3791 return 1;
3794 n = (insn << 12) & 0x80000000;
3795 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3796 if (dp) {
3797 if (i & 0x40)
3798 i |= 0x3f80;
3799 else
3800 i |= 0x4000;
3801 n |= i << 16;
3802 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3803 } else {
3804 if (i & 0x40)
3805 i |= 0x780;
3806 else
3807 i |= 0x800;
3808 n |= i << 19;
3809 tcg_gen_movi_i32(cpu_F0s, n);
3811 break;
3812 case 15: /* extension space */
3813 switch (rn) {
3814 case 0: /* cpy */
3815 /* no-op */
3816 break;
3817 case 1: /* abs */
3818 gen_vfp_abs(dp);
3819 break;
3820 case 2: /* neg */
3821 gen_vfp_neg(dp);
3822 break;
3823 case 3: /* sqrt */
3824 gen_vfp_sqrt(dp);
3825 break;
3826 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3828 TCGv_ptr fpst = get_fpstatus_ptr(false);
3829 TCGv_i32 ahp_mode = get_ahp_flag();
3830 tmp = gen_vfp_mrs();
3831 tcg_gen_ext16u_i32(tmp, tmp);
3832 if (dp) {
3833 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3834 fpst, ahp_mode);
3835 } else {
3836 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3837 fpst, ahp_mode);
3839 tcg_temp_free_i32(ahp_mode);
3840 tcg_temp_free_ptr(fpst);
3841 tcg_temp_free_i32(tmp);
3842 break;
3844 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3846 TCGv_ptr fpst = get_fpstatus_ptr(false);
3847 TCGv_i32 ahp = get_ahp_flag();
3848 tmp = gen_vfp_mrs();
3849 tcg_gen_shri_i32(tmp, tmp, 16);
3850 if (dp) {
3851 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3852 fpst, ahp);
3853 } else {
3854 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3855 fpst, ahp);
3857 tcg_temp_free_i32(tmp);
3858 tcg_temp_free_i32(ahp);
3859 tcg_temp_free_ptr(fpst);
3860 break;
3862 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3864 TCGv_ptr fpst = get_fpstatus_ptr(false);
3865 TCGv_i32 ahp = get_ahp_flag();
3866 tmp = tcg_temp_new_i32();
3868 if (dp) {
3869 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3870 fpst, ahp);
3871 } else {
3872 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3873 fpst, ahp);
3875 tcg_temp_free_i32(ahp);
3876 tcg_temp_free_ptr(fpst);
3877 gen_mov_F0_vreg(0, rd);
3878 tmp2 = gen_vfp_mrs();
3879 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3880 tcg_gen_or_i32(tmp, tmp, tmp2);
3881 tcg_temp_free_i32(tmp2);
3882 gen_vfp_msr(tmp);
3883 break;
3885 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3887 TCGv_ptr fpst = get_fpstatus_ptr(false);
3888 TCGv_i32 ahp = get_ahp_flag();
3889 tmp = tcg_temp_new_i32();
3890 if (dp) {
3891 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3892 fpst, ahp);
3893 } else {
3894 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3895 fpst, ahp);
3897 tcg_temp_free_i32(ahp);
3898 tcg_temp_free_ptr(fpst);
3899 tcg_gen_shli_i32(tmp, tmp, 16);
3900 gen_mov_F0_vreg(0, rd);
3901 tmp2 = gen_vfp_mrs();
3902 tcg_gen_ext16u_i32(tmp2, tmp2);
3903 tcg_gen_or_i32(tmp, tmp, tmp2);
3904 tcg_temp_free_i32(tmp2);
3905 gen_vfp_msr(tmp);
3906 break;
3908 case 8: /* cmp */
3909 gen_vfp_cmp(dp);
3910 break;
3911 case 9: /* cmpe */
3912 gen_vfp_cmpe(dp);
3913 break;
3914 case 10: /* cmpz */
3915 gen_vfp_cmp(dp);
3916 break;
3917 case 11: /* cmpez */
3918 gen_vfp_F1_ld0(dp);
3919 gen_vfp_cmpe(dp);
3920 break;
3921 case 12: /* vrintr */
3923 TCGv_ptr fpst = get_fpstatus_ptr(0);
3924 if (dp) {
3925 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3926 } else {
3927 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3929 tcg_temp_free_ptr(fpst);
3930 break;
3932 case 13: /* vrintz */
3934 TCGv_ptr fpst = get_fpstatus_ptr(0);
3935 TCGv_i32 tcg_rmode;
3936 tcg_rmode = tcg_const_i32(float_round_to_zero);
3937 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3938 if (dp) {
3939 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3940 } else {
3941 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3943 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3944 tcg_temp_free_i32(tcg_rmode);
3945 tcg_temp_free_ptr(fpst);
3946 break;
3948 case 14: /* vrintx */
3950 TCGv_ptr fpst = get_fpstatus_ptr(0);
3951 if (dp) {
3952 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3953 } else {
3954 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3956 tcg_temp_free_ptr(fpst);
3957 break;
3959 case 15: /* single<->double conversion */
3960 if (dp)
3961 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3962 else
3963 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3964 break;
3965 case 16: /* fuito */
3966 gen_vfp_uito(dp, 0);
3967 break;
3968 case 17: /* fsito */
3969 gen_vfp_sito(dp, 0);
3970 break;
3971 case 20: /* fshto */
3972 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3973 return 1;
3975 gen_vfp_shto(dp, 16 - rm, 0);
3976 break;
3977 case 21: /* fslto */
3978 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3979 return 1;
3981 gen_vfp_slto(dp, 32 - rm, 0);
3982 break;
3983 case 22: /* fuhto */
3984 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3985 return 1;
3987 gen_vfp_uhto(dp, 16 - rm, 0);
3988 break;
3989 case 23: /* fulto */
3990 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3991 return 1;
3993 gen_vfp_ulto(dp, 32 - rm, 0);
3994 break;
3995 case 24: /* ftoui */
3996 gen_vfp_toui(dp, 0);
3997 break;
3998 case 25: /* ftouiz */
3999 gen_vfp_touiz(dp, 0);
4000 break;
4001 case 26: /* ftosi */
4002 gen_vfp_tosi(dp, 0);
4003 break;
4004 case 27: /* ftosiz */
4005 gen_vfp_tosiz(dp, 0);
4006 break;
4007 case 28: /* ftosh */
4008 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4009 return 1;
4011 gen_vfp_tosh(dp, 16 - rm, 0);
4012 break;
4013 case 29: /* ftosl */
4014 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4015 return 1;
4017 gen_vfp_tosl(dp, 32 - rm, 0);
4018 break;
4019 case 30: /* ftouh */
4020 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4021 return 1;
4023 gen_vfp_touh(dp, 16 - rm, 0);
4024 break;
4025 case 31: /* ftoul */
4026 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4027 return 1;
4029 gen_vfp_toul(dp, 32 - rm, 0);
4030 break;
4031 default: /* undefined */
4032 return 1;
4034 break;
4035 default: /* undefined */
4036 return 1;
4039 /* Write back the result. */
4040 if (op == 15 && (rn >= 8 && rn <= 11)) {
4041 /* Comparison, do nothing. */
4042 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4043 (rn & 0x1e) == 0x6)) {
4044 /* VCVT double to int: always integer result.
4045 * VCVT double to half precision is always a single
4046 * precision result.
4048 gen_mov_vreg_F0(0, rd);
4049 } else if (op == 15 && rn == 15) {
4050 /* conversion */
4051 gen_mov_vreg_F0(!dp, rd);
4052 } else {
4053 gen_mov_vreg_F0(dp, rd);
4056 /* break out of the loop if we have finished */
4057 if (veclen == 0)
4058 break;
4060 if (op == 15 && delta_m == 0) {
4061 /* single source one-many */
4062 while (veclen--) {
4063 rd = ((rd + delta_d) & (bank_mask - 1))
4064 | (rd & bank_mask);
4065 gen_mov_vreg_F0(dp, rd);
4067 break;
4069 /* Setup the next operands. */
4070 veclen--;
4071 rd = ((rd + delta_d) & (bank_mask - 1))
4072 | (rd & bank_mask);
4074 if (op == 15) {
4075 /* One source operand. */
4076 rm = ((rm + delta_m) & (bank_mask - 1))
4077 | (rm & bank_mask);
4078 gen_mov_F0_vreg(dp, rm);
4079 } else {
4080 /* Two source operands. */
4081 rn = ((rn + delta_d) & (bank_mask - 1))
4082 | (rn & bank_mask);
4083 gen_mov_F0_vreg(dp, rn);
4084 if (delta_m) {
4085 rm = ((rm + delta_m) & (bank_mask - 1))
4086 | (rm & bank_mask);
4087 gen_mov_F1_vreg(dp, rm);
4092 break;
4093 case 0xc:
4094 case 0xd:
4095 if ((insn & 0x03e00000) == 0x00400000) {
4096 /* two-register transfer */
4097 rn = (insn >> 16) & 0xf;
4098 rd = (insn >> 12) & 0xf;
4099 if (dp) {
4100 VFP_DREG_M(rm, insn);
4101 } else {
4102 rm = VFP_SREG_M(insn);
4105 if (insn & ARM_CP_RW_BIT) {
4106 /* vfp->arm */
4107 if (dp) {
4108 gen_mov_F0_vreg(0, rm * 2);
4109 tmp = gen_vfp_mrs();
4110 store_reg(s, rd, tmp);
4111 gen_mov_F0_vreg(0, rm * 2 + 1);
4112 tmp = gen_vfp_mrs();
4113 store_reg(s, rn, tmp);
4114 } else {
4115 gen_mov_F0_vreg(0, rm);
4116 tmp = gen_vfp_mrs();
4117 store_reg(s, rd, tmp);
4118 gen_mov_F0_vreg(0, rm + 1);
4119 tmp = gen_vfp_mrs();
4120 store_reg(s, rn, tmp);
4122 } else {
4123 /* arm->vfp */
4124 if (dp) {
4125 tmp = load_reg(s, rd);
4126 gen_vfp_msr(tmp);
4127 gen_mov_vreg_F0(0, rm * 2);
4128 tmp = load_reg(s, rn);
4129 gen_vfp_msr(tmp);
4130 gen_mov_vreg_F0(0, rm * 2 + 1);
4131 } else {
4132 tmp = load_reg(s, rd);
4133 gen_vfp_msr(tmp);
4134 gen_mov_vreg_F0(0, rm);
4135 tmp = load_reg(s, rn);
4136 gen_vfp_msr(tmp);
4137 gen_mov_vreg_F0(0, rm + 1);
4140 } else {
4141 /* Load/store */
4142 rn = (insn >> 16) & 0xf;
4143 if (dp)
4144 VFP_DREG_D(rd, insn);
4145 else
4146 rd = VFP_SREG_D(insn);
4147 if ((insn & 0x01200000) == 0x01000000) {
4148 /* Single load/store */
4149 offset = (insn & 0xff) << 2;
4150 if ((insn & (1 << 23)) == 0)
4151 offset = -offset;
4152 if (s->thumb && rn == 15) {
4153 /* This is actually UNPREDICTABLE */
4154 addr = tcg_temp_new_i32();
4155 tcg_gen_movi_i32(addr, s->pc & ~2);
4156 } else {
4157 addr = load_reg(s, rn);
4159 tcg_gen_addi_i32(addr, addr, offset);
4160 if (insn & (1 << 20)) {
4161 gen_vfp_ld(s, dp, addr);
4162 gen_mov_vreg_F0(dp, rd);
4163 } else {
4164 gen_mov_F0_vreg(dp, rd);
4165 gen_vfp_st(s, dp, addr);
4167 tcg_temp_free_i32(addr);
4168 } else {
4169 /* load/store multiple */
4170 int w = insn & (1 << 21);
4171 if (dp)
4172 n = (insn >> 1) & 0x7f;
4173 else
4174 n = insn & 0xff;
4176 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4177 /* P == U , W == 1 => UNDEF */
4178 return 1;
4180 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4181 /* UNPREDICTABLE cases for bad immediates: we choose to
4182 * UNDEF to avoid generating huge numbers of TCG ops
4184 return 1;
4186 if (rn == 15 && w) {
4187 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4188 return 1;
4191 if (s->thumb && rn == 15) {
4192 /* This is actually UNPREDICTABLE */
4193 addr = tcg_temp_new_i32();
4194 tcg_gen_movi_i32(addr, s->pc & ~2);
4195 } else {
4196 addr = load_reg(s, rn);
4198 if (insn & (1 << 24)) /* pre-decrement */
4199 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4201 if (dp)
4202 offset = 8;
4203 else
4204 offset = 4;
4205 for (i = 0; i < n; i++) {
4206 if (insn & ARM_CP_RW_BIT) {
4207 /* load */
4208 gen_vfp_ld(s, dp, addr);
4209 gen_mov_vreg_F0(dp, rd + i);
4210 } else {
4211 /* store */
4212 gen_mov_F0_vreg(dp, rd + i);
4213 gen_vfp_st(s, dp, addr);
4215 tcg_gen_addi_i32(addr, addr, offset);
4217 if (w) {
4218 /* writeback */
4219 if (insn & (1 << 24))
4220 offset = -offset * n;
4221 else if (dp && (insn & 1))
4222 offset = 4;
4223 else
4224 offset = 0;
4226 if (offset != 0)
4227 tcg_gen_addi_i32(addr, addr, offset);
4228 store_reg(s, rn, addr);
4229 } else {
4230 tcg_temp_free_i32(addr);
4234 break;
4235 default:
4236 /* Should never happen. */
4237 return 1;
4239 return 0;
4242 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4244 #ifndef CONFIG_USER_ONLY
4245 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4246 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4247 #else
4248 return true;
4249 #endif
4252 static void gen_goto_ptr(void)
4254 tcg_gen_lookup_and_goto_ptr();
4257 /* This will end the TB but doesn't guarantee we'll return to
4258 * cpu_loop_exec. Any live exit_requests will be processed as we
4259 * enter the next TB.
4261 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4263 if (use_goto_tb(s, dest)) {
4264 tcg_gen_goto_tb(n);
4265 gen_set_pc_im(s, dest);
4266 tcg_gen_exit_tb(s->base.tb, n);
4267 } else {
4268 gen_set_pc_im(s, dest);
4269 gen_goto_ptr();
4271 s->base.is_jmp = DISAS_NORETURN;
4274 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4276 if (unlikely(is_singlestepping(s))) {
4277 /* An indirect jump so that we still trigger the debug exception. */
4278 if (s->thumb)
4279 dest |= 1;
4280 gen_bx_im(s, dest);
4281 } else {
4282 gen_goto_tb(s, 0, dest);
4286 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4288 if (x)
4289 tcg_gen_sari_i32(t0, t0, 16);
4290 else
4291 gen_sxth(t0);
4292 if (y)
4293 tcg_gen_sari_i32(t1, t1, 16);
4294 else
4295 gen_sxth(t1);
4296 tcg_gen_mul_i32(t0, t0, t1);
4299 /* Return the mask of PSR bits set by a MSR instruction. */
4300 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4302 uint32_t mask;
4304 mask = 0;
4305 if (flags & (1 << 0))
4306 mask |= 0xff;
4307 if (flags & (1 << 1))
4308 mask |= 0xff00;
4309 if (flags & (1 << 2))
4310 mask |= 0xff0000;
4311 if (flags & (1 << 3))
4312 mask |= 0xff000000;
4314 /* Mask out undefined bits. */
4315 mask &= ~CPSR_RESERVED;
4316 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4317 mask &= ~CPSR_T;
4319 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4320 mask &= ~CPSR_Q; /* V5TE in reality*/
4322 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4323 mask &= ~(CPSR_E | CPSR_GE);
4325 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4326 mask &= ~CPSR_IT;
4328 /* Mask out execution state and reserved bits. */
4329 if (!spsr) {
4330 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4332 /* Mask out privileged bits. */
4333 if (IS_USER(s))
4334 mask &= CPSR_USER;
4335 return mask;
4338 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4339 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4341 TCGv_i32 tmp;
4342 if (spsr) {
4343 /* ??? This is also undefined in system mode. */
4344 if (IS_USER(s))
4345 return 1;
4347 tmp = load_cpu_field(spsr);
4348 tcg_gen_andi_i32(tmp, tmp, ~mask);
4349 tcg_gen_andi_i32(t0, t0, mask);
4350 tcg_gen_or_i32(tmp, tmp, t0);
4351 store_cpu_field(tmp, spsr);
4352 } else {
4353 gen_set_cpsr(t0, mask);
4355 tcg_temp_free_i32(t0);
4356 gen_lookup_tb(s);
4357 return 0;
4360 /* Returns nonzero if access to the PSR is not permitted. */
4361 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4363 TCGv_i32 tmp;
4364 tmp = tcg_temp_new_i32();
4365 tcg_gen_movi_i32(tmp, val);
4366 return gen_set_psr(s, mask, spsr, tmp);
4369 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4370 int *tgtmode, int *regno)
4372 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4373 * the target mode and register number, and identify the various
4374 * unpredictable cases.
4375 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4376 * + executed in user mode
4377 * + using R15 as the src/dest register
4378 * + accessing an unimplemented register
4379 * + accessing a register that's inaccessible at current PL/security state*
4380 * + accessing a register that you could access with a different insn
4381 * We choose to UNDEF in all these cases.
4382 * Since we don't know which of the various AArch32 modes we are in
4383 * we have to defer some checks to runtime.
4384 * Accesses to Monitor mode registers from Secure EL1 (which implies
4385 * that EL3 is AArch64) must trap to EL3.
4387 * If the access checks fail this function will emit code to take
4388 * an exception and return false. Otherwise it will return true,
4389 * and set *tgtmode and *regno appropriately.
4391 int exc_target = default_exception_el(s);
4393 /* These instructions are present only in ARMv8, or in ARMv7 with the
4394 * Virtualization Extensions.
4396 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4397 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4398 goto undef;
4401 if (IS_USER(s) || rn == 15) {
4402 goto undef;
4405 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4406 * of registers into (r, sysm).
4408 if (r) {
4409 /* SPSRs for other modes */
4410 switch (sysm) {
4411 case 0xe: /* SPSR_fiq */
4412 *tgtmode = ARM_CPU_MODE_FIQ;
4413 break;
4414 case 0x10: /* SPSR_irq */
4415 *tgtmode = ARM_CPU_MODE_IRQ;
4416 break;
4417 case 0x12: /* SPSR_svc */
4418 *tgtmode = ARM_CPU_MODE_SVC;
4419 break;
4420 case 0x14: /* SPSR_abt */
4421 *tgtmode = ARM_CPU_MODE_ABT;
4422 break;
4423 case 0x16: /* SPSR_und */
4424 *tgtmode = ARM_CPU_MODE_UND;
4425 break;
4426 case 0x1c: /* SPSR_mon */
4427 *tgtmode = ARM_CPU_MODE_MON;
4428 break;
4429 case 0x1e: /* SPSR_hyp */
4430 *tgtmode = ARM_CPU_MODE_HYP;
4431 break;
4432 default: /* unallocated */
4433 goto undef;
4435 /* We arbitrarily assign SPSR a register number of 16. */
4436 *regno = 16;
4437 } else {
4438 /* general purpose registers for other modes */
4439 switch (sysm) {
4440 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4441 *tgtmode = ARM_CPU_MODE_USR;
4442 *regno = sysm + 8;
4443 break;
4444 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4445 *tgtmode = ARM_CPU_MODE_FIQ;
4446 *regno = sysm;
4447 break;
4448 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4449 *tgtmode = ARM_CPU_MODE_IRQ;
4450 *regno = sysm & 1 ? 13 : 14;
4451 break;
4452 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4453 *tgtmode = ARM_CPU_MODE_SVC;
4454 *regno = sysm & 1 ? 13 : 14;
4455 break;
4456 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4457 *tgtmode = ARM_CPU_MODE_ABT;
4458 *regno = sysm & 1 ? 13 : 14;
4459 break;
4460 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4461 *tgtmode = ARM_CPU_MODE_UND;
4462 *regno = sysm & 1 ? 13 : 14;
4463 break;
4464 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4465 *tgtmode = ARM_CPU_MODE_MON;
4466 *regno = sysm & 1 ? 13 : 14;
4467 break;
4468 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4469 *tgtmode = ARM_CPU_MODE_HYP;
4470 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4471 *regno = sysm & 1 ? 13 : 17;
4472 break;
4473 default: /* unallocated */
4474 goto undef;
4478 /* Catch the 'accessing inaccessible register' cases we can detect
4479 * at translate time.
4481 switch (*tgtmode) {
4482 case ARM_CPU_MODE_MON:
4483 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4484 goto undef;
4486 if (s->current_el == 1) {
4487 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4488 * then accesses to Mon registers trap to EL3
4490 exc_target = 3;
4491 goto undef;
4493 break;
4494 case ARM_CPU_MODE_HYP:
4495 /* Note that we can forbid accesses from EL2 here because they
4496 * must be from Hyp mode itself
4498 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4499 goto undef;
4501 break;
4502 default:
4503 break;
4506 return true;
4508 undef:
4509 /* If we get here then some access check did not pass */
4510 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4511 return false;
4514 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4516 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4517 int tgtmode = 0, regno = 0;
4519 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4520 return;
4523 /* Sync state because msr_banked() can raise exceptions */
4524 gen_set_condexec(s);
4525 gen_set_pc_im(s, s->pc - 4);
4526 tcg_reg = load_reg(s, rn);
4527 tcg_tgtmode = tcg_const_i32(tgtmode);
4528 tcg_regno = tcg_const_i32(regno);
4529 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4530 tcg_temp_free_i32(tcg_tgtmode);
4531 tcg_temp_free_i32(tcg_regno);
4532 tcg_temp_free_i32(tcg_reg);
4533 s->base.is_jmp = DISAS_UPDATE;
4536 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4538 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4539 int tgtmode = 0, regno = 0;
4541 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4542 return;
4545 /* Sync state because mrs_banked() can raise exceptions */
4546 gen_set_condexec(s);
4547 gen_set_pc_im(s, s->pc - 4);
4548 tcg_reg = tcg_temp_new_i32();
4549 tcg_tgtmode = tcg_const_i32(tgtmode);
4550 tcg_regno = tcg_const_i32(regno);
4551 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4552 tcg_temp_free_i32(tcg_tgtmode);
4553 tcg_temp_free_i32(tcg_regno);
4554 store_reg(s, rn, tcg_reg);
4555 s->base.is_jmp = DISAS_UPDATE;
4558 /* Store value to PC as for an exception return (ie don't
4559 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4560 * will do the masking based on the new value of the Thumb bit.
4562 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4564 tcg_gen_mov_i32(cpu_R[15], pc);
4565 tcg_temp_free_i32(pc);
4568 /* Generate a v6 exception return. Marks both values as dead. */
4569 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4571 store_pc_exc_ret(s, pc);
4572 /* The cpsr_write_eret helper will mask the low bits of PC
4573 * appropriately depending on the new Thumb bit, so it must
4574 * be called after storing the new PC.
4576 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4577 gen_io_start();
4579 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4580 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4581 gen_io_end();
4583 tcg_temp_free_i32(cpsr);
4584 /* Must exit loop to check un-masked IRQs */
4585 s->base.is_jmp = DISAS_EXIT;
4588 /* Generate an old-style exception return. Marks pc as dead. */
4589 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4591 gen_rfe(s, pc, load_cpu_field(spsr));
4595 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4596 * only call the helper when running single threaded TCG code to ensure
4597 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4598 * just skip this instruction. Currently the SEV/SEVL instructions
4599 * which are *one* of many ways to wake the CPU from WFE are not
4600 * implemented so we can't sleep like WFI does.
4602 static void gen_nop_hint(DisasContext *s, int val)
4604 switch (val) {
4605 /* When running in MTTCG we don't generate jumps to the yield and
4606 * WFE helpers as it won't affect the scheduling of other vCPUs.
4607 * If we wanted to more completely model WFE/SEV so we don't busy
4608 * spin unnecessarily we would need to do something more involved.
4610 case 1: /* yield */
4611 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4612 gen_set_pc_im(s, s->pc);
4613 s->base.is_jmp = DISAS_YIELD;
4615 break;
4616 case 3: /* wfi */
4617 gen_set_pc_im(s, s->pc);
4618 s->base.is_jmp = DISAS_WFI;
4619 break;
4620 case 2: /* wfe */
4621 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4622 gen_set_pc_im(s, s->pc);
4623 s->base.is_jmp = DISAS_WFE;
4625 break;
4626 case 4: /* sev */
4627 case 5: /* sevl */
4628 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4629 default: /* nop */
4630 break;
4634 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4636 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4638 switch (size) {
4639 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4640 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4641 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4642 default: abort();
4646 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4648 switch (size) {
4649 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4650 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4651 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4652 default: return;
4656 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4657 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4658 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4659 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4660 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4662 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4663 switch ((size << 1) | u) { \
4664 case 0: \
4665 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4666 break; \
4667 case 1: \
4668 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4669 break; \
4670 case 2: \
4671 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4672 break; \
4673 case 3: \
4674 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4675 break; \
4676 case 4: \
4677 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4678 break; \
4679 case 5: \
4680 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4681 break; \
4682 default: return 1; \
4683 }} while (0)
4685 #define GEN_NEON_INTEGER_OP(name) do { \
4686 switch ((size << 1) | u) { \
4687 case 0: \
4688 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4689 break; \
4690 case 1: \
4691 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4692 break; \
4693 case 2: \
4694 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4695 break; \
4696 case 3: \
4697 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4698 break; \
4699 case 4: \
4700 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4701 break; \
4702 case 5: \
4703 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4704 break; \
4705 default: return 1; \
4706 }} while (0)
4708 static TCGv_i32 neon_load_scratch(int scratch)
4710 TCGv_i32 tmp = tcg_temp_new_i32();
4711 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4712 return tmp;
4715 static void neon_store_scratch(int scratch, TCGv_i32 var)
4717 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4718 tcg_temp_free_i32(var);
4721 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4723 TCGv_i32 tmp;
4724 if (size == 1) {
4725 tmp = neon_load_reg(reg & 7, reg >> 4);
4726 if (reg & 8) {
4727 gen_neon_dup_high16(tmp);
4728 } else {
4729 gen_neon_dup_low16(tmp);
4731 } else {
4732 tmp = neon_load_reg(reg & 15, reg >> 4);
4734 return tmp;
4737 static int gen_neon_unzip(int rd, int rm, int size, int q)
4739 TCGv_ptr pd, pm;
4741 if (!q && size == 2) {
4742 return 1;
4744 pd = vfp_reg_ptr(true, rd);
4745 pm = vfp_reg_ptr(true, rm);
4746 if (q) {
4747 switch (size) {
4748 case 0:
4749 gen_helper_neon_qunzip8(pd, pm);
4750 break;
4751 case 1:
4752 gen_helper_neon_qunzip16(pd, pm);
4753 break;
4754 case 2:
4755 gen_helper_neon_qunzip32(pd, pm);
4756 break;
4757 default:
4758 abort();
4760 } else {
4761 switch (size) {
4762 case 0:
4763 gen_helper_neon_unzip8(pd, pm);
4764 break;
4765 case 1:
4766 gen_helper_neon_unzip16(pd, pm);
4767 break;
4768 default:
4769 abort();
4772 tcg_temp_free_ptr(pd);
4773 tcg_temp_free_ptr(pm);
4774 return 0;
4777 static int gen_neon_zip(int rd, int rm, int size, int q)
4779 TCGv_ptr pd, pm;
4781 if (!q && size == 2) {
4782 return 1;
4784 pd = vfp_reg_ptr(true, rd);
4785 pm = vfp_reg_ptr(true, rm);
4786 if (q) {
4787 switch (size) {
4788 case 0:
4789 gen_helper_neon_qzip8(pd, pm);
4790 break;
4791 case 1:
4792 gen_helper_neon_qzip16(pd, pm);
4793 break;
4794 case 2:
4795 gen_helper_neon_qzip32(pd, pm);
4796 break;
4797 default:
4798 abort();
4800 } else {
4801 switch (size) {
4802 case 0:
4803 gen_helper_neon_zip8(pd, pm);
4804 break;
4805 case 1:
4806 gen_helper_neon_zip16(pd, pm);
4807 break;
4808 default:
4809 abort();
4812 tcg_temp_free_ptr(pd);
4813 tcg_temp_free_ptr(pm);
4814 return 0;
4817 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4819 TCGv_i32 rd, tmp;
4821 rd = tcg_temp_new_i32();
4822 tmp = tcg_temp_new_i32();
4824 tcg_gen_shli_i32(rd, t0, 8);
4825 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4826 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4827 tcg_gen_or_i32(rd, rd, tmp);
4829 tcg_gen_shri_i32(t1, t1, 8);
4830 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4831 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4832 tcg_gen_or_i32(t1, t1, tmp);
4833 tcg_gen_mov_i32(t0, rd);
4835 tcg_temp_free_i32(tmp);
4836 tcg_temp_free_i32(rd);
4839 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4841 TCGv_i32 rd, tmp;
4843 rd = tcg_temp_new_i32();
4844 tmp = tcg_temp_new_i32();
4846 tcg_gen_shli_i32(rd, t0, 16);
4847 tcg_gen_andi_i32(tmp, t1, 0xffff);
4848 tcg_gen_or_i32(rd, rd, tmp);
4849 tcg_gen_shri_i32(t1, t1, 16);
4850 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4851 tcg_gen_or_i32(t1, t1, tmp);
4852 tcg_gen_mov_i32(t0, rd);
4854 tcg_temp_free_i32(tmp);
4855 tcg_temp_free_i32(rd);
4859 static struct {
4860 int nregs;
4861 int interleave;
4862 int spacing;
4863 } neon_ls_element_type[11] = {
4864 {4, 4, 1},
4865 {4, 4, 2},
4866 {4, 1, 1},
4867 {4, 2, 1},
4868 {3, 3, 1},
4869 {3, 3, 2},
4870 {3, 1, 1},
4871 {1, 1, 1},
4872 {2, 2, 1},
4873 {2, 2, 2},
4874 {2, 1, 1}
4877 /* Translate a NEON load/store element instruction. Return nonzero if the
4878 instruction is invalid. */
4879 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4881 int rd, rn, rm;
4882 int op;
4883 int nregs;
4884 int interleave;
4885 int spacing;
4886 int stride;
4887 int size;
4888 int reg;
4889 int pass;
4890 int load;
4891 int shift;
4892 int n;
4893 TCGv_i32 addr;
4894 TCGv_i32 tmp;
4895 TCGv_i32 tmp2;
4896 TCGv_i64 tmp64;
4898 /* FIXME: this access check should not take precedence over UNDEF
4899 * for invalid encodings; we will generate incorrect syndrome information
4900 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4902 if (s->fp_excp_el) {
4903 gen_exception_insn(s, 4, EXCP_UDEF,
4904 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4905 return 0;
4908 if (!s->vfp_enabled)
4909 return 1;
4910 VFP_DREG_D(rd, insn);
4911 rn = (insn >> 16) & 0xf;
4912 rm = insn & 0xf;
4913 load = (insn & (1 << 21)) != 0;
4914 if ((insn & (1 << 23)) == 0) {
4915 /* Load store all elements. */
4916 op = (insn >> 8) & 0xf;
4917 size = (insn >> 6) & 3;
4918 if (op > 10)
4919 return 1;
4920 /* Catch UNDEF cases for bad values of align field */
4921 switch (op & 0xc) {
4922 case 4:
4923 if (((insn >> 5) & 1) == 1) {
4924 return 1;
4926 break;
4927 case 8:
4928 if (((insn >> 4) & 3) == 3) {
4929 return 1;
4931 break;
4932 default:
4933 break;
4935 nregs = neon_ls_element_type[op].nregs;
4936 interleave = neon_ls_element_type[op].interleave;
4937 spacing = neon_ls_element_type[op].spacing;
4938 if (size == 3 && (interleave | spacing) != 1)
4939 return 1;
4940 addr = tcg_temp_new_i32();
4941 load_reg_var(s, addr, rn);
4942 stride = (1 << size) * interleave;
4943 for (reg = 0; reg < nregs; reg++) {
4944 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4945 load_reg_var(s, addr, rn);
4946 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4947 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4948 load_reg_var(s, addr, rn);
4949 tcg_gen_addi_i32(addr, addr, 1 << size);
4951 if (size == 3) {
4952 tmp64 = tcg_temp_new_i64();
4953 if (load) {
4954 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4955 neon_store_reg64(tmp64, rd);
4956 } else {
4957 neon_load_reg64(tmp64, rd);
4958 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4960 tcg_temp_free_i64(tmp64);
4961 tcg_gen_addi_i32(addr, addr, stride);
4962 } else {
4963 for (pass = 0; pass < 2; pass++) {
4964 if (size == 2) {
4965 if (load) {
4966 tmp = tcg_temp_new_i32();
4967 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4968 neon_store_reg(rd, pass, tmp);
4969 } else {
4970 tmp = neon_load_reg(rd, pass);
4971 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4972 tcg_temp_free_i32(tmp);
4974 tcg_gen_addi_i32(addr, addr, stride);
4975 } else if (size == 1) {
4976 if (load) {
4977 tmp = tcg_temp_new_i32();
4978 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4979 tcg_gen_addi_i32(addr, addr, stride);
4980 tmp2 = tcg_temp_new_i32();
4981 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4982 tcg_gen_addi_i32(addr, addr, stride);
4983 tcg_gen_shli_i32(tmp2, tmp2, 16);
4984 tcg_gen_or_i32(tmp, tmp, tmp2);
4985 tcg_temp_free_i32(tmp2);
4986 neon_store_reg(rd, pass, tmp);
4987 } else {
4988 tmp = neon_load_reg(rd, pass);
4989 tmp2 = tcg_temp_new_i32();
4990 tcg_gen_shri_i32(tmp2, tmp, 16);
4991 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4992 tcg_temp_free_i32(tmp);
4993 tcg_gen_addi_i32(addr, addr, stride);
4994 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4995 tcg_temp_free_i32(tmp2);
4996 tcg_gen_addi_i32(addr, addr, stride);
4998 } else /* size == 0 */ {
4999 if (load) {
5000 tmp2 = NULL;
5001 for (n = 0; n < 4; n++) {
5002 tmp = tcg_temp_new_i32();
5003 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5004 tcg_gen_addi_i32(addr, addr, stride);
5005 if (n == 0) {
5006 tmp2 = tmp;
5007 } else {
5008 tcg_gen_shli_i32(tmp, tmp, n * 8);
5009 tcg_gen_or_i32(tmp2, tmp2, tmp);
5010 tcg_temp_free_i32(tmp);
5013 neon_store_reg(rd, pass, tmp2);
5014 } else {
5015 tmp2 = neon_load_reg(rd, pass);
5016 for (n = 0; n < 4; n++) {
5017 tmp = tcg_temp_new_i32();
5018 if (n == 0) {
5019 tcg_gen_mov_i32(tmp, tmp2);
5020 } else {
5021 tcg_gen_shri_i32(tmp, tmp2, n * 8);
5023 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5024 tcg_temp_free_i32(tmp);
5025 tcg_gen_addi_i32(addr, addr, stride);
5027 tcg_temp_free_i32(tmp2);
5032 rd += spacing;
5034 tcg_temp_free_i32(addr);
5035 stride = nregs * 8;
5036 } else {
5037 size = (insn >> 10) & 3;
5038 if (size == 3) {
5039 /* Load single element to all lanes. */
5040 int a = (insn >> 4) & 1;
5041 if (!load) {
5042 return 1;
5044 size = (insn >> 6) & 3;
5045 nregs = ((insn >> 8) & 3) + 1;
5047 if (size == 3) {
5048 if (nregs != 4 || a == 0) {
5049 return 1;
5051 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5052 size = 2;
5054 if (nregs == 1 && a == 1 && size == 0) {
5055 return 1;
5057 if (nregs == 3 && a == 1) {
5058 return 1;
5060 addr = tcg_temp_new_i32();
5061 load_reg_var(s, addr, rn);
5062 if (nregs == 1) {
5063 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5064 tmp = gen_load_and_replicate(s, addr, size);
5065 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5066 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5067 if (insn & (1 << 5)) {
5068 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5069 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5071 tcg_temp_free_i32(tmp);
5072 } else {
5073 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5074 stride = (insn & (1 << 5)) ? 2 : 1;
5075 for (reg = 0; reg < nregs; reg++) {
5076 tmp = gen_load_and_replicate(s, addr, size);
5077 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5078 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5079 tcg_temp_free_i32(tmp);
5080 tcg_gen_addi_i32(addr, addr, 1 << size);
5081 rd += stride;
5084 tcg_temp_free_i32(addr);
5085 stride = (1 << size) * nregs;
5086 } else {
5087 /* Single element. */
5088 int idx = (insn >> 4) & 0xf;
5089 pass = (insn >> 7) & 1;
5090 switch (size) {
5091 case 0:
5092 shift = ((insn >> 5) & 3) * 8;
5093 stride = 1;
5094 break;
5095 case 1:
5096 shift = ((insn >> 6) & 1) * 16;
5097 stride = (insn & (1 << 5)) ? 2 : 1;
5098 break;
5099 case 2:
5100 shift = 0;
5101 stride = (insn & (1 << 6)) ? 2 : 1;
5102 break;
5103 default:
5104 abort();
5106 nregs = ((insn >> 8) & 3) + 1;
5107 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5108 switch (nregs) {
5109 case 1:
5110 if (((idx & (1 << size)) != 0) ||
5111 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5112 return 1;
5114 break;
5115 case 3:
5116 if ((idx & 1) != 0) {
5117 return 1;
5119 /* fall through */
5120 case 2:
5121 if (size == 2 && (idx & 2) != 0) {
5122 return 1;
5124 break;
5125 case 4:
5126 if ((size == 2) && ((idx & 3) == 3)) {
5127 return 1;
5129 break;
5130 default:
5131 abort();
5133 if ((rd + stride * (nregs - 1)) > 31) {
5134 /* Attempts to write off the end of the register file
5135 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5136 * the neon_load_reg() would write off the end of the array.
5138 return 1;
5140 addr = tcg_temp_new_i32();
5141 load_reg_var(s, addr, rn);
5142 for (reg = 0; reg < nregs; reg++) {
5143 if (load) {
5144 tmp = tcg_temp_new_i32();
5145 switch (size) {
5146 case 0:
5147 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5148 break;
5149 case 1:
5150 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5151 break;
5152 case 2:
5153 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5154 break;
5155 default: /* Avoid compiler warnings. */
5156 abort();
5158 if (size != 2) {
5159 tmp2 = neon_load_reg(rd, pass);
5160 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5161 shift, size ? 16 : 8);
5162 tcg_temp_free_i32(tmp2);
5164 neon_store_reg(rd, pass, tmp);
5165 } else { /* Store */
5166 tmp = neon_load_reg(rd, pass);
5167 if (shift)
5168 tcg_gen_shri_i32(tmp, tmp, shift);
5169 switch (size) {
5170 case 0:
5171 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5172 break;
5173 case 1:
5174 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5175 break;
5176 case 2:
5177 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5178 break;
5180 tcg_temp_free_i32(tmp);
5182 rd += stride;
5183 tcg_gen_addi_i32(addr, addr, 1 << size);
5185 tcg_temp_free_i32(addr);
5186 stride = nregs * (1 << size);
5189 if (rm != 15) {
5190 TCGv_i32 base;
5192 base = load_reg(s, rn);
5193 if (rm == 13) {
5194 tcg_gen_addi_i32(base, base, stride);
5195 } else {
5196 TCGv_i32 index;
5197 index = load_reg(s, rm);
5198 tcg_gen_add_i32(base, base, index);
5199 tcg_temp_free_i32(index);
5201 store_reg(s, rn, base);
5203 return 0;
5206 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5207 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5209 tcg_gen_and_i32(t, t, c);
5210 tcg_gen_andc_i32(f, f, c);
5211 tcg_gen_or_i32(dest, t, f);
5214 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5216 switch (size) {
5217 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5218 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5219 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5220 default: abort();
5224 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5226 switch (size) {
5227 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5228 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5229 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5230 default: abort();
5234 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5236 switch (size) {
5237 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5238 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5239 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5240 default: abort();
5244 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5246 switch (size) {
5247 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5248 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5249 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5250 default: abort();
5254 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5255 int q, int u)
5257 if (q) {
5258 if (u) {
5259 switch (size) {
5260 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5261 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5262 default: abort();
5264 } else {
5265 switch (size) {
5266 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5267 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5268 default: abort();
5271 } else {
5272 if (u) {
5273 switch (size) {
5274 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5275 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5276 default: abort();
5278 } else {
5279 switch (size) {
5280 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5281 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5282 default: abort();
5288 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5290 if (u) {
5291 switch (size) {
5292 case 0: gen_helper_neon_widen_u8(dest, src); break;
5293 case 1: gen_helper_neon_widen_u16(dest, src); break;
5294 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5295 default: abort();
5297 } else {
5298 switch (size) {
5299 case 0: gen_helper_neon_widen_s8(dest, src); break;
5300 case 1: gen_helper_neon_widen_s16(dest, src); break;
5301 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5302 default: abort();
5305 tcg_temp_free_i32(src);
5308 static inline void gen_neon_addl(int size)
5310 switch (size) {
5311 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5312 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5313 case 2: tcg_gen_add_i64(CPU_V001); break;
5314 default: abort();
5318 static inline void gen_neon_subl(int size)
5320 switch (size) {
5321 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5322 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5323 case 2: tcg_gen_sub_i64(CPU_V001); break;
5324 default: abort();
5328 static inline void gen_neon_negl(TCGv_i64 var, int size)
5330 switch (size) {
5331 case 0: gen_helper_neon_negl_u16(var, var); break;
5332 case 1: gen_helper_neon_negl_u32(var, var); break;
5333 case 2:
5334 tcg_gen_neg_i64(var, var);
5335 break;
5336 default: abort();
5340 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5342 switch (size) {
5343 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5344 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5345 default: abort();
5349 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5350 int size, int u)
5352 TCGv_i64 tmp;
5354 switch ((size << 1) | u) {
5355 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5356 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5357 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5358 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5359 case 4:
5360 tmp = gen_muls_i64_i32(a, b);
5361 tcg_gen_mov_i64(dest, tmp);
5362 tcg_temp_free_i64(tmp);
5363 break;
5364 case 5:
5365 tmp = gen_mulu_i64_i32(a, b);
5366 tcg_gen_mov_i64(dest, tmp);
5367 tcg_temp_free_i64(tmp);
5368 break;
5369 default: abort();
5372 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5373 Don't forget to clean them now. */
5374 if (size < 2) {
5375 tcg_temp_free_i32(a);
5376 tcg_temp_free_i32(b);
5380 static void gen_neon_narrow_op(int op, int u, int size,
5381 TCGv_i32 dest, TCGv_i64 src)
5383 if (op) {
5384 if (u) {
5385 gen_neon_unarrow_sats(size, dest, src);
5386 } else {
5387 gen_neon_narrow(size, dest, src);
5389 } else {
5390 if (u) {
5391 gen_neon_narrow_satu(size, dest, src);
5392 } else {
5393 gen_neon_narrow_sats(size, dest, src);
5398 /* Symbolic constants for op fields for Neon 3-register same-length.
5399 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5400 * table A7-9.
5402 #define NEON_3R_VHADD 0
5403 #define NEON_3R_VQADD 1
5404 #define NEON_3R_VRHADD 2
5405 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5406 #define NEON_3R_VHSUB 4
5407 #define NEON_3R_VQSUB 5
5408 #define NEON_3R_VCGT 6
5409 #define NEON_3R_VCGE 7
5410 #define NEON_3R_VSHL 8
5411 #define NEON_3R_VQSHL 9
5412 #define NEON_3R_VRSHL 10
5413 #define NEON_3R_VQRSHL 11
5414 #define NEON_3R_VMAX 12
5415 #define NEON_3R_VMIN 13
5416 #define NEON_3R_VABD 14
5417 #define NEON_3R_VABA 15
5418 #define NEON_3R_VADD_VSUB 16
5419 #define NEON_3R_VTST_VCEQ 17
5420 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5421 #define NEON_3R_VMUL 19
5422 #define NEON_3R_VPMAX 20
5423 #define NEON_3R_VPMIN 21
5424 #define NEON_3R_VQDMULH_VQRDMULH 22
5425 #define NEON_3R_VPADD_VQRDMLAH 23
5426 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5427 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5428 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5429 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5430 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5431 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5432 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5433 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5435 static const uint8_t neon_3r_sizes[] = {
5436 [NEON_3R_VHADD] = 0x7,
5437 [NEON_3R_VQADD] = 0xf,
5438 [NEON_3R_VRHADD] = 0x7,
5439 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5440 [NEON_3R_VHSUB] = 0x7,
5441 [NEON_3R_VQSUB] = 0xf,
5442 [NEON_3R_VCGT] = 0x7,
5443 [NEON_3R_VCGE] = 0x7,
5444 [NEON_3R_VSHL] = 0xf,
5445 [NEON_3R_VQSHL] = 0xf,
5446 [NEON_3R_VRSHL] = 0xf,
5447 [NEON_3R_VQRSHL] = 0xf,
5448 [NEON_3R_VMAX] = 0x7,
5449 [NEON_3R_VMIN] = 0x7,
5450 [NEON_3R_VABD] = 0x7,
5451 [NEON_3R_VABA] = 0x7,
5452 [NEON_3R_VADD_VSUB] = 0xf,
5453 [NEON_3R_VTST_VCEQ] = 0x7,
5454 [NEON_3R_VML] = 0x7,
5455 [NEON_3R_VMUL] = 0x7,
5456 [NEON_3R_VPMAX] = 0x7,
5457 [NEON_3R_VPMIN] = 0x7,
5458 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5459 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5460 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5461 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5462 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5463 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5464 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5465 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5466 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5467 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5470 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5471 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5472 * table A7-13.
5474 #define NEON_2RM_VREV64 0
5475 #define NEON_2RM_VREV32 1
5476 #define NEON_2RM_VREV16 2
5477 #define NEON_2RM_VPADDL 4
5478 #define NEON_2RM_VPADDL_U 5
5479 #define NEON_2RM_AESE 6 /* Includes AESD */
5480 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5481 #define NEON_2RM_VCLS 8
5482 #define NEON_2RM_VCLZ 9
5483 #define NEON_2RM_VCNT 10
5484 #define NEON_2RM_VMVN 11
5485 #define NEON_2RM_VPADAL 12
5486 #define NEON_2RM_VPADAL_U 13
5487 #define NEON_2RM_VQABS 14
5488 #define NEON_2RM_VQNEG 15
5489 #define NEON_2RM_VCGT0 16
5490 #define NEON_2RM_VCGE0 17
5491 #define NEON_2RM_VCEQ0 18
5492 #define NEON_2RM_VCLE0 19
5493 #define NEON_2RM_VCLT0 20
5494 #define NEON_2RM_SHA1H 21
5495 #define NEON_2RM_VABS 22
5496 #define NEON_2RM_VNEG 23
5497 #define NEON_2RM_VCGT0_F 24
5498 #define NEON_2RM_VCGE0_F 25
5499 #define NEON_2RM_VCEQ0_F 26
5500 #define NEON_2RM_VCLE0_F 27
5501 #define NEON_2RM_VCLT0_F 28
5502 #define NEON_2RM_VABS_F 30
5503 #define NEON_2RM_VNEG_F 31
5504 #define NEON_2RM_VSWP 32
5505 #define NEON_2RM_VTRN 33
5506 #define NEON_2RM_VUZP 34
5507 #define NEON_2RM_VZIP 35
5508 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5509 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5510 #define NEON_2RM_VSHLL 38
5511 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5512 #define NEON_2RM_VRINTN 40
5513 #define NEON_2RM_VRINTX 41
5514 #define NEON_2RM_VRINTA 42
5515 #define NEON_2RM_VRINTZ 43
5516 #define NEON_2RM_VCVT_F16_F32 44
5517 #define NEON_2RM_VRINTM 45
5518 #define NEON_2RM_VCVT_F32_F16 46
5519 #define NEON_2RM_VRINTP 47
5520 #define NEON_2RM_VCVTAU 48
5521 #define NEON_2RM_VCVTAS 49
5522 #define NEON_2RM_VCVTNU 50
5523 #define NEON_2RM_VCVTNS 51
5524 #define NEON_2RM_VCVTPU 52
5525 #define NEON_2RM_VCVTPS 53
5526 #define NEON_2RM_VCVTMU 54
5527 #define NEON_2RM_VCVTMS 55
5528 #define NEON_2RM_VRECPE 56
5529 #define NEON_2RM_VRSQRTE 57
5530 #define NEON_2RM_VRECPE_F 58
5531 #define NEON_2RM_VRSQRTE_F 59
5532 #define NEON_2RM_VCVT_FS 60
5533 #define NEON_2RM_VCVT_FU 61
5534 #define NEON_2RM_VCVT_SF 62
5535 #define NEON_2RM_VCVT_UF 63
5537 static int neon_2rm_is_float_op(int op)
5539 /* Return true if this neon 2reg-misc op is float-to-float */
5540 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5541 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5542 op == NEON_2RM_VRINTM ||
5543 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5544 op >= NEON_2RM_VRECPE_F);
5547 static bool neon_2rm_is_v8_op(int op)
5549 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5550 switch (op) {
5551 case NEON_2RM_VRINTN:
5552 case NEON_2RM_VRINTA:
5553 case NEON_2RM_VRINTM:
5554 case NEON_2RM_VRINTP:
5555 case NEON_2RM_VRINTZ:
5556 case NEON_2RM_VRINTX:
5557 case NEON_2RM_VCVTAU:
5558 case NEON_2RM_VCVTAS:
5559 case NEON_2RM_VCVTNU:
5560 case NEON_2RM_VCVTNS:
5561 case NEON_2RM_VCVTPU:
5562 case NEON_2RM_VCVTPS:
5563 case NEON_2RM_VCVTMU:
5564 case NEON_2RM_VCVTMS:
5565 return true;
5566 default:
5567 return false;
5571 /* Each entry in this array has bit n set if the insn allows
5572 * size value n (otherwise it will UNDEF). Since unallocated
5573 * op values will have no bits set they always UNDEF.
5575 static const uint8_t neon_2rm_sizes[] = {
5576 [NEON_2RM_VREV64] = 0x7,
5577 [NEON_2RM_VREV32] = 0x3,
5578 [NEON_2RM_VREV16] = 0x1,
5579 [NEON_2RM_VPADDL] = 0x7,
5580 [NEON_2RM_VPADDL_U] = 0x7,
5581 [NEON_2RM_AESE] = 0x1,
5582 [NEON_2RM_AESMC] = 0x1,
5583 [NEON_2RM_VCLS] = 0x7,
5584 [NEON_2RM_VCLZ] = 0x7,
5585 [NEON_2RM_VCNT] = 0x1,
5586 [NEON_2RM_VMVN] = 0x1,
5587 [NEON_2RM_VPADAL] = 0x7,
5588 [NEON_2RM_VPADAL_U] = 0x7,
5589 [NEON_2RM_VQABS] = 0x7,
5590 [NEON_2RM_VQNEG] = 0x7,
5591 [NEON_2RM_VCGT0] = 0x7,
5592 [NEON_2RM_VCGE0] = 0x7,
5593 [NEON_2RM_VCEQ0] = 0x7,
5594 [NEON_2RM_VCLE0] = 0x7,
5595 [NEON_2RM_VCLT0] = 0x7,
5596 [NEON_2RM_SHA1H] = 0x4,
5597 [NEON_2RM_VABS] = 0x7,
5598 [NEON_2RM_VNEG] = 0x7,
5599 [NEON_2RM_VCGT0_F] = 0x4,
5600 [NEON_2RM_VCGE0_F] = 0x4,
5601 [NEON_2RM_VCEQ0_F] = 0x4,
5602 [NEON_2RM_VCLE0_F] = 0x4,
5603 [NEON_2RM_VCLT0_F] = 0x4,
5604 [NEON_2RM_VABS_F] = 0x4,
5605 [NEON_2RM_VNEG_F] = 0x4,
5606 [NEON_2RM_VSWP] = 0x1,
5607 [NEON_2RM_VTRN] = 0x7,
5608 [NEON_2RM_VUZP] = 0x7,
5609 [NEON_2RM_VZIP] = 0x7,
5610 [NEON_2RM_VMOVN] = 0x7,
5611 [NEON_2RM_VQMOVN] = 0x7,
5612 [NEON_2RM_VSHLL] = 0x7,
5613 [NEON_2RM_SHA1SU1] = 0x4,
5614 [NEON_2RM_VRINTN] = 0x4,
5615 [NEON_2RM_VRINTX] = 0x4,
5616 [NEON_2RM_VRINTA] = 0x4,
5617 [NEON_2RM_VRINTZ] = 0x4,
5618 [NEON_2RM_VCVT_F16_F32] = 0x2,
5619 [NEON_2RM_VRINTM] = 0x4,
5620 [NEON_2RM_VCVT_F32_F16] = 0x2,
5621 [NEON_2RM_VRINTP] = 0x4,
5622 [NEON_2RM_VCVTAU] = 0x4,
5623 [NEON_2RM_VCVTAS] = 0x4,
5624 [NEON_2RM_VCVTNU] = 0x4,
5625 [NEON_2RM_VCVTNS] = 0x4,
5626 [NEON_2RM_VCVTPU] = 0x4,
5627 [NEON_2RM_VCVTPS] = 0x4,
5628 [NEON_2RM_VCVTMU] = 0x4,
5629 [NEON_2RM_VCVTMS] = 0x4,
5630 [NEON_2RM_VRECPE] = 0x4,
5631 [NEON_2RM_VRSQRTE] = 0x4,
5632 [NEON_2RM_VRECPE_F] = 0x4,
5633 [NEON_2RM_VRSQRTE_F] = 0x4,
5634 [NEON_2RM_VCVT_FS] = 0x4,
5635 [NEON_2RM_VCVT_FU] = 0x4,
5636 [NEON_2RM_VCVT_SF] = 0x4,
5637 [NEON_2RM_VCVT_UF] = 0x4,
5641 /* Expand v8.1 simd helper. */
5642 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5643 int q, int rd, int rn, int rm)
5645 if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
5646 int opr_sz = (1 + q) * 8;
5647 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5648 vfp_reg_offset(1, rn),
5649 vfp_reg_offset(1, rm), cpu_env,
5650 opr_sz, opr_sz, 0, fn);
5651 return 0;
5653 return 1;
5656 /* Translate a NEON data processing instruction. Return nonzero if the
5657 instruction is invalid.
5658 We process data in a mixture of 32-bit and 64-bit chunks.
5659 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5661 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5663 int op;
5664 int q;
5665 int rd, rn, rm;
5666 int size;
5667 int shift;
5668 int pass;
5669 int count;
5670 int pairwise;
5671 int u;
5672 uint32_t imm, mask;
5673 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5674 TCGv_ptr ptr1, ptr2, ptr3;
5675 TCGv_i64 tmp64;
5677 /* FIXME: this access check should not take precedence over UNDEF
5678 * for invalid encodings; we will generate incorrect syndrome information
5679 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5681 if (s->fp_excp_el) {
5682 gen_exception_insn(s, 4, EXCP_UDEF,
5683 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5684 return 0;
5687 if (!s->vfp_enabled)
5688 return 1;
5689 q = (insn & (1 << 6)) != 0;
5690 u = (insn >> 24) & 1;
5691 VFP_DREG_D(rd, insn);
5692 VFP_DREG_N(rn, insn);
5693 VFP_DREG_M(rm, insn);
5694 size = (insn >> 20) & 3;
5695 if ((insn & (1 << 23)) == 0) {
5696 /* Three register same length. */
5697 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5698 /* Catch invalid op and bad size combinations: UNDEF */
5699 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5700 return 1;
5702 /* All insns of this form UNDEF for either this condition or the
5703 * superset of cases "Q==1"; we catch the latter later.
5705 if (q && ((rd | rn | rm) & 1)) {
5706 return 1;
5708 switch (op) {
5709 case NEON_3R_SHA:
5710 /* The SHA-1/SHA-256 3-register instructions require special
5711 * treatment here, as their size field is overloaded as an
5712 * op type selector, and they all consume their input in a
5713 * single pass.
5715 if (!q) {
5716 return 1;
5718 if (!u) { /* SHA-1 */
5719 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5720 return 1;
5722 ptr1 = vfp_reg_ptr(true, rd);
5723 ptr2 = vfp_reg_ptr(true, rn);
5724 ptr3 = vfp_reg_ptr(true, rm);
5725 tmp4 = tcg_const_i32(size);
5726 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5727 tcg_temp_free_i32(tmp4);
5728 } else { /* SHA-256 */
5729 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5730 return 1;
5732 ptr1 = vfp_reg_ptr(true, rd);
5733 ptr2 = vfp_reg_ptr(true, rn);
5734 ptr3 = vfp_reg_ptr(true, rm);
5735 switch (size) {
5736 case 0:
5737 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5738 break;
5739 case 1:
5740 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5741 break;
5742 case 2:
5743 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5744 break;
5747 tcg_temp_free_ptr(ptr1);
5748 tcg_temp_free_ptr(ptr2);
5749 tcg_temp_free_ptr(ptr3);
5750 return 0;
5752 case NEON_3R_VPADD_VQRDMLAH:
5753 if (!u) {
5754 break; /* VPADD */
5756 /* VQRDMLAH */
5757 switch (size) {
5758 case 1:
5759 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5760 q, rd, rn, rm);
5761 case 2:
5762 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5763 q, rd, rn, rm);
5765 return 1;
5767 case NEON_3R_VFM_VQRDMLSH:
5768 if (!u) {
5769 /* VFM, VFMS */
5770 if (size == 1) {
5771 return 1;
5773 break;
5775 /* VQRDMLSH */
5776 switch (size) {
5777 case 1:
5778 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5779 q, rd, rn, rm);
5780 case 2:
5781 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5782 q, rd, rn, rm);
5784 return 1;
5786 if (size == 3 && op != NEON_3R_LOGIC) {
5787 /* 64-bit element instructions. */
5788 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5789 neon_load_reg64(cpu_V0, rn + pass);
5790 neon_load_reg64(cpu_V1, rm + pass);
5791 switch (op) {
5792 case NEON_3R_VQADD:
5793 if (u) {
5794 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5795 cpu_V0, cpu_V1);
5796 } else {
5797 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5798 cpu_V0, cpu_V1);
5800 break;
5801 case NEON_3R_VQSUB:
5802 if (u) {
5803 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5804 cpu_V0, cpu_V1);
5805 } else {
5806 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5807 cpu_V0, cpu_V1);
5809 break;
5810 case NEON_3R_VSHL:
5811 if (u) {
5812 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5813 } else {
5814 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5816 break;
5817 case NEON_3R_VQSHL:
5818 if (u) {
5819 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5820 cpu_V1, cpu_V0);
5821 } else {
5822 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5823 cpu_V1, cpu_V0);
5825 break;
5826 case NEON_3R_VRSHL:
5827 if (u) {
5828 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5829 } else {
5830 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5832 break;
5833 case NEON_3R_VQRSHL:
5834 if (u) {
5835 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5836 cpu_V1, cpu_V0);
5837 } else {
5838 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5839 cpu_V1, cpu_V0);
5841 break;
5842 case NEON_3R_VADD_VSUB:
5843 if (u) {
5844 tcg_gen_sub_i64(CPU_V001);
5845 } else {
5846 tcg_gen_add_i64(CPU_V001);
5848 break;
5849 default:
5850 abort();
5852 neon_store_reg64(cpu_V0, rd + pass);
5854 return 0;
5856 pairwise = 0;
5857 switch (op) {
5858 case NEON_3R_VSHL:
5859 case NEON_3R_VQSHL:
5860 case NEON_3R_VRSHL:
5861 case NEON_3R_VQRSHL:
5863 int rtmp;
5864 /* Shift instruction operands are reversed. */
5865 rtmp = rn;
5866 rn = rm;
5867 rm = rtmp;
5869 break;
5870 case NEON_3R_VPADD_VQRDMLAH:
5871 case NEON_3R_VPMAX:
5872 case NEON_3R_VPMIN:
5873 pairwise = 1;
5874 break;
5875 case NEON_3R_FLOAT_ARITH:
5876 pairwise = (u && size < 2); /* if VPADD (float) */
5877 break;
5878 case NEON_3R_FLOAT_MINMAX:
5879 pairwise = u; /* if VPMIN/VPMAX (float) */
5880 break;
5881 case NEON_3R_FLOAT_CMP:
5882 if (!u && size) {
5883 /* no encoding for U=0 C=1x */
5884 return 1;
5886 break;
5887 case NEON_3R_FLOAT_ACMP:
5888 if (!u) {
5889 return 1;
5891 break;
5892 case NEON_3R_FLOAT_MISC:
5893 /* VMAXNM/VMINNM in ARMv8 */
5894 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5895 return 1;
5897 break;
5898 case NEON_3R_VMUL:
5899 if (u && (size != 0)) {
5900 /* UNDEF on invalid size for polynomial subcase */
5901 return 1;
5903 break;
5904 case NEON_3R_VFM_VQRDMLSH:
5905 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5906 return 1;
5908 break;
5909 default:
5910 break;
5913 if (pairwise && q) {
5914 /* All the pairwise insns UNDEF if Q is set */
5915 return 1;
5918 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5920 if (pairwise) {
5921 /* Pairwise. */
5922 if (pass < 1) {
5923 tmp = neon_load_reg(rn, 0);
5924 tmp2 = neon_load_reg(rn, 1);
5925 } else {
5926 tmp = neon_load_reg(rm, 0);
5927 tmp2 = neon_load_reg(rm, 1);
5929 } else {
5930 /* Elementwise. */
5931 tmp = neon_load_reg(rn, pass);
5932 tmp2 = neon_load_reg(rm, pass);
5934 switch (op) {
5935 case NEON_3R_VHADD:
5936 GEN_NEON_INTEGER_OP(hadd);
5937 break;
5938 case NEON_3R_VQADD:
5939 GEN_NEON_INTEGER_OP_ENV(qadd);
5940 break;
5941 case NEON_3R_VRHADD:
5942 GEN_NEON_INTEGER_OP(rhadd);
5943 break;
5944 case NEON_3R_LOGIC: /* Logic ops. */
5945 switch ((u << 2) | size) {
5946 case 0: /* VAND */
5947 tcg_gen_and_i32(tmp, tmp, tmp2);
5948 break;
5949 case 1: /* BIC */
5950 tcg_gen_andc_i32(tmp, tmp, tmp2);
5951 break;
5952 case 2: /* VORR */
5953 tcg_gen_or_i32(tmp, tmp, tmp2);
5954 break;
5955 case 3: /* VORN */
5956 tcg_gen_orc_i32(tmp, tmp, tmp2);
5957 break;
5958 case 4: /* VEOR */
5959 tcg_gen_xor_i32(tmp, tmp, tmp2);
5960 break;
5961 case 5: /* VBSL */
5962 tmp3 = neon_load_reg(rd, pass);
5963 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5964 tcg_temp_free_i32(tmp3);
5965 break;
5966 case 6: /* VBIT */
5967 tmp3 = neon_load_reg(rd, pass);
5968 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5969 tcg_temp_free_i32(tmp3);
5970 break;
5971 case 7: /* VBIF */
5972 tmp3 = neon_load_reg(rd, pass);
5973 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5974 tcg_temp_free_i32(tmp3);
5975 break;
5977 break;
5978 case NEON_3R_VHSUB:
5979 GEN_NEON_INTEGER_OP(hsub);
5980 break;
5981 case NEON_3R_VQSUB:
5982 GEN_NEON_INTEGER_OP_ENV(qsub);
5983 break;
5984 case NEON_3R_VCGT:
5985 GEN_NEON_INTEGER_OP(cgt);
5986 break;
5987 case NEON_3R_VCGE:
5988 GEN_NEON_INTEGER_OP(cge);
5989 break;
5990 case NEON_3R_VSHL:
5991 GEN_NEON_INTEGER_OP(shl);
5992 break;
5993 case NEON_3R_VQSHL:
5994 GEN_NEON_INTEGER_OP_ENV(qshl);
5995 break;
5996 case NEON_3R_VRSHL:
5997 GEN_NEON_INTEGER_OP(rshl);
5998 break;
5999 case NEON_3R_VQRSHL:
6000 GEN_NEON_INTEGER_OP_ENV(qrshl);
6001 break;
6002 case NEON_3R_VMAX:
6003 GEN_NEON_INTEGER_OP(max);
6004 break;
6005 case NEON_3R_VMIN:
6006 GEN_NEON_INTEGER_OP(min);
6007 break;
6008 case NEON_3R_VABD:
6009 GEN_NEON_INTEGER_OP(abd);
6010 break;
6011 case NEON_3R_VABA:
6012 GEN_NEON_INTEGER_OP(abd);
6013 tcg_temp_free_i32(tmp2);
6014 tmp2 = neon_load_reg(rd, pass);
6015 gen_neon_add(size, tmp, tmp2);
6016 break;
6017 case NEON_3R_VADD_VSUB:
6018 if (!u) { /* VADD */
6019 gen_neon_add(size, tmp, tmp2);
6020 } else { /* VSUB */
6021 switch (size) {
6022 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
6023 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
6024 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
6025 default: abort();
6028 break;
6029 case NEON_3R_VTST_VCEQ:
6030 if (!u) { /* VTST */
6031 switch (size) {
6032 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
6033 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
6034 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
6035 default: abort();
6037 } else { /* VCEQ */
6038 switch (size) {
6039 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6040 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6041 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6042 default: abort();
6045 break;
6046 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
6047 switch (size) {
6048 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6049 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6050 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6051 default: abort();
6053 tcg_temp_free_i32(tmp2);
6054 tmp2 = neon_load_reg(rd, pass);
6055 if (u) { /* VMLS */
6056 gen_neon_rsb(size, tmp, tmp2);
6057 } else { /* VMLA */
6058 gen_neon_add(size, tmp, tmp2);
6060 break;
6061 case NEON_3R_VMUL:
6062 if (u) { /* polynomial */
6063 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6064 } else { /* Integer */
6065 switch (size) {
6066 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6067 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6068 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6069 default: abort();
6072 break;
6073 case NEON_3R_VPMAX:
6074 GEN_NEON_INTEGER_OP(pmax);
6075 break;
6076 case NEON_3R_VPMIN:
6077 GEN_NEON_INTEGER_OP(pmin);
6078 break;
6079 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6080 if (!u) { /* VQDMULH */
6081 switch (size) {
6082 case 1:
6083 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6084 break;
6085 case 2:
6086 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6087 break;
6088 default: abort();
6090 } else { /* VQRDMULH */
6091 switch (size) {
6092 case 1:
6093 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6094 break;
6095 case 2:
6096 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6097 break;
6098 default: abort();
6101 break;
6102 case NEON_3R_VPADD_VQRDMLAH:
6103 switch (size) {
6104 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6105 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6106 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6107 default: abort();
6109 break;
6110 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6112 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6113 switch ((u << 2) | size) {
6114 case 0: /* VADD */
6115 case 4: /* VPADD */
6116 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6117 break;
6118 case 2: /* VSUB */
6119 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6120 break;
6121 case 6: /* VABD */
6122 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6123 break;
6124 default:
6125 abort();
6127 tcg_temp_free_ptr(fpstatus);
6128 break;
6130 case NEON_3R_FLOAT_MULTIPLY:
6132 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6133 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6134 if (!u) {
6135 tcg_temp_free_i32(tmp2);
6136 tmp2 = neon_load_reg(rd, pass);
6137 if (size == 0) {
6138 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6139 } else {
6140 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6143 tcg_temp_free_ptr(fpstatus);
6144 break;
6146 case NEON_3R_FLOAT_CMP:
6148 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6149 if (!u) {
6150 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6151 } else {
6152 if (size == 0) {
6153 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6154 } else {
6155 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6158 tcg_temp_free_ptr(fpstatus);
6159 break;
6161 case NEON_3R_FLOAT_ACMP:
6163 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6164 if (size == 0) {
6165 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6166 } else {
6167 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6169 tcg_temp_free_ptr(fpstatus);
6170 break;
6172 case NEON_3R_FLOAT_MINMAX:
6174 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6175 if (size == 0) {
6176 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6177 } else {
6178 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6180 tcg_temp_free_ptr(fpstatus);
6181 break;
6183 case NEON_3R_FLOAT_MISC:
6184 if (u) {
6185 /* VMAXNM/VMINNM */
6186 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6187 if (size == 0) {
6188 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6189 } else {
6190 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6192 tcg_temp_free_ptr(fpstatus);
6193 } else {
6194 if (size == 0) {
6195 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6196 } else {
6197 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6200 break;
6201 case NEON_3R_VFM_VQRDMLSH:
6203 /* VFMA, VFMS: fused multiply-add */
6204 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6205 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6206 if (size) {
6207 /* VFMS */
6208 gen_helper_vfp_negs(tmp, tmp);
6210 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6211 tcg_temp_free_i32(tmp3);
6212 tcg_temp_free_ptr(fpstatus);
6213 break;
6215 default:
6216 abort();
6218 tcg_temp_free_i32(tmp2);
6220 /* Save the result. For elementwise operations we can put it
6221 straight into the destination register. For pairwise operations
6222 we have to be careful to avoid clobbering the source operands. */
6223 if (pairwise && rd == rm) {
6224 neon_store_scratch(pass, tmp);
6225 } else {
6226 neon_store_reg(rd, pass, tmp);
6229 } /* for pass */
6230 if (pairwise && rd == rm) {
6231 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6232 tmp = neon_load_scratch(pass);
6233 neon_store_reg(rd, pass, tmp);
6236 /* End of 3 register same size operations. */
6237 } else if (insn & (1 << 4)) {
6238 if ((insn & 0x00380080) != 0) {
6239 /* Two registers and shift. */
6240 op = (insn >> 8) & 0xf;
6241 if (insn & (1 << 7)) {
6242 /* 64-bit shift. */
6243 if (op > 7) {
6244 return 1;
6246 size = 3;
6247 } else {
6248 size = 2;
6249 while ((insn & (1 << (size + 19))) == 0)
6250 size--;
6252 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6253 /* To avoid excessive duplication of ops we implement shift
6254 by immediate using the variable shift operations. */
6255 if (op < 8) {
6256 /* Shift by immediate:
6257 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6258 if (q && ((rd | rm) & 1)) {
6259 return 1;
6261 if (!u && (op == 4 || op == 6)) {
6262 return 1;
6264 /* Right shifts are encoded as N - shift, where N is the
6265 element size in bits. */
6266 if (op <= 4)
6267 shift = shift - (1 << (size + 3));
6268 if (size == 3) {
6269 count = q + 1;
6270 } else {
6271 count = q ? 4: 2;
6273 switch (size) {
6274 case 0:
6275 imm = (uint8_t) shift;
6276 imm |= imm << 8;
6277 imm |= imm << 16;
6278 break;
6279 case 1:
6280 imm = (uint16_t) shift;
6281 imm |= imm << 16;
6282 break;
6283 case 2:
6284 case 3:
6285 imm = shift;
6286 break;
6287 default:
6288 abort();
6291 for (pass = 0; pass < count; pass++) {
6292 if (size == 3) {
6293 neon_load_reg64(cpu_V0, rm + pass);
6294 tcg_gen_movi_i64(cpu_V1, imm);
6295 switch (op) {
6296 case 0: /* VSHR */
6297 case 1: /* VSRA */
6298 if (u)
6299 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6300 else
6301 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6302 break;
6303 case 2: /* VRSHR */
6304 case 3: /* VRSRA */
6305 if (u)
6306 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6307 else
6308 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6309 break;
6310 case 4: /* VSRI */
6311 case 5: /* VSHL, VSLI */
6312 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6313 break;
6314 case 6: /* VQSHLU */
6315 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6316 cpu_V0, cpu_V1);
6317 break;
6318 case 7: /* VQSHL */
6319 if (u) {
6320 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6321 cpu_V0, cpu_V1);
6322 } else {
6323 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6324 cpu_V0, cpu_V1);
6326 break;
6328 if (op == 1 || op == 3) {
6329 /* Accumulate. */
6330 neon_load_reg64(cpu_V1, rd + pass);
6331 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6332 } else if (op == 4 || (op == 5 && u)) {
6333 /* Insert */
6334 neon_load_reg64(cpu_V1, rd + pass);
6335 uint64_t mask;
6336 if (shift < -63 || shift > 63) {
6337 mask = 0;
6338 } else {
6339 if (op == 4) {
6340 mask = 0xffffffffffffffffull >> -shift;
6341 } else {
6342 mask = 0xffffffffffffffffull << shift;
6345 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6346 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6348 neon_store_reg64(cpu_V0, rd + pass);
6349 } else { /* size < 3 */
6350 /* Operands in T0 and T1. */
6351 tmp = neon_load_reg(rm, pass);
6352 tmp2 = tcg_temp_new_i32();
6353 tcg_gen_movi_i32(tmp2, imm);
6354 switch (op) {
6355 case 0: /* VSHR */
6356 case 1: /* VSRA */
6357 GEN_NEON_INTEGER_OP(shl);
6358 break;
6359 case 2: /* VRSHR */
6360 case 3: /* VRSRA */
6361 GEN_NEON_INTEGER_OP(rshl);
6362 break;
6363 case 4: /* VSRI */
6364 case 5: /* VSHL, VSLI */
6365 switch (size) {
6366 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6367 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6368 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6369 default: abort();
6371 break;
6372 case 6: /* VQSHLU */
6373 switch (size) {
6374 case 0:
6375 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6376 tmp, tmp2);
6377 break;
6378 case 1:
6379 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6380 tmp, tmp2);
6381 break;
6382 case 2:
6383 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6384 tmp, tmp2);
6385 break;
6386 default:
6387 abort();
6389 break;
6390 case 7: /* VQSHL */
6391 GEN_NEON_INTEGER_OP_ENV(qshl);
6392 break;
6394 tcg_temp_free_i32(tmp2);
6396 if (op == 1 || op == 3) {
6397 /* Accumulate. */
6398 tmp2 = neon_load_reg(rd, pass);
6399 gen_neon_add(size, tmp, tmp2);
6400 tcg_temp_free_i32(tmp2);
6401 } else if (op == 4 || (op == 5 && u)) {
6402 /* Insert */
6403 switch (size) {
6404 case 0:
6405 if (op == 4)
6406 mask = 0xff >> -shift;
6407 else
6408 mask = (uint8_t)(0xff << shift);
6409 mask |= mask << 8;
6410 mask |= mask << 16;
6411 break;
6412 case 1:
6413 if (op == 4)
6414 mask = 0xffff >> -shift;
6415 else
6416 mask = (uint16_t)(0xffff << shift);
6417 mask |= mask << 16;
6418 break;
6419 case 2:
6420 if (shift < -31 || shift > 31) {
6421 mask = 0;
6422 } else {
6423 if (op == 4)
6424 mask = 0xffffffffu >> -shift;
6425 else
6426 mask = 0xffffffffu << shift;
6428 break;
6429 default:
6430 abort();
6432 tmp2 = neon_load_reg(rd, pass);
6433 tcg_gen_andi_i32(tmp, tmp, mask);
6434 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6435 tcg_gen_or_i32(tmp, tmp, tmp2);
6436 tcg_temp_free_i32(tmp2);
6438 neon_store_reg(rd, pass, tmp);
6440 } /* for pass */
6441 } else if (op < 10) {
6442 /* Shift by immediate and narrow:
6443 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6444 int input_unsigned = (op == 8) ? !u : u;
6445 if (rm & 1) {
6446 return 1;
6448 shift = shift - (1 << (size + 3));
6449 size++;
6450 if (size == 3) {
6451 tmp64 = tcg_const_i64(shift);
6452 neon_load_reg64(cpu_V0, rm);
6453 neon_load_reg64(cpu_V1, rm + 1);
6454 for (pass = 0; pass < 2; pass++) {
6455 TCGv_i64 in;
6456 if (pass == 0) {
6457 in = cpu_V0;
6458 } else {
6459 in = cpu_V1;
6461 if (q) {
6462 if (input_unsigned) {
6463 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6464 } else {
6465 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6467 } else {
6468 if (input_unsigned) {
6469 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6470 } else {
6471 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6474 tmp = tcg_temp_new_i32();
6475 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6476 neon_store_reg(rd, pass, tmp);
6477 } /* for pass */
6478 tcg_temp_free_i64(tmp64);
6479 } else {
6480 if (size == 1) {
6481 imm = (uint16_t)shift;
6482 imm |= imm << 16;
6483 } else {
6484 /* size == 2 */
6485 imm = (uint32_t)shift;
6487 tmp2 = tcg_const_i32(imm);
6488 tmp4 = neon_load_reg(rm + 1, 0);
6489 tmp5 = neon_load_reg(rm + 1, 1);
6490 for (pass = 0; pass < 2; pass++) {
6491 if (pass == 0) {
6492 tmp = neon_load_reg(rm, 0);
6493 } else {
6494 tmp = tmp4;
6496 gen_neon_shift_narrow(size, tmp, tmp2, q,
6497 input_unsigned);
6498 if (pass == 0) {
6499 tmp3 = neon_load_reg(rm, 1);
6500 } else {
6501 tmp3 = tmp5;
6503 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6504 input_unsigned);
6505 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6506 tcg_temp_free_i32(tmp);
6507 tcg_temp_free_i32(tmp3);
6508 tmp = tcg_temp_new_i32();
6509 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6510 neon_store_reg(rd, pass, tmp);
6511 } /* for pass */
6512 tcg_temp_free_i32(tmp2);
6514 } else if (op == 10) {
6515 /* VSHLL, VMOVL */
6516 if (q || (rd & 1)) {
6517 return 1;
6519 tmp = neon_load_reg(rm, 0);
6520 tmp2 = neon_load_reg(rm, 1);
6521 for (pass = 0; pass < 2; pass++) {
6522 if (pass == 1)
6523 tmp = tmp2;
6525 gen_neon_widen(cpu_V0, tmp, size, u);
6527 if (shift != 0) {
6528 /* The shift is less than the width of the source
6529 type, so we can just shift the whole register. */
6530 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6531 /* Widen the result of shift: we need to clear
6532 * the potential overflow bits resulting from
6533 * left bits of the narrow input appearing as
6534 * right bits of left the neighbour narrow
6535 * input. */
6536 if (size < 2 || !u) {
6537 uint64_t imm64;
6538 if (size == 0) {
6539 imm = (0xffu >> (8 - shift));
6540 imm |= imm << 16;
6541 } else if (size == 1) {
6542 imm = 0xffff >> (16 - shift);
6543 } else {
6544 /* size == 2 */
6545 imm = 0xffffffff >> (32 - shift);
6547 if (size < 2) {
6548 imm64 = imm | (((uint64_t)imm) << 32);
6549 } else {
6550 imm64 = imm;
6552 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6555 neon_store_reg64(cpu_V0, rd + pass);
6557 } else if (op >= 14) {
6558 /* VCVT fixed-point. */
6559 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6560 return 1;
6562 /* We have already masked out the must-be-1 top bit of imm6,
6563 * hence this 32-shift where the ARM ARM has 64-imm6.
6565 shift = 32 - shift;
6566 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6567 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6568 if (!(op & 1)) {
6569 if (u)
6570 gen_vfp_ulto(0, shift, 1);
6571 else
6572 gen_vfp_slto(0, shift, 1);
6573 } else {
6574 if (u)
6575 gen_vfp_toul(0, shift, 1);
6576 else
6577 gen_vfp_tosl(0, shift, 1);
6579 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6581 } else {
6582 return 1;
6584 } else { /* (insn & 0x00380080) == 0 */
6585 int invert;
6586 if (q && (rd & 1)) {
6587 return 1;
6590 op = (insn >> 8) & 0xf;
6591 /* One register and immediate. */
6592 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6593 invert = (insn & (1 << 5)) != 0;
6594 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6595 * We choose to not special-case this and will behave as if a
6596 * valid constant encoding of 0 had been given.
6598 switch (op) {
6599 case 0: case 1:
6600 /* no-op */
6601 break;
6602 case 2: case 3:
6603 imm <<= 8;
6604 break;
6605 case 4: case 5:
6606 imm <<= 16;
6607 break;
6608 case 6: case 7:
6609 imm <<= 24;
6610 break;
6611 case 8: case 9:
6612 imm |= imm << 16;
6613 break;
6614 case 10: case 11:
6615 imm = (imm << 8) | (imm << 24);
6616 break;
6617 case 12:
6618 imm = (imm << 8) | 0xff;
6619 break;
6620 case 13:
6621 imm = (imm << 16) | 0xffff;
6622 break;
6623 case 14:
6624 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6625 if (invert)
6626 imm = ~imm;
6627 break;
6628 case 15:
6629 if (invert) {
6630 return 1;
6632 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6633 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6634 break;
6636 if (invert)
6637 imm = ~imm;
6639 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6640 if (op & 1 && op < 12) {
6641 tmp = neon_load_reg(rd, pass);
6642 if (invert) {
6643 /* The immediate value has already been inverted, so
6644 BIC becomes AND. */
6645 tcg_gen_andi_i32(tmp, tmp, imm);
6646 } else {
6647 tcg_gen_ori_i32(tmp, tmp, imm);
6649 } else {
6650 /* VMOV, VMVN. */
6651 tmp = tcg_temp_new_i32();
6652 if (op == 14 && invert) {
6653 int n;
6654 uint32_t val;
6655 val = 0;
6656 for (n = 0; n < 4; n++) {
6657 if (imm & (1 << (n + (pass & 1) * 4)))
6658 val |= 0xff << (n * 8);
6660 tcg_gen_movi_i32(tmp, val);
6661 } else {
6662 tcg_gen_movi_i32(tmp, imm);
6665 neon_store_reg(rd, pass, tmp);
6668 } else { /* (insn & 0x00800010 == 0x00800000) */
6669 if (size != 3) {
6670 op = (insn >> 8) & 0xf;
6671 if ((insn & (1 << 6)) == 0) {
6672 /* Three registers of different lengths. */
6673 int src1_wide;
6674 int src2_wide;
6675 int prewiden;
6676 /* undefreq: bit 0 : UNDEF if size == 0
6677 * bit 1 : UNDEF if size == 1
6678 * bit 2 : UNDEF if size == 2
6679 * bit 3 : UNDEF if U == 1
6680 * Note that [2:0] set implies 'always UNDEF'
6682 int undefreq;
6683 /* prewiden, src1_wide, src2_wide, undefreq */
6684 static const int neon_3reg_wide[16][4] = {
6685 {1, 0, 0, 0}, /* VADDL */
6686 {1, 1, 0, 0}, /* VADDW */
6687 {1, 0, 0, 0}, /* VSUBL */
6688 {1, 1, 0, 0}, /* VSUBW */
6689 {0, 1, 1, 0}, /* VADDHN */
6690 {0, 0, 0, 0}, /* VABAL */
6691 {0, 1, 1, 0}, /* VSUBHN */
6692 {0, 0, 0, 0}, /* VABDL */
6693 {0, 0, 0, 0}, /* VMLAL */
6694 {0, 0, 0, 9}, /* VQDMLAL */
6695 {0, 0, 0, 0}, /* VMLSL */
6696 {0, 0, 0, 9}, /* VQDMLSL */
6697 {0, 0, 0, 0}, /* Integer VMULL */
6698 {0, 0, 0, 1}, /* VQDMULL */
6699 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6700 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6703 prewiden = neon_3reg_wide[op][0];
6704 src1_wide = neon_3reg_wide[op][1];
6705 src2_wide = neon_3reg_wide[op][2];
6706 undefreq = neon_3reg_wide[op][3];
6708 if ((undefreq & (1 << size)) ||
6709 ((undefreq & 8) && u)) {
6710 return 1;
6712 if ((src1_wide && (rn & 1)) ||
6713 (src2_wide && (rm & 1)) ||
6714 (!src2_wide && (rd & 1))) {
6715 return 1;
6718 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6719 * outside the loop below as it only performs a single pass.
6721 if (op == 14 && size == 2) {
6722 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6724 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6725 return 1;
6727 tcg_rn = tcg_temp_new_i64();
6728 tcg_rm = tcg_temp_new_i64();
6729 tcg_rd = tcg_temp_new_i64();
6730 neon_load_reg64(tcg_rn, rn);
6731 neon_load_reg64(tcg_rm, rm);
6732 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6733 neon_store_reg64(tcg_rd, rd);
6734 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6735 neon_store_reg64(tcg_rd, rd + 1);
6736 tcg_temp_free_i64(tcg_rn);
6737 tcg_temp_free_i64(tcg_rm);
6738 tcg_temp_free_i64(tcg_rd);
6739 return 0;
6742 /* Avoid overlapping operands. Wide source operands are
6743 always aligned so will never overlap with wide
6744 destinations in problematic ways. */
6745 if (rd == rm && !src2_wide) {
6746 tmp = neon_load_reg(rm, 1);
6747 neon_store_scratch(2, tmp);
6748 } else if (rd == rn && !src1_wide) {
6749 tmp = neon_load_reg(rn, 1);
6750 neon_store_scratch(2, tmp);
6752 tmp3 = NULL;
6753 for (pass = 0; pass < 2; pass++) {
6754 if (src1_wide) {
6755 neon_load_reg64(cpu_V0, rn + pass);
6756 tmp = NULL;
6757 } else {
6758 if (pass == 1 && rd == rn) {
6759 tmp = neon_load_scratch(2);
6760 } else {
6761 tmp = neon_load_reg(rn, pass);
6763 if (prewiden) {
6764 gen_neon_widen(cpu_V0, tmp, size, u);
6767 if (src2_wide) {
6768 neon_load_reg64(cpu_V1, rm + pass);
6769 tmp2 = NULL;
6770 } else {
6771 if (pass == 1 && rd == rm) {
6772 tmp2 = neon_load_scratch(2);
6773 } else {
6774 tmp2 = neon_load_reg(rm, pass);
6776 if (prewiden) {
6777 gen_neon_widen(cpu_V1, tmp2, size, u);
6780 switch (op) {
6781 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6782 gen_neon_addl(size);
6783 break;
6784 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6785 gen_neon_subl(size);
6786 break;
6787 case 5: case 7: /* VABAL, VABDL */
6788 switch ((size << 1) | u) {
6789 case 0:
6790 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6791 break;
6792 case 1:
6793 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6794 break;
6795 case 2:
6796 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6797 break;
6798 case 3:
6799 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6800 break;
6801 case 4:
6802 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6803 break;
6804 case 5:
6805 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6806 break;
6807 default: abort();
6809 tcg_temp_free_i32(tmp2);
6810 tcg_temp_free_i32(tmp);
6811 break;
6812 case 8: case 9: case 10: case 11: case 12: case 13:
6813 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6814 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6815 break;
6816 case 14: /* Polynomial VMULL */
6817 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6818 tcg_temp_free_i32(tmp2);
6819 tcg_temp_free_i32(tmp);
6820 break;
6821 default: /* 15 is RESERVED: caught earlier */
6822 abort();
6824 if (op == 13) {
6825 /* VQDMULL */
6826 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6827 neon_store_reg64(cpu_V0, rd + pass);
6828 } else if (op == 5 || (op >= 8 && op <= 11)) {
6829 /* Accumulate. */
6830 neon_load_reg64(cpu_V1, rd + pass);
6831 switch (op) {
6832 case 10: /* VMLSL */
6833 gen_neon_negl(cpu_V0, size);
6834 /* Fall through */
6835 case 5: case 8: /* VABAL, VMLAL */
6836 gen_neon_addl(size);
6837 break;
6838 case 9: case 11: /* VQDMLAL, VQDMLSL */
6839 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6840 if (op == 11) {
6841 gen_neon_negl(cpu_V0, size);
6843 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6844 break;
6845 default:
6846 abort();
6848 neon_store_reg64(cpu_V0, rd + pass);
6849 } else if (op == 4 || op == 6) {
6850 /* Narrowing operation. */
6851 tmp = tcg_temp_new_i32();
6852 if (!u) {
6853 switch (size) {
6854 case 0:
6855 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6856 break;
6857 case 1:
6858 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6859 break;
6860 case 2:
6861 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6862 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6863 break;
6864 default: abort();
6866 } else {
6867 switch (size) {
6868 case 0:
6869 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6870 break;
6871 case 1:
6872 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6873 break;
6874 case 2:
6875 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6876 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6877 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6878 break;
6879 default: abort();
6882 if (pass == 0) {
6883 tmp3 = tmp;
6884 } else {
6885 neon_store_reg(rd, 0, tmp3);
6886 neon_store_reg(rd, 1, tmp);
6888 } else {
6889 /* Write back the result. */
6890 neon_store_reg64(cpu_V0, rd + pass);
6893 } else {
6894 /* Two registers and a scalar. NB that for ops of this form
6895 * the ARM ARM labels bit 24 as Q, but it is in our variable
6896 * 'u', not 'q'.
6898 if (size == 0) {
6899 return 1;
6901 switch (op) {
6902 case 1: /* Float VMLA scalar */
6903 case 5: /* Floating point VMLS scalar */
6904 case 9: /* Floating point VMUL scalar */
6905 if (size == 1) {
6906 return 1;
6908 /* fall through */
6909 case 0: /* Integer VMLA scalar */
6910 case 4: /* Integer VMLS scalar */
6911 case 8: /* Integer VMUL scalar */
6912 case 12: /* VQDMULH scalar */
6913 case 13: /* VQRDMULH scalar */
6914 if (u && ((rd | rn) & 1)) {
6915 return 1;
6917 tmp = neon_get_scalar(size, rm);
6918 neon_store_scratch(0, tmp);
6919 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6920 tmp = neon_load_scratch(0);
6921 tmp2 = neon_load_reg(rn, pass);
6922 if (op == 12) {
6923 if (size == 1) {
6924 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6925 } else {
6926 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6928 } else if (op == 13) {
6929 if (size == 1) {
6930 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6931 } else {
6932 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6934 } else if (op & 1) {
6935 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6936 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6937 tcg_temp_free_ptr(fpstatus);
6938 } else {
6939 switch (size) {
6940 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6941 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6942 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6943 default: abort();
6946 tcg_temp_free_i32(tmp2);
6947 if (op < 8) {
6948 /* Accumulate. */
6949 tmp2 = neon_load_reg(rd, pass);
6950 switch (op) {
6951 case 0:
6952 gen_neon_add(size, tmp, tmp2);
6953 break;
6954 case 1:
6956 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6957 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6958 tcg_temp_free_ptr(fpstatus);
6959 break;
6961 case 4:
6962 gen_neon_rsb(size, tmp, tmp2);
6963 break;
6964 case 5:
6966 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6967 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6968 tcg_temp_free_ptr(fpstatus);
6969 break;
6971 default:
6972 abort();
6974 tcg_temp_free_i32(tmp2);
6976 neon_store_reg(rd, pass, tmp);
6978 break;
6979 case 3: /* VQDMLAL scalar */
6980 case 7: /* VQDMLSL scalar */
6981 case 11: /* VQDMULL scalar */
6982 if (u == 1) {
6983 return 1;
6985 /* fall through */
6986 case 2: /* VMLAL sclar */
6987 case 6: /* VMLSL scalar */
6988 case 10: /* VMULL scalar */
6989 if (rd & 1) {
6990 return 1;
6992 tmp2 = neon_get_scalar(size, rm);
6993 /* We need a copy of tmp2 because gen_neon_mull
6994 * deletes it during pass 0. */
6995 tmp4 = tcg_temp_new_i32();
6996 tcg_gen_mov_i32(tmp4, tmp2);
6997 tmp3 = neon_load_reg(rn, 1);
6999 for (pass = 0; pass < 2; pass++) {
7000 if (pass == 0) {
7001 tmp = neon_load_reg(rn, 0);
7002 } else {
7003 tmp = tmp3;
7004 tmp2 = tmp4;
7006 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7007 if (op != 11) {
7008 neon_load_reg64(cpu_V1, rd + pass);
7010 switch (op) {
7011 case 6:
7012 gen_neon_negl(cpu_V0, size);
7013 /* Fall through */
7014 case 2:
7015 gen_neon_addl(size);
7016 break;
7017 case 3: case 7:
7018 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7019 if (op == 7) {
7020 gen_neon_negl(cpu_V0, size);
7022 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7023 break;
7024 case 10:
7025 /* no-op */
7026 break;
7027 case 11:
7028 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7029 break;
7030 default:
7031 abort();
7033 neon_store_reg64(cpu_V0, rd + pass);
7035 break;
7036 case 14: /* VQRDMLAH scalar */
7037 case 15: /* VQRDMLSH scalar */
7039 NeonGenThreeOpEnvFn *fn;
7041 if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
7042 return 1;
7044 if (u && ((rd | rn) & 1)) {
7045 return 1;
7047 if (op == 14) {
7048 if (size == 1) {
7049 fn = gen_helper_neon_qrdmlah_s16;
7050 } else {
7051 fn = gen_helper_neon_qrdmlah_s32;
7053 } else {
7054 if (size == 1) {
7055 fn = gen_helper_neon_qrdmlsh_s16;
7056 } else {
7057 fn = gen_helper_neon_qrdmlsh_s32;
7061 tmp2 = neon_get_scalar(size, rm);
7062 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7063 tmp = neon_load_reg(rn, pass);
7064 tmp3 = neon_load_reg(rd, pass);
7065 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7066 tcg_temp_free_i32(tmp3);
7067 neon_store_reg(rd, pass, tmp);
7069 tcg_temp_free_i32(tmp2);
7071 break;
7072 default:
7073 g_assert_not_reached();
7076 } else { /* size == 3 */
7077 if (!u) {
7078 /* Extract. */
7079 imm = (insn >> 8) & 0xf;
7081 if (imm > 7 && !q)
7082 return 1;
7084 if (q && ((rd | rn | rm) & 1)) {
7085 return 1;
7088 if (imm == 0) {
7089 neon_load_reg64(cpu_V0, rn);
7090 if (q) {
7091 neon_load_reg64(cpu_V1, rn + 1);
7093 } else if (imm == 8) {
7094 neon_load_reg64(cpu_V0, rn + 1);
7095 if (q) {
7096 neon_load_reg64(cpu_V1, rm);
7098 } else if (q) {
7099 tmp64 = tcg_temp_new_i64();
7100 if (imm < 8) {
7101 neon_load_reg64(cpu_V0, rn);
7102 neon_load_reg64(tmp64, rn + 1);
7103 } else {
7104 neon_load_reg64(cpu_V0, rn + 1);
7105 neon_load_reg64(tmp64, rm);
7107 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7108 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7109 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7110 if (imm < 8) {
7111 neon_load_reg64(cpu_V1, rm);
7112 } else {
7113 neon_load_reg64(cpu_V1, rm + 1);
7114 imm -= 8;
7116 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7117 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7118 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7119 tcg_temp_free_i64(tmp64);
7120 } else {
7121 /* BUGFIX */
7122 neon_load_reg64(cpu_V0, rn);
7123 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7124 neon_load_reg64(cpu_V1, rm);
7125 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7126 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7128 neon_store_reg64(cpu_V0, rd);
7129 if (q) {
7130 neon_store_reg64(cpu_V1, rd + 1);
7132 } else if ((insn & (1 << 11)) == 0) {
7133 /* Two register misc. */
7134 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7135 size = (insn >> 18) & 3;
7136 /* UNDEF for unknown op values and bad op-size combinations */
7137 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7138 return 1;
7140 if (neon_2rm_is_v8_op(op) &&
7141 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7142 return 1;
7144 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7145 q && ((rm | rd) & 1)) {
7146 return 1;
7148 switch (op) {
7149 case NEON_2RM_VREV64:
7150 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7151 tmp = neon_load_reg(rm, pass * 2);
7152 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7153 switch (size) {
7154 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7155 case 1: gen_swap_half(tmp); break;
7156 case 2: /* no-op */ break;
7157 default: abort();
7159 neon_store_reg(rd, pass * 2 + 1, tmp);
7160 if (size == 2) {
7161 neon_store_reg(rd, pass * 2, tmp2);
7162 } else {
7163 switch (size) {
7164 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7165 case 1: gen_swap_half(tmp2); break;
7166 default: abort();
7168 neon_store_reg(rd, pass * 2, tmp2);
7171 break;
7172 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7173 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7174 for (pass = 0; pass < q + 1; pass++) {
7175 tmp = neon_load_reg(rm, pass * 2);
7176 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7177 tmp = neon_load_reg(rm, pass * 2 + 1);
7178 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7179 switch (size) {
7180 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7181 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7182 case 2: tcg_gen_add_i64(CPU_V001); break;
7183 default: abort();
7185 if (op >= NEON_2RM_VPADAL) {
7186 /* Accumulate. */
7187 neon_load_reg64(cpu_V1, rd + pass);
7188 gen_neon_addl(size);
7190 neon_store_reg64(cpu_V0, rd + pass);
7192 break;
7193 case NEON_2RM_VTRN:
7194 if (size == 2) {
7195 int n;
7196 for (n = 0; n < (q ? 4 : 2); n += 2) {
7197 tmp = neon_load_reg(rm, n);
7198 tmp2 = neon_load_reg(rd, n + 1);
7199 neon_store_reg(rm, n, tmp2);
7200 neon_store_reg(rd, n + 1, tmp);
7202 } else {
7203 goto elementwise;
7205 break;
7206 case NEON_2RM_VUZP:
7207 if (gen_neon_unzip(rd, rm, size, q)) {
7208 return 1;
7210 break;
7211 case NEON_2RM_VZIP:
7212 if (gen_neon_zip(rd, rm, size, q)) {
7213 return 1;
7215 break;
7216 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7217 /* also VQMOVUN; op field and mnemonics don't line up */
7218 if (rm & 1) {
7219 return 1;
7221 tmp2 = NULL;
7222 for (pass = 0; pass < 2; pass++) {
7223 neon_load_reg64(cpu_V0, rm + pass);
7224 tmp = tcg_temp_new_i32();
7225 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7226 tmp, cpu_V0);
7227 if (pass == 0) {
7228 tmp2 = tmp;
7229 } else {
7230 neon_store_reg(rd, 0, tmp2);
7231 neon_store_reg(rd, 1, tmp);
7234 break;
7235 case NEON_2RM_VSHLL:
7236 if (q || (rd & 1)) {
7237 return 1;
7239 tmp = neon_load_reg(rm, 0);
7240 tmp2 = neon_load_reg(rm, 1);
7241 for (pass = 0; pass < 2; pass++) {
7242 if (pass == 1)
7243 tmp = tmp2;
7244 gen_neon_widen(cpu_V0, tmp, size, 1);
7245 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7246 neon_store_reg64(cpu_V0, rd + pass);
7248 break;
7249 case NEON_2RM_VCVT_F16_F32:
7251 TCGv_ptr fpst;
7252 TCGv_i32 ahp;
7254 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7255 q || (rm & 1)) {
7256 return 1;
7258 tmp = tcg_temp_new_i32();
7259 tmp2 = tcg_temp_new_i32();
7260 fpst = get_fpstatus_ptr(true);
7261 ahp = get_ahp_flag();
7262 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7263 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7264 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7265 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7266 tcg_gen_shli_i32(tmp2, tmp2, 16);
7267 tcg_gen_or_i32(tmp2, tmp2, tmp);
7268 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7269 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7270 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7271 neon_store_reg(rd, 0, tmp2);
7272 tmp2 = tcg_temp_new_i32();
7273 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7274 tcg_gen_shli_i32(tmp2, tmp2, 16);
7275 tcg_gen_or_i32(tmp2, tmp2, tmp);
7276 neon_store_reg(rd, 1, tmp2);
7277 tcg_temp_free_i32(tmp);
7278 tcg_temp_free_i32(ahp);
7279 tcg_temp_free_ptr(fpst);
7280 break;
7282 case NEON_2RM_VCVT_F32_F16:
7284 TCGv_ptr fpst;
7285 TCGv_i32 ahp;
7286 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7287 q || (rd & 1)) {
7288 return 1;
7290 fpst = get_fpstatus_ptr(true);
7291 ahp = get_ahp_flag();
7292 tmp3 = tcg_temp_new_i32();
7293 tmp = neon_load_reg(rm, 0);
7294 tmp2 = neon_load_reg(rm, 1);
7295 tcg_gen_ext16u_i32(tmp3, tmp);
7296 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7297 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7298 tcg_gen_shri_i32(tmp3, tmp, 16);
7299 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7300 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7301 tcg_temp_free_i32(tmp);
7302 tcg_gen_ext16u_i32(tmp3, tmp2);
7303 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7304 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7305 tcg_gen_shri_i32(tmp3, tmp2, 16);
7306 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7307 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7308 tcg_temp_free_i32(tmp2);
7309 tcg_temp_free_i32(tmp3);
7310 tcg_temp_free_i32(ahp);
7311 tcg_temp_free_ptr(fpst);
7312 break;
7314 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7315 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7316 || ((rm | rd) & 1)) {
7317 return 1;
7319 ptr1 = vfp_reg_ptr(true, rd);
7320 ptr2 = vfp_reg_ptr(true, rm);
7322 /* Bit 6 is the lowest opcode bit; it distinguishes between
7323 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7325 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7327 if (op == NEON_2RM_AESE) {
7328 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7329 } else {
7330 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7332 tcg_temp_free_ptr(ptr1);
7333 tcg_temp_free_ptr(ptr2);
7334 tcg_temp_free_i32(tmp3);
7335 break;
7336 case NEON_2RM_SHA1H:
7337 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7338 || ((rm | rd) & 1)) {
7339 return 1;
7341 ptr1 = vfp_reg_ptr(true, rd);
7342 ptr2 = vfp_reg_ptr(true, rm);
7344 gen_helper_crypto_sha1h(ptr1, ptr2);
7346 tcg_temp_free_ptr(ptr1);
7347 tcg_temp_free_ptr(ptr2);
7348 break;
7349 case NEON_2RM_SHA1SU1:
7350 if ((rm | rd) & 1) {
7351 return 1;
7353 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7354 if (q) {
7355 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7356 return 1;
7358 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7359 return 1;
7361 ptr1 = vfp_reg_ptr(true, rd);
7362 ptr2 = vfp_reg_ptr(true, rm);
7363 if (q) {
7364 gen_helper_crypto_sha256su0(ptr1, ptr2);
7365 } else {
7366 gen_helper_crypto_sha1su1(ptr1, ptr2);
7368 tcg_temp_free_ptr(ptr1);
7369 tcg_temp_free_ptr(ptr2);
7370 break;
7371 default:
7372 elementwise:
7373 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7374 if (neon_2rm_is_float_op(op)) {
7375 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7376 neon_reg_offset(rm, pass));
7377 tmp = NULL;
7378 } else {
7379 tmp = neon_load_reg(rm, pass);
7381 switch (op) {
7382 case NEON_2RM_VREV32:
7383 switch (size) {
7384 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7385 case 1: gen_swap_half(tmp); break;
7386 default: abort();
7388 break;
7389 case NEON_2RM_VREV16:
7390 gen_rev16(tmp);
7391 break;
7392 case NEON_2RM_VCLS:
7393 switch (size) {
7394 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7395 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7396 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7397 default: abort();
7399 break;
7400 case NEON_2RM_VCLZ:
7401 switch (size) {
7402 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7403 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7404 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7405 default: abort();
7407 break;
7408 case NEON_2RM_VCNT:
7409 gen_helper_neon_cnt_u8(tmp, tmp);
7410 break;
7411 case NEON_2RM_VMVN:
7412 tcg_gen_not_i32(tmp, tmp);
7413 break;
7414 case NEON_2RM_VQABS:
7415 switch (size) {
7416 case 0:
7417 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7418 break;
7419 case 1:
7420 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7421 break;
7422 case 2:
7423 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7424 break;
7425 default: abort();
7427 break;
7428 case NEON_2RM_VQNEG:
7429 switch (size) {
7430 case 0:
7431 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7432 break;
7433 case 1:
7434 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7435 break;
7436 case 2:
7437 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7438 break;
7439 default: abort();
7441 break;
7442 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7443 tmp2 = tcg_const_i32(0);
7444 switch(size) {
7445 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7446 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7447 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7448 default: abort();
7450 tcg_temp_free_i32(tmp2);
7451 if (op == NEON_2RM_VCLE0) {
7452 tcg_gen_not_i32(tmp, tmp);
7454 break;
7455 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7456 tmp2 = tcg_const_i32(0);
7457 switch(size) {
7458 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7459 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7460 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7461 default: abort();
7463 tcg_temp_free_i32(tmp2);
7464 if (op == NEON_2RM_VCLT0) {
7465 tcg_gen_not_i32(tmp, tmp);
7467 break;
7468 case NEON_2RM_VCEQ0:
7469 tmp2 = tcg_const_i32(0);
7470 switch(size) {
7471 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7472 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7473 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7474 default: abort();
7476 tcg_temp_free_i32(tmp2);
7477 break;
7478 case NEON_2RM_VABS:
7479 switch(size) {
7480 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7481 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7482 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7483 default: abort();
7485 break;
7486 case NEON_2RM_VNEG:
7487 tmp2 = tcg_const_i32(0);
7488 gen_neon_rsb(size, tmp, tmp2);
7489 tcg_temp_free_i32(tmp2);
7490 break;
7491 case NEON_2RM_VCGT0_F:
7493 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7494 tmp2 = tcg_const_i32(0);
7495 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7496 tcg_temp_free_i32(tmp2);
7497 tcg_temp_free_ptr(fpstatus);
7498 break;
7500 case NEON_2RM_VCGE0_F:
7502 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7503 tmp2 = tcg_const_i32(0);
7504 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7505 tcg_temp_free_i32(tmp2);
7506 tcg_temp_free_ptr(fpstatus);
7507 break;
7509 case NEON_2RM_VCEQ0_F:
7511 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7512 tmp2 = tcg_const_i32(0);
7513 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7514 tcg_temp_free_i32(tmp2);
7515 tcg_temp_free_ptr(fpstatus);
7516 break;
7518 case NEON_2RM_VCLE0_F:
7520 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7521 tmp2 = tcg_const_i32(0);
7522 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7523 tcg_temp_free_i32(tmp2);
7524 tcg_temp_free_ptr(fpstatus);
7525 break;
7527 case NEON_2RM_VCLT0_F:
7529 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7530 tmp2 = tcg_const_i32(0);
7531 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7532 tcg_temp_free_i32(tmp2);
7533 tcg_temp_free_ptr(fpstatus);
7534 break;
7536 case NEON_2RM_VABS_F:
7537 gen_vfp_abs(0);
7538 break;
7539 case NEON_2RM_VNEG_F:
7540 gen_vfp_neg(0);
7541 break;
7542 case NEON_2RM_VSWP:
7543 tmp2 = neon_load_reg(rd, pass);
7544 neon_store_reg(rm, pass, tmp2);
7545 break;
7546 case NEON_2RM_VTRN:
7547 tmp2 = neon_load_reg(rd, pass);
7548 switch (size) {
7549 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7550 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7551 default: abort();
7553 neon_store_reg(rm, pass, tmp2);
7554 break;
7555 case NEON_2RM_VRINTN:
7556 case NEON_2RM_VRINTA:
7557 case NEON_2RM_VRINTM:
7558 case NEON_2RM_VRINTP:
7559 case NEON_2RM_VRINTZ:
7561 TCGv_i32 tcg_rmode;
7562 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7563 int rmode;
7565 if (op == NEON_2RM_VRINTZ) {
7566 rmode = FPROUNDING_ZERO;
7567 } else {
7568 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7571 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7572 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7573 cpu_env);
7574 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7575 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7576 cpu_env);
7577 tcg_temp_free_ptr(fpstatus);
7578 tcg_temp_free_i32(tcg_rmode);
7579 break;
7581 case NEON_2RM_VRINTX:
7583 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7584 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7585 tcg_temp_free_ptr(fpstatus);
7586 break;
7588 case NEON_2RM_VCVTAU:
7589 case NEON_2RM_VCVTAS:
7590 case NEON_2RM_VCVTNU:
7591 case NEON_2RM_VCVTNS:
7592 case NEON_2RM_VCVTPU:
7593 case NEON_2RM_VCVTPS:
7594 case NEON_2RM_VCVTMU:
7595 case NEON_2RM_VCVTMS:
7597 bool is_signed = !extract32(insn, 7, 1);
7598 TCGv_ptr fpst = get_fpstatus_ptr(1);
7599 TCGv_i32 tcg_rmode, tcg_shift;
7600 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7602 tcg_shift = tcg_const_i32(0);
7603 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7604 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7605 cpu_env);
7607 if (is_signed) {
7608 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7609 tcg_shift, fpst);
7610 } else {
7611 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7612 tcg_shift, fpst);
7615 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7616 cpu_env);
7617 tcg_temp_free_i32(tcg_rmode);
7618 tcg_temp_free_i32(tcg_shift);
7619 tcg_temp_free_ptr(fpst);
7620 break;
7622 case NEON_2RM_VRECPE:
7624 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7625 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7626 tcg_temp_free_ptr(fpstatus);
7627 break;
7629 case NEON_2RM_VRSQRTE:
7631 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7632 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7633 tcg_temp_free_ptr(fpstatus);
7634 break;
7636 case NEON_2RM_VRECPE_F:
7638 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7639 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7640 tcg_temp_free_ptr(fpstatus);
7641 break;
7643 case NEON_2RM_VRSQRTE_F:
7645 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7646 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7647 tcg_temp_free_ptr(fpstatus);
7648 break;
7650 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7651 gen_vfp_sito(0, 1);
7652 break;
7653 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7654 gen_vfp_uito(0, 1);
7655 break;
7656 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7657 gen_vfp_tosiz(0, 1);
7658 break;
7659 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7660 gen_vfp_touiz(0, 1);
7661 break;
7662 default:
7663 /* Reserved op values were caught by the
7664 * neon_2rm_sizes[] check earlier.
7666 abort();
7668 if (neon_2rm_is_float_op(op)) {
7669 tcg_gen_st_f32(cpu_F0s, cpu_env,
7670 neon_reg_offset(rd, pass));
7671 } else {
7672 neon_store_reg(rd, pass, tmp);
7675 break;
7677 } else if ((insn & (1 << 10)) == 0) {
7678 /* VTBL, VTBX. */
7679 int n = ((insn >> 8) & 3) + 1;
7680 if ((rn + n) > 32) {
7681 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7682 * helper function running off the end of the register file.
7684 return 1;
7686 n <<= 3;
7687 if (insn & (1 << 6)) {
7688 tmp = neon_load_reg(rd, 0);
7689 } else {
7690 tmp = tcg_temp_new_i32();
7691 tcg_gen_movi_i32(tmp, 0);
7693 tmp2 = neon_load_reg(rm, 0);
7694 ptr1 = vfp_reg_ptr(true, rn);
7695 tmp5 = tcg_const_i32(n);
7696 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7697 tcg_temp_free_i32(tmp);
7698 if (insn & (1 << 6)) {
7699 tmp = neon_load_reg(rd, 1);
7700 } else {
7701 tmp = tcg_temp_new_i32();
7702 tcg_gen_movi_i32(tmp, 0);
7704 tmp3 = neon_load_reg(rm, 1);
7705 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7706 tcg_temp_free_i32(tmp5);
7707 tcg_temp_free_ptr(ptr1);
7708 neon_store_reg(rd, 0, tmp2);
7709 neon_store_reg(rd, 1, tmp3);
7710 tcg_temp_free_i32(tmp);
7711 } else if ((insn & 0x380) == 0) {
7712 /* VDUP */
7713 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7714 return 1;
7716 if (insn & (1 << 19)) {
7717 tmp = neon_load_reg(rm, 1);
7718 } else {
7719 tmp = neon_load_reg(rm, 0);
7721 if (insn & (1 << 16)) {
7722 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7723 } else if (insn & (1 << 17)) {
7724 if ((insn >> 18) & 1)
7725 gen_neon_dup_high16(tmp);
7726 else
7727 gen_neon_dup_low16(tmp);
7729 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7730 tmp2 = tcg_temp_new_i32();
7731 tcg_gen_mov_i32(tmp2, tmp);
7732 neon_store_reg(rd, pass, tmp2);
7734 tcg_temp_free_i32(tmp);
7735 } else {
7736 return 1;
7740 return 0;
7743 /* Advanced SIMD three registers of the same length extension.
7744 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7745 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7746 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7747 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7749 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7751 gen_helper_gvec_3_ptr *fn_gvec_ptr;
7752 int rd, rn, rm, rot, size, opr_sz;
7753 TCGv_ptr fpst;
7754 bool q;
7756 q = extract32(insn, 6, 1);
7757 VFP_DREG_D(rd, insn);
7758 VFP_DREG_N(rn, insn);
7759 VFP_DREG_M(rm, insn);
7760 if ((rd | rn | rm) & q) {
7761 return 1;
7764 if ((insn & 0xfe200f10) == 0xfc200800) {
7765 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7766 size = extract32(insn, 20, 1);
7767 rot = extract32(insn, 23, 2);
7768 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7769 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7770 return 1;
7772 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7773 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7774 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7775 size = extract32(insn, 20, 1);
7776 rot = extract32(insn, 24, 1);
7777 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7778 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7779 return 1;
7781 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7782 } else {
7783 return 1;
7786 if (s->fp_excp_el) {
7787 gen_exception_insn(s, 4, EXCP_UDEF,
7788 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7789 return 0;
7791 if (!s->vfp_enabled) {
7792 return 1;
7795 opr_sz = (1 + q) * 8;
7796 fpst = get_fpstatus_ptr(1);
7797 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7798 vfp_reg_offset(1, rn),
7799 vfp_reg_offset(1, rm), fpst,
7800 opr_sz, opr_sz, rot, fn_gvec_ptr);
7801 tcg_temp_free_ptr(fpst);
7802 return 0;
7805 /* Advanced SIMD two registers and a scalar extension.
7806 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7807 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7808 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7809 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7813 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7815 int rd, rn, rm, rot, size, opr_sz;
7816 TCGv_ptr fpst;
7817 bool q;
7819 q = extract32(insn, 6, 1);
7820 VFP_DREG_D(rd, insn);
7821 VFP_DREG_N(rn, insn);
7822 VFP_DREG_M(rm, insn);
7823 if ((rd | rn) & q) {
7824 return 1;
7827 if ((insn & 0xff000f10) == 0xfe000800) {
7828 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7829 rot = extract32(insn, 20, 2);
7830 size = extract32(insn, 23, 1);
7831 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7832 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7833 return 1;
7835 } else {
7836 return 1;
7839 if (s->fp_excp_el) {
7840 gen_exception_insn(s, 4, EXCP_UDEF,
7841 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7842 return 0;
7844 if (!s->vfp_enabled) {
7845 return 1;
7848 opr_sz = (1 + q) * 8;
7849 fpst = get_fpstatus_ptr(1);
7850 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7851 vfp_reg_offset(1, rn),
7852 vfp_reg_offset(1, rm), fpst,
7853 opr_sz, opr_sz, rot,
7854 size ? gen_helper_gvec_fcmlas_idx
7855 : gen_helper_gvec_fcmlah_idx);
7856 tcg_temp_free_ptr(fpst);
7857 return 0;
7860 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7862 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7863 const ARMCPRegInfo *ri;
7865 cpnum = (insn >> 8) & 0xf;
7867 /* First check for coprocessor space used for XScale/iwMMXt insns */
7868 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7869 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7870 return 1;
7872 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7873 return disas_iwmmxt_insn(s, insn);
7874 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7875 return disas_dsp_insn(s, insn);
7877 return 1;
7880 /* Otherwise treat as a generic register access */
7881 is64 = (insn & (1 << 25)) == 0;
7882 if (!is64 && ((insn & (1 << 4)) == 0)) {
7883 /* cdp */
7884 return 1;
7887 crm = insn & 0xf;
7888 if (is64) {
7889 crn = 0;
7890 opc1 = (insn >> 4) & 0xf;
7891 opc2 = 0;
7892 rt2 = (insn >> 16) & 0xf;
7893 } else {
7894 crn = (insn >> 16) & 0xf;
7895 opc1 = (insn >> 21) & 7;
7896 opc2 = (insn >> 5) & 7;
7897 rt2 = 0;
7899 isread = (insn >> 20) & 1;
7900 rt = (insn >> 12) & 0xf;
7902 ri = get_arm_cp_reginfo(s->cp_regs,
7903 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7904 if (ri) {
7905 /* Check access permissions */
7906 if (!cp_access_ok(s->current_el, ri, isread)) {
7907 return 1;
7910 if (ri->accessfn ||
7911 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7912 /* Emit code to perform further access permissions checks at
7913 * runtime; this may result in an exception.
7914 * Note that on XScale all cp0..c13 registers do an access check
7915 * call in order to handle c15_cpar.
7917 TCGv_ptr tmpptr;
7918 TCGv_i32 tcg_syn, tcg_isread;
7919 uint32_t syndrome;
7921 /* Note that since we are an implementation which takes an
7922 * exception on a trapped conditional instruction only if the
7923 * instruction passes its condition code check, we can take
7924 * advantage of the clause in the ARM ARM that allows us to set
7925 * the COND field in the instruction to 0xE in all cases.
7926 * We could fish the actual condition out of the insn (ARM)
7927 * or the condexec bits (Thumb) but it isn't necessary.
7929 switch (cpnum) {
7930 case 14:
7931 if (is64) {
7932 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7933 isread, false);
7934 } else {
7935 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7936 rt, isread, false);
7938 break;
7939 case 15:
7940 if (is64) {
7941 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7942 isread, false);
7943 } else {
7944 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7945 rt, isread, false);
7947 break;
7948 default:
7949 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7950 * so this can only happen if this is an ARMv7 or earlier CPU,
7951 * in which case the syndrome information won't actually be
7952 * guest visible.
7954 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7955 syndrome = syn_uncategorized();
7956 break;
7959 gen_set_condexec(s);
7960 gen_set_pc_im(s, s->pc - 4);
7961 tmpptr = tcg_const_ptr(ri);
7962 tcg_syn = tcg_const_i32(syndrome);
7963 tcg_isread = tcg_const_i32(isread);
7964 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7965 tcg_isread);
7966 tcg_temp_free_ptr(tmpptr);
7967 tcg_temp_free_i32(tcg_syn);
7968 tcg_temp_free_i32(tcg_isread);
7971 /* Handle special cases first */
7972 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7973 case ARM_CP_NOP:
7974 return 0;
7975 case ARM_CP_WFI:
7976 if (isread) {
7977 return 1;
7979 gen_set_pc_im(s, s->pc);
7980 s->base.is_jmp = DISAS_WFI;
7981 return 0;
7982 default:
7983 break;
7986 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7987 gen_io_start();
7990 if (isread) {
7991 /* Read */
7992 if (is64) {
7993 TCGv_i64 tmp64;
7994 TCGv_i32 tmp;
7995 if (ri->type & ARM_CP_CONST) {
7996 tmp64 = tcg_const_i64(ri->resetvalue);
7997 } else if (ri->readfn) {
7998 TCGv_ptr tmpptr;
7999 tmp64 = tcg_temp_new_i64();
8000 tmpptr = tcg_const_ptr(ri);
8001 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8002 tcg_temp_free_ptr(tmpptr);
8003 } else {
8004 tmp64 = tcg_temp_new_i64();
8005 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8007 tmp = tcg_temp_new_i32();
8008 tcg_gen_extrl_i64_i32(tmp, tmp64);
8009 store_reg(s, rt, tmp);
8010 tcg_gen_shri_i64(tmp64, tmp64, 32);
8011 tmp = tcg_temp_new_i32();
8012 tcg_gen_extrl_i64_i32(tmp, tmp64);
8013 tcg_temp_free_i64(tmp64);
8014 store_reg(s, rt2, tmp);
8015 } else {
8016 TCGv_i32 tmp;
8017 if (ri->type & ARM_CP_CONST) {
8018 tmp = tcg_const_i32(ri->resetvalue);
8019 } else if (ri->readfn) {
8020 TCGv_ptr tmpptr;
8021 tmp = tcg_temp_new_i32();
8022 tmpptr = tcg_const_ptr(ri);
8023 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8024 tcg_temp_free_ptr(tmpptr);
8025 } else {
8026 tmp = load_cpu_offset(ri->fieldoffset);
8028 if (rt == 15) {
8029 /* Destination register of r15 for 32 bit loads sets
8030 * the condition codes from the high 4 bits of the value
8032 gen_set_nzcv(tmp);
8033 tcg_temp_free_i32(tmp);
8034 } else {
8035 store_reg(s, rt, tmp);
8038 } else {
8039 /* Write */
8040 if (ri->type & ARM_CP_CONST) {
8041 /* If not forbidden by access permissions, treat as WI */
8042 return 0;
8045 if (is64) {
8046 TCGv_i32 tmplo, tmphi;
8047 TCGv_i64 tmp64 = tcg_temp_new_i64();
8048 tmplo = load_reg(s, rt);
8049 tmphi = load_reg(s, rt2);
8050 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8051 tcg_temp_free_i32(tmplo);
8052 tcg_temp_free_i32(tmphi);
8053 if (ri->writefn) {
8054 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8055 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8056 tcg_temp_free_ptr(tmpptr);
8057 } else {
8058 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8060 tcg_temp_free_i64(tmp64);
8061 } else {
8062 if (ri->writefn) {
8063 TCGv_i32 tmp;
8064 TCGv_ptr tmpptr;
8065 tmp = load_reg(s, rt);
8066 tmpptr = tcg_const_ptr(ri);
8067 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8068 tcg_temp_free_ptr(tmpptr);
8069 tcg_temp_free_i32(tmp);
8070 } else {
8071 TCGv_i32 tmp = load_reg(s, rt);
8072 store_cpu_offset(tmp, ri->fieldoffset);
8077 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8078 /* I/O operations must end the TB here (whether read or write) */
8079 gen_io_end();
8080 gen_lookup_tb(s);
8081 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8082 /* We default to ending the TB on a coprocessor register write,
8083 * but allow this to be suppressed by the register definition
8084 * (usually only necessary to work around guest bugs).
8086 gen_lookup_tb(s);
8089 return 0;
8092 /* Unknown register; this might be a guest error or a QEMU
8093 * unimplemented feature.
8095 if (is64) {
8096 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8097 "64 bit system register cp:%d opc1: %d crm:%d "
8098 "(%s)\n",
8099 isread ? "read" : "write", cpnum, opc1, crm,
8100 s->ns ? "non-secure" : "secure");
8101 } else {
8102 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8103 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8104 "(%s)\n",
8105 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8106 s->ns ? "non-secure" : "secure");
8109 return 1;
8113 /* Store a 64-bit value to a register pair. Clobbers val. */
8114 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8116 TCGv_i32 tmp;
8117 tmp = tcg_temp_new_i32();
8118 tcg_gen_extrl_i64_i32(tmp, val);
8119 store_reg(s, rlow, tmp);
8120 tmp = tcg_temp_new_i32();
8121 tcg_gen_shri_i64(val, val, 32);
8122 tcg_gen_extrl_i64_i32(tmp, val);
8123 store_reg(s, rhigh, tmp);
8126 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8127 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8129 TCGv_i64 tmp;
8130 TCGv_i32 tmp2;
8132 /* Load value and extend to 64 bits. */
8133 tmp = tcg_temp_new_i64();
8134 tmp2 = load_reg(s, rlow);
8135 tcg_gen_extu_i32_i64(tmp, tmp2);
8136 tcg_temp_free_i32(tmp2);
8137 tcg_gen_add_i64(val, val, tmp);
8138 tcg_temp_free_i64(tmp);
8141 /* load and add a 64-bit value from a register pair. */
8142 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8144 TCGv_i64 tmp;
8145 TCGv_i32 tmpl;
8146 TCGv_i32 tmph;
8148 /* Load 64-bit value rd:rn. */
8149 tmpl = load_reg(s, rlow);
8150 tmph = load_reg(s, rhigh);
8151 tmp = tcg_temp_new_i64();
8152 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8153 tcg_temp_free_i32(tmpl);
8154 tcg_temp_free_i32(tmph);
8155 tcg_gen_add_i64(val, val, tmp);
8156 tcg_temp_free_i64(tmp);
8159 /* Set N and Z flags from hi|lo. */
8160 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8162 tcg_gen_mov_i32(cpu_NF, hi);
8163 tcg_gen_or_i32(cpu_ZF, lo, hi);
8166 /* Load/Store exclusive instructions are implemented by remembering
8167 the value/address loaded, and seeing if these are the same
8168 when the store is performed. This should be sufficient to implement
8169 the architecturally mandated semantics, and avoids having to monitor
8170 regular stores. The compare vs the remembered value is done during
8171 the cmpxchg operation, but we must compare the addresses manually. */
8172 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8173 TCGv_i32 addr, int size)
8175 TCGv_i32 tmp = tcg_temp_new_i32();
8176 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8178 s->is_ldex = true;
8180 if (size == 3) {
8181 TCGv_i32 tmp2 = tcg_temp_new_i32();
8182 TCGv_i64 t64 = tcg_temp_new_i64();
8184 /* For AArch32, architecturally the 32-bit word at the lowest
8185 * address is always Rt and the one at addr+4 is Rt2, even if
8186 * the CPU is big-endian. That means we don't want to do a
8187 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8188 * for an architecturally 64-bit access, but instead do a
8189 * 64-bit access using MO_BE if appropriate and then split
8190 * the two halves.
8191 * This only makes a difference for BE32 user-mode, where
8192 * frob64() must not flip the two halves of the 64-bit data
8193 * but this code must treat BE32 user-mode like BE32 system.
8195 TCGv taddr = gen_aa32_addr(s, addr, opc);
8197 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8198 tcg_temp_free(taddr);
8199 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8200 if (s->be_data == MO_BE) {
8201 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8202 } else {
8203 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8205 tcg_temp_free_i64(t64);
8207 store_reg(s, rt2, tmp2);
8208 } else {
8209 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8210 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8213 store_reg(s, rt, tmp);
8214 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8217 static void gen_clrex(DisasContext *s)
8219 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8222 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8223 TCGv_i32 addr, int size)
8225 TCGv_i32 t0, t1, t2;
8226 TCGv_i64 extaddr;
8227 TCGv taddr;
8228 TCGLabel *done_label;
8229 TCGLabel *fail_label;
8230 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8232 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8233 [addr] = {Rt};
8234 {Rd} = 0;
8235 } else {
8236 {Rd} = 1;
8237 } */
8238 fail_label = gen_new_label();
8239 done_label = gen_new_label();
8240 extaddr = tcg_temp_new_i64();
8241 tcg_gen_extu_i32_i64(extaddr, addr);
8242 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8243 tcg_temp_free_i64(extaddr);
8245 taddr = gen_aa32_addr(s, addr, opc);
8246 t0 = tcg_temp_new_i32();
8247 t1 = load_reg(s, rt);
8248 if (size == 3) {
8249 TCGv_i64 o64 = tcg_temp_new_i64();
8250 TCGv_i64 n64 = tcg_temp_new_i64();
8252 t2 = load_reg(s, rt2);
8253 /* For AArch32, architecturally the 32-bit word at the lowest
8254 * address is always Rt and the one at addr+4 is Rt2, even if
8255 * the CPU is big-endian. Since we're going to treat this as a
8256 * single 64-bit BE store, we need to put the two halves in the
8257 * opposite order for BE to LE, so that they end up in the right
8258 * places.
8259 * We don't want gen_aa32_frob64() because that does the wrong
8260 * thing for BE32 usermode.
8262 if (s->be_data == MO_BE) {
8263 tcg_gen_concat_i32_i64(n64, t2, t1);
8264 } else {
8265 tcg_gen_concat_i32_i64(n64, t1, t2);
8267 tcg_temp_free_i32(t2);
8269 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8270 get_mem_index(s), opc);
8271 tcg_temp_free_i64(n64);
8273 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8274 tcg_gen_extrl_i64_i32(t0, o64);
8276 tcg_temp_free_i64(o64);
8277 } else {
8278 t2 = tcg_temp_new_i32();
8279 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8280 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8281 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8282 tcg_temp_free_i32(t2);
8284 tcg_temp_free_i32(t1);
8285 tcg_temp_free(taddr);
8286 tcg_gen_mov_i32(cpu_R[rd], t0);
8287 tcg_temp_free_i32(t0);
8288 tcg_gen_br(done_label);
8290 gen_set_label(fail_label);
8291 tcg_gen_movi_i32(cpu_R[rd], 1);
8292 gen_set_label(done_label);
8293 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8296 /* gen_srs:
8297 * @env: CPUARMState
8298 * @s: DisasContext
8299 * @mode: mode field from insn (which stack to store to)
8300 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8301 * @writeback: true if writeback bit set
8303 * Generate code for the SRS (Store Return State) insn.
8305 static void gen_srs(DisasContext *s,
8306 uint32_t mode, uint32_t amode, bool writeback)
8308 int32_t offset;
8309 TCGv_i32 addr, tmp;
8310 bool undef = false;
8312 /* SRS is:
8313 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8314 * and specified mode is monitor mode
8315 * - UNDEFINED in Hyp mode
8316 * - UNPREDICTABLE in User or System mode
8317 * - UNPREDICTABLE if the specified mode is:
8318 * -- not implemented
8319 * -- not a valid mode number
8320 * -- a mode that's at a higher exception level
8321 * -- Monitor, if we are Non-secure
8322 * For the UNPREDICTABLE cases we choose to UNDEF.
8324 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8325 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8326 return;
8329 if (s->current_el == 0 || s->current_el == 2) {
8330 undef = true;
8333 switch (mode) {
8334 case ARM_CPU_MODE_USR:
8335 case ARM_CPU_MODE_FIQ:
8336 case ARM_CPU_MODE_IRQ:
8337 case ARM_CPU_MODE_SVC:
8338 case ARM_CPU_MODE_ABT:
8339 case ARM_CPU_MODE_UND:
8340 case ARM_CPU_MODE_SYS:
8341 break;
8342 case ARM_CPU_MODE_HYP:
8343 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8344 undef = true;
8346 break;
8347 case ARM_CPU_MODE_MON:
8348 /* No need to check specifically for "are we non-secure" because
8349 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8350 * so if this isn't EL3 then we must be non-secure.
8352 if (s->current_el != 3) {
8353 undef = true;
8355 break;
8356 default:
8357 undef = true;
8360 if (undef) {
8361 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8362 default_exception_el(s));
8363 return;
8366 addr = tcg_temp_new_i32();
8367 tmp = tcg_const_i32(mode);
8368 /* get_r13_banked() will raise an exception if called from System mode */
8369 gen_set_condexec(s);
8370 gen_set_pc_im(s, s->pc - 4);
8371 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8372 tcg_temp_free_i32(tmp);
8373 switch (amode) {
8374 case 0: /* DA */
8375 offset = -4;
8376 break;
8377 case 1: /* IA */
8378 offset = 0;
8379 break;
8380 case 2: /* DB */
8381 offset = -8;
8382 break;
8383 case 3: /* IB */
8384 offset = 4;
8385 break;
8386 default:
8387 abort();
8389 tcg_gen_addi_i32(addr, addr, offset);
8390 tmp = load_reg(s, 14);
8391 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8392 tcg_temp_free_i32(tmp);
8393 tmp = load_cpu_field(spsr);
8394 tcg_gen_addi_i32(addr, addr, 4);
8395 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8396 tcg_temp_free_i32(tmp);
8397 if (writeback) {
8398 switch (amode) {
8399 case 0:
8400 offset = -8;
8401 break;
8402 case 1:
8403 offset = 4;
8404 break;
8405 case 2:
8406 offset = -4;
8407 break;
8408 case 3:
8409 offset = 0;
8410 break;
8411 default:
8412 abort();
8414 tcg_gen_addi_i32(addr, addr, offset);
8415 tmp = tcg_const_i32(mode);
8416 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8417 tcg_temp_free_i32(tmp);
8419 tcg_temp_free_i32(addr);
8420 s->base.is_jmp = DISAS_UPDATE;
8423 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8425 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8426 TCGv_i32 tmp;
8427 TCGv_i32 tmp2;
8428 TCGv_i32 tmp3;
8429 TCGv_i32 addr;
8430 TCGv_i64 tmp64;
8432 /* M variants do not implement ARM mode; this must raise the INVSTATE
8433 * UsageFault exception.
8435 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8436 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8437 default_exception_el(s));
8438 return;
8440 cond = insn >> 28;
8441 if (cond == 0xf){
8442 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8443 * choose to UNDEF. In ARMv5 and above the space is used
8444 * for miscellaneous unconditional instructions.
8446 ARCH(5);
8448 /* Unconditional instructions. */
8449 if (((insn >> 25) & 7) == 1) {
8450 /* NEON Data processing. */
8451 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8452 goto illegal_op;
8455 if (disas_neon_data_insn(s, insn)) {
8456 goto illegal_op;
8458 return;
8460 if ((insn & 0x0f100000) == 0x04000000) {
8461 /* NEON load/store. */
8462 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8463 goto illegal_op;
8466 if (disas_neon_ls_insn(s, insn)) {
8467 goto illegal_op;
8469 return;
8471 if ((insn & 0x0f000e10) == 0x0e000a00) {
8472 /* VFP. */
8473 if (disas_vfp_insn(s, insn)) {
8474 goto illegal_op;
8476 return;
8478 if (((insn & 0x0f30f000) == 0x0510f000) ||
8479 ((insn & 0x0f30f010) == 0x0710f000)) {
8480 if ((insn & (1 << 22)) == 0) {
8481 /* PLDW; v7MP */
8482 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8483 goto illegal_op;
8486 /* Otherwise PLD; v5TE+ */
8487 ARCH(5TE);
8488 return;
8490 if (((insn & 0x0f70f000) == 0x0450f000) ||
8491 ((insn & 0x0f70f010) == 0x0650f000)) {
8492 ARCH(7);
8493 return; /* PLI; V7 */
8495 if (((insn & 0x0f700000) == 0x04100000) ||
8496 ((insn & 0x0f700010) == 0x06100000)) {
8497 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8498 goto illegal_op;
8500 return; /* v7MP: Unallocated memory hint: must NOP */
8503 if ((insn & 0x0ffffdff) == 0x01010000) {
8504 ARCH(6);
8505 /* setend */
8506 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8507 gen_helper_setend(cpu_env);
8508 s->base.is_jmp = DISAS_UPDATE;
8510 return;
8511 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8512 switch ((insn >> 4) & 0xf) {
8513 case 1: /* clrex */
8514 ARCH(6K);
8515 gen_clrex(s);
8516 return;
8517 case 4: /* dsb */
8518 case 5: /* dmb */
8519 ARCH(7);
8520 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8521 return;
8522 case 6: /* isb */
8523 /* We need to break the TB after this insn to execute
8524 * self-modifying code correctly and also to take
8525 * any pending interrupts immediately.
8527 gen_goto_tb(s, 0, s->pc & ~1);
8528 return;
8529 default:
8530 goto illegal_op;
8532 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8533 /* srs */
8534 ARCH(6);
8535 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8536 return;
8537 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8538 /* rfe */
8539 int32_t offset;
8540 if (IS_USER(s))
8541 goto illegal_op;
8542 ARCH(6);
8543 rn = (insn >> 16) & 0xf;
8544 addr = load_reg(s, rn);
8545 i = (insn >> 23) & 3;
8546 switch (i) {
8547 case 0: offset = -4; break; /* DA */
8548 case 1: offset = 0; break; /* IA */
8549 case 2: offset = -8; break; /* DB */
8550 case 3: offset = 4; break; /* IB */
8551 default: abort();
8553 if (offset)
8554 tcg_gen_addi_i32(addr, addr, offset);
8555 /* Load PC into tmp and CPSR into tmp2. */
8556 tmp = tcg_temp_new_i32();
8557 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8558 tcg_gen_addi_i32(addr, addr, 4);
8559 tmp2 = tcg_temp_new_i32();
8560 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8561 if (insn & (1 << 21)) {
8562 /* Base writeback. */
8563 switch (i) {
8564 case 0: offset = -8; break;
8565 case 1: offset = 4; break;
8566 case 2: offset = -4; break;
8567 case 3: offset = 0; break;
8568 default: abort();
8570 if (offset)
8571 tcg_gen_addi_i32(addr, addr, offset);
8572 store_reg(s, rn, addr);
8573 } else {
8574 tcg_temp_free_i32(addr);
8576 gen_rfe(s, tmp, tmp2);
8577 return;
8578 } else if ((insn & 0x0e000000) == 0x0a000000) {
8579 /* branch link and change to thumb (blx <offset>) */
8580 int32_t offset;
8582 val = (uint32_t)s->pc;
8583 tmp = tcg_temp_new_i32();
8584 tcg_gen_movi_i32(tmp, val);
8585 store_reg(s, 14, tmp);
8586 /* Sign-extend the 24-bit offset */
8587 offset = (((int32_t)insn) << 8) >> 8;
8588 /* offset * 4 + bit24 * 2 + (thumb bit) */
8589 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8590 /* pipeline offset */
8591 val += 4;
8592 /* protected by ARCH(5); above, near the start of uncond block */
8593 gen_bx_im(s, val);
8594 return;
8595 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8596 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8597 /* iWMMXt register transfer. */
8598 if (extract32(s->c15_cpar, 1, 1)) {
8599 if (!disas_iwmmxt_insn(s, insn)) {
8600 return;
8604 } else if ((insn & 0x0e000a00) == 0x0c000800
8605 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8606 if (disas_neon_insn_3same_ext(s, insn)) {
8607 goto illegal_op;
8609 return;
8610 } else if ((insn & 0x0f000a00) == 0x0e000800
8611 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8612 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8613 goto illegal_op;
8615 return;
8616 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8617 /* Coprocessor double register transfer. */
8618 ARCH(5TE);
8619 } else if ((insn & 0x0f000010) == 0x0e000010) {
8620 /* Additional coprocessor register transfer. */
8621 } else if ((insn & 0x0ff10020) == 0x01000000) {
8622 uint32_t mask;
8623 uint32_t val;
8624 /* cps (privileged) */
8625 if (IS_USER(s))
8626 return;
8627 mask = val = 0;
8628 if (insn & (1 << 19)) {
8629 if (insn & (1 << 8))
8630 mask |= CPSR_A;
8631 if (insn & (1 << 7))
8632 mask |= CPSR_I;
8633 if (insn & (1 << 6))
8634 mask |= CPSR_F;
8635 if (insn & (1 << 18))
8636 val |= mask;
8638 if (insn & (1 << 17)) {
8639 mask |= CPSR_M;
8640 val |= (insn & 0x1f);
8642 if (mask) {
8643 gen_set_psr_im(s, mask, 0, val);
8645 return;
8647 goto illegal_op;
8649 if (cond != 0xe) {
8650 /* if not always execute, we generate a conditional jump to
8651 next instruction */
8652 s->condlabel = gen_new_label();
8653 arm_gen_test_cc(cond ^ 1, s->condlabel);
8654 s->condjmp = 1;
8656 if ((insn & 0x0f900000) == 0x03000000) {
8657 if ((insn & (1 << 21)) == 0) {
8658 ARCH(6T2);
8659 rd = (insn >> 12) & 0xf;
8660 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8661 if ((insn & (1 << 22)) == 0) {
8662 /* MOVW */
8663 tmp = tcg_temp_new_i32();
8664 tcg_gen_movi_i32(tmp, val);
8665 } else {
8666 /* MOVT */
8667 tmp = load_reg(s, rd);
8668 tcg_gen_ext16u_i32(tmp, tmp);
8669 tcg_gen_ori_i32(tmp, tmp, val << 16);
8671 store_reg(s, rd, tmp);
8672 } else {
8673 if (((insn >> 12) & 0xf) != 0xf)
8674 goto illegal_op;
8675 if (((insn >> 16) & 0xf) == 0) {
8676 gen_nop_hint(s, insn & 0xff);
8677 } else {
8678 /* CPSR = immediate */
8679 val = insn & 0xff;
8680 shift = ((insn >> 8) & 0xf) * 2;
8681 if (shift)
8682 val = (val >> shift) | (val << (32 - shift));
8683 i = ((insn & (1 << 22)) != 0);
8684 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8685 i, val)) {
8686 goto illegal_op;
8690 } else if ((insn & 0x0f900000) == 0x01000000
8691 && (insn & 0x00000090) != 0x00000090) {
8692 /* miscellaneous instructions */
8693 op1 = (insn >> 21) & 3;
8694 sh = (insn >> 4) & 0xf;
8695 rm = insn & 0xf;
8696 switch (sh) {
8697 case 0x0: /* MSR, MRS */
8698 if (insn & (1 << 9)) {
8699 /* MSR (banked) and MRS (banked) */
8700 int sysm = extract32(insn, 16, 4) |
8701 (extract32(insn, 8, 1) << 4);
8702 int r = extract32(insn, 22, 1);
8704 if (op1 & 1) {
8705 /* MSR (banked) */
8706 gen_msr_banked(s, r, sysm, rm);
8707 } else {
8708 /* MRS (banked) */
8709 int rd = extract32(insn, 12, 4);
8711 gen_mrs_banked(s, r, sysm, rd);
8713 break;
8716 /* MSR, MRS (for PSRs) */
8717 if (op1 & 1) {
8718 /* PSR = reg */
8719 tmp = load_reg(s, rm);
8720 i = ((op1 & 2) != 0);
8721 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8722 goto illegal_op;
8723 } else {
8724 /* reg = PSR */
8725 rd = (insn >> 12) & 0xf;
8726 if (op1 & 2) {
8727 if (IS_USER(s))
8728 goto illegal_op;
8729 tmp = load_cpu_field(spsr);
8730 } else {
8731 tmp = tcg_temp_new_i32();
8732 gen_helper_cpsr_read(tmp, cpu_env);
8734 store_reg(s, rd, tmp);
8736 break;
8737 case 0x1:
8738 if (op1 == 1) {
8739 /* branch/exchange thumb (bx). */
8740 ARCH(4T);
8741 tmp = load_reg(s, rm);
8742 gen_bx(s, tmp);
8743 } else if (op1 == 3) {
8744 /* clz */
8745 ARCH(5);
8746 rd = (insn >> 12) & 0xf;
8747 tmp = load_reg(s, rm);
8748 tcg_gen_clzi_i32(tmp, tmp, 32);
8749 store_reg(s, rd, tmp);
8750 } else {
8751 goto illegal_op;
8753 break;
8754 case 0x2:
8755 if (op1 == 1) {
8756 ARCH(5J); /* bxj */
8757 /* Trivial implementation equivalent to bx. */
8758 tmp = load_reg(s, rm);
8759 gen_bx(s, tmp);
8760 } else {
8761 goto illegal_op;
8763 break;
8764 case 0x3:
8765 if (op1 != 1)
8766 goto illegal_op;
8768 ARCH(5);
8769 /* branch link/exchange thumb (blx) */
8770 tmp = load_reg(s, rm);
8771 tmp2 = tcg_temp_new_i32();
8772 tcg_gen_movi_i32(tmp2, s->pc);
8773 store_reg(s, 14, tmp2);
8774 gen_bx(s, tmp);
8775 break;
8776 case 0x4:
8778 /* crc32/crc32c */
8779 uint32_t c = extract32(insn, 8, 4);
8781 /* Check this CPU supports ARMv8 CRC instructions.
8782 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8783 * Bits 8, 10 and 11 should be zero.
8785 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8786 (c & 0xd) != 0) {
8787 goto illegal_op;
8790 rn = extract32(insn, 16, 4);
8791 rd = extract32(insn, 12, 4);
8793 tmp = load_reg(s, rn);
8794 tmp2 = load_reg(s, rm);
8795 if (op1 == 0) {
8796 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8797 } else if (op1 == 1) {
8798 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8800 tmp3 = tcg_const_i32(1 << op1);
8801 if (c & 0x2) {
8802 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8803 } else {
8804 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8806 tcg_temp_free_i32(tmp2);
8807 tcg_temp_free_i32(tmp3);
8808 store_reg(s, rd, tmp);
8809 break;
8811 case 0x5: /* saturating add/subtract */
8812 ARCH(5TE);
8813 rd = (insn >> 12) & 0xf;
8814 rn = (insn >> 16) & 0xf;
8815 tmp = load_reg(s, rm);
8816 tmp2 = load_reg(s, rn);
8817 if (op1 & 2)
8818 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8819 if (op1 & 1)
8820 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8821 else
8822 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8823 tcg_temp_free_i32(tmp2);
8824 store_reg(s, rd, tmp);
8825 break;
8826 case 7:
8828 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8829 switch (op1) {
8830 case 0:
8831 /* HLT */
8832 gen_hlt(s, imm16);
8833 break;
8834 case 1:
8835 /* bkpt */
8836 ARCH(5);
8837 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8838 break;
8839 case 2:
8840 /* Hypervisor call (v7) */
8841 ARCH(7);
8842 if (IS_USER(s)) {
8843 goto illegal_op;
8845 gen_hvc(s, imm16);
8846 break;
8847 case 3:
8848 /* Secure monitor call (v6+) */
8849 ARCH(6K);
8850 if (IS_USER(s)) {
8851 goto illegal_op;
8853 gen_smc(s);
8854 break;
8855 default:
8856 g_assert_not_reached();
8858 break;
8860 case 0x8: /* signed multiply */
8861 case 0xa:
8862 case 0xc:
8863 case 0xe:
8864 ARCH(5TE);
8865 rs = (insn >> 8) & 0xf;
8866 rn = (insn >> 12) & 0xf;
8867 rd = (insn >> 16) & 0xf;
8868 if (op1 == 1) {
8869 /* (32 * 16) >> 16 */
8870 tmp = load_reg(s, rm);
8871 tmp2 = load_reg(s, rs);
8872 if (sh & 4)
8873 tcg_gen_sari_i32(tmp2, tmp2, 16);
8874 else
8875 gen_sxth(tmp2);
8876 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8877 tcg_gen_shri_i64(tmp64, tmp64, 16);
8878 tmp = tcg_temp_new_i32();
8879 tcg_gen_extrl_i64_i32(tmp, tmp64);
8880 tcg_temp_free_i64(tmp64);
8881 if ((sh & 2) == 0) {
8882 tmp2 = load_reg(s, rn);
8883 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8884 tcg_temp_free_i32(tmp2);
8886 store_reg(s, rd, tmp);
8887 } else {
8888 /* 16 * 16 */
8889 tmp = load_reg(s, rm);
8890 tmp2 = load_reg(s, rs);
8891 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8892 tcg_temp_free_i32(tmp2);
8893 if (op1 == 2) {
8894 tmp64 = tcg_temp_new_i64();
8895 tcg_gen_ext_i32_i64(tmp64, tmp);
8896 tcg_temp_free_i32(tmp);
8897 gen_addq(s, tmp64, rn, rd);
8898 gen_storeq_reg(s, rn, rd, tmp64);
8899 tcg_temp_free_i64(tmp64);
8900 } else {
8901 if (op1 == 0) {
8902 tmp2 = load_reg(s, rn);
8903 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8904 tcg_temp_free_i32(tmp2);
8906 store_reg(s, rd, tmp);
8909 break;
8910 default:
8911 goto illegal_op;
8913 } else if (((insn & 0x0e000000) == 0 &&
8914 (insn & 0x00000090) != 0x90) ||
8915 ((insn & 0x0e000000) == (1 << 25))) {
8916 int set_cc, logic_cc, shiftop;
8918 op1 = (insn >> 21) & 0xf;
8919 set_cc = (insn >> 20) & 1;
8920 logic_cc = table_logic_cc[op1] & set_cc;
8922 /* data processing instruction */
8923 if (insn & (1 << 25)) {
8924 /* immediate operand */
8925 val = insn & 0xff;
8926 shift = ((insn >> 8) & 0xf) * 2;
8927 if (shift) {
8928 val = (val >> shift) | (val << (32 - shift));
8930 tmp2 = tcg_temp_new_i32();
8931 tcg_gen_movi_i32(tmp2, val);
8932 if (logic_cc && shift) {
8933 gen_set_CF_bit31(tmp2);
8935 } else {
8936 /* register */
8937 rm = (insn) & 0xf;
8938 tmp2 = load_reg(s, rm);
8939 shiftop = (insn >> 5) & 3;
8940 if (!(insn & (1 << 4))) {
8941 shift = (insn >> 7) & 0x1f;
8942 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8943 } else {
8944 rs = (insn >> 8) & 0xf;
8945 tmp = load_reg(s, rs);
8946 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8949 if (op1 != 0x0f && op1 != 0x0d) {
8950 rn = (insn >> 16) & 0xf;
8951 tmp = load_reg(s, rn);
8952 } else {
8953 tmp = NULL;
8955 rd = (insn >> 12) & 0xf;
8956 switch(op1) {
8957 case 0x00:
8958 tcg_gen_and_i32(tmp, tmp, tmp2);
8959 if (logic_cc) {
8960 gen_logic_CC(tmp);
8962 store_reg_bx(s, rd, tmp);
8963 break;
8964 case 0x01:
8965 tcg_gen_xor_i32(tmp, tmp, tmp2);
8966 if (logic_cc) {
8967 gen_logic_CC(tmp);
8969 store_reg_bx(s, rd, tmp);
8970 break;
8971 case 0x02:
8972 if (set_cc && rd == 15) {
8973 /* SUBS r15, ... is used for exception return. */
8974 if (IS_USER(s)) {
8975 goto illegal_op;
8977 gen_sub_CC(tmp, tmp, tmp2);
8978 gen_exception_return(s, tmp);
8979 } else {
8980 if (set_cc) {
8981 gen_sub_CC(tmp, tmp, tmp2);
8982 } else {
8983 tcg_gen_sub_i32(tmp, tmp, tmp2);
8985 store_reg_bx(s, rd, tmp);
8987 break;
8988 case 0x03:
8989 if (set_cc) {
8990 gen_sub_CC(tmp, tmp2, tmp);
8991 } else {
8992 tcg_gen_sub_i32(tmp, tmp2, tmp);
8994 store_reg_bx(s, rd, tmp);
8995 break;
8996 case 0x04:
8997 if (set_cc) {
8998 gen_add_CC(tmp, tmp, tmp2);
8999 } else {
9000 tcg_gen_add_i32(tmp, tmp, tmp2);
9002 store_reg_bx(s, rd, tmp);
9003 break;
9004 case 0x05:
9005 if (set_cc) {
9006 gen_adc_CC(tmp, tmp, tmp2);
9007 } else {
9008 gen_add_carry(tmp, tmp, tmp2);
9010 store_reg_bx(s, rd, tmp);
9011 break;
9012 case 0x06:
9013 if (set_cc) {
9014 gen_sbc_CC(tmp, tmp, tmp2);
9015 } else {
9016 gen_sub_carry(tmp, tmp, tmp2);
9018 store_reg_bx(s, rd, tmp);
9019 break;
9020 case 0x07:
9021 if (set_cc) {
9022 gen_sbc_CC(tmp, tmp2, tmp);
9023 } else {
9024 gen_sub_carry(tmp, tmp2, tmp);
9026 store_reg_bx(s, rd, tmp);
9027 break;
9028 case 0x08:
9029 if (set_cc) {
9030 tcg_gen_and_i32(tmp, tmp, tmp2);
9031 gen_logic_CC(tmp);
9033 tcg_temp_free_i32(tmp);
9034 break;
9035 case 0x09:
9036 if (set_cc) {
9037 tcg_gen_xor_i32(tmp, tmp, tmp2);
9038 gen_logic_CC(tmp);
9040 tcg_temp_free_i32(tmp);
9041 break;
9042 case 0x0a:
9043 if (set_cc) {
9044 gen_sub_CC(tmp, tmp, tmp2);
9046 tcg_temp_free_i32(tmp);
9047 break;
9048 case 0x0b:
9049 if (set_cc) {
9050 gen_add_CC(tmp, tmp, tmp2);
9052 tcg_temp_free_i32(tmp);
9053 break;
9054 case 0x0c:
9055 tcg_gen_or_i32(tmp, tmp, tmp2);
9056 if (logic_cc) {
9057 gen_logic_CC(tmp);
9059 store_reg_bx(s, rd, tmp);
9060 break;
9061 case 0x0d:
9062 if (logic_cc && rd == 15) {
9063 /* MOVS r15, ... is used for exception return. */
9064 if (IS_USER(s)) {
9065 goto illegal_op;
9067 gen_exception_return(s, tmp2);
9068 } else {
9069 if (logic_cc) {
9070 gen_logic_CC(tmp2);
9072 store_reg_bx(s, rd, tmp2);
9074 break;
9075 case 0x0e:
9076 tcg_gen_andc_i32(tmp, tmp, tmp2);
9077 if (logic_cc) {
9078 gen_logic_CC(tmp);
9080 store_reg_bx(s, rd, tmp);
9081 break;
9082 default:
9083 case 0x0f:
9084 tcg_gen_not_i32(tmp2, tmp2);
9085 if (logic_cc) {
9086 gen_logic_CC(tmp2);
9088 store_reg_bx(s, rd, tmp2);
9089 break;
9091 if (op1 != 0x0f && op1 != 0x0d) {
9092 tcg_temp_free_i32(tmp2);
9094 } else {
9095 /* other instructions */
9096 op1 = (insn >> 24) & 0xf;
9097 switch(op1) {
9098 case 0x0:
9099 case 0x1:
9100 /* multiplies, extra load/stores */
9101 sh = (insn >> 5) & 3;
9102 if (sh == 0) {
9103 if (op1 == 0x0) {
9104 rd = (insn >> 16) & 0xf;
9105 rn = (insn >> 12) & 0xf;
9106 rs = (insn >> 8) & 0xf;
9107 rm = (insn) & 0xf;
9108 op1 = (insn >> 20) & 0xf;
9109 switch (op1) {
9110 case 0: case 1: case 2: case 3: case 6:
9111 /* 32 bit mul */
9112 tmp = load_reg(s, rs);
9113 tmp2 = load_reg(s, rm);
9114 tcg_gen_mul_i32(tmp, tmp, tmp2);
9115 tcg_temp_free_i32(tmp2);
9116 if (insn & (1 << 22)) {
9117 /* Subtract (mls) */
9118 ARCH(6T2);
9119 tmp2 = load_reg(s, rn);
9120 tcg_gen_sub_i32(tmp, tmp2, tmp);
9121 tcg_temp_free_i32(tmp2);
9122 } else if (insn & (1 << 21)) {
9123 /* Add */
9124 tmp2 = load_reg(s, rn);
9125 tcg_gen_add_i32(tmp, tmp, tmp2);
9126 tcg_temp_free_i32(tmp2);
9128 if (insn & (1 << 20))
9129 gen_logic_CC(tmp);
9130 store_reg(s, rd, tmp);
9131 break;
9132 case 4:
9133 /* 64 bit mul double accumulate (UMAAL) */
9134 ARCH(6);
9135 tmp = load_reg(s, rs);
9136 tmp2 = load_reg(s, rm);
9137 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9138 gen_addq_lo(s, tmp64, rn);
9139 gen_addq_lo(s, tmp64, rd);
9140 gen_storeq_reg(s, rn, rd, tmp64);
9141 tcg_temp_free_i64(tmp64);
9142 break;
9143 case 8: case 9: case 10: case 11:
9144 case 12: case 13: case 14: case 15:
9145 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9146 tmp = load_reg(s, rs);
9147 tmp2 = load_reg(s, rm);
9148 if (insn & (1 << 22)) {
9149 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9150 } else {
9151 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9153 if (insn & (1 << 21)) { /* mult accumulate */
9154 TCGv_i32 al = load_reg(s, rn);
9155 TCGv_i32 ah = load_reg(s, rd);
9156 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9157 tcg_temp_free_i32(al);
9158 tcg_temp_free_i32(ah);
9160 if (insn & (1 << 20)) {
9161 gen_logicq_cc(tmp, tmp2);
9163 store_reg(s, rn, tmp);
9164 store_reg(s, rd, tmp2);
9165 break;
9166 default:
9167 goto illegal_op;
9169 } else {
9170 rn = (insn >> 16) & 0xf;
9171 rd = (insn >> 12) & 0xf;
9172 if (insn & (1 << 23)) {
9173 /* load/store exclusive */
9174 int op2 = (insn >> 8) & 3;
9175 op1 = (insn >> 21) & 0x3;
9177 switch (op2) {
9178 case 0: /* lda/stl */
9179 if (op1 == 1) {
9180 goto illegal_op;
9182 ARCH(8);
9183 break;
9184 case 1: /* reserved */
9185 goto illegal_op;
9186 case 2: /* ldaex/stlex */
9187 ARCH(8);
9188 break;
9189 case 3: /* ldrex/strex */
9190 if (op1) {
9191 ARCH(6K);
9192 } else {
9193 ARCH(6);
9195 break;
9198 addr = tcg_temp_local_new_i32();
9199 load_reg_var(s, addr, rn);
9201 /* Since the emulation does not have barriers,
9202 the acquire/release semantics need no special
9203 handling */
9204 if (op2 == 0) {
9205 if (insn & (1 << 20)) {
9206 tmp = tcg_temp_new_i32();
9207 switch (op1) {
9208 case 0: /* lda */
9209 gen_aa32_ld32u_iss(s, tmp, addr,
9210 get_mem_index(s),
9211 rd | ISSIsAcqRel);
9212 break;
9213 case 2: /* ldab */
9214 gen_aa32_ld8u_iss(s, tmp, addr,
9215 get_mem_index(s),
9216 rd | ISSIsAcqRel);
9217 break;
9218 case 3: /* ldah */
9219 gen_aa32_ld16u_iss(s, tmp, addr,
9220 get_mem_index(s),
9221 rd | ISSIsAcqRel);
9222 break;
9223 default:
9224 abort();
9226 store_reg(s, rd, tmp);
9227 } else {
9228 rm = insn & 0xf;
9229 tmp = load_reg(s, rm);
9230 switch (op1) {
9231 case 0: /* stl */
9232 gen_aa32_st32_iss(s, tmp, addr,
9233 get_mem_index(s),
9234 rm | ISSIsAcqRel);
9235 break;
9236 case 2: /* stlb */
9237 gen_aa32_st8_iss(s, tmp, addr,
9238 get_mem_index(s),
9239 rm | ISSIsAcqRel);
9240 break;
9241 case 3: /* stlh */
9242 gen_aa32_st16_iss(s, tmp, addr,
9243 get_mem_index(s),
9244 rm | ISSIsAcqRel);
9245 break;
9246 default:
9247 abort();
9249 tcg_temp_free_i32(tmp);
9251 } else if (insn & (1 << 20)) {
9252 switch (op1) {
9253 case 0: /* ldrex */
9254 gen_load_exclusive(s, rd, 15, addr, 2);
9255 break;
9256 case 1: /* ldrexd */
9257 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9258 break;
9259 case 2: /* ldrexb */
9260 gen_load_exclusive(s, rd, 15, addr, 0);
9261 break;
9262 case 3: /* ldrexh */
9263 gen_load_exclusive(s, rd, 15, addr, 1);
9264 break;
9265 default:
9266 abort();
9268 } else {
9269 rm = insn & 0xf;
9270 switch (op1) {
9271 case 0: /* strex */
9272 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9273 break;
9274 case 1: /* strexd */
9275 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9276 break;
9277 case 2: /* strexb */
9278 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9279 break;
9280 case 3: /* strexh */
9281 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9282 break;
9283 default:
9284 abort();
9287 tcg_temp_free_i32(addr);
9288 } else if ((insn & 0x00300f00) == 0) {
9289 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9290 * - SWP, SWPB
9293 TCGv taddr;
9294 TCGMemOp opc = s->be_data;
9296 rm = (insn) & 0xf;
9298 if (insn & (1 << 22)) {
9299 opc |= MO_UB;
9300 } else {
9301 opc |= MO_UL | MO_ALIGN;
9304 addr = load_reg(s, rn);
9305 taddr = gen_aa32_addr(s, addr, opc);
9306 tcg_temp_free_i32(addr);
9308 tmp = load_reg(s, rm);
9309 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9310 get_mem_index(s), opc);
9311 tcg_temp_free(taddr);
9312 store_reg(s, rd, tmp);
9313 } else {
9314 goto illegal_op;
9317 } else {
9318 int address_offset;
9319 bool load = insn & (1 << 20);
9320 bool wbit = insn & (1 << 21);
9321 bool pbit = insn & (1 << 24);
9322 bool doubleword = false;
9323 ISSInfo issinfo;
9325 /* Misc load/store */
9326 rn = (insn >> 16) & 0xf;
9327 rd = (insn >> 12) & 0xf;
9329 /* ISS not valid if writeback */
9330 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9332 if (!load && (sh & 2)) {
9333 /* doubleword */
9334 ARCH(5TE);
9335 if (rd & 1) {
9336 /* UNPREDICTABLE; we choose to UNDEF */
9337 goto illegal_op;
9339 load = (sh & 1) == 0;
9340 doubleword = true;
9343 addr = load_reg(s, rn);
9344 if (pbit) {
9345 gen_add_datah_offset(s, insn, 0, addr);
9347 address_offset = 0;
9349 if (doubleword) {
9350 if (!load) {
9351 /* store */
9352 tmp = load_reg(s, rd);
9353 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9354 tcg_temp_free_i32(tmp);
9355 tcg_gen_addi_i32(addr, addr, 4);
9356 tmp = load_reg(s, rd + 1);
9357 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9358 tcg_temp_free_i32(tmp);
9359 } else {
9360 /* load */
9361 tmp = tcg_temp_new_i32();
9362 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9363 store_reg(s, rd, tmp);
9364 tcg_gen_addi_i32(addr, addr, 4);
9365 tmp = tcg_temp_new_i32();
9366 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9367 rd++;
9369 address_offset = -4;
9370 } else if (load) {
9371 /* load */
9372 tmp = tcg_temp_new_i32();
9373 switch (sh) {
9374 case 1:
9375 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9376 issinfo);
9377 break;
9378 case 2:
9379 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9380 issinfo);
9381 break;
9382 default:
9383 case 3:
9384 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9385 issinfo);
9386 break;
9388 } else {
9389 /* store */
9390 tmp = load_reg(s, rd);
9391 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9392 tcg_temp_free_i32(tmp);
9394 /* Perform base writeback before the loaded value to
9395 ensure correct behavior with overlapping index registers.
9396 ldrd with base writeback is undefined if the
9397 destination and index registers overlap. */
9398 if (!pbit) {
9399 gen_add_datah_offset(s, insn, address_offset, addr);
9400 store_reg(s, rn, addr);
9401 } else if (wbit) {
9402 if (address_offset)
9403 tcg_gen_addi_i32(addr, addr, address_offset);
9404 store_reg(s, rn, addr);
9405 } else {
9406 tcg_temp_free_i32(addr);
9408 if (load) {
9409 /* Complete the load. */
9410 store_reg(s, rd, tmp);
9413 break;
9414 case 0x4:
9415 case 0x5:
9416 goto do_ldst;
9417 case 0x6:
9418 case 0x7:
9419 if (insn & (1 << 4)) {
9420 ARCH(6);
9421 /* Armv6 Media instructions. */
9422 rm = insn & 0xf;
9423 rn = (insn >> 16) & 0xf;
9424 rd = (insn >> 12) & 0xf;
9425 rs = (insn >> 8) & 0xf;
9426 switch ((insn >> 23) & 3) {
9427 case 0: /* Parallel add/subtract. */
9428 op1 = (insn >> 20) & 7;
9429 tmp = load_reg(s, rn);
9430 tmp2 = load_reg(s, rm);
9431 sh = (insn >> 5) & 7;
9432 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9433 goto illegal_op;
9434 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9435 tcg_temp_free_i32(tmp2);
9436 store_reg(s, rd, tmp);
9437 break;
9438 case 1:
9439 if ((insn & 0x00700020) == 0) {
9440 /* Halfword pack. */
9441 tmp = load_reg(s, rn);
9442 tmp2 = load_reg(s, rm);
9443 shift = (insn >> 7) & 0x1f;
9444 if (insn & (1 << 6)) {
9445 /* pkhtb */
9446 if (shift == 0)
9447 shift = 31;
9448 tcg_gen_sari_i32(tmp2, tmp2, shift);
9449 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9450 tcg_gen_ext16u_i32(tmp2, tmp2);
9451 } else {
9452 /* pkhbt */
9453 if (shift)
9454 tcg_gen_shli_i32(tmp2, tmp2, shift);
9455 tcg_gen_ext16u_i32(tmp, tmp);
9456 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9458 tcg_gen_or_i32(tmp, tmp, tmp2);
9459 tcg_temp_free_i32(tmp2);
9460 store_reg(s, rd, tmp);
9461 } else if ((insn & 0x00200020) == 0x00200000) {
9462 /* [us]sat */
9463 tmp = load_reg(s, rm);
9464 shift = (insn >> 7) & 0x1f;
9465 if (insn & (1 << 6)) {
9466 if (shift == 0)
9467 shift = 31;
9468 tcg_gen_sari_i32(tmp, tmp, shift);
9469 } else {
9470 tcg_gen_shli_i32(tmp, tmp, shift);
9472 sh = (insn >> 16) & 0x1f;
9473 tmp2 = tcg_const_i32(sh);
9474 if (insn & (1 << 22))
9475 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9476 else
9477 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9478 tcg_temp_free_i32(tmp2);
9479 store_reg(s, rd, tmp);
9480 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9481 /* [us]sat16 */
9482 tmp = load_reg(s, rm);
9483 sh = (insn >> 16) & 0x1f;
9484 tmp2 = tcg_const_i32(sh);
9485 if (insn & (1 << 22))
9486 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9487 else
9488 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9489 tcg_temp_free_i32(tmp2);
9490 store_reg(s, rd, tmp);
9491 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9492 /* Select bytes. */
9493 tmp = load_reg(s, rn);
9494 tmp2 = load_reg(s, rm);
9495 tmp3 = tcg_temp_new_i32();
9496 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9497 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9498 tcg_temp_free_i32(tmp3);
9499 tcg_temp_free_i32(tmp2);
9500 store_reg(s, rd, tmp);
9501 } else if ((insn & 0x000003e0) == 0x00000060) {
9502 tmp = load_reg(s, rm);
9503 shift = (insn >> 10) & 3;
9504 /* ??? In many cases it's not necessary to do a
9505 rotate, a shift is sufficient. */
9506 if (shift != 0)
9507 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9508 op1 = (insn >> 20) & 7;
9509 switch (op1) {
9510 case 0: gen_sxtb16(tmp); break;
9511 case 2: gen_sxtb(tmp); break;
9512 case 3: gen_sxth(tmp); break;
9513 case 4: gen_uxtb16(tmp); break;
9514 case 6: gen_uxtb(tmp); break;
9515 case 7: gen_uxth(tmp); break;
9516 default: goto illegal_op;
9518 if (rn != 15) {
9519 tmp2 = load_reg(s, rn);
9520 if ((op1 & 3) == 0) {
9521 gen_add16(tmp, tmp2);
9522 } else {
9523 tcg_gen_add_i32(tmp, tmp, tmp2);
9524 tcg_temp_free_i32(tmp2);
9527 store_reg(s, rd, tmp);
9528 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9529 /* rev */
9530 tmp = load_reg(s, rm);
9531 if (insn & (1 << 22)) {
9532 if (insn & (1 << 7)) {
9533 gen_revsh(tmp);
9534 } else {
9535 ARCH(6T2);
9536 gen_helper_rbit(tmp, tmp);
9538 } else {
9539 if (insn & (1 << 7))
9540 gen_rev16(tmp);
9541 else
9542 tcg_gen_bswap32_i32(tmp, tmp);
9544 store_reg(s, rd, tmp);
9545 } else {
9546 goto illegal_op;
9548 break;
9549 case 2: /* Multiplies (Type 3). */
9550 switch ((insn >> 20) & 0x7) {
9551 case 5:
9552 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9553 /* op2 not 00x or 11x : UNDEF */
9554 goto illegal_op;
9556 /* Signed multiply most significant [accumulate].
9557 (SMMUL, SMMLA, SMMLS) */
9558 tmp = load_reg(s, rm);
9559 tmp2 = load_reg(s, rs);
9560 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9562 if (rd != 15) {
9563 tmp = load_reg(s, rd);
9564 if (insn & (1 << 6)) {
9565 tmp64 = gen_subq_msw(tmp64, tmp);
9566 } else {
9567 tmp64 = gen_addq_msw(tmp64, tmp);
9570 if (insn & (1 << 5)) {
9571 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9573 tcg_gen_shri_i64(tmp64, tmp64, 32);
9574 tmp = tcg_temp_new_i32();
9575 tcg_gen_extrl_i64_i32(tmp, tmp64);
9576 tcg_temp_free_i64(tmp64);
9577 store_reg(s, rn, tmp);
9578 break;
9579 case 0:
9580 case 4:
9581 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9582 if (insn & (1 << 7)) {
9583 goto illegal_op;
9585 tmp = load_reg(s, rm);
9586 tmp2 = load_reg(s, rs);
9587 if (insn & (1 << 5))
9588 gen_swap_half(tmp2);
9589 gen_smul_dual(tmp, tmp2);
9590 if (insn & (1 << 22)) {
9591 /* smlald, smlsld */
9592 TCGv_i64 tmp64_2;
9594 tmp64 = tcg_temp_new_i64();
9595 tmp64_2 = tcg_temp_new_i64();
9596 tcg_gen_ext_i32_i64(tmp64, tmp);
9597 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9598 tcg_temp_free_i32(tmp);
9599 tcg_temp_free_i32(tmp2);
9600 if (insn & (1 << 6)) {
9601 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9602 } else {
9603 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9605 tcg_temp_free_i64(tmp64_2);
9606 gen_addq(s, tmp64, rd, rn);
9607 gen_storeq_reg(s, rd, rn, tmp64);
9608 tcg_temp_free_i64(tmp64);
9609 } else {
9610 /* smuad, smusd, smlad, smlsd */
9611 if (insn & (1 << 6)) {
9612 /* This subtraction cannot overflow. */
9613 tcg_gen_sub_i32(tmp, tmp, tmp2);
9614 } else {
9615 /* This addition cannot overflow 32 bits;
9616 * however it may overflow considered as a
9617 * signed operation, in which case we must set
9618 * the Q flag.
9620 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9622 tcg_temp_free_i32(tmp2);
9623 if (rd != 15)
9625 tmp2 = load_reg(s, rd);
9626 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9627 tcg_temp_free_i32(tmp2);
9629 store_reg(s, rn, tmp);
9631 break;
9632 case 1:
9633 case 3:
9634 /* SDIV, UDIV */
9635 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9636 goto illegal_op;
9638 if (((insn >> 5) & 7) || (rd != 15)) {
9639 goto illegal_op;
9641 tmp = load_reg(s, rm);
9642 tmp2 = load_reg(s, rs);
9643 if (insn & (1 << 21)) {
9644 gen_helper_udiv(tmp, tmp, tmp2);
9645 } else {
9646 gen_helper_sdiv(tmp, tmp, tmp2);
9648 tcg_temp_free_i32(tmp2);
9649 store_reg(s, rn, tmp);
9650 break;
9651 default:
9652 goto illegal_op;
9654 break;
9655 case 3:
9656 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9657 switch (op1) {
9658 case 0: /* Unsigned sum of absolute differences. */
9659 ARCH(6);
9660 tmp = load_reg(s, rm);
9661 tmp2 = load_reg(s, rs);
9662 gen_helper_usad8(tmp, tmp, tmp2);
9663 tcg_temp_free_i32(tmp2);
9664 if (rd != 15) {
9665 tmp2 = load_reg(s, rd);
9666 tcg_gen_add_i32(tmp, tmp, tmp2);
9667 tcg_temp_free_i32(tmp2);
9669 store_reg(s, rn, tmp);
9670 break;
9671 case 0x20: case 0x24: case 0x28: case 0x2c:
9672 /* Bitfield insert/clear. */
9673 ARCH(6T2);
9674 shift = (insn >> 7) & 0x1f;
9675 i = (insn >> 16) & 0x1f;
9676 if (i < shift) {
9677 /* UNPREDICTABLE; we choose to UNDEF */
9678 goto illegal_op;
9680 i = i + 1 - shift;
9681 if (rm == 15) {
9682 tmp = tcg_temp_new_i32();
9683 tcg_gen_movi_i32(tmp, 0);
9684 } else {
9685 tmp = load_reg(s, rm);
9687 if (i != 32) {
9688 tmp2 = load_reg(s, rd);
9689 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9690 tcg_temp_free_i32(tmp2);
9692 store_reg(s, rd, tmp);
9693 break;
9694 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9695 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9696 ARCH(6T2);
9697 tmp = load_reg(s, rm);
9698 shift = (insn >> 7) & 0x1f;
9699 i = ((insn >> 16) & 0x1f) + 1;
9700 if (shift + i > 32)
9701 goto illegal_op;
9702 if (i < 32) {
9703 if (op1 & 0x20) {
9704 tcg_gen_extract_i32(tmp, tmp, shift, i);
9705 } else {
9706 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9709 store_reg(s, rd, tmp);
9710 break;
9711 default:
9712 goto illegal_op;
9714 break;
9716 break;
9718 do_ldst:
9719 /* Check for undefined extension instructions
9720 * per the ARM Bible IE:
9721 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9723 sh = (0xf << 20) | (0xf << 4);
9724 if (op1 == 0x7 && ((insn & sh) == sh))
9726 goto illegal_op;
9728 /* load/store byte/word */
9729 rn = (insn >> 16) & 0xf;
9730 rd = (insn >> 12) & 0xf;
9731 tmp2 = load_reg(s, rn);
9732 if ((insn & 0x01200000) == 0x00200000) {
9733 /* ldrt/strt */
9734 i = get_a32_user_mem_index(s);
9735 } else {
9736 i = get_mem_index(s);
9738 if (insn & (1 << 24))
9739 gen_add_data_offset(s, insn, tmp2);
9740 if (insn & (1 << 20)) {
9741 /* load */
9742 tmp = tcg_temp_new_i32();
9743 if (insn & (1 << 22)) {
9744 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9745 } else {
9746 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9748 } else {
9749 /* store */
9750 tmp = load_reg(s, rd);
9751 if (insn & (1 << 22)) {
9752 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9753 } else {
9754 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9756 tcg_temp_free_i32(tmp);
9758 if (!(insn & (1 << 24))) {
9759 gen_add_data_offset(s, insn, tmp2);
9760 store_reg(s, rn, tmp2);
9761 } else if (insn & (1 << 21)) {
9762 store_reg(s, rn, tmp2);
9763 } else {
9764 tcg_temp_free_i32(tmp2);
9766 if (insn & (1 << 20)) {
9767 /* Complete the load. */
9768 store_reg_from_load(s, rd, tmp);
9770 break;
9771 case 0x08:
9772 case 0x09:
9774 int j, n, loaded_base;
9775 bool exc_return = false;
9776 bool is_load = extract32(insn, 20, 1);
9777 bool user = false;
9778 TCGv_i32 loaded_var;
9779 /* load/store multiple words */
9780 /* XXX: store correct base if write back */
9781 if (insn & (1 << 22)) {
9782 /* LDM (user), LDM (exception return) and STM (user) */
9783 if (IS_USER(s))
9784 goto illegal_op; /* only usable in supervisor mode */
9786 if (is_load && extract32(insn, 15, 1)) {
9787 exc_return = true;
9788 } else {
9789 user = true;
9792 rn = (insn >> 16) & 0xf;
9793 addr = load_reg(s, rn);
9795 /* compute total size */
9796 loaded_base = 0;
9797 loaded_var = NULL;
9798 n = 0;
9799 for(i=0;i<16;i++) {
9800 if (insn & (1 << i))
9801 n++;
9803 /* XXX: test invalid n == 0 case ? */
9804 if (insn & (1 << 23)) {
9805 if (insn & (1 << 24)) {
9806 /* pre increment */
9807 tcg_gen_addi_i32(addr, addr, 4);
9808 } else {
9809 /* post increment */
9811 } else {
9812 if (insn & (1 << 24)) {
9813 /* pre decrement */
9814 tcg_gen_addi_i32(addr, addr, -(n * 4));
9815 } else {
9816 /* post decrement */
9817 if (n != 1)
9818 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9821 j = 0;
9822 for(i=0;i<16;i++) {
9823 if (insn & (1 << i)) {
9824 if (is_load) {
9825 /* load */
9826 tmp = tcg_temp_new_i32();
9827 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9828 if (user) {
9829 tmp2 = tcg_const_i32(i);
9830 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9831 tcg_temp_free_i32(tmp2);
9832 tcg_temp_free_i32(tmp);
9833 } else if (i == rn) {
9834 loaded_var = tmp;
9835 loaded_base = 1;
9836 } else if (rn == 15 && exc_return) {
9837 store_pc_exc_ret(s, tmp);
9838 } else {
9839 store_reg_from_load(s, i, tmp);
9841 } else {
9842 /* store */
9843 if (i == 15) {
9844 /* special case: r15 = PC + 8 */
9845 val = (long)s->pc + 4;
9846 tmp = tcg_temp_new_i32();
9847 tcg_gen_movi_i32(tmp, val);
9848 } else if (user) {
9849 tmp = tcg_temp_new_i32();
9850 tmp2 = tcg_const_i32(i);
9851 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9852 tcg_temp_free_i32(tmp2);
9853 } else {
9854 tmp = load_reg(s, i);
9856 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9857 tcg_temp_free_i32(tmp);
9859 j++;
9860 /* no need to add after the last transfer */
9861 if (j != n)
9862 tcg_gen_addi_i32(addr, addr, 4);
9865 if (insn & (1 << 21)) {
9866 /* write back */
9867 if (insn & (1 << 23)) {
9868 if (insn & (1 << 24)) {
9869 /* pre increment */
9870 } else {
9871 /* post increment */
9872 tcg_gen_addi_i32(addr, addr, 4);
9874 } else {
9875 if (insn & (1 << 24)) {
9876 /* pre decrement */
9877 if (n != 1)
9878 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9879 } else {
9880 /* post decrement */
9881 tcg_gen_addi_i32(addr, addr, -(n * 4));
9884 store_reg(s, rn, addr);
9885 } else {
9886 tcg_temp_free_i32(addr);
9888 if (loaded_base) {
9889 store_reg(s, rn, loaded_var);
9891 if (exc_return) {
9892 /* Restore CPSR from SPSR. */
9893 tmp = load_cpu_field(spsr);
9894 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9895 gen_io_start();
9897 gen_helper_cpsr_write_eret(cpu_env, tmp);
9898 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9899 gen_io_end();
9901 tcg_temp_free_i32(tmp);
9902 /* Must exit loop to check un-masked IRQs */
9903 s->base.is_jmp = DISAS_EXIT;
9906 break;
9907 case 0xa:
9908 case 0xb:
9910 int32_t offset;
9912 /* branch (and link) */
9913 val = (int32_t)s->pc;
9914 if (insn & (1 << 24)) {
9915 tmp = tcg_temp_new_i32();
9916 tcg_gen_movi_i32(tmp, val);
9917 store_reg(s, 14, tmp);
9919 offset = sextract32(insn << 2, 0, 26);
9920 val += offset + 4;
9921 gen_jmp(s, val);
9923 break;
9924 case 0xc:
9925 case 0xd:
9926 case 0xe:
9927 if (((insn >> 8) & 0xe) == 10) {
9928 /* VFP. */
9929 if (disas_vfp_insn(s, insn)) {
9930 goto illegal_op;
9932 } else if (disas_coproc_insn(s, insn)) {
9933 /* Coprocessor. */
9934 goto illegal_op;
9936 break;
9937 case 0xf:
9938 /* swi */
9939 gen_set_pc_im(s, s->pc);
9940 s->svc_imm = extract32(insn, 0, 24);
9941 s->base.is_jmp = DISAS_SWI;
9942 break;
9943 default:
9944 illegal_op:
9945 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9946 default_exception_el(s));
9947 break;
9952 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9954 /* Return true if this is a 16 bit instruction. We must be precise
9955 * about this (matching the decode). We assume that s->pc still
9956 * points to the first 16 bits of the insn.
9958 if ((insn >> 11) < 0x1d) {
9959 /* Definitely a 16-bit instruction */
9960 return true;
9963 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9964 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9965 * end up actually treating this as two 16-bit insns, though,
9966 * if it's half of a bl/blx pair that might span a page boundary.
9968 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9969 arm_dc_feature(s, ARM_FEATURE_M)) {
9970 /* Thumb2 cores (including all M profile ones) always treat
9971 * 32-bit insns as 32-bit.
9973 return false;
9976 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9977 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9978 * is not on the next page; we merge this into a 32-bit
9979 * insn.
9981 return false;
9983 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9984 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9985 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9986 * -- handle as single 16 bit insn
9988 return true;
9991 /* Return true if this is a Thumb-2 logical op. */
9992 static int
9993 thumb2_logic_op(int op)
9995 return (op < 8);
9998 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9999 then set condition code flags based on the result of the operation.
10000 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10001 to the high bit of T1.
10002 Returns zero if the opcode is valid. */
10004 static int
10005 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10006 TCGv_i32 t0, TCGv_i32 t1)
10008 int logic_cc;
10010 logic_cc = 0;
10011 switch (op) {
10012 case 0: /* and */
10013 tcg_gen_and_i32(t0, t0, t1);
10014 logic_cc = conds;
10015 break;
10016 case 1: /* bic */
10017 tcg_gen_andc_i32(t0, t0, t1);
10018 logic_cc = conds;
10019 break;
10020 case 2: /* orr */
10021 tcg_gen_or_i32(t0, t0, t1);
10022 logic_cc = conds;
10023 break;
10024 case 3: /* orn */
10025 tcg_gen_orc_i32(t0, t0, t1);
10026 logic_cc = conds;
10027 break;
10028 case 4: /* eor */
10029 tcg_gen_xor_i32(t0, t0, t1);
10030 logic_cc = conds;
10031 break;
10032 case 8: /* add */
10033 if (conds)
10034 gen_add_CC(t0, t0, t1);
10035 else
10036 tcg_gen_add_i32(t0, t0, t1);
10037 break;
10038 case 10: /* adc */
10039 if (conds)
10040 gen_adc_CC(t0, t0, t1);
10041 else
10042 gen_adc(t0, t1);
10043 break;
10044 case 11: /* sbc */
10045 if (conds) {
10046 gen_sbc_CC(t0, t0, t1);
10047 } else {
10048 gen_sub_carry(t0, t0, t1);
10050 break;
10051 case 13: /* sub */
10052 if (conds)
10053 gen_sub_CC(t0, t0, t1);
10054 else
10055 tcg_gen_sub_i32(t0, t0, t1);
10056 break;
10057 case 14: /* rsb */
10058 if (conds)
10059 gen_sub_CC(t0, t1, t0);
10060 else
10061 tcg_gen_sub_i32(t0, t1, t0);
10062 break;
10063 default: /* 5, 6, 7, 9, 12, 15. */
10064 return 1;
10066 if (logic_cc) {
10067 gen_logic_CC(t0);
10068 if (shifter_out)
10069 gen_set_CF_bit31(t1);
10071 return 0;
10074 /* Translate a 32-bit thumb instruction. */
10075 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10077 uint32_t imm, shift, offset;
10078 uint32_t rd, rn, rm, rs;
10079 TCGv_i32 tmp;
10080 TCGv_i32 tmp2;
10081 TCGv_i32 tmp3;
10082 TCGv_i32 addr;
10083 TCGv_i64 tmp64;
10084 int op;
10085 int shiftop;
10086 int conds;
10087 int logic_cc;
10090 * ARMv6-M supports a limited subset of Thumb2 instructions.
10091 * Other Thumb1 architectures allow only 32-bit
10092 * combined BL/BLX prefix and suffix.
10094 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10095 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10096 int i;
10097 bool found = false;
10098 const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10099 0xf3b08040 /* dsb */,
10100 0xf3b08050 /* dmb */,
10101 0xf3b08060 /* isb */,
10102 0xf3e08000 /* mrs */,
10103 0xf000d000 /* bl */};
10104 const uint32_t armv6m_mask[] = {0xffe0d000,
10105 0xfff0d0f0,
10106 0xfff0d0f0,
10107 0xfff0d0f0,
10108 0xffe0d000,
10109 0xf800d000};
10111 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10112 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10113 found = true;
10114 break;
10117 if (!found) {
10118 goto illegal_op;
10120 } else if ((insn & 0xf800e800) != 0xf000e800) {
10121 ARCH(6T2);
10124 rn = (insn >> 16) & 0xf;
10125 rs = (insn >> 12) & 0xf;
10126 rd = (insn >> 8) & 0xf;
10127 rm = insn & 0xf;
10128 switch ((insn >> 25) & 0xf) {
10129 case 0: case 1: case 2: case 3:
10130 /* 16-bit instructions. Should never happen. */
10131 abort();
10132 case 4:
10133 if (insn & (1 << 22)) {
10134 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10135 * - load/store doubleword, load/store exclusive, ldacq/strel,
10136 * table branch, TT.
10138 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10139 arm_dc_feature(s, ARM_FEATURE_V8)) {
10140 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10141 * - SG (v8M only)
10142 * The bulk of the behaviour for this instruction is implemented
10143 * in v7m_handle_execute_nsc(), which deals with the insn when
10144 * it is executed by a CPU in non-secure state from memory
10145 * which is Secure & NonSecure-Callable.
10146 * Here we only need to handle the remaining cases:
10147 * * in NS memory (including the "security extension not
10148 * implemented" case) : NOP
10149 * * in S memory but CPU already secure (clear IT bits)
10150 * We know that the attribute for the memory this insn is
10151 * in must match the current CPU state, because otherwise
10152 * get_phys_addr_pmsav8 would have generated an exception.
10154 if (s->v8m_secure) {
10155 /* Like the IT insn, we don't need to generate any code */
10156 s->condexec_cond = 0;
10157 s->condexec_mask = 0;
10159 } else if (insn & 0x01200000) {
10160 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10161 * - load/store dual (post-indexed)
10162 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10163 * - load/store dual (literal and immediate)
10164 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10165 * - load/store dual (pre-indexed)
10167 if (rn == 15) {
10168 if (insn & (1 << 21)) {
10169 /* UNPREDICTABLE */
10170 goto illegal_op;
10172 addr = tcg_temp_new_i32();
10173 tcg_gen_movi_i32(addr, s->pc & ~3);
10174 } else {
10175 addr = load_reg(s, rn);
10177 offset = (insn & 0xff) * 4;
10178 if ((insn & (1 << 23)) == 0)
10179 offset = -offset;
10180 if (insn & (1 << 24)) {
10181 tcg_gen_addi_i32(addr, addr, offset);
10182 offset = 0;
10184 if (insn & (1 << 20)) {
10185 /* ldrd */
10186 tmp = tcg_temp_new_i32();
10187 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10188 store_reg(s, rs, tmp);
10189 tcg_gen_addi_i32(addr, addr, 4);
10190 tmp = tcg_temp_new_i32();
10191 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10192 store_reg(s, rd, tmp);
10193 } else {
10194 /* strd */
10195 tmp = load_reg(s, rs);
10196 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10197 tcg_temp_free_i32(tmp);
10198 tcg_gen_addi_i32(addr, addr, 4);
10199 tmp = load_reg(s, rd);
10200 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10201 tcg_temp_free_i32(tmp);
10203 if (insn & (1 << 21)) {
10204 /* Base writeback. */
10205 tcg_gen_addi_i32(addr, addr, offset - 4);
10206 store_reg(s, rn, addr);
10207 } else {
10208 tcg_temp_free_i32(addr);
10210 } else if ((insn & (1 << 23)) == 0) {
10211 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10212 * - load/store exclusive word
10213 * - TT (v8M only)
10215 if (rs == 15) {
10216 if (!(insn & (1 << 20)) &&
10217 arm_dc_feature(s, ARM_FEATURE_M) &&
10218 arm_dc_feature(s, ARM_FEATURE_V8)) {
10219 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10220 * - TT (v8M only)
10222 bool alt = insn & (1 << 7);
10223 TCGv_i32 addr, op, ttresp;
10225 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10226 /* we UNDEF for these UNPREDICTABLE cases */
10227 goto illegal_op;
10230 if (alt && !s->v8m_secure) {
10231 goto illegal_op;
10234 addr = load_reg(s, rn);
10235 op = tcg_const_i32(extract32(insn, 6, 2));
10236 ttresp = tcg_temp_new_i32();
10237 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10238 tcg_temp_free_i32(addr);
10239 tcg_temp_free_i32(op);
10240 store_reg(s, rd, ttresp);
10241 break;
10243 goto illegal_op;
10245 addr = tcg_temp_local_new_i32();
10246 load_reg_var(s, addr, rn);
10247 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10248 if (insn & (1 << 20)) {
10249 gen_load_exclusive(s, rs, 15, addr, 2);
10250 } else {
10251 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10253 tcg_temp_free_i32(addr);
10254 } else if ((insn & (7 << 5)) == 0) {
10255 /* Table Branch. */
10256 if (rn == 15) {
10257 addr = tcg_temp_new_i32();
10258 tcg_gen_movi_i32(addr, s->pc);
10259 } else {
10260 addr = load_reg(s, rn);
10262 tmp = load_reg(s, rm);
10263 tcg_gen_add_i32(addr, addr, tmp);
10264 if (insn & (1 << 4)) {
10265 /* tbh */
10266 tcg_gen_add_i32(addr, addr, tmp);
10267 tcg_temp_free_i32(tmp);
10268 tmp = tcg_temp_new_i32();
10269 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10270 } else { /* tbb */
10271 tcg_temp_free_i32(tmp);
10272 tmp = tcg_temp_new_i32();
10273 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10275 tcg_temp_free_i32(addr);
10276 tcg_gen_shli_i32(tmp, tmp, 1);
10277 tcg_gen_addi_i32(tmp, tmp, s->pc);
10278 store_reg(s, 15, tmp);
10279 } else {
10280 int op2 = (insn >> 6) & 0x3;
10281 op = (insn >> 4) & 0x3;
10282 switch (op2) {
10283 case 0:
10284 goto illegal_op;
10285 case 1:
10286 /* Load/store exclusive byte/halfword/doubleword */
10287 if (op == 2) {
10288 goto illegal_op;
10290 ARCH(7);
10291 break;
10292 case 2:
10293 /* Load-acquire/store-release */
10294 if (op == 3) {
10295 goto illegal_op;
10297 /* Fall through */
10298 case 3:
10299 /* Load-acquire/store-release exclusive */
10300 ARCH(8);
10301 break;
10303 addr = tcg_temp_local_new_i32();
10304 load_reg_var(s, addr, rn);
10305 if (!(op2 & 1)) {
10306 if (insn & (1 << 20)) {
10307 tmp = tcg_temp_new_i32();
10308 switch (op) {
10309 case 0: /* ldab */
10310 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10311 rs | ISSIsAcqRel);
10312 break;
10313 case 1: /* ldah */
10314 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10315 rs | ISSIsAcqRel);
10316 break;
10317 case 2: /* lda */
10318 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10319 rs | ISSIsAcqRel);
10320 break;
10321 default:
10322 abort();
10324 store_reg(s, rs, tmp);
10325 } else {
10326 tmp = load_reg(s, rs);
10327 switch (op) {
10328 case 0: /* stlb */
10329 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10330 rs | ISSIsAcqRel);
10331 break;
10332 case 1: /* stlh */
10333 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10334 rs | ISSIsAcqRel);
10335 break;
10336 case 2: /* stl */
10337 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10338 rs | ISSIsAcqRel);
10339 break;
10340 default:
10341 abort();
10343 tcg_temp_free_i32(tmp);
10345 } else if (insn & (1 << 20)) {
10346 gen_load_exclusive(s, rs, rd, addr, op);
10347 } else {
10348 gen_store_exclusive(s, rm, rs, rd, addr, op);
10350 tcg_temp_free_i32(addr);
10352 } else {
10353 /* Load/store multiple, RFE, SRS. */
10354 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10355 /* RFE, SRS: not available in user mode or on M profile */
10356 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10357 goto illegal_op;
10359 if (insn & (1 << 20)) {
10360 /* rfe */
10361 addr = load_reg(s, rn);
10362 if ((insn & (1 << 24)) == 0)
10363 tcg_gen_addi_i32(addr, addr, -8);
10364 /* Load PC into tmp and CPSR into tmp2. */
10365 tmp = tcg_temp_new_i32();
10366 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10367 tcg_gen_addi_i32(addr, addr, 4);
10368 tmp2 = tcg_temp_new_i32();
10369 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10370 if (insn & (1 << 21)) {
10371 /* Base writeback. */
10372 if (insn & (1 << 24)) {
10373 tcg_gen_addi_i32(addr, addr, 4);
10374 } else {
10375 tcg_gen_addi_i32(addr, addr, -4);
10377 store_reg(s, rn, addr);
10378 } else {
10379 tcg_temp_free_i32(addr);
10381 gen_rfe(s, tmp, tmp2);
10382 } else {
10383 /* srs */
10384 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10385 insn & (1 << 21));
10387 } else {
10388 int i, loaded_base = 0;
10389 TCGv_i32 loaded_var;
10390 /* Load/store multiple. */
10391 addr = load_reg(s, rn);
10392 offset = 0;
10393 for (i = 0; i < 16; i++) {
10394 if (insn & (1 << i))
10395 offset += 4;
10397 if (insn & (1 << 24)) {
10398 tcg_gen_addi_i32(addr, addr, -offset);
10401 loaded_var = NULL;
10402 for (i = 0; i < 16; i++) {
10403 if ((insn & (1 << i)) == 0)
10404 continue;
10405 if (insn & (1 << 20)) {
10406 /* Load. */
10407 tmp = tcg_temp_new_i32();
10408 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10409 if (i == 15) {
10410 gen_bx_excret(s, tmp);
10411 } else if (i == rn) {
10412 loaded_var = tmp;
10413 loaded_base = 1;
10414 } else {
10415 store_reg(s, i, tmp);
10417 } else {
10418 /* Store. */
10419 tmp = load_reg(s, i);
10420 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10421 tcg_temp_free_i32(tmp);
10423 tcg_gen_addi_i32(addr, addr, 4);
10425 if (loaded_base) {
10426 store_reg(s, rn, loaded_var);
10428 if (insn & (1 << 21)) {
10429 /* Base register writeback. */
10430 if (insn & (1 << 24)) {
10431 tcg_gen_addi_i32(addr, addr, -offset);
10433 /* Fault if writeback register is in register list. */
10434 if (insn & (1 << rn))
10435 goto illegal_op;
10436 store_reg(s, rn, addr);
10437 } else {
10438 tcg_temp_free_i32(addr);
10442 break;
10443 case 5:
10445 op = (insn >> 21) & 0xf;
10446 if (op == 6) {
10447 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10448 goto illegal_op;
10450 /* Halfword pack. */
10451 tmp = load_reg(s, rn);
10452 tmp2 = load_reg(s, rm);
10453 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10454 if (insn & (1 << 5)) {
10455 /* pkhtb */
10456 if (shift == 0)
10457 shift = 31;
10458 tcg_gen_sari_i32(tmp2, tmp2, shift);
10459 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10460 tcg_gen_ext16u_i32(tmp2, tmp2);
10461 } else {
10462 /* pkhbt */
10463 if (shift)
10464 tcg_gen_shli_i32(tmp2, tmp2, shift);
10465 tcg_gen_ext16u_i32(tmp, tmp);
10466 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10468 tcg_gen_or_i32(tmp, tmp, tmp2);
10469 tcg_temp_free_i32(tmp2);
10470 store_reg(s, rd, tmp);
10471 } else {
10472 /* Data processing register constant shift. */
10473 if (rn == 15) {
10474 tmp = tcg_temp_new_i32();
10475 tcg_gen_movi_i32(tmp, 0);
10476 } else {
10477 tmp = load_reg(s, rn);
10479 tmp2 = load_reg(s, rm);
10481 shiftop = (insn >> 4) & 3;
10482 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10483 conds = (insn & (1 << 20)) != 0;
10484 logic_cc = (conds && thumb2_logic_op(op));
10485 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10486 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10487 goto illegal_op;
10488 tcg_temp_free_i32(tmp2);
10489 if (rd != 15) {
10490 store_reg(s, rd, tmp);
10491 } else {
10492 tcg_temp_free_i32(tmp);
10495 break;
10496 case 13: /* Misc data processing. */
10497 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10498 if (op < 4 && (insn & 0xf000) != 0xf000)
10499 goto illegal_op;
10500 switch (op) {
10501 case 0: /* Register controlled shift. */
10502 tmp = load_reg(s, rn);
10503 tmp2 = load_reg(s, rm);
10504 if ((insn & 0x70) != 0)
10505 goto illegal_op;
10506 op = (insn >> 21) & 3;
10507 logic_cc = (insn & (1 << 20)) != 0;
10508 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10509 if (logic_cc)
10510 gen_logic_CC(tmp);
10511 store_reg(s, rd, tmp);
10512 break;
10513 case 1: /* Sign/zero extend. */
10514 op = (insn >> 20) & 7;
10515 switch (op) {
10516 case 0: /* SXTAH, SXTH */
10517 case 1: /* UXTAH, UXTH */
10518 case 4: /* SXTAB, SXTB */
10519 case 5: /* UXTAB, UXTB */
10520 break;
10521 case 2: /* SXTAB16, SXTB16 */
10522 case 3: /* UXTAB16, UXTB16 */
10523 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10524 goto illegal_op;
10526 break;
10527 default:
10528 goto illegal_op;
10530 if (rn != 15) {
10531 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10532 goto illegal_op;
10535 tmp = load_reg(s, rm);
10536 shift = (insn >> 4) & 3;
10537 /* ??? In many cases it's not necessary to do a
10538 rotate, a shift is sufficient. */
10539 if (shift != 0)
10540 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10541 op = (insn >> 20) & 7;
10542 switch (op) {
10543 case 0: gen_sxth(tmp); break;
10544 case 1: gen_uxth(tmp); break;
10545 case 2: gen_sxtb16(tmp); break;
10546 case 3: gen_uxtb16(tmp); break;
10547 case 4: gen_sxtb(tmp); break;
10548 case 5: gen_uxtb(tmp); break;
10549 default:
10550 g_assert_not_reached();
10552 if (rn != 15) {
10553 tmp2 = load_reg(s, rn);
10554 if ((op >> 1) == 1) {
10555 gen_add16(tmp, tmp2);
10556 } else {
10557 tcg_gen_add_i32(tmp, tmp, tmp2);
10558 tcg_temp_free_i32(tmp2);
10561 store_reg(s, rd, tmp);
10562 break;
10563 case 2: /* SIMD add/subtract. */
10564 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10565 goto illegal_op;
10567 op = (insn >> 20) & 7;
10568 shift = (insn >> 4) & 7;
10569 if ((op & 3) == 3 || (shift & 3) == 3)
10570 goto illegal_op;
10571 tmp = load_reg(s, rn);
10572 tmp2 = load_reg(s, rm);
10573 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10574 tcg_temp_free_i32(tmp2);
10575 store_reg(s, rd, tmp);
10576 break;
10577 case 3: /* Other data processing. */
10578 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10579 if (op < 4) {
10580 /* Saturating add/subtract. */
10581 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10582 goto illegal_op;
10584 tmp = load_reg(s, rn);
10585 tmp2 = load_reg(s, rm);
10586 if (op & 1)
10587 gen_helper_double_saturate(tmp, cpu_env, tmp);
10588 if (op & 2)
10589 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10590 else
10591 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10592 tcg_temp_free_i32(tmp2);
10593 } else {
10594 switch (op) {
10595 case 0x0a: /* rbit */
10596 case 0x08: /* rev */
10597 case 0x09: /* rev16 */
10598 case 0x0b: /* revsh */
10599 case 0x18: /* clz */
10600 break;
10601 case 0x10: /* sel */
10602 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10603 goto illegal_op;
10605 break;
10606 case 0x20: /* crc32/crc32c */
10607 case 0x21:
10608 case 0x22:
10609 case 0x28:
10610 case 0x29:
10611 case 0x2a:
10612 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10613 goto illegal_op;
10615 break;
10616 default:
10617 goto illegal_op;
10619 tmp = load_reg(s, rn);
10620 switch (op) {
10621 case 0x0a: /* rbit */
10622 gen_helper_rbit(tmp, tmp);
10623 break;
10624 case 0x08: /* rev */
10625 tcg_gen_bswap32_i32(tmp, tmp);
10626 break;
10627 case 0x09: /* rev16 */
10628 gen_rev16(tmp);
10629 break;
10630 case 0x0b: /* revsh */
10631 gen_revsh(tmp);
10632 break;
10633 case 0x10: /* sel */
10634 tmp2 = load_reg(s, rm);
10635 tmp3 = tcg_temp_new_i32();
10636 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10637 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10638 tcg_temp_free_i32(tmp3);
10639 tcg_temp_free_i32(tmp2);
10640 break;
10641 case 0x18: /* clz */
10642 tcg_gen_clzi_i32(tmp, tmp, 32);
10643 break;
10644 case 0x20:
10645 case 0x21:
10646 case 0x22:
10647 case 0x28:
10648 case 0x29:
10649 case 0x2a:
10651 /* crc32/crc32c */
10652 uint32_t sz = op & 0x3;
10653 uint32_t c = op & 0x8;
10655 tmp2 = load_reg(s, rm);
10656 if (sz == 0) {
10657 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10658 } else if (sz == 1) {
10659 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10661 tmp3 = tcg_const_i32(1 << sz);
10662 if (c) {
10663 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10664 } else {
10665 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10667 tcg_temp_free_i32(tmp2);
10668 tcg_temp_free_i32(tmp3);
10669 break;
10671 default:
10672 g_assert_not_reached();
10675 store_reg(s, rd, tmp);
10676 break;
10677 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10678 switch ((insn >> 20) & 7) {
10679 case 0: /* 32 x 32 -> 32 */
10680 case 7: /* Unsigned sum of absolute differences. */
10681 break;
10682 case 1: /* 16 x 16 -> 32 */
10683 case 2: /* Dual multiply add. */
10684 case 3: /* 32 * 16 -> 32msb */
10685 case 4: /* Dual multiply subtract. */
10686 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10687 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10688 goto illegal_op;
10690 break;
10692 op = (insn >> 4) & 0xf;
10693 tmp = load_reg(s, rn);
10694 tmp2 = load_reg(s, rm);
10695 switch ((insn >> 20) & 7) {
10696 case 0: /* 32 x 32 -> 32 */
10697 tcg_gen_mul_i32(tmp, tmp, tmp2);
10698 tcg_temp_free_i32(tmp2);
10699 if (rs != 15) {
10700 tmp2 = load_reg(s, rs);
10701 if (op)
10702 tcg_gen_sub_i32(tmp, tmp2, tmp);
10703 else
10704 tcg_gen_add_i32(tmp, tmp, tmp2);
10705 tcg_temp_free_i32(tmp2);
10707 break;
10708 case 1: /* 16 x 16 -> 32 */
10709 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10710 tcg_temp_free_i32(tmp2);
10711 if (rs != 15) {
10712 tmp2 = load_reg(s, rs);
10713 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10714 tcg_temp_free_i32(tmp2);
10716 break;
10717 case 2: /* Dual multiply add. */
10718 case 4: /* Dual multiply subtract. */
10719 if (op)
10720 gen_swap_half(tmp2);
10721 gen_smul_dual(tmp, tmp2);
10722 if (insn & (1 << 22)) {
10723 /* This subtraction cannot overflow. */
10724 tcg_gen_sub_i32(tmp, tmp, tmp2);
10725 } else {
10726 /* This addition cannot overflow 32 bits;
10727 * however it may overflow considered as a signed
10728 * operation, in which case we must set the Q flag.
10730 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10732 tcg_temp_free_i32(tmp2);
10733 if (rs != 15)
10735 tmp2 = load_reg(s, rs);
10736 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10737 tcg_temp_free_i32(tmp2);
10739 break;
10740 case 3: /* 32 * 16 -> 32msb */
10741 if (op)
10742 tcg_gen_sari_i32(tmp2, tmp2, 16);
10743 else
10744 gen_sxth(tmp2);
10745 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10746 tcg_gen_shri_i64(tmp64, tmp64, 16);
10747 tmp = tcg_temp_new_i32();
10748 tcg_gen_extrl_i64_i32(tmp, tmp64);
10749 tcg_temp_free_i64(tmp64);
10750 if (rs != 15)
10752 tmp2 = load_reg(s, rs);
10753 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10754 tcg_temp_free_i32(tmp2);
10756 break;
10757 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10758 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10759 if (rs != 15) {
10760 tmp = load_reg(s, rs);
10761 if (insn & (1 << 20)) {
10762 tmp64 = gen_addq_msw(tmp64, tmp);
10763 } else {
10764 tmp64 = gen_subq_msw(tmp64, tmp);
10767 if (insn & (1 << 4)) {
10768 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10770 tcg_gen_shri_i64(tmp64, tmp64, 32);
10771 tmp = tcg_temp_new_i32();
10772 tcg_gen_extrl_i64_i32(tmp, tmp64);
10773 tcg_temp_free_i64(tmp64);
10774 break;
10775 case 7: /* Unsigned sum of absolute differences. */
10776 gen_helper_usad8(tmp, tmp, tmp2);
10777 tcg_temp_free_i32(tmp2);
10778 if (rs != 15) {
10779 tmp2 = load_reg(s, rs);
10780 tcg_gen_add_i32(tmp, tmp, tmp2);
10781 tcg_temp_free_i32(tmp2);
10783 break;
10785 store_reg(s, rd, tmp);
10786 break;
10787 case 6: case 7: /* 64-bit multiply, Divide. */
10788 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10789 tmp = load_reg(s, rn);
10790 tmp2 = load_reg(s, rm);
10791 if ((op & 0x50) == 0x10) {
10792 /* sdiv, udiv */
10793 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10794 goto illegal_op;
10796 if (op & 0x20)
10797 gen_helper_udiv(tmp, tmp, tmp2);
10798 else
10799 gen_helper_sdiv(tmp, tmp, tmp2);
10800 tcg_temp_free_i32(tmp2);
10801 store_reg(s, rd, tmp);
10802 } else if ((op & 0xe) == 0xc) {
10803 /* Dual multiply accumulate long. */
10804 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10805 tcg_temp_free_i32(tmp);
10806 tcg_temp_free_i32(tmp2);
10807 goto illegal_op;
10809 if (op & 1)
10810 gen_swap_half(tmp2);
10811 gen_smul_dual(tmp, tmp2);
10812 if (op & 0x10) {
10813 tcg_gen_sub_i32(tmp, tmp, tmp2);
10814 } else {
10815 tcg_gen_add_i32(tmp, tmp, tmp2);
10817 tcg_temp_free_i32(tmp2);
10818 /* BUGFIX */
10819 tmp64 = tcg_temp_new_i64();
10820 tcg_gen_ext_i32_i64(tmp64, tmp);
10821 tcg_temp_free_i32(tmp);
10822 gen_addq(s, tmp64, rs, rd);
10823 gen_storeq_reg(s, rs, rd, tmp64);
10824 tcg_temp_free_i64(tmp64);
10825 } else {
10826 if (op & 0x20) {
10827 /* Unsigned 64-bit multiply */
10828 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10829 } else {
10830 if (op & 8) {
10831 /* smlalxy */
10832 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10833 tcg_temp_free_i32(tmp2);
10834 tcg_temp_free_i32(tmp);
10835 goto illegal_op;
10837 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10838 tcg_temp_free_i32(tmp2);
10839 tmp64 = tcg_temp_new_i64();
10840 tcg_gen_ext_i32_i64(tmp64, tmp);
10841 tcg_temp_free_i32(tmp);
10842 } else {
10843 /* Signed 64-bit multiply */
10844 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10847 if (op & 4) {
10848 /* umaal */
10849 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10850 tcg_temp_free_i64(tmp64);
10851 goto illegal_op;
10853 gen_addq_lo(s, tmp64, rs);
10854 gen_addq_lo(s, tmp64, rd);
10855 } else if (op & 0x40) {
10856 /* 64-bit accumulate. */
10857 gen_addq(s, tmp64, rs, rd);
10859 gen_storeq_reg(s, rs, rd, tmp64);
10860 tcg_temp_free_i64(tmp64);
10862 break;
10864 break;
10865 case 6: case 7: case 14: case 15:
10866 /* Coprocessor. */
10867 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10868 /* We don't currently implement M profile FP support,
10869 * so this entire space should give a NOCP fault, with
10870 * the exception of the v8M VLLDM and VLSTM insns, which
10871 * must be NOPs in Secure state and UNDEF in Nonsecure state.
10873 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10874 (insn & 0xffa00f00) == 0xec200a00) {
10875 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10876 * - VLLDM, VLSTM
10877 * We choose to UNDEF if the RAZ bits are non-zero.
10879 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10880 goto illegal_op;
10882 /* Just NOP since FP support is not implemented */
10883 break;
10885 /* All other insns: NOCP */
10886 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10887 default_exception_el(s));
10888 break;
10890 if ((insn & 0xfe000a00) == 0xfc000800
10891 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10892 /* The Thumb2 and ARM encodings are identical. */
10893 if (disas_neon_insn_3same_ext(s, insn)) {
10894 goto illegal_op;
10896 } else if ((insn & 0xff000a00) == 0xfe000800
10897 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10898 /* The Thumb2 and ARM encodings are identical. */
10899 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10900 goto illegal_op;
10902 } else if (((insn >> 24) & 3) == 3) {
10903 /* Translate into the equivalent ARM encoding. */
10904 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10905 if (disas_neon_data_insn(s, insn)) {
10906 goto illegal_op;
10908 } else if (((insn >> 8) & 0xe) == 10) {
10909 if (disas_vfp_insn(s, insn)) {
10910 goto illegal_op;
10912 } else {
10913 if (insn & (1 << 28))
10914 goto illegal_op;
10915 if (disas_coproc_insn(s, insn)) {
10916 goto illegal_op;
10919 break;
10920 case 8: case 9: case 10: case 11:
10921 if (insn & (1 << 15)) {
10922 /* Branches, misc control. */
10923 if (insn & 0x5000) {
10924 /* Unconditional branch. */
10925 /* signextend(hw1[10:0]) -> offset[:12]. */
10926 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10927 /* hw1[10:0] -> offset[11:1]. */
10928 offset |= (insn & 0x7ff) << 1;
10929 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10930 offset[24:22] already have the same value because of the
10931 sign extension above. */
10932 offset ^= ((~insn) & (1 << 13)) << 10;
10933 offset ^= ((~insn) & (1 << 11)) << 11;
10935 if (insn & (1 << 14)) {
10936 /* Branch and link. */
10937 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10940 offset += s->pc;
10941 if (insn & (1 << 12)) {
10942 /* b/bl */
10943 gen_jmp(s, offset);
10944 } else {
10945 /* blx */
10946 offset &= ~(uint32_t)2;
10947 /* thumb2 bx, no need to check */
10948 gen_bx_im(s, offset);
10950 } else if (((insn >> 23) & 7) == 7) {
10951 /* Misc control */
10952 if (insn & (1 << 13))
10953 goto illegal_op;
10955 if (insn & (1 << 26)) {
10956 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10957 goto illegal_op;
10959 if (!(insn & (1 << 20))) {
10960 /* Hypervisor call (v7) */
10961 int imm16 = extract32(insn, 16, 4) << 12
10962 | extract32(insn, 0, 12);
10963 ARCH(7);
10964 if (IS_USER(s)) {
10965 goto illegal_op;
10967 gen_hvc(s, imm16);
10968 } else {
10969 /* Secure monitor call (v6+) */
10970 ARCH(6K);
10971 if (IS_USER(s)) {
10972 goto illegal_op;
10974 gen_smc(s);
10976 } else {
10977 op = (insn >> 20) & 7;
10978 switch (op) {
10979 case 0: /* msr cpsr. */
10980 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10981 tmp = load_reg(s, rn);
10982 /* the constant is the mask and SYSm fields */
10983 addr = tcg_const_i32(insn & 0xfff);
10984 gen_helper_v7m_msr(cpu_env, addr, tmp);
10985 tcg_temp_free_i32(addr);
10986 tcg_temp_free_i32(tmp);
10987 gen_lookup_tb(s);
10988 break;
10990 /* fall through */
10991 case 1: /* msr spsr. */
10992 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10993 goto illegal_op;
10996 if (extract32(insn, 5, 1)) {
10997 /* MSR (banked) */
10998 int sysm = extract32(insn, 8, 4) |
10999 (extract32(insn, 4, 1) << 4);
11000 int r = op & 1;
11002 gen_msr_banked(s, r, sysm, rm);
11003 break;
11006 /* MSR (for PSRs) */
11007 tmp = load_reg(s, rn);
11008 if (gen_set_psr(s,
11009 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11010 op == 1, tmp))
11011 goto illegal_op;
11012 break;
11013 case 2: /* cps, nop-hint. */
11014 if (((insn >> 8) & 7) == 0) {
11015 gen_nop_hint(s, insn & 0xff);
11017 /* Implemented as NOP in user mode. */
11018 if (IS_USER(s))
11019 break;
11020 offset = 0;
11021 imm = 0;
11022 if (insn & (1 << 10)) {
11023 if (insn & (1 << 7))
11024 offset |= CPSR_A;
11025 if (insn & (1 << 6))
11026 offset |= CPSR_I;
11027 if (insn & (1 << 5))
11028 offset |= CPSR_F;
11029 if (insn & (1 << 9))
11030 imm = CPSR_A | CPSR_I | CPSR_F;
11032 if (insn & (1 << 8)) {
11033 offset |= 0x1f;
11034 imm |= (insn & 0x1f);
11036 if (offset) {
11037 gen_set_psr_im(s, offset, 0, imm);
11039 break;
11040 case 3: /* Special control operations. */
11041 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11042 !(arm_dc_feature(s, ARM_FEATURE_V6) &&
11043 arm_dc_feature(s, ARM_FEATURE_M))) {
11044 goto illegal_op;
11046 op = (insn >> 4) & 0xf;
11047 switch (op) {
11048 case 2: /* clrex */
11049 gen_clrex(s);
11050 break;
11051 case 4: /* dsb */
11052 case 5: /* dmb */
11053 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11054 break;
11055 case 6: /* isb */
11056 /* We need to break the TB after this insn
11057 * to execute self-modifying code correctly
11058 * and also to take any pending interrupts
11059 * immediately.
11061 gen_goto_tb(s, 0, s->pc & ~1);
11062 break;
11063 default:
11064 goto illegal_op;
11066 break;
11067 case 4: /* bxj */
11068 /* Trivial implementation equivalent to bx.
11069 * This instruction doesn't exist at all for M-profile.
11071 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11072 goto illegal_op;
11074 tmp = load_reg(s, rn);
11075 gen_bx(s, tmp);
11076 break;
11077 case 5: /* Exception return. */
11078 if (IS_USER(s)) {
11079 goto illegal_op;
11081 if (rn != 14 || rd != 15) {
11082 goto illegal_op;
11084 tmp = load_reg(s, rn);
11085 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11086 gen_exception_return(s, tmp);
11087 break;
11088 case 6: /* MRS */
11089 if (extract32(insn, 5, 1) &&
11090 !arm_dc_feature(s, ARM_FEATURE_M)) {
11091 /* MRS (banked) */
11092 int sysm = extract32(insn, 16, 4) |
11093 (extract32(insn, 4, 1) << 4);
11095 gen_mrs_banked(s, 0, sysm, rd);
11096 break;
11099 if (extract32(insn, 16, 4) != 0xf) {
11100 goto illegal_op;
11102 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11103 extract32(insn, 0, 8) != 0) {
11104 goto illegal_op;
11107 /* mrs cpsr */
11108 tmp = tcg_temp_new_i32();
11109 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11110 addr = tcg_const_i32(insn & 0xff);
11111 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11112 tcg_temp_free_i32(addr);
11113 } else {
11114 gen_helper_cpsr_read(tmp, cpu_env);
11116 store_reg(s, rd, tmp);
11117 break;
11118 case 7: /* MRS */
11119 if (extract32(insn, 5, 1) &&
11120 !arm_dc_feature(s, ARM_FEATURE_M)) {
11121 /* MRS (banked) */
11122 int sysm = extract32(insn, 16, 4) |
11123 (extract32(insn, 4, 1) << 4);
11125 gen_mrs_banked(s, 1, sysm, rd);
11126 break;
11129 /* mrs spsr. */
11130 /* Not accessible in user mode. */
11131 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11132 goto illegal_op;
11135 if (extract32(insn, 16, 4) != 0xf ||
11136 extract32(insn, 0, 8) != 0) {
11137 goto illegal_op;
11140 tmp = load_cpu_field(spsr);
11141 store_reg(s, rd, tmp);
11142 break;
11145 } else {
11146 /* Conditional branch. */
11147 op = (insn >> 22) & 0xf;
11148 /* Generate a conditional jump to next instruction. */
11149 s->condlabel = gen_new_label();
11150 arm_gen_test_cc(op ^ 1, s->condlabel);
11151 s->condjmp = 1;
11153 /* offset[11:1] = insn[10:0] */
11154 offset = (insn & 0x7ff) << 1;
11155 /* offset[17:12] = insn[21:16]. */
11156 offset |= (insn & 0x003f0000) >> 4;
11157 /* offset[31:20] = insn[26]. */
11158 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11159 /* offset[18] = insn[13]. */
11160 offset |= (insn & (1 << 13)) << 5;
11161 /* offset[19] = insn[11]. */
11162 offset |= (insn & (1 << 11)) << 8;
11164 /* jump to the offset */
11165 gen_jmp(s, s->pc + offset);
11167 } else {
11168 /* Data processing immediate. */
11169 if (insn & (1 << 25)) {
11170 if (insn & (1 << 24)) {
11171 if (insn & (1 << 20))
11172 goto illegal_op;
11173 /* Bitfield/Saturate. */
11174 op = (insn >> 21) & 7;
11175 imm = insn & 0x1f;
11176 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11177 if (rn == 15) {
11178 tmp = tcg_temp_new_i32();
11179 tcg_gen_movi_i32(tmp, 0);
11180 } else {
11181 tmp = load_reg(s, rn);
11183 switch (op) {
11184 case 2: /* Signed bitfield extract. */
11185 imm++;
11186 if (shift + imm > 32)
11187 goto illegal_op;
11188 if (imm < 32) {
11189 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11191 break;
11192 case 6: /* Unsigned bitfield extract. */
11193 imm++;
11194 if (shift + imm > 32)
11195 goto illegal_op;
11196 if (imm < 32) {
11197 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11199 break;
11200 case 3: /* Bitfield insert/clear. */
11201 if (imm < shift)
11202 goto illegal_op;
11203 imm = imm + 1 - shift;
11204 if (imm != 32) {
11205 tmp2 = load_reg(s, rd);
11206 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11207 tcg_temp_free_i32(tmp2);
11209 break;
11210 case 7:
11211 goto illegal_op;
11212 default: /* Saturate. */
11213 if (shift) {
11214 if (op & 1)
11215 tcg_gen_sari_i32(tmp, tmp, shift);
11216 else
11217 tcg_gen_shli_i32(tmp, tmp, shift);
11219 tmp2 = tcg_const_i32(imm);
11220 if (op & 4) {
11221 /* Unsigned. */
11222 if ((op & 1) && shift == 0) {
11223 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11224 tcg_temp_free_i32(tmp);
11225 tcg_temp_free_i32(tmp2);
11226 goto illegal_op;
11228 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11229 } else {
11230 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11232 } else {
11233 /* Signed. */
11234 if ((op & 1) && shift == 0) {
11235 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11236 tcg_temp_free_i32(tmp);
11237 tcg_temp_free_i32(tmp2);
11238 goto illegal_op;
11240 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11241 } else {
11242 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11245 tcg_temp_free_i32(tmp2);
11246 break;
11248 store_reg(s, rd, tmp);
11249 } else {
11250 imm = ((insn & 0x04000000) >> 15)
11251 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11252 if (insn & (1 << 22)) {
11253 /* 16-bit immediate. */
11254 imm |= (insn >> 4) & 0xf000;
11255 if (insn & (1 << 23)) {
11256 /* movt */
11257 tmp = load_reg(s, rd);
11258 tcg_gen_ext16u_i32(tmp, tmp);
11259 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11260 } else {
11261 /* movw */
11262 tmp = tcg_temp_new_i32();
11263 tcg_gen_movi_i32(tmp, imm);
11265 } else {
11266 /* Add/sub 12-bit immediate. */
11267 if (rn == 15) {
11268 offset = s->pc & ~(uint32_t)3;
11269 if (insn & (1 << 23))
11270 offset -= imm;
11271 else
11272 offset += imm;
11273 tmp = tcg_temp_new_i32();
11274 tcg_gen_movi_i32(tmp, offset);
11275 } else {
11276 tmp = load_reg(s, rn);
11277 if (insn & (1 << 23))
11278 tcg_gen_subi_i32(tmp, tmp, imm);
11279 else
11280 tcg_gen_addi_i32(tmp, tmp, imm);
11283 store_reg(s, rd, tmp);
11285 } else {
11286 int shifter_out = 0;
11287 /* modified 12-bit immediate. */
11288 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11289 imm = (insn & 0xff);
11290 switch (shift) {
11291 case 0: /* XY */
11292 /* Nothing to do. */
11293 break;
11294 case 1: /* 00XY00XY */
11295 imm |= imm << 16;
11296 break;
11297 case 2: /* XY00XY00 */
11298 imm |= imm << 16;
11299 imm <<= 8;
11300 break;
11301 case 3: /* XYXYXYXY */
11302 imm |= imm << 16;
11303 imm |= imm << 8;
11304 break;
11305 default: /* Rotated constant. */
11306 shift = (shift << 1) | (imm >> 7);
11307 imm |= 0x80;
11308 imm = imm << (32 - shift);
11309 shifter_out = 1;
11310 break;
11312 tmp2 = tcg_temp_new_i32();
11313 tcg_gen_movi_i32(tmp2, imm);
11314 rn = (insn >> 16) & 0xf;
11315 if (rn == 15) {
11316 tmp = tcg_temp_new_i32();
11317 tcg_gen_movi_i32(tmp, 0);
11318 } else {
11319 tmp = load_reg(s, rn);
11321 op = (insn >> 21) & 0xf;
11322 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11323 shifter_out, tmp, tmp2))
11324 goto illegal_op;
11325 tcg_temp_free_i32(tmp2);
11326 rd = (insn >> 8) & 0xf;
11327 if (rd != 15) {
11328 store_reg(s, rd, tmp);
11329 } else {
11330 tcg_temp_free_i32(tmp);
11334 break;
11335 case 12: /* Load/store single data item. */
11337 int postinc = 0;
11338 int writeback = 0;
11339 int memidx;
11340 ISSInfo issinfo;
11342 if ((insn & 0x01100000) == 0x01000000) {
11343 if (disas_neon_ls_insn(s, insn)) {
11344 goto illegal_op;
11346 break;
11348 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11349 if (rs == 15) {
11350 if (!(insn & (1 << 20))) {
11351 goto illegal_op;
11353 if (op != 2) {
11354 /* Byte or halfword load space with dest == r15 : memory hints.
11355 * Catch them early so we don't emit pointless addressing code.
11356 * This space is a mix of:
11357 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11358 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11359 * cores)
11360 * unallocated hints, which must be treated as NOPs
11361 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11362 * which is easiest for the decoding logic
11363 * Some space which must UNDEF
11365 int op1 = (insn >> 23) & 3;
11366 int op2 = (insn >> 6) & 0x3f;
11367 if (op & 2) {
11368 goto illegal_op;
11370 if (rn == 15) {
11371 /* UNPREDICTABLE, unallocated hint or
11372 * PLD/PLDW/PLI (literal)
11374 return;
11376 if (op1 & 1) {
11377 return; /* PLD/PLDW/PLI or unallocated hint */
11379 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11380 return; /* PLD/PLDW/PLI or unallocated hint */
11382 /* UNDEF space, or an UNPREDICTABLE */
11383 goto illegal_op;
11386 memidx = get_mem_index(s);
11387 if (rn == 15) {
11388 addr = tcg_temp_new_i32();
11389 /* PC relative. */
11390 /* s->pc has already been incremented by 4. */
11391 imm = s->pc & 0xfffffffc;
11392 if (insn & (1 << 23))
11393 imm += insn & 0xfff;
11394 else
11395 imm -= insn & 0xfff;
11396 tcg_gen_movi_i32(addr, imm);
11397 } else {
11398 addr = load_reg(s, rn);
11399 if (insn & (1 << 23)) {
11400 /* Positive offset. */
11401 imm = insn & 0xfff;
11402 tcg_gen_addi_i32(addr, addr, imm);
11403 } else {
11404 imm = insn & 0xff;
11405 switch ((insn >> 8) & 0xf) {
11406 case 0x0: /* Shifted Register. */
11407 shift = (insn >> 4) & 0xf;
11408 if (shift > 3) {
11409 tcg_temp_free_i32(addr);
11410 goto illegal_op;
11412 tmp = load_reg(s, rm);
11413 if (shift)
11414 tcg_gen_shli_i32(tmp, tmp, shift);
11415 tcg_gen_add_i32(addr, addr, tmp);
11416 tcg_temp_free_i32(tmp);
11417 break;
11418 case 0xc: /* Negative offset. */
11419 tcg_gen_addi_i32(addr, addr, -imm);
11420 break;
11421 case 0xe: /* User privilege. */
11422 tcg_gen_addi_i32(addr, addr, imm);
11423 memidx = get_a32_user_mem_index(s);
11424 break;
11425 case 0x9: /* Post-decrement. */
11426 imm = -imm;
11427 /* Fall through. */
11428 case 0xb: /* Post-increment. */
11429 postinc = 1;
11430 writeback = 1;
11431 break;
11432 case 0xd: /* Pre-decrement. */
11433 imm = -imm;
11434 /* Fall through. */
11435 case 0xf: /* Pre-increment. */
11436 tcg_gen_addi_i32(addr, addr, imm);
11437 writeback = 1;
11438 break;
11439 default:
11440 tcg_temp_free_i32(addr);
11441 goto illegal_op;
11446 issinfo = writeback ? ISSInvalid : rs;
11448 if (insn & (1 << 20)) {
11449 /* Load. */
11450 tmp = tcg_temp_new_i32();
11451 switch (op) {
11452 case 0:
11453 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11454 break;
11455 case 4:
11456 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11457 break;
11458 case 1:
11459 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11460 break;
11461 case 5:
11462 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11463 break;
11464 case 2:
11465 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11466 break;
11467 default:
11468 tcg_temp_free_i32(tmp);
11469 tcg_temp_free_i32(addr);
11470 goto illegal_op;
11472 if (rs == 15) {
11473 gen_bx_excret(s, tmp);
11474 } else {
11475 store_reg(s, rs, tmp);
11477 } else {
11478 /* Store. */
11479 tmp = load_reg(s, rs);
11480 switch (op) {
11481 case 0:
11482 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11483 break;
11484 case 1:
11485 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11486 break;
11487 case 2:
11488 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11489 break;
11490 default:
11491 tcg_temp_free_i32(tmp);
11492 tcg_temp_free_i32(addr);
11493 goto illegal_op;
11495 tcg_temp_free_i32(tmp);
11497 if (postinc)
11498 tcg_gen_addi_i32(addr, addr, imm);
11499 if (writeback) {
11500 store_reg(s, rn, addr);
11501 } else {
11502 tcg_temp_free_i32(addr);
11505 break;
11506 default:
11507 goto illegal_op;
11509 return;
11510 illegal_op:
11511 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11512 default_exception_el(s));
11515 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11517 uint32_t val, op, rm, rn, rd, shift, cond;
11518 int32_t offset;
11519 int i;
11520 TCGv_i32 tmp;
11521 TCGv_i32 tmp2;
11522 TCGv_i32 addr;
11524 switch (insn >> 12) {
11525 case 0: case 1:
11527 rd = insn & 7;
11528 op = (insn >> 11) & 3;
11529 if (op == 3) {
11530 /* add/subtract */
11531 rn = (insn >> 3) & 7;
11532 tmp = load_reg(s, rn);
11533 if (insn & (1 << 10)) {
11534 /* immediate */
11535 tmp2 = tcg_temp_new_i32();
11536 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11537 } else {
11538 /* reg */
11539 rm = (insn >> 6) & 7;
11540 tmp2 = load_reg(s, rm);
11542 if (insn & (1 << 9)) {
11543 if (s->condexec_mask)
11544 tcg_gen_sub_i32(tmp, tmp, tmp2);
11545 else
11546 gen_sub_CC(tmp, tmp, tmp2);
11547 } else {
11548 if (s->condexec_mask)
11549 tcg_gen_add_i32(tmp, tmp, tmp2);
11550 else
11551 gen_add_CC(tmp, tmp, tmp2);
11553 tcg_temp_free_i32(tmp2);
11554 store_reg(s, rd, tmp);
11555 } else {
11556 /* shift immediate */
11557 rm = (insn >> 3) & 7;
11558 shift = (insn >> 6) & 0x1f;
11559 tmp = load_reg(s, rm);
11560 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11561 if (!s->condexec_mask)
11562 gen_logic_CC(tmp);
11563 store_reg(s, rd, tmp);
11565 break;
11566 case 2: case 3:
11567 /* arithmetic large immediate */
11568 op = (insn >> 11) & 3;
11569 rd = (insn >> 8) & 0x7;
11570 if (op == 0) { /* mov */
11571 tmp = tcg_temp_new_i32();
11572 tcg_gen_movi_i32(tmp, insn & 0xff);
11573 if (!s->condexec_mask)
11574 gen_logic_CC(tmp);
11575 store_reg(s, rd, tmp);
11576 } else {
11577 tmp = load_reg(s, rd);
11578 tmp2 = tcg_temp_new_i32();
11579 tcg_gen_movi_i32(tmp2, insn & 0xff);
11580 switch (op) {
11581 case 1: /* cmp */
11582 gen_sub_CC(tmp, tmp, tmp2);
11583 tcg_temp_free_i32(tmp);
11584 tcg_temp_free_i32(tmp2);
11585 break;
11586 case 2: /* add */
11587 if (s->condexec_mask)
11588 tcg_gen_add_i32(tmp, tmp, tmp2);
11589 else
11590 gen_add_CC(tmp, tmp, tmp2);
11591 tcg_temp_free_i32(tmp2);
11592 store_reg(s, rd, tmp);
11593 break;
11594 case 3: /* sub */
11595 if (s->condexec_mask)
11596 tcg_gen_sub_i32(tmp, tmp, tmp2);
11597 else
11598 gen_sub_CC(tmp, tmp, tmp2);
11599 tcg_temp_free_i32(tmp2);
11600 store_reg(s, rd, tmp);
11601 break;
11604 break;
11605 case 4:
11606 if (insn & (1 << 11)) {
11607 rd = (insn >> 8) & 7;
11608 /* load pc-relative. Bit 1 of PC is ignored. */
11609 val = s->pc + 2 + ((insn & 0xff) * 4);
11610 val &= ~(uint32_t)2;
11611 addr = tcg_temp_new_i32();
11612 tcg_gen_movi_i32(addr, val);
11613 tmp = tcg_temp_new_i32();
11614 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11615 rd | ISSIs16Bit);
11616 tcg_temp_free_i32(addr);
11617 store_reg(s, rd, tmp);
11618 break;
11620 if (insn & (1 << 10)) {
11621 /* 0b0100_01xx_xxxx_xxxx
11622 * - data processing extended, branch and exchange
11624 rd = (insn & 7) | ((insn >> 4) & 8);
11625 rm = (insn >> 3) & 0xf;
11626 op = (insn >> 8) & 3;
11627 switch (op) {
11628 case 0: /* add */
11629 tmp = load_reg(s, rd);
11630 tmp2 = load_reg(s, rm);
11631 tcg_gen_add_i32(tmp, tmp, tmp2);
11632 tcg_temp_free_i32(tmp2);
11633 store_reg(s, rd, tmp);
11634 break;
11635 case 1: /* cmp */
11636 tmp = load_reg(s, rd);
11637 tmp2 = load_reg(s, rm);
11638 gen_sub_CC(tmp, tmp, tmp2);
11639 tcg_temp_free_i32(tmp2);
11640 tcg_temp_free_i32(tmp);
11641 break;
11642 case 2: /* mov/cpy */
11643 tmp = load_reg(s, rm);
11644 store_reg(s, rd, tmp);
11645 break;
11646 case 3:
11648 /* 0b0100_0111_xxxx_xxxx
11649 * - branch [and link] exchange thumb register
11651 bool link = insn & (1 << 7);
11653 if (insn & 3) {
11654 goto undef;
11656 if (link) {
11657 ARCH(5);
11659 if ((insn & 4)) {
11660 /* BXNS/BLXNS: only exists for v8M with the
11661 * security extensions, and always UNDEF if NonSecure.
11662 * We don't implement these in the user-only mode
11663 * either (in theory you can use them from Secure User
11664 * mode but they are too tied in to system emulation.)
11666 if (!s->v8m_secure || IS_USER_ONLY) {
11667 goto undef;
11669 if (link) {
11670 gen_blxns(s, rm);
11671 } else {
11672 gen_bxns(s, rm);
11674 break;
11676 /* BLX/BX */
11677 tmp = load_reg(s, rm);
11678 if (link) {
11679 val = (uint32_t)s->pc | 1;
11680 tmp2 = tcg_temp_new_i32();
11681 tcg_gen_movi_i32(tmp2, val);
11682 store_reg(s, 14, tmp2);
11683 gen_bx(s, tmp);
11684 } else {
11685 /* Only BX works as exception-return, not BLX */
11686 gen_bx_excret(s, tmp);
11688 break;
11691 break;
11694 /* data processing register */
11695 rd = insn & 7;
11696 rm = (insn >> 3) & 7;
11697 op = (insn >> 6) & 0xf;
11698 if (op == 2 || op == 3 || op == 4 || op == 7) {
11699 /* the shift/rotate ops want the operands backwards */
11700 val = rm;
11701 rm = rd;
11702 rd = val;
11703 val = 1;
11704 } else {
11705 val = 0;
11708 if (op == 9) { /* neg */
11709 tmp = tcg_temp_new_i32();
11710 tcg_gen_movi_i32(tmp, 0);
11711 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11712 tmp = load_reg(s, rd);
11713 } else {
11714 tmp = NULL;
11717 tmp2 = load_reg(s, rm);
11718 switch (op) {
11719 case 0x0: /* and */
11720 tcg_gen_and_i32(tmp, tmp, tmp2);
11721 if (!s->condexec_mask)
11722 gen_logic_CC(tmp);
11723 break;
11724 case 0x1: /* eor */
11725 tcg_gen_xor_i32(tmp, tmp, tmp2);
11726 if (!s->condexec_mask)
11727 gen_logic_CC(tmp);
11728 break;
11729 case 0x2: /* lsl */
11730 if (s->condexec_mask) {
11731 gen_shl(tmp2, tmp2, tmp);
11732 } else {
11733 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11734 gen_logic_CC(tmp2);
11736 break;
11737 case 0x3: /* lsr */
11738 if (s->condexec_mask) {
11739 gen_shr(tmp2, tmp2, tmp);
11740 } else {
11741 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11742 gen_logic_CC(tmp2);
11744 break;
11745 case 0x4: /* asr */
11746 if (s->condexec_mask) {
11747 gen_sar(tmp2, tmp2, tmp);
11748 } else {
11749 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11750 gen_logic_CC(tmp2);
11752 break;
11753 case 0x5: /* adc */
11754 if (s->condexec_mask) {
11755 gen_adc(tmp, tmp2);
11756 } else {
11757 gen_adc_CC(tmp, tmp, tmp2);
11759 break;
11760 case 0x6: /* sbc */
11761 if (s->condexec_mask) {
11762 gen_sub_carry(tmp, tmp, tmp2);
11763 } else {
11764 gen_sbc_CC(tmp, tmp, tmp2);
11766 break;
11767 case 0x7: /* ror */
11768 if (s->condexec_mask) {
11769 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11770 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11771 } else {
11772 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11773 gen_logic_CC(tmp2);
11775 break;
11776 case 0x8: /* tst */
11777 tcg_gen_and_i32(tmp, tmp, tmp2);
11778 gen_logic_CC(tmp);
11779 rd = 16;
11780 break;
11781 case 0x9: /* neg */
11782 if (s->condexec_mask)
11783 tcg_gen_neg_i32(tmp, tmp2);
11784 else
11785 gen_sub_CC(tmp, tmp, tmp2);
11786 break;
11787 case 0xa: /* cmp */
11788 gen_sub_CC(tmp, tmp, tmp2);
11789 rd = 16;
11790 break;
11791 case 0xb: /* cmn */
11792 gen_add_CC(tmp, tmp, tmp2);
11793 rd = 16;
11794 break;
11795 case 0xc: /* orr */
11796 tcg_gen_or_i32(tmp, tmp, tmp2);
11797 if (!s->condexec_mask)
11798 gen_logic_CC(tmp);
11799 break;
11800 case 0xd: /* mul */
11801 tcg_gen_mul_i32(tmp, tmp, tmp2);
11802 if (!s->condexec_mask)
11803 gen_logic_CC(tmp);
11804 break;
11805 case 0xe: /* bic */
11806 tcg_gen_andc_i32(tmp, tmp, tmp2);
11807 if (!s->condexec_mask)
11808 gen_logic_CC(tmp);
11809 break;
11810 case 0xf: /* mvn */
11811 tcg_gen_not_i32(tmp2, tmp2);
11812 if (!s->condexec_mask)
11813 gen_logic_CC(tmp2);
11814 val = 1;
11815 rm = rd;
11816 break;
11818 if (rd != 16) {
11819 if (val) {
11820 store_reg(s, rm, tmp2);
11821 if (op != 0xf)
11822 tcg_temp_free_i32(tmp);
11823 } else {
11824 store_reg(s, rd, tmp);
11825 tcg_temp_free_i32(tmp2);
11827 } else {
11828 tcg_temp_free_i32(tmp);
11829 tcg_temp_free_i32(tmp2);
11831 break;
11833 case 5:
11834 /* load/store register offset. */
11835 rd = insn & 7;
11836 rn = (insn >> 3) & 7;
11837 rm = (insn >> 6) & 7;
11838 op = (insn >> 9) & 7;
11839 addr = load_reg(s, rn);
11840 tmp = load_reg(s, rm);
11841 tcg_gen_add_i32(addr, addr, tmp);
11842 tcg_temp_free_i32(tmp);
11844 if (op < 3) { /* store */
11845 tmp = load_reg(s, rd);
11846 } else {
11847 tmp = tcg_temp_new_i32();
11850 switch (op) {
11851 case 0: /* str */
11852 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11853 break;
11854 case 1: /* strh */
11855 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11856 break;
11857 case 2: /* strb */
11858 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11859 break;
11860 case 3: /* ldrsb */
11861 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11862 break;
11863 case 4: /* ldr */
11864 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11865 break;
11866 case 5: /* ldrh */
11867 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11868 break;
11869 case 6: /* ldrb */
11870 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11871 break;
11872 case 7: /* ldrsh */
11873 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11874 break;
11876 if (op >= 3) { /* load */
11877 store_reg(s, rd, tmp);
11878 } else {
11879 tcg_temp_free_i32(tmp);
11881 tcg_temp_free_i32(addr);
11882 break;
11884 case 6:
11885 /* load/store word immediate offset */
11886 rd = insn & 7;
11887 rn = (insn >> 3) & 7;
11888 addr = load_reg(s, rn);
11889 val = (insn >> 4) & 0x7c;
11890 tcg_gen_addi_i32(addr, addr, val);
11892 if (insn & (1 << 11)) {
11893 /* load */
11894 tmp = tcg_temp_new_i32();
11895 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11896 store_reg(s, rd, tmp);
11897 } else {
11898 /* store */
11899 tmp = load_reg(s, rd);
11900 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11901 tcg_temp_free_i32(tmp);
11903 tcg_temp_free_i32(addr);
11904 break;
11906 case 7:
11907 /* load/store byte immediate offset */
11908 rd = insn & 7;
11909 rn = (insn >> 3) & 7;
11910 addr = load_reg(s, rn);
11911 val = (insn >> 6) & 0x1f;
11912 tcg_gen_addi_i32(addr, addr, val);
11914 if (insn & (1 << 11)) {
11915 /* load */
11916 tmp = tcg_temp_new_i32();
11917 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11918 store_reg(s, rd, tmp);
11919 } else {
11920 /* store */
11921 tmp = load_reg(s, rd);
11922 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11923 tcg_temp_free_i32(tmp);
11925 tcg_temp_free_i32(addr);
11926 break;
11928 case 8:
11929 /* load/store halfword immediate offset */
11930 rd = insn & 7;
11931 rn = (insn >> 3) & 7;
11932 addr = load_reg(s, rn);
11933 val = (insn >> 5) & 0x3e;
11934 tcg_gen_addi_i32(addr, addr, val);
11936 if (insn & (1 << 11)) {
11937 /* load */
11938 tmp = tcg_temp_new_i32();
11939 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11940 store_reg(s, rd, tmp);
11941 } else {
11942 /* store */
11943 tmp = load_reg(s, rd);
11944 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11945 tcg_temp_free_i32(tmp);
11947 tcg_temp_free_i32(addr);
11948 break;
11950 case 9:
11951 /* load/store from stack */
11952 rd = (insn >> 8) & 7;
11953 addr = load_reg(s, 13);
11954 val = (insn & 0xff) * 4;
11955 tcg_gen_addi_i32(addr, addr, val);
11957 if (insn & (1 << 11)) {
11958 /* load */
11959 tmp = tcg_temp_new_i32();
11960 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11961 store_reg(s, rd, tmp);
11962 } else {
11963 /* store */
11964 tmp = load_reg(s, rd);
11965 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11966 tcg_temp_free_i32(tmp);
11968 tcg_temp_free_i32(addr);
11969 break;
11971 case 10:
11972 /* add to high reg */
11973 rd = (insn >> 8) & 7;
11974 if (insn & (1 << 11)) {
11975 /* SP */
11976 tmp = load_reg(s, 13);
11977 } else {
11978 /* PC. bit 1 is ignored. */
11979 tmp = tcg_temp_new_i32();
11980 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11982 val = (insn & 0xff) * 4;
11983 tcg_gen_addi_i32(tmp, tmp, val);
11984 store_reg(s, rd, tmp);
11985 break;
11987 case 11:
11988 /* misc */
11989 op = (insn >> 8) & 0xf;
11990 switch (op) {
11991 case 0:
11992 /* adjust stack pointer */
11993 tmp = load_reg(s, 13);
11994 val = (insn & 0x7f) * 4;
11995 if (insn & (1 << 7))
11996 val = -(int32_t)val;
11997 tcg_gen_addi_i32(tmp, tmp, val);
11998 store_reg(s, 13, tmp);
11999 break;
12001 case 2: /* sign/zero extend. */
12002 ARCH(6);
12003 rd = insn & 7;
12004 rm = (insn >> 3) & 7;
12005 tmp = load_reg(s, rm);
12006 switch ((insn >> 6) & 3) {
12007 case 0: gen_sxth(tmp); break;
12008 case 1: gen_sxtb(tmp); break;
12009 case 2: gen_uxth(tmp); break;
12010 case 3: gen_uxtb(tmp); break;
12012 store_reg(s, rd, tmp);
12013 break;
12014 case 4: case 5: case 0xc: case 0xd:
12015 /* push/pop */
12016 addr = load_reg(s, 13);
12017 if (insn & (1 << 8))
12018 offset = 4;
12019 else
12020 offset = 0;
12021 for (i = 0; i < 8; i++) {
12022 if (insn & (1 << i))
12023 offset += 4;
12025 if ((insn & (1 << 11)) == 0) {
12026 tcg_gen_addi_i32(addr, addr, -offset);
12028 for (i = 0; i < 8; i++) {
12029 if (insn & (1 << i)) {
12030 if (insn & (1 << 11)) {
12031 /* pop */
12032 tmp = tcg_temp_new_i32();
12033 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12034 store_reg(s, i, tmp);
12035 } else {
12036 /* push */
12037 tmp = load_reg(s, i);
12038 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12039 tcg_temp_free_i32(tmp);
12041 /* advance to the next address. */
12042 tcg_gen_addi_i32(addr, addr, 4);
12045 tmp = NULL;
12046 if (insn & (1 << 8)) {
12047 if (insn & (1 << 11)) {
12048 /* pop pc */
12049 tmp = tcg_temp_new_i32();
12050 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12051 /* don't set the pc until the rest of the instruction
12052 has completed */
12053 } else {
12054 /* push lr */
12055 tmp = load_reg(s, 14);
12056 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12057 tcg_temp_free_i32(tmp);
12059 tcg_gen_addi_i32(addr, addr, 4);
12061 if ((insn & (1 << 11)) == 0) {
12062 tcg_gen_addi_i32(addr, addr, -offset);
12064 /* write back the new stack pointer */
12065 store_reg(s, 13, addr);
12066 /* set the new PC value */
12067 if ((insn & 0x0900) == 0x0900) {
12068 store_reg_from_load(s, 15, tmp);
12070 break;
12072 case 1: case 3: case 9: case 11: /* czb */
12073 rm = insn & 7;
12074 tmp = load_reg(s, rm);
12075 s->condlabel = gen_new_label();
12076 s->condjmp = 1;
12077 if (insn & (1 << 11))
12078 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12079 else
12080 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12081 tcg_temp_free_i32(tmp);
12082 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12083 val = (uint32_t)s->pc + 2;
12084 val += offset;
12085 gen_jmp(s, val);
12086 break;
12088 case 15: /* IT, nop-hint. */
12089 if ((insn & 0xf) == 0) {
12090 gen_nop_hint(s, (insn >> 4) & 0xf);
12091 break;
12093 /* If Then. */
12094 s->condexec_cond = (insn >> 4) & 0xe;
12095 s->condexec_mask = insn & 0x1f;
12096 /* No actual code generated for this insn, just setup state. */
12097 break;
12099 case 0xe: /* bkpt */
12101 int imm8 = extract32(insn, 0, 8);
12102 ARCH(5);
12103 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12104 break;
12107 case 0xa: /* rev, and hlt */
12109 int op1 = extract32(insn, 6, 2);
12111 if (op1 == 2) {
12112 /* HLT */
12113 int imm6 = extract32(insn, 0, 6);
12115 gen_hlt(s, imm6);
12116 break;
12119 /* Otherwise this is rev */
12120 ARCH(6);
12121 rn = (insn >> 3) & 0x7;
12122 rd = insn & 0x7;
12123 tmp = load_reg(s, rn);
12124 switch (op1) {
12125 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12126 case 1: gen_rev16(tmp); break;
12127 case 3: gen_revsh(tmp); break;
12128 default:
12129 g_assert_not_reached();
12131 store_reg(s, rd, tmp);
12132 break;
12135 case 6:
12136 switch ((insn >> 5) & 7) {
12137 case 2:
12138 /* setend */
12139 ARCH(6);
12140 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12141 gen_helper_setend(cpu_env);
12142 s->base.is_jmp = DISAS_UPDATE;
12144 break;
12145 case 3:
12146 /* cps */
12147 ARCH(6);
12148 if (IS_USER(s)) {
12149 break;
12151 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12152 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12153 /* FAULTMASK */
12154 if (insn & 1) {
12155 addr = tcg_const_i32(19);
12156 gen_helper_v7m_msr(cpu_env, addr, tmp);
12157 tcg_temp_free_i32(addr);
12159 /* PRIMASK */
12160 if (insn & 2) {
12161 addr = tcg_const_i32(16);
12162 gen_helper_v7m_msr(cpu_env, addr, tmp);
12163 tcg_temp_free_i32(addr);
12165 tcg_temp_free_i32(tmp);
12166 gen_lookup_tb(s);
12167 } else {
12168 if (insn & (1 << 4)) {
12169 shift = CPSR_A | CPSR_I | CPSR_F;
12170 } else {
12171 shift = 0;
12173 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12175 break;
12176 default:
12177 goto undef;
12179 break;
12181 default:
12182 goto undef;
12184 break;
12186 case 12:
12188 /* load/store multiple */
12189 TCGv_i32 loaded_var = NULL;
12190 rn = (insn >> 8) & 0x7;
12191 addr = load_reg(s, rn);
12192 for (i = 0; i < 8; i++) {
12193 if (insn & (1 << i)) {
12194 if (insn & (1 << 11)) {
12195 /* load */
12196 tmp = tcg_temp_new_i32();
12197 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12198 if (i == rn) {
12199 loaded_var = tmp;
12200 } else {
12201 store_reg(s, i, tmp);
12203 } else {
12204 /* store */
12205 tmp = load_reg(s, i);
12206 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12207 tcg_temp_free_i32(tmp);
12209 /* advance to the next address */
12210 tcg_gen_addi_i32(addr, addr, 4);
12213 if ((insn & (1 << rn)) == 0) {
12214 /* base reg not in list: base register writeback */
12215 store_reg(s, rn, addr);
12216 } else {
12217 /* base reg in list: if load, complete it now */
12218 if (insn & (1 << 11)) {
12219 store_reg(s, rn, loaded_var);
12221 tcg_temp_free_i32(addr);
12223 break;
12225 case 13:
12226 /* conditional branch or swi */
12227 cond = (insn >> 8) & 0xf;
12228 if (cond == 0xe)
12229 goto undef;
12231 if (cond == 0xf) {
12232 /* swi */
12233 gen_set_pc_im(s, s->pc);
12234 s->svc_imm = extract32(insn, 0, 8);
12235 s->base.is_jmp = DISAS_SWI;
12236 break;
12238 /* generate a conditional jump to next instruction */
12239 s->condlabel = gen_new_label();
12240 arm_gen_test_cc(cond ^ 1, s->condlabel);
12241 s->condjmp = 1;
12243 /* jump to the offset */
12244 val = (uint32_t)s->pc + 2;
12245 offset = ((int32_t)insn << 24) >> 24;
12246 val += offset << 1;
12247 gen_jmp(s, val);
12248 break;
12250 case 14:
12251 if (insn & (1 << 11)) {
12252 /* thumb_insn_is_16bit() ensures we can't get here for
12253 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12254 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12256 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12257 ARCH(5);
12258 offset = ((insn & 0x7ff) << 1);
12259 tmp = load_reg(s, 14);
12260 tcg_gen_addi_i32(tmp, tmp, offset);
12261 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12263 tmp2 = tcg_temp_new_i32();
12264 tcg_gen_movi_i32(tmp2, s->pc | 1);
12265 store_reg(s, 14, tmp2);
12266 gen_bx(s, tmp);
12267 break;
12269 /* unconditional branch */
12270 val = (uint32_t)s->pc;
12271 offset = ((int32_t)insn << 21) >> 21;
12272 val += (offset << 1) + 2;
12273 gen_jmp(s, val);
12274 break;
12276 case 15:
12277 /* thumb_insn_is_16bit() ensures we can't get here for
12278 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12280 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12282 if (insn & (1 << 11)) {
12283 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12284 offset = ((insn & 0x7ff) << 1) | 1;
12285 tmp = load_reg(s, 14);
12286 tcg_gen_addi_i32(tmp, tmp, offset);
12288 tmp2 = tcg_temp_new_i32();
12289 tcg_gen_movi_i32(tmp2, s->pc | 1);
12290 store_reg(s, 14, tmp2);
12291 gen_bx(s, tmp);
12292 } else {
12293 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12294 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12296 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12298 break;
12300 return;
12301 illegal_op:
12302 undef:
12303 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12304 default_exception_el(s));
12307 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12309 /* Return true if the insn at dc->pc might cross a page boundary.
12310 * (False positives are OK, false negatives are not.)
12311 * We know this is a Thumb insn, and our caller ensures we are
12312 * only called if dc->pc is less than 4 bytes from the page
12313 * boundary, so we cross the page if the first 16 bits indicate
12314 * that this is a 32 bit insn.
12316 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12318 return !thumb_insn_is_16bit(s, insn);
12321 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12323 DisasContext *dc = container_of(dcbase, DisasContext, base);
12324 CPUARMState *env = cs->env_ptr;
12325 ARMCPU *cpu = arm_env_get_cpu(env);
12327 dc->pc = dc->base.pc_first;
12328 dc->condjmp = 0;
12330 dc->aarch64 = 0;
12331 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12332 * there is no secure EL1, so we route exceptions to EL3.
12334 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12335 !arm_el_is_aa64(env, 3);
12336 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
12337 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
12338 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
12339 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
12340 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
12341 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
12342 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12343 #if !defined(CONFIG_USER_ONLY)
12344 dc->user = (dc->current_el == 0);
12345 #endif
12346 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12347 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12348 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12349 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12350 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12351 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12352 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12353 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12354 regime_is_secure(env, dc->mmu_idx);
12355 dc->cp_regs = cpu->cp_regs;
12356 dc->features = env->features;
12358 /* Single step state. The code-generation logic here is:
12359 * SS_ACTIVE == 0:
12360 * generate code with no special handling for single-stepping (except
12361 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12362 * this happens anyway because those changes are all system register or
12363 * PSTATE writes).
12364 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12365 * emit code for one insn
12366 * emit code to clear PSTATE.SS
12367 * emit code to generate software step exception for completed step
12368 * end TB (as usual for having generated an exception)
12369 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12370 * emit code to generate a software step exception
12371 * end the TB
12373 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12374 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12375 dc->is_ldex = false;
12376 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12378 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
12380 /* If architectural single step active, limit to 1. */
12381 if (is_singlestepping(dc)) {
12382 dc->base.max_insns = 1;
12385 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12386 to those left on the page. */
12387 if (!dc->thumb) {
12388 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
12389 dc->base.max_insns = MIN(dc->base.max_insns, bound);
12392 cpu_F0s = tcg_temp_new_i32();
12393 cpu_F1s = tcg_temp_new_i32();
12394 cpu_F0d = tcg_temp_new_i64();
12395 cpu_F1d = tcg_temp_new_i64();
12396 cpu_V0 = cpu_F0d;
12397 cpu_V1 = cpu_F1d;
12398 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12399 cpu_M0 = tcg_temp_new_i64();
12402 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12404 DisasContext *dc = container_of(dcbase, DisasContext, base);
12406 /* A note on handling of the condexec (IT) bits:
12408 * We want to avoid the overhead of having to write the updated condexec
12409 * bits back to the CPUARMState for every instruction in an IT block. So:
12410 * (1) if the condexec bits are not already zero then we write
12411 * zero back into the CPUARMState now. This avoids complications trying
12412 * to do it at the end of the block. (For example if we don't do this
12413 * it's hard to identify whether we can safely skip writing condexec
12414 * at the end of the TB, which we definitely want to do for the case
12415 * where a TB doesn't do anything with the IT state at all.)
12416 * (2) if we are going to leave the TB then we call gen_set_condexec()
12417 * which will write the correct value into CPUARMState if zero is wrong.
12418 * This is done both for leaving the TB at the end, and for leaving
12419 * it because of an exception we know will happen, which is done in
12420 * gen_exception_insn(). The latter is necessary because we need to
12421 * leave the TB with the PC/IT state just prior to execution of the
12422 * instruction which caused the exception.
12423 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12424 * then the CPUARMState will be wrong and we need to reset it.
12425 * This is handled in the same way as restoration of the
12426 * PC in these situations; we save the value of the condexec bits
12427 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12428 * then uses this to restore them after an exception.
12430 * Note that there are no instructions which can read the condexec
12431 * bits, and none which can write non-static values to them, so
12432 * we don't need to care about whether CPUARMState is correct in the
12433 * middle of a TB.
12436 /* Reset the conditional execution bits immediately. This avoids
12437 complications trying to do it at the end of the block. */
12438 if (dc->condexec_mask || dc->condexec_cond) {
12439 TCGv_i32 tmp = tcg_temp_new_i32();
12440 tcg_gen_movi_i32(tmp, 0);
12441 store_cpu_field(tmp, condexec_bits);
12443 tcg_clear_temp_count();
12446 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12448 DisasContext *dc = container_of(dcbase, DisasContext, base);
12450 tcg_gen_insn_start(dc->pc,
12451 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12453 dc->insn_start = tcg_last_op();
12456 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12457 const CPUBreakpoint *bp)
12459 DisasContext *dc = container_of(dcbase, DisasContext, base);
12461 if (bp->flags & BP_CPU) {
12462 gen_set_condexec(dc);
12463 gen_set_pc_im(dc, dc->pc);
12464 gen_helper_check_breakpoints(cpu_env);
12465 /* End the TB early; it's likely not going to be executed */
12466 dc->base.is_jmp = DISAS_TOO_MANY;
12467 } else {
12468 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12469 /* The address covered by the breakpoint must be
12470 included in [tb->pc, tb->pc + tb->size) in order
12471 to for it to be properly cleared -- thus we
12472 increment the PC here so that the logic setting
12473 tb->size below does the right thing. */
12474 /* TODO: Advance PC by correct instruction length to
12475 * avoid disassembler error messages */
12476 dc->pc += 2;
12477 dc->base.is_jmp = DISAS_NORETURN;
12480 return true;
12483 static bool arm_pre_translate_insn(DisasContext *dc)
12485 #ifdef CONFIG_USER_ONLY
12486 /* Intercept jump to the magic kernel page. */
12487 if (dc->pc >= 0xffff0000) {
12488 /* We always get here via a jump, so know we are not in a
12489 conditional execution block. */
12490 gen_exception_internal(EXCP_KERNEL_TRAP);
12491 dc->base.is_jmp = DISAS_NORETURN;
12492 return true;
12494 #endif
12496 if (dc->ss_active && !dc->pstate_ss) {
12497 /* Singlestep state is Active-pending.
12498 * If we're in this state at the start of a TB then either
12499 * a) we just took an exception to an EL which is being debugged
12500 * and this is the first insn in the exception handler
12501 * b) debug exceptions were masked and we just unmasked them
12502 * without changing EL (eg by clearing PSTATE.D)
12503 * In either case we're going to take a swstep exception in the
12504 * "did not step an insn" case, and so the syndrome ISV and EX
12505 * bits should be zero.
12507 assert(dc->base.num_insns == 1);
12508 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12509 default_exception_el(dc));
12510 dc->base.is_jmp = DISAS_NORETURN;
12511 return true;
12514 return false;
12517 static void arm_post_translate_insn(DisasContext *dc)
12519 if (dc->condjmp && !dc->base.is_jmp) {
12520 gen_set_label(dc->condlabel);
12521 dc->condjmp = 0;
12523 dc->base.pc_next = dc->pc;
12524 translator_loop_temp_check(&dc->base);
12527 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12529 DisasContext *dc = container_of(dcbase, DisasContext, base);
12530 CPUARMState *env = cpu->env_ptr;
12531 unsigned int insn;
12533 if (arm_pre_translate_insn(dc)) {
12534 return;
12537 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12538 dc->insn = insn;
12539 dc->pc += 4;
12540 disas_arm_insn(dc, insn);
12542 arm_post_translate_insn(dc);
12544 /* ARM is a fixed-length ISA. We performed the cross-page check
12545 in init_disas_context by adjusting max_insns. */
12548 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12550 /* Return true if this Thumb insn is always unconditional,
12551 * even inside an IT block. This is true of only a very few
12552 * instructions: BKPT, HLT, and SG.
12554 * A larger class of instructions are UNPREDICTABLE if used
12555 * inside an IT block; we do not need to detect those here, because
12556 * what we do by default (perform the cc check and update the IT
12557 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12558 * choice for those situations.
12560 * insn is either a 16-bit or a 32-bit instruction; the two are
12561 * distinguishable because for the 16-bit case the top 16 bits
12562 * are zeroes, and that isn't a valid 32-bit encoding.
12564 if ((insn & 0xffffff00) == 0xbe00) {
12565 /* BKPT */
12566 return true;
12569 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12570 !arm_dc_feature(s, ARM_FEATURE_M)) {
12571 /* HLT: v8A only. This is unconditional even when it is going to
12572 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12573 * For v7 cores this was a plain old undefined encoding and so
12574 * honours its cc check. (We might be using the encoding as
12575 * a semihosting trap, but we don't change the cc check behaviour
12576 * on that account, because a debugger connected to a real v7A
12577 * core and emulating semihosting traps by catching the UNDEF
12578 * exception would also only see cases where the cc check passed.
12579 * No guest code should be trying to do a HLT semihosting trap
12580 * in an IT block anyway.
12582 return true;
12585 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12586 arm_dc_feature(s, ARM_FEATURE_M)) {
12587 /* SG: v8M only */
12588 return true;
12591 return false;
12594 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12596 DisasContext *dc = container_of(dcbase, DisasContext, base);
12597 CPUARMState *env = cpu->env_ptr;
12598 uint32_t insn;
12599 bool is_16bit;
12601 if (arm_pre_translate_insn(dc)) {
12602 return;
12605 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12606 is_16bit = thumb_insn_is_16bit(dc, insn);
12607 dc->pc += 2;
12608 if (!is_16bit) {
12609 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12611 insn = insn << 16 | insn2;
12612 dc->pc += 2;
12614 dc->insn = insn;
12616 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12617 uint32_t cond = dc->condexec_cond;
12619 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12620 dc->condlabel = gen_new_label();
12621 arm_gen_test_cc(cond ^ 1, dc->condlabel);
12622 dc->condjmp = 1;
12626 if (is_16bit) {
12627 disas_thumb_insn(dc, insn);
12628 } else {
12629 disas_thumb2_insn(dc, insn);
12632 /* Advance the Thumb condexec condition. */
12633 if (dc->condexec_mask) {
12634 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12635 ((dc->condexec_mask >> 4) & 1));
12636 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12637 if (dc->condexec_mask == 0) {
12638 dc->condexec_cond = 0;
12642 arm_post_translate_insn(dc);
12644 /* Thumb is a variable-length ISA. Stop translation when the next insn
12645 * will touch a new page. This ensures that prefetch aborts occur at
12646 * the right place.
12648 * We want to stop the TB if the next insn starts in a new page,
12649 * or if it spans between this page and the next. This means that
12650 * if we're looking at the last halfword in the page we need to
12651 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12652 * or a 32-bit Thumb insn (which won't).
12653 * This is to avoid generating a silly TB with a single 16-bit insn
12654 * in it at the end of this page (which would execute correctly
12655 * but isn't very efficient).
12657 if (dc->base.is_jmp == DISAS_NEXT
12658 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12659 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12660 && insn_crosses_page(env, dc)))) {
12661 dc->base.is_jmp = DISAS_TOO_MANY;
12665 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12667 DisasContext *dc = container_of(dcbase, DisasContext, base);
12669 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12670 /* FIXME: This can theoretically happen with self-modifying code. */
12671 cpu_abort(cpu, "IO on conditional branch instruction");
12674 /* At this stage dc->condjmp will only be set when the skipped
12675 instruction was a conditional branch or trap, and the PC has
12676 already been written. */
12677 gen_set_condexec(dc);
12678 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12679 /* Exception return branches need some special case code at the
12680 * end of the TB, which is complex enough that it has to
12681 * handle the single-step vs not and the condition-failed
12682 * insn codepath itself.
12684 gen_bx_excret_final_code(dc);
12685 } else if (unlikely(is_singlestepping(dc))) {
12686 /* Unconditional and "condition passed" instruction codepath. */
12687 switch (dc->base.is_jmp) {
12688 case DISAS_SWI:
12689 gen_ss_advance(dc);
12690 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12691 default_exception_el(dc));
12692 break;
12693 case DISAS_HVC:
12694 gen_ss_advance(dc);
12695 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12696 break;
12697 case DISAS_SMC:
12698 gen_ss_advance(dc);
12699 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12700 break;
12701 case DISAS_NEXT:
12702 case DISAS_TOO_MANY:
12703 case DISAS_UPDATE:
12704 gen_set_pc_im(dc, dc->pc);
12705 /* fall through */
12706 default:
12707 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12708 gen_singlestep_exception(dc);
12709 break;
12710 case DISAS_NORETURN:
12711 break;
12713 } else {
12714 /* While branches must always occur at the end of an IT block,
12715 there are a few other things that can cause us to terminate
12716 the TB in the middle of an IT block:
12717 - Exception generating instructions (bkpt, swi, undefined).
12718 - Page boundaries.
12719 - Hardware watchpoints.
12720 Hardware breakpoints have already been handled and skip this code.
12722 switch(dc->base.is_jmp) {
12723 case DISAS_NEXT:
12724 case DISAS_TOO_MANY:
12725 gen_goto_tb(dc, 1, dc->pc);
12726 break;
12727 case DISAS_JUMP:
12728 gen_goto_ptr();
12729 break;
12730 case DISAS_UPDATE:
12731 gen_set_pc_im(dc, dc->pc);
12732 /* fall through */
12733 default:
12734 /* indicate that the hash table must be used to find the next TB */
12735 tcg_gen_exit_tb(NULL, 0);
12736 break;
12737 case DISAS_NORETURN:
12738 /* nothing more to generate */
12739 break;
12740 case DISAS_WFI:
12742 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12743 !(dc->insn & (1U << 31))) ? 2 : 4);
12745 gen_helper_wfi(cpu_env, tmp);
12746 tcg_temp_free_i32(tmp);
12747 /* The helper doesn't necessarily throw an exception, but we
12748 * must go back to the main loop to check for interrupts anyway.
12750 tcg_gen_exit_tb(NULL, 0);
12751 break;
12753 case DISAS_WFE:
12754 gen_helper_wfe(cpu_env);
12755 break;
12756 case DISAS_YIELD:
12757 gen_helper_yield(cpu_env);
12758 break;
12759 case DISAS_SWI:
12760 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12761 default_exception_el(dc));
12762 break;
12763 case DISAS_HVC:
12764 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12765 break;
12766 case DISAS_SMC:
12767 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12768 break;
12772 if (dc->condjmp) {
12773 /* "Condition failed" instruction codepath for the branch/trap insn */
12774 gen_set_label(dc->condlabel);
12775 gen_set_condexec(dc);
12776 if (unlikely(is_singlestepping(dc))) {
12777 gen_set_pc_im(dc, dc->pc);
12778 gen_singlestep_exception(dc);
12779 } else {
12780 gen_goto_tb(dc, 1, dc->pc);
12784 /* Functions above can change dc->pc, so re-align db->pc_next */
12785 dc->base.pc_next = dc->pc;
12788 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12790 DisasContext *dc = container_of(dcbase, DisasContext, base);
12792 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12793 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12796 static const TranslatorOps arm_translator_ops = {
12797 .init_disas_context = arm_tr_init_disas_context,
12798 .tb_start = arm_tr_tb_start,
12799 .insn_start = arm_tr_insn_start,
12800 .breakpoint_check = arm_tr_breakpoint_check,
12801 .translate_insn = arm_tr_translate_insn,
12802 .tb_stop = arm_tr_tb_stop,
12803 .disas_log = arm_tr_disas_log,
12806 static const TranslatorOps thumb_translator_ops = {
12807 .init_disas_context = arm_tr_init_disas_context,
12808 .tb_start = arm_tr_tb_start,
12809 .insn_start = arm_tr_insn_start,
12810 .breakpoint_check = arm_tr_breakpoint_check,
12811 .translate_insn = thumb_tr_translate_insn,
12812 .tb_stop = arm_tr_tb_stop,
12813 .disas_log = arm_tr_disas_log,
12816 /* generate intermediate code for basic block 'tb'. */
12817 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12819 DisasContext dc;
12820 const TranslatorOps *ops = &arm_translator_ops;
12822 if (ARM_TBFLAG_THUMB(tb->flags)) {
12823 ops = &thumb_translator_ops;
12825 #ifdef TARGET_AARCH64
12826 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12827 ops = &aarch64_translator_ops;
12829 #endif
12831 translator_loop(ops, &dc.base, cpu, tb);
12834 static const char *cpu_mode_names[16] = {
12835 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12836 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12839 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12840 int flags)
12842 ARMCPU *cpu = ARM_CPU(cs);
12843 CPUARMState *env = &cpu->env;
12844 int i;
12846 if (is_a64(env)) {
12847 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12848 return;
12851 for(i=0;i<16;i++) {
12852 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12853 if ((i % 4) == 3)
12854 cpu_fprintf(f, "\n");
12855 else
12856 cpu_fprintf(f, " ");
12859 if (arm_feature(env, ARM_FEATURE_M)) {
12860 uint32_t xpsr = xpsr_read(env);
12861 const char *mode;
12862 const char *ns_status = "";
12864 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12865 ns_status = env->v7m.secure ? "S " : "NS ";
12868 if (xpsr & XPSR_EXCP) {
12869 mode = "handler";
12870 } else {
12871 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12872 mode = "unpriv-thread";
12873 } else {
12874 mode = "priv-thread";
12878 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12879 xpsr,
12880 xpsr & XPSR_N ? 'N' : '-',
12881 xpsr & XPSR_Z ? 'Z' : '-',
12882 xpsr & XPSR_C ? 'C' : '-',
12883 xpsr & XPSR_V ? 'V' : '-',
12884 xpsr & XPSR_T ? 'T' : 'A',
12885 ns_status,
12886 mode);
12887 } else {
12888 uint32_t psr = cpsr_read(env);
12889 const char *ns_status = "";
12891 if (arm_feature(env, ARM_FEATURE_EL3) &&
12892 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12893 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12896 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12897 psr,
12898 psr & CPSR_N ? 'N' : '-',
12899 psr & CPSR_Z ? 'Z' : '-',
12900 psr & CPSR_C ? 'C' : '-',
12901 psr & CPSR_V ? 'V' : '-',
12902 psr & CPSR_T ? 'T' : 'A',
12903 ns_status,
12904 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12907 if (flags & CPU_DUMP_FPU) {
12908 int numvfpregs = 0;
12909 if (arm_feature(env, ARM_FEATURE_VFP)) {
12910 numvfpregs += 16;
12912 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12913 numvfpregs += 16;
12915 for (i = 0; i < numvfpregs; i++) {
12916 uint64_t v = *aa32_vfp_dreg(env, i);
12917 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12918 i * 2, (uint32_t)v,
12919 i * 2 + 1, (uint32_t)(v >> 32),
12920 i, v);
12922 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12926 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12927 target_ulong *data)
12929 if (is_a64(env)) {
12930 env->pc = data[0];
12931 env->condexec_bits = 0;
12932 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12933 } else {
12934 env->regs[15] = data[0];
12935 env->condexec_bits = data[1];
12936 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;