target/arm: Use pointers in crypto helpers
[qemu/ar7.git] / target / arm / translate.c
blob7b5db15861199e081c41b71c717694c5ec9d8054
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "qemu/log.h"
29 #include "qemu/bitops.h"
30 #include "arm_ldst.h"
31 #include "exec/semihost.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
36 #include "trace-tcg.h"
37 #include "exec/log.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) 1
57 #else
58 #define IS_USER(s) (s->user)
59 #endif
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
63 static TCGv_i32 cpu_R[16];
64 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
65 TCGv_i64 cpu_exclusive_addr;
66 TCGv_i64 cpu_exclusive_val;
68 /* FIXME: These should be removed. */
69 static TCGv_i32 cpu_F0s, cpu_F1s;
70 static TCGv_i64 cpu_F0d, cpu_F1d;
72 #include "exec/gen-icount.h"
74 static const char *regnames[] =
75 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
76 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
78 /* initialize TCG globals. */
79 void arm_translate_init(void)
81 int i;
83 for (i = 0; i < 16; i++) {
84 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
85 offsetof(CPUARMState, regs[i]),
86 regnames[i]);
88 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
89 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
90 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
91 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
93 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
94 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
95 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
96 offsetof(CPUARMState, exclusive_val), "exclusive_val");
98 a64_translate_init();
101 /* Flags for the disas_set_da_iss info argument:
102 * lower bits hold the Rt register number, higher bits are flags.
104 typedef enum ISSInfo {
105 ISSNone = 0,
106 ISSRegMask = 0x1f,
107 ISSInvalid = (1 << 5),
108 ISSIsAcqRel = (1 << 6),
109 ISSIsWrite = (1 << 7),
110 ISSIs16Bit = (1 << 8),
111 } ISSInfo;
113 /* Save the syndrome information for a Data Abort */
114 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
116 uint32_t syn;
117 int sas = memop & MO_SIZE;
118 bool sse = memop & MO_SIGN;
119 bool is_acqrel = issinfo & ISSIsAcqRel;
120 bool is_write = issinfo & ISSIsWrite;
121 bool is_16bit = issinfo & ISSIs16Bit;
122 int srt = issinfo & ISSRegMask;
124 if (issinfo & ISSInvalid) {
125 /* Some callsites want to conditionally provide ISS info,
126 * eg "only if this was not a writeback"
128 return;
131 if (srt == 15) {
132 /* For AArch32, insns where the src/dest is R15 never generate
133 * ISS information. Catching that here saves checking at all
134 * the call sites.
136 return;
139 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
140 0, 0, 0, is_write, 0, is_16bit);
141 disas_set_insn_syndrome(s, syn);
144 static inline int get_a32_user_mem_index(DisasContext *s)
146 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
147 * insns:
148 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
149 * otherwise, access as if at PL0.
151 switch (s->mmu_idx) {
152 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
153 case ARMMMUIdx_S12NSE0:
154 case ARMMMUIdx_S12NSE1:
155 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
156 case ARMMMUIdx_S1E3:
157 case ARMMMUIdx_S1SE0:
158 case ARMMMUIdx_S1SE1:
159 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
160 case ARMMMUIdx_MUser:
161 case ARMMMUIdx_MPriv:
162 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
163 case ARMMMUIdx_MUserNegPri:
164 case ARMMMUIdx_MPrivNegPri:
165 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
166 case ARMMMUIdx_MSUser:
167 case ARMMMUIdx_MSPriv:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
169 case ARMMMUIdx_MSUserNegPri:
170 case ARMMMUIdx_MSPrivNegPri:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
172 case ARMMMUIdx_S2NS:
173 default:
174 g_assert_not_reached();
178 static inline TCGv_i32 load_cpu_offset(int offset)
180 TCGv_i32 tmp = tcg_temp_new_i32();
181 tcg_gen_ld_i32(tmp, cpu_env, offset);
182 return tmp;
185 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
187 static inline void store_cpu_offset(TCGv_i32 var, int offset)
189 tcg_gen_st_i32(var, cpu_env, offset);
190 tcg_temp_free_i32(var);
193 #define store_cpu_field(var, name) \
194 store_cpu_offset(var, offsetof(CPUARMState, name))
196 /* Set a variable to the value of a CPU register. */
197 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
199 if (reg == 15) {
200 uint32_t addr;
201 /* normally, since we updated PC, we need only to add one insn */
202 if (s->thumb)
203 addr = (long)s->pc + 2;
204 else
205 addr = (long)s->pc + 4;
206 tcg_gen_movi_i32(var, addr);
207 } else {
208 tcg_gen_mov_i32(var, cpu_R[reg]);
212 /* Create a new temporary and set it to the value of a CPU register. */
213 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
215 TCGv_i32 tmp = tcg_temp_new_i32();
216 load_reg_var(s, tmp, reg);
217 return tmp;
220 /* Set a CPU register. The source must be a temporary and will be
221 marked as dead. */
222 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
224 if (reg == 15) {
225 /* In Thumb mode, we must ignore bit 0.
226 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
227 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
228 * We choose to ignore [1:0] in ARM mode for all architecture versions.
230 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
231 s->base.is_jmp = DISAS_JUMP;
233 tcg_gen_mov_i32(cpu_R[reg], var);
234 tcg_temp_free_i32(var);
237 /* Value extensions. */
238 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
239 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
240 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
241 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
243 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
244 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
247 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
249 TCGv_i32 tmp_mask = tcg_const_i32(mask);
250 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
251 tcg_temp_free_i32(tmp_mask);
253 /* Set NZCV flags from the high 4 bits of var. */
254 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
256 static void gen_exception_internal(int excp)
258 TCGv_i32 tcg_excp = tcg_const_i32(excp);
260 assert(excp_is_internal(excp));
261 gen_helper_exception_internal(cpu_env, tcg_excp);
262 tcg_temp_free_i32(tcg_excp);
265 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
267 TCGv_i32 tcg_excp = tcg_const_i32(excp);
268 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
269 TCGv_i32 tcg_el = tcg_const_i32(target_el);
271 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
272 tcg_syn, tcg_el);
274 tcg_temp_free_i32(tcg_el);
275 tcg_temp_free_i32(tcg_syn);
276 tcg_temp_free_i32(tcg_excp);
279 static void gen_ss_advance(DisasContext *s)
281 /* If the singlestep state is Active-not-pending, advance to
282 * Active-pending.
284 if (s->ss_active) {
285 s->pstate_ss = 0;
286 gen_helper_clear_pstate_ss(cpu_env);
290 static void gen_step_complete_exception(DisasContext *s)
292 /* We just completed step of an insn. Move from Active-not-pending
293 * to Active-pending, and then also take the swstep exception.
294 * This corresponds to making the (IMPDEF) choice to prioritize
295 * swstep exceptions over asynchronous exceptions taken to an exception
296 * level where debug is disabled. This choice has the advantage that
297 * we do not need to maintain internal state corresponding to the
298 * ISV/EX syndrome bits between completion of the step and generation
299 * of the exception, and our syndrome information is always correct.
301 gen_ss_advance(s);
302 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
303 default_exception_el(s));
304 s->base.is_jmp = DISAS_NORETURN;
307 static void gen_singlestep_exception(DisasContext *s)
309 /* Generate the right kind of exception for singlestep, which is
310 * either the architectural singlestep or EXCP_DEBUG for QEMU's
311 * gdb singlestepping.
313 if (s->ss_active) {
314 gen_step_complete_exception(s);
315 } else {
316 gen_exception_internal(EXCP_DEBUG);
320 static inline bool is_singlestepping(DisasContext *s)
322 /* Return true if we are singlestepping either because of
323 * architectural singlestep or QEMU gdbstub singlestep. This does
324 * not include the command line '-singlestep' mode which is rather
325 * misnamed as it only means "one instruction per TB" and doesn't
326 * affect the code we generate.
328 return s->base.singlestep_enabled || s->ss_active;
331 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
333 TCGv_i32 tmp1 = tcg_temp_new_i32();
334 TCGv_i32 tmp2 = tcg_temp_new_i32();
335 tcg_gen_ext16s_i32(tmp1, a);
336 tcg_gen_ext16s_i32(tmp2, b);
337 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
338 tcg_temp_free_i32(tmp2);
339 tcg_gen_sari_i32(a, a, 16);
340 tcg_gen_sari_i32(b, b, 16);
341 tcg_gen_mul_i32(b, b, a);
342 tcg_gen_mov_i32(a, tmp1);
343 tcg_temp_free_i32(tmp1);
346 /* Byteswap each halfword. */
347 static void gen_rev16(TCGv_i32 var)
349 TCGv_i32 tmp = tcg_temp_new_i32();
350 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
351 tcg_gen_shri_i32(tmp, var, 8);
352 tcg_gen_and_i32(tmp, tmp, mask);
353 tcg_gen_and_i32(var, var, mask);
354 tcg_gen_shli_i32(var, var, 8);
355 tcg_gen_or_i32(var, var, tmp);
356 tcg_temp_free_i32(mask);
357 tcg_temp_free_i32(tmp);
360 /* Byteswap low halfword and sign extend. */
361 static void gen_revsh(TCGv_i32 var)
363 tcg_gen_ext16u_i32(var, var);
364 tcg_gen_bswap16_i32(var, var);
365 tcg_gen_ext16s_i32(var, var);
368 /* Return (b << 32) + a. Mark inputs as dead */
369 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
371 TCGv_i64 tmp64 = tcg_temp_new_i64();
373 tcg_gen_extu_i32_i64(tmp64, b);
374 tcg_temp_free_i32(b);
375 tcg_gen_shli_i64(tmp64, tmp64, 32);
376 tcg_gen_add_i64(a, tmp64, a);
378 tcg_temp_free_i64(tmp64);
379 return a;
382 /* Return (b << 32) - a. Mark inputs as dead. */
383 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
385 TCGv_i64 tmp64 = tcg_temp_new_i64();
387 tcg_gen_extu_i32_i64(tmp64, b);
388 tcg_temp_free_i32(b);
389 tcg_gen_shli_i64(tmp64, tmp64, 32);
390 tcg_gen_sub_i64(a, tmp64, a);
392 tcg_temp_free_i64(tmp64);
393 return a;
396 /* 32x32->64 multiply. Marks inputs as dead. */
397 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
399 TCGv_i32 lo = tcg_temp_new_i32();
400 TCGv_i32 hi = tcg_temp_new_i32();
401 TCGv_i64 ret;
403 tcg_gen_mulu2_i32(lo, hi, a, b);
404 tcg_temp_free_i32(a);
405 tcg_temp_free_i32(b);
407 ret = tcg_temp_new_i64();
408 tcg_gen_concat_i32_i64(ret, lo, hi);
409 tcg_temp_free_i32(lo);
410 tcg_temp_free_i32(hi);
412 return ret;
415 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
417 TCGv_i32 lo = tcg_temp_new_i32();
418 TCGv_i32 hi = tcg_temp_new_i32();
419 TCGv_i64 ret;
421 tcg_gen_muls2_i32(lo, hi, a, b);
422 tcg_temp_free_i32(a);
423 tcg_temp_free_i32(b);
425 ret = tcg_temp_new_i64();
426 tcg_gen_concat_i32_i64(ret, lo, hi);
427 tcg_temp_free_i32(lo);
428 tcg_temp_free_i32(hi);
430 return ret;
433 /* Swap low and high halfwords. */
434 static void gen_swap_half(TCGv_i32 var)
436 TCGv_i32 tmp = tcg_temp_new_i32();
437 tcg_gen_shri_i32(tmp, var, 16);
438 tcg_gen_shli_i32(var, var, 16);
439 tcg_gen_or_i32(var, var, tmp);
440 tcg_temp_free_i32(tmp);
443 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
444 tmp = (t0 ^ t1) & 0x8000;
445 t0 &= ~0x8000;
446 t1 &= ~0x8000;
447 t0 = (t0 + t1) ^ tmp;
450 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
452 TCGv_i32 tmp = tcg_temp_new_i32();
453 tcg_gen_xor_i32(tmp, t0, t1);
454 tcg_gen_andi_i32(tmp, tmp, 0x8000);
455 tcg_gen_andi_i32(t0, t0, ~0x8000);
456 tcg_gen_andi_i32(t1, t1, ~0x8000);
457 tcg_gen_add_i32(t0, t0, t1);
458 tcg_gen_xor_i32(t0, t0, tmp);
459 tcg_temp_free_i32(tmp);
460 tcg_temp_free_i32(t1);
463 /* Set CF to the top bit of var. */
464 static void gen_set_CF_bit31(TCGv_i32 var)
466 tcg_gen_shri_i32(cpu_CF, var, 31);
469 /* Set N and Z flags from var. */
470 static inline void gen_logic_CC(TCGv_i32 var)
472 tcg_gen_mov_i32(cpu_NF, var);
473 tcg_gen_mov_i32(cpu_ZF, var);
476 /* T0 += T1 + CF. */
477 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
479 tcg_gen_add_i32(t0, t0, t1);
480 tcg_gen_add_i32(t0, t0, cpu_CF);
483 /* dest = T0 + T1 + CF. */
484 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
486 tcg_gen_add_i32(dest, t0, t1);
487 tcg_gen_add_i32(dest, dest, cpu_CF);
490 /* dest = T0 - T1 + CF - 1. */
491 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
493 tcg_gen_sub_i32(dest, t0, t1);
494 tcg_gen_add_i32(dest, dest, cpu_CF);
495 tcg_gen_subi_i32(dest, dest, 1);
498 /* dest = T0 + T1. Compute C, N, V and Z flags */
499 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
501 TCGv_i32 tmp = tcg_temp_new_i32();
502 tcg_gen_movi_i32(tmp, 0);
503 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
504 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
505 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
506 tcg_gen_xor_i32(tmp, t0, t1);
507 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
508 tcg_temp_free_i32(tmp);
509 tcg_gen_mov_i32(dest, cpu_NF);
512 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
513 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
515 TCGv_i32 tmp = tcg_temp_new_i32();
516 if (TCG_TARGET_HAS_add2_i32) {
517 tcg_gen_movi_i32(tmp, 0);
518 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
519 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
520 } else {
521 TCGv_i64 q0 = tcg_temp_new_i64();
522 TCGv_i64 q1 = tcg_temp_new_i64();
523 tcg_gen_extu_i32_i64(q0, t0);
524 tcg_gen_extu_i32_i64(q1, t1);
525 tcg_gen_add_i64(q0, q0, q1);
526 tcg_gen_extu_i32_i64(q1, cpu_CF);
527 tcg_gen_add_i64(q0, q0, q1);
528 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
529 tcg_temp_free_i64(q0);
530 tcg_temp_free_i64(q1);
532 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
533 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
534 tcg_gen_xor_i32(tmp, t0, t1);
535 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
536 tcg_temp_free_i32(tmp);
537 tcg_gen_mov_i32(dest, cpu_NF);
540 /* dest = T0 - T1. Compute C, N, V and Z flags */
541 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
543 TCGv_i32 tmp;
544 tcg_gen_sub_i32(cpu_NF, t0, t1);
545 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
546 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
547 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
548 tmp = tcg_temp_new_i32();
549 tcg_gen_xor_i32(tmp, t0, t1);
550 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
551 tcg_temp_free_i32(tmp);
552 tcg_gen_mov_i32(dest, cpu_NF);
555 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
556 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
558 TCGv_i32 tmp = tcg_temp_new_i32();
559 tcg_gen_not_i32(tmp, t1);
560 gen_adc_CC(dest, t0, tmp);
561 tcg_temp_free_i32(tmp);
564 #define GEN_SHIFT(name) \
565 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
567 TCGv_i32 tmp1, tmp2, tmp3; \
568 tmp1 = tcg_temp_new_i32(); \
569 tcg_gen_andi_i32(tmp1, t1, 0xff); \
570 tmp2 = tcg_const_i32(0); \
571 tmp3 = tcg_const_i32(0x1f); \
572 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
573 tcg_temp_free_i32(tmp3); \
574 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
575 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
576 tcg_temp_free_i32(tmp2); \
577 tcg_temp_free_i32(tmp1); \
579 GEN_SHIFT(shl)
580 GEN_SHIFT(shr)
581 #undef GEN_SHIFT
583 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
585 TCGv_i32 tmp1, tmp2;
586 tmp1 = tcg_temp_new_i32();
587 tcg_gen_andi_i32(tmp1, t1, 0xff);
588 tmp2 = tcg_const_i32(0x1f);
589 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
590 tcg_temp_free_i32(tmp2);
591 tcg_gen_sar_i32(dest, t0, tmp1);
592 tcg_temp_free_i32(tmp1);
595 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
597 TCGv_i32 c0 = tcg_const_i32(0);
598 TCGv_i32 tmp = tcg_temp_new_i32();
599 tcg_gen_neg_i32(tmp, src);
600 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
601 tcg_temp_free_i32(c0);
602 tcg_temp_free_i32(tmp);
605 static void shifter_out_im(TCGv_i32 var, int shift)
607 if (shift == 0) {
608 tcg_gen_andi_i32(cpu_CF, var, 1);
609 } else {
610 tcg_gen_shri_i32(cpu_CF, var, shift);
611 if (shift != 31) {
612 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
617 /* Shift by immediate. Includes special handling for shift == 0. */
618 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
619 int shift, int flags)
621 switch (shiftop) {
622 case 0: /* LSL */
623 if (shift != 0) {
624 if (flags)
625 shifter_out_im(var, 32 - shift);
626 tcg_gen_shli_i32(var, var, shift);
628 break;
629 case 1: /* LSR */
630 if (shift == 0) {
631 if (flags) {
632 tcg_gen_shri_i32(cpu_CF, var, 31);
634 tcg_gen_movi_i32(var, 0);
635 } else {
636 if (flags)
637 shifter_out_im(var, shift - 1);
638 tcg_gen_shri_i32(var, var, shift);
640 break;
641 case 2: /* ASR */
642 if (shift == 0)
643 shift = 32;
644 if (flags)
645 shifter_out_im(var, shift - 1);
646 if (shift == 32)
647 shift = 31;
648 tcg_gen_sari_i32(var, var, shift);
649 break;
650 case 3: /* ROR/RRX */
651 if (shift != 0) {
652 if (flags)
653 shifter_out_im(var, shift - 1);
654 tcg_gen_rotri_i32(var, var, shift); break;
655 } else {
656 TCGv_i32 tmp = tcg_temp_new_i32();
657 tcg_gen_shli_i32(tmp, cpu_CF, 31);
658 if (flags)
659 shifter_out_im(var, 0);
660 tcg_gen_shri_i32(var, var, 1);
661 tcg_gen_or_i32(var, var, tmp);
662 tcg_temp_free_i32(tmp);
667 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
668 TCGv_i32 shift, int flags)
670 if (flags) {
671 switch (shiftop) {
672 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
673 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
674 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
675 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
677 } else {
678 switch (shiftop) {
679 case 0:
680 gen_shl(var, var, shift);
681 break;
682 case 1:
683 gen_shr(var, var, shift);
684 break;
685 case 2:
686 gen_sar(var, var, shift);
687 break;
688 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
689 tcg_gen_rotr_i32(var, var, shift); break;
692 tcg_temp_free_i32(shift);
695 #define PAS_OP(pfx) \
696 switch (op2) { \
697 case 0: gen_pas_helper(glue(pfx,add16)); break; \
698 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
699 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
700 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
701 case 4: gen_pas_helper(glue(pfx,add8)); break; \
702 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
704 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
706 TCGv_ptr tmp;
708 switch (op1) {
709 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
710 case 1:
711 tmp = tcg_temp_new_ptr();
712 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
713 PAS_OP(s)
714 tcg_temp_free_ptr(tmp);
715 break;
716 case 5:
717 tmp = tcg_temp_new_ptr();
718 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
719 PAS_OP(u)
720 tcg_temp_free_ptr(tmp);
721 break;
722 #undef gen_pas_helper
723 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
724 case 2:
725 PAS_OP(q);
726 break;
727 case 3:
728 PAS_OP(sh);
729 break;
730 case 6:
731 PAS_OP(uq);
732 break;
733 case 7:
734 PAS_OP(uh);
735 break;
736 #undef gen_pas_helper
739 #undef PAS_OP
741 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
742 #define PAS_OP(pfx) \
743 switch (op1) { \
744 case 0: gen_pas_helper(glue(pfx,add8)); break; \
745 case 1: gen_pas_helper(glue(pfx,add16)); break; \
746 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
747 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
748 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
749 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
751 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
753 TCGv_ptr tmp;
755 switch (op2) {
756 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
757 case 0:
758 tmp = tcg_temp_new_ptr();
759 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
760 PAS_OP(s)
761 tcg_temp_free_ptr(tmp);
762 break;
763 case 4:
764 tmp = tcg_temp_new_ptr();
765 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
766 PAS_OP(u)
767 tcg_temp_free_ptr(tmp);
768 break;
769 #undef gen_pas_helper
770 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
771 case 1:
772 PAS_OP(q);
773 break;
774 case 2:
775 PAS_OP(sh);
776 break;
777 case 5:
778 PAS_OP(uq);
779 break;
780 case 6:
781 PAS_OP(uh);
782 break;
783 #undef gen_pas_helper
786 #undef PAS_OP
789 * Generate a conditional based on ARM condition code cc.
790 * This is common between ARM and Aarch64 targets.
792 void arm_test_cc(DisasCompare *cmp, int cc)
794 TCGv_i32 value;
795 TCGCond cond;
796 bool global = true;
798 switch (cc) {
799 case 0: /* eq: Z */
800 case 1: /* ne: !Z */
801 cond = TCG_COND_EQ;
802 value = cpu_ZF;
803 break;
805 case 2: /* cs: C */
806 case 3: /* cc: !C */
807 cond = TCG_COND_NE;
808 value = cpu_CF;
809 break;
811 case 4: /* mi: N */
812 case 5: /* pl: !N */
813 cond = TCG_COND_LT;
814 value = cpu_NF;
815 break;
817 case 6: /* vs: V */
818 case 7: /* vc: !V */
819 cond = TCG_COND_LT;
820 value = cpu_VF;
821 break;
823 case 8: /* hi: C && !Z */
824 case 9: /* ls: !C || Z -> !(C && !Z) */
825 cond = TCG_COND_NE;
826 value = tcg_temp_new_i32();
827 global = false;
828 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
829 ZF is non-zero for !Z; so AND the two subexpressions. */
830 tcg_gen_neg_i32(value, cpu_CF);
831 tcg_gen_and_i32(value, value, cpu_ZF);
832 break;
834 case 10: /* ge: N == V -> N ^ V == 0 */
835 case 11: /* lt: N != V -> N ^ V != 0 */
836 /* Since we're only interested in the sign bit, == 0 is >= 0. */
837 cond = TCG_COND_GE;
838 value = tcg_temp_new_i32();
839 global = false;
840 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
841 break;
843 case 12: /* gt: !Z && N == V */
844 case 13: /* le: Z || N != V */
845 cond = TCG_COND_NE;
846 value = tcg_temp_new_i32();
847 global = false;
848 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
849 * the sign bit then AND with ZF to yield the result. */
850 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
851 tcg_gen_sari_i32(value, value, 31);
852 tcg_gen_andc_i32(value, cpu_ZF, value);
853 break;
855 case 14: /* always */
856 case 15: /* always */
857 /* Use the ALWAYS condition, which will fold early.
858 * It doesn't matter what we use for the value. */
859 cond = TCG_COND_ALWAYS;
860 value = cpu_ZF;
861 goto no_invert;
863 default:
864 fprintf(stderr, "Bad condition code 0x%x\n", cc);
865 abort();
868 if (cc & 1) {
869 cond = tcg_invert_cond(cond);
872 no_invert:
873 cmp->cond = cond;
874 cmp->value = value;
875 cmp->value_global = global;
878 void arm_free_cc(DisasCompare *cmp)
880 if (!cmp->value_global) {
881 tcg_temp_free_i32(cmp->value);
885 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
887 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
890 void arm_gen_test_cc(int cc, TCGLabel *label)
892 DisasCompare cmp;
893 arm_test_cc(&cmp, cc);
894 arm_jump_cc(&cmp, label);
895 arm_free_cc(&cmp);
898 static const uint8_t table_logic_cc[16] = {
899 1, /* and */
900 1, /* xor */
901 0, /* sub */
902 0, /* rsb */
903 0, /* add */
904 0, /* adc */
905 0, /* sbc */
906 0, /* rsc */
907 1, /* andl */
908 1, /* xorl */
909 0, /* cmp */
910 0, /* cmn */
911 1, /* orr */
912 1, /* mov */
913 1, /* bic */
914 1, /* mvn */
917 static inline void gen_set_condexec(DisasContext *s)
919 if (s->condexec_mask) {
920 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
921 TCGv_i32 tmp = tcg_temp_new_i32();
922 tcg_gen_movi_i32(tmp, val);
923 store_cpu_field(tmp, condexec_bits);
927 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
929 tcg_gen_movi_i32(cpu_R[15], val);
932 /* Set PC and Thumb state from an immediate address. */
933 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
935 TCGv_i32 tmp;
937 s->base.is_jmp = DISAS_JUMP;
938 if (s->thumb != (addr & 1)) {
939 tmp = tcg_temp_new_i32();
940 tcg_gen_movi_i32(tmp, addr & 1);
941 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
942 tcg_temp_free_i32(tmp);
944 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
947 /* Set PC and Thumb state from var. var is marked as dead. */
948 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
950 s->base.is_jmp = DISAS_JUMP;
951 tcg_gen_andi_i32(cpu_R[15], var, ~1);
952 tcg_gen_andi_i32(var, var, 1);
953 store_cpu_field(var, thumb);
956 /* Set PC and Thumb state from var. var is marked as dead.
957 * For M-profile CPUs, include logic to detect exception-return
958 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
959 * and BX reg, and no others, and happens only for code in Handler mode.
961 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
963 /* Generate the same code here as for a simple bx, but flag via
964 * s->base.is_jmp that we need to do the rest of the work later.
966 gen_bx(s, var);
967 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
968 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
969 s->base.is_jmp = DISAS_BX_EXCRET;
973 static inline void gen_bx_excret_final_code(DisasContext *s)
975 /* Generate the code to finish possible exception return and end the TB */
976 TCGLabel *excret_label = gen_new_label();
977 uint32_t min_magic;
979 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
980 /* Covers FNC_RETURN and EXC_RETURN magic */
981 min_magic = FNC_RETURN_MIN_MAGIC;
982 } else {
983 /* EXC_RETURN magic only */
984 min_magic = EXC_RETURN_MIN_MAGIC;
987 /* Is the new PC value in the magic range indicating exception return? */
988 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
989 /* No: end the TB as we would for a DISAS_JMP */
990 if (is_singlestepping(s)) {
991 gen_singlestep_exception(s);
992 } else {
993 tcg_gen_exit_tb(0);
995 gen_set_label(excret_label);
996 /* Yes: this is an exception return.
997 * At this point in runtime env->regs[15] and env->thumb will hold
998 * the exception-return magic number, which do_v7m_exception_exit()
999 * will read. Nothing else will be able to see those values because
1000 * the cpu-exec main loop guarantees that we will always go straight
1001 * from raising the exception to the exception-handling code.
1003 * gen_ss_advance(s) does nothing on M profile currently but
1004 * calling it is conceptually the right thing as we have executed
1005 * this instruction (compare SWI, HVC, SMC handling).
1007 gen_ss_advance(s);
1008 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1011 static inline void gen_bxns(DisasContext *s, int rm)
1013 TCGv_i32 var = load_reg(s, rm);
1015 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1016 * we need to sync state before calling it, but:
1017 * - we don't need to do gen_set_pc_im() because the bxns helper will
1018 * always set the PC itself
1019 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1020 * unless it's outside an IT block or the last insn in an IT block,
1021 * so we know that condexec == 0 (already set at the top of the TB)
1022 * is correct in the non-UNPREDICTABLE cases, and we can choose
1023 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1025 gen_helper_v7m_bxns(cpu_env, var);
1026 tcg_temp_free_i32(var);
1027 s->base.is_jmp = DISAS_EXIT;
1030 static inline void gen_blxns(DisasContext *s, int rm)
1032 TCGv_i32 var = load_reg(s, rm);
1034 /* We don't need to sync condexec state, for the same reason as bxns.
1035 * We do however need to set the PC, because the blxns helper reads it.
1036 * The blxns helper may throw an exception.
1038 gen_set_pc_im(s, s->pc);
1039 gen_helper_v7m_blxns(cpu_env, var);
1040 tcg_temp_free_i32(var);
1041 s->base.is_jmp = DISAS_EXIT;
1044 /* Variant of store_reg which uses branch&exchange logic when storing
1045 to r15 in ARM architecture v7 and above. The source must be a temporary
1046 and will be marked as dead. */
1047 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1049 if (reg == 15 && ENABLE_ARCH_7) {
1050 gen_bx(s, var);
1051 } else {
1052 store_reg(s, reg, var);
1056 /* Variant of store_reg which uses branch&exchange logic when storing
1057 * to r15 in ARM architecture v5T and above. This is used for storing
1058 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1059 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1060 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1062 if (reg == 15 && ENABLE_ARCH_5) {
1063 gen_bx_excret(s, var);
1064 } else {
1065 store_reg(s, reg, var);
1069 #ifdef CONFIG_USER_ONLY
1070 #define IS_USER_ONLY 1
1071 #else
1072 #define IS_USER_ONLY 0
1073 #endif
1075 /* Abstractions of "generate code to do a guest load/store for
1076 * AArch32", where a vaddr is always 32 bits (and is zero
1077 * extended if we're a 64 bit core) and data is also
1078 * 32 bits unless specifically doing a 64 bit access.
1079 * These functions work like tcg_gen_qemu_{ld,st}* except
1080 * that the address argument is TCGv_i32 rather than TCGv.
1083 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1085 TCGv addr = tcg_temp_new();
1086 tcg_gen_extu_i32_tl(addr, a32);
1088 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1089 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1090 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1092 return addr;
1095 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1096 int index, TCGMemOp opc)
1098 TCGv addr = gen_aa32_addr(s, a32, opc);
1099 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1100 tcg_temp_free(addr);
1103 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1104 int index, TCGMemOp opc)
1106 TCGv addr = gen_aa32_addr(s, a32, opc);
1107 tcg_gen_qemu_st_i32(val, addr, index, opc);
1108 tcg_temp_free(addr);
1111 #define DO_GEN_LD(SUFF, OPC) \
1112 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1113 TCGv_i32 a32, int index) \
1115 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1117 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1118 TCGv_i32 val, \
1119 TCGv_i32 a32, int index, \
1120 ISSInfo issinfo) \
1122 gen_aa32_ld##SUFF(s, val, a32, index); \
1123 disas_set_da_iss(s, OPC, issinfo); \
1126 #define DO_GEN_ST(SUFF, OPC) \
1127 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1128 TCGv_i32 a32, int index) \
1130 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1132 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1133 TCGv_i32 val, \
1134 TCGv_i32 a32, int index, \
1135 ISSInfo issinfo) \
1137 gen_aa32_st##SUFF(s, val, a32, index); \
1138 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1141 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1143 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1144 if (!IS_USER_ONLY && s->sctlr_b) {
1145 tcg_gen_rotri_i64(val, val, 32);
1149 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1150 int index, TCGMemOp opc)
1152 TCGv addr = gen_aa32_addr(s, a32, opc);
1153 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1154 gen_aa32_frob64(s, val);
1155 tcg_temp_free(addr);
1158 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1159 TCGv_i32 a32, int index)
1161 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1164 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1165 int index, TCGMemOp opc)
1167 TCGv addr = gen_aa32_addr(s, a32, opc);
1169 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1170 if (!IS_USER_ONLY && s->sctlr_b) {
1171 TCGv_i64 tmp = tcg_temp_new_i64();
1172 tcg_gen_rotri_i64(tmp, val, 32);
1173 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1174 tcg_temp_free_i64(tmp);
1175 } else {
1176 tcg_gen_qemu_st_i64(val, addr, index, opc);
1178 tcg_temp_free(addr);
1181 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1182 TCGv_i32 a32, int index)
1184 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1187 DO_GEN_LD(8s, MO_SB)
1188 DO_GEN_LD(8u, MO_UB)
1189 DO_GEN_LD(16s, MO_SW)
1190 DO_GEN_LD(16u, MO_UW)
1191 DO_GEN_LD(32u, MO_UL)
1192 DO_GEN_ST(8, MO_UB)
1193 DO_GEN_ST(16, MO_UW)
1194 DO_GEN_ST(32, MO_UL)
1196 static inline void gen_hvc(DisasContext *s, int imm16)
1198 /* The pre HVC helper handles cases when HVC gets trapped
1199 * as an undefined insn by runtime configuration (ie before
1200 * the insn really executes).
1202 gen_set_pc_im(s, s->pc - 4);
1203 gen_helper_pre_hvc(cpu_env);
1204 /* Otherwise we will treat this as a real exception which
1205 * happens after execution of the insn. (The distinction matters
1206 * for the PC value reported to the exception handler and also
1207 * for single stepping.)
1209 s->svc_imm = imm16;
1210 gen_set_pc_im(s, s->pc);
1211 s->base.is_jmp = DISAS_HVC;
1214 static inline void gen_smc(DisasContext *s)
1216 /* As with HVC, we may take an exception either before or after
1217 * the insn executes.
1219 TCGv_i32 tmp;
1221 gen_set_pc_im(s, s->pc - 4);
1222 tmp = tcg_const_i32(syn_aa32_smc());
1223 gen_helper_pre_smc(cpu_env, tmp);
1224 tcg_temp_free_i32(tmp);
1225 gen_set_pc_im(s, s->pc);
1226 s->base.is_jmp = DISAS_SMC;
1229 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1231 gen_set_condexec(s);
1232 gen_set_pc_im(s, s->pc - offset);
1233 gen_exception_internal(excp);
1234 s->base.is_jmp = DISAS_NORETURN;
1237 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1238 int syn, uint32_t target_el)
1240 gen_set_condexec(s);
1241 gen_set_pc_im(s, s->pc - offset);
1242 gen_exception(excp, syn, target_el);
1243 s->base.is_jmp = DISAS_NORETURN;
1246 /* Force a TB lookup after an instruction that changes the CPU state. */
1247 static inline void gen_lookup_tb(DisasContext *s)
1249 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1250 s->base.is_jmp = DISAS_EXIT;
1253 static inline void gen_hlt(DisasContext *s, int imm)
1255 /* HLT. This has two purposes.
1256 * Architecturally, it is an external halting debug instruction.
1257 * Since QEMU doesn't implement external debug, we treat this as
1258 * it is required for halting debug disabled: it will UNDEF.
1259 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1260 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1261 * must trigger semihosting even for ARMv7 and earlier, where
1262 * HLT was an undefined encoding.
1263 * In system mode, we don't allow userspace access to
1264 * semihosting, to provide some semblance of security
1265 * (and for consistency with our 32-bit semihosting).
1267 if (semihosting_enabled() &&
1268 #ifndef CONFIG_USER_ONLY
1269 s->current_el != 0 &&
1270 #endif
1271 (imm == (s->thumb ? 0x3c : 0xf000))) {
1272 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1273 return;
1276 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1277 default_exception_el(s));
1280 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1281 TCGv_i32 var)
1283 int val, rm, shift, shiftop;
1284 TCGv_i32 offset;
1286 if (!(insn & (1 << 25))) {
1287 /* immediate */
1288 val = insn & 0xfff;
1289 if (!(insn & (1 << 23)))
1290 val = -val;
1291 if (val != 0)
1292 tcg_gen_addi_i32(var, var, val);
1293 } else {
1294 /* shift/register */
1295 rm = (insn) & 0xf;
1296 shift = (insn >> 7) & 0x1f;
1297 shiftop = (insn >> 5) & 3;
1298 offset = load_reg(s, rm);
1299 gen_arm_shift_im(offset, shiftop, shift, 0);
1300 if (!(insn & (1 << 23)))
1301 tcg_gen_sub_i32(var, var, offset);
1302 else
1303 tcg_gen_add_i32(var, var, offset);
1304 tcg_temp_free_i32(offset);
1308 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1309 int extra, TCGv_i32 var)
1311 int val, rm;
1312 TCGv_i32 offset;
1314 if (insn & (1 << 22)) {
1315 /* immediate */
1316 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1317 if (!(insn & (1 << 23)))
1318 val = -val;
1319 val += extra;
1320 if (val != 0)
1321 tcg_gen_addi_i32(var, var, val);
1322 } else {
1323 /* register */
1324 if (extra)
1325 tcg_gen_addi_i32(var, var, extra);
1326 rm = (insn) & 0xf;
1327 offset = load_reg(s, rm);
1328 if (!(insn & (1 << 23)))
1329 tcg_gen_sub_i32(var, var, offset);
1330 else
1331 tcg_gen_add_i32(var, var, offset);
1332 tcg_temp_free_i32(offset);
1336 static TCGv_ptr get_fpstatus_ptr(int neon)
1338 TCGv_ptr statusptr = tcg_temp_new_ptr();
1339 int offset;
1340 if (neon) {
1341 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1342 } else {
1343 offset = offsetof(CPUARMState, vfp.fp_status);
1345 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1346 return statusptr;
1349 #define VFP_OP2(name) \
1350 static inline void gen_vfp_##name(int dp) \
1352 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1353 if (dp) { \
1354 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1355 } else { \
1356 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1358 tcg_temp_free_ptr(fpst); \
1361 VFP_OP2(add)
1362 VFP_OP2(sub)
1363 VFP_OP2(mul)
1364 VFP_OP2(div)
1366 #undef VFP_OP2
1368 static inline void gen_vfp_F1_mul(int dp)
1370 /* Like gen_vfp_mul() but put result in F1 */
1371 TCGv_ptr fpst = get_fpstatus_ptr(0);
1372 if (dp) {
1373 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1374 } else {
1375 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1377 tcg_temp_free_ptr(fpst);
1380 static inline void gen_vfp_F1_neg(int dp)
1382 /* Like gen_vfp_neg() but put result in F1 */
1383 if (dp) {
1384 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1385 } else {
1386 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1390 static inline void gen_vfp_abs(int dp)
1392 if (dp)
1393 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1394 else
1395 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1398 static inline void gen_vfp_neg(int dp)
1400 if (dp)
1401 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1402 else
1403 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1406 static inline void gen_vfp_sqrt(int dp)
1408 if (dp)
1409 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1410 else
1411 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1414 static inline void gen_vfp_cmp(int dp)
1416 if (dp)
1417 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1418 else
1419 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1422 static inline void gen_vfp_cmpe(int dp)
1424 if (dp)
1425 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1426 else
1427 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1430 static inline void gen_vfp_F1_ld0(int dp)
1432 if (dp)
1433 tcg_gen_movi_i64(cpu_F1d, 0);
1434 else
1435 tcg_gen_movi_i32(cpu_F1s, 0);
1438 #define VFP_GEN_ITOF(name) \
1439 static inline void gen_vfp_##name(int dp, int neon) \
1441 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1442 if (dp) { \
1443 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1444 } else { \
1445 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1447 tcg_temp_free_ptr(statusptr); \
1450 VFP_GEN_ITOF(uito)
1451 VFP_GEN_ITOF(sito)
1452 #undef VFP_GEN_ITOF
1454 #define VFP_GEN_FTOI(name) \
1455 static inline void gen_vfp_##name(int dp, int neon) \
1457 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1458 if (dp) { \
1459 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1460 } else { \
1461 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1463 tcg_temp_free_ptr(statusptr); \
1466 VFP_GEN_FTOI(toui)
1467 VFP_GEN_FTOI(touiz)
1468 VFP_GEN_FTOI(tosi)
1469 VFP_GEN_FTOI(tosiz)
1470 #undef VFP_GEN_FTOI
1472 #define VFP_GEN_FIX(name, round) \
1473 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1475 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1476 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1477 if (dp) { \
1478 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1479 statusptr); \
1480 } else { \
1481 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1482 statusptr); \
1484 tcg_temp_free_i32(tmp_shift); \
1485 tcg_temp_free_ptr(statusptr); \
1487 VFP_GEN_FIX(tosh, _round_to_zero)
1488 VFP_GEN_FIX(tosl, _round_to_zero)
1489 VFP_GEN_FIX(touh, _round_to_zero)
1490 VFP_GEN_FIX(toul, _round_to_zero)
1491 VFP_GEN_FIX(shto, )
1492 VFP_GEN_FIX(slto, )
1493 VFP_GEN_FIX(uhto, )
1494 VFP_GEN_FIX(ulto, )
1495 #undef VFP_GEN_FIX
1497 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1499 if (dp) {
1500 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1501 } else {
1502 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1506 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1508 if (dp) {
1509 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1510 } else {
1511 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1515 static inline long
1516 vfp_reg_offset (int dp, int reg)
1518 if (dp)
1519 return offsetof(CPUARMState, vfp.regs[reg]);
1520 else if (reg & 1) {
1521 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1522 + offsetof(CPU_DoubleU, l.upper);
1523 } else {
1524 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1525 + offsetof(CPU_DoubleU, l.lower);
1529 /* Return the offset of a 32-bit piece of a NEON register.
1530 zero is the least significant end of the register. */
1531 static inline long
1532 neon_reg_offset (int reg, int n)
1534 int sreg;
1535 sreg = reg * 2 + n;
1536 return vfp_reg_offset(0, sreg);
1539 static TCGv_i32 neon_load_reg(int reg, int pass)
1541 TCGv_i32 tmp = tcg_temp_new_i32();
1542 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1543 return tmp;
1546 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1548 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1549 tcg_temp_free_i32(var);
1552 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1554 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1557 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1559 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1562 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1564 TCGv_ptr ret = tcg_temp_new_ptr();
1565 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1566 return ret;
1569 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1570 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1571 #define tcg_gen_st_f32 tcg_gen_st_i32
1572 #define tcg_gen_st_f64 tcg_gen_st_i64
1574 static inline void gen_mov_F0_vreg(int dp, int reg)
1576 if (dp)
1577 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1578 else
1579 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1582 static inline void gen_mov_F1_vreg(int dp, int reg)
1584 if (dp)
1585 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1586 else
1587 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1590 static inline void gen_mov_vreg_F0(int dp, int reg)
1592 if (dp)
1593 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1594 else
1595 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1598 #define ARM_CP_RW_BIT (1 << 20)
1600 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1602 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1605 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1607 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1610 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1612 TCGv_i32 var = tcg_temp_new_i32();
1613 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1614 return var;
1617 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1619 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1620 tcg_temp_free_i32(var);
1623 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1625 iwmmxt_store_reg(cpu_M0, rn);
1628 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1630 iwmmxt_load_reg(cpu_M0, rn);
1633 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1635 iwmmxt_load_reg(cpu_V1, rn);
1636 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1639 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1641 iwmmxt_load_reg(cpu_V1, rn);
1642 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1645 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1647 iwmmxt_load_reg(cpu_V1, rn);
1648 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1651 #define IWMMXT_OP(name) \
1652 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1654 iwmmxt_load_reg(cpu_V1, rn); \
1655 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1658 #define IWMMXT_OP_ENV(name) \
1659 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1661 iwmmxt_load_reg(cpu_V1, rn); \
1662 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1665 #define IWMMXT_OP_ENV_SIZE(name) \
1666 IWMMXT_OP_ENV(name##b) \
1667 IWMMXT_OP_ENV(name##w) \
1668 IWMMXT_OP_ENV(name##l)
1670 #define IWMMXT_OP_ENV1(name) \
1671 static inline void gen_op_iwmmxt_##name##_M0(void) \
1673 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1676 IWMMXT_OP(maddsq)
1677 IWMMXT_OP(madduq)
1678 IWMMXT_OP(sadb)
1679 IWMMXT_OP(sadw)
1680 IWMMXT_OP(mulslw)
1681 IWMMXT_OP(mulshw)
1682 IWMMXT_OP(mululw)
1683 IWMMXT_OP(muluhw)
1684 IWMMXT_OP(macsw)
1685 IWMMXT_OP(macuw)
1687 IWMMXT_OP_ENV_SIZE(unpackl)
1688 IWMMXT_OP_ENV_SIZE(unpackh)
1690 IWMMXT_OP_ENV1(unpacklub)
1691 IWMMXT_OP_ENV1(unpackluw)
1692 IWMMXT_OP_ENV1(unpacklul)
1693 IWMMXT_OP_ENV1(unpackhub)
1694 IWMMXT_OP_ENV1(unpackhuw)
1695 IWMMXT_OP_ENV1(unpackhul)
1696 IWMMXT_OP_ENV1(unpacklsb)
1697 IWMMXT_OP_ENV1(unpacklsw)
1698 IWMMXT_OP_ENV1(unpacklsl)
1699 IWMMXT_OP_ENV1(unpackhsb)
1700 IWMMXT_OP_ENV1(unpackhsw)
1701 IWMMXT_OP_ENV1(unpackhsl)
1703 IWMMXT_OP_ENV_SIZE(cmpeq)
1704 IWMMXT_OP_ENV_SIZE(cmpgtu)
1705 IWMMXT_OP_ENV_SIZE(cmpgts)
1707 IWMMXT_OP_ENV_SIZE(mins)
1708 IWMMXT_OP_ENV_SIZE(minu)
1709 IWMMXT_OP_ENV_SIZE(maxs)
1710 IWMMXT_OP_ENV_SIZE(maxu)
1712 IWMMXT_OP_ENV_SIZE(subn)
1713 IWMMXT_OP_ENV_SIZE(addn)
1714 IWMMXT_OP_ENV_SIZE(subu)
1715 IWMMXT_OP_ENV_SIZE(addu)
1716 IWMMXT_OP_ENV_SIZE(subs)
1717 IWMMXT_OP_ENV_SIZE(adds)
1719 IWMMXT_OP_ENV(avgb0)
1720 IWMMXT_OP_ENV(avgb1)
1721 IWMMXT_OP_ENV(avgw0)
1722 IWMMXT_OP_ENV(avgw1)
1724 IWMMXT_OP_ENV(packuw)
1725 IWMMXT_OP_ENV(packul)
1726 IWMMXT_OP_ENV(packuq)
1727 IWMMXT_OP_ENV(packsw)
1728 IWMMXT_OP_ENV(packsl)
1729 IWMMXT_OP_ENV(packsq)
1731 static void gen_op_iwmmxt_set_mup(void)
1733 TCGv_i32 tmp;
1734 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1735 tcg_gen_ori_i32(tmp, tmp, 2);
1736 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1739 static void gen_op_iwmmxt_set_cup(void)
1741 TCGv_i32 tmp;
1742 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1743 tcg_gen_ori_i32(tmp, tmp, 1);
1744 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1747 static void gen_op_iwmmxt_setpsr_nz(void)
1749 TCGv_i32 tmp = tcg_temp_new_i32();
1750 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1751 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1754 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1756 iwmmxt_load_reg(cpu_V1, rn);
1757 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1758 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1761 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1762 TCGv_i32 dest)
1764 int rd;
1765 uint32_t offset;
1766 TCGv_i32 tmp;
1768 rd = (insn >> 16) & 0xf;
1769 tmp = load_reg(s, rd);
1771 offset = (insn & 0xff) << ((insn >> 7) & 2);
1772 if (insn & (1 << 24)) {
1773 /* Pre indexed */
1774 if (insn & (1 << 23))
1775 tcg_gen_addi_i32(tmp, tmp, offset);
1776 else
1777 tcg_gen_addi_i32(tmp, tmp, -offset);
1778 tcg_gen_mov_i32(dest, tmp);
1779 if (insn & (1 << 21))
1780 store_reg(s, rd, tmp);
1781 else
1782 tcg_temp_free_i32(tmp);
1783 } else if (insn & (1 << 21)) {
1784 /* Post indexed */
1785 tcg_gen_mov_i32(dest, tmp);
1786 if (insn & (1 << 23))
1787 tcg_gen_addi_i32(tmp, tmp, offset);
1788 else
1789 tcg_gen_addi_i32(tmp, tmp, -offset);
1790 store_reg(s, rd, tmp);
1791 } else if (!(insn & (1 << 23)))
1792 return 1;
1793 return 0;
1796 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1798 int rd = (insn >> 0) & 0xf;
1799 TCGv_i32 tmp;
1801 if (insn & (1 << 8)) {
1802 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1803 return 1;
1804 } else {
1805 tmp = iwmmxt_load_creg(rd);
1807 } else {
1808 tmp = tcg_temp_new_i32();
1809 iwmmxt_load_reg(cpu_V0, rd);
1810 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1812 tcg_gen_andi_i32(tmp, tmp, mask);
1813 tcg_gen_mov_i32(dest, tmp);
1814 tcg_temp_free_i32(tmp);
1815 return 0;
1818 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1819 (ie. an undefined instruction). */
1820 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1822 int rd, wrd;
1823 int rdhi, rdlo, rd0, rd1, i;
1824 TCGv_i32 addr;
1825 TCGv_i32 tmp, tmp2, tmp3;
1827 if ((insn & 0x0e000e00) == 0x0c000000) {
1828 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1829 wrd = insn & 0xf;
1830 rdlo = (insn >> 12) & 0xf;
1831 rdhi = (insn >> 16) & 0xf;
1832 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1833 iwmmxt_load_reg(cpu_V0, wrd);
1834 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1835 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1836 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1837 } else { /* TMCRR */
1838 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1839 iwmmxt_store_reg(cpu_V0, wrd);
1840 gen_op_iwmmxt_set_mup();
1842 return 0;
1845 wrd = (insn >> 12) & 0xf;
1846 addr = tcg_temp_new_i32();
1847 if (gen_iwmmxt_address(s, insn, addr)) {
1848 tcg_temp_free_i32(addr);
1849 return 1;
1851 if (insn & ARM_CP_RW_BIT) {
1852 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1853 tmp = tcg_temp_new_i32();
1854 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1855 iwmmxt_store_creg(wrd, tmp);
1856 } else {
1857 i = 1;
1858 if (insn & (1 << 8)) {
1859 if (insn & (1 << 22)) { /* WLDRD */
1860 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1861 i = 0;
1862 } else { /* WLDRW wRd */
1863 tmp = tcg_temp_new_i32();
1864 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1866 } else {
1867 tmp = tcg_temp_new_i32();
1868 if (insn & (1 << 22)) { /* WLDRH */
1869 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1870 } else { /* WLDRB */
1871 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1874 if (i) {
1875 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1876 tcg_temp_free_i32(tmp);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd);
1880 } else {
1881 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1882 tmp = iwmmxt_load_creg(wrd);
1883 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1884 } else {
1885 gen_op_iwmmxt_movq_M0_wRn(wrd);
1886 tmp = tcg_temp_new_i32();
1887 if (insn & (1 << 8)) {
1888 if (insn & (1 << 22)) { /* WSTRD */
1889 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1890 } else { /* WSTRW wRd */
1891 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1892 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1894 } else {
1895 if (insn & (1 << 22)) { /* WSTRH */
1896 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1897 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1898 } else { /* WSTRB */
1899 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1900 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1904 tcg_temp_free_i32(tmp);
1906 tcg_temp_free_i32(addr);
1907 return 0;
1910 if ((insn & 0x0f000000) != 0x0e000000)
1911 return 1;
1913 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1914 case 0x000: /* WOR */
1915 wrd = (insn >> 12) & 0xf;
1916 rd0 = (insn >> 0) & 0xf;
1917 rd1 = (insn >> 16) & 0xf;
1918 gen_op_iwmmxt_movq_M0_wRn(rd0);
1919 gen_op_iwmmxt_orq_M0_wRn(rd1);
1920 gen_op_iwmmxt_setpsr_nz();
1921 gen_op_iwmmxt_movq_wRn_M0(wrd);
1922 gen_op_iwmmxt_set_mup();
1923 gen_op_iwmmxt_set_cup();
1924 break;
1925 case 0x011: /* TMCR */
1926 if (insn & 0xf)
1927 return 1;
1928 rd = (insn >> 12) & 0xf;
1929 wrd = (insn >> 16) & 0xf;
1930 switch (wrd) {
1931 case ARM_IWMMXT_wCID:
1932 case ARM_IWMMXT_wCASF:
1933 break;
1934 case ARM_IWMMXT_wCon:
1935 gen_op_iwmmxt_set_cup();
1936 /* Fall through. */
1937 case ARM_IWMMXT_wCSSF:
1938 tmp = iwmmxt_load_creg(wrd);
1939 tmp2 = load_reg(s, rd);
1940 tcg_gen_andc_i32(tmp, tmp, tmp2);
1941 tcg_temp_free_i32(tmp2);
1942 iwmmxt_store_creg(wrd, tmp);
1943 break;
1944 case ARM_IWMMXT_wCGR0:
1945 case ARM_IWMMXT_wCGR1:
1946 case ARM_IWMMXT_wCGR2:
1947 case ARM_IWMMXT_wCGR3:
1948 gen_op_iwmmxt_set_cup();
1949 tmp = load_reg(s, rd);
1950 iwmmxt_store_creg(wrd, tmp);
1951 break;
1952 default:
1953 return 1;
1955 break;
1956 case 0x100: /* WXOR */
1957 wrd = (insn >> 12) & 0xf;
1958 rd0 = (insn >> 0) & 0xf;
1959 rd1 = (insn >> 16) & 0xf;
1960 gen_op_iwmmxt_movq_M0_wRn(rd0);
1961 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1962 gen_op_iwmmxt_setpsr_nz();
1963 gen_op_iwmmxt_movq_wRn_M0(wrd);
1964 gen_op_iwmmxt_set_mup();
1965 gen_op_iwmmxt_set_cup();
1966 break;
1967 case 0x111: /* TMRC */
1968 if (insn & 0xf)
1969 return 1;
1970 rd = (insn >> 12) & 0xf;
1971 wrd = (insn >> 16) & 0xf;
1972 tmp = iwmmxt_load_creg(wrd);
1973 store_reg(s, rd, tmp);
1974 break;
1975 case 0x300: /* WANDN */
1976 wrd = (insn >> 12) & 0xf;
1977 rd0 = (insn >> 0) & 0xf;
1978 rd1 = (insn >> 16) & 0xf;
1979 gen_op_iwmmxt_movq_M0_wRn(rd0);
1980 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1981 gen_op_iwmmxt_andq_M0_wRn(rd1);
1982 gen_op_iwmmxt_setpsr_nz();
1983 gen_op_iwmmxt_movq_wRn_M0(wrd);
1984 gen_op_iwmmxt_set_mup();
1985 gen_op_iwmmxt_set_cup();
1986 break;
1987 case 0x200: /* WAND */
1988 wrd = (insn >> 12) & 0xf;
1989 rd0 = (insn >> 0) & 0xf;
1990 rd1 = (insn >> 16) & 0xf;
1991 gen_op_iwmmxt_movq_M0_wRn(rd0);
1992 gen_op_iwmmxt_andq_M0_wRn(rd1);
1993 gen_op_iwmmxt_setpsr_nz();
1994 gen_op_iwmmxt_movq_wRn_M0(wrd);
1995 gen_op_iwmmxt_set_mup();
1996 gen_op_iwmmxt_set_cup();
1997 break;
1998 case 0x810: case 0xa10: /* WMADD */
1999 wrd = (insn >> 12) & 0xf;
2000 rd0 = (insn >> 0) & 0xf;
2001 rd1 = (insn >> 16) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0);
2003 if (insn & (1 << 21))
2004 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2005 else
2006 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2007 gen_op_iwmmxt_movq_wRn_M0(wrd);
2008 gen_op_iwmmxt_set_mup();
2009 break;
2010 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2011 wrd = (insn >> 12) & 0xf;
2012 rd0 = (insn >> 16) & 0xf;
2013 rd1 = (insn >> 0) & 0xf;
2014 gen_op_iwmmxt_movq_M0_wRn(rd0);
2015 switch ((insn >> 22) & 3) {
2016 case 0:
2017 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2018 break;
2019 case 1:
2020 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2021 break;
2022 case 2:
2023 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2024 break;
2025 case 3:
2026 return 1;
2028 gen_op_iwmmxt_movq_wRn_M0(wrd);
2029 gen_op_iwmmxt_set_mup();
2030 gen_op_iwmmxt_set_cup();
2031 break;
2032 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2033 wrd = (insn >> 12) & 0xf;
2034 rd0 = (insn >> 16) & 0xf;
2035 rd1 = (insn >> 0) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0);
2037 switch ((insn >> 22) & 3) {
2038 case 0:
2039 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2040 break;
2041 case 1:
2042 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2043 break;
2044 case 2:
2045 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2046 break;
2047 case 3:
2048 return 1;
2050 gen_op_iwmmxt_movq_wRn_M0(wrd);
2051 gen_op_iwmmxt_set_mup();
2052 gen_op_iwmmxt_set_cup();
2053 break;
2054 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2055 wrd = (insn >> 12) & 0xf;
2056 rd0 = (insn >> 16) & 0xf;
2057 rd1 = (insn >> 0) & 0xf;
2058 gen_op_iwmmxt_movq_M0_wRn(rd0);
2059 if (insn & (1 << 22))
2060 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2061 else
2062 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2063 if (!(insn & (1 << 20)))
2064 gen_op_iwmmxt_addl_M0_wRn(wrd);
2065 gen_op_iwmmxt_movq_wRn_M0(wrd);
2066 gen_op_iwmmxt_set_mup();
2067 break;
2068 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2069 wrd = (insn >> 12) & 0xf;
2070 rd0 = (insn >> 16) & 0xf;
2071 rd1 = (insn >> 0) & 0xf;
2072 gen_op_iwmmxt_movq_M0_wRn(rd0);
2073 if (insn & (1 << 21)) {
2074 if (insn & (1 << 20))
2075 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2076 else
2077 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2078 } else {
2079 if (insn & (1 << 20))
2080 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2081 else
2082 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2084 gen_op_iwmmxt_movq_wRn_M0(wrd);
2085 gen_op_iwmmxt_set_mup();
2086 break;
2087 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2088 wrd = (insn >> 12) & 0xf;
2089 rd0 = (insn >> 16) & 0xf;
2090 rd1 = (insn >> 0) & 0xf;
2091 gen_op_iwmmxt_movq_M0_wRn(rd0);
2092 if (insn & (1 << 21))
2093 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2094 else
2095 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2096 if (!(insn & (1 << 20))) {
2097 iwmmxt_load_reg(cpu_V1, wrd);
2098 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd);
2101 gen_op_iwmmxt_set_mup();
2102 break;
2103 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2104 wrd = (insn >> 12) & 0xf;
2105 rd0 = (insn >> 16) & 0xf;
2106 rd1 = (insn >> 0) & 0xf;
2107 gen_op_iwmmxt_movq_M0_wRn(rd0);
2108 switch ((insn >> 22) & 3) {
2109 case 0:
2110 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2111 break;
2112 case 1:
2113 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2114 break;
2115 case 2:
2116 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2117 break;
2118 case 3:
2119 return 1;
2121 gen_op_iwmmxt_movq_wRn_M0(wrd);
2122 gen_op_iwmmxt_set_mup();
2123 gen_op_iwmmxt_set_cup();
2124 break;
2125 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2126 wrd = (insn >> 12) & 0xf;
2127 rd0 = (insn >> 16) & 0xf;
2128 rd1 = (insn >> 0) & 0xf;
2129 gen_op_iwmmxt_movq_M0_wRn(rd0);
2130 if (insn & (1 << 22)) {
2131 if (insn & (1 << 20))
2132 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2133 else
2134 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2135 } else {
2136 if (insn & (1 << 20))
2137 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2138 else
2139 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2141 gen_op_iwmmxt_movq_wRn_M0(wrd);
2142 gen_op_iwmmxt_set_mup();
2143 gen_op_iwmmxt_set_cup();
2144 break;
2145 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2146 wrd = (insn >> 12) & 0xf;
2147 rd0 = (insn >> 16) & 0xf;
2148 rd1 = (insn >> 0) & 0xf;
2149 gen_op_iwmmxt_movq_M0_wRn(rd0);
2150 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2151 tcg_gen_andi_i32(tmp, tmp, 7);
2152 iwmmxt_load_reg(cpu_V1, rd1);
2153 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2154 tcg_temp_free_i32(tmp);
2155 gen_op_iwmmxt_movq_wRn_M0(wrd);
2156 gen_op_iwmmxt_set_mup();
2157 break;
2158 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2159 if (((insn >> 6) & 3) == 3)
2160 return 1;
2161 rd = (insn >> 12) & 0xf;
2162 wrd = (insn >> 16) & 0xf;
2163 tmp = load_reg(s, rd);
2164 gen_op_iwmmxt_movq_M0_wRn(wrd);
2165 switch ((insn >> 6) & 3) {
2166 case 0:
2167 tmp2 = tcg_const_i32(0xff);
2168 tmp3 = tcg_const_i32((insn & 7) << 3);
2169 break;
2170 case 1:
2171 tmp2 = tcg_const_i32(0xffff);
2172 tmp3 = tcg_const_i32((insn & 3) << 4);
2173 break;
2174 case 2:
2175 tmp2 = tcg_const_i32(0xffffffff);
2176 tmp3 = tcg_const_i32((insn & 1) << 5);
2177 break;
2178 default:
2179 tmp2 = NULL;
2180 tmp3 = NULL;
2182 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2183 tcg_temp_free_i32(tmp3);
2184 tcg_temp_free_i32(tmp2);
2185 tcg_temp_free_i32(tmp);
2186 gen_op_iwmmxt_movq_wRn_M0(wrd);
2187 gen_op_iwmmxt_set_mup();
2188 break;
2189 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2190 rd = (insn >> 12) & 0xf;
2191 wrd = (insn >> 16) & 0xf;
2192 if (rd == 15 || ((insn >> 22) & 3) == 3)
2193 return 1;
2194 gen_op_iwmmxt_movq_M0_wRn(wrd);
2195 tmp = tcg_temp_new_i32();
2196 switch ((insn >> 22) & 3) {
2197 case 0:
2198 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2199 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2200 if (insn & 8) {
2201 tcg_gen_ext8s_i32(tmp, tmp);
2202 } else {
2203 tcg_gen_andi_i32(tmp, tmp, 0xff);
2205 break;
2206 case 1:
2207 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2208 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2209 if (insn & 8) {
2210 tcg_gen_ext16s_i32(tmp, tmp);
2211 } else {
2212 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2214 break;
2215 case 2:
2216 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2217 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2218 break;
2220 store_reg(s, rd, tmp);
2221 break;
2222 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2223 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2224 return 1;
2225 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2226 switch ((insn >> 22) & 3) {
2227 case 0:
2228 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2229 break;
2230 case 1:
2231 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2232 break;
2233 case 2:
2234 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2235 break;
2237 tcg_gen_shli_i32(tmp, tmp, 28);
2238 gen_set_nzcv(tmp);
2239 tcg_temp_free_i32(tmp);
2240 break;
2241 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2242 if (((insn >> 6) & 3) == 3)
2243 return 1;
2244 rd = (insn >> 12) & 0xf;
2245 wrd = (insn >> 16) & 0xf;
2246 tmp = load_reg(s, rd);
2247 switch ((insn >> 6) & 3) {
2248 case 0:
2249 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2250 break;
2251 case 1:
2252 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2253 break;
2254 case 2:
2255 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2256 break;
2258 tcg_temp_free_i32(tmp);
2259 gen_op_iwmmxt_movq_wRn_M0(wrd);
2260 gen_op_iwmmxt_set_mup();
2261 break;
2262 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2263 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2264 return 1;
2265 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2266 tmp2 = tcg_temp_new_i32();
2267 tcg_gen_mov_i32(tmp2, tmp);
2268 switch ((insn >> 22) & 3) {
2269 case 0:
2270 for (i = 0; i < 7; i ++) {
2271 tcg_gen_shli_i32(tmp2, tmp2, 4);
2272 tcg_gen_and_i32(tmp, tmp, tmp2);
2274 break;
2275 case 1:
2276 for (i = 0; i < 3; i ++) {
2277 tcg_gen_shli_i32(tmp2, tmp2, 8);
2278 tcg_gen_and_i32(tmp, tmp, tmp2);
2280 break;
2281 case 2:
2282 tcg_gen_shli_i32(tmp2, tmp2, 16);
2283 tcg_gen_and_i32(tmp, tmp, tmp2);
2284 break;
2286 gen_set_nzcv(tmp);
2287 tcg_temp_free_i32(tmp2);
2288 tcg_temp_free_i32(tmp);
2289 break;
2290 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2291 wrd = (insn >> 12) & 0xf;
2292 rd0 = (insn >> 16) & 0xf;
2293 gen_op_iwmmxt_movq_M0_wRn(rd0);
2294 switch ((insn >> 22) & 3) {
2295 case 0:
2296 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2297 break;
2298 case 1:
2299 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2300 break;
2301 case 2:
2302 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2303 break;
2304 case 3:
2305 return 1;
2307 gen_op_iwmmxt_movq_wRn_M0(wrd);
2308 gen_op_iwmmxt_set_mup();
2309 break;
2310 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2311 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2312 return 1;
2313 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2314 tmp2 = tcg_temp_new_i32();
2315 tcg_gen_mov_i32(tmp2, tmp);
2316 switch ((insn >> 22) & 3) {
2317 case 0:
2318 for (i = 0; i < 7; i ++) {
2319 tcg_gen_shli_i32(tmp2, tmp2, 4);
2320 tcg_gen_or_i32(tmp, tmp, tmp2);
2322 break;
2323 case 1:
2324 for (i = 0; i < 3; i ++) {
2325 tcg_gen_shli_i32(tmp2, tmp2, 8);
2326 tcg_gen_or_i32(tmp, tmp, tmp2);
2328 break;
2329 case 2:
2330 tcg_gen_shli_i32(tmp2, tmp2, 16);
2331 tcg_gen_or_i32(tmp, tmp, tmp2);
2332 break;
2334 gen_set_nzcv(tmp);
2335 tcg_temp_free_i32(tmp2);
2336 tcg_temp_free_i32(tmp);
2337 break;
2338 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2339 rd = (insn >> 12) & 0xf;
2340 rd0 = (insn >> 16) & 0xf;
2341 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2342 return 1;
2343 gen_op_iwmmxt_movq_M0_wRn(rd0);
2344 tmp = tcg_temp_new_i32();
2345 switch ((insn >> 22) & 3) {
2346 case 0:
2347 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2348 break;
2349 case 1:
2350 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2351 break;
2352 case 2:
2353 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2354 break;
2356 store_reg(s, rd, tmp);
2357 break;
2358 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2359 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2360 wrd = (insn >> 12) & 0xf;
2361 rd0 = (insn >> 16) & 0xf;
2362 rd1 = (insn >> 0) & 0xf;
2363 gen_op_iwmmxt_movq_M0_wRn(rd0);
2364 switch ((insn >> 22) & 3) {
2365 case 0:
2366 if (insn & (1 << 21))
2367 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2368 else
2369 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2370 break;
2371 case 1:
2372 if (insn & (1 << 21))
2373 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2374 else
2375 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2376 break;
2377 case 2:
2378 if (insn & (1 << 21))
2379 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2380 else
2381 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2382 break;
2383 case 3:
2384 return 1;
2386 gen_op_iwmmxt_movq_wRn_M0(wrd);
2387 gen_op_iwmmxt_set_mup();
2388 gen_op_iwmmxt_set_cup();
2389 break;
2390 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2391 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2392 wrd = (insn >> 12) & 0xf;
2393 rd0 = (insn >> 16) & 0xf;
2394 gen_op_iwmmxt_movq_M0_wRn(rd0);
2395 switch ((insn >> 22) & 3) {
2396 case 0:
2397 if (insn & (1 << 21))
2398 gen_op_iwmmxt_unpacklsb_M0();
2399 else
2400 gen_op_iwmmxt_unpacklub_M0();
2401 break;
2402 case 1:
2403 if (insn & (1 << 21))
2404 gen_op_iwmmxt_unpacklsw_M0();
2405 else
2406 gen_op_iwmmxt_unpackluw_M0();
2407 break;
2408 case 2:
2409 if (insn & (1 << 21))
2410 gen_op_iwmmxt_unpacklsl_M0();
2411 else
2412 gen_op_iwmmxt_unpacklul_M0();
2413 break;
2414 case 3:
2415 return 1;
2417 gen_op_iwmmxt_movq_wRn_M0(wrd);
2418 gen_op_iwmmxt_set_mup();
2419 gen_op_iwmmxt_set_cup();
2420 break;
2421 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2422 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2423 wrd = (insn >> 12) & 0xf;
2424 rd0 = (insn >> 16) & 0xf;
2425 gen_op_iwmmxt_movq_M0_wRn(rd0);
2426 switch ((insn >> 22) & 3) {
2427 case 0:
2428 if (insn & (1 << 21))
2429 gen_op_iwmmxt_unpackhsb_M0();
2430 else
2431 gen_op_iwmmxt_unpackhub_M0();
2432 break;
2433 case 1:
2434 if (insn & (1 << 21))
2435 gen_op_iwmmxt_unpackhsw_M0();
2436 else
2437 gen_op_iwmmxt_unpackhuw_M0();
2438 break;
2439 case 2:
2440 if (insn & (1 << 21))
2441 gen_op_iwmmxt_unpackhsl_M0();
2442 else
2443 gen_op_iwmmxt_unpackhul_M0();
2444 break;
2445 case 3:
2446 return 1;
2448 gen_op_iwmmxt_movq_wRn_M0(wrd);
2449 gen_op_iwmmxt_set_mup();
2450 gen_op_iwmmxt_set_cup();
2451 break;
2452 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2453 case 0x214: case 0x614: case 0xa14: case 0xe14:
2454 if (((insn >> 22) & 3) == 0)
2455 return 1;
2456 wrd = (insn >> 12) & 0xf;
2457 rd0 = (insn >> 16) & 0xf;
2458 gen_op_iwmmxt_movq_M0_wRn(rd0);
2459 tmp = tcg_temp_new_i32();
2460 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2461 tcg_temp_free_i32(tmp);
2462 return 1;
2464 switch ((insn >> 22) & 3) {
2465 case 1:
2466 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2467 break;
2468 case 2:
2469 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2470 break;
2471 case 3:
2472 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2473 break;
2475 tcg_temp_free_i32(tmp);
2476 gen_op_iwmmxt_movq_wRn_M0(wrd);
2477 gen_op_iwmmxt_set_mup();
2478 gen_op_iwmmxt_set_cup();
2479 break;
2480 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2481 case 0x014: case 0x414: case 0x814: case 0xc14:
2482 if (((insn >> 22) & 3) == 0)
2483 return 1;
2484 wrd = (insn >> 12) & 0xf;
2485 rd0 = (insn >> 16) & 0xf;
2486 gen_op_iwmmxt_movq_M0_wRn(rd0);
2487 tmp = tcg_temp_new_i32();
2488 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2489 tcg_temp_free_i32(tmp);
2490 return 1;
2492 switch ((insn >> 22) & 3) {
2493 case 1:
2494 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2495 break;
2496 case 2:
2497 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2498 break;
2499 case 3:
2500 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2501 break;
2503 tcg_temp_free_i32(tmp);
2504 gen_op_iwmmxt_movq_wRn_M0(wrd);
2505 gen_op_iwmmxt_set_mup();
2506 gen_op_iwmmxt_set_cup();
2507 break;
2508 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2509 case 0x114: case 0x514: case 0x914: case 0xd14:
2510 if (((insn >> 22) & 3) == 0)
2511 return 1;
2512 wrd = (insn >> 12) & 0xf;
2513 rd0 = (insn >> 16) & 0xf;
2514 gen_op_iwmmxt_movq_M0_wRn(rd0);
2515 tmp = tcg_temp_new_i32();
2516 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2517 tcg_temp_free_i32(tmp);
2518 return 1;
2520 switch ((insn >> 22) & 3) {
2521 case 1:
2522 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2523 break;
2524 case 2:
2525 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2526 break;
2527 case 3:
2528 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2529 break;
2531 tcg_temp_free_i32(tmp);
2532 gen_op_iwmmxt_movq_wRn_M0(wrd);
2533 gen_op_iwmmxt_set_mup();
2534 gen_op_iwmmxt_set_cup();
2535 break;
2536 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2537 case 0x314: case 0x714: case 0xb14: case 0xf14:
2538 if (((insn >> 22) & 3) == 0)
2539 return 1;
2540 wrd = (insn >> 12) & 0xf;
2541 rd0 = (insn >> 16) & 0xf;
2542 gen_op_iwmmxt_movq_M0_wRn(rd0);
2543 tmp = tcg_temp_new_i32();
2544 switch ((insn >> 22) & 3) {
2545 case 1:
2546 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2547 tcg_temp_free_i32(tmp);
2548 return 1;
2550 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2551 break;
2552 case 2:
2553 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2554 tcg_temp_free_i32(tmp);
2555 return 1;
2557 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2558 break;
2559 case 3:
2560 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2561 tcg_temp_free_i32(tmp);
2562 return 1;
2564 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2565 break;
2567 tcg_temp_free_i32(tmp);
2568 gen_op_iwmmxt_movq_wRn_M0(wrd);
2569 gen_op_iwmmxt_set_mup();
2570 gen_op_iwmmxt_set_cup();
2571 break;
2572 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2573 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2574 wrd = (insn >> 12) & 0xf;
2575 rd0 = (insn >> 16) & 0xf;
2576 rd1 = (insn >> 0) & 0xf;
2577 gen_op_iwmmxt_movq_M0_wRn(rd0);
2578 switch ((insn >> 22) & 3) {
2579 case 0:
2580 if (insn & (1 << 21))
2581 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2582 else
2583 gen_op_iwmmxt_minub_M0_wRn(rd1);
2584 break;
2585 case 1:
2586 if (insn & (1 << 21))
2587 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2588 else
2589 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2590 break;
2591 case 2:
2592 if (insn & (1 << 21))
2593 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2594 else
2595 gen_op_iwmmxt_minul_M0_wRn(rd1);
2596 break;
2597 case 3:
2598 return 1;
2600 gen_op_iwmmxt_movq_wRn_M0(wrd);
2601 gen_op_iwmmxt_set_mup();
2602 break;
2603 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2604 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2605 wrd = (insn >> 12) & 0xf;
2606 rd0 = (insn >> 16) & 0xf;
2607 rd1 = (insn >> 0) & 0xf;
2608 gen_op_iwmmxt_movq_M0_wRn(rd0);
2609 switch ((insn >> 22) & 3) {
2610 case 0:
2611 if (insn & (1 << 21))
2612 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2613 else
2614 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2615 break;
2616 case 1:
2617 if (insn & (1 << 21))
2618 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2619 else
2620 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2621 break;
2622 case 2:
2623 if (insn & (1 << 21))
2624 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2625 else
2626 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2627 break;
2628 case 3:
2629 return 1;
2631 gen_op_iwmmxt_movq_wRn_M0(wrd);
2632 gen_op_iwmmxt_set_mup();
2633 break;
2634 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2635 case 0x402: case 0x502: case 0x602: case 0x702:
2636 wrd = (insn >> 12) & 0xf;
2637 rd0 = (insn >> 16) & 0xf;
2638 rd1 = (insn >> 0) & 0xf;
2639 gen_op_iwmmxt_movq_M0_wRn(rd0);
2640 tmp = tcg_const_i32((insn >> 20) & 3);
2641 iwmmxt_load_reg(cpu_V1, rd1);
2642 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2643 tcg_temp_free_i32(tmp);
2644 gen_op_iwmmxt_movq_wRn_M0(wrd);
2645 gen_op_iwmmxt_set_mup();
2646 break;
2647 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2648 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2649 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2650 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2651 wrd = (insn >> 12) & 0xf;
2652 rd0 = (insn >> 16) & 0xf;
2653 rd1 = (insn >> 0) & 0xf;
2654 gen_op_iwmmxt_movq_M0_wRn(rd0);
2655 switch ((insn >> 20) & 0xf) {
2656 case 0x0:
2657 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2658 break;
2659 case 0x1:
2660 gen_op_iwmmxt_subub_M0_wRn(rd1);
2661 break;
2662 case 0x3:
2663 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2664 break;
2665 case 0x4:
2666 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2667 break;
2668 case 0x5:
2669 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2670 break;
2671 case 0x7:
2672 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2673 break;
2674 case 0x8:
2675 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2676 break;
2677 case 0x9:
2678 gen_op_iwmmxt_subul_M0_wRn(rd1);
2679 break;
2680 case 0xb:
2681 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2682 break;
2683 default:
2684 return 1;
2686 gen_op_iwmmxt_movq_wRn_M0(wrd);
2687 gen_op_iwmmxt_set_mup();
2688 gen_op_iwmmxt_set_cup();
2689 break;
2690 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2691 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2692 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2693 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2694 wrd = (insn >> 12) & 0xf;
2695 rd0 = (insn >> 16) & 0xf;
2696 gen_op_iwmmxt_movq_M0_wRn(rd0);
2697 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2698 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2699 tcg_temp_free_i32(tmp);
2700 gen_op_iwmmxt_movq_wRn_M0(wrd);
2701 gen_op_iwmmxt_set_mup();
2702 gen_op_iwmmxt_set_cup();
2703 break;
2704 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2705 case 0x418: case 0x518: case 0x618: case 0x718:
2706 case 0x818: case 0x918: case 0xa18: case 0xb18:
2707 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2708 wrd = (insn >> 12) & 0xf;
2709 rd0 = (insn >> 16) & 0xf;
2710 rd1 = (insn >> 0) & 0xf;
2711 gen_op_iwmmxt_movq_M0_wRn(rd0);
2712 switch ((insn >> 20) & 0xf) {
2713 case 0x0:
2714 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2715 break;
2716 case 0x1:
2717 gen_op_iwmmxt_addub_M0_wRn(rd1);
2718 break;
2719 case 0x3:
2720 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2721 break;
2722 case 0x4:
2723 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2724 break;
2725 case 0x5:
2726 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2727 break;
2728 case 0x7:
2729 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2730 break;
2731 case 0x8:
2732 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2733 break;
2734 case 0x9:
2735 gen_op_iwmmxt_addul_M0_wRn(rd1);
2736 break;
2737 case 0xb:
2738 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2739 break;
2740 default:
2741 return 1;
2743 gen_op_iwmmxt_movq_wRn_M0(wrd);
2744 gen_op_iwmmxt_set_mup();
2745 gen_op_iwmmxt_set_cup();
2746 break;
2747 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2748 case 0x408: case 0x508: case 0x608: case 0x708:
2749 case 0x808: case 0x908: case 0xa08: case 0xb08:
2750 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2751 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2752 return 1;
2753 wrd = (insn >> 12) & 0xf;
2754 rd0 = (insn >> 16) & 0xf;
2755 rd1 = (insn >> 0) & 0xf;
2756 gen_op_iwmmxt_movq_M0_wRn(rd0);
2757 switch ((insn >> 22) & 3) {
2758 case 1:
2759 if (insn & (1 << 21))
2760 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2761 else
2762 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2763 break;
2764 case 2:
2765 if (insn & (1 << 21))
2766 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2767 else
2768 gen_op_iwmmxt_packul_M0_wRn(rd1);
2769 break;
2770 case 3:
2771 if (insn & (1 << 21))
2772 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2773 else
2774 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2775 break;
2777 gen_op_iwmmxt_movq_wRn_M0(wrd);
2778 gen_op_iwmmxt_set_mup();
2779 gen_op_iwmmxt_set_cup();
2780 break;
2781 case 0x201: case 0x203: case 0x205: case 0x207:
2782 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2783 case 0x211: case 0x213: case 0x215: case 0x217:
2784 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2785 wrd = (insn >> 5) & 0xf;
2786 rd0 = (insn >> 12) & 0xf;
2787 rd1 = (insn >> 0) & 0xf;
2788 if (rd0 == 0xf || rd1 == 0xf)
2789 return 1;
2790 gen_op_iwmmxt_movq_M0_wRn(wrd);
2791 tmp = load_reg(s, rd0);
2792 tmp2 = load_reg(s, rd1);
2793 switch ((insn >> 16) & 0xf) {
2794 case 0x0: /* TMIA */
2795 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2796 break;
2797 case 0x8: /* TMIAPH */
2798 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2799 break;
2800 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2801 if (insn & (1 << 16))
2802 tcg_gen_shri_i32(tmp, tmp, 16);
2803 if (insn & (1 << 17))
2804 tcg_gen_shri_i32(tmp2, tmp2, 16);
2805 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2806 break;
2807 default:
2808 tcg_temp_free_i32(tmp2);
2809 tcg_temp_free_i32(tmp);
2810 return 1;
2812 tcg_temp_free_i32(tmp2);
2813 tcg_temp_free_i32(tmp);
2814 gen_op_iwmmxt_movq_wRn_M0(wrd);
2815 gen_op_iwmmxt_set_mup();
2816 break;
2817 default:
2818 return 1;
2821 return 0;
2824 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2825 (ie. an undefined instruction). */
2826 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2828 int acc, rd0, rd1, rdhi, rdlo;
2829 TCGv_i32 tmp, tmp2;
2831 if ((insn & 0x0ff00f10) == 0x0e200010) {
2832 /* Multiply with Internal Accumulate Format */
2833 rd0 = (insn >> 12) & 0xf;
2834 rd1 = insn & 0xf;
2835 acc = (insn >> 5) & 7;
2837 if (acc != 0)
2838 return 1;
2840 tmp = load_reg(s, rd0);
2841 tmp2 = load_reg(s, rd1);
2842 switch ((insn >> 16) & 0xf) {
2843 case 0x0: /* MIA */
2844 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2845 break;
2846 case 0x8: /* MIAPH */
2847 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2848 break;
2849 case 0xc: /* MIABB */
2850 case 0xd: /* MIABT */
2851 case 0xe: /* MIATB */
2852 case 0xf: /* MIATT */
2853 if (insn & (1 << 16))
2854 tcg_gen_shri_i32(tmp, tmp, 16);
2855 if (insn & (1 << 17))
2856 tcg_gen_shri_i32(tmp2, tmp2, 16);
2857 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2858 break;
2859 default:
2860 return 1;
2862 tcg_temp_free_i32(tmp2);
2863 tcg_temp_free_i32(tmp);
2865 gen_op_iwmmxt_movq_wRn_M0(acc);
2866 return 0;
2869 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2870 /* Internal Accumulator Access Format */
2871 rdhi = (insn >> 16) & 0xf;
2872 rdlo = (insn >> 12) & 0xf;
2873 acc = insn & 7;
2875 if (acc != 0)
2876 return 1;
2878 if (insn & ARM_CP_RW_BIT) { /* MRA */
2879 iwmmxt_load_reg(cpu_V0, acc);
2880 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2881 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2882 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2883 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2884 } else { /* MAR */
2885 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2886 iwmmxt_store_reg(cpu_V0, acc);
2888 return 0;
2891 return 1;
2894 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2895 #define VFP_SREG(insn, bigbit, smallbit) \
2896 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2897 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2898 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2899 reg = (((insn) >> (bigbit)) & 0x0f) \
2900 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2901 } else { \
2902 if (insn & (1 << (smallbit))) \
2903 return 1; \
2904 reg = ((insn) >> (bigbit)) & 0x0f; \
2905 }} while (0)
2907 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2908 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2909 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2910 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2911 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2912 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2914 /* Move between integer and VFP cores. */
2915 static TCGv_i32 gen_vfp_mrs(void)
2917 TCGv_i32 tmp = tcg_temp_new_i32();
2918 tcg_gen_mov_i32(tmp, cpu_F0s);
2919 return tmp;
2922 static void gen_vfp_msr(TCGv_i32 tmp)
2924 tcg_gen_mov_i32(cpu_F0s, tmp);
2925 tcg_temp_free_i32(tmp);
2928 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2930 TCGv_i32 tmp = tcg_temp_new_i32();
2931 if (shift)
2932 tcg_gen_shri_i32(var, var, shift);
2933 tcg_gen_ext8u_i32(var, var);
2934 tcg_gen_shli_i32(tmp, var, 8);
2935 tcg_gen_or_i32(var, var, tmp);
2936 tcg_gen_shli_i32(tmp, var, 16);
2937 tcg_gen_or_i32(var, var, tmp);
2938 tcg_temp_free_i32(tmp);
2941 static void gen_neon_dup_low16(TCGv_i32 var)
2943 TCGv_i32 tmp = tcg_temp_new_i32();
2944 tcg_gen_ext16u_i32(var, var);
2945 tcg_gen_shli_i32(tmp, var, 16);
2946 tcg_gen_or_i32(var, var, tmp);
2947 tcg_temp_free_i32(tmp);
2950 static void gen_neon_dup_high16(TCGv_i32 var)
2952 TCGv_i32 tmp = tcg_temp_new_i32();
2953 tcg_gen_andi_i32(var, var, 0xffff0000);
2954 tcg_gen_shri_i32(tmp, var, 16);
2955 tcg_gen_or_i32(var, var, tmp);
2956 tcg_temp_free_i32(tmp);
2959 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2961 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2962 TCGv_i32 tmp = tcg_temp_new_i32();
2963 switch (size) {
2964 case 0:
2965 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2966 gen_neon_dup_u8(tmp, 0);
2967 break;
2968 case 1:
2969 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2970 gen_neon_dup_low16(tmp);
2971 break;
2972 case 2:
2973 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2974 break;
2975 default: /* Avoid compiler warnings. */
2976 abort();
2978 return tmp;
2981 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2982 uint32_t dp)
2984 uint32_t cc = extract32(insn, 20, 2);
2986 if (dp) {
2987 TCGv_i64 frn, frm, dest;
2988 TCGv_i64 tmp, zero, zf, nf, vf;
2990 zero = tcg_const_i64(0);
2992 frn = tcg_temp_new_i64();
2993 frm = tcg_temp_new_i64();
2994 dest = tcg_temp_new_i64();
2996 zf = tcg_temp_new_i64();
2997 nf = tcg_temp_new_i64();
2998 vf = tcg_temp_new_i64();
3000 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3001 tcg_gen_ext_i32_i64(nf, cpu_NF);
3002 tcg_gen_ext_i32_i64(vf, cpu_VF);
3004 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3005 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3006 switch (cc) {
3007 case 0: /* eq: Z */
3008 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3009 frn, frm);
3010 break;
3011 case 1: /* vs: V */
3012 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3013 frn, frm);
3014 break;
3015 case 2: /* ge: N == V -> N ^ V == 0 */
3016 tmp = tcg_temp_new_i64();
3017 tcg_gen_xor_i64(tmp, vf, nf);
3018 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3019 frn, frm);
3020 tcg_temp_free_i64(tmp);
3021 break;
3022 case 3: /* gt: !Z && N == V */
3023 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3024 frn, frm);
3025 tmp = tcg_temp_new_i64();
3026 tcg_gen_xor_i64(tmp, vf, nf);
3027 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3028 dest, frm);
3029 tcg_temp_free_i64(tmp);
3030 break;
3032 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3033 tcg_temp_free_i64(frn);
3034 tcg_temp_free_i64(frm);
3035 tcg_temp_free_i64(dest);
3037 tcg_temp_free_i64(zf);
3038 tcg_temp_free_i64(nf);
3039 tcg_temp_free_i64(vf);
3041 tcg_temp_free_i64(zero);
3042 } else {
3043 TCGv_i32 frn, frm, dest;
3044 TCGv_i32 tmp, zero;
3046 zero = tcg_const_i32(0);
3048 frn = tcg_temp_new_i32();
3049 frm = tcg_temp_new_i32();
3050 dest = tcg_temp_new_i32();
3051 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3052 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3053 switch (cc) {
3054 case 0: /* eq: Z */
3055 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3056 frn, frm);
3057 break;
3058 case 1: /* vs: V */
3059 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3060 frn, frm);
3061 break;
3062 case 2: /* ge: N == V -> N ^ V == 0 */
3063 tmp = tcg_temp_new_i32();
3064 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3065 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3066 frn, frm);
3067 tcg_temp_free_i32(tmp);
3068 break;
3069 case 3: /* gt: !Z && N == V */
3070 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3071 frn, frm);
3072 tmp = tcg_temp_new_i32();
3073 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3074 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3075 dest, frm);
3076 tcg_temp_free_i32(tmp);
3077 break;
3079 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3080 tcg_temp_free_i32(frn);
3081 tcg_temp_free_i32(frm);
3082 tcg_temp_free_i32(dest);
3084 tcg_temp_free_i32(zero);
3087 return 0;
3090 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3091 uint32_t rm, uint32_t dp)
3093 uint32_t vmin = extract32(insn, 6, 1);
3094 TCGv_ptr fpst = get_fpstatus_ptr(0);
3096 if (dp) {
3097 TCGv_i64 frn, frm, dest;
3099 frn = tcg_temp_new_i64();
3100 frm = tcg_temp_new_i64();
3101 dest = tcg_temp_new_i64();
3103 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3104 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3105 if (vmin) {
3106 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3107 } else {
3108 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3110 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3111 tcg_temp_free_i64(frn);
3112 tcg_temp_free_i64(frm);
3113 tcg_temp_free_i64(dest);
3114 } else {
3115 TCGv_i32 frn, frm, dest;
3117 frn = tcg_temp_new_i32();
3118 frm = tcg_temp_new_i32();
3119 dest = tcg_temp_new_i32();
3121 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3122 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3123 if (vmin) {
3124 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3125 } else {
3126 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3128 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3129 tcg_temp_free_i32(frn);
3130 tcg_temp_free_i32(frm);
3131 tcg_temp_free_i32(dest);
3134 tcg_temp_free_ptr(fpst);
3135 return 0;
3138 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3139 int rounding)
3141 TCGv_ptr fpst = get_fpstatus_ptr(0);
3142 TCGv_i32 tcg_rmode;
3144 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3145 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3147 if (dp) {
3148 TCGv_i64 tcg_op;
3149 TCGv_i64 tcg_res;
3150 tcg_op = tcg_temp_new_i64();
3151 tcg_res = tcg_temp_new_i64();
3152 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3153 gen_helper_rintd(tcg_res, tcg_op, fpst);
3154 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3155 tcg_temp_free_i64(tcg_op);
3156 tcg_temp_free_i64(tcg_res);
3157 } else {
3158 TCGv_i32 tcg_op;
3159 TCGv_i32 tcg_res;
3160 tcg_op = tcg_temp_new_i32();
3161 tcg_res = tcg_temp_new_i32();
3162 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3163 gen_helper_rints(tcg_res, tcg_op, fpst);
3164 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3165 tcg_temp_free_i32(tcg_op);
3166 tcg_temp_free_i32(tcg_res);
3169 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3170 tcg_temp_free_i32(tcg_rmode);
3172 tcg_temp_free_ptr(fpst);
3173 return 0;
3176 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3177 int rounding)
3179 bool is_signed = extract32(insn, 7, 1);
3180 TCGv_ptr fpst = get_fpstatus_ptr(0);
3181 TCGv_i32 tcg_rmode, tcg_shift;
3183 tcg_shift = tcg_const_i32(0);
3185 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3186 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3188 if (dp) {
3189 TCGv_i64 tcg_double, tcg_res;
3190 TCGv_i32 tcg_tmp;
3191 /* Rd is encoded as a single precision register even when the source
3192 * is double precision.
3194 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3195 tcg_double = tcg_temp_new_i64();
3196 tcg_res = tcg_temp_new_i64();
3197 tcg_tmp = tcg_temp_new_i32();
3198 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3199 if (is_signed) {
3200 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3201 } else {
3202 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3204 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3205 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3206 tcg_temp_free_i32(tcg_tmp);
3207 tcg_temp_free_i64(tcg_res);
3208 tcg_temp_free_i64(tcg_double);
3209 } else {
3210 TCGv_i32 tcg_single, tcg_res;
3211 tcg_single = tcg_temp_new_i32();
3212 tcg_res = tcg_temp_new_i32();
3213 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3214 if (is_signed) {
3215 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3216 } else {
3217 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3219 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3220 tcg_temp_free_i32(tcg_res);
3221 tcg_temp_free_i32(tcg_single);
3224 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3225 tcg_temp_free_i32(tcg_rmode);
3227 tcg_temp_free_i32(tcg_shift);
3229 tcg_temp_free_ptr(fpst);
3231 return 0;
3234 /* Table for converting the most common AArch32 encoding of
3235 * rounding mode to arm_fprounding order (which matches the
3236 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3238 static const uint8_t fp_decode_rm[] = {
3239 FPROUNDING_TIEAWAY,
3240 FPROUNDING_TIEEVEN,
3241 FPROUNDING_POSINF,
3242 FPROUNDING_NEGINF,
3245 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3247 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3249 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3250 return 1;
3253 if (dp) {
3254 VFP_DREG_D(rd, insn);
3255 VFP_DREG_N(rn, insn);
3256 VFP_DREG_M(rm, insn);
3257 } else {
3258 rd = VFP_SREG_D(insn);
3259 rn = VFP_SREG_N(insn);
3260 rm = VFP_SREG_M(insn);
3263 if ((insn & 0x0f800e50) == 0x0e000a00) {
3264 return handle_vsel(insn, rd, rn, rm, dp);
3265 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3266 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3267 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3268 /* VRINTA, VRINTN, VRINTP, VRINTM */
3269 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3270 return handle_vrint(insn, rd, rm, dp, rounding);
3271 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3272 /* VCVTA, VCVTN, VCVTP, VCVTM */
3273 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3274 return handle_vcvt(insn, rd, rm, dp, rounding);
3276 return 1;
3279 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3280 (ie. an undefined instruction). */
3281 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3283 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3284 int dp, veclen;
3285 TCGv_i32 addr;
3286 TCGv_i32 tmp;
3287 TCGv_i32 tmp2;
3289 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3290 return 1;
3293 /* FIXME: this access check should not take precedence over UNDEF
3294 * for invalid encodings; we will generate incorrect syndrome information
3295 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3297 if (s->fp_excp_el) {
3298 gen_exception_insn(s, 4, EXCP_UDEF,
3299 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3300 return 0;
3303 if (!s->vfp_enabled) {
3304 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3305 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3306 return 1;
3307 rn = (insn >> 16) & 0xf;
3308 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3309 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3310 return 1;
3314 if (extract32(insn, 28, 4) == 0xf) {
3315 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3316 * only used in v8 and above.
3318 return disas_vfp_v8_insn(s, insn);
3321 dp = ((insn & 0xf00) == 0xb00);
3322 switch ((insn >> 24) & 0xf) {
3323 case 0xe:
3324 if (insn & (1 << 4)) {
3325 /* single register transfer */
3326 rd = (insn >> 12) & 0xf;
3327 if (dp) {
3328 int size;
3329 int pass;
3331 VFP_DREG_N(rn, insn);
3332 if (insn & 0xf)
3333 return 1;
3334 if (insn & 0x00c00060
3335 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3336 return 1;
3339 pass = (insn >> 21) & 1;
3340 if (insn & (1 << 22)) {
3341 size = 0;
3342 offset = ((insn >> 5) & 3) * 8;
3343 } else if (insn & (1 << 5)) {
3344 size = 1;
3345 offset = (insn & (1 << 6)) ? 16 : 0;
3346 } else {
3347 size = 2;
3348 offset = 0;
3350 if (insn & ARM_CP_RW_BIT) {
3351 /* vfp->arm */
3352 tmp = neon_load_reg(rn, pass);
3353 switch (size) {
3354 case 0:
3355 if (offset)
3356 tcg_gen_shri_i32(tmp, tmp, offset);
3357 if (insn & (1 << 23))
3358 gen_uxtb(tmp);
3359 else
3360 gen_sxtb(tmp);
3361 break;
3362 case 1:
3363 if (insn & (1 << 23)) {
3364 if (offset) {
3365 tcg_gen_shri_i32(tmp, tmp, 16);
3366 } else {
3367 gen_uxth(tmp);
3369 } else {
3370 if (offset) {
3371 tcg_gen_sari_i32(tmp, tmp, 16);
3372 } else {
3373 gen_sxth(tmp);
3376 break;
3377 case 2:
3378 break;
3380 store_reg(s, rd, tmp);
3381 } else {
3382 /* arm->vfp */
3383 tmp = load_reg(s, rd);
3384 if (insn & (1 << 23)) {
3385 /* VDUP */
3386 if (size == 0) {
3387 gen_neon_dup_u8(tmp, 0);
3388 } else if (size == 1) {
3389 gen_neon_dup_low16(tmp);
3391 for (n = 0; n <= pass * 2; n++) {
3392 tmp2 = tcg_temp_new_i32();
3393 tcg_gen_mov_i32(tmp2, tmp);
3394 neon_store_reg(rn, n, tmp2);
3396 neon_store_reg(rn, n, tmp);
3397 } else {
3398 /* VMOV */
3399 switch (size) {
3400 case 0:
3401 tmp2 = neon_load_reg(rn, pass);
3402 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3403 tcg_temp_free_i32(tmp2);
3404 break;
3405 case 1:
3406 tmp2 = neon_load_reg(rn, pass);
3407 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3408 tcg_temp_free_i32(tmp2);
3409 break;
3410 case 2:
3411 break;
3413 neon_store_reg(rn, pass, tmp);
3416 } else { /* !dp */
3417 if ((insn & 0x6f) != 0x00)
3418 return 1;
3419 rn = VFP_SREG_N(insn);
3420 if (insn & ARM_CP_RW_BIT) {
3421 /* vfp->arm */
3422 if (insn & (1 << 21)) {
3423 /* system register */
3424 rn >>= 1;
3426 switch (rn) {
3427 case ARM_VFP_FPSID:
3428 /* VFP2 allows access to FSID from userspace.
3429 VFP3 restricts all id registers to privileged
3430 accesses. */
3431 if (IS_USER(s)
3432 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3433 return 1;
3435 tmp = load_cpu_field(vfp.xregs[rn]);
3436 break;
3437 case ARM_VFP_FPEXC:
3438 if (IS_USER(s))
3439 return 1;
3440 tmp = load_cpu_field(vfp.xregs[rn]);
3441 break;
3442 case ARM_VFP_FPINST:
3443 case ARM_VFP_FPINST2:
3444 /* Not present in VFP3. */
3445 if (IS_USER(s)
3446 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3447 return 1;
3449 tmp = load_cpu_field(vfp.xregs[rn]);
3450 break;
3451 case ARM_VFP_FPSCR:
3452 if (rd == 15) {
3453 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3454 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3455 } else {
3456 tmp = tcg_temp_new_i32();
3457 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3459 break;
3460 case ARM_VFP_MVFR2:
3461 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3462 return 1;
3464 /* fall through */
3465 case ARM_VFP_MVFR0:
3466 case ARM_VFP_MVFR1:
3467 if (IS_USER(s)
3468 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3469 return 1;
3471 tmp = load_cpu_field(vfp.xregs[rn]);
3472 break;
3473 default:
3474 return 1;
3476 } else {
3477 gen_mov_F0_vreg(0, rn);
3478 tmp = gen_vfp_mrs();
3480 if (rd == 15) {
3481 /* Set the 4 flag bits in the CPSR. */
3482 gen_set_nzcv(tmp);
3483 tcg_temp_free_i32(tmp);
3484 } else {
3485 store_reg(s, rd, tmp);
3487 } else {
3488 /* arm->vfp */
3489 if (insn & (1 << 21)) {
3490 rn >>= 1;
3491 /* system register */
3492 switch (rn) {
3493 case ARM_VFP_FPSID:
3494 case ARM_VFP_MVFR0:
3495 case ARM_VFP_MVFR1:
3496 /* Writes are ignored. */
3497 break;
3498 case ARM_VFP_FPSCR:
3499 tmp = load_reg(s, rd);
3500 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3501 tcg_temp_free_i32(tmp);
3502 gen_lookup_tb(s);
3503 break;
3504 case ARM_VFP_FPEXC:
3505 if (IS_USER(s))
3506 return 1;
3507 /* TODO: VFP subarchitecture support.
3508 * For now, keep the EN bit only */
3509 tmp = load_reg(s, rd);
3510 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3511 store_cpu_field(tmp, vfp.xregs[rn]);
3512 gen_lookup_tb(s);
3513 break;
3514 case ARM_VFP_FPINST:
3515 case ARM_VFP_FPINST2:
3516 if (IS_USER(s)) {
3517 return 1;
3519 tmp = load_reg(s, rd);
3520 store_cpu_field(tmp, vfp.xregs[rn]);
3521 break;
3522 default:
3523 return 1;
3525 } else {
3526 tmp = load_reg(s, rd);
3527 gen_vfp_msr(tmp);
3528 gen_mov_vreg_F0(0, rn);
3532 } else {
3533 /* data processing */
3534 /* The opcode is in bits 23, 21, 20 and 6. */
3535 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3536 if (dp) {
3537 if (op == 15) {
3538 /* rn is opcode */
3539 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3540 } else {
3541 /* rn is register number */
3542 VFP_DREG_N(rn, insn);
3545 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3546 ((rn & 0x1e) == 0x6))) {
3547 /* Integer or single/half precision destination. */
3548 rd = VFP_SREG_D(insn);
3549 } else {
3550 VFP_DREG_D(rd, insn);
3552 if (op == 15 &&
3553 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3554 ((rn & 0x1e) == 0x4))) {
3555 /* VCVT from int or half precision is always from S reg
3556 * regardless of dp bit. VCVT with immediate frac_bits
3557 * has same format as SREG_M.
3559 rm = VFP_SREG_M(insn);
3560 } else {
3561 VFP_DREG_M(rm, insn);
3563 } else {
3564 rn = VFP_SREG_N(insn);
3565 if (op == 15 && rn == 15) {
3566 /* Double precision destination. */
3567 VFP_DREG_D(rd, insn);
3568 } else {
3569 rd = VFP_SREG_D(insn);
3571 /* NB that we implicitly rely on the encoding for the frac_bits
3572 * in VCVT of fixed to float being the same as that of an SREG_M
3574 rm = VFP_SREG_M(insn);
3577 veclen = s->vec_len;
3578 if (op == 15 && rn > 3)
3579 veclen = 0;
3581 /* Shut up compiler warnings. */
3582 delta_m = 0;
3583 delta_d = 0;
3584 bank_mask = 0;
3586 if (veclen > 0) {
3587 if (dp)
3588 bank_mask = 0xc;
3589 else
3590 bank_mask = 0x18;
3592 /* Figure out what type of vector operation this is. */
3593 if ((rd & bank_mask) == 0) {
3594 /* scalar */
3595 veclen = 0;
3596 } else {
3597 if (dp)
3598 delta_d = (s->vec_stride >> 1) + 1;
3599 else
3600 delta_d = s->vec_stride + 1;
3602 if ((rm & bank_mask) == 0) {
3603 /* mixed scalar/vector */
3604 delta_m = 0;
3605 } else {
3606 /* vector */
3607 delta_m = delta_d;
3612 /* Load the initial operands. */
3613 if (op == 15) {
3614 switch (rn) {
3615 case 16:
3616 case 17:
3617 /* Integer source */
3618 gen_mov_F0_vreg(0, rm);
3619 break;
3620 case 8:
3621 case 9:
3622 /* Compare */
3623 gen_mov_F0_vreg(dp, rd);
3624 gen_mov_F1_vreg(dp, rm);
3625 break;
3626 case 10:
3627 case 11:
3628 /* Compare with zero */
3629 gen_mov_F0_vreg(dp, rd);
3630 gen_vfp_F1_ld0(dp);
3631 break;
3632 case 20:
3633 case 21:
3634 case 22:
3635 case 23:
3636 case 28:
3637 case 29:
3638 case 30:
3639 case 31:
3640 /* Source and destination the same. */
3641 gen_mov_F0_vreg(dp, rd);
3642 break;
3643 case 4:
3644 case 5:
3645 case 6:
3646 case 7:
3647 /* VCVTB, VCVTT: only present with the halfprec extension
3648 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3649 * (we choose to UNDEF)
3651 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3652 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3653 return 1;
3655 if (!extract32(rn, 1, 1)) {
3656 /* Half precision source. */
3657 gen_mov_F0_vreg(0, rm);
3658 break;
3660 /* Otherwise fall through */
3661 default:
3662 /* One source operand. */
3663 gen_mov_F0_vreg(dp, rm);
3664 break;
3666 } else {
3667 /* Two source operands. */
3668 gen_mov_F0_vreg(dp, rn);
3669 gen_mov_F1_vreg(dp, rm);
3672 for (;;) {
3673 /* Perform the calculation. */
3674 switch (op) {
3675 case 0: /* VMLA: fd + (fn * fm) */
3676 /* Note that order of inputs to the add matters for NaNs */
3677 gen_vfp_F1_mul(dp);
3678 gen_mov_F0_vreg(dp, rd);
3679 gen_vfp_add(dp);
3680 break;
3681 case 1: /* VMLS: fd + -(fn * fm) */
3682 gen_vfp_mul(dp);
3683 gen_vfp_F1_neg(dp);
3684 gen_mov_F0_vreg(dp, rd);
3685 gen_vfp_add(dp);
3686 break;
3687 case 2: /* VNMLS: -fd + (fn * fm) */
3688 /* Note that it isn't valid to replace (-A + B) with (B - A)
3689 * or similar plausible looking simplifications
3690 * because this will give wrong results for NaNs.
3692 gen_vfp_F1_mul(dp);
3693 gen_mov_F0_vreg(dp, rd);
3694 gen_vfp_neg(dp);
3695 gen_vfp_add(dp);
3696 break;
3697 case 3: /* VNMLA: -fd + -(fn * fm) */
3698 gen_vfp_mul(dp);
3699 gen_vfp_F1_neg(dp);
3700 gen_mov_F0_vreg(dp, rd);
3701 gen_vfp_neg(dp);
3702 gen_vfp_add(dp);
3703 break;
3704 case 4: /* mul: fn * fm */
3705 gen_vfp_mul(dp);
3706 break;
3707 case 5: /* nmul: -(fn * fm) */
3708 gen_vfp_mul(dp);
3709 gen_vfp_neg(dp);
3710 break;
3711 case 6: /* add: fn + fm */
3712 gen_vfp_add(dp);
3713 break;
3714 case 7: /* sub: fn - fm */
3715 gen_vfp_sub(dp);
3716 break;
3717 case 8: /* div: fn / fm */
3718 gen_vfp_div(dp);
3719 break;
3720 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3721 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3722 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3723 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3724 /* These are fused multiply-add, and must be done as one
3725 * floating point operation with no rounding between the
3726 * multiplication and addition steps.
3727 * NB that doing the negations here as separate steps is
3728 * correct : an input NaN should come out with its sign bit
3729 * flipped if it is a negated-input.
3731 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3732 return 1;
3734 if (dp) {
3735 TCGv_ptr fpst;
3736 TCGv_i64 frd;
3737 if (op & 1) {
3738 /* VFNMS, VFMS */
3739 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3741 frd = tcg_temp_new_i64();
3742 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3743 if (op & 2) {
3744 /* VFNMA, VFNMS */
3745 gen_helper_vfp_negd(frd, frd);
3747 fpst = get_fpstatus_ptr(0);
3748 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3749 cpu_F1d, frd, fpst);
3750 tcg_temp_free_ptr(fpst);
3751 tcg_temp_free_i64(frd);
3752 } else {
3753 TCGv_ptr fpst;
3754 TCGv_i32 frd;
3755 if (op & 1) {
3756 /* VFNMS, VFMS */
3757 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3759 frd = tcg_temp_new_i32();
3760 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3761 if (op & 2) {
3762 gen_helper_vfp_negs(frd, frd);
3764 fpst = get_fpstatus_ptr(0);
3765 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3766 cpu_F1s, frd, fpst);
3767 tcg_temp_free_ptr(fpst);
3768 tcg_temp_free_i32(frd);
3770 break;
3771 case 14: /* fconst */
3772 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3773 return 1;
3776 n = (insn << 12) & 0x80000000;
3777 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3778 if (dp) {
3779 if (i & 0x40)
3780 i |= 0x3f80;
3781 else
3782 i |= 0x4000;
3783 n |= i << 16;
3784 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3785 } else {
3786 if (i & 0x40)
3787 i |= 0x780;
3788 else
3789 i |= 0x800;
3790 n |= i << 19;
3791 tcg_gen_movi_i32(cpu_F0s, n);
3793 break;
3794 case 15: /* extension space */
3795 switch (rn) {
3796 case 0: /* cpy */
3797 /* no-op */
3798 break;
3799 case 1: /* abs */
3800 gen_vfp_abs(dp);
3801 break;
3802 case 2: /* neg */
3803 gen_vfp_neg(dp);
3804 break;
3805 case 3: /* sqrt */
3806 gen_vfp_sqrt(dp);
3807 break;
3808 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3809 tmp = gen_vfp_mrs();
3810 tcg_gen_ext16u_i32(tmp, tmp);
3811 if (dp) {
3812 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3813 cpu_env);
3814 } else {
3815 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3816 cpu_env);
3818 tcg_temp_free_i32(tmp);
3819 break;
3820 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3821 tmp = gen_vfp_mrs();
3822 tcg_gen_shri_i32(tmp, tmp, 16);
3823 if (dp) {
3824 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3825 cpu_env);
3826 } else {
3827 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3828 cpu_env);
3830 tcg_temp_free_i32(tmp);
3831 break;
3832 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3833 tmp = tcg_temp_new_i32();
3834 if (dp) {
3835 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3836 cpu_env);
3837 } else {
3838 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3839 cpu_env);
3841 gen_mov_F0_vreg(0, rd);
3842 tmp2 = gen_vfp_mrs();
3843 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3844 tcg_gen_or_i32(tmp, tmp, tmp2);
3845 tcg_temp_free_i32(tmp2);
3846 gen_vfp_msr(tmp);
3847 break;
3848 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3849 tmp = tcg_temp_new_i32();
3850 if (dp) {
3851 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3852 cpu_env);
3853 } else {
3854 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3855 cpu_env);
3857 tcg_gen_shli_i32(tmp, tmp, 16);
3858 gen_mov_F0_vreg(0, rd);
3859 tmp2 = gen_vfp_mrs();
3860 tcg_gen_ext16u_i32(tmp2, tmp2);
3861 tcg_gen_or_i32(tmp, tmp, tmp2);
3862 tcg_temp_free_i32(tmp2);
3863 gen_vfp_msr(tmp);
3864 break;
3865 case 8: /* cmp */
3866 gen_vfp_cmp(dp);
3867 break;
3868 case 9: /* cmpe */
3869 gen_vfp_cmpe(dp);
3870 break;
3871 case 10: /* cmpz */
3872 gen_vfp_cmp(dp);
3873 break;
3874 case 11: /* cmpez */
3875 gen_vfp_F1_ld0(dp);
3876 gen_vfp_cmpe(dp);
3877 break;
3878 case 12: /* vrintr */
3880 TCGv_ptr fpst = get_fpstatus_ptr(0);
3881 if (dp) {
3882 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3883 } else {
3884 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3886 tcg_temp_free_ptr(fpst);
3887 break;
3889 case 13: /* vrintz */
3891 TCGv_ptr fpst = get_fpstatus_ptr(0);
3892 TCGv_i32 tcg_rmode;
3893 tcg_rmode = tcg_const_i32(float_round_to_zero);
3894 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3895 if (dp) {
3896 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3897 } else {
3898 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3900 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3901 tcg_temp_free_i32(tcg_rmode);
3902 tcg_temp_free_ptr(fpst);
3903 break;
3905 case 14: /* vrintx */
3907 TCGv_ptr fpst = get_fpstatus_ptr(0);
3908 if (dp) {
3909 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3910 } else {
3911 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3913 tcg_temp_free_ptr(fpst);
3914 break;
3916 case 15: /* single<->double conversion */
3917 if (dp)
3918 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3919 else
3920 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3921 break;
3922 case 16: /* fuito */
3923 gen_vfp_uito(dp, 0);
3924 break;
3925 case 17: /* fsito */
3926 gen_vfp_sito(dp, 0);
3927 break;
3928 case 20: /* fshto */
3929 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3930 return 1;
3932 gen_vfp_shto(dp, 16 - rm, 0);
3933 break;
3934 case 21: /* fslto */
3935 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3936 return 1;
3938 gen_vfp_slto(dp, 32 - rm, 0);
3939 break;
3940 case 22: /* fuhto */
3941 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3942 return 1;
3944 gen_vfp_uhto(dp, 16 - rm, 0);
3945 break;
3946 case 23: /* fulto */
3947 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3948 return 1;
3950 gen_vfp_ulto(dp, 32 - rm, 0);
3951 break;
3952 case 24: /* ftoui */
3953 gen_vfp_toui(dp, 0);
3954 break;
3955 case 25: /* ftouiz */
3956 gen_vfp_touiz(dp, 0);
3957 break;
3958 case 26: /* ftosi */
3959 gen_vfp_tosi(dp, 0);
3960 break;
3961 case 27: /* ftosiz */
3962 gen_vfp_tosiz(dp, 0);
3963 break;
3964 case 28: /* ftosh */
3965 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3966 return 1;
3968 gen_vfp_tosh(dp, 16 - rm, 0);
3969 break;
3970 case 29: /* ftosl */
3971 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3972 return 1;
3974 gen_vfp_tosl(dp, 32 - rm, 0);
3975 break;
3976 case 30: /* ftouh */
3977 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3978 return 1;
3980 gen_vfp_touh(dp, 16 - rm, 0);
3981 break;
3982 case 31: /* ftoul */
3983 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3984 return 1;
3986 gen_vfp_toul(dp, 32 - rm, 0);
3987 break;
3988 default: /* undefined */
3989 return 1;
3991 break;
3992 default: /* undefined */
3993 return 1;
3996 /* Write back the result. */
3997 if (op == 15 && (rn >= 8 && rn <= 11)) {
3998 /* Comparison, do nothing. */
3999 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4000 (rn & 0x1e) == 0x6)) {
4001 /* VCVT double to int: always integer result.
4002 * VCVT double to half precision is always a single
4003 * precision result.
4005 gen_mov_vreg_F0(0, rd);
4006 } else if (op == 15 && rn == 15) {
4007 /* conversion */
4008 gen_mov_vreg_F0(!dp, rd);
4009 } else {
4010 gen_mov_vreg_F0(dp, rd);
4013 /* break out of the loop if we have finished */
4014 if (veclen == 0)
4015 break;
4017 if (op == 15 && delta_m == 0) {
4018 /* single source one-many */
4019 while (veclen--) {
4020 rd = ((rd + delta_d) & (bank_mask - 1))
4021 | (rd & bank_mask);
4022 gen_mov_vreg_F0(dp, rd);
4024 break;
4026 /* Setup the next operands. */
4027 veclen--;
4028 rd = ((rd + delta_d) & (bank_mask - 1))
4029 | (rd & bank_mask);
4031 if (op == 15) {
4032 /* One source operand. */
4033 rm = ((rm + delta_m) & (bank_mask - 1))
4034 | (rm & bank_mask);
4035 gen_mov_F0_vreg(dp, rm);
4036 } else {
4037 /* Two source operands. */
4038 rn = ((rn + delta_d) & (bank_mask - 1))
4039 | (rn & bank_mask);
4040 gen_mov_F0_vreg(dp, rn);
4041 if (delta_m) {
4042 rm = ((rm + delta_m) & (bank_mask - 1))
4043 | (rm & bank_mask);
4044 gen_mov_F1_vreg(dp, rm);
4049 break;
4050 case 0xc:
4051 case 0xd:
4052 if ((insn & 0x03e00000) == 0x00400000) {
4053 /* two-register transfer */
4054 rn = (insn >> 16) & 0xf;
4055 rd = (insn >> 12) & 0xf;
4056 if (dp) {
4057 VFP_DREG_M(rm, insn);
4058 } else {
4059 rm = VFP_SREG_M(insn);
4062 if (insn & ARM_CP_RW_BIT) {
4063 /* vfp->arm */
4064 if (dp) {
4065 gen_mov_F0_vreg(0, rm * 2);
4066 tmp = gen_vfp_mrs();
4067 store_reg(s, rd, tmp);
4068 gen_mov_F0_vreg(0, rm * 2 + 1);
4069 tmp = gen_vfp_mrs();
4070 store_reg(s, rn, tmp);
4071 } else {
4072 gen_mov_F0_vreg(0, rm);
4073 tmp = gen_vfp_mrs();
4074 store_reg(s, rd, tmp);
4075 gen_mov_F0_vreg(0, rm + 1);
4076 tmp = gen_vfp_mrs();
4077 store_reg(s, rn, tmp);
4079 } else {
4080 /* arm->vfp */
4081 if (dp) {
4082 tmp = load_reg(s, rd);
4083 gen_vfp_msr(tmp);
4084 gen_mov_vreg_F0(0, rm * 2);
4085 tmp = load_reg(s, rn);
4086 gen_vfp_msr(tmp);
4087 gen_mov_vreg_F0(0, rm * 2 + 1);
4088 } else {
4089 tmp = load_reg(s, rd);
4090 gen_vfp_msr(tmp);
4091 gen_mov_vreg_F0(0, rm);
4092 tmp = load_reg(s, rn);
4093 gen_vfp_msr(tmp);
4094 gen_mov_vreg_F0(0, rm + 1);
4097 } else {
4098 /* Load/store */
4099 rn = (insn >> 16) & 0xf;
4100 if (dp)
4101 VFP_DREG_D(rd, insn);
4102 else
4103 rd = VFP_SREG_D(insn);
4104 if ((insn & 0x01200000) == 0x01000000) {
4105 /* Single load/store */
4106 offset = (insn & 0xff) << 2;
4107 if ((insn & (1 << 23)) == 0)
4108 offset = -offset;
4109 if (s->thumb && rn == 15) {
4110 /* This is actually UNPREDICTABLE */
4111 addr = tcg_temp_new_i32();
4112 tcg_gen_movi_i32(addr, s->pc & ~2);
4113 } else {
4114 addr = load_reg(s, rn);
4116 tcg_gen_addi_i32(addr, addr, offset);
4117 if (insn & (1 << 20)) {
4118 gen_vfp_ld(s, dp, addr);
4119 gen_mov_vreg_F0(dp, rd);
4120 } else {
4121 gen_mov_F0_vreg(dp, rd);
4122 gen_vfp_st(s, dp, addr);
4124 tcg_temp_free_i32(addr);
4125 } else {
4126 /* load/store multiple */
4127 int w = insn & (1 << 21);
4128 if (dp)
4129 n = (insn >> 1) & 0x7f;
4130 else
4131 n = insn & 0xff;
4133 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4134 /* P == U , W == 1 => UNDEF */
4135 return 1;
4137 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4138 /* UNPREDICTABLE cases for bad immediates: we choose to
4139 * UNDEF to avoid generating huge numbers of TCG ops
4141 return 1;
4143 if (rn == 15 && w) {
4144 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4145 return 1;
4148 if (s->thumb && rn == 15) {
4149 /* This is actually UNPREDICTABLE */
4150 addr = tcg_temp_new_i32();
4151 tcg_gen_movi_i32(addr, s->pc & ~2);
4152 } else {
4153 addr = load_reg(s, rn);
4155 if (insn & (1 << 24)) /* pre-decrement */
4156 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4158 if (dp)
4159 offset = 8;
4160 else
4161 offset = 4;
4162 for (i = 0; i < n; i++) {
4163 if (insn & ARM_CP_RW_BIT) {
4164 /* load */
4165 gen_vfp_ld(s, dp, addr);
4166 gen_mov_vreg_F0(dp, rd + i);
4167 } else {
4168 /* store */
4169 gen_mov_F0_vreg(dp, rd + i);
4170 gen_vfp_st(s, dp, addr);
4172 tcg_gen_addi_i32(addr, addr, offset);
4174 if (w) {
4175 /* writeback */
4176 if (insn & (1 << 24))
4177 offset = -offset * n;
4178 else if (dp && (insn & 1))
4179 offset = 4;
4180 else
4181 offset = 0;
4183 if (offset != 0)
4184 tcg_gen_addi_i32(addr, addr, offset);
4185 store_reg(s, rn, addr);
4186 } else {
4187 tcg_temp_free_i32(addr);
4191 break;
4192 default:
4193 /* Should never happen. */
4194 return 1;
4196 return 0;
4199 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4201 #ifndef CONFIG_USER_ONLY
4202 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4203 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4204 #else
4205 return true;
4206 #endif
4209 static void gen_goto_ptr(void)
4211 tcg_gen_lookup_and_goto_ptr();
4214 /* This will end the TB but doesn't guarantee we'll return to
4215 * cpu_loop_exec. Any live exit_requests will be processed as we
4216 * enter the next TB.
4218 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4220 if (use_goto_tb(s, dest)) {
4221 tcg_gen_goto_tb(n);
4222 gen_set_pc_im(s, dest);
4223 tcg_gen_exit_tb((uintptr_t)s->base.tb + n);
4224 } else {
4225 gen_set_pc_im(s, dest);
4226 gen_goto_ptr();
4228 s->base.is_jmp = DISAS_NORETURN;
4231 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4233 if (unlikely(is_singlestepping(s))) {
4234 /* An indirect jump so that we still trigger the debug exception. */
4235 if (s->thumb)
4236 dest |= 1;
4237 gen_bx_im(s, dest);
4238 } else {
4239 gen_goto_tb(s, 0, dest);
4243 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4245 if (x)
4246 tcg_gen_sari_i32(t0, t0, 16);
4247 else
4248 gen_sxth(t0);
4249 if (y)
4250 tcg_gen_sari_i32(t1, t1, 16);
4251 else
4252 gen_sxth(t1);
4253 tcg_gen_mul_i32(t0, t0, t1);
4256 /* Return the mask of PSR bits set by a MSR instruction. */
4257 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4259 uint32_t mask;
4261 mask = 0;
4262 if (flags & (1 << 0))
4263 mask |= 0xff;
4264 if (flags & (1 << 1))
4265 mask |= 0xff00;
4266 if (flags & (1 << 2))
4267 mask |= 0xff0000;
4268 if (flags & (1 << 3))
4269 mask |= 0xff000000;
4271 /* Mask out undefined bits. */
4272 mask &= ~CPSR_RESERVED;
4273 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4274 mask &= ~CPSR_T;
4276 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4277 mask &= ~CPSR_Q; /* V5TE in reality*/
4279 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4280 mask &= ~(CPSR_E | CPSR_GE);
4282 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4283 mask &= ~CPSR_IT;
4285 /* Mask out execution state and reserved bits. */
4286 if (!spsr) {
4287 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4289 /* Mask out privileged bits. */
4290 if (IS_USER(s))
4291 mask &= CPSR_USER;
4292 return mask;
4295 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4296 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4298 TCGv_i32 tmp;
4299 if (spsr) {
4300 /* ??? This is also undefined in system mode. */
4301 if (IS_USER(s))
4302 return 1;
4304 tmp = load_cpu_field(spsr);
4305 tcg_gen_andi_i32(tmp, tmp, ~mask);
4306 tcg_gen_andi_i32(t0, t0, mask);
4307 tcg_gen_or_i32(tmp, tmp, t0);
4308 store_cpu_field(tmp, spsr);
4309 } else {
4310 gen_set_cpsr(t0, mask);
4312 tcg_temp_free_i32(t0);
4313 gen_lookup_tb(s);
4314 return 0;
4317 /* Returns nonzero if access to the PSR is not permitted. */
4318 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4320 TCGv_i32 tmp;
4321 tmp = tcg_temp_new_i32();
4322 tcg_gen_movi_i32(tmp, val);
4323 return gen_set_psr(s, mask, spsr, tmp);
4326 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4327 int *tgtmode, int *regno)
4329 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4330 * the target mode and register number, and identify the various
4331 * unpredictable cases.
4332 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4333 * + executed in user mode
4334 * + using R15 as the src/dest register
4335 * + accessing an unimplemented register
4336 * + accessing a register that's inaccessible at current PL/security state*
4337 * + accessing a register that you could access with a different insn
4338 * We choose to UNDEF in all these cases.
4339 * Since we don't know which of the various AArch32 modes we are in
4340 * we have to defer some checks to runtime.
4341 * Accesses to Monitor mode registers from Secure EL1 (which implies
4342 * that EL3 is AArch64) must trap to EL3.
4344 * If the access checks fail this function will emit code to take
4345 * an exception and return false. Otherwise it will return true,
4346 * and set *tgtmode and *regno appropriately.
4348 int exc_target = default_exception_el(s);
4350 /* These instructions are present only in ARMv8, or in ARMv7 with the
4351 * Virtualization Extensions.
4353 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4354 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4355 goto undef;
4358 if (IS_USER(s) || rn == 15) {
4359 goto undef;
4362 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4363 * of registers into (r, sysm).
4365 if (r) {
4366 /* SPSRs for other modes */
4367 switch (sysm) {
4368 case 0xe: /* SPSR_fiq */
4369 *tgtmode = ARM_CPU_MODE_FIQ;
4370 break;
4371 case 0x10: /* SPSR_irq */
4372 *tgtmode = ARM_CPU_MODE_IRQ;
4373 break;
4374 case 0x12: /* SPSR_svc */
4375 *tgtmode = ARM_CPU_MODE_SVC;
4376 break;
4377 case 0x14: /* SPSR_abt */
4378 *tgtmode = ARM_CPU_MODE_ABT;
4379 break;
4380 case 0x16: /* SPSR_und */
4381 *tgtmode = ARM_CPU_MODE_UND;
4382 break;
4383 case 0x1c: /* SPSR_mon */
4384 *tgtmode = ARM_CPU_MODE_MON;
4385 break;
4386 case 0x1e: /* SPSR_hyp */
4387 *tgtmode = ARM_CPU_MODE_HYP;
4388 break;
4389 default: /* unallocated */
4390 goto undef;
4392 /* We arbitrarily assign SPSR a register number of 16. */
4393 *regno = 16;
4394 } else {
4395 /* general purpose registers for other modes */
4396 switch (sysm) {
4397 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4398 *tgtmode = ARM_CPU_MODE_USR;
4399 *regno = sysm + 8;
4400 break;
4401 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4402 *tgtmode = ARM_CPU_MODE_FIQ;
4403 *regno = sysm;
4404 break;
4405 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4406 *tgtmode = ARM_CPU_MODE_IRQ;
4407 *regno = sysm & 1 ? 13 : 14;
4408 break;
4409 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4410 *tgtmode = ARM_CPU_MODE_SVC;
4411 *regno = sysm & 1 ? 13 : 14;
4412 break;
4413 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4414 *tgtmode = ARM_CPU_MODE_ABT;
4415 *regno = sysm & 1 ? 13 : 14;
4416 break;
4417 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4418 *tgtmode = ARM_CPU_MODE_UND;
4419 *regno = sysm & 1 ? 13 : 14;
4420 break;
4421 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4422 *tgtmode = ARM_CPU_MODE_MON;
4423 *regno = sysm & 1 ? 13 : 14;
4424 break;
4425 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4426 *tgtmode = ARM_CPU_MODE_HYP;
4427 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4428 *regno = sysm & 1 ? 13 : 17;
4429 break;
4430 default: /* unallocated */
4431 goto undef;
4435 /* Catch the 'accessing inaccessible register' cases we can detect
4436 * at translate time.
4438 switch (*tgtmode) {
4439 case ARM_CPU_MODE_MON:
4440 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4441 goto undef;
4443 if (s->current_el == 1) {
4444 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4445 * then accesses to Mon registers trap to EL3
4447 exc_target = 3;
4448 goto undef;
4450 break;
4451 case ARM_CPU_MODE_HYP:
4452 /* Note that we can forbid accesses from EL2 here because they
4453 * must be from Hyp mode itself
4455 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4456 goto undef;
4458 break;
4459 default:
4460 break;
4463 return true;
4465 undef:
4466 /* If we get here then some access check did not pass */
4467 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4468 return false;
4471 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4473 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4474 int tgtmode = 0, regno = 0;
4476 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4477 return;
4480 /* Sync state because msr_banked() can raise exceptions */
4481 gen_set_condexec(s);
4482 gen_set_pc_im(s, s->pc - 4);
4483 tcg_reg = load_reg(s, rn);
4484 tcg_tgtmode = tcg_const_i32(tgtmode);
4485 tcg_regno = tcg_const_i32(regno);
4486 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4487 tcg_temp_free_i32(tcg_tgtmode);
4488 tcg_temp_free_i32(tcg_regno);
4489 tcg_temp_free_i32(tcg_reg);
4490 s->base.is_jmp = DISAS_UPDATE;
4493 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4495 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4496 int tgtmode = 0, regno = 0;
4498 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4499 return;
4502 /* Sync state because mrs_banked() can raise exceptions */
4503 gen_set_condexec(s);
4504 gen_set_pc_im(s, s->pc - 4);
4505 tcg_reg = tcg_temp_new_i32();
4506 tcg_tgtmode = tcg_const_i32(tgtmode);
4507 tcg_regno = tcg_const_i32(regno);
4508 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4509 tcg_temp_free_i32(tcg_tgtmode);
4510 tcg_temp_free_i32(tcg_regno);
4511 store_reg(s, rn, tcg_reg);
4512 s->base.is_jmp = DISAS_UPDATE;
4515 /* Store value to PC as for an exception return (ie don't
4516 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4517 * will do the masking based on the new value of the Thumb bit.
4519 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4521 tcg_gen_mov_i32(cpu_R[15], pc);
4522 tcg_temp_free_i32(pc);
4525 /* Generate a v6 exception return. Marks both values as dead. */
4526 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4528 store_pc_exc_ret(s, pc);
4529 /* The cpsr_write_eret helper will mask the low bits of PC
4530 * appropriately depending on the new Thumb bit, so it must
4531 * be called after storing the new PC.
4533 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4534 tcg_temp_free_i32(cpsr);
4535 /* Must exit loop to check un-masked IRQs */
4536 s->base.is_jmp = DISAS_EXIT;
4539 /* Generate an old-style exception return. Marks pc as dead. */
4540 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4542 gen_rfe(s, pc, load_cpu_field(spsr));
4546 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4547 * only call the helper when running single threaded TCG code to ensure
4548 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4549 * just skip this instruction. Currently the SEV/SEVL instructions
4550 * which are *one* of many ways to wake the CPU from WFE are not
4551 * implemented so we can't sleep like WFI does.
4553 static void gen_nop_hint(DisasContext *s, int val)
4555 switch (val) {
4556 /* When running in MTTCG we don't generate jumps to the yield and
4557 * WFE helpers as it won't affect the scheduling of other vCPUs.
4558 * If we wanted to more completely model WFE/SEV so we don't busy
4559 * spin unnecessarily we would need to do something more involved.
4561 case 1: /* yield */
4562 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4563 gen_set_pc_im(s, s->pc);
4564 s->base.is_jmp = DISAS_YIELD;
4566 break;
4567 case 3: /* wfi */
4568 gen_set_pc_im(s, s->pc);
4569 s->base.is_jmp = DISAS_WFI;
4570 break;
4571 case 2: /* wfe */
4572 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4573 gen_set_pc_im(s, s->pc);
4574 s->base.is_jmp = DISAS_WFE;
4576 break;
4577 case 4: /* sev */
4578 case 5: /* sevl */
4579 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4580 default: /* nop */
4581 break;
4585 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4587 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4589 switch (size) {
4590 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4591 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4592 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4593 default: abort();
4597 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4599 switch (size) {
4600 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4601 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4602 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4603 default: return;
4607 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4608 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4609 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4610 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4611 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4613 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4614 switch ((size << 1) | u) { \
4615 case 0: \
4616 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4617 break; \
4618 case 1: \
4619 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4620 break; \
4621 case 2: \
4622 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4623 break; \
4624 case 3: \
4625 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4626 break; \
4627 case 4: \
4628 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4629 break; \
4630 case 5: \
4631 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4632 break; \
4633 default: return 1; \
4634 }} while (0)
4636 #define GEN_NEON_INTEGER_OP(name) do { \
4637 switch ((size << 1) | u) { \
4638 case 0: \
4639 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4640 break; \
4641 case 1: \
4642 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4643 break; \
4644 case 2: \
4645 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4646 break; \
4647 case 3: \
4648 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4649 break; \
4650 case 4: \
4651 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4652 break; \
4653 case 5: \
4654 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4655 break; \
4656 default: return 1; \
4657 }} while (0)
4659 static TCGv_i32 neon_load_scratch(int scratch)
4661 TCGv_i32 tmp = tcg_temp_new_i32();
4662 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4663 return tmp;
4666 static void neon_store_scratch(int scratch, TCGv_i32 var)
4668 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4669 tcg_temp_free_i32(var);
4672 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4674 TCGv_i32 tmp;
4675 if (size == 1) {
4676 tmp = neon_load_reg(reg & 7, reg >> 4);
4677 if (reg & 8) {
4678 gen_neon_dup_high16(tmp);
4679 } else {
4680 gen_neon_dup_low16(tmp);
4682 } else {
4683 tmp = neon_load_reg(reg & 15, reg >> 4);
4685 return tmp;
4688 static int gen_neon_unzip(int rd, int rm, int size, int q)
4690 TCGv_i32 tmp, tmp2;
4691 if (!q && size == 2) {
4692 return 1;
4694 tmp = tcg_const_i32(rd);
4695 tmp2 = tcg_const_i32(rm);
4696 if (q) {
4697 switch (size) {
4698 case 0:
4699 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4700 break;
4701 case 1:
4702 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4703 break;
4704 case 2:
4705 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4706 break;
4707 default:
4708 abort();
4710 } else {
4711 switch (size) {
4712 case 0:
4713 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4714 break;
4715 case 1:
4716 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4717 break;
4718 default:
4719 abort();
4722 tcg_temp_free_i32(tmp);
4723 tcg_temp_free_i32(tmp2);
4724 return 0;
4727 static int gen_neon_zip(int rd, int rm, int size, int q)
4729 TCGv_i32 tmp, tmp2;
4730 if (!q && size == 2) {
4731 return 1;
4733 tmp = tcg_const_i32(rd);
4734 tmp2 = tcg_const_i32(rm);
4735 if (q) {
4736 switch (size) {
4737 case 0:
4738 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4739 break;
4740 case 1:
4741 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4742 break;
4743 case 2:
4744 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4745 break;
4746 default:
4747 abort();
4749 } else {
4750 switch (size) {
4751 case 0:
4752 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4753 break;
4754 case 1:
4755 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4756 break;
4757 default:
4758 abort();
4761 tcg_temp_free_i32(tmp);
4762 tcg_temp_free_i32(tmp2);
4763 return 0;
4766 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4768 TCGv_i32 rd, tmp;
4770 rd = tcg_temp_new_i32();
4771 tmp = tcg_temp_new_i32();
4773 tcg_gen_shli_i32(rd, t0, 8);
4774 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4775 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4776 tcg_gen_or_i32(rd, rd, tmp);
4778 tcg_gen_shri_i32(t1, t1, 8);
4779 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4780 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4781 tcg_gen_or_i32(t1, t1, tmp);
4782 tcg_gen_mov_i32(t0, rd);
4784 tcg_temp_free_i32(tmp);
4785 tcg_temp_free_i32(rd);
4788 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4790 TCGv_i32 rd, tmp;
4792 rd = tcg_temp_new_i32();
4793 tmp = tcg_temp_new_i32();
4795 tcg_gen_shli_i32(rd, t0, 16);
4796 tcg_gen_andi_i32(tmp, t1, 0xffff);
4797 tcg_gen_or_i32(rd, rd, tmp);
4798 tcg_gen_shri_i32(t1, t1, 16);
4799 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4800 tcg_gen_or_i32(t1, t1, tmp);
4801 tcg_gen_mov_i32(t0, rd);
4803 tcg_temp_free_i32(tmp);
4804 tcg_temp_free_i32(rd);
4808 static struct {
4809 int nregs;
4810 int interleave;
4811 int spacing;
4812 } neon_ls_element_type[11] = {
4813 {4, 4, 1},
4814 {4, 4, 2},
4815 {4, 1, 1},
4816 {4, 2, 1},
4817 {3, 3, 1},
4818 {3, 3, 2},
4819 {3, 1, 1},
4820 {1, 1, 1},
4821 {2, 2, 1},
4822 {2, 2, 2},
4823 {2, 1, 1}
4826 /* Translate a NEON load/store element instruction. Return nonzero if the
4827 instruction is invalid. */
4828 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4830 int rd, rn, rm;
4831 int op;
4832 int nregs;
4833 int interleave;
4834 int spacing;
4835 int stride;
4836 int size;
4837 int reg;
4838 int pass;
4839 int load;
4840 int shift;
4841 int n;
4842 TCGv_i32 addr;
4843 TCGv_i32 tmp;
4844 TCGv_i32 tmp2;
4845 TCGv_i64 tmp64;
4847 /* FIXME: this access check should not take precedence over UNDEF
4848 * for invalid encodings; we will generate incorrect syndrome information
4849 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4851 if (s->fp_excp_el) {
4852 gen_exception_insn(s, 4, EXCP_UDEF,
4853 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4854 return 0;
4857 if (!s->vfp_enabled)
4858 return 1;
4859 VFP_DREG_D(rd, insn);
4860 rn = (insn >> 16) & 0xf;
4861 rm = insn & 0xf;
4862 load = (insn & (1 << 21)) != 0;
4863 if ((insn & (1 << 23)) == 0) {
4864 /* Load store all elements. */
4865 op = (insn >> 8) & 0xf;
4866 size = (insn >> 6) & 3;
4867 if (op > 10)
4868 return 1;
4869 /* Catch UNDEF cases for bad values of align field */
4870 switch (op & 0xc) {
4871 case 4:
4872 if (((insn >> 5) & 1) == 1) {
4873 return 1;
4875 break;
4876 case 8:
4877 if (((insn >> 4) & 3) == 3) {
4878 return 1;
4880 break;
4881 default:
4882 break;
4884 nregs = neon_ls_element_type[op].nregs;
4885 interleave = neon_ls_element_type[op].interleave;
4886 spacing = neon_ls_element_type[op].spacing;
4887 if (size == 3 && (interleave | spacing) != 1)
4888 return 1;
4889 addr = tcg_temp_new_i32();
4890 load_reg_var(s, addr, rn);
4891 stride = (1 << size) * interleave;
4892 for (reg = 0; reg < nregs; reg++) {
4893 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4894 load_reg_var(s, addr, rn);
4895 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4896 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4897 load_reg_var(s, addr, rn);
4898 tcg_gen_addi_i32(addr, addr, 1 << size);
4900 if (size == 3) {
4901 tmp64 = tcg_temp_new_i64();
4902 if (load) {
4903 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4904 neon_store_reg64(tmp64, rd);
4905 } else {
4906 neon_load_reg64(tmp64, rd);
4907 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4909 tcg_temp_free_i64(tmp64);
4910 tcg_gen_addi_i32(addr, addr, stride);
4911 } else {
4912 for (pass = 0; pass < 2; pass++) {
4913 if (size == 2) {
4914 if (load) {
4915 tmp = tcg_temp_new_i32();
4916 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4917 neon_store_reg(rd, pass, tmp);
4918 } else {
4919 tmp = neon_load_reg(rd, pass);
4920 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4921 tcg_temp_free_i32(tmp);
4923 tcg_gen_addi_i32(addr, addr, stride);
4924 } else if (size == 1) {
4925 if (load) {
4926 tmp = tcg_temp_new_i32();
4927 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4928 tcg_gen_addi_i32(addr, addr, stride);
4929 tmp2 = tcg_temp_new_i32();
4930 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4931 tcg_gen_addi_i32(addr, addr, stride);
4932 tcg_gen_shli_i32(tmp2, tmp2, 16);
4933 tcg_gen_or_i32(tmp, tmp, tmp2);
4934 tcg_temp_free_i32(tmp2);
4935 neon_store_reg(rd, pass, tmp);
4936 } else {
4937 tmp = neon_load_reg(rd, pass);
4938 tmp2 = tcg_temp_new_i32();
4939 tcg_gen_shri_i32(tmp2, tmp, 16);
4940 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4941 tcg_temp_free_i32(tmp);
4942 tcg_gen_addi_i32(addr, addr, stride);
4943 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4944 tcg_temp_free_i32(tmp2);
4945 tcg_gen_addi_i32(addr, addr, stride);
4947 } else /* size == 0 */ {
4948 if (load) {
4949 tmp2 = NULL;
4950 for (n = 0; n < 4; n++) {
4951 tmp = tcg_temp_new_i32();
4952 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4953 tcg_gen_addi_i32(addr, addr, stride);
4954 if (n == 0) {
4955 tmp2 = tmp;
4956 } else {
4957 tcg_gen_shli_i32(tmp, tmp, n * 8);
4958 tcg_gen_or_i32(tmp2, tmp2, tmp);
4959 tcg_temp_free_i32(tmp);
4962 neon_store_reg(rd, pass, tmp2);
4963 } else {
4964 tmp2 = neon_load_reg(rd, pass);
4965 for (n = 0; n < 4; n++) {
4966 tmp = tcg_temp_new_i32();
4967 if (n == 0) {
4968 tcg_gen_mov_i32(tmp, tmp2);
4969 } else {
4970 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4972 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4973 tcg_temp_free_i32(tmp);
4974 tcg_gen_addi_i32(addr, addr, stride);
4976 tcg_temp_free_i32(tmp2);
4981 rd += spacing;
4983 tcg_temp_free_i32(addr);
4984 stride = nregs * 8;
4985 } else {
4986 size = (insn >> 10) & 3;
4987 if (size == 3) {
4988 /* Load single element to all lanes. */
4989 int a = (insn >> 4) & 1;
4990 if (!load) {
4991 return 1;
4993 size = (insn >> 6) & 3;
4994 nregs = ((insn >> 8) & 3) + 1;
4996 if (size == 3) {
4997 if (nregs != 4 || a == 0) {
4998 return 1;
5000 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5001 size = 2;
5003 if (nregs == 1 && a == 1 && size == 0) {
5004 return 1;
5006 if (nregs == 3 && a == 1) {
5007 return 1;
5009 addr = tcg_temp_new_i32();
5010 load_reg_var(s, addr, rn);
5011 if (nregs == 1) {
5012 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5013 tmp = gen_load_and_replicate(s, addr, size);
5014 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5015 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5016 if (insn & (1 << 5)) {
5017 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5018 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5020 tcg_temp_free_i32(tmp);
5021 } else {
5022 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5023 stride = (insn & (1 << 5)) ? 2 : 1;
5024 for (reg = 0; reg < nregs; reg++) {
5025 tmp = gen_load_and_replicate(s, addr, size);
5026 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5027 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5028 tcg_temp_free_i32(tmp);
5029 tcg_gen_addi_i32(addr, addr, 1 << size);
5030 rd += stride;
5033 tcg_temp_free_i32(addr);
5034 stride = (1 << size) * nregs;
5035 } else {
5036 /* Single element. */
5037 int idx = (insn >> 4) & 0xf;
5038 pass = (insn >> 7) & 1;
5039 switch (size) {
5040 case 0:
5041 shift = ((insn >> 5) & 3) * 8;
5042 stride = 1;
5043 break;
5044 case 1:
5045 shift = ((insn >> 6) & 1) * 16;
5046 stride = (insn & (1 << 5)) ? 2 : 1;
5047 break;
5048 case 2:
5049 shift = 0;
5050 stride = (insn & (1 << 6)) ? 2 : 1;
5051 break;
5052 default:
5053 abort();
5055 nregs = ((insn >> 8) & 3) + 1;
5056 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5057 switch (nregs) {
5058 case 1:
5059 if (((idx & (1 << size)) != 0) ||
5060 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5061 return 1;
5063 break;
5064 case 3:
5065 if ((idx & 1) != 0) {
5066 return 1;
5068 /* fall through */
5069 case 2:
5070 if (size == 2 && (idx & 2) != 0) {
5071 return 1;
5073 break;
5074 case 4:
5075 if ((size == 2) && ((idx & 3) == 3)) {
5076 return 1;
5078 break;
5079 default:
5080 abort();
5082 if ((rd + stride * (nregs - 1)) > 31) {
5083 /* Attempts to write off the end of the register file
5084 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5085 * the neon_load_reg() would write off the end of the array.
5087 return 1;
5089 addr = tcg_temp_new_i32();
5090 load_reg_var(s, addr, rn);
5091 for (reg = 0; reg < nregs; reg++) {
5092 if (load) {
5093 tmp = tcg_temp_new_i32();
5094 switch (size) {
5095 case 0:
5096 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5097 break;
5098 case 1:
5099 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5100 break;
5101 case 2:
5102 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5103 break;
5104 default: /* Avoid compiler warnings. */
5105 abort();
5107 if (size != 2) {
5108 tmp2 = neon_load_reg(rd, pass);
5109 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5110 shift, size ? 16 : 8);
5111 tcg_temp_free_i32(tmp2);
5113 neon_store_reg(rd, pass, tmp);
5114 } else { /* Store */
5115 tmp = neon_load_reg(rd, pass);
5116 if (shift)
5117 tcg_gen_shri_i32(tmp, tmp, shift);
5118 switch (size) {
5119 case 0:
5120 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5121 break;
5122 case 1:
5123 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5124 break;
5125 case 2:
5126 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5127 break;
5129 tcg_temp_free_i32(tmp);
5131 rd += stride;
5132 tcg_gen_addi_i32(addr, addr, 1 << size);
5134 tcg_temp_free_i32(addr);
5135 stride = nregs * (1 << size);
5138 if (rm != 15) {
5139 TCGv_i32 base;
5141 base = load_reg(s, rn);
5142 if (rm == 13) {
5143 tcg_gen_addi_i32(base, base, stride);
5144 } else {
5145 TCGv_i32 index;
5146 index = load_reg(s, rm);
5147 tcg_gen_add_i32(base, base, index);
5148 tcg_temp_free_i32(index);
5150 store_reg(s, rn, base);
5152 return 0;
5155 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5156 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5158 tcg_gen_and_i32(t, t, c);
5159 tcg_gen_andc_i32(f, f, c);
5160 tcg_gen_or_i32(dest, t, f);
5163 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5165 switch (size) {
5166 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5167 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5168 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5169 default: abort();
5173 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5175 switch (size) {
5176 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5177 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5178 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5179 default: abort();
5183 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5185 switch (size) {
5186 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5187 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5188 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5189 default: abort();
5193 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5195 switch (size) {
5196 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5197 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5198 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5199 default: abort();
5203 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5204 int q, int u)
5206 if (q) {
5207 if (u) {
5208 switch (size) {
5209 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5210 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5211 default: abort();
5213 } else {
5214 switch (size) {
5215 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5216 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5217 default: abort();
5220 } else {
5221 if (u) {
5222 switch (size) {
5223 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5224 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5225 default: abort();
5227 } else {
5228 switch (size) {
5229 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5230 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5231 default: abort();
5237 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5239 if (u) {
5240 switch (size) {
5241 case 0: gen_helper_neon_widen_u8(dest, src); break;
5242 case 1: gen_helper_neon_widen_u16(dest, src); break;
5243 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5244 default: abort();
5246 } else {
5247 switch (size) {
5248 case 0: gen_helper_neon_widen_s8(dest, src); break;
5249 case 1: gen_helper_neon_widen_s16(dest, src); break;
5250 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5251 default: abort();
5254 tcg_temp_free_i32(src);
5257 static inline void gen_neon_addl(int size)
5259 switch (size) {
5260 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5261 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5262 case 2: tcg_gen_add_i64(CPU_V001); break;
5263 default: abort();
5267 static inline void gen_neon_subl(int size)
5269 switch (size) {
5270 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5271 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5272 case 2: tcg_gen_sub_i64(CPU_V001); break;
5273 default: abort();
5277 static inline void gen_neon_negl(TCGv_i64 var, int size)
5279 switch (size) {
5280 case 0: gen_helper_neon_negl_u16(var, var); break;
5281 case 1: gen_helper_neon_negl_u32(var, var); break;
5282 case 2:
5283 tcg_gen_neg_i64(var, var);
5284 break;
5285 default: abort();
5289 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5291 switch (size) {
5292 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5293 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5294 default: abort();
5298 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5299 int size, int u)
5301 TCGv_i64 tmp;
5303 switch ((size << 1) | u) {
5304 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5305 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5306 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5307 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5308 case 4:
5309 tmp = gen_muls_i64_i32(a, b);
5310 tcg_gen_mov_i64(dest, tmp);
5311 tcg_temp_free_i64(tmp);
5312 break;
5313 case 5:
5314 tmp = gen_mulu_i64_i32(a, b);
5315 tcg_gen_mov_i64(dest, tmp);
5316 tcg_temp_free_i64(tmp);
5317 break;
5318 default: abort();
5321 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5322 Don't forget to clean them now. */
5323 if (size < 2) {
5324 tcg_temp_free_i32(a);
5325 tcg_temp_free_i32(b);
5329 static void gen_neon_narrow_op(int op, int u, int size,
5330 TCGv_i32 dest, TCGv_i64 src)
5332 if (op) {
5333 if (u) {
5334 gen_neon_unarrow_sats(size, dest, src);
5335 } else {
5336 gen_neon_narrow(size, dest, src);
5338 } else {
5339 if (u) {
5340 gen_neon_narrow_satu(size, dest, src);
5341 } else {
5342 gen_neon_narrow_sats(size, dest, src);
5347 /* Symbolic constants for op fields for Neon 3-register same-length.
5348 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5349 * table A7-9.
5351 #define NEON_3R_VHADD 0
5352 #define NEON_3R_VQADD 1
5353 #define NEON_3R_VRHADD 2
5354 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5355 #define NEON_3R_VHSUB 4
5356 #define NEON_3R_VQSUB 5
5357 #define NEON_3R_VCGT 6
5358 #define NEON_3R_VCGE 7
5359 #define NEON_3R_VSHL 8
5360 #define NEON_3R_VQSHL 9
5361 #define NEON_3R_VRSHL 10
5362 #define NEON_3R_VQRSHL 11
5363 #define NEON_3R_VMAX 12
5364 #define NEON_3R_VMIN 13
5365 #define NEON_3R_VABD 14
5366 #define NEON_3R_VABA 15
5367 #define NEON_3R_VADD_VSUB 16
5368 #define NEON_3R_VTST_VCEQ 17
5369 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5370 #define NEON_3R_VMUL 19
5371 #define NEON_3R_VPMAX 20
5372 #define NEON_3R_VPMIN 21
5373 #define NEON_3R_VQDMULH_VQRDMULH 22
5374 #define NEON_3R_VPADD 23
5375 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5376 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5377 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5378 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5379 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5380 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5381 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5382 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5384 static const uint8_t neon_3r_sizes[] = {
5385 [NEON_3R_VHADD] = 0x7,
5386 [NEON_3R_VQADD] = 0xf,
5387 [NEON_3R_VRHADD] = 0x7,
5388 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5389 [NEON_3R_VHSUB] = 0x7,
5390 [NEON_3R_VQSUB] = 0xf,
5391 [NEON_3R_VCGT] = 0x7,
5392 [NEON_3R_VCGE] = 0x7,
5393 [NEON_3R_VSHL] = 0xf,
5394 [NEON_3R_VQSHL] = 0xf,
5395 [NEON_3R_VRSHL] = 0xf,
5396 [NEON_3R_VQRSHL] = 0xf,
5397 [NEON_3R_VMAX] = 0x7,
5398 [NEON_3R_VMIN] = 0x7,
5399 [NEON_3R_VABD] = 0x7,
5400 [NEON_3R_VABA] = 0x7,
5401 [NEON_3R_VADD_VSUB] = 0xf,
5402 [NEON_3R_VTST_VCEQ] = 0x7,
5403 [NEON_3R_VML] = 0x7,
5404 [NEON_3R_VMUL] = 0x7,
5405 [NEON_3R_VPMAX] = 0x7,
5406 [NEON_3R_VPMIN] = 0x7,
5407 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5408 [NEON_3R_VPADD] = 0x7,
5409 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5410 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5411 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5412 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5413 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5414 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5415 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5416 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5419 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5420 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5421 * table A7-13.
5423 #define NEON_2RM_VREV64 0
5424 #define NEON_2RM_VREV32 1
5425 #define NEON_2RM_VREV16 2
5426 #define NEON_2RM_VPADDL 4
5427 #define NEON_2RM_VPADDL_U 5
5428 #define NEON_2RM_AESE 6 /* Includes AESD */
5429 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5430 #define NEON_2RM_VCLS 8
5431 #define NEON_2RM_VCLZ 9
5432 #define NEON_2RM_VCNT 10
5433 #define NEON_2RM_VMVN 11
5434 #define NEON_2RM_VPADAL 12
5435 #define NEON_2RM_VPADAL_U 13
5436 #define NEON_2RM_VQABS 14
5437 #define NEON_2RM_VQNEG 15
5438 #define NEON_2RM_VCGT0 16
5439 #define NEON_2RM_VCGE0 17
5440 #define NEON_2RM_VCEQ0 18
5441 #define NEON_2RM_VCLE0 19
5442 #define NEON_2RM_VCLT0 20
5443 #define NEON_2RM_SHA1H 21
5444 #define NEON_2RM_VABS 22
5445 #define NEON_2RM_VNEG 23
5446 #define NEON_2RM_VCGT0_F 24
5447 #define NEON_2RM_VCGE0_F 25
5448 #define NEON_2RM_VCEQ0_F 26
5449 #define NEON_2RM_VCLE0_F 27
5450 #define NEON_2RM_VCLT0_F 28
5451 #define NEON_2RM_VABS_F 30
5452 #define NEON_2RM_VNEG_F 31
5453 #define NEON_2RM_VSWP 32
5454 #define NEON_2RM_VTRN 33
5455 #define NEON_2RM_VUZP 34
5456 #define NEON_2RM_VZIP 35
5457 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5458 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5459 #define NEON_2RM_VSHLL 38
5460 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5461 #define NEON_2RM_VRINTN 40
5462 #define NEON_2RM_VRINTX 41
5463 #define NEON_2RM_VRINTA 42
5464 #define NEON_2RM_VRINTZ 43
5465 #define NEON_2RM_VCVT_F16_F32 44
5466 #define NEON_2RM_VRINTM 45
5467 #define NEON_2RM_VCVT_F32_F16 46
5468 #define NEON_2RM_VRINTP 47
5469 #define NEON_2RM_VCVTAU 48
5470 #define NEON_2RM_VCVTAS 49
5471 #define NEON_2RM_VCVTNU 50
5472 #define NEON_2RM_VCVTNS 51
5473 #define NEON_2RM_VCVTPU 52
5474 #define NEON_2RM_VCVTPS 53
5475 #define NEON_2RM_VCVTMU 54
5476 #define NEON_2RM_VCVTMS 55
5477 #define NEON_2RM_VRECPE 56
5478 #define NEON_2RM_VRSQRTE 57
5479 #define NEON_2RM_VRECPE_F 58
5480 #define NEON_2RM_VRSQRTE_F 59
5481 #define NEON_2RM_VCVT_FS 60
5482 #define NEON_2RM_VCVT_FU 61
5483 #define NEON_2RM_VCVT_SF 62
5484 #define NEON_2RM_VCVT_UF 63
5486 static int neon_2rm_is_float_op(int op)
5488 /* Return true if this neon 2reg-misc op is float-to-float */
5489 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5490 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5491 op == NEON_2RM_VRINTM ||
5492 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5493 op >= NEON_2RM_VRECPE_F);
5496 static bool neon_2rm_is_v8_op(int op)
5498 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5499 switch (op) {
5500 case NEON_2RM_VRINTN:
5501 case NEON_2RM_VRINTA:
5502 case NEON_2RM_VRINTM:
5503 case NEON_2RM_VRINTP:
5504 case NEON_2RM_VRINTZ:
5505 case NEON_2RM_VRINTX:
5506 case NEON_2RM_VCVTAU:
5507 case NEON_2RM_VCVTAS:
5508 case NEON_2RM_VCVTNU:
5509 case NEON_2RM_VCVTNS:
5510 case NEON_2RM_VCVTPU:
5511 case NEON_2RM_VCVTPS:
5512 case NEON_2RM_VCVTMU:
5513 case NEON_2RM_VCVTMS:
5514 return true;
5515 default:
5516 return false;
5520 /* Each entry in this array has bit n set if the insn allows
5521 * size value n (otherwise it will UNDEF). Since unallocated
5522 * op values will have no bits set they always UNDEF.
5524 static const uint8_t neon_2rm_sizes[] = {
5525 [NEON_2RM_VREV64] = 0x7,
5526 [NEON_2RM_VREV32] = 0x3,
5527 [NEON_2RM_VREV16] = 0x1,
5528 [NEON_2RM_VPADDL] = 0x7,
5529 [NEON_2RM_VPADDL_U] = 0x7,
5530 [NEON_2RM_AESE] = 0x1,
5531 [NEON_2RM_AESMC] = 0x1,
5532 [NEON_2RM_VCLS] = 0x7,
5533 [NEON_2RM_VCLZ] = 0x7,
5534 [NEON_2RM_VCNT] = 0x1,
5535 [NEON_2RM_VMVN] = 0x1,
5536 [NEON_2RM_VPADAL] = 0x7,
5537 [NEON_2RM_VPADAL_U] = 0x7,
5538 [NEON_2RM_VQABS] = 0x7,
5539 [NEON_2RM_VQNEG] = 0x7,
5540 [NEON_2RM_VCGT0] = 0x7,
5541 [NEON_2RM_VCGE0] = 0x7,
5542 [NEON_2RM_VCEQ0] = 0x7,
5543 [NEON_2RM_VCLE0] = 0x7,
5544 [NEON_2RM_VCLT0] = 0x7,
5545 [NEON_2RM_SHA1H] = 0x4,
5546 [NEON_2RM_VABS] = 0x7,
5547 [NEON_2RM_VNEG] = 0x7,
5548 [NEON_2RM_VCGT0_F] = 0x4,
5549 [NEON_2RM_VCGE0_F] = 0x4,
5550 [NEON_2RM_VCEQ0_F] = 0x4,
5551 [NEON_2RM_VCLE0_F] = 0x4,
5552 [NEON_2RM_VCLT0_F] = 0x4,
5553 [NEON_2RM_VABS_F] = 0x4,
5554 [NEON_2RM_VNEG_F] = 0x4,
5555 [NEON_2RM_VSWP] = 0x1,
5556 [NEON_2RM_VTRN] = 0x7,
5557 [NEON_2RM_VUZP] = 0x7,
5558 [NEON_2RM_VZIP] = 0x7,
5559 [NEON_2RM_VMOVN] = 0x7,
5560 [NEON_2RM_VQMOVN] = 0x7,
5561 [NEON_2RM_VSHLL] = 0x7,
5562 [NEON_2RM_SHA1SU1] = 0x4,
5563 [NEON_2RM_VRINTN] = 0x4,
5564 [NEON_2RM_VRINTX] = 0x4,
5565 [NEON_2RM_VRINTA] = 0x4,
5566 [NEON_2RM_VRINTZ] = 0x4,
5567 [NEON_2RM_VCVT_F16_F32] = 0x2,
5568 [NEON_2RM_VRINTM] = 0x4,
5569 [NEON_2RM_VCVT_F32_F16] = 0x2,
5570 [NEON_2RM_VRINTP] = 0x4,
5571 [NEON_2RM_VCVTAU] = 0x4,
5572 [NEON_2RM_VCVTAS] = 0x4,
5573 [NEON_2RM_VCVTNU] = 0x4,
5574 [NEON_2RM_VCVTNS] = 0x4,
5575 [NEON_2RM_VCVTPU] = 0x4,
5576 [NEON_2RM_VCVTPS] = 0x4,
5577 [NEON_2RM_VCVTMU] = 0x4,
5578 [NEON_2RM_VCVTMS] = 0x4,
5579 [NEON_2RM_VRECPE] = 0x4,
5580 [NEON_2RM_VRSQRTE] = 0x4,
5581 [NEON_2RM_VRECPE_F] = 0x4,
5582 [NEON_2RM_VRSQRTE_F] = 0x4,
5583 [NEON_2RM_VCVT_FS] = 0x4,
5584 [NEON_2RM_VCVT_FU] = 0x4,
5585 [NEON_2RM_VCVT_SF] = 0x4,
5586 [NEON_2RM_VCVT_UF] = 0x4,
5589 /* Translate a NEON data processing instruction. Return nonzero if the
5590 instruction is invalid.
5591 We process data in a mixture of 32-bit and 64-bit chunks.
5592 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5594 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5596 int op;
5597 int q;
5598 int rd, rn, rm;
5599 int size;
5600 int shift;
5601 int pass;
5602 int count;
5603 int pairwise;
5604 int u;
5605 uint32_t imm, mask;
5606 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5607 TCGv_ptr ptr1, ptr2, ptr3;
5608 TCGv_i64 tmp64;
5610 /* FIXME: this access check should not take precedence over UNDEF
5611 * for invalid encodings; we will generate incorrect syndrome information
5612 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5614 if (s->fp_excp_el) {
5615 gen_exception_insn(s, 4, EXCP_UDEF,
5616 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5617 return 0;
5620 if (!s->vfp_enabled)
5621 return 1;
5622 q = (insn & (1 << 6)) != 0;
5623 u = (insn >> 24) & 1;
5624 VFP_DREG_D(rd, insn);
5625 VFP_DREG_N(rn, insn);
5626 VFP_DREG_M(rm, insn);
5627 size = (insn >> 20) & 3;
5628 if ((insn & (1 << 23)) == 0) {
5629 /* Three register same length. */
5630 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5631 /* Catch invalid op and bad size combinations: UNDEF */
5632 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5633 return 1;
5635 /* All insns of this form UNDEF for either this condition or the
5636 * superset of cases "Q==1"; we catch the latter later.
5638 if (q && ((rd | rn | rm) & 1)) {
5639 return 1;
5642 * The SHA-1/SHA-256 3-register instructions require special treatment
5643 * here, as their size field is overloaded as an op type selector, and
5644 * they all consume their input in a single pass.
5646 if (op == NEON_3R_SHA) {
5647 if (!q) {
5648 return 1;
5650 if (!u) { /* SHA-1 */
5651 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5652 return 1;
5654 ptr1 = vfp_reg_ptr(true, rd);
5655 ptr2 = vfp_reg_ptr(true, rn);
5656 ptr3 = vfp_reg_ptr(true, rm);
5657 tmp4 = tcg_const_i32(size);
5658 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5659 tcg_temp_free_i32(tmp4);
5660 } else { /* SHA-256 */
5661 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5662 return 1;
5664 ptr1 = vfp_reg_ptr(true, rd);
5665 ptr2 = vfp_reg_ptr(true, rn);
5666 ptr3 = vfp_reg_ptr(true, rm);
5667 switch (size) {
5668 case 0:
5669 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5670 break;
5671 case 1:
5672 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5673 break;
5674 case 2:
5675 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5676 break;
5679 tcg_temp_free_ptr(ptr1);
5680 tcg_temp_free_ptr(ptr2);
5681 tcg_temp_free_ptr(ptr3);
5682 return 0;
5684 if (size == 3 && op != NEON_3R_LOGIC) {
5685 /* 64-bit element instructions. */
5686 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5687 neon_load_reg64(cpu_V0, rn + pass);
5688 neon_load_reg64(cpu_V1, rm + pass);
5689 switch (op) {
5690 case NEON_3R_VQADD:
5691 if (u) {
5692 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5693 cpu_V0, cpu_V1);
5694 } else {
5695 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5696 cpu_V0, cpu_V1);
5698 break;
5699 case NEON_3R_VQSUB:
5700 if (u) {
5701 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5702 cpu_V0, cpu_V1);
5703 } else {
5704 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5705 cpu_V0, cpu_V1);
5707 break;
5708 case NEON_3R_VSHL:
5709 if (u) {
5710 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5711 } else {
5712 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5714 break;
5715 case NEON_3R_VQSHL:
5716 if (u) {
5717 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5718 cpu_V1, cpu_V0);
5719 } else {
5720 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5721 cpu_V1, cpu_V0);
5723 break;
5724 case NEON_3R_VRSHL:
5725 if (u) {
5726 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5727 } else {
5728 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5730 break;
5731 case NEON_3R_VQRSHL:
5732 if (u) {
5733 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5734 cpu_V1, cpu_V0);
5735 } else {
5736 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5737 cpu_V1, cpu_V0);
5739 break;
5740 case NEON_3R_VADD_VSUB:
5741 if (u) {
5742 tcg_gen_sub_i64(CPU_V001);
5743 } else {
5744 tcg_gen_add_i64(CPU_V001);
5746 break;
5747 default:
5748 abort();
5750 neon_store_reg64(cpu_V0, rd + pass);
5752 return 0;
5754 pairwise = 0;
5755 switch (op) {
5756 case NEON_3R_VSHL:
5757 case NEON_3R_VQSHL:
5758 case NEON_3R_VRSHL:
5759 case NEON_3R_VQRSHL:
5761 int rtmp;
5762 /* Shift instruction operands are reversed. */
5763 rtmp = rn;
5764 rn = rm;
5765 rm = rtmp;
5767 break;
5768 case NEON_3R_VPADD:
5769 if (u) {
5770 return 1;
5772 /* Fall through */
5773 case NEON_3R_VPMAX:
5774 case NEON_3R_VPMIN:
5775 pairwise = 1;
5776 break;
5777 case NEON_3R_FLOAT_ARITH:
5778 pairwise = (u && size < 2); /* if VPADD (float) */
5779 break;
5780 case NEON_3R_FLOAT_MINMAX:
5781 pairwise = u; /* if VPMIN/VPMAX (float) */
5782 break;
5783 case NEON_3R_FLOAT_CMP:
5784 if (!u && size) {
5785 /* no encoding for U=0 C=1x */
5786 return 1;
5788 break;
5789 case NEON_3R_FLOAT_ACMP:
5790 if (!u) {
5791 return 1;
5793 break;
5794 case NEON_3R_FLOAT_MISC:
5795 /* VMAXNM/VMINNM in ARMv8 */
5796 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5797 return 1;
5799 break;
5800 case NEON_3R_VMUL:
5801 if (u && (size != 0)) {
5802 /* UNDEF on invalid size for polynomial subcase */
5803 return 1;
5805 break;
5806 case NEON_3R_VFM:
5807 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5808 return 1;
5810 break;
5811 default:
5812 break;
5815 if (pairwise && q) {
5816 /* All the pairwise insns UNDEF if Q is set */
5817 return 1;
5820 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5822 if (pairwise) {
5823 /* Pairwise. */
5824 if (pass < 1) {
5825 tmp = neon_load_reg(rn, 0);
5826 tmp2 = neon_load_reg(rn, 1);
5827 } else {
5828 tmp = neon_load_reg(rm, 0);
5829 tmp2 = neon_load_reg(rm, 1);
5831 } else {
5832 /* Elementwise. */
5833 tmp = neon_load_reg(rn, pass);
5834 tmp2 = neon_load_reg(rm, pass);
5836 switch (op) {
5837 case NEON_3R_VHADD:
5838 GEN_NEON_INTEGER_OP(hadd);
5839 break;
5840 case NEON_3R_VQADD:
5841 GEN_NEON_INTEGER_OP_ENV(qadd);
5842 break;
5843 case NEON_3R_VRHADD:
5844 GEN_NEON_INTEGER_OP(rhadd);
5845 break;
5846 case NEON_3R_LOGIC: /* Logic ops. */
5847 switch ((u << 2) | size) {
5848 case 0: /* VAND */
5849 tcg_gen_and_i32(tmp, tmp, tmp2);
5850 break;
5851 case 1: /* BIC */
5852 tcg_gen_andc_i32(tmp, tmp, tmp2);
5853 break;
5854 case 2: /* VORR */
5855 tcg_gen_or_i32(tmp, tmp, tmp2);
5856 break;
5857 case 3: /* VORN */
5858 tcg_gen_orc_i32(tmp, tmp, tmp2);
5859 break;
5860 case 4: /* VEOR */
5861 tcg_gen_xor_i32(tmp, tmp, tmp2);
5862 break;
5863 case 5: /* VBSL */
5864 tmp3 = neon_load_reg(rd, pass);
5865 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5866 tcg_temp_free_i32(tmp3);
5867 break;
5868 case 6: /* VBIT */
5869 tmp3 = neon_load_reg(rd, pass);
5870 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5871 tcg_temp_free_i32(tmp3);
5872 break;
5873 case 7: /* VBIF */
5874 tmp3 = neon_load_reg(rd, pass);
5875 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5876 tcg_temp_free_i32(tmp3);
5877 break;
5879 break;
5880 case NEON_3R_VHSUB:
5881 GEN_NEON_INTEGER_OP(hsub);
5882 break;
5883 case NEON_3R_VQSUB:
5884 GEN_NEON_INTEGER_OP_ENV(qsub);
5885 break;
5886 case NEON_3R_VCGT:
5887 GEN_NEON_INTEGER_OP(cgt);
5888 break;
5889 case NEON_3R_VCGE:
5890 GEN_NEON_INTEGER_OP(cge);
5891 break;
5892 case NEON_3R_VSHL:
5893 GEN_NEON_INTEGER_OP(shl);
5894 break;
5895 case NEON_3R_VQSHL:
5896 GEN_NEON_INTEGER_OP_ENV(qshl);
5897 break;
5898 case NEON_3R_VRSHL:
5899 GEN_NEON_INTEGER_OP(rshl);
5900 break;
5901 case NEON_3R_VQRSHL:
5902 GEN_NEON_INTEGER_OP_ENV(qrshl);
5903 break;
5904 case NEON_3R_VMAX:
5905 GEN_NEON_INTEGER_OP(max);
5906 break;
5907 case NEON_3R_VMIN:
5908 GEN_NEON_INTEGER_OP(min);
5909 break;
5910 case NEON_3R_VABD:
5911 GEN_NEON_INTEGER_OP(abd);
5912 break;
5913 case NEON_3R_VABA:
5914 GEN_NEON_INTEGER_OP(abd);
5915 tcg_temp_free_i32(tmp2);
5916 tmp2 = neon_load_reg(rd, pass);
5917 gen_neon_add(size, tmp, tmp2);
5918 break;
5919 case NEON_3R_VADD_VSUB:
5920 if (!u) { /* VADD */
5921 gen_neon_add(size, tmp, tmp2);
5922 } else { /* VSUB */
5923 switch (size) {
5924 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5925 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5926 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5927 default: abort();
5930 break;
5931 case NEON_3R_VTST_VCEQ:
5932 if (!u) { /* VTST */
5933 switch (size) {
5934 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5935 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5936 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5937 default: abort();
5939 } else { /* VCEQ */
5940 switch (size) {
5941 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5942 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5943 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5944 default: abort();
5947 break;
5948 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5949 switch (size) {
5950 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5951 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5952 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5953 default: abort();
5955 tcg_temp_free_i32(tmp2);
5956 tmp2 = neon_load_reg(rd, pass);
5957 if (u) { /* VMLS */
5958 gen_neon_rsb(size, tmp, tmp2);
5959 } else { /* VMLA */
5960 gen_neon_add(size, tmp, tmp2);
5962 break;
5963 case NEON_3R_VMUL:
5964 if (u) { /* polynomial */
5965 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5966 } else { /* Integer */
5967 switch (size) {
5968 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5969 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5970 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5971 default: abort();
5974 break;
5975 case NEON_3R_VPMAX:
5976 GEN_NEON_INTEGER_OP(pmax);
5977 break;
5978 case NEON_3R_VPMIN:
5979 GEN_NEON_INTEGER_OP(pmin);
5980 break;
5981 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5982 if (!u) { /* VQDMULH */
5983 switch (size) {
5984 case 1:
5985 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5986 break;
5987 case 2:
5988 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5989 break;
5990 default: abort();
5992 } else { /* VQRDMULH */
5993 switch (size) {
5994 case 1:
5995 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5996 break;
5997 case 2:
5998 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5999 break;
6000 default: abort();
6003 break;
6004 case NEON_3R_VPADD:
6005 switch (size) {
6006 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6007 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6008 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6009 default: abort();
6011 break;
6012 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6014 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6015 switch ((u << 2) | size) {
6016 case 0: /* VADD */
6017 case 4: /* VPADD */
6018 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6019 break;
6020 case 2: /* VSUB */
6021 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6022 break;
6023 case 6: /* VABD */
6024 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6025 break;
6026 default:
6027 abort();
6029 tcg_temp_free_ptr(fpstatus);
6030 break;
6032 case NEON_3R_FLOAT_MULTIPLY:
6034 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6035 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6036 if (!u) {
6037 tcg_temp_free_i32(tmp2);
6038 tmp2 = neon_load_reg(rd, pass);
6039 if (size == 0) {
6040 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6041 } else {
6042 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6045 tcg_temp_free_ptr(fpstatus);
6046 break;
6048 case NEON_3R_FLOAT_CMP:
6050 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6051 if (!u) {
6052 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6053 } else {
6054 if (size == 0) {
6055 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6056 } else {
6057 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6060 tcg_temp_free_ptr(fpstatus);
6061 break;
6063 case NEON_3R_FLOAT_ACMP:
6065 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6066 if (size == 0) {
6067 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6068 } else {
6069 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6071 tcg_temp_free_ptr(fpstatus);
6072 break;
6074 case NEON_3R_FLOAT_MINMAX:
6076 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6077 if (size == 0) {
6078 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6079 } else {
6080 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6082 tcg_temp_free_ptr(fpstatus);
6083 break;
6085 case NEON_3R_FLOAT_MISC:
6086 if (u) {
6087 /* VMAXNM/VMINNM */
6088 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6089 if (size == 0) {
6090 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6091 } else {
6092 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6094 tcg_temp_free_ptr(fpstatus);
6095 } else {
6096 if (size == 0) {
6097 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6098 } else {
6099 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6102 break;
6103 case NEON_3R_VFM:
6105 /* VFMA, VFMS: fused multiply-add */
6106 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6107 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6108 if (size) {
6109 /* VFMS */
6110 gen_helper_vfp_negs(tmp, tmp);
6112 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6113 tcg_temp_free_i32(tmp3);
6114 tcg_temp_free_ptr(fpstatus);
6115 break;
6117 default:
6118 abort();
6120 tcg_temp_free_i32(tmp2);
6122 /* Save the result. For elementwise operations we can put it
6123 straight into the destination register. For pairwise operations
6124 we have to be careful to avoid clobbering the source operands. */
6125 if (pairwise && rd == rm) {
6126 neon_store_scratch(pass, tmp);
6127 } else {
6128 neon_store_reg(rd, pass, tmp);
6131 } /* for pass */
6132 if (pairwise && rd == rm) {
6133 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6134 tmp = neon_load_scratch(pass);
6135 neon_store_reg(rd, pass, tmp);
6138 /* End of 3 register same size operations. */
6139 } else if (insn & (1 << 4)) {
6140 if ((insn & 0x00380080) != 0) {
6141 /* Two registers and shift. */
6142 op = (insn >> 8) & 0xf;
6143 if (insn & (1 << 7)) {
6144 /* 64-bit shift. */
6145 if (op > 7) {
6146 return 1;
6148 size = 3;
6149 } else {
6150 size = 2;
6151 while ((insn & (1 << (size + 19))) == 0)
6152 size--;
6154 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6155 /* To avoid excessive duplication of ops we implement shift
6156 by immediate using the variable shift operations. */
6157 if (op < 8) {
6158 /* Shift by immediate:
6159 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6160 if (q && ((rd | rm) & 1)) {
6161 return 1;
6163 if (!u && (op == 4 || op == 6)) {
6164 return 1;
6166 /* Right shifts are encoded as N - shift, where N is the
6167 element size in bits. */
6168 if (op <= 4)
6169 shift = shift - (1 << (size + 3));
6170 if (size == 3) {
6171 count = q + 1;
6172 } else {
6173 count = q ? 4: 2;
6175 switch (size) {
6176 case 0:
6177 imm = (uint8_t) shift;
6178 imm |= imm << 8;
6179 imm |= imm << 16;
6180 break;
6181 case 1:
6182 imm = (uint16_t) shift;
6183 imm |= imm << 16;
6184 break;
6185 case 2:
6186 case 3:
6187 imm = shift;
6188 break;
6189 default:
6190 abort();
6193 for (pass = 0; pass < count; pass++) {
6194 if (size == 3) {
6195 neon_load_reg64(cpu_V0, rm + pass);
6196 tcg_gen_movi_i64(cpu_V1, imm);
6197 switch (op) {
6198 case 0: /* VSHR */
6199 case 1: /* VSRA */
6200 if (u)
6201 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6202 else
6203 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6204 break;
6205 case 2: /* VRSHR */
6206 case 3: /* VRSRA */
6207 if (u)
6208 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6209 else
6210 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6211 break;
6212 case 4: /* VSRI */
6213 case 5: /* VSHL, VSLI */
6214 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6215 break;
6216 case 6: /* VQSHLU */
6217 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6218 cpu_V0, cpu_V1);
6219 break;
6220 case 7: /* VQSHL */
6221 if (u) {
6222 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6223 cpu_V0, cpu_V1);
6224 } else {
6225 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6226 cpu_V0, cpu_V1);
6228 break;
6230 if (op == 1 || op == 3) {
6231 /* Accumulate. */
6232 neon_load_reg64(cpu_V1, rd + pass);
6233 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6234 } else if (op == 4 || (op == 5 && u)) {
6235 /* Insert */
6236 neon_load_reg64(cpu_V1, rd + pass);
6237 uint64_t mask;
6238 if (shift < -63 || shift > 63) {
6239 mask = 0;
6240 } else {
6241 if (op == 4) {
6242 mask = 0xffffffffffffffffull >> -shift;
6243 } else {
6244 mask = 0xffffffffffffffffull << shift;
6247 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6248 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6250 neon_store_reg64(cpu_V0, rd + pass);
6251 } else { /* size < 3 */
6252 /* Operands in T0 and T1. */
6253 tmp = neon_load_reg(rm, pass);
6254 tmp2 = tcg_temp_new_i32();
6255 tcg_gen_movi_i32(tmp2, imm);
6256 switch (op) {
6257 case 0: /* VSHR */
6258 case 1: /* VSRA */
6259 GEN_NEON_INTEGER_OP(shl);
6260 break;
6261 case 2: /* VRSHR */
6262 case 3: /* VRSRA */
6263 GEN_NEON_INTEGER_OP(rshl);
6264 break;
6265 case 4: /* VSRI */
6266 case 5: /* VSHL, VSLI */
6267 switch (size) {
6268 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6269 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6270 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6271 default: abort();
6273 break;
6274 case 6: /* VQSHLU */
6275 switch (size) {
6276 case 0:
6277 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6278 tmp, tmp2);
6279 break;
6280 case 1:
6281 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6282 tmp, tmp2);
6283 break;
6284 case 2:
6285 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6286 tmp, tmp2);
6287 break;
6288 default:
6289 abort();
6291 break;
6292 case 7: /* VQSHL */
6293 GEN_NEON_INTEGER_OP_ENV(qshl);
6294 break;
6296 tcg_temp_free_i32(tmp2);
6298 if (op == 1 || op == 3) {
6299 /* Accumulate. */
6300 tmp2 = neon_load_reg(rd, pass);
6301 gen_neon_add(size, tmp, tmp2);
6302 tcg_temp_free_i32(tmp2);
6303 } else if (op == 4 || (op == 5 && u)) {
6304 /* Insert */
6305 switch (size) {
6306 case 0:
6307 if (op == 4)
6308 mask = 0xff >> -shift;
6309 else
6310 mask = (uint8_t)(0xff << shift);
6311 mask |= mask << 8;
6312 mask |= mask << 16;
6313 break;
6314 case 1:
6315 if (op == 4)
6316 mask = 0xffff >> -shift;
6317 else
6318 mask = (uint16_t)(0xffff << shift);
6319 mask |= mask << 16;
6320 break;
6321 case 2:
6322 if (shift < -31 || shift > 31) {
6323 mask = 0;
6324 } else {
6325 if (op == 4)
6326 mask = 0xffffffffu >> -shift;
6327 else
6328 mask = 0xffffffffu << shift;
6330 break;
6331 default:
6332 abort();
6334 tmp2 = neon_load_reg(rd, pass);
6335 tcg_gen_andi_i32(tmp, tmp, mask);
6336 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6337 tcg_gen_or_i32(tmp, tmp, tmp2);
6338 tcg_temp_free_i32(tmp2);
6340 neon_store_reg(rd, pass, tmp);
6342 } /* for pass */
6343 } else if (op < 10) {
6344 /* Shift by immediate and narrow:
6345 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6346 int input_unsigned = (op == 8) ? !u : u;
6347 if (rm & 1) {
6348 return 1;
6350 shift = shift - (1 << (size + 3));
6351 size++;
6352 if (size == 3) {
6353 tmp64 = tcg_const_i64(shift);
6354 neon_load_reg64(cpu_V0, rm);
6355 neon_load_reg64(cpu_V1, rm + 1);
6356 for (pass = 0; pass < 2; pass++) {
6357 TCGv_i64 in;
6358 if (pass == 0) {
6359 in = cpu_V0;
6360 } else {
6361 in = cpu_V1;
6363 if (q) {
6364 if (input_unsigned) {
6365 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6366 } else {
6367 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6369 } else {
6370 if (input_unsigned) {
6371 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6372 } else {
6373 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6376 tmp = tcg_temp_new_i32();
6377 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6378 neon_store_reg(rd, pass, tmp);
6379 } /* for pass */
6380 tcg_temp_free_i64(tmp64);
6381 } else {
6382 if (size == 1) {
6383 imm = (uint16_t)shift;
6384 imm |= imm << 16;
6385 } else {
6386 /* size == 2 */
6387 imm = (uint32_t)shift;
6389 tmp2 = tcg_const_i32(imm);
6390 tmp4 = neon_load_reg(rm + 1, 0);
6391 tmp5 = neon_load_reg(rm + 1, 1);
6392 for (pass = 0; pass < 2; pass++) {
6393 if (pass == 0) {
6394 tmp = neon_load_reg(rm, 0);
6395 } else {
6396 tmp = tmp4;
6398 gen_neon_shift_narrow(size, tmp, tmp2, q,
6399 input_unsigned);
6400 if (pass == 0) {
6401 tmp3 = neon_load_reg(rm, 1);
6402 } else {
6403 tmp3 = tmp5;
6405 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6406 input_unsigned);
6407 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6408 tcg_temp_free_i32(tmp);
6409 tcg_temp_free_i32(tmp3);
6410 tmp = tcg_temp_new_i32();
6411 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6412 neon_store_reg(rd, pass, tmp);
6413 } /* for pass */
6414 tcg_temp_free_i32(tmp2);
6416 } else if (op == 10) {
6417 /* VSHLL, VMOVL */
6418 if (q || (rd & 1)) {
6419 return 1;
6421 tmp = neon_load_reg(rm, 0);
6422 tmp2 = neon_load_reg(rm, 1);
6423 for (pass = 0; pass < 2; pass++) {
6424 if (pass == 1)
6425 tmp = tmp2;
6427 gen_neon_widen(cpu_V0, tmp, size, u);
6429 if (shift != 0) {
6430 /* The shift is less than the width of the source
6431 type, so we can just shift the whole register. */
6432 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6433 /* Widen the result of shift: we need to clear
6434 * the potential overflow bits resulting from
6435 * left bits of the narrow input appearing as
6436 * right bits of left the neighbour narrow
6437 * input. */
6438 if (size < 2 || !u) {
6439 uint64_t imm64;
6440 if (size == 0) {
6441 imm = (0xffu >> (8 - shift));
6442 imm |= imm << 16;
6443 } else if (size == 1) {
6444 imm = 0xffff >> (16 - shift);
6445 } else {
6446 /* size == 2 */
6447 imm = 0xffffffff >> (32 - shift);
6449 if (size < 2) {
6450 imm64 = imm | (((uint64_t)imm) << 32);
6451 } else {
6452 imm64 = imm;
6454 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6457 neon_store_reg64(cpu_V0, rd + pass);
6459 } else if (op >= 14) {
6460 /* VCVT fixed-point. */
6461 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6462 return 1;
6464 /* We have already masked out the must-be-1 top bit of imm6,
6465 * hence this 32-shift where the ARM ARM has 64-imm6.
6467 shift = 32 - shift;
6468 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6469 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6470 if (!(op & 1)) {
6471 if (u)
6472 gen_vfp_ulto(0, shift, 1);
6473 else
6474 gen_vfp_slto(0, shift, 1);
6475 } else {
6476 if (u)
6477 gen_vfp_toul(0, shift, 1);
6478 else
6479 gen_vfp_tosl(0, shift, 1);
6481 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6483 } else {
6484 return 1;
6486 } else { /* (insn & 0x00380080) == 0 */
6487 int invert;
6488 if (q && (rd & 1)) {
6489 return 1;
6492 op = (insn >> 8) & 0xf;
6493 /* One register and immediate. */
6494 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6495 invert = (insn & (1 << 5)) != 0;
6496 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6497 * We choose to not special-case this and will behave as if a
6498 * valid constant encoding of 0 had been given.
6500 switch (op) {
6501 case 0: case 1:
6502 /* no-op */
6503 break;
6504 case 2: case 3:
6505 imm <<= 8;
6506 break;
6507 case 4: case 5:
6508 imm <<= 16;
6509 break;
6510 case 6: case 7:
6511 imm <<= 24;
6512 break;
6513 case 8: case 9:
6514 imm |= imm << 16;
6515 break;
6516 case 10: case 11:
6517 imm = (imm << 8) | (imm << 24);
6518 break;
6519 case 12:
6520 imm = (imm << 8) | 0xff;
6521 break;
6522 case 13:
6523 imm = (imm << 16) | 0xffff;
6524 break;
6525 case 14:
6526 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6527 if (invert)
6528 imm = ~imm;
6529 break;
6530 case 15:
6531 if (invert) {
6532 return 1;
6534 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6535 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6536 break;
6538 if (invert)
6539 imm = ~imm;
6541 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6542 if (op & 1 && op < 12) {
6543 tmp = neon_load_reg(rd, pass);
6544 if (invert) {
6545 /* The immediate value has already been inverted, so
6546 BIC becomes AND. */
6547 tcg_gen_andi_i32(tmp, tmp, imm);
6548 } else {
6549 tcg_gen_ori_i32(tmp, tmp, imm);
6551 } else {
6552 /* VMOV, VMVN. */
6553 tmp = tcg_temp_new_i32();
6554 if (op == 14 && invert) {
6555 int n;
6556 uint32_t val;
6557 val = 0;
6558 for (n = 0; n < 4; n++) {
6559 if (imm & (1 << (n + (pass & 1) * 4)))
6560 val |= 0xff << (n * 8);
6562 tcg_gen_movi_i32(tmp, val);
6563 } else {
6564 tcg_gen_movi_i32(tmp, imm);
6567 neon_store_reg(rd, pass, tmp);
6570 } else { /* (insn & 0x00800010 == 0x00800000) */
6571 if (size != 3) {
6572 op = (insn >> 8) & 0xf;
6573 if ((insn & (1 << 6)) == 0) {
6574 /* Three registers of different lengths. */
6575 int src1_wide;
6576 int src2_wide;
6577 int prewiden;
6578 /* undefreq: bit 0 : UNDEF if size == 0
6579 * bit 1 : UNDEF if size == 1
6580 * bit 2 : UNDEF if size == 2
6581 * bit 3 : UNDEF if U == 1
6582 * Note that [2:0] set implies 'always UNDEF'
6584 int undefreq;
6585 /* prewiden, src1_wide, src2_wide, undefreq */
6586 static const int neon_3reg_wide[16][4] = {
6587 {1, 0, 0, 0}, /* VADDL */
6588 {1, 1, 0, 0}, /* VADDW */
6589 {1, 0, 0, 0}, /* VSUBL */
6590 {1, 1, 0, 0}, /* VSUBW */
6591 {0, 1, 1, 0}, /* VADDHN */
6592 {0, 0, 0, 0}, /* VABAL */
6593 {0, 1, 1, 0}, /* VSUBHN */
6594 {0, 0, 0, 0}, /* VABDL */
6595 {0, 0, 0, 0}, /* VMLAL */
6596 {0, 0, 0, 9}, /* VQDMLAL */
6597 {0, 0, 0, 0}, /* VMLSL */
6598 {0, 0, 0, 9}, /* VQDMLSL */
6599 {0, 0, 0, 0}, /* Integer VMULL */
6600 {0, 0, 0, 1}, /* VQDMULL */
6601 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6602 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6605 prewiden = neon_3reg_wide[op][0];
6606 src1_wide = neon_3reg_wide[op][1];
6607 src2_wide = neon_3reg_wide[op][2];
6608 undefreq = neon_3reg_wide[op][3];
6610 if ((undefreq & (1 << size)) ||
6611 ((undefreq & 8) && u)) {
6612 return 1;
6614 if ((src1_wide && (rn & 1)) ||
6615 (src2_wide && (rm & 1)) ||
6616 (!src2_wide && (rd & 1))) {
6617 return 1;
6620 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6621 * outside the loop below as it only performs a single pass.
6623 if (op == 14 && size == 2) {
6624 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6626 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6627 return 1;
6629 tcg_rn = tcg_temp_new_i64();
6630 tcg_rm = tcg_temp_new_i64();
6631 tcg_rd = tcg_temp_new_i64();
6632 neon_load_reg64(tcg_rn, rn);
6633 neon_load_reg64(tcg_rm, rm);
6634 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6635 neon_store_reg64(tcg_rd, rd);
6636 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6637 neon_store_reg64(tcg_rd, rd + 1);
6638 tcg_temp_free_i64(tcg_rn);
6639 tcg_temp_free_i64(tcg_rm);
6640 tcg_temp_free_i64(tcg_rd);
6641 return 0;
6644 /* Avoid overlapping operands. Wide source operands are
6645 always aligned so will never overlap with wide
6646 destinations in problematic ways. */
6647 if (rd == rm && !src2_wide) {
6648 tmp = neon_load_reg(rm, 1);
6649 neon_store_scratch(2, tmp);
6650 } else if (rd == rn && !src1_wide) {
6651 tmp = neon_load_reg(rn, 1);
6652 neon_store_scratch(2, tmp);
6654 tmp3 = NULL;
6655 for (pass = 0; pass < 2; pass++) {
6656 if (src1_wide) {
6657 neon_load_reg64(cpu_V0, rn + pass);
6658 tmp = NULL;
6659 } else {
6660 if (pass == 1 && rd == rn) {
6661 tmp = neon_load_scratch(2);
6662 } else {
6663 tmp = neon_load_reg(rn, pass);
6665 if (prewiden) {
6666 gen_neon_widen(cpu_V0, tmp, size, u);
6669 if (src2_wide) {
6670 neon_load_reg64(cpu_V1, rm + pass);
6671 tmp2 = NULL;
6672 } else {
6673 if (pass == 1 && rd == rm) {
6674 tmp2 = neon_load_scratch(2);
6675 } else {
6676 tmp2 = neon_load_reg(rm, pass);
6678 if (prewiden) {
6679 gen_neon_widen(cpu_V1, tmp2, size, u);
6682 switch (op) {
6683 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6684 gen_neon_addl(size);
6685 break;
6686 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6687 gen_neon_subl(size);
6688 break;
6689 case 5: case 7: /* VABAL, VABDL */
6690 switch ((size << 1) | u) {
6691 case 0:
6692 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6693 break;
6694 case 1:
6695 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6696 break;
6697 case 2:
6698 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6699 break;
6700 case 3:
6701 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6702 break;
6703 case 4:
6704 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6705 break;
6706 case 5:
6707 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6708 break;
6709 default: abort();
6711 tcg_temp_free_i32(tmp2);
6712 tcg_temp_free_i32(tmp);
6713 break;
6714 case 8: case 9: case 10: case 11: case 12: case 13:
6715 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6716 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6717 break;
6718 case 14: /* Polynomial VMULL */
6719 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6720 tcg_temp_free_i32(tmp2);
6721 tcg_temp_free_i32(tmp);
6722 break;
6723 default: /* 15 is RESERVED: caught earlier */
6724 abort();
6726 if (op == 13) {
6727 /* VQDMULL */
6728 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6729 neon_store_reg64(cpu_V0, rd + pass);
6730 } else if (op == 5 || (op >= 8 && op <= 11)) {
6731 /* Accumulate. */
6732 neon_load_reg64(cpu_V1, rd + pass);
6733 switch (op) {
6734 case 10: /* VMLSL */
6735 gen_neon_negl(cpu_V0, size);
6736 /* Fall through */
6737 case 5: case 8: /* VABAL, VMLAL */
6738 gen_neon_addl(size);
6739 break;
6740 case 9: case 11: /* VQDMLAL, VQDMLSL */
6741 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6742 if (op == 11) {
6743 gen_neon_negl(cpu_V0, size);
6745 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6746 break;
6747 default:
6748 abort();
6750 neon_store_reg64(cpu_V0, rd + pass);
6751 } else if (op == 4 || op == 6) {
6752 /* Narrowing operation. */
6753 tmp = tcg_temp_new_i32();
6754 if (!u) {
6755 switch (size) {
6756 case 0:
6757 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6758 break;
6759 case 1:
6760 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6761 break;
6762 case 2:
6763 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6764 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6765 break;
6766 default: abort();
6768 } else {
6769 switch (size) {
6770 case 0:
6771 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6772 break;
6773 case 1:
6774 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6775 break;
6776 case 2:
6777 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6778 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6779 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6780 break;
6781 default: abort();
6784 if (pass == 0) {
6785 tmp3 = tmp;
6786 } else {
6787 neon_store_reg(rd, 0, tmp3);
6788 neon_store_reg(rd, 1, tmp);
6790 } else {
6791 /* Write back the result. */
6792 neon_store_reg64(cpu_V0, rd + pass);
6795 } else {
6796 /* Two registers and a scalar. NB that for ops of this form
6797 * the ARM ARM labels bit 24 as Q, but it is in our variable
6798 * 'u', not 'q'.
6800 if (size == 0) {
6801 return 1;
6803 switch (op) {
6804 case 1: /* Float VMLA scalar */
6805 case 5: /* Floating point VMLS scalar */
6806 case 9: /* Floating point VMUL scalar */
6807 if (size == 1) {
6808 return 1;
6810 /* fall through */
6811 case 0: /* Integer VMLA scalar */
6812 case 4: /* Integer VMLS scalar */
6813 case 8: /* Integer VMUL scalar */
6814 case 12: /* VQDMULH scalar */
6815 case 13: /* VQRDMULH scalar */
6816 if (u && ((rd | rn) & 1)) {
6817 return 1;
6819 tmp = neon_get_scalar(size, rm);
6820 neon_store_scratch(0, tmp);
6821 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6822 tmp = neon_load_scratch(0);
6823 tmp2 = neon_load_reg(rn, pass);
6824 if (op == 12) {
6825 if (size == 1) {
6826 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6827 } else {
6828 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6830 } else if (op == 13) {
6831 if (size == 1) {
6832 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6833 } else {
6834 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6836 } else if (op & 1) {
6837 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6838 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6839 tcg_temp_free_ptr(fpstatus);
6840 } else {
6841 switch (size) {
6842 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6843 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6844 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6845 default: abort();
6848 tcg_temp_free_i32(tmp2);
6849 if (op < 8) {
6850 /* Accumulate. */
6851 tmp2 = neon_load_reg(rd, pass);
6852 switch (op) {
6853 case 0:
6854 gen_neon_add(size, tmp, tmp2);
6855 break;
6856 case 1:
6858 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6859 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6860 tcg_temp_free_ptr(fpstatus);
6861 break;
6863 case 4:
6864 gen_neon_rsb(size, tmp, tmp2);
6865 break;
6866 case 5:
6868 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6869 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6870 tcg_temp_free_ptr(fpstatus);
6871 break;
6873 default:
6874 abort();
6876 tcg_temp_free_i32(tmp2);
6878 neon_store_reg(rd, pass, tmp);
6880 break;
6881 case 3: /* VQDMLAL scalar */
6882 case 7: /* VQDMLSL scalar */
6883 case 11: /* VQDMULL scalar */
6884 if (u == 1) {
6885 return 1;
6887 /* fall through */
6888 case 2: /* VMLAL sclar */
6889 case 6: /* VMLSL scalar */
6890 case 10: /* VMULL scalar */
6891 if (rd & 1) {
6892 return 1;
6894 tmp2 = neon_get_scalar(size, rm);
6895 /* We need a copy of tmp2 because gen_neon_mull
6896 * deletes it during pass 0. */
6897 tmp4 = tcg_temp_new_i32();
6898 tcg_gen_mov_i32(tmp4, tmp2);
6899 tmp3 = neon_load_reg(rn, 1);
6901 for (pass = 0; pass < 2; pass++) {
6902 if (pass == 0) {
6903 tmp = neon_load_reg(rn, 0);
6904 } else {
6905 tmp = tmp3;
6906 tmp2 = tmp4;
6908 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6909 if (op != 11) {
6910 neon_load_reg64(cpu_V1, rd + pass);
6912 switch (op) {
6913 case 6:
6914 gen_neon_negl(cpu_V0, size);
6915 /* Fall through */
6916 case 2:
6917 gen_neon_addl(size);
6918 break;
6919 case 3: case 7:
6920 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6921 if (op == 7) {
6922 gen_neon_negl(cpu_V0, size);
6924 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6925 break;
6926 case 10:
6927 /* no-op */
6928 break;
6929 case 11:
6930 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6931 break;
6932 default:
6933 abort();
6935 neon_store_reg64(cpu_V0, rd + pass);
6939 break;
6940 default: /* 14 and 15 are RESERVED */
6941 return 1;
6944 } else { /* size == 3 */
6945 if (!u) {
6946 /* Extract. */
6947 imm = (insn >> 8) & 0xf;
6949 if (imm > 7 && !q)
6950 return 1;
6952 if (q && ((rd | rn | rm) & 1)) {
6953 return 1;
6956 if (imm == 0) {
6957 neon_load_reg64(cpu_V0, rn);
6958 if (q) {
6959 neon_load_reg64(cpu_V1, rn + 1);
6961 } else if (imm == 8) {
6962 neon_load_reg64(cpu_V0, rn + 1);
6963 if (q) {
6964 neon_load_reg64(cpu_V1, rm);
6966 } else if (q) {
6967 tmp64 = tcg_temp_new_i64();
6968 if (imm < 8) {
6969 neon_load_reg64(cpu_V0, rn);
6970 neon_load_reg64(tmp64, rn + 1);
6971 } else {
6972 neon_load_reg64(cpu_V0, rn + 1);
6973 neon_load_reg64(tmp64, rm);
6975 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6976 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6977 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6978 if (imm < 8) {
6979 neon_load_reg64(cpu_V1, rm);
6980 } else {
6981 neon_load_reg64(cpu_V1, rm + 1);
6982 imm -= 8;
6984 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6985 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6986 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6987 tcg_temp_free_i64(tmp64);
6988 } else {
6989 /* BUGFIX */
6990 neon_load_reg64(cpu_V0, rn);
6991 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6992 neon_load_reg64(cpu_V1, rm);
6993 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6994 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6996 neon_store_reg64(cpu_V0, rd);
6997 if (q) {
6998 neon_store_reg64(cpu_V1, rd + 1);
7000 } else if ((insn & (1 << 11)) == 0) {
7001 /* Two register misc. */
7002 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7003 size = (insn >> 18) & 3;
7004 /* UNDEF for unknown op values and bad op-size combinations */
7005 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7006 return 1;
7008 if (neon_2rm_is_v8_op(op) &&
7009 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7010 return 1;
7012 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7013 q && ((rm | rd) & 1)) {
7014 return 1;
7016 switch (op) {
7017 case NEON_2RM_VREV64:
7018 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7019 tmp = neon_load_reg(rm, pass * 2);
7020 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7021 switch (size) {
7022 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7023 case 1: gen_swap_half(tmp); break;
7024 case 2: /* no-op */ break;
7025 default: abort();
7027 neon_store_reg(rd, pass * 2 + 1, tmp);
7028 if (size == 2) {
7029 neon_store_reg(rd, pass * 2, tmp2);
7030 } else {
7031 switch (size) {
7032 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7033 case 1: gen_swap_half(tmp2); break;
7034 default: abort();
7036 neon_store_reg(rd, pass * 2, tmp2);
7039 break;
7040 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7041 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7042 for (pass = 0; pass < q + 1; pass++) {
7043 tmp = neon_load_reg(rm, pass * 2);
7044 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7045 tmp = neon_load_reg(rm, pass * 2 + 1);
7046 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7047 switch (size) {
7048 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7049 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7050 case 2: tcg_gen_add_i64(CPU_V001); break;
7051 default: abort();
7053 if (op >= NEON_2RM_VPADAL) {
7054 /* Accumulate. */
7055 neon_load_reg64(cpu_V1, rd + pass);
7056 gen_neon_addl(size);
7058 neon_store_reg64(cpu_V0, rd + pass);
7060 break;
7061 case NEON_2RM_VTRN:
7062 if (size == 2) {
7063 int n;
7064 for (n = 0; n < (q ? 4 : 2); n += 2) {
7065 tmp = neon_load_reg(rm, n);
7066 tmp2 = neon_load_reg(rd, n + 1);
7067 neon_store_reg(rm, n, tmp2);
7068 neon_store_reg(rd, n + 1, tmp);
7070 } else {
7071 goto elementwise;
7073 break;
7074 case NEON_2RM_VUZP:
7075 if (gen_neon_unzip(rd, rm, size, q)) {
7076 return 1;
7078 break;
7079 case NEON_2RM_VZIP:
7080 if (gen_neon_zip(rd, rm, size, q)) {
7081 return 1;
7083 break;
7084 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7085 /* also VQMOVUN; op field and mnemonics don't line up */
7086 if (rm & 1) {
7087 return 1;
7089 tmp2 = NULL;
7090 for (pass = 0; pass < 2; pass++) {
7091 neon_load_reg64(cpu_V0, rm + pass);
7092 tmp = tcg_temp_new_i32();
7093 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7094 tmp, cpu_V0);
7095 if (pass == 0) {
7096 tmp2 = tmp;
7097 } else {
7098 neon_store_reg(rd, 0, tmp2);
7099 neon_store_reg(rd, 1, tmp);
7102 break;
7103 case NEON_2RM_VSHLL:
7104 if (q || (rd & 1)) {
7105 return 1;
7107 tmp = neon_load_reg(rm, 0);
7108 tmp2 = neon_load_reg(rm, 1);
7109 for (pass = 0; pass < 2; pass++) {
7110 if (pass == 1)
7111 tmp = tmp2;
7112 gen_neon_widen(cpu_V0, tmp, size, 1);
7113 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7114 neon_store_reg64(cpu_V0, rd + pass);
7116 break;
7117 case NEON_2RM_VCVT_F16_F32:
7118 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7119 q || (rm & 1)) {
7120 return 1;
7122 tmp = tcg_temp_new_i32();
7123 tmp2 = tcg_temp_new_i32();
7124 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7125 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7126 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7127 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7128 tcg_gen_shli_i32(tmp2, tmp2, 16);
7129 tcg_gen_or_i32(tmp2, tmp2, tmp);
7130 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7131 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7132 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7133 neon_store_reg(rd, 0, tmp2);
7134 tmp2 = tcg_temp_new_i32();
7135 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7136 tcg_gen_shli_i32(tmp2, tmp2, 16);
7137 tcg_gen_or_i32(tmp2, tmp2, tmp);
7138 neon_store_reg(rd, 1, tmp2);
7139 tcg_temp_free_i32(tmp);
7140 break;
7141 case NEON_2RM_VCVT_F32_F16:
7142 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7143 q || (rd & 1)) {
7144 return 1;
7146 tmp3 = tcg_temp_new_i32();
7147 tmp = neon_load_reg(rm, 0);
7148 tmp2 = neon_load_reg(rm, 1);
7149 tcg_gen_ext16u_i32(tmp3, tmp);
7150 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7151 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7152 tcg_gen_shri_i32(tmp3, tmp, 16);
7153 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7154 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7155 tcg_temp_free_i32(tmp);
7156 tcg_gen_ext16u_i32(tmp3, tmp2);
7157 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7158 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7159 tcg_gen_shri_i32(tmp3, tmp2, 16);
7160 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7161 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7162 tcg_temp_free_i32(tmp2);
7163 tcg_temp_free_i32(tmp3);
7164 break;
7165 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7166 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7167 || ((rm | rd) & 1)) {
7168 return 1;
7170 ptr1 = vfp_reg_ptr(true, rd);
7171 ptr2 = vfp_reg_ptr(true, rm);
7173 /* Bit 6 is the lowest opcode bit; it distinguishes between
7174 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7176 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7178 if (op == NEON_2RM_AESE) {
7179 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7180 } else {
7181 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7183 tcg_temp_free_ptr(ptr1);
7184 tcg_temp_free_ptr(ptr2);
7185 tcg_temp_free_i32(tmp3);
7186 break;
7187 case NEON_2RM_SHA1H:
7188 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7189 || ((rm | rd) & 1)) {
7190 return 1;
7192 ptr1 = vfp_reg_ptr(true, rd);
7193 ptr2 = vfp_reg_ptr(true, rm);
7195 gen_helper_crypto_sha1h(ptr1, ptr2);
7197 tcg_temp_free_ptr(ptr1);
7198 tcg_temp_free_ptr(ptr2);
7199 break;
7200 case NEON_2RM_SHA1SU1:
7201 if ((rm | rd) & 1) {
7202 return 1;
7204 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7205 if (q) {
7206 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7207 return 1;
7209 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7210 return 1;
7212 ptr1 = vfp_reg_ptr(true, rd);
7213 ptr2 = vfp_reg_ptr(true, rm);
7214 if (q) {
7215 gen_helper_crypto_sha256su0(ptr1, ptr2);
7216 } else {
7217 gen_helper_crypto_sha1su1(ptr1, ptr2);
7219 tcg_temp_free_ptr(ptr1);
7220 tcg_temp_free_ptr(ptr2);
7221 break;
7222 default:
7223 elementwise:
7224 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7225 if (neon_2rm_is_float_op(op)) {
7226 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7227 neon_reg_offset(rm, pass));
7228 tmp = NULL;
7229 } else {
7230 tmp = neon_load_reg(rm, pass);
7232 switch (op) {
7233 case NEON_2RM_VREV32:
7234 switch (size) {
7235 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7236 case 1: gen_swap_half(tmp); break;
7237 default: abort();
7239 break;
7240 case NEON_2RM_VREV16:
7241 gen_rev16(tmp);
7242 break;
7243 case NEON_2RM_VCLS:
7244 switch (size) {
7245 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7246 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7247 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7248 default: abort();
7250 break;
7251 case NEON_2RM_VCLZ:
7252 switch (size) {
7253 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7254 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7255 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7256 default: abort();
7258 break;
7259 case NEON_2RM_VCNT:
7260 gen_helper_neon_cnt_u8(tmp, tmp);
7261 break;
7262 case NEON_2RM_VMVN:
7263 tcg_gen_not_i32(tmp, tmp);
7264 break;
7265 case NEON_2RM_VQABS:
7266 switch (size) {
7267 case 0:
7268 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7269 break;
7270 case 1:
7271 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7272 break;
7273 case 2:
7274 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7275 break;
7276 default: abort();
7278 break;
7279 case NEON_2RM_VQNEG:
7280 switch (size) {
7281 case 0:
7282 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7283 break;
7284 case 1:
7285 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7286 break;
7287 case 2:
7288 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7289 break;
7290 default: abort();
7292 break;
7293 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7294 tmp2 = tcg_const_i32(0);
7295 switch(size) {
7296 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7297 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7298 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7299 default: abort();
7301 tcg_temp_free_i32(tmp2);
7302 if (op == NEON_2RM_VCLE0) {
7303 tcg_gen_not_i32(tmp, tmp);
7305 break;
7306 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7307 tmp2 = tcg_const_i32(0);
7308 switch(size) {
7309 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7310 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7311 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7312 default: abort();
7314 tcg_temp_free_i32(tmp2);
7315 if (op == NEON_2RM_VCLT0) {
7316 tcg_gen_not_i32(tmp, tmp);
7318 break;
7319 case NEON_2RM_VCEQ0:
7320 tmp2 = tcg_const_i32(0);
7321 switch(size) {
7322 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7323 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7324 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7325 default: abort();
7327 tcg_temp_free_i32(tmp2);
7328 break;
7329 case NEON_2RM_VABS:
7330 switch(size) {
7331 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7332 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7333 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7334 default: abort();
7336 break;
7337 case NEON_2RM_VNEG:
7338 tmp2 = tcg_const_i32(0);
7339 gen_neon_rsb(size, tmp, tmp2);
7340 tcg_temp_free_i32(tmp2);
7341 break;
7342 case NEON_2RM_VCGT0_F:
7344 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7345 tmp2 = tcg_const_i32(0);
7346 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7347 tcg_temp_free_i32(tmp2);
7348 tcg_temp_free_ptr(fpstatus);
7349 break;
7351 case NEON_2RM_VCGE0_F:
7353 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7354 tmp2 = tcg_const_i32(0);
7355 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7356 tcg_temp_free_i32(tmp2);
7357 tcg_temp_free_ptr(fpstatus);
7358 break;
7360 case NEON_2RM_VCEQ0_F:
7362 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7363 tmp2 = tcg_const_i32(0);
7364 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7365 tcg_temp_free_i32(tmp2);
7366 tcg_temp_free_ptr(fpstatus);
7367 break;
7369 case NEON_2RM_VCLE0_F:
7371 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7372 tmp2 = tcg_const_i32(0);
7373 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7374 tcg_temp_free_i32(tmp2);
7375 tcg_temp_free_ptr(fpstatus);
7376 break;
7378 case NEON_2RM_VCLT0_F:
7380 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7381 tmp2 = tcg_const_i32(0);
7382 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7383 tcg_temp_free_i32(tmp2);
7384 tcg_temp_free_ptr(fpstatus);
7385 break;
7387 case NEON_2RM_VABS_F:
7388 gen_vfp_abs(0);
7389 break;
7390 case NEON_2RM_VNEG_F:
7391 gen_vfp_neg(0);
7392 break;
7393 case NEON_2RM_VSWP:
7394 tmp2 = neon_load_reg(rd, pass);
7395 neon_store_reg(rm, pass, tmp2);
7396 break;
7397 case NEON_2RM_VTRN:
7398 tmp2 = neon_load_reg(rd, pass);
7399 switch (size) {
7400 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7401 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7402 default: abort();
7404 neon_store_reg(rm, pass, tmp2);
7405 break;
7406 case NEON_2RM_VRINTN:
7407 case NEON_2RM_VRINTA:
7408 case NEON_2RM_VRINTM:
7409 case NEON_2RM_VRINTP:
7410 case NEON_2RM_VRINTZ:
7412 TCGv_i32 tcg_rmode;
7413 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7414 int rmode;
7416 if (op == NEON_2RM_VRINTZ) {
7417 rmode = FPROUNDING_ZERO;
7418 } else {
7419 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7422 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7423 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7424 cpu_env);
7425 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7426 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7427 cpu_env);
7428 tcg_temp_free_ptr(fpstatus);
7429 tcg_temp_free_i32(tcg_rmode);
7430 break;
7432 case NEON_2RM_VRINTX:
7434 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7435 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7436 tcg_temp_free_ptr(fpstatus);
7437 break;
7439 case NEON_2RM_VCVTAU:
7440 case NEON_2RM_VCVTAS:
7441 case NEON_2RM_VCVTNU:
7442 case NEON_2RM_VCVTNS:
7443 case NEON_2RM_VCVTPU:
7444 case NEON_2RM_VCVTPS:
7445 case NEON_2RM_VCVTMU:
7446 case NEON_2RM_VCVTMS:
7448 bool is_signed = !extract32(insn, 7, 1);
7449 TCGv_ptr fpst = get_fpstatus_ptr(1);
7450 TCGv_i32 tcg_rmode, tcg_shift;
7451 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7453 tcg_shift = tcg_const_i32(0);
7454 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7455 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7456 cpu_env);
7458 if (is_signed) {
7459 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7460 tcg_shift, fpst);
7461 } else {
7462 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7463 tcg_shift, fpst);
7466 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7467 cpu_env);
7468 tcg_temp_free_i32(tcg_rmode);
7469 tcg_temp_free_i32(tcg_shift);
7470 tcg_temp_free_ptr(fpst);
7471 break;
7473 case NEON_2RM_VRECPE:
7475 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7476 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7477 tcg_temp_free_ptr(fpstatus);
7478 break;
7480 case NEON_2RM_VRSQRTE:
7482 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7483 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7484 tcg_temp_free_ptr(fpstatus);
7485 break;
7487 case NEON_2RM_VRECPE_F:
7489 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7490 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7491 tcg_temp_free_ptr(fpstatus);
7492 break;
7494 case NEON_2RM_VRSQRTE_F:
7496 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7497 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7498 tcg_temp_free_ptr(fpstatus);
7499 break;
7501 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7502 gen_vfp_sito(0, 1);
7503 break;
7504 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7505 gen_vfp_uito(0, 1);
7506 break;
7507 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7508 gen_vfp_tosiz(0, 1);
7509 break;
7510 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7511 gen_vfp_touiz(0, 1);
7512 break;
7513 default:
7514 /* Reserved op values were caught by the
7515 * neon_2rm_sizes[] check earlier.
7517 abort();
7519 if (neon_2rm_is_float_op(op)) {
7520 tcg_gen_st_f32(cpu_F0s, cpu_env,
7521 neon_reg_offset(rd, pass));
7522 } else {
7523 neon_store_reg(rd, pass, tmp);
7526 break;
7528 } else if ((insn & (1 << 10)) == 0) {
7529 /* VTBL, VTBX. */
7530 int n = ((insn >> 8) & 3) + 1;
7531 if ((rn + n) > 32) {
7532 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7533 * helper function running off the end of the register file.
7535 return 1;
7537 n <<= 3;
7538 if (insn & (1 << 6)) {
7539 tmp = neon_load_reg(rd, 0);
7540 } else {
7541 tmp = tcg_temp_new_i32();
7542 tcg_gen_movi_i32(tmp, 0);
7544 tmp2 = neon_load_reg(rm, 0);
7545 tmp4 = tcg_const_i32(rn);
7546 tmp5 = tcg_const_i32(n);
7547 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7548 tcg_temp_free_i32(tmp);
7549 if (insn & (1 << 6)) {
7550 tmp = neon_load_reg(rd, 1);
7551 } else {
7552 tmp = tcg_temp_new_i32();
7553 tcg_gen_movi_i32(tmp, 0);
7555 tmp3 = neon_load_reg(rm, 1);
7556 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7557 tcg_temp_free_i32(tmp5);
7558 tcg_temp_free_i32(tmp4);
7559 neon_store_reg(rd, 0, tmp2);
7560 neon_store_reg(rd, 1, tmp3);
7561 tcg_temp_free_i32(tmp);
7562 } else if ((insn & 0x380) == 0) {
7563 /* VDUP */
7564 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7565 return 1;
7567 if (insn & (1 << 19)) {
7568 tmp = neon_load_reg(rm, 1);
7569 } else {
7570 tmp = neon_load_reg(rm, 0);
7572 if (insn & (1 << 16)) {
7573 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7574 } else if (insn & (1 << 17)) {
7575 if ((insn >> 18) & 1)
7576 gen_neon_dup_high16(tmp);
7577 else
7578 gen_neon_dup_low16(tmp);
7580 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7581 tmp2 = tcg_temp_new_i32();
7582 tcg_gen_mov_i32(tmp2, tmp);
7583 neon_store_reg(rd, pass, tmp2);
7585 tcg_temp_free_i32(tmp);
7586 } else {
7587 return 1;
7591 return 0;
7594 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7596 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7597 const ARMCPRegInfo *ri;
7599 cpnum = (insn >> 8) & 0xf;
7601 /* First check for coprocessor space used for XScale/iwMMXt insns */
7602 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7603 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7604 return 1;
7606 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7607 return disas_iwmmxt_insn(s, insn);
7608 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7609 return disas_dsp_insn(s, insn);
7611 return 1;
7614 /* Otherwise treat as a generic register access */
7615 is64 = (insn & (1 << 25)) == 0;
7616 if (!is64 && ((insn & (1 << 4)) == 0)) {
7617 /* cdp */
7618 return 1;
7621 crm = insn & 0xf;
7622 if (is64) {
7623 crn = 0;
7624 opc1 = (insn >> 4) & 0xf;
7625 opc2 = 0;
7626 rt2 = (insn >> 16) & 0xf;
7627 } else {
7628 crn = (insn >> 16) & 0xf;
7629 opc1 = (insn >> 21) & 7;
7630 opc2 = (insn >> 5) & 7;
7631 rt2 = 0;
7633 isread = (insn >> 20) & 1;
7634 rt = (insn >> 12) & 0xf;
7636 ri = get_arm_cp_reginfo(s->cp_regs,
7637 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7638 if (ri) {
7639 /* Check access permissions */
7640 if (!cp_access_ok(s->current_el, ri, isread)) {
7641 return 1;
7644 if (ri->accessfn ||
7645 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7646 /* Emit code to perform further access permissions checks at
7647 * runtime; this may result in an exception.
7648 * Note that on XScale all cp0..c13 registers do an access check
7649 * call in order to handle c15_cpar.
7651 TCGv_ptr tmpptr;
7652 TCGv_i32 tcg_syn, tcg_isread;
7653 uint32_t syndrome;
7655 /* Note that since we are an implementation which takes an
7656 * exception on a trapped conditional instruction only if the
7657 * instruction passes its condition code check, we can take
7658 * advantage of the clause in the ARM ARM that allows us to set
7659 * the COND field in the instruction to 0xE in all cases.
7660 * We could fish the actual condition out of the insn (ARM)
7661 * or the condexec bits (Thumb) but it isn't necessary.
7663 switch (cpnum) {
7664 case 14:
7665 if (is64) {
7666 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7667 isread, false);
7668 } else {
7669 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7670 rt, isread, false);
7672 break;
7673 case 15:
7674 if (is64) {
7675 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7676 isread, false);
7677 } else {
7678 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7679 rt, isread, false);
7681 break;
7682 default:
7683 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7684 * so this can only happen if this is an ARMv7 or earlier CPU,
7685 * in which case the syndrome information won't actually be
7686 * guest visible.
7688 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7689 syndrome = syn_uncategorized();
7690 break;
7693 gen_set_condexec(s);
7694 gen_set_pc_im(s, s->pc - 4);
7695 tmpptr = tcg_const_ptr(ri);
7696 tcg_syn = tcg_const_i32(syndrome);
7697 tcg_isread = tcg_const_i32(isread);
7698 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7699 tcg_isread);
7700 tcg_temp_free_ptr(tmpptr);
7701 tcg_temp_free_i32(tcg_syn);
7702 tcg_temp_free_i32(tcg_isread);
7705 /* Handle special cases first */
7706 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7707 case ARM_CP_NOP:
7708 return 0;
7709 case ARM_CP_WFI:
7710 if (isread) {
7711 return 1;
7713 gen_set_pc_im(s, s->pc);
7714 s->base.is_jmp = DISAS_WFI;
7715 return 0;
7716 default:
7717 break;
7720 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7721 gen_io_start();
7724 if (isread) {
7725 /* Read */
7726 if (is64) {
7727 TCGv_i64 tmp64;
7728 TCGv_i32 tmp;
7729 if (ri->type & ARM_CP_CONST) {
7730 tmp64 = tcg_const_i64(ri->resetvalue);
7731 } else if (ri->readfn) {
7732 TCGv_ptr tmpptr;
7733 tmp64 = tcg_temp_new_i64();
7734 tmpptr = tcg_const_ptr(ri);
7735 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7736 tcg_temp_free_ptr(tmpptr);
7737 } else {
7738 tmp64 = tcg_temp_new_i64();
7739 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7741 tmp = tcg_temp_new_i32();
7742 tcg_gen_extrl_i64_i32(tmp, tmp64);
7743 store_reg(s, rt, tmp);
7744 tcg_gen_shri_i64(tmp64, tmp64, 32);
7745 tmp = tcg_temp_new_i32();
7746 tcg_gen_extrl_i64_i32(tmp, tmp64);
7747 tcg_temp_free_i64(tmp64);
7748 store_reg(s, rt2, tmp);
7749 } else {
7750 TCGv_i32 tmp;
7751 if (ri->type & ARM_CP_CONST) {
7752 tmp = tcg_const_i32(ri->resetvalue);
7753 } else if (ri->readfn) {
7754 TCGv_ptr tmpptr;
7755 tmp = tcg_temp_new_i32();
7756 tmpptr = tcg_const_ptr(ri);
7757 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7758 tcg_temp_free_ptr(tmpptr);
7759 } else {
7760 tmp = load_cpu_offset(ri->fieldoffset);
7762 if (rt == 15) {
7763 /* Destination register of r15 for 32 bit loads sets
7764 * the condition codes from the high 4 bits of the value
7766 gen_set_nzcv(tmp);
7767 tcg_temp_free_i32(tmp);
7768 } else {
7769 store_reg(s, rt, tmp);
7772 } else {
7773 /* Write */
7774 if (ri->type & ARM_CP_CONST) {
7775 /* If not forbidden by access permissions, treat as WI */
7776 return 0;
7779 if (is64) {
7780 TCGv_i32 tmplo, tmphi;
7781 TCGv_i64 tmp64 = tcg_temp_new_i64();
7782 tmplo = load_reg(s, rt);
7783 tmphi = load_reg(s, rt2);
7784 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7785 tcg_temp_free_i32(tmplo);
7786 tcg_temp_free_i32(tmphi);
7787 if (ri->writefn) {
7788 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7789 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7790 tcg_temp_free_ptr(tmpptr);
7791 } else {
7792 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7794 tcg_temp_free_i64(tmp64);
7795 } else {
7796 if (ri->writefn) {
7797 TCGv_i32 tmp;
7798 TCGv_ptr tmpptr;
7799 tmp = load_reg(s, rt);
7800 tmpptr = tcg_const_ptr(ri);
7801 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7802 tcg_temp_free_ptr(tmpptr);
7803 tcg_temp_free_i32(tmp);
7804 } else {
7805 TCGv_i32 tmp = load_reg(s, rt);
7806 store_cpu_offset(tmp, ri->fieldoffset);
7811 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7812 /* I/O operations must end the TB here (whether read or write) */
7813 gen_io_end();
7814 gen_lookup_tb(s);
7815 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7816 /* We default to ending the TB on a coprocessor register write,
7817 * but allow this to be suppressed by the register definition
7818 * (usually only necessary to work around guest bugs).
7820 gen_lookup_tb(s);
7823 return 0;
7826 /* Unknown register; this might be a guest error or a QEMU
7827 * unimplemented feature.
7829 if (is64) {
7830 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7831 "64 bit system register cp:%d opc1: %d crm:%d "
7832 "(%s)\n",
7833 isread ? "read" : "write", cpnum, opc1, crm,
7834 s->ns ? "non-secure" : "secure");
7835 } else {
7836 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7837 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7838 "(%s)\n",
7839 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7840 s->ns ? "non-secure" : "secure");
7843 return 1;
7847 /* Store a 64-bit value to a register pair. Clobbers val. */
7848 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7850 TCGv_i32 tmp;
7851 tmp = tcg_temp_new_i32();
7852 tcg_gen_extrl_i64_i32(tmp, val);
7853 store_reg(s, rlow, tmp);
7854 tmp = tcg_temp_new_i32();
7855 tcg_gen_shri_i64(val, val, 32);
7856 tcg_gen_extrl_i64_i32(tmp, val);
7857 store_reg(s, rhigh, tmp);
7860 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7861 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7863 TCGv_i64 tmp;
7864 TCGv_i32 tmp2;
7866 /* Load value and extend to 64 bits. */
7867 tmp = tcg_temp_new_i64();
7868 tmp2 = load_reg(s, rlow);
7869 tcg_gen_extu_i32_i64(tmp, tmp2);
7870 tcg_temp_free_i32(tmp2);
7871 tcg_gen_add_i64(val, val, tmp);
7872 tcg_temp_free_i64(tmp);
7875 /* load and add a 64-bit value from a register pair. */
7876 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7878 TCGv_i64 tmp;
7879 TCGv_i32 tmpl;
7880 TCGv_i32 tmph;
7882 /* Load 64-bit value rd:rn. */
7883 tmpl = load_reg(s, rlow);
7884 tmph = load_reg(s, rhigh);
7885 tmp = tcg_temp_new_i64();
7886 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7887 tcg_temp_free_i32(tmpl);
7888 tcg_temp_free_i32(tmph);
7889 tcg_gen_add_i64(val, val, tmp);
7890 tcg_temp_free_i64(tmp);
7893 /* Set N and Z flags from hi|lo. */
7894 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7896 tcg_gen_mov_i32(cpu_NF, hi);
7897 tcg_gen_or_i32(cpu_ZF, lo, hi);
7900 /* Load/Store exclusive instructions are implemented by remembering
7901 the value/address loaded, and seeing if these are the same
7902 when the store is performed. This should be sufficient to implement
7903 the architecturally mandated semantics, and avoids having to monitor
7904 regular stores. The compare vs the remembered value is done during
7905 the cmpxchg operation, but we must compare the addresses manually. */
7906 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7907 TCGv_i32 addr, int size)
7909 TCGv_i32 tmp = tcg_temp_new_i32();
7910 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7912 s->is_ldex = true;
7914 if (size == 3) {
7915 TCGv_i32 tmp2 = tcg_temp_new_i32();
7916 TCGv_i64 t64 = tcg_temp_new_i64();
7918 /* For AArch32, architecturally the 32-bit word at the lowest
7919 * address is always Rt and the one at addr+4 is Rt2, even if
7920 * the CPU is big-endian. That means we don't want to do a
7921 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7922 * for an architecturally 64-bit access, but instead do a
7923 * 64-bit access using MO_BE if appropriate and then split
7924 * the two halves.
7925 * This only makes a difference for BE32 user-mode, where
7926 * frob64() must not flip the two halves of the 64-bit data
7927 * but this code must treat BE32 user-mode like BE32 system.
7929 TCGv taddr = gen_aa32_addr(s, addr, opc);
7931 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7932 tcg_temp_free(taddr);
7933 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7934 if (s->be_data == MO_BE) {
7935 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7936 } else {
7937 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7939 tcg_temp_free_i64(t64);
7941 store_reg(s, rt2, tmp2);
7942 } else {
7943 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7944 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7947 store_reg(s, rt, tmp);
7948 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7951 static void gen_clrex(DisasContext *s)
7953 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7956 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7957 TCGv_i32 addr, int size)
7959 TCGv_i32 t0, t1, t2;
7960 TCGv_i64 extaddr;
7961 TCGv taddr;
7962 TCGLabel *done_label;
7963 TCGLabel *fail_label;
7964 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7966 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7967 [addr] = {Rt};
7968 {Rd} = 0;
7969 } else {
7970 {Rd} = 1;
7971 } */
7972 fail_label = gen_new_label();
7973 done_label = gen_new_label();
7974 extaddr = tcg_temp_new_i64();
7975 tcg_gen_extu_i32_i64(extaddr, addr);
7976 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7977 tcg_temp_free_i64(extaddr);
7979 taddr = gen_aa32_addr(s, addr, opc);
7980 t0 = tcg_temp_new_i32();
7981 t1 = load_reg(s, rt);
7982 if (size == 3) {
7983 TCGv_i64 o64 = tcg_temp_new_i64();
7984 TCGv_i64 n64 = tcg_temp_new_i64();
7986 t2 = load_reg(s, rt2);
7987 /* For AArch32, architecturally the 32-bit word at the lowest
7988 * address is always Rt and the one at addr+4 is Rt2, even if
7989 * the CPU is big-endian. Since we're going to treat this as a
7990 * single 64-bit BE store, we need to put the two halves in the
7991 * opposite order for BE to LE, so that they end up in the right
7992 * places.
7993 * We don't want gen_aa32_frob64() because that does the wrong
7994 * thing for BE32 usermode.
7996 if (s->be_data == MO_BE) {
7997 tcg_gen_concat_i32_i64(n64, t2, t1);
7998 } else {
7999 tcg_gen_concat_i32_i64(n64, t1, t2);
8001 tcg_temp_free_i32(t2);
8003 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8004 get_mem_index(s), opc);
8005 tcg_temp_free_i64(n64);
8007 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8008 tcg_gen_extrl_i64_i32(t0, o64);
8010 tcg_temp_free_i64(o64);
8011 } else {
8012 t2 = tcg_temp_new_i32();
8013 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8014 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8015 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8016 tcg_temp_free_i32(t2);
8018 tcg_temp_free_i32(t1);
8019 tcg_temp_free(taddr);
8020 tcg_gen_mov_i32(cpu_R[rd], t0);
8021 tcg_temp_free_i32(t0);
8022 tcg_gen_br(done_label);
8024 gen_set_label(fail_label);
8025 tcg_gen_movi_i32(cpu_R[rd], 1);
8026 gen_set_label(done_label);
8027 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8030 /* gen_srs:
8031 * @env: CPUARMState
8032 * @s: DisasContext
8033 * @mode: mode field from insn (which stack to store to)
8034 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8035 * @writeback: true if writeback bit set
8037 * Generate code for the SRS (Store Return State) insn.
8039 static void gen_srs(DisasContext *s,
8040 uint32_t mode, uint32_t amode, bool writeback)
8042 int32_t offset;
8043 TCGv_i32 addr, tmp;
8044 bool undef = false;
8046 /* SRS is:
8047 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8048 * and specified mode is monitor mode
8049 * - UNDEFINED in Hyp mode
8050 * - UNPREDICTABLE in User or System mode
8051 * - UNPREDICTABLE if the specified mode is:
8052 * -- not implemented
8053 * -- not a valid mode number
8054 * -- a mode that's at a higher exception level
8055 * -- Monitor, if we are Non-secure
8056 * For the UNPREDICTABLE cases we choose to UNDEF.
8058 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8059 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8060 return;
8063 if (s->current_el == 0 || s->current_el == 2) {
8064 undef = true;
8067 switch (mode) {
8068 case ARM_CPU_MODE_USR:
8069 case ARM_CPU_MODE_FIQ:
8070 case ARM_CPU_MODE_IRQ:
8071 case ARM_CPU_MODE_SVC:
8072 case ARM_CPU_MODE_ABT:
8073 case ARM_CPU_MODE_UND:
8074 case ARM_CPU_MODE_SYS:
8075 break;
8076 case ARM_CPU_MODE_HYP:
8077 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8078 undef = true;
8080 break;
8081 case ARM_CPU_MODE_MON:
8082 /* No need to check specifically for "are we non-secure" because
8083 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8084 * so if this isn't EL3 then we must be non-secure.
8086 if (s->current_el != 3) {
8087 undef = true;
8089 break;
8090 default:
8091 undef = true;
8094 if (undef) {
8095 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8096 default_exception_el(s));
8097 return;
8100 addr = tcg_temp_new_i32();
8101 tmp = tcg_const_i32(mode);
8102 /* get_r13_banked() will raise an exception if called from System mode */
8103 gen_set_condexec(s);
8104 gen_set_pc_im(s, s->pc - 4);
8105 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8106 tcg_temp_free_i32(tmp);
8107 switch (amode) {
8108 case 0: /* DA */
8109 offset = -4;
8110 break;
8111 case 1: /* IA */
8112 offset = 0;
8113 break;
8114 case 2: /* DB */
8115 offset = -8;
8116 break;
8117 case 3: /* IB */
8118 offset = 4;
8119 break;
8120 default:
8121 abort();
8123 tcg_gen_addi_i32(addr, addr, offset);
8124 tmp = load_reg(s, 14);
8125 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8126 tcg_temp_free_i32(tmp);
8127 tmp = load_cpu_field(spsr);
8128 tcg_gen_addi_i32(addr, addr, 4);
8129 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8130 tcg_temp_free_i32(tmp);
8131 if (writeback) {
8132 switch (amode) {
8133 case 0:
8134 offset = -8;
8135 break;
8136 case 1:
8137 offset = 4;
8138 break;
8139 case 2:
8140 offset = -4;
8141 break;
8142 case 3:
8143 offset = 0;
8144 break;
8145 default:
8146 abort();
8148 tcg_gen_addi_i32(addr, addr, offset);
8149 tmp = tcg_const_i32(mode);
8150 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8151 tcg_temp_free_i32(tmp);
8153 tcg_temp_free_i32(addr);
8154 s->base.is_jmp = DISAS_UPDATE;
8157 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8159 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8160 TCGv_i32 tmp;
8161 TCGv_i32 tmp2;
8162 TCGv_i32 tmp3;
8163 TCGv_i32 addr;
8164 TCGv_i64 tmp64;
8166 /* M variants do not implement ARM mode; this must raise the INVSTATE
8167 * UsageFault exception.
8169 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8170 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8171 default_exception_el(s));
8172 return;
8174 cond = insn >> 28;
8175 if (cond == 0xf){
8176 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8177 * choose to UNDEF. In ARMv5 and above the space is used
8178 * for miscellaneous unconditional instructions.
8180 ARCH(5);
8182 /* Unconditional instructions. */
8183 if (((insn >> 25) & 7) == 1) {
8184 /* NEON Data processing. */
8185 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8186 goto illegal_op;
8189 if (disas_neon_data_insn(s, insn)) {
8190 goto illegal_op;
8192 return;
8194 if ((insn & 0x0f100000) == 0x04000000) {
8195 /* NEON load/store. */
8196 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8197 goto illegal_op;
8200 if (disas_neon_ls_insn(s, insn)) {
8201 goto illegal_op;
8203 return;
8205 if ((insn & 0x0f000e10) == 0x0e000a00) {
8206 /* VFP. */
8207 if (disas_vfp_insn(s, insn)) {
8208 goto illegal_op;
8210 return;
8212 if (((insn & 0x0f30f000) == 0x0510f000) ||
8213 ((insn & 0x0f30f010) == 0x0710f000)) {
8214 if ((insn & (1 << 22)) == 0) {
8215 /* PLDW; v7MP */
8216 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8217 goto illegal_op;
8220 /* Otherwise PLD; v5TE+ */
8221 ARCH(5TE);
8222 return;
8224 if (((insn & 0x0f70f000) == 0x0450f000) ||
8225 ((insn & 0x0f70f010) == 0x0650f000)) {
8226 ARCH(7);
8227 return; /* PLI; V7 */
8229 if (((insn & 0x0f700000) == 0x04100000) ||
8230 ((insn & 0x0f700010) == 0x06100000)) {
8231 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8232 goto illegal_op;
8234 return; /* v7MP: Unallocated memory hint: must NOP */
8237 if ((insn & 0x0ffffdff) == 0x01010000) {
8238 ARCH(6);
8239 /* setend */
8240 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8241 gen_helper_setend(cpu_env);
8242 s->base.is_jmp = DISAS_UPDATE;
8244 return;
8245 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8246 switch ((insn >> 4) & 0xf) {
8247 case 1: /* clrex */
8248 ARCH(6K);
8249 gen_clrex(s);
8250 return;
8251 case 4: /* dsb */
8252 case 5: /* dmb */
8253 ARCH(7);
8254 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8255 return;
8256 case 6: /* isb */
8257 /* We need to break the TB after this insn to execute
8258 * self-modifying code correctly and also to take
8259 * any pending interrupts immediately.
8261 gen_goto_tb(s, 0, s->pc & ~1);
8262 return;
8263 default:
8264 goto illegal_op;
8266 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8267 /* srs */
8268 ARCH(6);
8269 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8270 return;
8271 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8272 /* rfe */
8273 int32_t offset;
8274 if (IS_USER(s))
8275 goto illegal_op;
8276 ARCH(6);
8277 rn = (insn >> 16) & 0xf;
8278 addr = load_reg(s, rn);
8279 i = (insn >> 23) & 3;
8280 switch (i) {
8281 case 0: offset = -4; break; /* DA */
8282 case 1: offset = 0; break; /* IA */
8283 case 2: offset = -8; break; /* DB */
8284 case 3: offset = 4; break; /* IB */
8285 default: abort();
8287 if (offset)
8288 tcg_gen_addi_i32(addr, addr, offset);
8289 /* Load PC into tmp and CPSR into tmp2. */
8290 tmp = tcg_temp_new_i32();
8291 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8292 tcg_gen_addi_i32(addr, addr, 4);
8293 tmp2 = tcg_temp_new_i32();
8294 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8295 if (insn & (1 << 21)) {
8296 /* Base writeback. */
8297 switch (i) {
8298 case 0: offset = -8; break;
8299 case 1: offset = 4; break;
8300 case 2: offset = -4; break;
8301 case 3: offset = 0; break;
8302 default: abort();
8304 if (offset)
8305 tcg_gen_addi_i32(addr, addr, offset);
8306 store_reg(s, rn, addr);
8307 } else {
8308 tcg_temp_free_i32(addr);
8310 gen_rfe(s, tmp, tmp2);
8311 return;
8312 } else if ((insn & 0x0e000000) == 0x0a000000) {
8313 /* branch link and change to thumb (blx <offset>) */
8314 int32_t offset;
8316 val = (uint32_t)s->pc;
8317 tmp = tcg_temp_new_i32();
8318 tcg_gen_movi_i32(tmp, val);
8319 store_reg(s, 14, tmp);
8320 /* Sign-extend the 24-bit offset */
8321 offset = (((int32_t)insn) << 8) >> 8;
8322 /* offset * 4 + bit24 * 2 + (thumb bit) */
8323 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8324 /* pipeline offset */
8325 val += 4;
8326 /* protected by ARCH(5); above, near the start of uncond block */
8327 gen_bx_im(s, val);
8328 return;
8329 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8330 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8331 /* iWMMXt register transfer. */
8332 if (extract32(s->c15_cpar, 1, 1)) {
8333 if (!disas_iwmmxt_insn(s, insn)) {
8334 return;
8338 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8339 /* Coprocessor double register transfer. */
8340 ARCH(5TE);
8341 } else if ((insn & 0x0f000010) == 0x0e000010) {
8342 /* Additional coprocessor register transfer. */
8343 } else if ((insn & 0x0ff10020) == 0x01000000) {
8344 uint32_t mask;
8345 uint32_t val;
8346 /* cps (privileged) */
8347 if (IS_USER(s))
8348 return;
8349 mask = val = 0;
8350 if (insn & (1 << 19)) {
8351 if (insn & (1 << 8))
8352 mask |= CPSR_A;
8353 if (insn & (1 << 7))
8354 mask |= CPSR_I;
8355 if (insn & (1 << 6))
8356 mask |= CPSR_F;
8357 if (insn & (1 << 18))
8358 val |= mask;
8360 if (insn & (1 << 17)) {
8361 mask |= CPSR_M;
8362 val |= (insn & 0x1f);
8364 if (mask) {
8365 gen_set_psr_im(s, mask, 0, val);
8367 return;
8369 goto illegal_op;
8371 if (cond != 0xe) {
8372 /* if not always execute, we generate a conditional jump to
8373 next instruction */
8374 s->condlabel = gen_new_label();
8375 arm_gen_test_cc(cond ^ 1, s->condlabel);
8376 s->condjmp = 1;
8378 if ((insn & 0x0f900000) == 0x03000000) {
8379 if ((insn & (1 << 21)) == 0) {
8380 ARCH(6T2);
8381 rd = (insn >> 12) & 0xf;
8382 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8383 if ((insn & (1 << 22)) == 0) {
8384 /* MOVW */
8385 tmp = tcg_temp_new_i32();
8386 tcg_gen_movi_i32(tmp, val);
8387 } else {
8388 /* MOVT */
8389 tmp = load_reg(s, rd);
8390 tcg_gen_ext16u_i32(tmp, tmp);
8391 tcg_gen_ori_i32(tmp, tmp, val << 16);
8393 store_reg(s, rd, tmp);
8394 } else {
8395 if (((insn >> 12) & 0xf) != 0xf)
8396 goto illegal_op;
8397 if (((insn >> 16) & 0xf) == 0) {
8398 gen_nop_hint(s, insn & 0xff);
8399 } else {
8400 /* CPSR = immediate */
8401 val = insn & 0xff;
8402 shift = ((insn >> 8) & 0xf) * 2;
8403 if (shift)
8404 val = (val >> shift) | (val << (32 - shift));
8405 i = ((insn & (1 << 22)) != 0);
8406 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8407 i, val)) {
8408 goto illegal_op;
8412 } else if ((insn & 0x0f900000) == 0x01000000
8413 && (insn & 0x00000090) != 0x00000090) {
8414 /* miscellaneous instructions */
8415 op1 = (insn >> 21) & 3;
8416 sh = (insn >> 4) & 0xf;
8417 rm = insn & 0xf;
8418 switch (sh) {
8419 case 0x0: /* MSR, MRS */
8420 if (insn & (1 << 9)) {
8421 /* MSR (banked) and MRS (banked) */
8422 int sysm = extract32(insn, 16, 4) |
8423 (extract32(insn, 8, 1) << 4);
8424 int r = extract32(insn, 22, 1);
8426 if (op1 & 1) {
8427 /* MSR (banked) */
8428 gen_msr_banked(s, r, sysm, rm);
8429 } else {
8430 /* MRS (banked) */
8431 int rd = extract32(insn, 12, 4);
8433 gen_mrs_banked(s, r, sysm, rd);
8435 break;
8438 /* MSR, MRS (for PSRs) */
8439 if (op1 & 1) {
8440 /* PSR = reg */
8441 tmp = load_reg(s, rm);
8442 i = ((op1 & 2) != 0);
8443 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8444 goto illegal_op;
8445 } else {
8446 /* reg = PSR */
8447 rd = (insn >> 12) & 0xf;
8448 if (op1 & 2) {
8449 if (IS_USER(s))
8450 goto illegal_op;
8451 tmp = load_cpu_field(spsr);
8452 } else {
8453 tmp = tcg_temp_new_i32();
8454 gen_helper_cpsr_read(tmp, cpu_env);
8456 store_reg(s, rd, tmp);
8458 break;
8459 case 0x1:
8460 if (op1 == 1) {
8461 /* branch/exchange thumb (bx). */
8462 ARCH(4T);
8463 tmp = load_reg(s, rm);
8464 gen_bx(s, tmp);
8465 } else if (op1 == 3) {
8466 /* clz */
8467 ARCH(5);
8468 rd = (insn >> 12) & 0xf;
8469 tmp = load_reg(s, rm);
8470 tcg_gen_clzi_i32(tmp, tmp, 32);
8471 store_reg(s, rd, tmp);
8472 } else {
8473 goto illegal_op;
8475 break;
8476 case 0x2:
8477 if (op1 == 1) {
8478 ARCH(5J); /* bxj */
8479 /* Trivial implementation equivalent to bx. */
8480 tmp = load_reg(s, rm);
8481 gen_bx(s, tmp);
8482 } else {
8483 goto illegal_op;
8485 break;
8486 case 0x3:
8487 if (op1 != 1)
8488 goto illegal_op;
8490 ARCH(5);
8491 /* branch link/exchange thumb (blx) */
8492 tmp = load_reg(s, rm);
8493 tmp2 = tcg_temp_new_i32();
8494 tcg_gen_movi_i32(tmp2, s->pc);
8495 store_reg(s, 14, tmp2);
8496 gen_bx(s, tmp);
8497 break;
8498 case 0x4:
8500 /* crc32/crc32c */
8501 uint32_t c = extract32(insn, 8, 4);
8503 /* Check this CPU supports ARMv8 CRC instructions.
8504 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8505 * Bits 8, 10 and 11 should be zero.
8507 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8508 (c & 0xd) != 0) {
8509 goto illegal_op;
8512 rn = extract32(insn, 16, 4);
8513 rd = extract32(insn, 12, 4);
8515 tmp = load_reg(s, rn);
8516 tmp2 = load_reg(s, rm);
8517 if (op1 == 0) {
8518 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8519 } else if (op1 == 1) {
8520 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8522 tmp3 = tcg_const_i32(1 << op1);
8523 if (c & 0x2) {
8524 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8525 } else {
8526 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8528 tcg_temp_free_i32(tmp2);
8529 tcg_temp_free_i32(tmp3);
8530 store_reg(s, rd, tmp);
8531 break;
8533 case 0x5: /* saturating add/subtract */
8534 ARCH(5TE);
8535 rd = (insn >> 12) & 0xf;
8536 rn = (insn >> 16) & 0xf;
8537 tmp = load_reg(s, rm);
8538 tmp2 = load_reg(s, rn);
8539 if (op1 & 2)
8540 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8541 if (op1 & 1)
8542 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8543 else
8544 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8545 tcg_temp_free_i32(tmp2);
8546 store_reg(s, rd, tmp);
8547 break;
8548 case 7:
8550 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8551 switch (op1) {
8552 case 0:
8553 /* HLT */
8554 gen_hlt(s, imm16);
8555 break;
8556 case 1:
8557 /* bkpt */
8558 ARCH(5);
8559 gen_exception_insn(s, 4, EXCP_BKPT,
8560 syn_aa32_bkpt(imm16, false),
8561 default_exception_el(s));
8562 break;
8563 case 2:
8564 /* Hypervisor call (v7) */
8565 ARCH(7);
8566 if (IS_USER(s)) {
8567 goto illegal_op;
8569 gen_hvc(s, imm16);
8570 break;
8571 case 3:
8572 /* Secure monitor call (v6+) */
8573 ARCH(6K);
8574 if (IS_USER(s)) {
8575 goto illegal_op;
8577 gen_smc(s);
8578 break;
8579 default:
8580 g_assert_not_reached();
8582 break;
8584 case 0x8: /* signed multiply */
8585 case 0xa:
8586 case 0xc:
8587 case 0xe:
8588 ARCH(5TE);
8589 rs = (insn >> 8) & 0xf;
8590 rn = (insn >> 12) & 0xf;
8591 rd = (insn >> 16) & 0xf;
8592 if (op1 == 1) {
8593 /* (32 * 16) >> 16 */
8594 tmp = load_reg(s, rm);
8595 tmp2 = load_reg(s, rs);
8596 if (sh & 4)
8597 tcg_gen_sari_i32(tmp2, tmp2, 16);
8598 else
8599 gen_sxth(tmp2);
8600 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8601 tcg_gen_shri_i64(tmp64, tmp64, 16);
8602 tmp = tcg_temp_new_i32();
8603 tcg_gen_extrl_i64_i32(tmp, tmp64);
8604 tcg_temp_free_i64(tmp64);
8605 if ((sh & 2) == 0) {
8606 tmp2 = load_reg(s, rn);
8607 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8608 tcg_temp_free_i32(tmp2);
8610 store_reg(s, rd, tmp);
8611 } else {
8612 /* 16 * 16 */
8613 tmp = load_reg(s, rm);
8614 tmp2 = load_reg(s, rs);
8615 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8616 tcg_temp_free_i32(tmp2);
8617 if (op1 == 2) {
8618 tmp64 = tcg_temp_new_i64();
8619 tcg_gen_ext_i32_i64(tmp64, tmp);
8620 tcg_temp_free_i32(tmp);
8621 gen_addq(s, tmp64, rn, rd);
8622 gen_storeq_reg(s, rn, rd, tmp64);
8623 tcg_temp_free_i64(tmp64);
8624 } else {
8625 if (op1 == 0) {
8626 tmp2 = load_reg(s, rn);
8627 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8628 tcg_temp_free_i32(tmp2);
8630 store_reg(s, rd, tmp);
8633 break;
8634 default:
8635 goto illegal_op;
8637 } else if (((insn & 0x0e000000) == 0 &&
8638 (insn & 0x00000090) != 0x90) ||
8639 ((insn & 0x0e000000) == (1 << 25))) {
8640 int set_cc, logic_cc, shiftop;
8642 op1 = (insn >> 21) & 0xf;
8643 set_cc = (insn >> 20) & 1;
8644 logic_cc = table_logic_cc[op1] & set_cc;
8646 /* data processing instruction */
8647 if (insn & (1 << 25)) {
8648 /* immediate operand */
8649 val = insn & 0xff;
8650 shift = ((insn >> 8) & 0xf) * 2;
8651 if (shift) {
8652 val = (val >> shift) | (val << (32 - shift));
8654 tmp2 = tcg_temp_new_i32();
8655 tcg_gen_movi_i32(tmp2, val);
8656 if (logic_cc && shift) {
8657 gen_set_CF_bit31(tmp2);
8659 } else {
8660 /* register */
8661 rm = (insn) & 0xf;
8662 tmp2 = load_reg(s, rm);
8663 shiftop = (insn >> 5) & 3;
8664 if (!(insn & (1 << 4))) {
8665 shift = (insn >> 7) & 0x1f;
8666 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8667 } else {
8668 rs = (insn >> 8) & 0xf;
8669 tmp = load_reg(s, rs);
8670 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8673 if (op1 != 0x0f && op1 != 0x0d) {
8674 rn = (insn >> 16) & 0xf;
8675 tmp = load_reg(s, rn);
8676 } else {
8677 tmp = NULL;
8679 rd = (insn >> 12) & 0xf;
8680 switch(op1) {
8681 case 0x00:
8682 tcg_gen_and_i32(tmp, tmp, tmp2);
8683 if (logic_cc) {
8684 gen_logic_CC(tmp);
8686 store_reg_bx(s, rd, tmp);
8687 break;
8688 case 0x01:
8689 tcg_gen_xor_i32(tmp, tmp, tmp2);
8690 if (logic_cc) {
8691 gen_logic_CC(tmp);
8693 store_reg_bx(s, rd, tmp);
8694 break;
8695 case 0x02:
8696 if (set_cc && rd == 15) {
8697 /* SUBS r15, ... is used for exception return. */
8698 if (IS_USER(s)) {
8699 goto illegal_op;
8701 gen_sub_CC(tmp, tmp, tmp2);
8702 gen_exception_return(s, tmp);
8703 } else {
8704 if (set_cc) {
8705 gen_sub_CC(tmp, tmp, tmp2);
8706 } else {
8707 tcg_gen_sub_i32(tmp, tmp, tmp2);
8709 store_reg_bx(s, rd, tmp);
8711 break;
8712 case 0x03:
8713 if (set_cc) {
8714 gen_sub_CC(tmp, tmp2, tmp);
8715 } else {
8716 tcg_gen_sub_i32(tmp, tmp2, tmp);
8718 store_reg_bx(s, rd, tmp);
8719 break;
8720 case 0x04:
8721 if (set_cc) {
8722 gen_add_CC(tmp, tmp, tmp2);
8723 } else {
8724 tcg_gen_add_i32(tmp, tmp, tmp2);
8726 store_reg_bx(s, rd, tmp);
8727 break;
8728 case 0x05:
8729 if (set_cc) {
8730 gen_adc_CC(tmp, tmp, tmp2);
8731 } else {
8732 gen_add_carry(tmp, tmp, tmp2);
8734 store_reg_bx(s, rd, tmp);
8735 break;
8736 case 0x06:
8737 if (set_cc) {
8738 gen_sbc_CC(tmp, tmp, tmp2);
8739 } else {
8740 gen_sub_carry(tmp, tmp, tmp2);
8742 store_reg_bx(s, rd, tmp);
8743 break;
8744 case 0x07:
8745 if (set_cc) {
8746 gen_sbc_CC(tmp, tmp2, tmp);
8747 } else {
8748 gen_sub_carry(tmp, tmp2, tmp);
8750 store_reg_bx(s, rd, tmp);
8751 break;
8752 case 0x08:
8753 if (set_cc) {
8754 tcg_gen_and_i32(tmp, tmp, tmp2);
8755 gen_logic_CC(tmp);
8757 tcg_temp_free_i32(tmp);
8758 break;
8759 case 0x09:
8760 if (set_cc) {
8761 tcg_gen_xor_i32(tmp, tmp, tmp2);
8762 gen_logic_CC(tmp);
8764 tcg_temp_free_i32(tmp);
8765 break;
8766 case 0x0a:
8767 if (set_cc) {
8768 gen_sub_CC(tmp, tmp, tmp2);
8770 tcg_temp_free_i32(tmp);
8771 break;
8772 case 0x0b:
8773 if (set_cc) {
8774 gen_add_CC(tmp, tmp, tmp2);
8776 tcg_temp_free_i32(tmp);
8777 break;
8778 case 0x0c:
8779 tcg_gen_or_i32(tmp, tmp, tmp2);
8780 if (logic_cc) {
8781 gen_logic_CC(tmp);
8783 store_reg_bx(s, rd, tmp);
8784 break;
8785 case 0x0d:
8786 if (logic_cc && rd == 15) {
8787 /* MOVS r15, ... is used for exception return. */
8788 if (IS_USER(s)) {
8789 goto illegal_op;
8791 gen_exception_return(s, tmp2);
8792 } else {
8793 if (logic_cc) {
8794 gen_logic_CC(tmp2);
8796 store_reg_bx(s, rd, tmp2);
8798 break;
8799 case 0x0e:
8800 tcg_gen_andc_i32(tmp, tmp, tmp2);
8801 if (logic_cc) {
8802 gen_logic_CC(tmp);
8804 store_reg_bx(s, rd, tmp);
8805 break;
8806 default:
8807 case 0x0f:
8808 tcg_gen_not_i32(tmp2, tmp2);
8809 if (logic_cc) {
8810 gen_logic_CC(tmp2);
8812 store_reg_bx(s, rd, tmp2);
8813 break;
8815 if (op1 != 0x0f && op1 != 0x0d) {
8816 tcg_temp_free_i32(tmp2);
8818 } else {
8819 /* other instructions */
8820 op1 = (insn >> 24) & 0xf;
8821 switch(op1) {
8822 case 0x0:
8823 case 0x1:
8824 /* multiplies, extra load/stores */
8825 sh = (insn >> 5) & 3;
8826 if (sh == 0) {
8827 if (op1 == 0x0) {
8828 rd = (insn >> 16) & 0xf;
8829 rn = (insn >> 12) & 0xf;
8830 rs = (insn >> 8) & 0xf;
8831 rm = (insn) & 0xf;
8832 op1 = (insn >> 20) & 0xf;
8833 switch (op1) {
8834 case 0: case 1: case 2: case 3: case 6:
8835 /* 32 bit mul */
8836 tmp = load_reg(s, rs);
8837 tmp2 = load_reg(s, rm);
8838 tcg_gen_mul_i32(tmp, tmp, tmp2);
8839 tcg_temp_free_i32(tmp2);
8840 if (insn & (1 << 22)) {
8841 /* Subtract (mls) */
8842 ARCH(6T2);
8843 tmp2 = load_reg(s, rn);
8844 tcg_gen_sub_i32(tmp, tmp2, tmp);
8845 tcg_temp_free_i32(tmp2);
8846 } else if (insn & (1 << 21)) {
8847 /* Add */
8848 tmp2 = load_reg(s, rn);
8849 tcg_gen_add_i32(tmp, tmp, tmp2);
8850 tcg_temp_free_i32(tmp2);
8852 if (insn & (1 << 20))
8853 gen_logic_CC(tmp);
8854 store_reg(s, rd, tmp);
8855 break;
8856 case 4:
8857 /* 64 bit mul double accumulate (UMAAL) */
8858 ARCH(6);
8859 tmp = load_reg(s, rs);
8860 tmp2 = load_reg(s, rm);
8861 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8862 gen_addq_lo(s, tmp64, rn);
8863 gen_addq_lo(s, tmp64, rd);
8864 gen_storeq_reg(s, rn, rd, tmp64);
8865 tcg_temp_free_i64(tmp64);
8866 break;
8867 case 8: case 9: case 10: case 11:
8868 case 12: case 13: case 14: case 15:
8869 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8870 tmp = load_reg(s, rs);
8871 tmp2 = load_reg(s, rm);
8872 if (insn & (1 << 22)) {
8873 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8874 } else {
8875 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8877 if (insn & (1 << 21)) { /* mult accumulate */
8878 TCGv_i32 al = load_reg(s, rn);
8879 TCGv_i32 ah = load_reg(s, rd);
8880 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8881 tcg_temp_free_i32(al);
8882 tcg_temp_free_i32(ah);
8884 if (insn & (1 << 20)) {
8885 gen_logicq_cc(tmp, tmp2);
8887 store_reg(s, rn, tmp);
8888 store_reg(s, rd, tmp2);
8889 break;
8890 default:
8891 goto illegal_op;
8893 } else {
8894 rn = (insn >> 16) & 0xf;
8895 rd = (insn >> 12) & 0xf;
8896 if (insn & (1 << 23)) {
8897 /* load/store exclusive */
8898 int op2 = (insn >> 8) & 3;
8899 op1 = (insn >> 21) & 0x3;
8901 switch (op2) {
8902 case 0: /* lda/stl */
8903 if (op1 == 1) {
8904 goto illegal_op;
8906 ARCH(8);
8907 break;
8908 case 1: /* reserved */
8909 goto illegal_op;
8910 case 2: /* ldaex/stlex */
8911 ARCH(8);
8912 break;
8913 case 3: /* ldrex/strex */
8914 if (op1) {
8915 ARCH(6K);
8916 } else {
8917 ARCH(6);
8919 break;
8922 addr = tcg_temp_local_new_i32();
8923 load_reg_var(s, addr, rn);
8925 /* Since the emulation does not have barriers,
8926 the acquire/release semantics need no special
8927 handling */
8928 if (op2 == 0) {
8929 if (insn & (1 << 20)) {
8930 tmp = tcg_temp_new_i32();
8931 switch (op1) {
8932 case 0: /* lda */
8933 gen_aa32_ld32u_iss(s, tmp, addr,
8934 get_mem_index(s),
8935 rd | ISSIsAcqRel);
8936 break;
8937 case 2: /* ldab */
8938 gen_aa32_ld8u_iss(s, tmp, addr,
8939 get_mem_index(s),
8940 rd | ISSIsAcqRel);
8941 break;
8942 case 3: /* ldah */
8943 gen_aa32_ld16u_iss(s, tmp, addr,
8944 get_mem_index(s),
8945 rd | ISSIsAcqRel);
8946 break;
8947 default:
8948 abort();
8950 store_reg(s, rd, tmp);
8951 } else {
8952 rm = insn & 0xf;
8953 tmp = load_reg(s, rm);
8954 switch (op1) {
8955 case 0: /* stl */
8956 gen_aa32_st32_iss(s, tmp, addr,
8957 get_mem_index(s),
8958 rm | ISSIsAcqRel);
8959 break;
8960 case 2: /* stlb */
8961 gen_aa32_st8_iss(s, tmp, addr,
8962 get_mem_index(s),
8963 rm | ISSIsAcqRel);
8964 break;
8965 case 3: /* stlh */
8966 gen_aa32_st16_iss(s, tmp, addr,
8967 get_mem_index(s),
8968 rm | ISSIsAcqRel);
8969 break;
8970 default:
8971 abort();
8973 tcg_temp_free_i32(tmp);
8975 } else if (insn & (1 << 20)) {
8976 switch (op1) {
8977 case 0: /* ldrex */
8978 gen_load_exclusive(s, rd, 15, addr, 2);
8979 break;
8980 case 1: /* ldrexd */
8981 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8982 break;
8983 case 2: /* ldrexb */
8984 gen_load_exclusive(s, rd, 15, addr, 0);
8985 break;
8986 case 3: /* ldrexh */
8987 gen_load_exclusive(s, rd, 15, addr, 1);
8988 break;
8989 default:
8990 abort();
8992 } else {
8993 rm = insn & 0xf;
8994 switch (op1) {
8995 case 0: /* strex */
8996 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8997 break;
8998 case 1: /* strexd */
8999 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9000 break;
9001 case 2: /* strexb */
9002 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9003 break;
9004 case 3: /* strexh */
9005 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9006 break;
9007 default:
9008 abort();
9011 tcg_temp_free_i32(addr);
9012 } else {
9013 TCGv taddr;
9014 TCGMemOp opc = s->be_data;
9016 /* SWP instruction */
9017 rm = (insn) & 0xf;
9019 if (insn & (1 << 22)) {
9020 opc |= MO_UB;
9021 } else {
9022 opc |= MO_UL | MO_ALIGN;
9025 addr = load_reg(s, rn);
9026 taddr = gen_aa32_addr(s, addr, opc);
9027 tcg_temp_free_i32(addr);
9029 tmp = load_reg(s, rm);
9030 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9031 get_mem_index(s), opc);
9032 tcg_temp_free(taddr);
9033 store_reg(s, rd, tmp);
9036 } else {
9037 int address_offset;
9038 bool load = insn & (1 << 20);
9039 bool wbit = insn & (1 << 21);
9040 bool pbit = insn & (1 << 24);
9041 bool doubleword = false;
9042 ISSInfo issinfo;
9044 /* Misc load/store */
9045 rn = (insn >> 16) & 0xf;
9046 rd = (insn >> 12) & 0xf;
9048 /* ISS not valid if writeback */
9049 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9051 if (!load && (sh & 2)) {
9052 /* doubleword */
9053 ARCH(5TE);
9054 if (rd & 1) {
9055 /* UNPREDICTABLE; we choose to UNDEF */
9056 goto illegal_op;
9058 load = (sh & 1) == 0;
9059 doubleword = true;
9062 addr = load_reg(s, rn);
9063 if (pbit) {
9064 gen_add_datah_offset(s, insn, 0, addr);
9066 address_offset = 0;
9068 if (doubleword) {
9069 if (!load) {
9070 /* store */
9071 tmp = load_reg(s, rd);
9072 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9073 tcg_temp_free_i32(tmp);
9074 tcg_gen_addi_i32(addr, addr, 4);
9075 tmp = load_reg(s, rd + 1);
9076 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9077 tcg_temp_free_i32(tmp);
9078 } else {
9079 /* load */
9080 tmp = tcg_temp_new_i32();
9081 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9082 store_reg(s, rd, tmp);
9083 tcg_gen_addi_i32(addr, addr, 4);
9084 tmp = tcg_temp_new_i32();
9085 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9086 rd++;
9088 address_offset = -4;
9089 } else if (load) {
9090 /* load */
9091 tmp = tcg_temp_new_i32();
9092 switch (sh) {
9093 case 1:
9094 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9095 issinfo);
9096 break;
9097 case 2:
9098 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9099 issinfo);
9100 break;
9101 default:
9102 case 3:
9103 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9104 issinfo);
9105 break;
9107 } else {
9108 /* store */
9109 tmp = load_reg(s, rd);
9110 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9111 tcg_temp_free_i32(tmp);
9113 /* Perform base writeback before the loaded value to
9114 ensure correct behavior with overlapping index registers.
9115 ldrd with base writeback is undefined if the
9116 destination and index registers overlap. */
9117 if (!pbit) {
9118 gen_add_datah_offset(s, insn, address_offset, addr);
9119 store_reg(s, rn, addr);
9120 } else if (wbit) {
9121 if (address_offset)
9122 tcg_gen_addi_i32(addr, addr, address_offset);
9123 store_reg(s, rn, addr);
9124 } else {
9125 tcg_temp_free_i32(addr);
9127 if (load) {
9128 /* Complete the load. */
9129 store_reg(s, rd, tmp);
9132 break;
9133 case 0x4:
9134 case 0x5:
9135 goto do_ldst;
9136 case 0x6:
9137 case 0x7:
9138 if (insn & (1 << 4)) {
9139 ARCH(6);
9140 /* Armv6 Media instructions. */
9141 rm = insn & 0xf;
9142 rn = (insn >> 16) & 0xf;
9143 rd = (insn >> 12) & 0xf;
9144 rs = (insn >> 8) & 0xf;
9145 switch ((insn >> 23) & 3) {
9146 case 0: /* Parallel add/subtract. */
9147 op1 = (insn >> 20) & 7;
9148 tmp = load_reg(s, rn);
9149 tmp2 = load_reg(s, rm);
9150 sh = (insn >> 5) & 7;
9151 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9152 goto illegal_op;
9153 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9154 tcg_temp_free_i32(tmp2);
9155 store_reg(s, rd, tmp);
9156 break;
9157 case 1:
9158 if ((insn & 0x00700020) == 0) {
9159 /* Halfword pack. */
9160 tmp = load_reg(s, rn);
9161 tmp2 = load_reg(s, rm);
9162 shift = (insn >> 7) & 0x1f;
9163 if (insn & (1 << 6)) {
9164 /* pkhtb */
9165 if (shift == 0)
9166 shift = 31;
9167 tcg_gen_sari_i32(tmp2, tmp2, shift);
9168 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9169 tcg_gen_ext16u_i32(tmp2, tmp2);
9170 } else {
9171 /* pkhbt */
9172 if (shift)
9173 tcg_gen_shli_i32(tmp2, tmp2, shift);
9174 tcg_gen_ext16u_i32(tmp, tmp);
9175 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9177 tcg_gen_or_i32(tmp, tmp, tmp2);
9178 tcg_temp_free_i32(tmp2);
9179 store_reg(s, rd, tmp);
9180 } else if ((insn & 0x00200020) == 0x00200000) {
9181 /* [us]sat */
9182 tmp = load_reg(s, rm);
9183 shift = (insn >> 7) & 0x1f;
9184 if (insn & (1 << 6)) {
9185 if (shift == 0)
9186 shift = 31;
9187 tcg_gen_sari_i32(tmp, tmp, shift);
9188 } else {
9189 tcg_gen_shli_i32(tmp, tmp, shift);
9191 sh = (insn >> 16) & 0x1f;
9192 tmp2 = tcg_const_i32(sh);
9193 if (insn & (1 << 22))
9194 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9195 else
9196 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9197 tcg_temp_free_i32(tmp2);
9198 store_reg(s, rd, tmp);
9199 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9200 /* [us]sat16 */
9201 tmp = load_reg(s, rm);
9202 sh = (insn >> 16) & 0x1f;
9203 tmp2 = tcg_const_i32(sh);
9204 if (insn & (1 << 22))
9205 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9206 else
9207 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9208 tcg_temp_free_i32(tmp2);
9209 store_reg(s, rd, tmp);
9210 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9211 /* Select bytes. */
9212 tmp = load_reg(s, rn);
9213 tmp2 = load_reg(s, rm);
9214 tmp3 = tcg_temp_new_i32();
9215 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9216 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9217 tcg_temp_free_i32(tmp3);
9218 tcg_temp_free_i32(tmp2);
9219 store_reg(s, rd, tmp);
9220 } else if ((insn & 0x000003e0) == 0x00000060) {
9221 tmp = load_reg(s, rm);
9222 shift = (insn >> 10) & 3;
9223 /* ??? In many cases it's not necessary to do a
9224 rotate, a shift is sufficient. */
9225 if (shift != 0)
9226 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9227 op1 = (insn >> 20) & 7;
9228 switch (op1) {
9229 case 0: gen_sxtb16(tmp); break;
9230 case 2: gen_sxtb(tmp); break;
9231 case 3: gen_sxth(tmp); break;
9232 case 4: gen_uxtb16(tmp); break;
9233 case 6: gen_uxtb(tmp); break;
9234 case 7: gen_uxth(tmp); break;
9235 default: goto illegal_op;
9237 if (rn != 15) {
9238 tmp2 = load_reg(s, rn);
9239 if ((op1 & 3) == 0) {
9240 gen_add16(tmp, tmp2);
9241 } else {
9242 tcg_gen_add_i32(tmp, tmp, tmp2);
9243 tcg_temp_free_i32(tmp2);
9246 store_reg(s, rd, tmp);
9247 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9248 /* rev */
9249 tmp = load_reg(s, rm);
9250 if (insn & (1 << 22)) {
9251 if (insn & (1 << 7)) {
9252 gen_revsh(tmp);
9253 } else {
9254 ARCH(6T2);
9255 gen_helper_rbit(tmp, tmp);
9257 } else {
9258 if (insn & (1 << 7))
9259 gen_rev16(tmp);
9260 else
9261 tcg_gen_bswap32_i32(tmp, tmp);
9263 store_reg(s, rd, tmp);
9264 } else {
9265 goto illegal_op;
9267 break;
9268 case 2: /* Multiplies (Type 3). */
9269 switch ((insn >> 20) & 0x7) {
9270 case 5:
9271 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9272 /* op2 not 00x or 11x : UNDEF */
9273 goto illegal_op;
9275 /* Signed multiply most significant [accumulate].
9276 (SMMUL, SMMLA, SMMLS) */
9277 tmp = load_reg(s, rm);
9278 tmp2 = load_reg(s, rs);
9279 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9281 if (rd != 15) {
9282 tmp = load_reg(s, rd);
9283 if (insn & (1 << 6)) {
9284 tmp64 = gen_subq_msw(tmp64, tmp);
9285 } else {
9286 tmp64 = gen_addq_msw(tmp64, tmp);
9289 if (insn & (1 << 5)) {
9290 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9292 tcg_gen_shri_i64(tmp64, tmp64, 32);
9293 tmp = tcg_temp_new_i32();
9294 tcg_gen_extrl_i64_i32(tmp, tmp64);
9295 tcg_temp_free_i64(tmp64);
9296 store_reg(s, rn, tmp);
9297 break;
9298 case 0:
9299 case 4:
9300 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9301 if (insn & (1 << 7)) {
9302 goto illegal_op;
9304 tmp = load_reg(s, rm);
9305 tmp2 = load_reg(s, rs);
9306 if (insn & (1 << 5))
9307 gen_swap_half(tmp2);
9308 gen_smul_dual(tmp, tmp2);
9309 if (insn & (1 << 22)) {
9310 /* smlald, smlsld */
9311 TCGv_i64 tmp64_2;
9313 tmp64 = tcg_temp_new_i64();
9314 tmp64_2 = tcg_temp_new_i64();
9315 tcg_gen_ext_i32_i64(tmp64, tmp);
9316 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9317 tcg_temp_free_i32(tmp);
9318 tcg_temp_free_i32(tmp2);
9319 if (insn & (1 << 6)) {
9320 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9321 } else {
9322 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9324 tcg_temp_free_i64(tmp64_2);
9325 gen_addq(s, tmp64, rd, rn);
9326 gen_storeq_reg(s, rd, rn, tmp64);
9327 tcg_temp_free_i64(tmp64);
9328 } else {
9329 /* smuad, smusd, smlad, smlsd */
9330 if (insn & (1 << 6)) {
9331 /* This subtraction cannot overflow. */
9332 tcg_gen_sub_i32(tmp, tmp, tmp2);
9333 } else {
9334 /* This addition cannot overflow 32 bits;
9335 * however it may overflow considered as a
9336 * signed operation, in which case we must set
9337 * the Q flag.
9339 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9341 tcg_temp_free_i32(tmp2);
9342 if (rd != 15)
9344 tmp2 = load_reg(s, rd);
9345 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9346 tcg_temp_free_i32(tmp2);
9348 store_reg(s, rn, tmp);
9350 break;
9351 case 1:
9352 case 3:
9353 /* SDIV, UDIV */
9354 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9355 goto illegal_op;
9357 if (((insn >> 5) & 7) || (rd != 15)) {
9358 goto illegal_op;
9360 tmp = load_reg(s, rm);
9361 tmp2 = load_reg(s, rs);
9362 if (insn & (1 << 21)) {
9363 gen_helper_udiv(tmp, tmp, tmp2);
9364 } else {
9365 gen_helper_sdiv(tmp, tmp, tmp2);
9367 tcg_temp_free_i32(tmp2);
9368 store_reg(s, rn, tmp);
9369 break;
9370 default:
9371 goto illegal_op;
9373 break;
9374 case 3:
9375 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9376 switch (op1) {
9377 case 0: /* Unsigned sum of absolute differences. */
9378 ARCH(6);
9379 tmp = load_reg(s, rm);
9380 tmp2 = load_reg(s, rs);
9381 gen_helper_usad8(tmp, tmp, tmp2);
9382 tcg_temp_free_i32(tmp2);
9383 if (rd != 15) {
9384 tmp2 = load_reg(s, rd);
9385 tcg_gen_add_i32(tmp, tmp, tmp2);
9386 tcg_temp_free_i32(tmp2);
9388 store_reg(s, rn, tmp);
9389 break;
9390 case 0x20: case 0x24: case 0x28: case 0x2c:
9391 /* Bitfield insert/clear. */
9392 ARCH(6T2);
9393 shift = (insn >> 7) & 0x1f;
9394 i = (insn >> 16) & 0x1f;
9395 if (i < shift) {
9396 /* UNPREDICTABLE; we choose to UNDEF */
9397 goto illegal_op;
9399 i = i + 1 - shift;
9400 if (rm == 15) {
9401 tmp = tcg_temp_new_i32();
9402 tcg_gen_movi_i32(tmp, 0);
9403 } else {
9404 tmp = load_reg(s, rm);
9406 if (i != 32) {
9407 tmp2 = load_reg(s, rd);
9408 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9409 tcg_temp_free_i32(tmp2);
9411 store_reg(s, rd, tmp);
9412 break;
9413 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9414 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9415 ARCH(6T2);
9416 tmp = load_reg(s, rm);
9417 shift = (insn >> 7) & 0x1f;
9418 i = ((insn >> 16) & 0x1f) + 1;
9419 if (shift + i > 32)
9420 goto illegal_op;
9421 if (i < 32) {
9422 if (op1 & 0x20) {
9423 tcg_gen_extract_i32(tmp, tmp, shift, i);
9424 } else {
9425 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9428 store_reg(s, rd, tmp);
9429 break;
9430 default:
9431 goto illegal_op;
9433 break;
9435 break;
9437 do_ldst:
9438 /* Check for undefined extension instructions
9439 * per the ARM Bible IE:
9440 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9442 sh = (0xf << 20) | (0xf << 4);
9443 if (op1 == 0x7 && ((insn & sh) == sh))
9445 goto illegal_op;
9447 /* load/store byte/word */
9448 rn = (insn >> 16) & 0xf;
9449 rd = (insn >> 12) & 0xf;
9450 tmp2 = load_reg(s, rn);
9451 if ((insn & 0x01200000) == 0x00200000) {
9452 /* ldrt/strt */
9453 i = get_a32_user_mem_index(s);
9454 } else {
9455 i = get_mem_index(s);
9457 if (insn & (1 << 24))
9458 gen_add_data_offset(s, insn, tmp2);
9459 if (insn & (1 << 20)) {
9460 /* load */
9461 tmp = tcg_temp_new_i32();
9462 if (insn & (1 << 22)) {
9463 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9464 } else {
9465 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9467 } else {
9468 /* store */
9469 tmp = load_reg(s, rd);
9470 if (insn & (1 << 22)) {
9471 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9472 } else {
9473 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9475 tcg_temp_free_i32(tmp);
9477 if (!(insn & (1 << 24))) {
9478 gen_add_data_offset(s, insn, tmp2);
9479 store_reg(s, rn, tmp2);
9480 } else if (insn & (1 << 21)) {
9481 store_reg(s, rn, tmp2);
9482 } else {
9483 tcg_temp_free_i32(tmp2);
9485 if (insn & (1 << 20)) {
9486 /* Complete the load. */
9487 store_reg_from_load(s, rd, tmp);
9489 break;
9490 case 0x08:
9491 case 0x09:
9493 int j, n, loaded_base;
9494 bool exc_return = false;
9495 bool is_load = extract32(insn, 20, 1);
9496 bool user = false;
9497 TCGv_i32 loaded_var;
9498 /* load/store multiple words */
9499 /* XXX: store correct base if write back */
9500 if (insn & (1 << 22)) {
9501 /* LDM (user), LDM (exception return) and STM (user) */
9502 if (IS_USER(s))
9503 goto illegal_op; /* only usable in supervisor mode */
9505 if (is_load && extract32(insn, 15, 1)) {
9506 exc_return = true;
9507 } else {
9508 user = true;
9511 rn = (insn >> 16) & 0xf;
9512 addr = load_reg(s, rn);
9514 /* compute total size */
9515 loaded_base = 0;
9516 loaded_var = NULL;
9517 n = 0;
9518 for(i=0;i<16;i++) {
9519 if (insn & (1 << i))
9520 n++;
9522 /* XXX: test invalid n == 0 case ? */
9523 if (insn & (1 << 23)) {
9524 if (insn & (1 << 24)) {
9525 /* pre increment */
9526 tcg_gen_addi_i32(addr, addr, 4);
9527 } else {
9528 /* post increment */
9530 } else {
9531 if (insn & (1 << 24)) {
9532 /* pre decrement */
9533 tcg_gen_addi_i32(addr, addr, -(n * 4));
9534 } else {
9535 /* post decrement */
9536 if (n != 1)
9537 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9540 j = 0;
9541 for(i=0;i<16;i++) {
9542 if (insn & (1 << i)) {
9543 if (is_load) {
9544 /* load */
9545 tmp = tcg_temp_new_i32();
9546 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9547 if (user) {
9548 tmp2 = tcg_const_i32(i);
9549 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9550 tcg_temp_free_i32(tmp2);
9551 tcg_temp_free_i32(tmp);
9552 } else if (i == rn) {
9553 loaded_var = tmp;
9554 loaded_base = 1;
9555 } else if (rn == 15 && exc_return) {
9556 store_pc_exc_ret(s, tmp);
9557 } else {
9558 store_reg_from_load(s, i, tmp);
9560 } else {
9561 /* store */
9562 if (i == 15) {
9563 /* special case: r15 = PC + 8 */
9564 val = (long)s->pc + 4;
9565 tmp = tcg_temp_new_i32();
9566 tcg_gen_movi_i32(tmp, val);
9567 } else if (user) {
9568 tmp = tcg_temp_new_i32();
9569 tmp2 = tcg_const_i32(i);
9570 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9571 tcg_temp_free_i32(tmp2);
9572 } else {
9573 tmp = load_reg(s, i);
9575 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9576 tcg_temp_free_i32(tmp);
9578 j++;
9579 /* no need to add after the last transfer */
9580 if (j != n)
9581 tcg_gen_addi_i32(addr, addr, 4);
9584 if (insn & (1 << 21)) {
9585 /* write back */
9586 if (insn & (1 << 23)) {
9587 if (insn & (1 << 24)) {
9588 /* pre increment */
9589 } else {
9590 /* post increment */
9591 tcg_gen_addi_i32(addr, addr, 4);
9593 } else {
9594 if (insn & (1 << 24)) {
9595 /* pre decrement */
9596 if (n != 1)
9597 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9598 } else {
9599 /* post decrement */
9600 tcg_gen_addi_i32(addr, addr, -(n * 4));
9603 store_reg(s, rn, addr);
9604 } else {
9605 tcg_temp_free_i32(addr);
9607 if (loaded_base) {
9608 store_reg(s, rn, loaded_var);
9610 if (exc_return) {
9611 /* Restore CPSR from SPSR. */
9612 tmp = load_cpu_field(spsr);
9613 gen_helper_cpsr_write_eret(cpu_env, tmp);
9614 tcg_temp_free_i32(tmp);
9615 /* Must exit loop to check un-masked IRQs */
9616 s->base.is_jmp = DISAS_EXIT;
9619 break;
9620 case 0xa:
9621 case 0xb:
9623 int32_t offset;
9625 /* branch (and link) */
9626 val = (int32_t)s->pc;
9627 if (insn & (1 << 24)) {
9628 tmp = tcg_temp_new_i32();
9629 tcg_gen_movi_i32(tmp, val);
9630 store_reg(s, 14, tmp);
9632 offset = sextract32(insn << 2, 0, 26);
9633 val += offset + 4;
9634 gen_jmp(s, val);
9636 break;
9637 case 0xc:
9638 case 0xd:
9639 case 0xe:
9640 if (((insn >> 8) & 0xe) == 10) {
9641 /* VFP. */
9642 if (disas_vfp_insn(s, insn)) {
9643 goto illegal_op;
9645 } else if (disas_coproc_insn(s, insn)) {
9646 /* Coprocessor. */
9647 goto illegal_op;
9649 break;
9650 case 0xf:
9651 /* swi */
9652 gen_set_pc_im(s, s->pc);
9653 s->svc_imm = extract32(insn, 0, 24);
9654 s->base.is_jmp = DISAS_SWI;
9655 break;
9656 default:
9657 illegal_op:
9658 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9659 default_exception_el(s));
9660 break;
9665 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9667 /* Return true if this is a 16 bit instruction. We must be precise
9668 * about this (matching the decode). We assume that s->pc still
9669 * points to the first 16 bits of the insn.
9671 if ((insn >> 11) < 0x1d) {
9672 /* Definitely a 16-bit instruction */
9673 return true;
9676 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9677 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9678 * end up actually treating this as two 16-bit insns, though,
9679 * if it's half of a bl/blx pair that might span a page boundary.
9681 if (arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
9682 /* Thumb2 cores (including all M profile ones) always treat
9683 * 32-bit insns as 32-bit.
9685 return false;
9688 if ((insn >> 11) == 0x1e && (s->pc < s->next_page_start - 3)) {
9689 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9690 * is not on the next page; we merge this into a 32-bit
9691 * insn.
9693 return false;
9695 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9696 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9697 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9698 * -- handle as single 16 bit insn
9700 return true;
9703 /* Return true if this is a Thumb-2 logical op. */
9704 static int
9705 thumb2_logic_op(int op)
9707 return (op < 8);
9710 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9711 then set condition code flags based on the result of the operation.
9712 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9713 to the high bit of T1.
9714 Returns zero if the opcode is valid. */
9716 static int
9717 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9718 TCGv_i32 t0, TCGv_i32 t1)
9720 int logic_cc;
9722 logic_cc = 0;
9723 switch (op) {
9724 case 0: /* and */
9725 tcg_gen_and_i32(t0, t0, t1);
9726 logic_cc = conds;
9727 break;
9728 case 1: /* bic */
9729 tcg_gen_andc_i32(t0, t0, t1);
9730 logic_cc = conds;
9731 break;
9732 case 2: /* orr */
9733 tcg_gen_or_i32(t0, t0, t1);
9734 logic_cc = conds;
9735 break;
9736 case 3: /* orn */
9737 tcg_gen_orc_i32(t0, t0, t1);
9738 logic_cc = conds;
9739 break;
9740 case 4: /* eor */
9741 tcg_gen_xor_i32(t0, t0, t1);
9742 logic_cc = conds;
9743 break;
9744 case 8: /* add */
9745 if (conds)
9746 gen_add_CC(t0, t0, t1);
9747 else
9748 tcg_gen_add_i32(t0, t0, t1);
9749 break;
9750 case 10: /* adc */
9751 if (conds)
9752 gen_adc_CC(t0, t0, t1);
9753 else
9754 gen_adc(t0, t1);
9755 break;
9756 case 11: /* sbc */
9757 if (conds) {
9758 gen_sbc_CC(t0, t0, t1);
9759 } else {
9760 gen_sub_carry(t0, t0, t1);
9762 break;
9763 case 13: /* sub */
9764 if (conds)
9765 gen_sub_CC(t0, t0, t1);
9766 else
9767 tcg_gen_sub_i32(t0, t0, t1);
9768 break;
9769 case 14: /* rsb */
9770 if (conds)
9771 gen_sub_CC(t0, t1, t0);
9772 else
9773 tcg_gen_sub_i32(t0, t1, t0);
9774 break;
9775 default: /* 5, 6, 7, 9, 12, 15. */
9776 return 1;
9778 if (logic_cc) {
9779 gen_logic_CC(t0);
9780 if (shifter_out)
9781 gen_set_CF_bit31(t1);
9783 return 0;
9786 /* Translate a 32-bit thumb instruction. */
9787 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9789 uint32_t imm, shift, offset;
9790 uint32_t rd, rn, rm, rs;
9791 TCGv_i32 tmp;
9792 TCGv_i32 tmp2;
9793 TCGv_i32 tmp3;
9794 TCGv_i32 addr;
9795 TCGv_i64 tmp64;
9796 int op;
9797 int shiftop;
9798 int conds;
9799 int logic_cc;
9801 /* The only 32 bit insn that's allowed for Thumb1 is the combined
9802 * BL/BLX prefix and suffix.
9804 if ((insn & 0xf800e800) != 0xf000e800) {
9805 ARCH(6T2);
9808 rn = (insn >> 16) & 0xf;
9809 rs = (insn >> 12) & 0xf;
9810 rd = (insn >> 8) & 0xf;
9811 rm = insn & 0xf;
9812 switch ((insn >> 25) & 0xf) {
9813 case 0: case 1: case 2: case 3:
9814 /* 16-bit instructions. Should never happen. */
9815 abort();
9816 case 4:
9817 if (insn & (1 << 22)) {
9818 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9819 * - load/store doubleword, load/store exclusive, ldacq/strel,
9820 * table branch, TT.
9822 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9823 arm_dc_feature(s, ARM_FEATURE_V8)) {
9824 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9825 * - SG (v8M only)
9826 * The bulk of the behaviour for this instruction is implemented
9827 * in v7m_handle_execute_nsc(), which deals with the insn when
9828 * it is executed by a CPU in non-secure state from memory
9829 * which is Secure & NonSecure-Callable.
9830 * Here we only need to handle the remaining cases:
9831 * * in NS memory (including the "security extension not
9832 * implemented" case) : NOP
9833 * * in S memory but CPU already secure (clear IT bits)
9834 * We know that the attribute for the memory this insn is
9835 * in must match the current CPU state, because otherwise
9836 * get_phys_addr_pmsav8 would have generated an exception.
9838 if (s->v8m_secure) {
9839 /* Like the IT insn, we don't need to generate any code */
9840 s->condexec_cond = 0;
9841 s->condexec_mask = 0;
9843 } else if (insn & 0x01200000) {
9844 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9845 * - load/store dual (post-indexed)
9846 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9847 * - load/store dual (literal and immediate)
9848 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9849 * - load/store dual (pre-indexed)
9851 if (rn == 15) {
9852 if (insn & (1 << 21)) {
9853 /* UNPREDICTABLE */
9854 goto illegal_op;
9856 addr = tcg_temp_new_i32();
9857 tcg_gen_movi_i32(addr, s->pc & ~3);
9858 } else {
9859 addr = load_reg(s, rn);
9861 offset = (insn & 0xff) * 4;
9862 if ((insn & (1 << 23)) == 0)
9863 offset = -offset;
9864 if (insn & (1 << 24)) {
9865 tcg_gen_addi_i32(addr, addr, offset);
9866 offset = 0;
9868 if (insn & (1 << 20)) {
9869 /* ldrd */
9870 tmp = tcg_temp_new_i32();
9871 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9872 store_reg(s, rs, tmp);
9873 tcg_gen_addi_i32(addr, addr, 4);
9874 tmp = tcg_temp_new_i32();
9875 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9876 store_reg(s, rd, tmp);
9877 } else {
9878 /* strd */
9879 tmp = load_reg(s, rs);
9880 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9881 tcg_temp_free_i32(tmp);
9882 tcg_gen_addi_i32(addr, addr, 4);
9883 tmp = load_reg(s, rd);
9884 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9885 tcg_temp_free_i32(tmp);
9887 if (insn & (1 << 21)) {
9888 /* Base writeback. */
9889 tcg_gen_addi_i32(addr, addr, offset - 4);
9890 store_reg(s, rn, addr);
9891 } else {
9892 tcg_temp_free_i32(addr);
9894 } else if ((insn & (1 << 23)) == 0) {
9895 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9896 * - load/store exclusive word
9897 * - TT (v8M only)
9899 if (rs == 15) {
9900 if (!(insn & (1 << 20)) &&
9901 arm_dc_feature(s, ARM_FEATURE_M) &&
9902 arm_dc_feature(s, ARM_FEATURE_V8)) {
9903 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9904 * - TT (v8M only)
9906 bool alt = insn & (1 << 7);
9907 TCGv_i32 addr, op, ttresp;
9909 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
9910 /* we UNDEF for these UNPREDICTABLE cases */
9911 goto illegal_op;
9914 if (alt && !s->v8m_secure) {
9915 goto illegal_op;
9918 addr = load_reg(s, rn);
9919 op = tcg_const_i32(extract32(insn, 6, 2));
9920 ttresp = tcg_temp_new_i32();
9921 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
9922 tcg_temp_free_i32(addr);
9923 tcg_temp_free_i32(op);
9924 store_reg(s, rd, ttresp);
9926 goto illegal_op;
9928 addr = tcg_temp_local_new_i32();
9929 load_reg_var(s, addr, rn);
9930 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9931 if (insn & (1 << 20)) {
9932 gen_load_exclusive(s, rs, 15, addr, 2);
9933 } else {
9934 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9936 tcg_temp_free_i32(addr);
9937 } else if ((insn & (7 << 5)) == 0) {
9938 /* Table Branch. */
9939 if (rn == 15) {
9940 addr = tcg_temp_new_i32();
9941 tcg_gen_movi_i32(addr, s->pc);
9942 } else {
9943 addr = load_reg(s, rn);
9945 tmp = load_reg(s, rm);
9946 tcg_gen_add_i32(addr, addr, tmp);
9947 if (insn & (1 << 4)) {
9948 /* tbh */
9949 tcg_gen_add_i32(addr, addr, tmp);
9950 tcg_temp_free_i32(tmp);
9951 tmp = tcg_temp_new_i32();
9952 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9953 } else { /* tbb */
9954 tcg_temp_free_i32(tmp);
9955 tmp = tcg_temp_new_i32();
9956 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9958 tcg_temp_free_i32(addr);
9959 tcg_gen_shli_i32(tmp, tmp, 1);
9960 tcg_gen_addi_i32(tmp, tmp, s->pc);
9961 store_reg(s, 15, tmp);
9962 } else {
9963 int op2 = (insn >> 6) & 0x3;
9964 op = (insn >> 4) & 0x3;
9965 switch (op2) {
9966 case 0:
9967 goto illegal_op;
9968 case 1:
9969 /* Load/store exclusive byte/halfword/doubleword */
9970 if (op == 2) {
9971 goto illegal_op;
9973 ARCH(7);
9974 break;
9975 case 2:
9976 /* Load-acquire/store-release */
9977 if (op == 3) {
9978 goto illegal_op;
9980 /* Fall through */
9981 case 3:
9982 /* Load-acquire/store-release exclusive */
9983 ARCH(8);
9984 break;
9986 addr = tcg_temp_local_new_i32();
9987 load_reg_var(s, addr, rn);
9988 if (!(op2 & 1)) {
9989 if (insn & (1 << 20)) {
9990 tmp = tcg_temp_new_i32();
9991 switch (op) {
9992 case 0: /* ldab */
9993 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9994 rs | ISSIsAcqRel);
9995 break;
9996 case 1: /* ldah */
9997 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9998 rs | ISSIsAcqRel);
9999 break;
10000 case 2: /* lda */
10001 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10002 rs | ISSIsAcqRel);
10003 break;
10004 default:
10005 abort();
10007 store_reg(s, rs, tmp);
10008 } else {
10009 tmp = load_reg(s, rs);
10010 switch (op) {
10011 case 0: /* stlb */
10012 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10013 rs | ISSIsAcqRel);
10014 break;
10015 case 1: /* stlh */
10016 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10017 rs | ISSIsAcqRel);
10018 break;
10019 case 2: /* stl */
10020 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10021 rs | ISSIsAcqRel);
10022 break;
10023 default:
10024 abort();
10026 tcg_temp_free_i32(tmp);
10028 } else if (insn & (1 << 20)) {
10029 gen_load_exclusive(s, rs, rd, addr, op);
10030 } else {
10031 gen_store_exclusive(s, rm, rs, rd, addr, op);
10033 tcg_temp_free_i32(addr);
10035 } else {
10036 /* Load/store multiple, RFE, SRS. */
10037 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10038 /* RFE, SRS: not available in user mode or on M profile */
10039 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10040 goto illegal_op;
10042 if (insn & (1 << 20)) {
10043 /* rfe */
10044 addr = load_reg(s, rn);
10045 if ((insn & (1 << 24)) == 0)
10046 tcg_gen_addi_i32(addr, addr, -8);
10047 /* Load PC into tmp and CPSR into tmp2. */
10048 tmp = tcg_temp_new_i32();
10049 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10050 tcg_gen_addi_i32(addr, addr, 4);
10051 tmp2 = tcg_temp_new_i32();
10052 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10053 if (insn & (1 << 21)) {
10054 /* Base writeback. */
10055 if (insn & (1 << 24)) {
10056 tcg_gen_addi_i32(addr, addr, 4);
10057 } else {
10058 tcg_gen_addi_i32(addr, addr, -4);
10060 store_reg(s, rn, addr);
10061 } else {
10062 tcg_temp_free_i32(addr);
10064 gen_rfe(s, tmp, tmp2);
10065 } else {
10066 /* srs */
10067 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10068 insn & (1 << 21));
10070 } else {
10071 int i, loaded_base = 0;
10072 TCGv_i32 loaded_var;
10073 /* Load/store multiple. */
10074 addr = load_reg(s, rn);
10075 offset = 0;
10076 for (i = 0; i < 16; i++) {
10077 if (insn & (1 << i))
10078 offset += 4;
10080 if (insn & (1 << 24)) {
10081 tcg_gen_addi_i32(addr, addr, -offset);
10084 loaded_var = NULL;
10085 for (i = 0; i < 16; i++) {
10086 if ((insn & (1 << i)) == 0)
10087 continue;
10088 if (insn & (1 << 20)) {
10089 /* Load. */
10090 tmp = tcg_temp_new_i32();
10091 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10092 if (i == 15) {
10093 gen_bx_excret(s, tmp);
10094 } else if (i == rn) {
10095 loaded_var = tmp;
10096 loaded_base = 1;
10097 } else {
10098 store_reg(s, i, tmp);
10100 } else {
10101 /* Store. */
10102 tmp = load_reg(s, i);
10103 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10104 tcg_temp_free_i32(tmp);
10106 tcg_gen_addi_i32(addr, addr, 4);
10108 if (loaded_base) {
10109 store_reg(s, rn, loaded_var);
10111 if (insn & (1 << 21)) {
10112 /* Base register writeback. */
10113 if (insn & (1 << 24)) {
10114 tcg_gen_addi_i32(addr, addr, -offset);
10116 /* Fault if writeback register is in register list. */
10117 if (insn & (1 << rn))
10118 goto illegal_op;
10119 store_reg(s, rn, addr);
10120 } else {
10121 tcg_temp_free_i32(addr);
10125 break;
10126 case 5:
10128 op = (insn >> 21) & 0xf;
10129 if (op == 6) {
10130 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10131 goto illegal_op;
10133 /* Halfword pack. */
10134 tmp = load_reg(s, rn);
10135 tmp2 = load_reg(s, rm);
10136 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10137 if (insn & (1 << 5)) {
10138 /* pkhtb */
10139 if (shift == 0)
10140 shift = 31;
10141 tcg_gen_sari_i32(tmp2, tmp2, shift);
10142 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10143 tcg_gen_ext16u_i32(tmp2, tmp2);
10144 } else {
10145 /* pkhbt */
10146 if (shift)
10147 tcg_gen_shli_i32(tmp2, tmp2, shift);
10148 tcg_gen_ext16u_i32(tmp, tmp);
10149 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10151 tcg_gen_or_i32(tmp, tmp, tmp2);
10152 tcg_temp_free_i32(tmp2);
10153 store_reg(s, rd, tmp);
10154 } else {
10155 /* Data processing register constant shift. */
10156 if (rn == 15) {
10157 tmp = tcg_temp_new_i32();
10158 tcg_gen_movi_i32(tmp, 0);
10159 } else {
10160 tmp = load_reg(s, rn);
10162 tmp2 = load_reg(s, rm);
10164 shiftop = (insn >> 4) & 3;
10165 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10166 conds = (insn & (1 << 20)) != 0;
10167 logic_cc = (conds && thumb2_logic_op(op));
10168 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10169 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10170 goto illegal_op;
10171 tcg_temp_free_i32(tmp2);
10172 if (rd != 15) {
10173 store_reg(s, rd, tmp);
10174 } else {
10175 tcg_temp_free_i32(tmp);
10178 break;
10179 case 13: /* Misc data processing. */
10180 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10181 if (op < 4 && (insn & 0xf000) != 0xf000)
10182 goto illegal_op;
10183 switch (op) {
10184 case 0: /* Register controlled shift. */
10185 tmp = load_reg(s, rn);
10186 tmp2 = load_reg(s, rm);
10187 if ((insn & 0x70) != 0)
10188 goto illegal_op;
10189 op = (insn >> 21) & 3;
10190 logic_cc = (insn & (1 << 20)) != 0;
10191 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10192 if (logic_cc)
10193 gen_logic_CC(tmp);
10194 store_reg(s, rd, tmp);
10195 break;
10196 case 1: /* Sign/zero extend. */
10197 op = (insn >> 20) & 7;
10198 switch (op) {
10199 case 0: /* SXTAH, SXTH */
10200 case 1: /* UXTAH, UXTH */
10201 case 4: /* SXTAB, SXTB */
10202 case 5: /* UXTAB, UXTB */
10203 break;
10204 case 2: /* SXTAB16, SXTB16 */
10205 case 3: /* UXTAB16, UXTB16 */
10206 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10207 goto illegal_op;
10209 break;
10210 default:
10211 goto illegal_op;
10213 if (rn != 15) {
10214 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10215 goto illegal_op;
10218 tmp = load_reg(s, rm);
10219 shift = (insn >> 4) & 3;
10220 /* ??? In many cases it's not necessary to do a
10221 rotate, a shift is sufficient. */
10222 if (shift != 0)
10223 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10224 op = (insn >> 20) & 7;
10225 switch (op) {
10226 case 0: gen_sxth(tmp); break;
10227 case 1: gen_uxth(tmp); break;
10228 case 2: gen_sxtb16(tmp); break;
10229 case 3: gen_uxtb16(tmp); break;
10230 case 4: gen_sxtb(tmp); break;
10231 case 5: gen_uxtb(tmp); break;
10232 default:
10233 g_assert_not_reached();
10235 if (rn != 15) {
10236 tmp2 = load_reg(s, rn);
10237 if ((op >> 1) == 1) {
10238 gen_add16(tmp, tmp2);
10239 } else {
10240 tcg_gen_add_i32(tmp, tmp, tmp2);
10241 tcg_temp_free_i32(tmp2);
10244 store_reg(s, rd, tmp);
10245 break;
10246 case 2: /* SIMD add/subtract. */
10247 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10248 goto illegal_op;
10250 op = (insn >> 20) & 7;
10251 shift = (insn >> 4) & 7;
10252 if ((op & 3) == 3 || (shift & 3) == 3)
10253 goto illegal_op;
10254 tmp = load_reg(s, rn);
10255 tmp2 = load_reg(s, rm);
10256 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10257 tcg_temp_free_i32(tmp2);
10258 store_reg(s, rd, tmp);
10259 break;
10260 case 3: /* Other data processing. */
10261 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10262 if (op < 4) {
10263 /* Saturating add/subtract. */
10264 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10265 goto illegal_op;
10267 tmp = load_reg(s, rn);
10268 tmp2 = load_reg(s, rm);
10269 if (op & 1)
10270 gen_helper_double_saturate(tmp, cpu_env, tmp);
10271 if (op & 2)
10272 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10273 else
10274 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10275 tcg_temp_free_i32(tmp2);
10276 } else {
10277 switch (op) {
10278 case 0x0a: /* rbit */
10279 case 0x08: /* rev */
10280 case 0x09: /* rev16 */
10281 case 0x0b: /* revsh */
10282 case 0x18: /* clz */
10283 break;
10284 case 0x10: /* sel */
10285 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10286 goto illegal_op;
10288 break;
10289 case 0x20: /* crc32/crc32c */
10290 case 0x21:
10291 case 0x22:
10292 case 0x28:
10293 case 0x29:
10294 case 0x2a:
10295 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10296 goto illegal_op;
10298 break;
10299 default:
10300 goto illegal_op;
10302 tmp = load_reg(s, rn);
10303 switch (op) {
10304 case 0x0a: /* rbit */
10305 gen_helper_rbit(tmp, tmp);
10306 break;
10307 case 0x08: /* rev */
10308 tcg_gen_bswap32_i32(tmp, tmp);
10309 break;
10310 case 0x09: /* rev16 */
10311 gen_rev16(tmp);
10312 break;
10313 case 0x0b: /* revsh */
10314 gen_revsh(tmp);
10315 break;
10316 case 0x10: /* sel */
10317 tmp2 = load_reg(s, rm);
10318 tmp3 = tcg_temp_new_i32();
10319 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10320 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10321 tcg_temp_free_i32(tmp3);
10322 tcg_temp_free_i32(tmp2);
10323 break;
10324 case 0x18: /* clz */
10325 tcg_gen_clzi_i32(tmp, tmp, 32);
10326 break;
10327 case 0x20:
10328 case 0x21:
10329 case 0x22:
10330 case 0x28:
10331 case 0x29:
10332 case 0x2a:
10334 /* crc32/crc32c */
10335 uint32_t sz = op & 0x3;
10336 uint32_t c = op & 0x8;
10338 tmp2 = load_reg(s, rm);
10339 if (sz == 0) {
10340 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10341 } else if (sz == 1) {
10342 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10344 tmp3 = tcg_const_i32(1 << sz);
10345 if (c) {
10346 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10347 } else {
10348 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10350 tcg_temp_free_i32(tmp2);
10351 tcg_temp_free_i32(tmp3);
10352 break;
10354 default:
10355 g_assert_not_reached();
10358 store_reg(s, rd, tmp);
10359 break;
10360 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10361 switch ((insn >> 20) & 7) {
10362 case 0: /* 32 x 32 -> 32 */
10363 case 7: /* Unsigned sum of absolute differences. */
10364 break;
10365 case 1: /* 16 x 16 -> 32 */
10366 case 2: /* Dual multiply add. */
10367 case 3: /* 32 * 16 -> 32msb */
10368 case 4: /* Dual multiply subtract. */
10369 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10370 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10371 goto illegal_op;
10373 break;
10375 op = (insn >> 4) & 0xf;
10376 tmp = load_reg(s, rn);
10377 tmp2 = load_reg(s, rm);
10378 switch ((insn >> 20) & 7) {
10379 case 0: /* 32 x 32 -> 32 */
10380 tcg_gen_mul_i32(tmp, tmp, tmp2);
10381 tcg_temp_free_i32(tmp2);
10382 if (rs != 15) {
10383 tmp2 = load_reg(s, rs);
10384 if (op)
10385 tcg_gen_sub_i32(tmp, tmp2, tmp);
10386 else
10387 tcg_gen_add_i32(tmp, tmp, tmp2);
10388 tcg_temp_free_i32(tmp2);
10390 break;
10391 case 1: /* 16 x 16 -> 32 */
10392 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10393 tcg_temp_free_i32(tmp2);
10394 if (rs != 15) {
10395 tmp2 = load_reg(s, rs);
10396 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10397 tcg_temp_free_i32(tmp2);
10399 break;
10400 case 2: /* Dual multiply add. */
10401 case 4: /* Dual multiply subtract. */
10402 if (op)
10403 gen_swap_half(tmp2);
10404 gen_smul_dual(tmp, tmp2);
10405 if (insn & (1 << 22)) {
10406 /* This subtraction cannot overflow. */
10407 tcg_gen_sub_i32(tmp, tmp, tmp2);
10408 } else {
10409 /* This addition cannot overflow 32 bits;
10410 * however it may overflow considered as a signed
10411 * operation, in which case we must set the Q flag.
10413 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10415 tcg_temp_free_i32(tmp2);
10416 if (rs != 15)
10418 tmp2 = load_reg(s, rs);
10419 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10420 tcg_temp_free_i32(tmp2);
10422 break;
10423 case 3: /* 32 * 16 -> 32msb */
10424 if (op)
10425 tcg_gen_sari_i32(tmp2, tmp2, 16);
10426 else
10427 gen_sxth(tmp2);
10428 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10429 tcg_gen_shri_i64(tmp64, tmp64, 16);
10430 tmp = tcg_temp_new_i32();
10431 tcg_gen_extrl_i64_i32(tmp, tmp64);
10432 tcg_temp_free_i64(tmp64);
10433 if (rs != 15)
10435 tmp2 = load_reg(s, rs);
10436 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10437 tcg_temp_free_i32(tmp2);
10439 break;
10440 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10441 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10442 if (rs != 15) {
10443 tmp = load_reg(s, rs);
10444 if (insn & (1 << 20)) {
10445 tmp64 = gen_addq_msw(tmp64, tmp);
10446 } else {
10447 tmp64 = gen_subq_msw(tmp64, tmp);
10450 if (insn & (1 << 4)) {
10451 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10453 tcg_gen_shri_i64(tmp64, tmp64, 32);
10454 tmp = tcg_temp_new_i32();
10455 tcg_gen_extrl_i64_i32(tmp, tmp64);
10456 tcg_temp_free_i64(tmp64);
10457 break;
10458 case 7: /* Unsigned sum of absolute differences. */
10459 gen_helper_usad8(tmp, tmp, tmp2);
10460 tcg_temp_free_i32(tmp2);
10461 if (rs != 15) {
10462 tmp2 = load_reg(s, rs);
10463 tcg_gen_add_i32(tmp, tmp, tmp2);
10464 tcg_temp_free_i32(tmp2);
10466 break;
10468 store_reg(s, rd, tmp);
10469 break;
10470 case 6: case 7: /* 64-bit multiply, Divide. */
10471 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10472 tmp = load_reg(s, rn);
10473 tmp2 = load_reg(s, rm);
10474 if ((op & 0x50) == 0x10) {
10475 /* sdiv, udiv */
10476 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10477 goto illegal_op;
10479 if (op & 0x20)
10480 gen_helper_udiv(tmp, tmp, tmp2);
10481 else
10482 gen_helper_sdiv(tmp, tmp, tmp2);
10483 tcg_temp_free_i32(tmp2);
10484 store_reg(s, rd, tmp);
10485 } else if ((op & 0xe) == 0xc) {
10486 /* Dual multiply accumulate long. */
10487 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10488 tcg_temp_free_i32(tmp);
10489 tcg_temp_free_i32(tmp2);
10490 goto illegal_op;
10492 if (op & 1)
10493 gen_swap_half(tmp2);
10494 gen_smul_dual(tmp, tmp2);
10495 if (op & 0x10) {
10496 tcg_gen_sub_i32(tmp, tmp, tmp2);
10497 } else {
10498 tcg_gen_add_i32(tmp, tmp, tmp2);
10500 tcg_temp_free_i32(tmp2);
10501 /* BUGFIX */
10502 tmp64 = tcg_temp_new_i64();
10503 tcg_gen_ext_i32_i64(tmp64, tmp);
10504 tcg_temp_free_i32(tmp);
10505 gen_addq(s, tmp64, rs, rd);
10506 gen_storeq_reg(s, rs, rd, tmp64);
10507 tcg_temp_free_i64(tmp64);
10508 } else {
10509 if (op & 0x20) {
10510 /* Unsigned 64-bit multiply */
10511 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10512 } else {
10513 if (op & 8) {
10514 /* smlalxy */
10515 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10516 tcg_temp_free_i32(tmp2);
10517 tcg_temp_free_i32(tmp);
10518 goto illegal_op;
10520 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10521 tcg_temp_free_i32(tmp2);
10522 tmp64 = tcg_temp_new_i64();
10523 tcg_gen_ext_i32_i64(tmp64, tmp);
10524 tcg_temp_free_i32(tmp);
10525 } else {
10526 /* Signed 64-bit multiply */
10527 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10530 if (op & 4) {
10531 /* umaal */
10532 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10533 tcg_temp_free_i64(tmp64);
10534 goto illegal_op;
10536 gen_addq_lo(s, tmp64, rs);
10537 gen_addq_lo(s, tmp64, rd);
10538 } else if (op & 0x40) {
10539 /* 64-bit accumulate. */
10540 gen_addq(s, tmp64, rs, rd);
10542 gen_storeq_reg(s, rs, rd, tmp64);
10543 tcg_temp_free_i64(tmp64);
10545 break;
10547 break;
10548 case 6: case 7: case 14: case 15:
10549 /* Coprocessor. */
10550 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10551 /* We don't currently implement M profile FP support,
10552 * so this entire space should give a NOCP fault.
10554 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10555 default_exception_el(s));
10556 break;
10558 if (((insn >> 24) & 3) == 3) {
10559 /* Translate into the equivalent ARM encoding. */
10560 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10561 if (disas_neon_data_insn(s, insn)) {
10562 goto illegal_op;
10564 } else if (((insn >> 8) & 0xe) == 10) {
10565 if (disas_vfp_insn(s, insn)) {
10566 goto illegal_op;
10568 } else {
10569 if (insn & (1 << 28))
10570 goto illegal_op;
10571 if (disas_coproc_insn(s, insn)) {
10572 goto illegal_op;
10575 break;
10576 case 8: case 9: case 10: case 11:
10577 if (insn & (1 << 15)) {
10578 /* Branches, misc control. */
10579 if (insn & 0x5000) {
10580 /* Unconditional branch. */
10581 /* signextend(hw1[10:0]) -> offset[:12]. */
10582 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10583 /* hw1[10:0] -> offset[11:1]. */
10584 offset |= (insn & 0x7ff) << 1;
10585 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10586 offset[24:22] already have the same value because of the
10587 sign extension above. */
10588 offset ^= ((~insn) & (1 << 13)) << 10;
10589 offset ^= ((~insn) & (1 << 11)) << 11;
10591 if (insn & (1 << 14)) {
10592 /* Branch and link. */
10593 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10596 offset += s->pc;
10597 if (insn & (1 << 12)) {
10598 /* b/bl */
10599 gen_jmp(s, offset);
10600 } else {
10601 /* blx */
10602 offset &= ~(uint32_t)2;
10603 /* thumb2 bx, no need to check */
10604 gen_bx_im(s, offset);
10606 } else if (((insn >> 23) & 7) == 7) {
10607 /* Misc control */
10608 if (insn & (1 << 13))
10609 goto illegal_op;
10611 if (insn & (1 << 26)) {
10612 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10613 goto illegal_op;
10615 if (!(insn & (1 << 20))) {
10616 /* Hypervisor call (v7) */
10617 int imm16 = extract32(insn, 16, 4) << 12
10618 | extract32(insn, 0, 12);
10619 ARCH(7);
10620 if (IS_USER(s)) {
10621 goto illegal_op;
10623 gen_hvc(s, imm16);
10624 } else {
10625 /* Secure monitor call (v6+) */
10626 ARCH(6K);
10627 if (IS_USER(s)) {
10628 goto illegal_op;
10630 gen_smc(s);
10632 } else {
10633 op = (insn >> 20) & 7;
10634 switch (op) {
10635 case 0: /* msr cpsr. */
10636 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10637 tmp = load_reg(s, rn);
10638 /* the constant is the mask and SYSm fields */
10639 addr = tcg_const_i32(insn & 0xfff);
10640 gen_helper_v7m_msr(cpu_env, addr, tmp);
10641 tcg_temp_free_i32(addr);
10642 tcg_temp_free_i32(tmp);
10643 gen_lookup_tb(s);
10644 break;
10646 /* fall through */
10647 case 1: /* msr spsr. */
10648 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10649 goto illegal_op;
10652 if (extract32(insn, 5, 1)) {
10653 /* MSR (banked) */
10654 int sysm = extract32(insn, 8, 4) |
10655 (extract32(insn, 4, 1) << 4);
10656 int r = op & 1;
10658 gen_msr_banked(s, r, sysm, rm);
10659 break;
10662 /* MSR (for PSRs) */
10663 tmp = load_reg(s, rn);
10664 if (gen_set_psr(s,
10665 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10666 op == 1, tmp))
10667 goto illegal_op;
10668 break;
10669 case 2: /* cps, nop-hint. */
10670 if (((insn >> 8) & 7) == 0) {
10671 gen_nop_hint(s, insn & 0xff);
10673 /* Implemented as NOP in user mode. */
10674 if (IS_USER(s))
10675 break;
10676 offset = 0;
10677 imm = 0;
10678 if (insn & (1 << 10)) {
10679 if (insn & (1 << 7))
10680 offset |= CPSR_A;
10681 if (insn & (1 << 6))
10682 offset |= CPSR_I;
10683 if (insn & (1 << 5))
10684 offset |= CPSR_F;
10685 if (insn & (1 << 9))
10686 imm = CPSR_A | CPSR_I | CPSR_F;
10688 if (insn & (1 << 8)) {
10689 offset |= 0x1f;
10690 imm |= (insn & 0x1f);
10692 if (offset) {
10693 gen_set_psr_im(s, offset, 0, imm);
10695 break;
10696 case 3: /* Special control operations. */
10697 ARCH(7);
10698 op = (insn >> 4) & 0xf;
10699 switch (op) {
10700 case 2: /* clrex */
10701 gen_clrex(s);
10702 break;
10703 case 4: /* dsb */
10704 case 5: /* dmb */
10705 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10706 break;
10707 case 6: /* isb */
10708 /* We need to break the TB after this insn
10709 * to execute self-modifying code correctly
10710 * and also to take any pending interrupts
10711 * immediately.
10713 gen_goto_tb(s, 0, s->pc & ~1);
10714 break;
10715 default:
10716 goto illegal_op;
10718 break;
10719 case 4: /* bxj */
10720 /* Trivial implementation equivalent to bx.
10721 * This instruction doesn't exist at all for M-profile.
10723 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10724 goto illegal_op;
10726 tmp = load_reg(s, rn);
10727 gen_bx(s, tmp);
10728 break;
10729 case 5: /* Exception return. */
10730 if (IS_USER(s)) {
10731 goto illegal_op;
10733 if (rn != 14 || rd != 15) {
10734 goto illegal_op;
10736 tmp = load_reg(s, rn);
10737 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10738 gen_exception_return(s, tmp);
10739 break;
10740 case 6: /* MRS */
10741 if (extract32(insn, 5, 1) &&
10742 !arm_dc_feature(s, ARM_FEATURE_M)) {
10743 /* MRS (banked) */
10744 int sysm = extract32(insn, 16, 4) |
10745 (extract32(insn, 4, 1) << 4);
10747 gen_mrs_banked(s, 0, sysm, rd);
10748 break;
10751 if (extract32(insn, 16, 4) != 0xf) {
10752 goto illegal_op;
10754 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10755 extract32(insn, 0, 8) != 0) {
10756 goto illegal_op;
10759 /* mrs cpsr */
10760 tmp = tcg_temp_new_i32();
10761 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10762 addr = tcg_const_i32(insn & 0xff);
10763 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10764 tcg_temp_free_i32(addr);
10765 } else {
10766 gen_helper_cpsr_read(tmp, cpu_env);
10768 store_reg(s, rd, tmp);
10769 break;
10770 case 7: /* MRS */
10771 if (extract32(insn, 5, 1) &&
10772 !arm_dc_feature(s, ARM_FEATURE_M)) {
10773 /* MRS (banked) */
10774 int sysm = extract32(insn, 16, 4) |
10775 (extract32(insn, 4, 1) << 4);
10777 gen_mrs_banked(s, 1, sysm, rd);
10778 break;
10781 /* mrs spsr. */
10782 /* Not accessible in user mode. */
10783 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10784 goto illegal_op;
10787 if (extract32(insn, 16, 4) != 0xf ||
10788 extract32(insn, 0, 8) != 0) {
10789 goto illegal_op;
10792 tmp = load_cpu_field(spsr);
10793 store_reg(s, rd, tmp);
10794 break;
10797 } else {
10798 /* Conditional branch. */
10799 op = (insn >> 22) & 0xf;
10800 /* Generate a conditional jump to next instruction. */
10801 s->condlabel = gen_new_label();
10802 arm_gen_test_cc(op ^ 1, s->condlabel);
10803 s->condjmp = 1;
10805 /* offset[11:1] = insn[10:0] */
10806 offset = (insn & 0x7ff) << 1;
10807 /* offset[17:12] = insn[21:16]. */
10808 offset |= (insn & 0x003f0000) >> 4;
10809 /* offset[31:20] = insn[26]. */
10810 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10811 /* offset[18] = insn[13]. */
10812 offset |= (insn & (1 << 13)) << 5;
10813 /* offset[19] = insn[11]. */
10814 offset |= (insn & (1 << 11)) << 8;
10816 /* jump to the offset */
10817 gen_jmp(s, s->pc + offset);
10819 } else {
10820 /* Data processing immediate. */
10821 if (insn & (1 << 25)) {
10822 if (insn & (1 << 24)) {
10823 if (insn & (1 << 20))
10824 goto illegal_op;
10825 /* Bitfield/Saturate. */
10826 op = (insn >> 21) & 7;
10827 imm = insn & 0x1f;
10828 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10829 if (rn == 15) {
10830 tmp = tcg_temp_new_i32();
10831 tcg_gen_movi_i32(tmp, 0);
10832 } else {
10833 tmp = load_reg(s, rn);
10835 switch (op) {
10836 case 2: /* Signed bitfield extract. */
10837 imm++;
10838 if (shift + imm > 32)
10839 goto illegal_op;
10840 if (imm < 32) {
10841 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10843 break;
10844 case 6: /* Unsigned bitfield extract. */
10845 imm++;
10846 if (shift + imm > 32)
10847 goto illegal_op;
10848 if (imm < 32) {
10849 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10851 break;
10852 case 3: /* Bitfield insert/clear. */
10853 if (imm < shift)
10854 goto illegal_op;
10855 imm = imm + 1 - shift;
10856 if (imm != 32) {
10857 tmp2 = load_reg(s, rd);
10858 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10859 tcg_temp_free_i32(tmp2);
10861 break;
10862 case 7:
10863 goto illegal_op;
10864 default: /* Saturate. */
10865 if (shift) {
10866 if (op & 1)
10867 tcg_gen_sari_i32(tmp, tmp, shift);
10868 else
10869 tcg_gen_shli_i32(tmp, tmp, shift);
10871 tmp2 = tcg_const_i32(imm);
10872 if (op & 4) {
10873 /* Unsigned. */
10874 if ((op & 1) && shift == 0) {
10875 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10876 tcg_temp_free_i32(tmp);
10877 tcg_temp_free_i32(tmp2);
10878 goto illegal_op;
10880 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10881 } else {
10882 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10884 } else {
10885 /* Signed. */
10886 if ((op & 1) && shift == 0) {
10887 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10888 tcg_temp_free_i32(tmp);
10889 tcg_temp_free_i32(tmp2);
10890 goto illegal_op;
10892 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10893 } else {
10894 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10897 tcg_temp_free_i32(tmp2);
10898 break;
10900 store_reg(s, rd, tmp);
10901 } else {
10902 imm = ((insn & 0x04000000) >> 15)
10903 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10904 if (insn & (1 << 22)) {
10905 /* 16-bit immediate. */
10906 imm |= (insn >> 4) & 0xf000;
10907 if (insn & (1 << 23)) {
10908 /* movt */
10909 tmp = load_reg(s, rd);
10910 tcg_gen_ext16u_i32(tmp, tmp);
10911 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10912 } else {
10913 /* movw */
10914 tmp = tcg_temp_new_i32();
10915 tcg_gen_movi_i32(tmp, imm);
10917 } else {
10918 /* Add/sub 12-bit immediate. */
10919 if (rn == 15) {
10920 offset = s->pc & ~(uint32_t)3;
10921 if (insn & (1 << 23))
10922 offset -= imm;
10923 else
10924 offset += imm;
10925 tmp = tcg_temp_new_i32();
10926 tcg_gen_movi_i32(tmp, offset);
10927 } else {
10928 tmp = load_reg(s, rn);
10929 if (insn & (1 << 23))
10930 tcg_gen_subi_i32(tmp, tmp, imm);
10931 else
10932 tcg_gen_addi_i32(tmp, tmp, imm);
10935 store_reg(s, rd, tmp);
10937 } else {
10938 int shifter_out = 0;
10939 /* modified 12-bit immediate. */
10940 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10941 imm = (insn & 0xff);
10942 switch (shift) {
10943 case 0: /* XY */
10944 /* Nothing to do. */
10945 break;
10946 case 1: /* 00XY00XY */
10947 imm |= imm << 16;
10948 break;
10949 case 2: /* XY00XY00 */
10950 imm |= imm << 16;
10951 imm <<= 8;
10952 break;
10953 case 3: /* XYXYXYXY */
10954 imm |= imm << 16;
10955 imm |= imm << 8;
10956 break;
10957 default: /* Rotated constant. */
10958 shift = (shift << 1) | (imm >> 7);
10959 imm |= 0x80;
10960 imm = imm << (32 - shift);
10961 shifter_out = 1;
10962 break;
10964 tmp2 = tcg_temp_new_i32();
10965 tcg_gen_movi_i32(tmp2, imm);
10966 rn = (insn >> 16) & 0xf;
10967 if (rn == 15) {
10968 tmp = tcg_temp_new_i32();
10969 tcg_gen_movi_i32(tmp, 0);
10970 } else {
10971 tmp = load_reg(s, rn);
10973 op = (insn >> 21) & 0xf;
10974 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10975 shifter_out, tmp, tmp2))
10976 goto illegal_op;
10977 tcg_temp_free_i32(tmp2);
10978 rd = (insn >> 8) & 0xf;
10979 if (rd != 15) {
10980 store_reg(s, rd, tmp);
10981 } else {
10982 tcg_temp_free_i32(tmp);
10986 break;
10987 case 12: /* Load/store single data item. */
10989 int postinc = 0;
10990 int writeback = 0;
10991 int memidx;
10992 ISSInfo issinfo;
10994 if ((insn & 0x01100000) == 0x01000000) {
10995 if (disas_neon_ls_insn(s, insn)) {
10996 goto illegal_op;
10998 break;
11000 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11001 if (rs == 15) {
11002 if (!(insn & (1 << 20))) {
11003 goto illegal_op;
11005 if (op != 2) {
11006 /* Byte or halfword load space with dest == r15 : memory hints.
11007 * Catch them early so we don't emit pointless addressing code.
11008 * This space is a mix of:
11009 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11010 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11011 * cores)
11012 * unallocated hints, which must be treated as NOPs
11013 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11014 * which is easiest for the decoding logic
11015 * Some space which must UNDEF
11017 int op1 = (insn >> 23) & 3;
11018 int op2 = (insn >> 6) & 0x3f;
11019 if (op & 2) {
11020 goto illegal_op;
11022 if (rn == 15) {
11023 /* UNPREDICTABLE, unallocated hint or
11024 * PLD/PLDW/PLI (literal)
11026 return;
11028 if (op1 & 1) {
11029 return; /* PLD/PLDW/PLI or unallocated hint */
11031 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11032 return; /* PLD/PLDW/PLI or unallocated hint */
11034 /* UNDEF space, or an UNPREDICTABLE */
11035 goto illegal_op;
11038 memidx = get_mem_index(s);
11039 if (rn == 15) {
11040 addr = tcg_temp_new_i32();
11041 /* PC relative. */
11042 /* s->pc has already been incremented by 4. */
11043 imm = s->pc & 0xfffffffc;
11044 if (insn & (1 << 23))
11045 imm += insn & 0xfff;
11046 else
11047 imm -= insn & 0xfff;
11048 tcg_gen_movi_i32(addr, imm);
11049 } else {
11050 addr = load_reg(s, rn);
11051 if (insn & (1 << 23)) {
11052 /* Positive offset. */
11053 imm = insn & 0xfff;
11054 tcg_gen_addi_i32(addr, addr, imm);
11055 } else {
11056 imm = insn & 0xff;
11057 switch ((insn >> 8) & 0xf) {
11058 case 0x0: /* Shifted Register. */
11059 shift = (insn >> 4) & 0xf;
11060 if (shift > 3) {
11061 tcg_temp_free_i32(addr);
11062 goto illegal_op;
11064 tmp = load_reg(s, rm);
11065 if (shift)
11066 tcg_gen_shli_i32(tmp, tmp, shift);
11067 tcg_gen_add_i32(addr, addr, tmp);
11068 tcg_temp_free_i32(tmp);
11069 break;
11070 case 0xc: /* Negative offset. */
11071 tcg_gen_addi_i32(addr, addr, -imm);
11072 break;
11073 case 0xe: /* User privilege. */
11074 tcg_gen_addi_i32(addr, addr, imm);
11075 memidx = get_a32_user_mem_index(s);
11076 break;
11077 case 0x9: /* Post-decrement. */
11078 imm = -imm;
11079 /* Fall through. */
11080 case 0xb: /* Post-increment. */
11081 postinc = 1;
11082 writeback = 1;
11083 break;
11084 case 0xd: /* Pre-decrement. */
11085 imm = -imm;
11086 /* Fall through. */
11087 case 0xf: /* Pre-increment. */
11088 tcg_gen_addi_i32(addr, addr, imm);
11089 writeback = 1;
11090 break;
11091 default:
11092 tcg_temp_free_i32(addr);
11093 goto illegal_op;
11098 issinfo = writeback ? ISSInvalid : rs;
11100 if (insn & (1 << 20)) {
11101 /* Load. */
11102 tmp = tcg_temp_new_i32();
11103 switch (op) {
11104 case 0:
11105 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11106 break;
11107 case 4:
11108 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11109 break;
11110 case 1:
11111 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11112 break;
11113 case 5:
11114 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11115 break;
11116 case 2:
11117 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11118 break;
11119 default:
11120 tcg_temp_free_i32(tmp);
11121 tcg_temp_free_i32(addr);
11122 goto illegal_op;
11124 if (rs == 15) {
11125 gen_bx_excret(s, tmp);
11126 } else {
11127 store_reg(s, rs, tmp);
11129 } else {
11130 /* Store. */
11131 tmp = load_reg(s, rs);
11132 switch (op) {
11133 case 0:
11134 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11135 break;
11136 case 1:
11137 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11138 break;
11139 case 2:
11140 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11141 break;
11142 default:
11143 tcg_temp_free_i32(tmp);
11144 tcg_temp_free_i32(addr);
11145 goto illegal_op;
11147 tcg_temp_free_i32(tmp);
11149 if (postinc)
11150 tcg_gen_addi_i32(addr, addr, imm);
11151 if (writeback) {
11152 store_reg(s, rn, addr);
11153 } else {
11154 tcg_temp_free_i32(addr);
11157 break;
11158 default:
11159 goto illegal_op;
11161 return;
11162 illegal_op:
11163 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11164 default_exception_el(s));
11167 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11169 uint32_t val, op, rm, rn, rd, shift, cond;
11170 int32_t offset;
11171 int i;
11172 TCGv_i32 tmp;
11173 TCGv_i32 tmp2;
11174 TCGv_i32 addr;
11176 switch (insn >> 12) {
11177 case 0: case 1:
11179 rd = insn & 7;
11180 op = (insn >> 11) & 3;
11181 if (op == 3) {
11182 /* add/subtract */
11183 rn = (insn >> 3) & 7;
11184 tmp = load_reg(s, rn);
11185 if (insn & (1 << 10)) {
11186 /* immediate */
11187 tmp2 = tcg_temp_new_i32();
11188 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11189 } else {
11190 /* reg */
11191 rm = (insn >> 6) & 7;
11192 tmp2 = load_reg(s, rm);
11194 if (insn & (1 << 9)) {
11195 if (s->condexec_mask)
11196 tcg_gen_sub_i32(tmp, tmp, tmp2);
11197 else
11198 gen_sub_CC(tmp, tmp, tmp2);
11199 } else {
11200 if (s->condexec_mask)
11201 tcg_gen_add_i32(tmp, tmp, tmp2);
11202 else
11203 gen_add_CC(tmp, tmp, tmp2);
11205 tcg_temp_free_i32(tmp2);
11206 store_reg(s, rd, tmp);
11207 } else {
11208 /* shift immediate */
11209 rm = (insn >> 3) & 7;
11210 shift = (insn >> 6) & 0x1f;
11211 tmp = load_reg(s, rm);
11212 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11213 if (!s->condexec_mask)
11214 gen_logic_CC(tmp);
11215 store_reg(s, rd, tmp);
11217 break;
11218 case 2: case 3:
11219 /* arithmetic large immediate */
11220 op = (insn >> 11) & 3;
11221 rd = (insn >> 8) & 0x7;
11222 if (op == 0) { /* mov */
11223 tmp = tcg_temp_new_i32();
11224 tcg_gen_movi_i32(tmp, insn & 0xff);
11225 if (!s->condexec_mask)
11226 gen_logic_CC(tmp);
11227 store_reg(s, rd, tmp);
11228 } else {
11229 tmp = load_reg(s, rd);
11230 tmp2 = tcg_temp_new_i32();
11231 tcg_gen_movi_i32(tmp2, insn & 0xff);
11232 switch (op) {
11233 case 1: /* cmp */
11234 gen_sub_CC(tmp, tmp, tmp2);
11235 tcg_temp_free_i32(tmp);
11236 tcg_temp_free_i32(tmp2);
11237 break;
11238 case 2: /* add */
11239 if (s->condexec_mask)
11240 tcg_gen_add_i32(tmp, tmp, tmp2);
11241 else
11242 gen_add_CC(tmp, tmp, tmp2);
11243 tcg_temp_free_i32(tmp2);
11244 store_reg(s, rd, tmp);
11245 break;
11246 case 3: /* sub */
11247 if (s->condexec_mask)
11248 tcg_gen_sub_i32(tmp, tmp, tmp2);
11249 else
11250 gen_sub_CC(tmp, tmp, tmp2);
11251 tcg_temp_free_i32(tmp2);
11252 store_reg(s, rd, tmp);
11253 break;
11256 break;
11257 case 4:
11258 if (insn & (1 << 11)) {
11259 rd = (insn >> 8) & 7;
11260 /* load pc-relative. Bit 1 of PC is ignored. */
11261 val = s->pc + 2 + ((insn & 0xff) * 4);
11262 val &= ~(uint32_t)2;
11263 addr = tcg_temp_new_i32();
11264 tcg_gen_movi_i32(addr, val);
11265 tmp = tcg_temp_new_i32();
11266 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11267 rd | ISSIs16Bit);
11268 tcg_temp_free_i32(addr);
11269 store_reg(s, rd, tmp);
11270 break;
11272 if (insn & (1 << 10)) {
11273 /* 0b0100_01xx_xxxx_xxxx
11274 * - data processing extended, branch and exchange
11276 rd = (insn & 7) | ((insn >> 4) & 8);
11277 rm = (insn >> 3) & 0xf;
11278 op = (insn >> 8) & 3;
11279 switch (op) {
11280 case 0: /* add */
11281 tmp = load_reg(s, rd);
11282 tmp2 = load_reg(s, rm);
11283 tcg_gen_add_i32(tmp, tmp, tmp2);
11284 tcg_temp_free_i32(tmp2);
11285 store_reg(s, rd, tmp);
11286 break;
11287 case 1: /* cmp */
11288 tmp = load_reg(s, rd);
11289 tmp2 = load_reg(s, rm);
11290 gen_sub_CC(tmp, tmp, tmp2);
11291 tcg_temp_free_i32(tmp2);
11292 tcg_temp_free_i32(tmp);
11293 break;
11294 case 2: /* mov/cpy */
11295 tmp = load_reg(s, rm);
11296 store_reg(s, rd, tmp);
11297 break;
11298 case 3:
11300 /* 0b0100_0111_xxxx_xxxx
11301 * - branch [and link] exchange thumb register
11303 bool link = insn & (1 << 7);
11305 if (insn & 3) {
11306 goto undef;
11308 if (link) {
11309 ARCH(5);
11311 if ((insn & 4)) {
11312 /* BXNS/BLXNS: only exists for v8M with the
11313 * security extensions, and always UNDEF if NonSecure.
11314 * We don't implement these in the user-only mode
11315 * either (in theory you can use them from Secure User
11316 * mode but they are too tied in to system emulation.)
11318 if (!s->v8m_secure || IS_USER_ONLY) {
11319 goto undef;
11321 if (link) {
11322 gen_blxns(s, rm);
11323 } else {
11324 gen_bxns(s, rm);
11326 break;
11328 /* BLX/BX */
11329 tmp = load_reg(s, rm);
11330 if (link) {
11331 val = (uint32_t)s->pc | 1;
11332 tmp2 = tcg_temp_new_i32();
11333 tcg_gen_movi_i32(tmp2, val);
11334 store_reg(s, 14, tmp2);
11335 gen_bx(s, tmp);
11336 } else {
11337 /* Only BX works as exception-return, not BLX */
11338 gen_bx_excret(s, tmp);
11340 break;
11343 break;
11346 /* data processing register */
11347 rd = insn & 7;
11348 rm = (insn >> 3) & 7;
11349 op = (insn >> 6) & 0xf;
11350 if (op == 2 || op == 3 || op == 4 || op == 7) {
11351 /* the shift/rotate ops want the operands backwards */
11352 val = rm;
11353 rm = rd;
11354 rd = val;
11355 val = 1;
11356 } else {
11357 val = 0;
11360 if (op == 9) { /* neg */
11361 tmp = tcg_temp_new_i32();
11362 tcg_gen_movi_i32(tmp, 0);
11363 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11364 tmp = load_reg(s, rd);
11365 } else {
11366 tmp = NULL;
11369 tmp2 = load_reg(s, rm);
11370 switch (op) {
11371 case 0x0: /* and */
11372 tcg_gen_and_i32(tmp, tmp, tmp2);
11373 if (!s->condexec_mask)
11374 gen_logic_CC(tmp);
11375 break;
11376 case 0x1: /* eor */
11377 tcg_gen_xor_i32(tmp, tmp, tmp2);
11378 if (!s->condexec_mask)
11379 gen_logic_CC(tmp);
11380 break;
11381 case 0x2: /* lsl */
11382 if (s->condexec_mask) {
11383 gen_shl(tmp2, tmp2, tmp);
11384 } else {
11385 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11386 gen_logic_CC(tmp2);
11388 break;
11389 case 0x3: /* lsr */
11390 if (s->condexec_mask) {
11391 gen_shr(tmp2, tmp2, tmp);
11392 } else {
11393 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11394 gen_logic_CC(tmp2);
11396 break;
11397 case 0x4: /* asr */
11398 if (s->condexec_mask) {
11399 gen_sar(tmp2, tmp2, tmp);
11400 } else {
11401 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11402 gen_logic_CC(tmp2);
11404 break;
11405 case 0x5: /* adc */
11406 if (s->condexec_mask) {
11407 gen_adc(tmp, tmp2);
11408 } else {
11409 gen_adc_CC(tmp, tmp, tmp2);
11411 break;
11412 case 0x6: /* sbc */
11413 if (s->condexec_mask) {
11414 gen_sub_carry(tmp, tmp, tmp2);
11415 } else {
11416 gen_sbc_CC(tmp, tmp, tmp2);
11418 break;
11419 case 0x7: /* ror */
11420 if (s->condexec_mask) {
11421 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11422 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11423 } else {
11424 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11425 gen_logic_CC(tmp2);
11427 break;
11428 case 0x8: /* tst */
11429 tcg_gen_and_i32(tmp, tmp, tmp2);
11430 gen_logic_CC(tmp);
11431 rd = 16;
11432 break;
11433 case 0x9: /* neg */
11434 if (s->condexec_mask)
11435 tcg_gen_neg_i32(tmp, tmp2);
11436 else
11437 gen_sub_CC(tmp, tmp, tmp2);
11438 break;
11439 case 0xa: /* cmp */
11440 gen_sub_CC(tmp, tmp, tmp2);
11441 rd = 16;
11442 break;
11443 case 0xb: /* cmn */
11444 gen_add_CC(tmp, tmp, tmp2);
11445 rd = 16;
11446 break;
11447 case 0xc: /* orr */
11448 tcg_gen_or_i32(tmp, tmp, tmp2);
11449 if (!s->condexec_mask)
11450 gen_logic_CC(tmp);
11451 break;
11452 case 0xd: /* mul */
11453 tcg_gen_mul_i32(tmp, tmp, tmp2);
11454 if (!s->condexec_mask)
11455 gen_logic_CC(tmp);
11456 break;
11457 case 0xe: /* bic */
11458 tcg_gen_andc_i32(tmp, tmp, tmp2);
11459 if (!s->condexec_mask)
11460 gen_logic_CC(tmp);
11461 break;
11462 case 0xf: /* mvn */
11463 tcg_gen_not_i32(tmp2, tmp2);
11464 if (!s->condexec_mask)
11465 gen_logic_CC(tmp2);
11466 val = 1;
11467 rm = rd;
11468 break;
11470 if (rd != 16) {
11471 if (val) {
11472 store_reg(s, rm, tmp2);
11473 if (op != 0xf)
11474 tcg_temp_free_i32(tmp);
11475 } else {
11476 store_reg(s, rd, tmp);
11477 tcg_temp_free_i32(tmp2);
11479 } else {
11480 tcg_temp_free_i32(tmp);
11481 tcg_temp_free_i32(tmp2);
11483 break;
11485 case 5:
11486 /* load/store register offset. */
11487 rd = insn & 7;
11488 rn = (insn >> 3) & 7;
11489 rm = (insn >> 6) & 7;
11490 op = (insn >> 9) & 7;
11491 addr = load_reg(s, rn);
11492 tmp = load_reg(s, rm);
11493 tcg_gen_add_i32(addr, addr, tmp);
11494 tcg_temp_free_i32(tmp);
11496 if (op < 3) { /* store */
11497 tmp = load_reg(s, rd);
11498 } else {
11499 tmp = tcg_temp_new_i32();
11502 switch (op) {
11503 case 0: /* str */
11504 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11505 break;
11506 case 1: /* strh */
11507 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11508 break;
11509 case 2: /* strb */
11510 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11511 break;
11512 case 3: /* ldrsb */
11513 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11514 break;
11515 case 4: /* ldr */
11516 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11517 break;
11518 case 5: /* ldrh */
11519 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11520 break;
11521 case 6: /* ldrb */
11522 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11523 break;
11524 case 7: /* ldrsh */
11525 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11526 break;
11528 if (op >= 3) { /* load */
11529 store_reg(s, rd, tmp);
11530 } else {
11531 tcg_temp_free_i32(tmp);
11533 tcg_temp_free_i32(addr);
11534 break;
11536 case 6:
11537 /* load/store word immediate offset */
11538 rd = insn & 7;
11539 rn = (insn >> 3) & 7;
11540 addr = load_reg(s, rn);
11541 val = (insn >> 4) & 0x7c;
11542 tcg_gen_addi_i32(addr, addr, val);
11544 if (insn & (1 << 11)) {
11545 /* load */
11546 tmp = tcg_temp_new_i32();
11547 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11548 store_reg(s, rd, tmp);
11549 } else {
11550 /* store */
11551 tmp = load_reg(s, rd);
11552 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11553 tcg_temp_free_i32(tmp);
11555 tcg_temp_free_i32(addr);
11556 break;
11558 case 7:
11559 /* load/store byte immediate offset */
11560 rd = insn & 7;
11561 rn = (insn >> 3) & 7;
11562 addr = load_reg(s, rn);
11563 val = (insn >> 6) & 0x1f;
11564 tcg_gen_addi_i32(addr, addr, val);
11566 if (insn & (1 << 11)) {
11567 /* load */
11568 tmp = tcg_temp_new_i32();
11569 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11570 store_reg(s, rd, tmp);
11571 } else {
11572 /* store */
11573 tmp = load_reg(s, rd);
11574 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11575 tcg_temp_free_i32(tmp);
11577 tcg_temp_free_i32(addr);
11578 break;
11580 case 8:
11581 /* load/store halfword immediate offset */
11582 rd = insn & 7;
11583 rn = (insn >> 3) & 7;
11584 addr = load_reg(s, rn);
11585 val = (insn >> 5) & 0x3e;
11586 tcg_gen_addi_i32(addr, addr, val);
11588 if (insn & (1 << 11)) {
11589 /* load */
11590 tmp = tcg_temp_new_i32();
11591 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11592 store_reg(s, rd, tmp);
11593 } else {
11594 /* store */
11595 tmp = load_reg(s, rd);
11596 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11597 tcg_temp_free_i32(tmp);
11599 tcg_temp_free_i32(addr);
11600 break;
11602 case 9:
11603 /* load/store from stack */
11604 rd = (insn >> 8) & 7;
11605 addr = load_reg(s, 13);
11606 val = (insn & 0xff) * 4;
11607 tcg_gen_addi_i32(addr, addr, val);
11609 if (insn & (1 << 11)) {
11610 /* load */
11611 tmp = tcg_temp_new_i32();
11612 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11613 store_reg(s, rd, tmp);
11614 } else {
11615 /* store */
11616 tmp = load_reg(s, rd);
11617 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11618 tcg_temp_free_i32(tmp);
11620 tcg_temp_free_i32(addr);
11621 break;
11623 case 10:
11624 /* add to high reg */
11625 rd = (insn >> 8) & 7;
11626 if (insn & (1 << 11)) {
11627 /* SP */
11628 tmp = load_reg(s, 13);
11629 } else {
11630 /* PC. bit 1 is ignored. */
11631 tmp = tcg_temp_new_i32();
11632 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11634 val = (insn & 0xff) * 4;
11635 tcg_gen_addi_i32(tmp, tmp, val);
11636 store_reg(s, rd, tmp);
11637 break;
11639 case 11:
11640 /* misc */
11641 op = (insn >> 8) & 0xf;
11642 switch (op) {
11643 case 0:
11644 /* adjust stack pointer */
11645 tmp = load_reg(s, 13);
11646 val = (insn & 0x7f) * 4;
11647 if (insn & (1 << 7))
11648 val = -(int32_t)val;
11649 tcg_gen_addi_i32(tmp, tmp, val);
11650 store_reg(s, 13, tmp);
11651 break;
11653 case 2: /* sign/zero extend. */
11654 ARCH(6);
11655 rd = insn & 7;
11656 rm = (insn >> 3) & 7;
11657 tmp = load_reg(s, rm);
11658 switch ((insn >> 6) & 3) {
11659 case 0: gen_sxth(tmp); break;
11660 case 1: gen_sxtb(tmp); break;
11661 case 2: gen_uxth(tmp); break;
11662 case 3: gen_uxtb(tmp); break;
11664 store_reg(s, rd, tmp);
11665 break;
11666 case 4: case 5: case 0xc: case 0xd:
11667 /* push/pop */
11668 addr = load_reg(s, 13);
11669 if (insn & (1 << 8))
11670 offset = 4;
11671 else
11672 offset = 0;
11673 for (i = 0; i < 8; i++) {
11674 if (insn & (1 << i))
11675 offset += 4;
11677 if ((insn & (1 << 11)) == 0) {
11678 tcg_gen_addi_i32(addr, addr, -offset);
11680 for (i = 0; i < 8; i++) {
11681 if (insn & (1 << i)) {
11682 if (insn & (1 << 11)) {
11683 /* pop */
11684 tmp = tcg_temp_new_i32();
11685 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11686 store_reg(s, i, tmp);
11687 } else {
11688 /* push */
11689 tmp = load_reg(s, i);
11690 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11691 tcg_temp_free_i32(tmp);
11693 /* advance to the next address. */
11694 tcg_gen_addi_i32(addr, addr, 4);
11697 tmp = NULL;
11698 if (insn & (1 << 8)) {
11699 if (insn & (1 << 11)) {
11700 /* pop pc */
11701 tmp = tcg_temp_new_i32();
11702 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11703 /* don't set the pc until the rest of the instruction
11704 has completed */
11705 } else {
11706 /* push lr */
11707 tmp = load_reg(s, 14);
11708 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11709 tcg_temp_free_i32(tmp);
11711 tcg_gen_addi_i32(addr, addr, 4);
11713 if ((insn & (1 << 11)) == 0) {
11714 tcg_gen_addi_i32(addr, addr, -offset);
11716 /* write back the new stack pointer */
11717 store_reg(s, 13, addr);
11718 /* set the new PC value */
11719 if ((insn & 0x0900) == 0x0900) {
11720 store_reg_from_load(s, 15, tmp);
11722 break;
11724 case 1: case 3: case 9: case 11: /* czb */
11725 rm = insn & 7;
11726 tmp = load_reg(s, rm);
11727 s->condlabel = gen_new_label();
11728 s->condjmp = 1;
11729 if (insn & (1 << 11))
11730 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11731 else
11732 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11733 tcg_temp_free_i32(tmp);
11734 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11735 val = (uint32_t)s->pc + 2;
11736 val += offset;
11737 gen_jmp(s, val);
11738 break;
11740 case 15: /* IT, nop-hint. */
11741 if ((insn & 0xf) == 0) {
11742 gen_nop_hint(s, (insn >> 4) & 0xf);
11743 break;
11745 /* If Then. */
11746 s->condexec_cond = (insn >> 4) & 0xe;
11747 s->condexec_mask = insn & 0x1f;
11748 /* No actual code generated for this insn, just setup state. */
11749 break;
11751 case 0xe: /* bkpt */
11753 int imm8 = extract32(insn, 0, 8);
11754 ARCH(5);
11755 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11756 default_exception_el(s));
11757 break;
11760 case 0xa: /* rev, and hlt */
11762 int op1 = extract32(insn, 6, 2);
11764 if (op1 == 2) {
11765 /* HLT */
11766 int imm6 = extract32(insn, 0, 6);
11768 gen_hlt(s, imm6);
11769 break;
11772 /* Otherwise this is rev */
11773 ARCH(6);
11774 rn = (insn >> 3) & 0x7;
11775 rd = insn & 0x7;
11776 tmp = load_reg(s, rn);
11777 switch (op1) {
11778 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11779 case 1: gen_rev16(tmp); break;
11780 case 3: gen_revsh(tmp); break;
11781 default:
11782 g_assert_not_reached();
11784 store_reg(s, rd, tmp);
11785 break;
11788 case 6:
11789 switch ((insn >> 5) & 7) {
11790 case 2:
11791 /* setend */
11792 ARCH(6);
11793 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11794 gen_helper_setend(cpu_env);
11795 s->base.is_jmp = DISAS_UPDATE;
11797 break;
11798 case 3:
11799 /* cps */
11800 ARCH(6);
11801 if (IS_USER(s)) {
11802 break;
11804 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11805 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11806 /* FAULTMASK */
11807 if (insn & 1) {
11808 addr = tcg_const_i32(19);
11809 gen_helper_v7m_msr(cpu_env, addr, tmp);
11810 tcg_temp_free_i32(addr);
11812 /* PRIMASK */
11813 if (insn & 2) {
11814 addr = tcg_const_i32(16);
11815 gen_helper_v7m_msr(cpu_env, addr, tmp);
11816 tcg_temp_free_i32(addr);
11818 tcg_temp_free_i32(tmp);
11819 gen_lookup_tb(s);
11820 } else {
11821 if (insn & (1 << 4)) {
11822 shift = CPSR_A | CPSR_I | CPSR_F;
11823 } else {
11824 shift = 0;
11826 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11828 break;
11829 default:
11830 goto undef;
11832 break;
11834 default:
11835 goto undef;
11837 break;
11839 case 12:
11841 /* load/store multiple */
11842 TCGv_i32 loaded_var = NULL;
11843 rn = (insn >> 8) & 0x7;
11844 addr = load_reg(s, rn);
11845 for (i = 0; i < 8; i++) {
11846 if (insn & (1 << i)) {
11847 if (insn & (1 << 11)) {
11848 /* load */
11849 tmp = tcg_temp_new_i32();
11850 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11851 if (i == rn) {
11852 loaded_var = tmp;
11853 } else {
11854 store_reg(s, i, tmp);
11856 } else {
11857 /* store */
11858 tmp = load_reg(s, i);
11859 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11860 tcg_temp_free_i32(tmp);
11862 /* advance to the next address */
11863 tcg_gen_addi_i32(addr, addr, 4);
11866 if ((insn & (1 << rn)) == 0) {
11867 /* base reg not in list: base register writeback */
11868 store_reg(s, rn, addr);
11869 } else {
11870 /* base reg in list: if load, complete it now */
11871 if (insn & (1 << 11)) {
11872 store_reg(s, rn, loaded_var);
11874 tcg_temp_free_i32(addr);
11876 break;
11878 case 13:
11879 /* conditional branch or swi */
11880 cond = (insn >> 8) & 0xf;
11881 if (cond == 0xe)
11882 goto undef;
11884 if (cond == 0xf) {
11885 /* swi */
11886 gen_set_pc_im(s, s->pc);
11887 s->svc_imm = extract32(insn, 0, 8);
11888 s->base.is_jmp = DISAS_SWI;
11889 break;
11891 /* generate a conditional jump to next instruction */
11892 s->condlabel = gen_new_label();
11893 arm_gen_test_cc(cond ^ 1, s->condlabel);
11894 s->condjmp = 1;
11896 /* jump to the offset */
11897 val = (uint32_t)s->pc + 2;
11898 offset = ((int32_t)insn << 24) >> 24;
11899 val += offset << 1;
11900 gen_jmp(s, val);
11901 break;
11903 case 14:
11904 if (insn & (1 << 11)) {
11905 /* thumb_insn_is_16bit() ensures we can't get here for
11906 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11907 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11909 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11910 ARCH(5);
11911 offset = ((insn & 0x7ff) << 1);
11912 tmp = load_reg(s, 14);
11913 tcg_gen_addi_i32(tmp, tmp, offset);
11914 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11916 tmp2 = tcg_temp_new_i32();
11917 tcg_gen_movi_i32(tmp2, s->pc | 1);
11918 store_reg(s, 14, tmp2);
11919 gen_bx(s, tmp);
11920 break;
11922 /* unconditional branch */
11923 val = (uint32_t)s->pc;
11924 offset = ((int32_t)insn << 21) >> 21;
11925 val += (offset << 1) + 2;
11926 gen_jmp(s, val);
11927 break;
11929 case 15:
11930 /* thumb_insn_is_16bit() ensures we can't get here for
11931 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11933 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11935 if (insn & (1 << 11)) {
11936 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11937 offset = ((insn & 0x7ff) << 1) | 1;
11938 tmp = load_reg(s, 14);
11939 tcg_gen_addi_i32(tmp, tmp, offset);
11941 tmp2 = tcg_temp_new_i32();
11942 tcg_gen_movi_i32(tmp2, s->pc | 1);
11943 store_reg(s, 14, tmp2);
11944 gen_bx(s, tmp);
11945 } else {
11946 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11947 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11949 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
11951 break;
11953 return;
11954 illegal_op:
11955 undef:
11956 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11957 default_exception_el(s));
11960 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11962 /* Return true if the insn at dc->pc might cross a page boundary.
11963 * (False positives are OK, false negatives are not.)
11964 * We know this is a Thumb insn, and our caller ensures we are
11965 * only called if dc->pc is less than 4 bytes from the page
11966 * boundary, so we cross the page if the first 16 bits indicate
11967 * that this is a 32 bit insn.
11969 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11971 return !thumb_insn_is_16bit(s, insn);
11974 static int arm_tr_init_disas_context(DisasContextBase *dcbase,
11975 CPUState *cs, int max_insns)
11977 DisasContext *dc = container_of(dcbase, DisasContext, base);
11978 CPUARMState *env = cs->env_ptr;
11979 ARMCPU *cpu = arm_env_get_cpu(env);
11981 dc->pc = dc->base.pc_first;
11982 dc->condjmp = 0;
11984 dc->aarch64 = 0;
11985 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11986 * there is no secure EL1, so we route exceptions to EL3.
11988 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11989 !arm_el_is_aa64(env, 3);
11990 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
11991 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
11992 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
11993 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
11994 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
11995 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
11996 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11997 #if !defined(CONFIG_USER_ONLY)
11998 dc->user = (dc->current_el == 0);
11999 #endif
12000 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12001 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12002 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12003 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12004 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12005 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12006 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12007 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12008 regime_is_secure(env, dc->mmu_idx);
12009 dc->cp_regs = cpu->cp_regs;
12010 dc->features = env->features;
12012 /* Single step state. The code-generation logic here is:
12013 * SS_ACTIVE == 0:
12014 * generate code with no special handling for single-stepping (except
12015 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12016 * this happens anyway because those changes are all system register or
12017 * PSTATE writes).
12018 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12019 * emit code for one insn
12020 * emit code to clear PSTATE.SS
12021 * emit code to generate software step exception for completed step
12022 * end TB (as usual for having generated an exception)
12023 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12024 * emit code to generate a software step exception
12025 * end the TB
12027 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12028 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12029 dc->is_ldex = false;
12030 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12032 dc->next_page_start =
12033 (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
12035 /* If architectural single step active, limit to 1. */
12036 if (is_singlestepping(dc)) {
12037 max_insns = 1;
12040 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12041 to those left on the page. */
12042 if (!dc->thumb) {
12043 int bound = (dc->next_page_start - dc->base.pc_first) / 4;
12044 max_insns = MIN(max_insns, bound);
12047 cpu_F0s = tcg_temp_new_i32();
12048 cpu_F1s = tcg_temp_new_i32();
12049 cpu_F0d = tcg_temp_new_i64();
12050 cpu_F1d = tcg_temp_new_i64();
12051 cpu_V0 = cpu_F0d;
12052 cpu_V1 = cpu_F1d;
12053 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12054 cpu_M0 = tcg_temp_new_i64();
12056 return max_insns;
12059 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12061 DisasContext *dc = container_of(dcbase, DisasContext, base);
12063 /* A note on handling of the condexec (IT) bits:
12065 * We want to avoid the overhead of having to write the updated condexec
12066 * bits back to the CPUARMState for every instruction in an IT block. So:
12067 * (1) if the condexec bits are not already zero then we write
12068 * zero back into the CPUARMState now. This avoids complications trying
12069 * to do it at the end of the block. (For example if we don't do this
12070 * it's hard to identify whether we can safely skip writing condexec
12071 * at the end of the TB, which we definitely want to do for the case
12072 * where a TB doesn't do anything with the IT state at all.)
12073 * (2) if we are going to leave the TB then we call gen_set_condexec()
12074 * which will write the correct value into CPUARMState if zero is wrong.
12075 * This is done both for leaving the TB at the end, and for leaving
12076 * it because of an exception we know will happen, which is done in
12077 * gen_exception_insn(). The latter is necessary because we need to
12078 * leave the TB with the PC/IT state just prior to execution of the
12079 * instruction which caused the exception.
12080 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12081 * then the CPUARMState will be wrong and we need to reset it.
12082 * This is handled in the same way as restoration of the
12083 * PC in these situations; we save the value of the condexec bits
12084 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12085 * then uses this to restore them after an exception.
12087 * Note that there are no instructions which can read the condexec
12088 * bits, and none which can write non-static values to them, so
12089 * we don't need to care about whether CPUARMState is correct in the
12090 * middle of a TB.
12093 /* Reset the conditional execution bits immediately. This avoids
12094 complications trying to do it at the end of the block. */
12095 if (dc->condexec_mask || dc->condexec_cond) {
12096 TCGv_i32 tmp = tcg_temp_new_i32();
12097 tcg_gen_movi_i32(tmp, 0);
12098 store_cpu_field(tmp, condexec_bits);
12100 tcg_clear_temp_count();
12103 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12105 DisasContext *dc = container_of(dcbase, DisasContext, base);
12107 tcg_gen_insn_start(dc->pc,
12108 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12110 dc->insn_start = tcg_last_op();
12113 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12114 const CPUBreakpoint *bp)
12116 DisasContext *dc = container_of(dcbase, DisasContext, base);
12118 if (bp->flags & BP_CPU) {
12119 gen_set_condexec(dc);
12120 gen_set_pc_im(dc, dc->pc);
12121 gen_helper_check_breakpoints(cpu_env);
12122 /* End the TB early; it's likely not going to be executed */
12123 dc->base.is_jmp = DISAS_TOO_MANY;
12124 } else {
12125 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12126 /* The address covered by the breakpoint must be
12127 included in [tb->pc, tb->pc + tb->size) in order
12128 to for it to be properly cleared -- thus we
12129 increment the PC here so that the logic setting
12130 tb->size below does the right thing. */
12131 /* TODO: Advance PC by correct instruction length to
12132 * avoid disassembler error messages */
12133 dc->pc += 2;
12134 dc->base.is_jmp = DISAS_NORETURN;
12137 return true;
12140 static bool arm_pre_translate_insn(DisasContext *dc)
12142 #ifdef CONFIG_USER_ONLY
12143 /* Intercept jump to the magic kernel page. */
12144 if (dc->pc >= 0xffff0000) {
12145 /* We always get here via a jump, so know we are not in a
12146 conditional execution block. */
12147 gen_exception_internal(EXCP_KERNEL_TRAP);
12148 dc->base.is_jmp = DISAS_NORETURN;
12149 return true;
12151 #endif
12153 if (dc->ss_active && !dc->pstate_ss) {
12154 /* Singlestep state is Active-pending.
12155 * If we're in this state at the start of a TB then either
12156 * a) we just took an exception to an EL which is being debugged
12157 * and this is the first insn in the exception handler
12158 * b) debug exceptions were masked and we just unmasked them
12159 * without changing EL (eg by clearing PSTATE.D)
12160 * In either case we're going to take a swstep exception in the
12161 * "did not step an insn" case, and so the syndrome ISV and EX
12162 * bits should be zero.
12164 assert(dc->base.num_insns == 1);
12165 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12166 default_exception_el(dc));
12167 dc->base.is_jmp = DISAS_NORETURN;
12168 return true;
12171 return false;
12174 static void arm_post_translate_insn(DisasContext *dc)
12176 if (dc->condjmp && !dc->base.is_jmp) {
12177 gen_set_label(dc->condlabel);
12178 dc->condjmp = 0;
12180 dc->base.pc_next = dc->pc;
12181 translator_loop_temp_check(&dc->base);
12184 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12186 DisasContext *dc = container_of(dcbase, DisasContext, base);
12187 CPUARMState *env = cpu->env_ptr;
12188 unsigned int insn;
12190 if (arm_pre_translate_insn(dc)) {
12191 return;
12194 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12195 dc->insn = insn;
12196 dc->pc += 4;
12197 disas_arm_insn(dc, insn);
12199 arm_post_translate_insn(dc);
12201 /* ARM is a fixed-length ISA. We performed the cross-page check
12202 in init_disas_context by adjusting max_insns. */
12205 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12207 /* Return true if this Thumb insn is always unconditional,
12208 * even inside an IT block. This is true of only a very few
12209 * instructions: BKPT, HLT, and SG.
12211 * A larger class of instructions are UNPREDICTABLE if used
12212 * inside an IT block; we do not need to detect those here, because
12213 * what we do by default (perform the cc check and update the IT
12214 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12215 * choice for those situations.
12217 * insn is either a 16-bit or a 32-bit instruction; the two are
12218 * distinguishable because for the 16-bit case the top 16 bits
12219 * are zeroes, and that isn't a valid 32-bit encoding.
12221 if ((insn & 0xffffff00) == 0xbe00) {
12222 /* BKPT */
12223 return true;
12226 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12227 !arm_dc_feature(s, ARM_FEATURE_M)) {
12228 /* HLT: v8A only. This is unconditional even when it is going to
12229 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12230 * For v7 cores this was a plain old undefined encoding and so
12231 * honours its cc check. (We might be using the encoding as
12232 * a semihosting trap, but we don't change the cc check behaviour
12233 * on that account, because a debugger connected to a real v7A
12234 * core and emulating semihosting traps by catching the UNDEF
12235 * exception would also only see cases where the cc check passed.
12236 * No guest code should be trying to do a HLT semihosting trap
12237 * in an IT block anyway.
12239 return true;
12242 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12243 arm_dc_feature(s, ARM_FEATURE_M)) {
12244 /* SG: v8M only */
12245 return true;
12248 return false;
12251 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12253 DisasContext *dc = container_of(dcbase, DisasContext, base);
12254 CPUARMState *env = cpu->env_ptr;
12255 uint32_t insn;
12256 bool is_16bit;
12258 if (arm_pre_translate_insn(dc)) {
12259 return;
12262 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12263 is_16bit = thumb_insn_is_16bit(dc, insn);
12264 dc->pc += 2;
12265 if (!is_16bit) {
12266 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12268 insn = insn << 16 | insn2;
12269 dc->pc += 2;
12271 dc->insn = insn;
12273 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12274 uint32_t cond = dc->condexec_cond;
12276 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12277 dc->condlabel = gen_new_label();
12278 arm_gen_test_cc(cond ^ 1, dc->condlabel);
12279 dc->condjmp = 1;
12283 if (is_16bit) {
12284 disas_thumb_insn(dc, insn);
12285 } else {
12286 disas_thumb2_insn(dc, insn);
12289 /* Advance the Thumb condexec condition. */
12290 if (dc->condexec_mask) {
12291 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12292 ((dc->condexec_mask >> 4) & 1));
12293 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12294 if (dc->condexec_mask == 0) {
12295 dc->condexec_cond = 0;
12299 arm_post_translate_insn(dc);
12301 /* Thumb is a variable-length ISA. Stop translation when the next insn
12302 * will touch a new page. This ensures that prefetch aborts occur at
12303 * the right place.
12305 * We want to stop the TB if the next insn starts in a new page,
12306 * or if it spans between this page and the next. This means that
12307 * if we're looking at the last halfword in the page we need to
12308 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12309 * or a 32-bit Thumb insn (which won't).
12310 * This is to avoid generating a silly TB with a single 16-bit insn
12311 * in it at the end of this page (which would execute correctly
12312 * but isn't very efficient).
12314 if (dc->base.is_jmp == DISAS_NEXT
12315 && (dc->pc >= dc->next_page_start
12316 || (dc->pc >= dc->next_page_start - 3
12317 && insn_crosses_page(env, dc)))) {
12318 dc->base.is_jmp = DISAS_TOO_MANY;
12322 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12324 DisasContext *dc = container_of(dcbase, DisasContext, base);
12326 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12327 /* FIXME: This can theoretically happen with self-modifying code. */
12328 cpu_abort(cpu, "IO on conditional branch instruction");
12331 /* At this stage dc->condjmp will only be set when the skipped
12332 instruction was a conditional branch or trap, and the PC has
12333 already been written. */
12334 gen_set_condexec(dc);
12335 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12336 /* Exception return branches need some special case code at the
12337 * end of the TB, which is complex enough that it has to
12338 * handle the single-step vs not and the condition-failed
12339 * insn codepath itself.
12341 gen_bx_excret_final_code(dc);
12342 } else if (unlikely(is_singlestepping(dc))) {
12343 /* Unconditional and "condition passed" instruction codepath. */
12344 switch (dc->base.is_jmp) {
12345 case DISAS_SWI:
12346 gen_ss_advance(dc);
12347 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12348 default_exception_el(dc));
12349 break;
12350 case DISAS_HVC:
12351 gen_ss_advance(dc);
12352 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12353 break;
12354 case DISAS_SMC:
12355 gen_ss_advance(dc);
12356 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12357 break;
12358 case DISAS_NEXT:
12359 case DISAS_TOO_MANY:
12360 case DISAS_UPDATE:
12361 gen_set_pc_im(dc, dc->pc);
12362 /* fall through */
12363 default:
12364 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12365 gen_singlestep_exception(dc);
12366 break;
12367 case DISAS_NORETURN:
12368 break;
12370 } else {
12371 /* While branches must always occur at the end of an IT block,
12372 there are a few other things that can cause us to terminate
12373 the TB in the middle of an IT block:
12374 - Exception generating instructions (bkpt, swi, undefined).
12375 - Page boundaries.
12376 - Hardware watchpoints.
12377 Hardware breakpoints have already been handled and skip this code.
12379 switch(dc->base.is_jmp) {
12380 case DISAS_NEXT:
12381 case DISAS_TOO_MANY:
12382 gen_goto_tb(dc, 1, dc->pc);
12383 break;
12384 case DISAS_JUMP:
12385 gen_goto_ptr();
12386 break;
12387 case DISAS_UPDATE:
12388 gen_set_pc_im(dc, dc->pc);
12389 /* fall through */
12390 default:
12391 /* indicate that the hash table must be used to find the next TB */
12392 tcg_gen_exit_tb(0);
12393 break;
12394 case DISAS_NORETURN:
12395 /* nothing more to generate */
12396 break;
12397 case DISAS_WFI:
12399 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12400 !(dc->insn & (1U << 31))) ? 2 : 4);
12402 gen_helper_wfi(cpu_env, tmp);
12403 tcg_temp_free_i32(tmp);
12404 /* The helper doesn't necessarily throw an exception, but we
12405 * must go back to the main loop to check for interrupts anyway.
12407 tcg_gen_exit_tb(0);
12408 break;
12410 case DISAS_WFE:
12411 gen_helper_wfe(cpu_env);
12412 break;
12413 case DISAS_YIELD:
12414 gen_helper_yield(cpu_env);
12415 break;
12416 case DISAS_SWI:
12417 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12418 default_exception_el(dc));
12419 break;
12420 case DISAS_HVC:
12421 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12422 break;
12423 case DISAS_SMC:
12424 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12425 break;
12429 if (dc->condjmp) {
12430 /* "Condition failed" instruction codepath for the branch/trap insn */
12431 gen_set_label(dc->condlabel);
12432 gen_set_condexec(dc);
12433 if (unlikely(is_singlestepping(dc))) {
12434 gen_set_pc_im(dc, dc->pc);
12435 gen_singlestep_exception(dc);
12436 } else {
12437 gen_goto_tb(dc, 1, dc->pc);
12441 /* Functions above can change dc->pc, so re-align db->pc_next */
12442 dc->base.pc_next = dc->pc;
12445 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12447 DisasContext *dc = container_of(dcbase, DisasContext, base);
12449 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12450 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12453 static const TranslatorOps arm_translator_ops = {
12454 .init_disas_context = arm_tr_init_disas_context,
12455 .tb_start = arm_tr_tb_start,
12456 .insn_start = arm_tr_insn_start,
12457 .breakpoint_check = arm_tr_breakpoint_check,
12458 .translate_insn = arm_tr_translate_insn,
12459 .tb_stop = arm_tr_tb_stop,
12460 .disas_log = arm_tr_disas_log,
12463 static const TranslatorOps thumb_translator_ops = {
12464 .init_disas_context = arm_tr_init_disas_context,
12465 .tb_start = arm_tr_tb_start,
12466 .insn_start = arm_tr_insn_start,
12467 .breakpoint_check = arm_tr_breakpoint_check,
12468 .translate_insn = thumb_tr_translate_insn,
12469 .tb_stop = arm_tr_tb_stop,
12470 .disas_log = arm_tr_disas_log,
12473 /* generate intermediate code for basic block 'tb'. */
12474 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12476 DisasContext dc;
12477 const TranslatorOps *ops = &arm_translator_ops;
12479 if (ARM_TBFLAG_THUMB(tb->flags)) {
12480 ops = &thumb_translator_ops;
12482 #ifdef TARGET_AARCH64
12483 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12484 ops = &aarch64_translator_ops;
12486 #endif
12488 translator_loop(ops, &dc.base, cpu, tb);
12491 static const char *cpu_mode_names[16] = {
12492 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12493 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12496 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12497 int flags)
12499 ARMCPU *cpu = ARM_CPU(cs);
12500 CPUARMState *env = &cpu->env;
12501 int i;
12503 if (is_a64(env)) {
12504 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12505 return;
12508 for(i=0;i<16;i++) {
12509 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12510 if ((i % 4) == 3)
12511 cpu_fprintf(f, "\n");
12512 else
12513 cpu_fprintf(f, " ");
12516 if (arm_feature(env, ARM_FEATURE_M)) {
12517 uint32_t xpsr = xpsr_read(env);
12518 const char *mode;
12519 const char *ns_status = "";
12521 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12522 ns_status = env->v7m.secure ? "S " : "NS ";
12525 if (xpsr & XPSR_EXCP) {
12526 mode = "handler";
12527 } else {
12528 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12529 mode = "unpriv-thread";
12530 } else {
12531 mode = "priv-thread";
12535 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12536 xpsr,
12537 xpsr & XPSR_N ? 'N' : '-',
12538 xpsr & XPSR_Z ? 'Z' : '-',
12539 xpsr & XPSR_C ? 'C' : '-',
12540 xpsr & XPSR_V ? 'V' : '-',
12541 xpsr & XPSR_T ? 'T' : 'A',
12542 ns_status,
12543 mode);
12544 } else {
12545 uint32_t psr = cpsr_read(env);
12546 const char *ns_status = "";
12548 if (arm_feature(env, ARM_FEATURE_EL3) &&
12549 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12550 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12553 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12554 psr,
12555 psr & CPSR_N ? 'N' : '-',
12556 psr & CPSR_Z ? 'Z' : '-',
12557 psr & CPSR_C ? 'C' : '-',
12558 psr & CPSR_V ? 'V' : '-',
12559 psr & CPSR_T ? 'T' : 'A',
12560 ns_status,
12561 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12564 if (flags & CPU_DUMP_FPU) {
12565 int numvfpregs = 0;
12566 if (arm_feature(env, ARM_FEATURE_VFP)) {
12567 numvfpregs += 16;
12569 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12570 numvfpregs += 16;
12572 for (i = 0; i < numvfpregs; i++) {
12573 uint64_t v = float64_val(env->vfp.regs[i]);
12574 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12575 i * 2, (uint32_t)v,
12576 i * 2 + 1, (uint32_t)(v >> 32),
12577 i, v);
12579 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12583 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12584 target_ulong *data)
12586 if (is_a64(env)) {
12587 env->pc = data[0];
12588 env->condexec_bits = 0;
12589 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12590 } else {
12591 env->regs[15] = data[0];
12592 env->condexec_bits = data[1];
12593 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;