target/arm: Enforce word alignment for LDRD/STRD
[qemu.git] / target / arm / translate.c
blob4b0dba9e7788c6a3d91e5c6d342561e129e97913
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.1 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/tcg-op.h"
28 #include "tcg/tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "semihosting/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
38 #include "exec/log.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #include "translate.h"
54 #if defined(CONFIG_USER_ONLY)
55 #define IS_USER(s) 1
56 #else
57 #define IS_USER(s) (s->user)
58 #endif
60 /* These are TCG temporaries used only by the legacy iwMMXt decoder */
61 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
62 /* These are TCG globals which alias CPUARMState fields */
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 #include "exec/gen-icount.h"
70 static const char * const regnames[] =
71 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
72 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
74 /* Function prototypes for gen_ functions calling Neon helpers. */
75 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
76 TCGv_i32, TCGv_i32);
77 /* Function prototypes for gen_ functions for fix point conversions */
78 typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
80 /* initialize TCG globals. */
81 void arm_translate_init(void)
83 int i;
85 for (i = 0; i < 16; i++) {
86 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
87 offsetof(CPUARMState, regs[i]),
88 regnames[i]);
90 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
91 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
92 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
93 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
95 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
96 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
97 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
98 offsetof(CPUARMState, exclusive_val), "exclusive_val");
100 a64_translate_init();
103 /* Generate a label used for skipping this instruction */
104 static void arm_gen_condlabel(DisasContext *s)
106 if (!s->condjmp) {
107 s->condlabel = gen_new_label();
108 s->condjmp = 1;
113 * Constant expanders for the decoders.
116 static int negate(DisasContext *s, int x)
118 return -x;
121 static int plus_2(DisasContext *s, int x)
123 return x + 2;
126 static int times_2(DisasContext *s, int x)
128 return x * 2;
131 static int times_4(DisasContext *s, int x)
133 return x * 4;
136 /* Flags for the disas_set_da_iss info argument:
137 * lower bits hold the Rt register number, higher bits are flags.
139 typedef enum ISSInfo {
140 ISSNone = 0,
141 ISSRegMask = 0x1f,
142 ISSInvalid = (1 << 5),
143 ISSIsAcqRel = (1 << 6),
144 ISSIsWrite = (1 << 7),
145 ISSIs16Bit = (1 << 8),
146 } ISSInfo;
148 /* Save the syndrome information for a Data Abort */
149 static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
151 uint32_t syn;
152 int sas = memop & MO_SIZE;
153 bool sse = memop & MO_SIGN;
154 bool is_acqrel = issinfo & ISSIsAcqRel;
155 bool is_write = issinfo & ISSIsWrite;
156 bool is_16bit = issinfo & ISSIs16Bit;
157 int srt = issinfo & ISSRegMask;
159 if (issinfo & ISSInvalid) {
160 /* Some callsites want to conditionally provide ISS info,
161 * eg "only if this was not a writeback"
163 return;
166 if (srt == 15) {
167 /* For AArch32, insns where the src/dest is R15 never generate
168 * ISS information. Catching that here saves checking at all
169 * the call sites.
171 return;
174 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
175 0, 0, 0, is_write, 0, is_16bit);
176 disas_set_insn_syndrome(s, syn);
179 static inline int get_a32_user_mem_index(DisasContext *s)
181 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
182 * insns:
183 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
184 * otherwise, access as if at PL0.
186 switch (s->mmu_idx) {
187 case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
188 case ARMMMUIdx_E10_0:
189 case ARMMMUIdx_E10_1:
190 case ARMMMUIdx_E10_1_PAN:
191 return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
192 case ARMMMUIdx_SE3:
193 case ARMMMUIdx_SE10_0:
194 case ARMMMUIdx_SE10_1:
195 case ARMMMUIdx_SE10_1_PAN:
196 return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
197 case ARMMMUIdx_MUser:
198 case ARMMMUIdx_MPriv:
199 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
200 case ARMMMUIdx_MUserNegPri:
201 case ARMMMUIdx_MPrivNegPri:
202 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
203 case ARMMMUIdx_MSUser:
204 case ARMMMUIdx_MSPriv:
205 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
206 case ARMMMUIdx_MSUserNegPri:
207 case ARMMMUIdx_MSPrivNegPri:
208 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
209 default:
210 g_assert_not_reached();
214 static inline TCGv_i32 load_cpu_offset(int offset)
216 TCGv_i32 tmp = tcg_temp_new_i32();
217 tcg_gen_ld_i32(tmp, cpu_env, offset);
218 return tmp;
221 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
223 static inline void store_cpu_offset(TCGv_i32 var, int offset)
225 tcg_gen_st_i32(var, cpu_env, offset);
226 tcg_temp_free_i32(var);
229 #define store_cpu_field(var, name) \
230 store_cpu_offset(var, offsetof(CPUARMState, name))
232 /* The architectural value of PC. */
233 static uint32_t read_pc(DisasContext *s)
235 return s->pc_curr + (s->thumb ? 4 : 8);
238 /* Set a variable to the value of a CPU register. */
239 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
241 if (reg == 15) {
242 tcg_gen_movi_i32(var, read_pc(s));
243 } else {
244 tcg_gen_mov_i32(var, cpu_R[reg]);
248 /* Create a new temporary and set it to the value of a CPU register. */
249 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
251 TCGv_i32 tmp = tcg_temp_new_i32();
252 load_reg_var(s, tmp, reg);
253 return tmp;
257 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
258 * This is used for load/store for which use of PC implies (literal),
259 * or ADD that implies ADR.
261 static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
263 TCGv_i32 tmp = tcg_temp_new_i32();
265 if (reg == 15) {
266 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
267 } else {
268 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
270 return tmp;
273 /* Set a CPU register. The source must be a temporary and will be
274 marked as dead. */
275 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
277 if (reg == 15) {
278 /* In Thumb mode, we must ignore bit 0.
279 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
280 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
281 * We choose to ignore [1:0] in ARM mode for all architecture versions.
283 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
284 s->base.is_jmp = DISAS_JUMP;
286 tcg_gen_mov_i32(cpu_R[reg], var);
287 tcg_temp_free_i32(var);
291 * Variant of store_reg which applies v8M stack-limit checks before updating
292 * SP. If the check fails this will result in an exception being taken.
293 * We disable the stack checks for CONFIG_USER_ONLY because we have
294 * no idea what the stack limits should be in that case.
295 * If stack checking is not being done this just acts like store_reg().
297 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
299 #ifndef CONFIG_USER_ONLY
300 if (s->v8m_stackcheck) {
301 gen_helper_v8m_stackcheck(cpu_env, var);
303 #endif
304 store_reg(s, 13, var);
307 /* Value extensions. */
308 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
309 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
310 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
311 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
313 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
314 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
317 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
319 TCGv_i32 tmp_mask = tcg_const_i32(mask);
320 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
321 tcg_temp_free_i32(tmp_mask);
323 /* Set NZCV flags from the high 4 bits of var. */
324 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
326 static void gen_exception_internal(int excp)
328 TCGv_i32 tcg_excp = tcg_const_i32(excp);
330 assert(excp_is_internal(excp));
331 gen_helper_exception_internal(cpu_env, tcg_excp);
332 tcg_temp_free_i32(tcg_excp);
335 static void gen_step_complete_exception(DisasContext *s)
337 /* We just completed step of an insn. Move from Active-not-pending
338 * to Active-pending, and then also take the swstep exception.
339 * This corresponds to making the (IMPDEF) choice to prioritize
340 * swstep exceptions over asynchronous exceptions taken to an exception
341 * level where debug is disabled. This choice has the advantage that
342 * we do not need to maintain internal state corresponding to the
343 * ISV/EX syndrome bits between completion of the step and generation
344 * of the exception, and our syndrome information is always correct.
346 gen_ss_advance(s);
347 gen_swstep_exception(s, 1, s->is_ldex);
348 s->base.is_jmp = DISAS_NORETURN;
351 static void gen_singlestep_exception(DisasContext *s)
353 /* Generate the right kind of exception for singlestep, which is
354 * either the architectural singlestep or EXCP_DEBUG for QEMU's
355 * gdb singlestepping.
357 if (s->ss_active) {
358 gen_step_complete_exception(s);
359 } else {
360 gen_exception_internal(EXCP_DEBUG);
364 static inline bool is_singlestepping(DisasContext *s)
366 /* Return true if we are singlestepping either because of
367 * architectural singlestep or QEMU gdbstub singlestep. This does
368 * not include the command line '-singlestep' mode which is rather
369 * misnamed as it only means "one instruction per TB" and doesn't
370 * affect the code we generate.
372 return s->base.singlestep_enabled || s->ss_active;
375 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
377 TCGv_i32 tmp1 = tcg_temp_new_i32();
378 TCGv_i32 tmp2 = tcg_temp_new_i32();
379 tcg_gen_ext16s_i32(tmp1, a);
380 tcg_gen_ext16s_i32(tmp2, b);
381 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
382 tcg_temp_free_i32(tmp2);
383 tcg_gen_sari_i32(a, a, 16);
384 tcg_gen_sari_i32(b, b, 16);
385 tcg_gen_mul_i32(b, b, a);
386 tcg_gen_mov_i32(a, tmp1);
387 tcg_temp_free_i32(tmp1);
390 /* Byteswap each halfword. */
391 static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
393 TCGv_i32 tmp = tcg_temp_new_i32();
394 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
395 tcg_gen_shri_i32(tmp, var, 8);
396 tcg_gen_and_i32(tmp, tmp, mask);
397 tcg_gen_and_i32(var, var, mask);
398 tcg_gen_shli_i32(var, var, 8);
399 tcg_gen_or_i32(dest, var, tmp);
400 tcg_temp_free_i32(mask);
401 tcg_temp_free_i32(tmp);
404 /* Byteswap low halfword and sign extend. */
405 static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
407 tcg_gen_ext16u_i32(var, var);
408 tcg_gen_bswap16_i32(var, var);
409 tcg_gen_ext16s_i32(dest, var);
412 /* Swap low and high halfwords. */
413 static void gen_swap_half(TCGv_i32 dest, TCGv_i32 var)
415 tcg_gen_rotri_i32(dest, var, 16);
418 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
419 tmp = (t0 ^ t1) & 0x8000;
420 t0 &= ~0x8000;
421 t1 &= ~0x8000;
422 t0 = (t0 + t1) ^ tmp;
425 static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
427 TCGv_i32 tmp = tcg_temp_new_i32();
428 tcg_gen_xor_i32(tmp, t0, t1);
429 tcg_gen_andi_i32(tmp, tmp, 0x8000);
430 tcg_gen_andi_i32(t0, t0, ~0x8000);
431 tcg_gen_andi_i32(t1, t1, ~0x8000);
432 tcg_gen_add_i32(t0, t0, t1);
433 tcg_gen_xor_i32(dest, t0, tmp);
434 tcg_temp_free_i32(tmp);
437 /* Set N and Z flags from var. */
438 static inline void gen_logic_CC(TCGv_i32 var)
440 tcg_gen_mov_i32(cpu_NF, var);
441 tcg_gen_mov_i32(cpu_ZF, var);
444 /* dest = T0 + T1 + CF. */
445 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
447 tcg_gen_add_i32(dest, t0, t1);
448 tcg_gen_add_i32(dest, dest, cpu_CF);
451 /* dest = T0 - T1 + CF - 1. */
452 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
454 tcg_gen_sub_i32(dest, t0, t1);
455 tcg_gen_add_i32(dest, dest, cpu_CF);
456 tcg_gen_subi_i32(dest, dest, 1);
459 /* dest = T0 + T1. Compute C, N, V and Z flags */
460 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
462 TCGv_i32 tmp = tcg_temp_new_i32();
463 tcg_gen_movi_i32(tmp, 0);
464 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
465 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
466 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
467 tcg_gen_xor_i32(tmp, t0, t1);
468 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
469 tcg_temp_free_i32(tmp);
470 tcg_gen_mov_i32(dest, cpu_NF);
473 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
474 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
476 TCGv_i32 tmp = tcg_temp_new_i32();
477 if (TCG_TARGET_HAS_add2_i32) {
478 tcg_gen_movi_i32(tmp, 0);
479 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
480 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
481 } else {
482 TCGv_i64 q0 = tcg_temp_new_i64();
483 TCGv_i64 q1 = tcg_temp_new_i64();
484 tcg_gen_extu_i32_i64(q0, t0);
485 tcg_gen_extu_i32_i64(q1, t1);
486 tcg_gen_add_i64(q0, q0, q1);
487 tcg_gen_extu_i32_i64(q1, cpu_CF);
488 tcg_gen_add_i64(q0, q0, q1);
489 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
490 tcg_temp_free_i64(q0);
491 tcg_temp_free_i64(q1);
493 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
494 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
495 tcg_gen_xor_i32(tmp, t0, t1);
496 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
497 tcg_temp_free_i32(tmp);
498 tcg_gen_mov_i32(dest, cpu_NF);
501 /* dest = T0 - T1. Compute C, N, V and Z flags */
502 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
504 TCGv_i32 tmp;
505 tcg_gen_sub_i32(cpu_NF, t0, t1);
506 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
507 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
508 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
509 tmp = tcg_temp_new_i32();
510 tcg_gen_xor_i32(tmp, t0, t1);
511 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
512 tcg_temp_free_i32(tmp);
513 tcg_gen_mov_i32(dest, cpu_NF);
516 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
517 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
519 TCGv_i32 tmp = tcg_temp_new_i32();
520 tcg_gen_not_i32(tmp, t1);
521 gen_adc_CC(dest, t0, tmp);
522 tcg_temp_free_i32(tmp);
525 #define GEN_SHIFT(name) \
526 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
528 TCGv_i32 tmp1, tmp2, tmp3; \
529 tmp1 = tcg_temp_new_i32(); \
530 tcg_gen_andi_i32(tmp1, t1, 0xff); \
531 tmp2 = tcg_const_i32(0); \
532 tmp3 = tcg_const_i32(0x1f); \
533 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
534 tcg_temp_free_i32(tmp3); \
535 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
536 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
537 tcg_temp_free_i32(tmp2); \
538 tcg_temp_free_i32(tmp1); \
540 GEN_SHIFT(shl)
541 GEN_SHIFT(shr)
542 #undef GEN_SHIFT
544 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
546 TCGv_i32 tmp1, tmp2;
547 tmp1 = tcg_temp_new_i32();
548 tcg_gen_andi_i32(tmp1, t1, 0xff);
549 tmp2 = tcg_const_i32(0x1f);
550 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
551 tcg_temp_free_i32(tmp2);
552 tcg_gen_sar_i32(dest, t0, tmp1);
553 tcg_temp_free_i32(tmp1);
556 static void shifter_out_im(TCGv_i32 var, int shift)
558 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
561 /* Shift by immediate. Includes special handling for shift == 0. */
562 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
563 int shift, int flags)
565 switch (shiftop) {
566 case 0: /* LSL */
567 if (shift != 0) {
568 if (flags)
569 shifter_out_im(var, 32 - shift);
570 tcg_gen_shli_i32(var, var, shift);
572 break;
573 case 1: /* LSR */
574 if (shift == 0) {
575 if (flags) {
576 tcg_gen_shri_i32(cpu_CF, var, 31);
578 tcg_gen_movi_i32(var, 0);
579 } else {
580 if (flags)
581 shifter_out_im(var, shift - 1);
582 tcg_gen_shri_i32(var, var, shift);
584 break;
585 case 2: /* ASR */
586 if (shift == 0)
587 shift = 32;
588 if (flags)
589 shifter_out_im(var, shift - 1);
590 if (shift == 32)
591 shift = 31;
592 tcg_gen_sari_i32(var, var, shift);
593 break;
594 case 3: /* ROR/RRX */
595 if (shift != 0) {
596 if (flags)
597 shifter_out_im(var, shift - 1);
598 tcg_gen_rotri_i32(var, var, shift); break;
599 } else {
600 TCGv_i32 tmp = tcg_temp_new_i32();
601 tcg_gen_shli_i32(tmp, cpu_CF, 31);
602 if (flags)
603 shifter_out_im(var, 0);
604 tcg_gen_shri_i32(var, var, 1);
605 tcg_gen_or_i32(var, var, tmp);
606 tcg_temp_free_i32(tmp);
611 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
612 TCGv_i32 shift, int flags)
614 if (flags) {
615 switch (shiftop) {
616 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
617 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
618 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
619 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
621 } else {
622 switch (shiftop) {
623 case 0:
624 gen_shl(var, var, shift);
625 break;
626 case 1:
627 gen_shr(var, var, shift);
628 break;
629 case 2:
630 gen_sar(var, var, shift);
631 break;
632 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
633 tcg_gen_rotr_i32(var, var, shift); break;
636 tcg_temp_free_i32(shift);
640 * Generate a conditional based on ARM condition code cc.
641 * This is common between ARM and Aarch64 targets.
643 void arm_test_cc(DisasCompare *cmp, int cc)
645 TCGv_i32 value;
646 TCGCond cond;
647 bool global = true;
649 switch (cc) {
650 case 0: /* eq: Z */
651 case 1: /* ne: !Z */
652 cond = TCG_COND_EQ;
653 value = cpu_ZF;
654 break;
656 case 2: /* cs: C */
657 case 3: /* cc: !C */
658 cond = TCG_COND_NE;
659 value = cpu_CF;
660 break;
662 case 4: /* mi: N */
663 case 5: /* pl: !N */
664 cond = TCG_COND_LT;
665 value = cpu_NF;
666 break;
668 case 6: /* vs: V */
669 case 7: /* vc: !V */
670 cond = TCG_COND_LT;
671 value = cpu_VF;
672 break;
674 case 8: /* hi: C && !Z */
675 case 9: /* ls: !C || Z -> !(C && !Z) */
676 cond = TCG_COND_NE;
677 value = tcg_temp_new_i32();
678 global = false;
679 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
680 ZF is non-zero for !Z; so AND the two subexpressions. */
681 tcg_gen_neg_i32(value, cpu_CF);
682 tcg_gen_and_i32(value, value, cpu_ZF);
683 break;
685 case 10: /* ge: N == V -> N ^ V == 0 */
686 case 11: /* lt: N != V -> N ^ V != 0 */
687 /* Since we're only interested in the sign bit, == 0 is >= 0. */
688 cond = TCG_COND_GE;
689 value = tcg_temp_new_i32();
690 global = false;
691 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
692 break;
694 case 12: /* gt: !Z && N == V */
695 case 13: /* le: Z || N != V */
696 cond = TCG_COND_NE;
697 value = tcg_temp_new_i32();
698 global = false;
699 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
700 * the sign bit then AND with ZF to yield the result. */
701 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
702 tcg_gen_sari_i32(value, value, 31);
703 tcg_gen_andc_i32(value, cpu_ZF, value);
704 break;
706 case 14: /* always */
707 case 15: /* always */
708 /* Use the ALWAYS condition, which will fold early.
709 * It doesn't matter what we use for the value. */
710 cond = TCG_COND_ALWAYS;
711 value = cpu_ZF;
712 goto no_invert;
714 default:
715 fprintf(stderr, "Bad condition code 0x%x\n", cc);
716 abort();
719 if (cc & 1) {
720 cond = tcg_invert_cond(cond);
723 no_invert:
724 cmp->cond = cond;
725 cmp->value = value;
726 cmp->value_global = global;
729 void arm_free_cc(DisasCompare *cmp)
731 if (!cmp->value_global) {
732 tcg_temp_free_i32(cmp->value);
736 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
738 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
741 void arm_gen_test_cc(int cc, TCGLabel *label)
743 DisasCompare cmp;
744 arm_test_cc(&cmp, cc);
745 arm_jump_cc(&cmp, label);
746 arm_free_cc(&cmp);
749 static inline void gen_set_condexec(DisasContext *s)
751 if (s->condexec_mask) {
752 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
753 TCGv_i32 tmp = tcg_temp_new_i32();
754 tcg_gen_movi_i32(tmp, val);
755 store_cpu_field(tmp, condexec_bits);
759 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
761 tcg_gen_movi_i32(cpu_R[15], val);
764 /* Set PC and Thumb state from var. var is marked as dead. */
765 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
767 s->base.is_jmp = DISAS_JUMP;
768 tcg_gen_andi_i32(cpu_R[15], var, ~1);
769 tcg_gen_andi_i32(var, var, 1);
770 store_cpu_field(var, thumb);
774 * Set PC and Thumb state from var. var is marked as dead.
775 * For M-profile CPUs, include logic to detect exception-return
776 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
777 * and BX reg, and no others, and happens only for code in Handler mode.
778 * The Security Extension also requires us to check for the FNC_RETURN
779 * which signals a function return from non-secure state; this can happen
780 * in both Handler and Thread mode.
781 * To avoid having to do multiple comparisons in inline generated code,
782 * we make the check we do here loose, so it will match for EXC_RETURN
783 * in Thread mode. For system emulation do_v7m_exception_exit() checks
784 * for these spurious cases and returns without doing anything (giving
785 * the same behaviour as for a branch to a non-magic address).
787 * In linux-user mode it is unclear what the right behaviour for an
788 * attempted FNC_RETURN should be, because in real hardware this will go
789 * directly to Secure code (ie not the Linux kernel) which will then treat
790 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
791 * attempt behave the way it would on a CPU without the security extension,
792 * which is to say "like a normal branch". That means we can simply treat
793 * all branches as normal with no magic address behaviour.
795 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
797 /* Generate the same code here as for a simple bx, but flag via
798 * s->base.is_jmp that we need to do the rest of the work later.
800 gen_bx(s, var);
801 #ifndef CONFIG_USER_ONLY
802 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
803 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
804 s->base.is_jmp = DISAS_BX_EXCRET;
806 #endif
809 static inline void gen_bx_excret_final_code(DisasContext *s)
811 /* Generate the code to finish possible exception return and end the TB */
812 TCGLabel *excret_label = gen_new_label();
813 uint32_t min_magic;
815 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
816 /* Covers FNC_RETURN and EXC_RETURN magic */
817 min_magic = FNC_RETURN_MIN_MAGIC;
818 } else {
819 /* EXC_RETURN magic only */
820 min_magic = EXC_RETURN_MIN_MAGIC;
823 /* Is the new PC value in the magic range indicating exception return? */
824 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
825 /* No: end the TB as we would for a DISAS_JMP */
826 if (is_singlestepping(s)) {
827 gen_singlestep_exception(s);
828 } else {
829 tcg_gen_exit_tb(NULL, 0);
831 gen_set_label(excret_label);
832 /* Yes: this is an exception return.
833 * At this point in runtime env->regs[15] and env->thumb will hold
834 * the exception-return magic number, which do_v7m_exception_exit()
835 * will read. Nothing else will be able to see those values because
836 * the cpu-exec main loop guarantees that we will always go straight
837 * from raising the exception to the exception-handling code.
839 * gen_ss_advance(s) does nothing on M profile currently but
840 * calling it is conceptually the right thing as we have executed
841 * this instruction (compare SWI, HVC, SMC handling).
843 gen_ss_advance(s);
844 gen_exception_internal(EXCP_EXCEPTION_EXIT);
847 static inline void gen_bxns(DisasContext *s, int rm)
849 TCGv_i32 var = load_reg(s, rm);
851 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
852 * we need to sync state before calling it, but:
853 * - we don't need to do gen_set_pc_im() because the bxns helper will
854 * always set the PC itself
855 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
856 * unless it's outside an IT block or the last insn in an IT block,
857 * so we know that condexec == 0 (already set at the top of the TB)
858 * is correct in the non-UNPREDICTABLE cases, and we can choose
859 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
861 gen_helper_v7m_bxns(cpu_env, var);
862 tcg_temp_free_i32(var);
863 s->base.is_jmp = DISAS_EXIT;
866 static inline void gen_blxns(DisasContext *s, int rm)
868 TCGv_i32 var = load_reg(s, rm);
870 /* We don't need to sync condexec state, for the same reason as bxns.
871 * We do however need to set the PC, because the blxns helper reads it.
872 * The blxns helper may throw an exception.
874 gen_set_pc_im(s, s->base.pc_next);
875 gen_helper_v7m_blxns(cpu_env, var);
876 tcg_temp_free_i32(var);
877 s->base.is_jmp = DISAS_EXIT;
880 /* Variant of store_reg which uses branch&exchange logic when storing
881 to r15 in ARM architecture v7 and above. The source must be a temporary
882 and will be marked as dead. */
883 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
885 if (reg == 15 && ENABLE_ARCH_7) {
886 gen_bx(s, var);
887 } else {
888 store_reg(s, reg, var);
892 /* Variant of store_reg which uses branch&exchange logic when storing
893 * to r15 in ARM architecture v5T and above. This is used for storing
894 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
895 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
896 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
898 if (reg == 15 && ENABLE_ARCH_5) {
899 gen_bx_excret(s, var);
900 } else {
901 store_reg(s, reg, var);
905 #ifdef CONFIG_USER_ONLY
906 #define IS_USER_ONLY 1
907 #else
908 #define IS_USER_ONLY 0
909 #endif
912 * Abstractions of "generate code to do a guest load/store for
913 * AArch32", where a vaddr is always 32 bits (and is zero
914 * extended if we're a 64 bit core) and data is also
915 * 32 bits unless specifically doing a 64 bit access.
916 * These functions work like tcg_gen_qemu_{ld,st}* except
917 * that the address argument is TCGv_i32 rather than TCGv.
920 static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
922 TCGv addr = tcg_temp_new();
923 tcg_gen_extu_i32_tl(addr, a32);
925 /* Not needed for user-mode BE32, where we use MO_BE instead. */
926 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
927 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
929 return addr;
933 * Internal routines are used for NEON cases where the endianness
934 * and/or alignment has already been taken into account and manipulated.
936 static void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
937 TCGv_i32 a32, int index, MemOp opc)
939 TCGv addr = gen_aa32_addr(s, a32, opc);
940 tcg_gen_qemu_ld_i32(val, addr, index, opc);
941 tcg_temp_free(addr);
944 static void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
945 TCGv_i32 a32, int index, MemOp opc)
947 TCGv addr = gen_aa32_addr(s, a32, opc);
948 tcg_gen_qemu_st_i32(val, addr, index, opc);
949 tcg_temp_free(addr);
952 static void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
953 TCGv_i32 a32, int index, MemOp opc)
955 TCGv addr = gen_aa32_addr(s, a32, opc);
957 tcg_gen_qemu_ld_i64(val, addr, index, opc);
959 /* Not needed for user-mode BE32, where we use MO_BE instead. */
960 if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
961 tcg_gen_rotri_i64(val, val, 32);
963 tcg_temp_free(addr);
966 static void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
967 TCGv_i32 a32, int index, MemOp opc)
969 TCGv addr = gen_aa32_addr(s, a32, opc);
971 /* Not needed for user-mode BE32, where we use MO_BE instead. */
972 if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
973 TCGv_i64 tmp = tcg_temp_new_i64();
974 tcg_gen_rotri_i64(tmp, val, 32);
975 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
976 tcg_temp_free_i64(tmp);
977 } else {
978 tcg_gen_qemu_st_i64(val, addr, index, opc);
980 tcg_temp_free(addr);
983 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
984 int index, MemOp opc)
986 gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
989 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
990 int index, MemOp opc)
992 gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
995 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
996 int index, MemOp opc)
998 gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
1001 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1002 int index, MemOp opc)
1004 gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
1007 #define DO_GEN_LD(SUFF, OPC) \
1008 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1009 TCGv_i32 a32, int index) \
1011 gen_aa32_ld_i32(s, val, a32, index, OPC); \
1014 #define DO_GEN_ST(SUFF, OPC) \
1015 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1016 TCGv_i32 a32, int index) \
1018 gen_aa32_st_i32(s, val, a32, index, OPC); \
1021 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1022 TCGv_i32 a32, int index)
1024 gen_aa32_ld_i64(s, val, a32, index, MO_Q);
1027 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1028 TCGv_i32 a32, int index)
1030 gen_aa32_st_i64(s, val, a32, index, MO_Q);
1033 DO_GEN_LD(8u, MO_UB)
1034 DO_GEN_LD(16u, MO_UW)
1035 DO_GEN_LD(32u, MO_UL)
1036 DO_GEN_ST(8, MO_UB)
1037 DO_GEN_ST(16, MO_UW)
1038 DO_GEN_ST(32, MO_UL)
1040 static inline void gen_hvc(DisasContext *s, int imm16)
1042 /* The pre HVC helper handles cases when HVC gets trapped
1043 * as an undefined insn by runtime configuration (ie before
1044 * the insn really executes).
1046 gen_set_pc_im(s, s->pc_curr);
1047 gen_helper_pre_hvc(cpu_env);
1048 /* Otherwise we will treat this as a real exception which
1049 * happens after execution of the insn. (The distinction matters
1050 * for the PC value reported to the exception handler and also
1051 * for single stepping.)
1053 s->svc_imm = imm16;
1054 gen_set_pc_im(s, s->base.pc_next);
1055 s->base.is_jmp = DISAS_HVC;
1058 static inline void gen_smc(DisasContext *s)
1060 /* As with HVC, we may take an exception either before or after
1061 * the insn executes.
1063 TCGv_i32 tmp;
1065 gen_set_pc_im(s, s->pc_curr);
1066 tmp = tcg_const_i32(syn_aa32_smc());
1067 gen_helper_pre_smc(cpu_env, tmp);
1068 tcg_temp_free_i32(tmp);
1069 gen_set_pc_im(s, s->base.pc_next);
1070 s->base.is_jmp = DISAS_SMC;
1073 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1075 gen_set_condexec(s);
1076 gen_set_pc_im(s, pc);
1077 gen_exception_internal(excp);
1078 s->base.is_jmp = DISAS_NORETURN;
1081 static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
1082 int syn, uint32_t target_el)
1084 gen_set_condexec(s);
1085 gen_set_pc_im(s, pc);
1086 gen_exception(excp, syn, target_el);
1087 s->base.is_jmp = DISAS_NORETURN;
1090 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1092 TCGv_i32 tcg_syn;
1094 gen_set_condexec(s);
1095 gen_set_pc_im(s, s->pc_curr);
1096 tcg_syn = tcg_const_i32(syn);
1097 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1098 tcg_temp_free_i32(tcg_syn);
1099 s->base.is_jmp = DISAS_NORETURN;
1102 static void unallocated_encoding(DisasContext *s)
1104 /* Unallocated and reserved encodings are uncategorized */
1105 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1106 default_exception_el(s));
1109 static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
1110 TCGv_i32 tcg_el)
1112 TCGv_i32 tcg_excp;
1113 TCGv_i32 tcg_syn;
1115 gen_set_condexec(s);
1116 gen_set_pc_im(s, s->pc_curr);
1117 tcg_excp = tcg_const_i32(excp);
1118 tcg_syn = tcg_const_i32(syn);
1119 gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn, tcg_el);
1120 tcg_temp_free_i32(tcg_syn);
1121 tcg_temp_free_i32(tcg_excp);
1122 s->base.is_jmp = DISAS_NORETURN;
1125 /* Force a TB lookup after an instruction that changes the CPU state. */
1126 static inline void gen_lookup_tb(DisasContext *s)
1128 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1129 s->base.is_jmp = DISAS_EXIT;
1132 static inline void gen_hlt(DisasContext *s, int imm)
1134 /* HLT. This has two purposes.
1135 * Architecturally, it is an external halting debug instruction.
1136 * Since QEMU doesn't implement external debug, we treat this as
1137 * it is required for halting debug disabled: it will UNDEF.
1138 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1139 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1140 * must trigger semihosting even for ARMv7 and earlier, where
1141 * HLT was an undefined encoding.
1142 * In system mode, we don't allow userspace access to
1143 * semihosting, to provide some semblance of security
1144 * (and for consistency with our 32-bit semihosting).
1146 if (semihosting_enabled() &&
1147 #ifndef CONFIG_USER_ONLY
1148 s->current_el != 0 &&
1149 #endif
1150 (imm == (s->thumb ? 0x3c : 0xf000))) {
1151 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
1152 return;
1155 unallocated_encoding(s);
1159 * Return the offset of a "full" NEON Dreg.
1161 static long neon_full_reg_offset(unsigned reg)
1163 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1167 * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1168 * where 0 is the least significant end of the register.
1170 static long neon_element_offset(int reg, int element, MemOp memop)
1172 int element_size = 1 << (memop & MO_SIZE);
1173 int ofs = element * element_size;
1174 #ifdef HOST_WORDS_BIGENDIAN
1176 * Calculate the offset assuming fully little-endian,
1177 * then XOR to account for the order of the 8-byte units.
1179 if (element_size < 8) {
1180 ofs ^= 8 - element_size;
1182 #endif
1183 return neon_full_reg_offset(reg) + ofs;
1186 /* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
1187 static long vfp_reg_offset(bool dp, unsigned reg)
1189 if (dp) {
1190 return neon_element_offset(reg, 0, MO_64);
1191 } else {
1192 return neon_element_offset(reg >> 1, reg & 1, MO_32);
1196 static inline void vfp_load_reg64(TCGv_i64 var, int reg)
1198 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(true, reg));
1201 static inline void vfp_store_reg64(TCGv_i64 var, int reg)
1203 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(true, reg));
1206 static inline void vfp_load_reg32(TCGv_i32 var, int reg)
1208 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1211 static inline void vfp_store_reg32(TCGv_i32 var, int reg)
1213 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1216 static void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
1218 long off = neon_element_offset(reg, ele, memop);
1220 switch (memop) {
1221 case MO_SB:
1222 tcg_gen_ld8s_i32(dest, cpu_env, off);
1223 break;
1224 case MO_UB:
1225 tcg_gen_ld8u_i32(dest, cpu_env, off);
1226 break;
1227 case MO_SW:
1228 tcg_gen_ld16s_i32(dest, cpu_env, off);
1229 break;
1230 case MO_UW:
1231 tcg_gen_ld16u_i32(dest, cpu_env, off);
1232 break;
1233 case MO_UL:
1234 case MO_SL:
1235 tcg_gen_ld_i32(dest, cpu_env, off);
1236 break;
1237 default:
1238 g_assert_not_reached();
1242 static void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
1244 long off = neon_element_offset(reg, ele, memop);
1246 switch (memop) {
1247 case MO_SL:
1248 tcg_gen_ld32s_i64(dest, cpu_env, off);
1249 break;
1250 case MO_UL:
1251 tcg_gen_ld32u_i64(dest, cpu_env, off);
1252 break;
1253 case MO_Q:
1254 tcg_gen_ld_i64(dest, cpu_env, off);
1255 break;
1256 default:
1257 g_assert_not_reached();
1261 static void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
1263 long off = neon_element_offset(reg, ele, memop);
1265 switch (memop) {
1266 case MO_8:
1267 tcg_gen_st8_i32(src, cpu_env, off);
1268 break;
1269 case MO_16:
1270 tcg_gen_st16_i32(src, cpu_env, off);
1271 break;
1272 case MO_32:
1273 tcg_gen_st_i32(src, cpu_env, off);
1274 break;
1275 default:
1276 g_assert_not_reached();
1280 static void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
1282 long off = neon_element_offset(reg, ele, memop);
1284 switch (memop) {
1285 case MO_32:
1286 tcg_gen_st32_i64(src, cpu_env, off);
1287 break;
1288 case MO_64:
1289 tcg_gen_st_i64(src, cpu_env, off);
1290 break;
1291 default:
1292 g_assert_not_reached();
1296 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1298 TCGv_ptr ret = tcg_temp_new_ptr();
1299 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1300 return ret;
1303 #define ARM_CP_RW_BIT (1 << 20)
1305 /* Include the VFP and Neon decoders */
1306 #include "decode-m-nocp.c.inc"
1307 #include "translate-vfp.c.inc"
1308 #include "translate-neon.c.inc"
1310 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1312 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1315 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1317 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1320 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1322 TCGv_i32 var = tcg_temp_new_i32();
1323 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1324 return var;
1327 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1329 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1330 tcg_temp_free_i32(var);
1333 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1335 iwmmxt_store_reg(cpu_M0, rn);
1338 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1340 iwmmxt_load_reg(cpu_M0, rn);
1343 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1345 iwmmxt_load_reg(cpu_V1, rn);
1346 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1349 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1351 iwmmxt_load_reg(cpu_V1, rn);
1352 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1355 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1357 iwmmxt_load_reg(cpu_V1, rn);
1358 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1361 #define IWMMXT_OP(name) \
1362 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1364 iwmmxt_load_reg(cpu_V1, rn); \
1365 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1368 #define IWMMXT_OP_ENV(name) \
1369 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1371 iwmmxt_load_reg(cpu_V1, rn); \
1372 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1375 #define IWMMXT_OP_ENV_SIZE(name) \
1376 IWMMXT_OP_ENV(name##b) \
1377 IWMMXT_OP_ENV(name##w) \
1378 IWMMXT_OP_ENV(name##l)
1380 #define IWMMXT_OP_ENV1(name) \
1381 static inline void gen_op_iwmmxt_##name##_M0(void) \
1383 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1386 IWMMXT_OP(maddsq)
1387 IWMMXT_OP(madduq)
1388 IWMMXT_OP(sadb)
1389 IWMMXT_OP(sadw)
1390 IWMMXT_OP(mulslw)
1391 IWMMXT_OP(mulshw)
1392 IWMMXT_OP(mululw)
1393 IWMMXT_OP(muluhw)
1394 IWMMXT_OP(macsw)
1395 IWMMXT_OP(macuw)
1397 IWMMXT_OP_ENV_SIZE(unpackl)
1398 IWMMXT_OP_ENV_SIZE(unpackh)
1400 IWMMXT_OP_ENV1(unpacklub)
1401 IWMMXT_OP_ENV1(unpackluw)
1402 IWMMXT_OP_ENV1(unpacklul)
1403 IWMMXT_OP_ENV1(unpackhub)
1404 IWMMXT_OP_ENV1(unpackhuw)
1405 IWMMXT_OP_ENV1(unpackhul)
1406 IWMMXT_OP_ENV1(unpacklsb)
1407 IWMMXT_OP_ENV1(unpacklsw)
1408 IWMMXT_OP_ENV1(unpacklsl)
1409 IWMMXT_OP_ENV1(unpackhsb)
1410 IWMMXT_OP_ENV1(unpackhsw)
1411 IWMMXT_OP_ENV1(unpackhsl)
1413 IWMMXT_OP_ENV_SIZE(cmpeq)
1414 IWMMXT_OP_ENV_SIZE(cmpgtu)
1415 IWMMXT_OP_ENV_SIZE(cmpgts)
1417 IWMMXT_OP_ENV_SIZE(mins)
1418 IWMMXT_OP_ENV_SIZE(minu)
1419 IWMMXT_OP_ENV_SIZE(maxs)
1420 IWMMXT_OP_ENV_SIZE(maxu)
1422 IWMMXT_OP_ENV_SIZE(subn)
1423 IWMMXT_OP_ENV_SIZE(addn)
1424 IWMMXT_OP_ENV_SIZE(subu)
1425 IWMMXT_OP_ENV_SIZE(addu)
1426 IWMMXT_OP_ENV_SIZE(subs)
1427 IWMMXT_OP_ENV_SIZE(adds)
1429 IWMMXT_OP_ENV(avgb0)
1430 IWMMXT_OP_ENV(avgb1)
1431 IWMMXT_OP_ENV(avgw0)
1432 IWMMXT_OP_ENV(avgw1)
1434 IWMMXT_OP_ENV(packuw)
1435 IWMMXT_OP_ENV(packul)
1436 IWMMXT_OP_ENV(packuq)
1437 IWMMXT_OP_ENV(packsw)
1438 IWMMXT_OP_ENV(packsl)
1439 IWMMXT_OP_ENV(packsq)
1441 static void gen_op_iwmmxt_set_mup(void)
1443 TCGv_i32 tmp;
1444 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1445 tcg_gen_ori_i32(tmp, tmp, 2);
1446 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1449 static void gen_op_iwmmxt_set_cup(void)
1451 TCGv_i32 tmp;
1452 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1453 tcg_gen_ori_i32(tmp, tmp, 1);
1454 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1457 static void gen_op_iwmmxt_setpsr_nz(void)
1459 TCGv_i32 tmp = tcg_temp_new_i32();
1460 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1461 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1464 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1466 iwmmxt_load_reg(cpu_V1, rn);
1467 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1468 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1471 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1472 TCGv_i32 dest)
1474 int rd;
1475 uint32_t offset;
1476 TCGv_i32 tmp;
1478 rd = (insn >> 16) & 0xf;
1479 tmp = load_reg(s, rd);
1481 offset = (insn & 0xff) << ((insn >> 7) & 2);
1482 if (insn & (1 << 24)) {
1483 /* Pre indexed */
1484 if (insn & (1 << 23))
1485 tcg_gen_addi_i32(tmp, tmp, offset);
1486 else
1487 tcg_gen_addi_i32(tmp, tmp, -offset);
1488 tcg_gen_mov_i32(dest, tmp);
1489 if (insn & (1 << 21))
1490 store_reg(s, rd, tmp);
1491 else
1492 tcg_temp_free_i32(tmp);
1493 } else if (insn & (1 << 21)) {
1494 /* Post indexed */
1495 tcg_gen_mov_i32(dest, tmp);
1496 if (insn & (1 << 23))
1497 tcg_gen_addi_i32(tmp, tmp, offset);
1498 else
1499 tcg_gen_addi_i32(tmp, tmp, -offset);
1500 store_reg(s, rd, tmp);
1501 } else if (!(insn & (1 << 23)))
1502 return 1;
1503 return 0;
1506 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1508 int rd = (insn >> 0) & 0xf;
1509 TCGv_i32 tmp;
1511 if (insn & (1 << 8)) {
1512 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1513 return 1;
1514 } else {
1515 tmp = iwmmxt_load_creg(rd);
1517 } else {
1518 tmp = tcg_temp_new_i32();
1519 iwmmxt_load_reg(cpu_V0, rd);
1520 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1522 tcg_gen_andi_i32(tmp, tmp, mask);
1523 tcg_gen_mov_i32(dest, tmp);
1524 tcg_temp_free_i32(tmp);
1525 return 0;
1528 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1529 (ie. an undefined instruction). */
1530 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1532 int rd, wrd;
1533 int rdhi, rdlo, rd0, rd1, i;
1534 TCGv_i32 addr;
1535 TCGv_i32 tmp, tmp2, tmp3;
1537 if ((insn & 0x0e000e00) == 0x0c000000) {
1538 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1539 wrd = insn & 0xf;
1540 rdlo = (insn >> 12) & 0xf;
1541 rdhi = (insn >> 16) & 0xf;
1542 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1543 iwmmxt_load_reg(cpu_V0, wrd);
1544 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1545 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1546 } else { /* TMCRR */
1547 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1548 iwmmxt_store_reg(cpu_V0, wrd);
1549 gen_op_iwmmxt_set_mup();
1551 return 0;
1554 wrd = (insn >> 12) & 0xf;
1555 addr = tcg_temp_new_i32();
1556 if (gen_iwmmxt_address(s, insn, addr)) {
1557 tcg_temp_free_i32(addr);
1558 return 1;
1560 if (insn & ARM_CP_RW_BIT) {
1561 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1562 tmp = tcg_temp_new_i32();
1563 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1564 iwmmxt_store_creg(wrd, tmp);
1565 } else {
1566 i = 1;
1567 if (insn & (1 << 8)) {
1568 if (insn & (1 << 22)) { /* WLDRD */
1569 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1570 i = 0;
1571 } else { /* WLDRW wRd */
1572 tmp = tcg_temp_new_i32();
1573 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1575 } else {
1576 tmp = tcg_temp_new_i32();
1577 if (insn & (1 << 22)) { /* WLDRH */
1578 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1579 } else { /* WLDRB */
1580 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1583 if (i) {
1584 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1585 tcg_temp_free_i32(tmp);
1587 gen_op_iwmmxt_movq_wRn_M0(wrd);
1589 } else {
1590 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1591 tmp = iwmmxt_load_creg(wrd);
1592 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1593 } else {
1594 gen_op_iwmmxt_movq_M0_wRn(wrd);
1595 tmp = tcg_temp_new_i32();
1596 if (insn & (1 << 8)) {
1597 if (insn & (1 << 22)) { /* WSTRD */
1598 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1599 } else { /* WSTRW wRd */
1600 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1601 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1603 } else {
1604 if (insn & (1 << 22)) { /* WSTRH */
1605 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1606 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1607 } else { /* WSTRB */
1608 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1609 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1613 tcg_temp_free_i32(tmp);
1615 tcg_temp_free_i32(addr);
1616 return 0;
1619 if ((insn & 0x0f000000) != 0x0e000000)
1620 return 1;
1622 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1623 case 0x000: /* WOR */
1624 wrd = (insn >> 12) & 0xf;
1625 rd0 = (insn >> 0) & 0xf;
1626 rd1 = (insn >> 16) & 0xf;
1627 gen_op_iwmmxt_movq_M0_wRn(rd0);
1628 gen_op_iwmmxt_orq_M0_wRn(rd1);
1629 gen_op_iwmmxt_setpsr_nz();
1630 gen_op_iwmmxt_movq_wRn_M0(wrd);
1631 gen_op_iwmmxt_set_mup();
1632 gen_op_iwmmxt_set_cup();
1633 break;
1634 case 0x011: /* TMCR */
1635 if (insn & 0xf)
1636 return 1;
1637 rd = (insn >> 12) & 0xf;
1638 wrd = (insn >> 16) & 0xf;
1639 switch (wrd) {
1640 case ARM_IWMMXT_wCID:
1641 case ARM_IWMMXT_wCASF:
1642 break;
1643 case ARM_IWMMXT_wCon:
1644 gen_op_iwmmxt_set_cup();
1645 /* Fall through. */
1646 case ARM_IWMMXT_wCSSF:
1647 tmp = iwmmxt_load_creg(wrd);
1648 tmp2 = load_reg(s, rd);
1649 tcg_gen_andc_i32(tmp, tmp, tmp2);
1650 tcg_temp_free_i32(tmp2);
1651 iwmmxt_store_creg(wrd, tmp);
1652 break;
1653 case ARM_IWMMXT_wCGR0:
1654 case ARM_IWMMXT_wCGR1:
1655 case ARM_IWMMXT_wCGR2:
1656 case ARM_IWMMXT_wCGR3:
1657 gen_op_iwmmxt_set_cup();
1658 tmp = load_reg(s, rd);
1659 iwmmxt_store_creg(wrd, tmp);
1660 break;
1661 default:
1662 return 1;
1664 break;
1665 case 0x100: /* WXOR */
1666 wrd = (insn >> 12) & 0xf;
1667 rd0 = (insn >> 0) & 0xf;
1668 rd1 = (insn >> 16) & 0xf;
1669 gen_op_iwmmxt_movq_M0_wRn(rd0);
1670 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1671 gen_op_iwmmxt_setpsr_nz();
1672 gen_op_iwmmxt_movq_wRn_M0(wrd);
1673 gen_op_iwmmxt_set_mup();
1674 gen_op_iwmmxt_set_cup();
1675 break;
1676 case 0x111: /* TMRC */
1677 if (insn & 0xf)
1678 return 1;
1679 rd = (insn >> 12) & 0xf;
1680 wrd = (insn >> 16) & 0xf;
1681 tmp = iwmmxt_load_creg(wrd);
1682 store_reg(s, rd, tmp);
1683 break;
1684 case 0x300: /* WANDN */
1685 wrd = (insn >> 12) & 0xf;
1686 rd0 = (insn >> 0) & 0xf;
1687 rd1 = (insn >> 16) & 0xf;
1688 gen_op_iwmmxt_movq_M0_wRn(rd0);
1689 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1690 gen_op_iwmmxt_andq_M0_wRn(rd1);
1691 gen_op_iwmmxt_setpsr_nz();
1692 gen_op_iwmmxt_movq_wRn_M0(wrd);
1693 gen_op_iwmmxt_set_mup();
1694 gen_op_iwmmxt_set_cup();
1695 break;
1696 case 0x200: /* WAND */
1697 wrd = (insn >> 12) & 0xf;
1698 rd0 = (insn >> 0) & 0xf;
1699 rd1 = (insn >> 16) & 0xf;
1700 gen_op_iwmmxt_movq_M0_wRn(rd0);
1701 gen_op_iwmmxt_andq_M0_wRn(rd1);
1702 gen_op_iwmmxt_setpsr_nz();
1703 gen_op_iwmmxt_movq_wRn_M0(wrd);
1704 gen_op_iwmmxt_set_mup();
1705 gen_op_iwmmxt_set_cup();
1706 break;
1707 case 0x810: case 0xa10: /* WMADD */
1708 wrd = (insn >> 12) & 0xf;
1709 rd0 = (insn >> 0) & 0xf;
1710 rd1 = (insn >> 16) & 0xf;
1711 gen_op_iwmmxt_movq_M0_wRn(rd0);
1712 if (insn & (1 << 21))
1713 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1714 else
1715 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1716 gen_op_iwmmxt_movq_wRn_M0(wrd);
1717 gen_op_iwmmxt_set_mup();
1718 break;
1719 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1720 wrd = (insn >> 12) & 0xf;
1721 rd0 = (insn >> 16) & 0xf;
1722 rd1 = (insn >> 0) & 0xf;
1723 gen_op_iwmmxt_movq_M0_wRn(rd0);
1724 switch ((insn >> 22) & 3) {
1725 case 0:
1726 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1727 break;
1728 case 1:
1729 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1730 break;
1731 case 2:
1732 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1733 break;
1734 case 3:
1735 return 1;
1737 gen_op_iwmmxt_movq_wRn_M0(wrd);
1738 gen_op_iwmmxt_set_mup();
1739 gen_op_iwmmxt_set_cup();
1740 break;
1741 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1742 wrd = (insn >> 12) & 0xf;
1743 rd0 = (insn >> 16) & 0xf;
1744 rd1 = (insn >> 0) & 0xf;
1745 gen_op_iwmmxt_movq_M0_wRn(rd0);
1746 switch ((insn >> 22) & 3) {
1747 case 0:
1748 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1749 break;
1750 case 1:
1751 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1752 break;
1753 case 2:
1754 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1755 break;
1756 case 3:
1757 return 1;
1759 gen_op_iwmmxt_movq_wRn_M0(wrd);
1760 gen_op_iwmmxt_set_mup();
1761 gen_op_iwmmxt_set_cup();
1762 break;
1763 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1764 wrd = (insn >> 12) & 0xf;
1765 rd0 = (insn >> 16) & 0xf;
1766 rd1 = (insn >> 0) & 0xf;
1767 gen_op_iwmmxt_movq_M0_wRn(rd0);
1768 if (insn & (1 << 22))
1769 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1770 else
1771 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1772 if (!(insn & (1 << 20)))
1773 gen_op_iwmmxt_addl_M0_wRn(wrd);
1774 gen_op_iwmmxt_movq_wRn_M0(wrd);
1775 gen_op_iwmmxt_set_mup();
1776 break;
1777 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1778 wrd = (insn >> 12) & 0xf;
1779 rd0 = (insn >> 16) & 0xf;
1780 rd1 = (insn >> 0) & 0xf;
1781 gen_op_iwmmxt_movq_M0_wRn(rd0);
1782 if (insn & (1 << 21)) {
1783 if (insn & (1 << 20))
1784 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1785 else
1786 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1787 } else {
1788 if (insn & (1 << 20))
1789 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1790 else
1791 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1793 gen_op_iwmmxt_movq_wRn_M0(wrd);
1794 gen_op_iwmmxt_set_mup();
1795 break;
1796 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1797 wrd = (insn >> 12) & 0xf;
1798 rd0 = (insn >> 16) & 0xf;
1799 rd1 = (insn >> 0) & 0xf;
1800 gen_op_iwmmxt_movq_M0_wRn(rd0);
1801 if (insn & (1 << 21))
1802 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1803 else
1804 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1805 if (!(insn & (1 << 20))) {
1806 iwmmxt_load_reg(cpu_V1, wrd);
1807 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1809 gen_op_iwmmxt_movq_wRn_M0(wrd);
1810 gen_op_iwmmxt_set_mup();
1811 break;
1812 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1813 wrd = (insn >> 12) & 0xf;
1814 rd0 = (insn >> 16) & 0xf;
1815 rd1 = (insn >> 0) & 0xf;
1816 gen_op_iwmmxt_movq_M0_wRn(rd0);
1817 switch ((insn >> 22) & 3) {
1818 case 0:
1819 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1820 break;
1821 case 1:
1822 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1823 break;
1824 case 2:
1825 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1826 break;
1827 case 3:
1828 return 1;
1830 gen_op_iwmmxt_movq_wRn_M0(wrd);
1831 gen_op_iwmmxt_set_mup();
1832 gen_op_iwmmxt_set_cup();
1833 break;
1834 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1835 wrd = (insn >> 12) & 0xf;
1836 rd0 = (insn >> 16) & 0xf;
1837 rd1 = (insn >> 0) & 0xf;
1838 gen_op_iwmmxt_movq_M0_wRn(rd0);
1839 if (insn & (1 << 22)) {
1840 if (insn & (1 << 20))
1841 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1842 else
1843 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1844 } else {
1845 if (insn & (1 << 20))
1846 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1847 else
1848 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd);
1851 gen_op_iwmmxt_set_mup();
1852 gen_op_iwmmxt_set_cup();
1853 break;
1854 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1855 wrd = (insn >> 12) & 0xf;
1856 rd0 = (insn >> 16) & 0xf;
1857 rd1 = (insn >> 0) & 0xf;
1858 gen_op_iwmmxt_movq_M0_wRn(rd0);
1859 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1860 tcg_gen_andi_i32(tmp, tmp, 7);
1861 iwmmxt_load_reg(cpu_V1, rd1);
1862 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1863 tcg_temp_free_i32(tmp);
1864 gen_op_iwmmxt_movq_wRn_M0(wrd);
1865 gen_op_iwmmxt_set_mup();
1866 break;
1867 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1868 if (((insn >> 6) & 3) == 3)
1869 return 1;
1870 rd = (insn >> 12) & 0xf;
1871 wrd = (insn >> 16) & 0xf;
1872 tmp = load_reg(s, rd);
1873 gen_op_iwmmxt_movq_M0_wRn(wrd);
1874 switch ((insn >> 6) & 3) {
1875 case 0:
1876 tmp2 = tcg_const_i32(0xff);
1877 tmp3 = tcg_const_i32((insn & 7) << 3);
1878 break;
1879 case 1:
1880 tmp2 = tcg_const_i32(0xffff);
1881 tmp3 = tcg_const_i32((insn & 3) << 4);
1882 break;
1883 case 2:
1884 tmp2 = tcg_const_i32(0xffffffff);
1885 tmp3 = tcg_const_i32((insn & 1) << 5);
1886 break;
1887 default:
1888 tmp2 = NULL;
1889 tmp3 = NULL;
1891 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1892 tcg_temp_free_i32(tmp3);
1893 tcg_temp_free_i32(tmp2);
1894 tcg_temp_free_i32(tmp);
1895 gen_op_iwmmxt_movq_wRn_M0(wrd);
1896 gen_op_iwmmxt_set_mup();
1897 break;
1898 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1899 rd = (insn >> 12) & 0xf;
1900 wrd = (insn >> 16) & 0xf;
1901 if (rd == 15 || ((insn >> 22) & 3) == 3)
1902 return 1;
1903 gen_op_iwmmxt_movq_M0_wRn(wrd);
1904 tmp = tcg_temp_new_i32();
1905 switch ((insn >> 22) & 3) {
1906 case 0:
1907 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1908 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1909 if (insn & 8) {
1910 tcg_gen_ext8s_i32(tmp, tmp);
1911 } else {
1912 tcg_gen_andi_i32(tmp, tmp, 0xff);
1914 break;
1915 case 1:
1916 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1917 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1918 if (insn & 8) {
1919 tcg_gen_ext16s_i32(tmp, tmp);
1920 } else {
1921 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1923 break;
1924 case 2:
1925 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1926 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1927 break;
1929 store_reg(s, rd, tmp);
1930 break;
1931 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1932 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1933 return 1;
1934 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1935 switch ((insn >> 22) & 3) {
1936 case 0:
1937 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1938 break;
1939 case 1:
1940 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1941 break;
1942 case 2:
1943 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1944 break;
1946 tcg_gen_shli_i32(tmp, tmp, 28);
1947 gen_set_nzcv(tmp);
1948 tcg_temp_free_i32(tmp);
1949 break;
1950 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1951 if (((insn >> 6) & 3) == 3)
1952 return 1;
1953 rd = (insn >> 12) & 0xf;
1954 wrd = (insn >> 16) & 0xf;
1955 tmp = load_reg(s, rd);
1956 switch ((insn >> 6) & 3) {
1957 case 0:
1958 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1959 break;
1960 case 1:
1961 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1962 break;
1963 case 2:
1964 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1965 break;
1967 tcg_temp_free_i32(tmp);
1968 gen_op_iwmmxt_movq_wRn_M0(wrd);
1969 gen_op_iwmmxt_set_mup();
1970 break;
1971 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1972 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1973 return 1;
1974 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1975 tmp2 = tcg_temp_new_i32();
1976 tcg_gen_mov_i32(tmp2, tmp);
1977 switch ((insn >> 22) & 3) {
1978 case 0:
1979 for (i = 0; i < 7; i ++) {
1980 tcg_gen_shli_i32(tmp2, tmp2, 4);
1981 tcg_gen_and_i32(tmp, tmp, tmp2);
1983 break;
1984 case 1:
1985 for (i = 0; i < 3; i ++) {
1986 tcg_gen_shli_i32(tmp2, tmp2, 8);
1987 tcg_gen_and_i32(tmp, tmp, tmp2);
1989 break;
1990 case 2:
1991 tcg_gen_shli_i32(tmp2, tmp2, 16);
1992 tcg_gen_and_i32(tmp, tmp, tmp2);
1993 break;
1995 gen_set_nzcv(tmp);
1996 tcg_temp_free_i32(tmp2);
1997 tcg_temp_free_i32(tmp);
1998 break;
1999 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2000 wrd = (insn >> 12) & 0xf;
2001 rd0 = (insn >> 16) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0);
2003 switch ((insn >> 22) & 3) {
2004 case 0:
2005 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2006 break;
2007 case 1:
2008 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2009 break;
2010 case 2:
2011 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2012 break;
2013 case 3:
2014 return 1;
2016 gen_op_iwmmxt_movq_wRn_M0(wrd);
2017 gen_op_iwmmxt_set_mup();
2018 break;
2019 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2020 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2021 return 1;
2022 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2023 tmp2 = tcg_temp_new_i32();
2024 tcg_gen_mov_i32(tmp2, tmp);
2025 switch ((insn >> 22) & 3) {
2026 case 0:
2027 for (i = 0; i < 7; i ++) {
2028 tcg_gen_shli_i32(tmp2, tmp2, 4);
2029 tcg_gen_or_i32(tmp, tmp, tmp2);
2031 break;
2032 case 1:
2033 for (i = 0; i < 3; i ++) {
2034 tcg_gen_shli_i32(tmp2, tmp2, 8);
2035 tcg_gen_or_i32(tmp, tmp, tmp2);
2037 break;
2038 case 2:
2039 tcg_gen_shli_i32(tmp2, tmp2, 16);
2040 tcg_gen_or_i32(tmp, tmp, tmp2);
2041 break;
2043 gen_set_nzcv(tmp);
2044 tcg_temp_free_i32(tmp2);
2045 tcg_temp_free_i32(tmp);
2046 break;
2047 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2048 rd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 16) & 0xf;
2050 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2051 return 1;
2052 gen_op_iwmmxt_movq_M0_wRn(rd0);
2053 tmp = tcg_temp_new_i32();
2054 switch ((insn >> 22) & 3) {
2055 case 0:
2056 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2057 break;
2058 case 1:
2059 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2060 break;
2061 case 2:
2062 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2063 break;
2065 store_reg(s, rd, tmp);
2066 break;
2067 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2068 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2069 wrd = (insn >> 12) & 0xf;
2070 rd0 = (insn >> 16) & 0xf;
2071 rd1 = (insn >> 0) & 0xf;
2072 gen_op_iwmmxt_movq_M0_wRn(rd0);
2073 switch ((insn >> 22) & 3) {
2074 case 0:
2075 if (insn & (1 << 21))
2076 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2077 else
2078 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2079 break;
2080 case 1:
2081 if (insn & (1 << 21))
2082 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2083 else
2084 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2085 break;
2086 case 2:
2087 if (insn & (1 << 21))
2088 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2089 else
2090 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2091 break;
2092 case 3:
2093 return 1;
2095 gen_op_iwmmxt_movq_wRn_M0(wrd);
2096 gen_op_iwmmxt_set_mup();
2097 gen_op_iwmmxt_set_cup();
2098 break;
2099 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2100 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2101 wrd = (insn >> 12) & 0xf;
2102 rd0 = (insn >> 16) & 0xf;
2103 gen_op_iwmmxt_movq_M0_wRn(rd0);
2104 switch ((insn >> 22) & 3) {
2105 case 0:
2106 if (insn & (1 << 21))
2107 gen_op_iwmmxt_unpacklsb_M0();
2108 else
2109 gen_op_iwmmxt_unpacklub_M0();
2110 break;
2111 case 1:
2112 if (insn & (1 << 21))
2113 gen_op_iwmmxt_unpacklsw_M0();
2114 else
2115 gen_op_iwmmxt_unpackluw_M0();
2116 break;
2117 case 2:
2118 if (insn & (1 << 21))
2119 gen_op_iwmmxt_unpacklsl_M0();
2120 else
2121 gen_op_iwmmxt_unpacklul_M0();
2122 break;
2123 case 3:
2124 return 1;
2126 gen_op_iwmmxt_movq_wRn_M0(wrd);
2127 gen_op_iwmmxt_set_mup();
2128 gen_op_iwmmxt_set_cup();
2129 break;
2130 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2131 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2132 wrd = (insn >> 12) & 0xf;
2133 rd0 = (insn >> 16) & 0xf;
2134 gen_op_iwmmxt_movq_M0_wRn(rd0);
2135 switch ((insn >> 22) & 3) {
2136 case 0:
2137 if (insn & (1 << 21))
2138 gen_op_iwmmxt_unpackhsb_M0();
2139 else
2140 gen_op_iwmmxt_unpackhub_M0();
2141 break;
2142 case 1:
2143 if (insn & (1 << 21))
2144 gen_op_iwmmxt_unpackhsw_M0();
2145 else
2146 gen_op_iwmmxt_unpackhuw_M0();
2147 break;
2148 case 2:
2149 if (insn & (1 << 21))
2150 gen_op_iwmmxt_unpackhsl_M0();
2151 else
2152 gen_op_iwmmxt_unpackhul_M0();
2153 break;
2154 case 3:
2155 return 1;
2157 gen_op_iwmmxt_movq_wRn_M0(wrd);
2158 gen_op_iwmmxt_set_mup();
2159 gen_op_iwmmxt_set_cup();
2160 break;
2161 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2162 case 0x214: case 0x614: case 0xa14: case 0xe14:
2163 if (((insn >> 22) & 3) == 0)
2164 return 1;
2165 wrd = (insn >> 12) & 0xf;
2166 rd0 = (insn >> 16) & 0xf;
2167 gen_op_iwmmxt_movq_M0_wRn(rd0);
2168 tmp = tcg_temp_new_i32();
2169 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2170 tcg_temp_free_i32(tmp);
2171 return 1;
2173 switch ((insn >> 22) & 3) {
2174 case 1:
2175 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2176 break;
2177 case 2:
2178 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2179 break;
2180 case 3:
2181 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2182 break;
2184 tcg_temp_free_i32(tmp);
2185 gen_op_iwmmxt_movq_wRn_M0(wrd);
2186 gen_op_iwmmxt_set_mup();
2187 gen_op_iwmmxt_set_cup();
2188 break;
2189 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2190 case 0x014: case 0x414: case 0x814: case 0xc14:
2191 if (((insn >> 22) & 3) == 0)
2192 return 1;
2193 wrd = (insn >> 12) & 0xf;
2194 rd0 = (insn >> 16) & 0xf;
2195 gen_op_iwmmxt_movq_M0_wRn(rd0);
2196 tmp = tcg_temp_new_i32();
2197 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2198 tcg_temp_free_i32(tmp);
2199 return 1;
2201 switch ((insn >> 22) & 3) {
2202 case 1:
2203 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2204 break;
2205 case 2:
2206 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2207 break;
2208 case 3:
2209 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2210 break;
2212 tcg_temp_free_i32(tmp);
2213 gen_op_iwmmxt_movq_wRn_M0(wrd);
2214 gen_op_iwmmxt_set_mup();
2215 gen_op_iwmmxt_set_cup();
2216 break;
2217 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2218 case 0x114: case 0x514: case 0x914: case 0xd14:
2219 if (((insn >> 22) & 3) == 0)
2220 return 1;
2221 wrd = (insn >> 12) & 0xf;
2222 rd0 = (insn >> 16) & 0xf;
2223 gen_op_iwmmxt_movq_M0_wRn(rd0);
2224 tmp = tcg_temp_new_i32();
2225 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2226 tcg_temp_free_i32(tmp);
2227 return 1;
2229 switch ((insn >> 22) & 3) {
2230 case 1:
2231 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2232 break;
2233 case 2:
2234 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2235 break;
2236 case 3:
2237 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2238 break;
2240 tcg_temp_free_i32(tmp);
2241 gen_op_iwmmxt_movq_wRn_M0(wrd);
2242 gen_op_iwmmxt_set_mup();
2243 gen_op_iwmmxt_set_cup();
2244 break;
2245 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2246 case 0x314: case 0x714: case 0xb14: case 0xf14:
2247 if (((insn >> 22) & 3) == 0)
2248 return 1;
2249 wrd = (insn >> 12) & 0xf;
2250 rd0 = (insn >> 16) & 0xf;
2251 gen_op_iwmmxt_movq_M0_wRn(rd0);
2252 tmp = tcg_temp_new_i32();
2253 switch ((insn >> 22) & 3) {
2254 case 1:
2255 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2256 tcg_temp_free_i32(tmp);
2257 return 1;
2259 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2260 break;
2261 case 2:
2262 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2263 tcg_temp_free_i32(tmp);
2264 return 1;
2266 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2267 break;
2268 case 3:
2269 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2270 tcg_temp_free_i32(tmp);
2271 return 1;
2273 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2274 break;
2276 tcg_temp_free_i32(tmp);
2277 gen_op_iwmmxt_movq_wRn_M0(wrd);
2278 gen_op_iwmmxt_set_mup();
2279 gen_op_iwmmxt_set_cup();
2280 break;
2281 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2282 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2283 wrd = (insn >> 12) & 0xf;
2284 rd0 = (insn >> 16) & 0xf;
2285 rd1 = (insn >> 0) & 0xf;
2286 gen_op_iwmmxt_movq_M0_wRn(rd0);
2287 switch ((insn >> 22) & 3) {
2288 case 0:
2289 if (insn & (1 << 21))
2290 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2291 else
2292 gen_op_iwmmxt_minub_M0_wRn(rd1);
2293 break;
2294 case 1:
2295 if (insn & (1 << 21))
2296 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2297 else
2298 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2299 break;
2300 case 2:
2301 if (insn & (1 << 21))
2302 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2303 else
2304 gen_op_iwmmxt_minul_M0_wRn(rd1);
2305 break;
2306 case 3:
2307 return 1;
2309 gen_op_iwmmxt_movq_wRn_M0(wrd);
2310 gen_op_iwmmxt_set_mup();
2311 break;
2312 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2313 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2314 wrd = (insn >> 12) & 0xf;
2315 rd0 = (insn >> 16) & 0xf;
2316 rd1 = (insn >> 0) & 0xf;
2317 gen_op_iwmmxt_movq_M0_wRn(rd0);
2318 switch ((insn >> 22) & 3) {
2319 case 0:
2320 if (insn & (1 << 21))
2321 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2322 else
2323 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2324 break;
2325 case 1:
2326 if (insn & (1 << 21))
2327 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2328 else
2329 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2330 break;
2331 case 2:
2332 if (insn & (1 << 21))
2333 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2334 else
2335 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2336 break;
2337 case 3:
2338 return 1;
2340 gen_op_iwmmxt_movq_wRn_M0(wrd);
2341 gen_op_iwmmxt_set_mup();
2342 break;
2343 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2344 case 0x402: case 0x502: case 0x602: case 0x702:
2345 wrd = (insn >> 12) & 0xf;
2346 rd0 = (insn >> 16) & 0xf;
2347 rd1 = (insn >> 0) & 0xf;
2348 gen_op_iwmmxt_movq_M0_wRn(rd0);
2349 tmp = tcg_const_i32((insn >> 20) & 3);
2350 iwmmxt_load_reg(cpu_V1, rd1);
2351 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2352 tcg_temp_free_i32(tmp);
2353 gen_op_iwmmxt_movq_wRn_M0(wrd);
2354 gen_op_iwmmxt_set_mup();
2355 break;
2356 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2357 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2358 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2359 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
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 >> 20) & 0xf) {
2365 case 0x0:
2366 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2367 break;
2368 case 0x1:
2369 gen_op_iwmmxt_subub_M0_wRn(rd1);
2370 break;
2371 case 0x3:
2372 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2373 break;
2374 case 0x4:
2375 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2376 break;
2377 case 0x5:
2378 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2379 break;
2380 case 0x7:
2381 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2382 break;
2383 case 0x8:
2384 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2385 break;
2386 case 0x9:
2387 gen_op_iwmmxt_subul_M0_wRn(rd1);
2388 break;
2389 case 0xb:
2390 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2391 break;
2392 default:
2393 return 1;
2395 gen_op_iwmmxt_movq_wRn_M0(wrd);
2396 gen_op_iwmmxt_set_mup();
2397 gen_op_iwmmxt_set_cup();
2398 break;
2399 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2400 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2401 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2402 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2403 wrd = (insn >> 12) & 0xf;
2404 rd0 = (insn >> 16) & 0xf;
2405 gen_op_iwmmxt_movq_M0_wRn(rd0);
2406 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2407 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2408 tcg_temp_free_i32(tmp);
2409 gen_op_iwmmxt_movq_wRn_M0(wrd);
2410 gen_op_iwmmxt_set_mup();
2411 gen_op_iwmmxt_set_cup();
2412 break;
2413 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2414 case 0x418: case 0x518: case 0x618: case 0x718:
2415 case 0x818: case 0x918: case 0xa18: case 0xb18:
2416 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2417 wrd = (insn >> 12) & 0xf;
2418 rd0 = (insn >> 16) & 0xf;
2419 rd1 = (insn >> 0) & 0xf;
2420 gen_op_iwmmxt_movq_M0_wRn(rd0);
2421 switch ((insn >> 20) & 0xf) {
2422 case 0x0:
2423 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2424 break;
2425 case 0x1:
2426 gen_op_iwmmxt_addub_M0_wRn(rd1);
2427 break;
2428 case 0x3:
2429 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2430 break;
2431 case 0x4:
2432 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2433 break;
2434 case 0x5:
2435 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2436 break;
2437 case 0x7:
2438 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2439 break;
2440 case 0x8:
2441 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2442 break;
2443 case 0x9:
2444 gen_op_iwmmxt_addul_M0_wRn(rd1);
2445 break;
2446 case 0xb:
2447 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2448 break;
2449 default:
2450 return 1;
2452 gen_op_iwmmxt_movq_wRn_M0(wrd);
2453 gen_op_iwmmxt_set_mup();
2454 gen_op_iwmmxt_set_cup();
2455 break;
2456 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2457 case 0x408: case 0x508: case 0x608: case 0x708:
2458 case 0x808: case 0x908: case 0xa08: case 0xb08:
2459 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2460 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2461 return 1;
2462 wrd = (insn >> 12) & 0xf;
2463 rd0 = (insn >> 16) & 0xf;
2464 rd1 = (insn >> 0) & 0xf;
2465 gen_op_iwmmxt_movq_M0_wRn(rd0);
2466 switch ((insn >> 22) & 3) {
2467 case 1:
2468 if (insn & (1 << 21))
2469 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2470 else
2471 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2472 break;
2473 case 2:
2474 if (insn & (1 << 21))
2475 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2476 else
2477 gen_op_iwmmxt_packul_M0_wRn(rd1);
2478 break;
2479 case 3:
2480 if (insn & (1 << 21))
2481 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2482 else
2483 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2484 break;
2486 gen_op_iwmmxt_movq_wRn_M0(wrd);
2487 gen_op_iwmmxt_set_mup();
2488 gen_op_iwmmxt_set_cup();
2489 break;
2490 case 0x201: case 0x203: case 0x205: case 0x207:
2491 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2492 case 0x211: case 0x213: case 0x215: case 0x217:
2493 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2494 wrd = (insn >> 5) & 0xf;
2495 rd0 = (insn >> 12) & 0xf;
2496 rd1 = (insn >> 0) & 0xf;
2497 if (rd0 == 0xf || rd1 == 0xf)
2498 return 1;
2499 gen_op_iwmmxt_movq_M0_wRn(wrd);
2500 tmp = load_reg(s, rd0);
2501 tmp2 = load_reg(s, rd1);
2502 switch ((insn >> 16) & 0xf) {
2503 case 0x0: /* TMIA */
2504 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2505 break;
2506 case 0x8: /* TMIAPH */
2507 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2508 break;
2509 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2510 if (insn & (1 << 16))
2511 tcg_gen_shri_i32(tmp, tmp, 16);
2512 if (insn & (1 << 17))
2513 tcg_gen_shri_i32(tmp2, tmp2, 16);
2514 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2515 break;
2516 default:
2517 tcg_temp_free_i32(tmp2);
2518 tcg_temp_free_i32(tmp);
2519 return 1;
2521 tcg_temp_free_i32(tmp2);
2522 tcg_temp_free_i32(tmp);
2523 gen_op_iwmmxt_movq_wRn_M0(wrd);
2524 gen_op_iwmmxt_set_mup();
2525 break;
2526 default:
2527 return 1;
2530 return 0;
2533 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2534 (ie. an undefined instruction). */
2535 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2537 int acc, rd0, rd1, rdhi, rdlo;
2538 TCGv_i32 tmp, tmp2;
2540 if ((insn & 0x0ff00f10) == 0x0e200010) {
2541 /* Multiply with Internal Accumulate Format */
2542 rd0 = (insn >> 12) & 0xf;
2543 rd1 = insn & 0xf;
2544 acc = (insn >> 5) & 7;
2546 if (acc != 0)
2547 return 1;
2549 tmp = load_reg(s, rd0);
2550 tmp2 = load_reg(s, rd1);
2551 switch ((insn >> 16) & 0xf) {
2552 case 0x0: /* MIA */
2553 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2554 break;
2555 case 0x8: /* MIAPH */
2556 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2557 break;
2558 case 0xc: /* MIABB */
2559 case 0xd: /* MIABT */
2560 case 0xe: /* MIATB */
2561 case 0xf: /* MIATT */
2562 if (insn & (1 << 16))
2563 tcg_gen_shri_i32(tmp, tmp, 16);
2564 if (insn & (1 << 17))
2565 tcg_gen_shri_i32(tmp2, tmp2, 16);
2566 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2567 break;
2568 default:
2569 return 1;
2571 tcg_temp_free_i32(tmp2);
2572 tcg_temp_free_i32(tmp);
2574 gen_op_iwmmxt_movq_wRn_M0(acc);
2575 return 0;
2578 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2579 /* Internal Accumulator Access Format */
2580 rdhi = (insn >> 16) & 0xf;
2581 rdlo = (insn >> 12) & 0xf;
2582 acc = insn & 7;
2584 if (acc != 0)
2585 return 1;
2587 if (insn & ARM_CP_RW_BIT) { /* MRA */
2588 iwmmxt_load_reg(cpu_V0, acc);
2589 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2590 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2591 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2592 } else { /* MAR */
2593 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2594 iwmmxt_store_reg(cpu_V0, acc);
2596 return 0;
2599 return 1;
2602 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2604 #ifndef CONFIG_USER_ONLY
2605 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2606 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2607 #else
2608 return true;
2609 #endif
2612 static void gen_goto_ptr(void)
2614 tcg_gen_lookup_and_goto_ptr();
2617 /* This will end the TB but doesn't guarantee we'll return to
2618 * cpu_loop_exec. Any live exit_requests will be processed as we
2619 * enter the next TB.
2621 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2623 if (use_goto_tb(s, dest)) {
2624 tcg_gen_goto_tb(n);
2625 gen_set_pc_im(s, dest);
2626 tcg_gen_exit_tb(s->base.tb, n);
2627 } else {
2628 gen_set_pc_im(s, dest);
2629 gen_goto_ptr();
2631 s->base.is_jmp = DISAS_NORETURN;
2634 /* Jump, specifying which TB number to use if we gen_goto_tb() */
2635 static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
2637 if (unlikely(is_singlestepping(s))) {
2638 /* An indirect jump so that we still trigger the debug exception. */
2639 gen_set_pc_im(s, dest);
2640 s->base.is_jmp = DISAS_JUMP;
2641 } else {
2642 gen_goto_tb(s, tbno, dest);
2646 static inline void gen_jmp(DisasContext *s, uint32_t dest)
2648 gen_jmp_tb(s, dest, 0);
2651 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2653 if (x)
2654 tcg_gen_sari_i32(t0, t0, 16);
2655 else
2656 gen_sxth(t0);
2657 if (y)
2658 tcg_gen_sari_i32(t1, t1, 16);
2659 else
2660 gen_sxth(t1);
2661 tcg_gen_mul_i32(t0, t0, t1);
2664 /* Return the mask of PSR bits set by a MSR instruction. */
2665 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2667 uint32_t mask = 0;
2669 if (flags & (1 << 0)) {
2670 mask |= 0xff;
2672 if (flags & (1 << 1)) {
2673 mask |= 0xff00;
2675 if (flags & (1 << 2)) {
2676 mask |= 0xff0000;
2678 if (flags & (1 << 3)) {
2679 mask |= 0xff000000;
2682 /* Mask out undefined and reserved bits. */
2683 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2685 /* Mask out execution state. */
2686 if (!spsr) {
2687 mask &= ~CPSR_EXEC;
2690 /* Mask out privileged bits. */
2691 if (IS_USER(s)) {
2692 mask &= CPSR_USER;
2694 return mask;
2697 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2698 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2700 TCGv_i32 tmp;
2701 if (spsr) {
2702 /* ??? This is also undefined in system mode. */
2703 if (IS_USER(s))
2704 return 1;
2706 tmp = load_cpu_field(spsr);
2707 tcg_gen_andi_i32(tmp, tmp, ~mask);
2708 tcg_gen_andi_i32(t0, t0, mask);
2709 tcg_gen_or_i32(tmp, tmp, t0);
2710 store_cpu_field(tmp, spsr);
2711 } else {
2712 gen_set_cpsr(t0, mask);
2714 tcg_temp_free_i32(t0);
2715 gen_lookup_tb(s);
2716 return 0;
2719 /* Returns nonzero if access to the PSR is not permitted. */
2720 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2722 TCGv_i32 tmp;
2723 tmp = tcg_temp_new_i32();
2724 tcg_gen_movi_i32(tmp, val);
2725 return gen_set_psr(s, mask, spsr, tmp);
2728 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2729 int *tgtmode, int *regno)
2731 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2732 * the target mode and register number, and identify the various
2733 * unpredictable cases.
2734 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2735 * + executed in user mode
2736 * + using R15 as the src/dest register
2737 * + accessing an unimplemented register
2738 * + accessing a register that's inaccessible at current PL/security state*
2739 * + accessing a register that you could access with a different insn
2740 * We choose to UNDEF in all these cases.
2741 * Since we don't know which of the various AArch32 modes we are in
2742 * we have to defer some checks to runtime.
2743 * Accesses to Monitor mode registers from Secure EL1 (which implies
2744 * that EL3 is AArch64) must trap to EL3.
2746 * If the access checks fail this function will emit code to take
2747 * an exception and return false. Otherwise it will return true,
2748 * and set *tgtmode and *regno appropriately.
2750 int exc_target = default_exception_el(s);
2752 /* These instructions are present only in ARMv8, or in ARMv7 with the
2753 * Virtualization Extensions.
2755 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2756 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2757 goto undef;
2760 if (IS_USER(s) || rn == 15) {
2761 goto undef;
2764 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2765 * of registers into (r, sysm).
2767 if (r) {
2768 /* SPSRs for other modes */
2769 switch (sysm) {
2770 case 0xe: /* SPSR_fiq */
2771 *tgtmode = ARM_CPU_MODE_FIQ;
2772 break;
2773 case 0x10: /* SPSR_irq */
2774 *tgtmode = ARM_CPU_MODE_IRQ;
2775 break;
2776 case 0x12: /* SPSR_svc */
2777 *tgtmode = ARM_CPU_MODE_SVC;
2778 break;
2779 case 0x14: /* SPSR_abt */
2780 *tgtmode = ARM_CPU_MODE_ABT;
2781 break;
2782 case 0x16: /* SPSR_und */
2783 *tgtmode = ARM_CPU_MODE_UND;
2784 break;
2785 case 0x1c: /* SPSR_mon */
2786 *tgtmode = ARM_CPU_MODE_MON;
2787 break;
2788 case 0x1e: /* SPSR_hyp */
2789 *tgtmode = ARM_CPU_MODE_HYP;
2790 break;
2791 default: /* unallocated */
2792 goto undef;
2794 /* We arbitrarily assign SPSR a register number of 16. */
2795 *regno = 16;
2796 } else {
2797 /* general purpose registers for other modes */
2798 switch (sysm) {
2799 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2800 *tgtmode = ARM_CPU_MODE_USR;
2801 *regno = sysm + 8;
2802 break;
2803 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2804 *tgtmode = ARM_CPU_MODE_FIQ;
2805 *regno = sysm;
2806 break;
2807 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2808 *tgtmode = ARM_CPU_MODE_IRQ;
2809 *regno = sysm & 1 ? 13 : 14;
2810 break;
2811 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2812 *tgtmode = ARM_CPU_MODE_SVC;
2813 *regno = sysm & 1 ? 13 : 14;
2814 break;
2815 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2816 *tgtmode = ARM_CPU_MODE_ABT;
2817 *regno = sysm & 1 ? 13 : 14;
2818 break;
2819 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2820 *tgtmode = ARM_CPU_MODE_UND;
2821 *regno = sysm & 1 ? 13 : 14;
2822 break;
2823 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2824 *tgtmode = ARM_CPU_MODE_MON;
2825 *regno = sysm & 1 ? 13 : 14;
2826 break;
2827 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2828 *tgtmode = ARM_CPU_MODE_HYP;
2829 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2830 *regno = sysm & 1 ? 13 : 17;
2831 break;
2832 default: /* unallocated */
2833 goto undef;
2837 /* Catch the 'accessing inaccessible register' cases we can detect
2838 * at translate time.
2840 switch (*tgtmode) {
2841 case ARM_CPU_MODE_MON:
2842 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2843 goto undef;
2845 if (s->current_el == 1) {
2846 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2847 * then accesses to Mon registers trap to Secure EL2, if it exists,
2848 * otherwise EL3.
2850 TCGv_i32 tcg_el;
2852 if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
2853 dc_isar_feature(aa64_sel2, s)) {
2854 /* Target EL is EL<3 minus SCR_EL3.EEL2> */
2855 tcg_el = load_cpu_field(cp15.scr_el3);
2856 tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
2857 tcg_gen_addi_i32(tcg_el, tcg_el, 3);
2858 } else {
2859 tcg_el = tcg_const_i32(3);
2862 gen_exception_el(s, EXCP_UDEF, syn_uncategorized(), tcg_el);
2863 tcg_temp_free_i32(tcg_el);
2864 return false;
2866 break;
2867 case ARM_CPU_MODE_HYP:
2869 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2870 * (and so we can forbid accesses from EL2 or below). elr_hyp
2871 * can be accessed also from Hyp mode, so forbid accesses from
2872 * EL0 or EL1.
2874 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2875 (s->current_el < 3 && *regno != 17)) {
2876 goto undef;
2878 break;
2879 default:
2880 break;
2883 return true;
2885 undef:
2886 /* If we get here then some access check did not pass */
2887 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2888 syn_uncategorized(), exc_target);
2889 return false;
2892 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2894 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2895 int tgtmode = 0, regno = 0;
2897 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2898 return;
2901 /* Sync state because msr_banked() can raise exceptions */
2902 gen_set_condexec(s);
2903 gen_set_pc_im(s, s->pc_curr);
2904 tcg_reg = load_reg(s, rn);
2905 tcg_tgtmode = tcg_const_i32(tgtmode);
2906 tcg_regno = tcg_const_i32(regno);
2907 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2908 tcg_temp_free_i32(tcg_tgtmode);
2909 tcg_temp_free_i32(tcg_regno);
2910 tcg_temp_free_i32(tcg_reg);
2911 s->base.is_jmp = DISAS_UPDATE_EXIT;
2914 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2916 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2917 int tgtmode = 0, regno = 0;
2919 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2920 return;
2923 /* Sync state because mrs_banked() can raise exceptions */
2924 gen_set_condexec(s);
2925 gen_set_pc_im(s, s->pc_curr);
2926 tcg_reg = tcg_temp_new_i32();
2927 tcg_tgtmode = tcg_const_i32(tgtmode);
2928 tcg_regno = tcg_const_i32(regno);
2929 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2930 tcg_temp_free_i32(tcg_tgtmode);
2931 tcg_temp_free_i32(tcg_regno);
2932 store_reg(s, rn, tcg_reg);
2933 s->base.is_jmp = DISAS_UPDATE_EXIT;
2936 /* Store value to PC as for an exception return (ie don't
2937 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2938 * will do the masking based on the new value of the Thumb bit.
2940 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2942 tcg_gen_mov_i32(cpu_R[15], pc);
2943 tcg_temp_free_i32(pc);
2946 /* Generate a v6 exception return. Marks both values as dead. */
2947 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2949 store_pc_exc_ret(s, pc);
2950 /* The cpsr_write_eret helper will mask the low bits of PC
2951 * appropriately depending on the new Thumb bit, so it must
2952 * be called after storing the new PC.
2954 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2955 gen_io_start();
2957 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2958 tcg_temp_free_i32(cpsr);
2959 /* Must exit loop to check un-masked IRQs */
2960 s->base.is_jmp = DISAS_EXIT;
2963 /* Generate an old-style exception return. Marks pc as dead. */
2964 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2966 gen_rfe(s, pc, load_cpu_field(spsr));
2969 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
2970 uint32_t opr_sz, uint32_t max_sz,
2971 gen_helper_gvec_3_ptr *fn)
2973 TCGv_ptr qc_ptr = tcg_temp_new_ptr();
2975 tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
2976 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
2977 opr_sz, max_sz, 0, fn);
2978 tcg_temp_free_ptr(qc_ptr);
2981 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2982 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2984 static gen_helper_gvec_3_ptr * const fns[2] = {
2985 gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
2987 tcg_debug_assert(vece >= 1 && vece <= 2);
2988 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2991 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2992 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2994 static gen_helper_gvec_3_ptr * const fns[2] = {
2995 gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
2997 tcg_debug_assert(vece >= 1 && vece <= 2);
2998 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
3001 #define GEN_CMP0(NAME, COND) \
3002 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
3004 tcg_gen_setcondi_i32(COND, d, a, 0); \
3005 tcg_gen_neg_i32(d, d); \
3007 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
3009 tcg_gen_setcondi_i64(COND, d, a, 0); \
3010 tcg_gen_neg_i64(d, d); \
3012 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
3014 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
3015 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
3016 tcg_temp_free_vec(zero); \
3018 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
3019 uint32_t opr_sz, uint32_t max_sz) \
3021 const GVecGen2 op[4] = { \
3022 { .fno = gen_helper_gvec_##NAME##0_b, \
3023 .fniv = gen_##NAME##0_vec, \
3024 .opt_opc = vecop_list_cmp, \
3025 .vece = MO_8 }, \
3026 { .fno = gen_helper_gvec_##NAME##0_h, \
3027 .fniv = gen_##NAME##0_vec, \
3028 .opt_opc = vecop_list_cmp, \
3029 .vece = MO_16 }, \
3030 { .fni4 = gen_##NAME##0_i32, \
3031 .fniv = gen_##NAME##0_vec, \
3032 .opt_opc = vecop_list_cmp, \
3033 .vece = MO_32 }, \
3034 { .fni8 = gen_##NAME##0_i64, \
3035 .fniv = gen_##NAME##0_vec, \
3036 .opt_opc = vecop_list_cmp, \
3037 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
3038 .vece = MO_64 }, \
3039 }; \
3040 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
3043 static const TCGOpcode vecop_list_cmp[] = {
3044 INDEX_op_cmp_vec, 0
3047 GEN_CMP0(ceq, TCG_COND_EQ)
3048 GEN_CMP0(cle, TCG_COND_LE)
3049 GEN_CMP0(cge, TCG_COND_GE)
3050 GEN_CMP0(clt, TCG_COND_LT)
3051 GEN_CMP0(cgt, TCG_COND_GT)
3053 #undef GEN_CMP0
3055 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3057 tcg_gen_vec_sar8i_i64(a, a, shift);
3058 tcg_gen_vec_add8_i64(d, d, a);
3061 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3063 tcg_gen_vec_sar16i_i64(a, a, shift);
3064 tcg_gen_vec_add16_i64(d, d, a);
3067 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3069 tcg_gen_sari_i32(a, a, shift);
3070 tcg_gen_add_i32(d, d, a);
3073 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3075 tcg_gen_sari_i64(a, a, shift);
3076 tcg_gen_add_i64(d, d, a);
3079 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3081 tcg_gen_sari_vec(vece, a, a, sh);
3082 tcg_gen_add_vec(vece, d, d, a);
3085 void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3086 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3088 static const TCGOpcode vecop_list[] = {
3089 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3091 static const GVecGen2i ops[4] = {
3092 { .fni8 = gen_ssra8_i64,
3093 .fniv = gen_ssra_vec,
3094 .fno = gen_helper_gvec_ssra_b,
3095 .load_dest = true,
3096 .opt_opc = vecop_list,
3097 .vece = MO_8 },
3098 { .fni8 = gen_ssra16_i64,
3099 .fniv = gen_ssra_vec,
3100 .fno = gen_helper_gvec_ssra_h,
3101 .load_dest = true,
3102 .opt_opc = vecop_list,
3103 .vece = MO_16 },
3104 { .fni4 = gen_ssra32_i32,
3105 .fniv = gen_ssra_vec,
3106 .fno = gen_helper_gvec_ssra_s,
3107 .load_dest = true,
3108 .opt_opc = vecop_list,
3109 .vece = MO_32 },
3110 { .fni8 = gen_ssra64_i64,
3111 .fniv = gen_ssra_vec,
3112 .fno = gen_helper_gvec_ssra_b,
3113 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3114 .opt_opc = vecop_list,
3115 .load_dest = true,
3116 .vece = MO_64 },
3119 /* tszimm encoding produces immediates in the range [1..esize]. */
3120 tcg_debug_assert(shift > 0);
3121 tcg_debug_assert(shift <= (8 << vece));
3124 * Shifts larger than the element size are architecturally valid.
3125 * Signed results in all sign bits.
3127 shift = MIN(shift, (8 << vece) - 1);
3128 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3131 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3133 tcg_gen_vec_shr8i_i64(a, a, shift);
3134 tcg_gen_vec_add8_i64(d, d, a);
3137 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3139 tcg_gen_vec_shr16i_i64(a, a, shift);
3140 tcg_gen_vec_add16_i64(d, d, a);
3143 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3145 tcg_gen_shri_i32(a, a, shift);
3146 tcg_gen_add_i32(d, d, a);
3149 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3151 tcg_gen_shri_i64(a, a, shift);
3152 tcg_gen_add_i64(d, d, a);
3155 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3157 tcg_gen_shri_vec(vece, a, a, sh);
3158 tcg_gen_add_vec(vece, d, d, a);
3161 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3162 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3164 static const TCGOpcode vecop_list[] = {
3165 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3167 static const GVecGen2i ops[4] = {
3168 { .fni8 = gen_usra8_i64,
3169 .fniv = gen_usra_vec,
3170 .fno = gen_helper_gvec_usra_b,
3171 .load_dest = true,
3172 .opt_opc = vecop_list,
3173 .vece = MO_8, },
3174 { .fni8 = gen_usra16_i64,
3175 .fniv = gen_usra_vec,
3176 .fno = gen_helper_gvec_usra_h,
3177 .load_dest = true,
3178 .opt_opc = vecop_list,
3179 .vece = MO_16, },
3180 { .fni4 = gen_usra32_i32,
3181 .fniv = gen_usra_vec,
3182 .fno = gen_helper_gvec_usra_s,
3183 .load_dest = true,
3184 .opt_opc = vecop_list,
3185 .vece = MO_32, },
3186 { .fni8 = gen_usra64_i64,
3187 .fniv = gen_usra_vec,
3188 .fno = gen_helper_gvec_usra_d,
3189 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3190 .load_dest = true,
3191 .opt_opc = vecop_list,
3192 .vece = MO_64, },
3195 /* tszimm encoding produces immediates in the range [1..esize]. */
3196 tcg_debug_assert(shift > 0);
3197 tcg_debug_assert(shift <= (8 << vece));
3200 * Shifts larger than the element size are architecturally valid.
3201 * Unsigned results in all zeros as input to accumulate: nop.
3203 if (shift < (8 << vece)) {
3204 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3205 } else {
3206 /* Nop, but we do need to clear the tail. */
3207 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3212 * Shift one less than the requested amount, and the low bit is
3213 * the rounding bit. For the 8 and 16-bit operations, because we
3214 * mask the low bit, we can perform a normal integer shift instead
3215 * of a vector shift.
3217 static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3219 TCGv_i64 t = tcg_temp_new_i64();
3221 tcg_gen_shri_i64(t, a, sh - 1);
3222 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3223 tcg_gen_vec_sar8i_i64(d, a, sh);
3224 tcg_gen_vec_add8_i64(d, d, t);
3225 tcg_temp_free_i64(t);
3228 static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3230 TCGv_i64 t = tcg_temp_new_i64();
3232 tcg_gen_shri_i64(t, a, sh - 1);
3233 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3234 tcg_gen_vec_sar16i_i64(d, a, sh);
3235 tcg_gen_vec_add16_i64(d, d, t);
3236 tcg_temp_free_i64(t);
3239 static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3241 TCGv_i32 t = tcg_temp_new_i32();
3243 tcg_gen_extract_i32(t, a, sh - 1, 1);
3244 tcg_gen_sari_i32(d, a, sh);
3245 tcg_gen_add_i32(d, d, t);
3246 tcg_temp_free_i32(t);
3249 static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3251 TCGv_i64 t = tcg_temp_new_i64();
3253 tcg_gen_extract_i64(t, a, sh - 1, 1);
3254 tcg_gen_sari_i64(d, a, sh);
3255 tcg_gen_add_i64(d, d, t);
3256 tcg_temp_free_i64(t);
3259 static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3261 TCGv_vec t = tcg_temp_new_vec_matching(d);
3262 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3264 tcg_gen_shri_vec(vece, t, a, sh - 1);
3265 tcg_gen_dupi_vec(vece, ones, 1);
3266 tcg_gen_and_vec(vece, t, t, ones);
3267 tcg_gen_sari_vec(vece, d, a, sh);
3268 tcg_gen_add_vec(vece, d, d, t);
3270 tcg_temp_free_vec(t);
3271 tcg_temp_free_vec(ones);
3274 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3275 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3277 static const TCGOpcode vecop_list[] = {
3278 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3280 static const GVecGen2i ops[4] = {
3281 { .fni8 = gen_srshr8_i64,
3282 .fniv = gen_srshr_vec,
3283 .fno = gen_helper_gvec_srshr_b,
3284 .opt_opc = vecop_list,
3285 .vece = MO_8 },
3286 { .fni8 = gen_srshr16_i64,
3287 .fniv = gen_srshr_vec,
3288 .fno = gen_helper_gvec_srshr_h,
3289 .opt_opc = vecop_list,
3290 .vece = MO_16 },
3291 { .fni4 = gen_srshr32_i32,
3292 .fniv = gen_srshr_vec,
3293 .fno = gen_helper_gvec_srshr_s,
3294 .opt_opc = vecop_list,
3295 .vece = MO_32 },
3296 { .fni8 = gen_srshr64_i64,
3297 .fniv = gen_srshr_vec,
3298 .fno = gen_helper_gvec_srshr_d,
3299 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3300 .opt_opc = vecop_list,
3301 .vece = MO_64 },
3304 /* tszimm encoding produces immediates in the range [1..esize] */
3305 tcg_debug_assert(shift > 0);
3306 tcg_debug_assert(shift <= (8 << vece));
3308 if (shift == (8 << vece)) {
3310 * Shifts larger than the element size are architecturally valid.
3311 * Signed results in all sign bits. With rounding, this produces
3312 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3313 * I.e. always zero.
3315 tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
3316 } else {
3317 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3321 static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3323 TCGv_i64 t = tcg_temp_new_i64();
3325 gen_srshr8_i64(t, a, sh);
3326 tcg_gen_vec_add8_i64(d, d, t);
3327 tcg_temp_free_i64(t);
3330 static void gen_srsra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3332 TCGv_i64 t = tcg_temp_new_i64();
3334 gen_srshr16_i64(t, a, sh);
3335 tcg_gen_vec_add16_i64(d, d, t);
3336 tcg_temp_free_i64(t);
3339 static void gen_srsra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3341 TCGv_i32 t = tcg_temp_new_i32();
3343 gen_srshr32_i32(t, a, sh);
3344 tcg_gen_add_i32(d, d, t);
3345 tcg_temp_free_i32(t);
3348 static void gen_srsra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3350 TCGv_i64 t = tcg_temp_new_i64();
3352 gen_srshr64_i64(t, a, sh);
3353 tcg_gen_add_i64(d, d, t);
3354 tcg_temp_free_i64(t);
3357 static void gen_srsra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3359 TCGv_vec t = tcg_temp_new_vec_matching(d);
3361 gen_srshr_vec(vece, t, a, sh);
3362 tcg_gen_add_vec(vece, d, d, t);
3363 tcg_temp_free_vec(t);
3366 void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3367 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3369 static const TCGOpcode vecop_list[] = {
3370 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3372 static const GVecGen2i ops[4] = {
3373 { .fni8 = gen_srsra8_i64,
3374 .fniv = gen_srsra_vec,
3375 .fno = gen_helper_gvec_srsra_b,
3376 .opt_opc = vecop_list,
3377 .load_dest = true,
3378 .vece = MO_8 },
3379 { .fni8 = gen_srsra16_i64,
3380 .fniv = gen_srsra_vec,
3381 .fno = gen_helper_gvec_srsra_h,
3382 .opt_opc = vecop_list,
3383 .load_dest = true,
3384 .vece = MO_16 },
3385 { .fni4 = gen_srsra32_i32,
3386 .fniv = gen_srsra_vec,
3387 .fno = gen_helper_gvec_srsra_s,
3388 .opt_opc = vecop_list,
3389 .load_dest = true,
3390 .vece = MO_32 },
3391 { .fni8 = gen_srsra64_i64,
3392 .fniv = gen_srsra_vec,
3393 .fno = gen_helper_gvec_srsra_d,
3394 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3395 .opt_opc = vecop_list,
3396 .load_dest = true,
3397 .vece = MO_64 },
3400 /* tszimm encoding produces immediates in the range [1..esize] */
3401 tcg_debug_assert(shift > 0);
3402 tcg_debug_assert(shift <= (8 << vece));
3405 * Shifts larger than the element size are architecturally valid.
3406 * Signed results in all sign bits. With rounding, this produces
3407 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3408 * I.e. always zero. With accumulation, this leaves D unchanged.
3410 if (shift == (8 << vece)) {
3411 /* Nop, but we do need to clear the tail. */
3412 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3413 } else {
3414 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3418 static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3420 TCGv_i64 t = tcg_temp_new_i64();
3422 tcg_gen_shri_i64(t, a, sh - 1);
3423 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3424 tcg_gen_vec_shr8i_i64(d, a, sh);
3425 tcg_gen_vec_add8_i64(d, d, t);
3426 tcg_temp_free_i64(t);
3429 static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3431 TCGv_i64 t = tcg_temp_new_i64();
3433 tcg_gen_shri_i64(t, a, sh - 1);
3434 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3435 tcg_gen_vec_shr16i_i64(d, a, sh);
3436 tcg_gen_vec_add16_i64(d, d, t);
3437 tcg_temp_free_i64(t);
3440 static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3442 TCGv_i32 t = tcg_temp_new_i32();
3444 tcg_gen_extract_i32(t, a, sh - 1, 1);
3445 tcg_gen_shri_i32(d, a, sh);
3446 tcg_gen_add_i32(d, d, t);
3447 tcg_temp_free_i32(t);
3450 static void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3452 TCGv_i64 t = tcg_temp_new_i64();
3454 tcg_gen_extract_i64(t, a, sh - 1, 1);
3455 tcg_gen_shri_i64(d, a, sh);
3456 tcg_gen_add_i64(d, d, t);
3457 tcg_temp_free_i64(t);
3460 static void gen_urshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t shift)
3462 TCGv_vec t = tcg_temp_new_vec_matching(d);
3463 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3465 tcg_gen_shri_vec(vece, t, a, shift - 1);
3466 tcg_gen_dupi_vec(vece, ones, 1);
3467 tcg_gen_and_vec(vece, t, t, ones);
3468 tcg_gen_shri_vec(vece, d, a, shift);
3469 tcg_gen_add_vec(vece, d, d, t);
3471 tcg_temp_free_vec(t);
3472 tcg_temp_free_vec(ones);
3475 void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3476 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3478 static const TCGOpcode vecop_list[] = {
3479 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3481 static const GVecGen2i ops[4] = {
3482 { .fni8 = gen_urshr8_i64,
3483 .fniv = gen_urshr_vec,
3484 .fno = gen_helper_gvec_urshr_b,
3485 .opt_opc = vecop_list,
3486 .vece = MO_8 },
3487 { .fni8 = gen_urshr16_i64,
3488 .fniv = gen_urshr_vec,
3489 .fno = gen_helper_gvec_urshr_h,
3490 .opt_opc = vecop_list,
3491 .vece = MO_16 },
3492 { .fni4 = gen_urshr32_i32,
3493 .fniv = gen_urshr_vec,
3494 .fno = gen_helper_gvec_urshr_s,
3495 .opt_opc = vecop_list,
3496 .vece = MO_32 },
3497 { .fni8 = gen_urshr64_i64,
3498 .fniv = gen_urshr_vec,
3499 .fno = gen_helper_gvec_urshr_d,
3500 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3501 .opt_opc = vecop_list,
3502 .vece = MO_64 },
3505 /* tszimm encoding produces immediates in the range [1..esize] */
3506 tcg_debug_assert(shift > 0);
3507 tcg_debug_assert(shift <= (8 << vece));
3509 if (shift == (8 << vece)) {
3511 * Shifts larger than the element size are architecturally valid.
3512 * Unsigned results in zero. With rounding, this produces a
3513 * copy of the most significant bit.
3515 tcg_gen_gvec_shri(vece, rd_ofs, rm_ofs, shift - 1, opr_sz, max_sz);
3516 } else {
3517 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3521 static void gen_ursra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3523 TCGv_i64 t = tcg_temp_new_i64();
3525 if (sh == 8) {
3526 tcg_gen_vec_shr8i_i64(t, a, 7);
3527 } else {
3528 gen_urshr8_i64(t, a, sh);
3530 tcg_gen_vec_add8_i64(d, d, t);
3531 tcg_temp_free_i64(t);
3534 static void gen_ursra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3536 TCGv_i64 t = tcg_temp_new_i64();
3538 if (sh == 16) {
3539 tcg_gen_vec_shr16i_i64(t, a, 15);
3540 } else {
3541 gen_urshr16_i64(t, a, sh);
3543 tcg_gen_vec_add16_i64(d, d, t);
3544 tcg_temp_free_i64(t);
3547 static void gen_ursra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3549 TCGv_i32 t = tcg_temp_new_i32();
3551 if (sh == 32) {
3552 tcg_gen_shri_i32(t, a, 31);
3553 } else {
3554 gen_urshr32_i32(t, a, sh);
3556 tcg_gen_add_i32(d, d, t);
3557 tcg_temp_free_i32(t);
3560 static void gen_ursra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3562 TCGv_i64 t = tcg_temp_new_i64();
3564 if (sh == 64) {
3565 tcg_gen_shri_i64(t, a, 63);
3566 } else {
3567 gen_urshr64_i64(t, a, sh);
3569 tcg_gen_add_i64(d, d, t);
3570 tcg_temp_free_i64(t);
3573 static void gen_ursra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3575 TCGv_vec t = tcg_temp_new_vec_matching(d);
3577 if (sh == (8 << vece)) {
3578 tcg_gen_shri_vec(vece, t, a, sh - 1);
3579 } else {
3580 gen_urshr_vec(vece, t, a, sh);
3582 tcg_gen_add_vec(vece, d, d, t);
3583 tcg_temp_free_vec(t);
3586 void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3587 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3589 static const TCGOpcode vecop_list[] = {
3590 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3592 static const GVecGen2i ops[4] = {
3593 { .fni8 = gen_ursra8_i64,
3594 .fniv = gen_ursra_vec,
3595 .fno = gen_helper_gvec_ursra_b,
3596 .opt_opc = vecop_list,
3597 .load_dest = true,
3598 .vece = MO_8 },
3599 { .fni8 = gen_ursra16_i64,
3600 .fniv = gen_ursra_vec,
3601 .fno = gen_helper_gvec_ursra_h,
3602 .opt_opc = vecop_list,
3603 .load_dest = true,
3604 .vece = MO_16 },
3605 { .fni4 = gen_ursra32_i32,
3606 .fniv = gen_ursra_vec,
3607 .fno = gen_helper_gvec_ursra_s,
3608 .opt_opc = vecop_list,
3609 .load_dest = true,
3610 .vece = MO_32 },
3611 { .fni8 = gen_ursra64_i64,
3612 .fniv = gen_ursra_vec,
3613 .fno = gen_helper_gvec_ursra_d,
3614 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3615 .opt_opc = vecop_list,
3616 .load_dest = true,
3617 .vece = MO_64 },
3620 /* tszimm encoding produces immediates in the range [1..esize] */
3621 tcg_debug_assert(shift > 0);
3622 tcg_debug_assert(shift <= (8 << vece));
3624 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3627 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3629 uint64_t mask = dup_const(MO_8, 0xff >> shift);
3630 TCGv_i64 t = tcg_temp_new_i64();
3632 tcg_gen_shri_i64(t, a, shift);
3633 tcg_gen_andi_i64(t, t, mask);
3634 tcg_gen_andi_i64(d, d, ~mask);
3635 tcg_gen_or_i64(d, d, t);
3636 tcg_temp_free_i64(t);
3639 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3641 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
3642 TCGv_i64 t = tcg_temp_new_i64();
3644 tcg_gen_shri_i64(t, a, shift);
3645 tcg_gen_andi_i64(t, t, mask);
3646 tcg_gen_andi_i64(d, d, ~mask);
3647 tcg_gen_or_i64(d, d, t);
3648 tcg_temp_free_i64(t);
3651 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3653 tcg_gen_shri_i32(a, a, shift);
3654 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
3657 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3659 tcg_gen_shri_i64(a, a, shift);
3660 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
3663 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3665 TCGv_vec t = tcg_temp_new_vec_matching(d);
3666 TCGv_vec m = tcg_temp_new_vec_matching(d);
3668 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
3669 tcg_gen_shri_vec(vece, t, a, sh);
3670 tcg_gen_and_vec(vece, d, d, m);
3671 tcg_gen_or_vec(vece, d, d, t);
3673 tcg_temp_free_vec(t);
3674 tcg_temp_free_vec(m);
3677 void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3678 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3680 static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
3681 const GVecGen2i ops[4] = {
3682 { .fni8 = gen_shr8_ins_i64,
3683 .fniv = gen_shr_ins_vec,
3684 .fno = gen_helper_gvec_sri_b,
3685 .load_dest = true,
3686 .opt_opc = vecop_list,
3687 .vece = MO_8 },
3688 { .fni8 = gen_shr16_ins_i64,
3689 .fniv = gen_shr_ins_vec,
3690 .fno = gen_helper_gvec_sri_h,
3691 .load_dest = true,
3692 .opt_opc = vecop_list,
3693 .vece = MO_16 },
3694 { .fni4 = gen_shr32_ins_i32,
3695 .fniv = gen_shr_ins_vec,
3696 .fno = gen_helper_gvec_sri_s,
3697 .load_dest = true,
3698 .opt_opc = vecop_list,
3699 .vece = MO_32 },
3700 { .fni8 = gen_shr64_ins_i64,
3701 .fniv = gen_shr_ins_vec,
3702 .fno = gen_helper_gvec_sri_d,
3703 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3704 .load_dest = true,
3705 .opt_opc = vecop_list,
3706 .vece = MO_64 },
3709 /* tszimm encoding produces immediates in the range [1..esize]. */
3710 tcg_debug_assert(shift > 0);
3711 tcg_debug_assert(shift <= (8 << vece));
3713 /* Shift of esize leaves destination unchanged. */
3714 if (shift < (8 << vece)) {
3715 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3716 } else {
3717 /* Nop, but we do need to clear the tail. */
3718 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3722 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3724 uint64_t mask = dup_const(MO_8, 0xff << shift);
3725 TCGv_i64 t = tcg_temp_new_i64();
3727 tcg_gen_shli_i64(t, a, shift);
3728 tcg_gen_andi_i64(t, t, mask);
3729 tcg_gen_andi_i64(d, d, ~mask);
3730 tcg_gen_or_i64(d, d, t);
3731 tcg_temp_free_i64(t);
3734 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3736 uint64_t mask = dup_const(MO_16, 0xffff << shift);
3737 TCGv_i64 t = tcg_temp_new_i64();
3739 tcg_gen_shli_i64(t, a, shift);
3740 tcg_gen_andi_i64(t, t, mask);
3741 tcg_gen_andi_i64(d, d, ~mask);
3742 tcg_gen_or_i64(d, d, t);
3743 tcg_temp_free_i64(t);
3746 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3748 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
3751 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3753 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
3756 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3758 TCGv_vec t = tcg_temp_new_vec_matching(d);
3759 TCGv_vec m = tcg_temp_new_vec_matching(d);
3761 tcg_gen_shli_vec(vece, t, a, sh);
3762 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
3763 tcg_gen_and_vec(vece, d, d, m);
3764 tcg_gen_or_vec(vece, d, d, t);
3766 tcg_temp_free_vec(t);
3767 tcg_temp_free_vec(m);
3770 void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3771 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3773 static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
3774 const GVecGen2i ops[4] = {
3775 { .fni8 = gen_shl8_ins_i64,
3776 .fniv = gen_shl_ins_vec,
3777 .fno = gen_helper_gvec_sli_b,
3778 .load_dest = true,
3779 .opt_opc = vecop_list,
3780 .vece = MO_8 },
3781 { .fni8 = gen_shl16_ins_i64,
3782 .fniv = gen_shl_ins_vec,
3783 .fno = gen_helper_gvec_sli_h,
3784 .load_dest = true,
3785 .opt_opc = vecop_list,
3786 .vece = MO_16 },
3787 { .fni4 = gen_shl32_ins_i32,
3788 .fniv = gen_shl_ins_vec,
3789 .fno = gen_helper_gvec_sli_s,
3790 .load_dest = true,
3791 .opt_opc = vecop_list,
3792 .vece = MO_32 },
3793 { .fni8 = gen_shl64_ins_i64,
3794 .fniv = gen_shl_ins_vec,
3795 .fno = gen_helper_gvec_sli_d,
3796 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3797 .load_dest = true,
3798 .opt_opc = vecop_list,
3799 .vece = MO_64 },
3802 /* tszimm encoding produces immediates in the range [0..esize-1]. */
3803 tcg_debug_assert(shift >= 0);
3804 tcg_debug_assert(shift < (8 << vece));
3806 if (shift == 0) {
3807 tcg_gen_gvec_mov(vece, rd_ofs, rm_ofs, opr_sz, max_sz);
3808 } else {
3809 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3813 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3815 gen_helper_neon_mul_u8(a, a, b);
3816 gen_helper_neon_add_u8(d, d, a);
3819 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3821 gen_helper_neon_mul_u8(a, a, b);
3822 gen_helper_neon_sub_u8(d, d, a);
3825 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3827 gen_helper_neon_mul_u16(a, a, b);
3828 gen_helper_neon_add_u16(d, d, a);
3831 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3833 gen_helper_neon_mul_u16(a, a, b);
3834 gen_helper_neon_sub_u16(d, d, a);
3837 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3839 tcg_gen_mul_i32(a, a, b);
3840 tcg_gen_add_i32(d, d, a);
3843 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3845 tcg_gen_mul_i32(a, a, b);
3846 tcg_gen_sub_i32(d, d, a);
3849 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3851 tcg_gen_mul_i64(a, a, b);
3852 tcg_gen_add_i64(d, d, a);
3855 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3857 tcg_gen_mul_i64(a, a, b);
3858 tcg_gen_sub_i64(d, d, a);
3861 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3863 tcg_gen_mul_vec(vece, a, a, b);
3864 tcg_gen_add_vec(vece, d, d, a);
3867 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3869 tcg_gen_mul_vec(vece, a, a, b);
3870 tcg_gen_sub_vec(vece, d, d, a);
3873 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
3874 * these tables are shared with AArch64 which does support them.
3876 void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3877 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3879 static const TCGOpcode vecop_list[] = {
3880 INDEX_op_mul_vec, INDEX_op_add_vec, 0
3882 static const GVecGen3 ops[4] = {
3883 { .fni4 = gen_mla8_i32,
3884 .fniv = gen_mla_vec,
3885 .load_dest = true,
3886 .opt_opc = vecop_list,
3887 .vece = MO_8 },
3888 { .fni4 = gen_mla16_i32,
3889 .fniv = gen_mla_vec,
3890 .load_dest = true,
3891 .opt_opc = vecop_list,
3892 .vece = MO_16 },
3893 { .fni4 = gen_mla32_i32,
3894 .fniv = gen_mla_vec,
3895 .load_dest = true,
3896 .opt_opc = vecop_list,
3897 .vece = MO_32 },
3898 { .fni8 = gen_mla64_i64,
3899 .fniv = gen_mla_vec,
3900 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3901 .load_dest = true,
3902 .opt_opc = vecop_list,
3903 .vece = MO_64 },
3905 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3908 void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3909 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3911 static const TCGOpcode vecop_list[] = {
3912 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
3914 static const GVecGen3 ops[4] = {
3915 { .fni4 = gen_mls8_i32,
3916 .fniv = gen_mls_vec,
3917 .load_dest = true,
3918 .opt_opc = vecop_list,
3919 .vece = MO_8 },
3920 { .fni4 = gen_mls16_i32,
3921 .fniv = gen_mls_vec,
3922 .load_dest = true,
3923 .opt_opc = vecop_list,
3924 .vece = MO_16 },
3925 { .fni4 = gen_mls32_i32,
3926 .fniv = gen_mls_vec,
3927 .load_dest = true,
3928 .opt_opc = vecop_list,
3929 .vece = MO_32 },
3930 { .fni8 = gen_mls64_i64,
3931 .fniv = gen_mls_vec,
3932 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3933 .load_dest = true,
3934 .opt_opc = vecop_list,
3935 .vece = MO_64 },
3937 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3940 /* CMTST : test is "if (X & Y != 0)". */
3941 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3943 tcg_gen_and_i32(d, a, b);
3944 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
3945 tcg_gen_neg_i32(d, d);
3948 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3950 tcg_gen_and_i64(d, a, b);
3951 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
3952 tcg_gen_neg_i64(d, d);
3955 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3957 tcg_gen_and_vec(vece, d, a, b);
3958 tcg_gen_dupi_vec(vece, a, 0);
3959 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
3962 void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3963 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3965 static const TCGOpcode vecop_list[] = { INDEX_op_cmp_vec, 0 };
3966 static const GVecGen3 ops[4] = {
3967 { .fni4 = gen_helper_neon_tst_u8,
3968 .fniv = gen_cmtst_vec,
3969 .opt_opc = vecop_list,
3970 .vece = MO_8 },
3971 { .fni4 = gen_helper_neon_tst_u16,
3972 .fniv = gen_cmtst_vec,
3973 .opt_opc = vecop_list,
3974 .vece = MO_16 },
3975 { .fni4 = gen_cmtst_i32,
3976 .fniv = gen_cmtst_vec,
3977 .opt_opc = vecop_list,
3978 .vece = MO_32 },
3979 { .fni8 = gen_cmtst_i64,
3980 .fniv = gen_cmtst_vec,
3981 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3982 .opt_opc = vecop_list,
3983 .vece = MO_64 },
3985 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3988 void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
3990 TCGv_i32 lval = tcg_temp_new_i32();
3991 TCGv_i32 rval = tcg_temp_new_i32();
3992 TCGv_i32 lsh = tcg_temp_new_i32();
3993 TCGv_i32 rsh = tcg_temp_new_i32();
3994 TCGv_i32 zero = tcg_const_i32(0);
3995 TCGv_i32 max = tcg_const_i32(32);
3998 * Rely on the TCG guarantee that out of range shifts produce
3999 * unspecified results, not undefined behaviour (i.e. no trap).
4000 * Discard out-of-range results after the fact.
4002 tcg_gen_ext8s_i32(lsh, shift);
4003 tcg_gen_neg_i32(rsh, lsh);
4004 tcg_gen_shl_i32(lval, src, lsh);
4005 tcg_gen_shr_i32(rval, src, rsh);
4006 tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
4007 tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
4009 tcg_temp_free_i32(lval);
4010 tcg_temp_free_i32(rval);
4011 tcg_temp_free_i32(lsh);
4012 tcg_temp_free_i32(rsh);
4013 tcg_temp_free_i32(zero);
4014 tcg_temp_free_i32(max);
4017 void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4019 TCGv_i64 lval = tcg_temp_new_i64();
4020 TCGv_i64 rval = tcg_temp_new_i64();
4021 TCGv_i64 lsh = tcg_temp_new_i64();
4022 TCGv_i64 rsh = tcg_temp_new_i64();
4023 TCGv_i64 zero = tcg_const_i64(0);
4024 TCGv_i64 max = tcg_const_i64(64);
4027 * Rely on the TCG guarantee that out of range shifts produce
4028 * unspecified results, not undefined behaviour (i.e. no trap).
4029 * Discard out-of-range results after the fact.
4031 tcg_gen_ext8s_i64(lsh, shift);
4032 tcg_gen_neg_i64(rsh, lsh);
4033 tcg_gen_shl_i64(lval, src, lsh);
4034 tcg_gen_shr_i64(rval, src, rsh);
4035 tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
4036 tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
4038 tcg_temp_free_i64(lval);
4039 tcg_temp_free_i64(rval);
4040 tcg_temp_free_i64(lsh);
4041 tcg_temp_free_i64(rsh);
4042 tcg_temp_free_i64(zero);
4043 tcg_temp_free_i64(max);
4046 static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
4047 TCGv_vec src, TCGv_vec shift)
4049 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4050 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4051 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4052 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4053 TCGv_vec msk, max;
4055 tcg_gen_neg_vec(vece, rsh, shift);
4056 if (vece == MO_8) {
4057 tcg_gen_mov_vec(lsh, shift);
4058 } else {
4059 msk = tcg_temp_new_vec_matching(dst);
4060 tcg_gen_dupi_vec(vece, msk, 0xff);
4061 tcg_gen_and_vec(vece, lsh, shift, msk);
4062 tcg_gen_and_vec(vece, rsh, rsh, msk);
4063 tcg_temp_free_vec(msk);
4067 * Rely on the TCG guarantee that out of range shifts produce
4068 * unspecified results, not undefined behaviour (i.e. no trap).
4069 * Discard out-of-range results after the fact.
4071 tcg_gen_shlv_vec(vece, lval, src, lsh);
4072 tcg_gen_shrv_vec(vece, rval, src, rsh);
4074 max = tcg_temp_new_vec_matching(dst);
4075 tcg_gen_dupi_vec(vece, max, 8 << vece);
4078 * The choice of LT (signed) and GEU (unsigned) are biased toward
4079 * the instructions of the x86_64 host. For MO_8, the whole byte
4080 * is significant so we must use an unsigned compare; otherwise we
4081 * have already masked to a byte and so a signed compare works.
4082 * Other tcg hosts have a full set of comparisons and do not care.
4084 if (vece == MO_8) {
4085 tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
4086 tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
4087 tcg_gen_andc_vec(vece, lval, lval, lsh);
4088 tcg_gen_andc_vec(vece, rval, rval, rsh);
4089 } else {
4090 tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
4091 tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
4092 tcg_gen_and_vec(vece, lval, lval, lsh);
4093 tcg_gen_and_vec(vece, rval, rval, rsh);
4095 tcg_gen_or_vec(vece, dst, lval, rval);
4097 tcg_temp_free_vec(max);
4098 tcg_temp_free_vec(lval);
4099 tcg_temp_free_vec(rval);
4100 tcg_temp_free_vec(lsh);
4101 tcg_temp_free_vec(rsh);
4104 void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4105 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4107 static const TCGOpcode vecop_list[] = {
4108 INDEX_op_neg_vec, INDEX_op_shlv_vec,
4109 INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
4111 static const GVecGen3 ops[4] = {
4112 { .fniv = gen_ushl_vec,
4113 .fno = gen_helper_gvec_ushl_b,
4114 .opt_opc = vecop_list,
4115 .vece = MO_8 },
4116 { .fniv = gen_ushl_vec,
4117 .fno = gen_helper_gvec_ushl_h,
4118 .opt_opc = vecop_list,
4119 .vece = MO_16 },
4120 { .fni4 = gen_ushl_i32,
4121 .fniv = gen_ushl_vec,
4122 .opt_opc = vecop_list,
4123 .vece = MO_32 },
4124 { .fni8 = gen_ushl_i64,
4125 .fniv = gen_ushl_vec,
4126 .opt_opc = vecop_list,
4127 .vece = MO_64 },
4129 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4132 void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4134 TCGv_i32 lval = tcg_temp_new_i32();
4135 TCGv_i32 rval = tcg_temp_new_i32();
4136 TCGv_i32 lsh = tcg_temp_new_i32();
4137 TCGv_i32 rsh = tcg_temp_new_i32();
4138 TCGv_i32 zero = tcg_const_i32(0);
4139 TCGv_i32 max = tcg_const_i32(31);
4142 * Rely on the TCG guarantee that out of range shifts produce
4143 * unspecified results, not undefined behaviour (i.e. no trap).
4144 * Discard out-of-range results after the fact.
4146 tcg_gen_ext8s_i32(lsh, shift);
4147 tcg_gen_neg_i32(rsh, lsh);
4148 tcg_gen_shl_i32(lval, src, lsh);
4149 tcg_gen_umin_i32(rsh, rsh, max);
4150 tcg_gen_sar_i32(rval, src, rsh);
4151 tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
4152 tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
4154 tcg_temp_free_i32(lval);
4155 tcg_temp_free_i32(rval);
4156 tcg_temp_free_i32(lsh);
4157 tcg_temp_free_i32(rsh);
4158 tcg_temp_free_i32(zero);
4159 tcg_temp_free_i32(max);
4162 void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4164 TCGv_i64 lval = tcg_temp_new_i64();
4165 TCGv_i64 rval = tcg_temp_new_i64();
4166 TCGv_i64 lsh = tcg_temp_new_i64();
4167 TCGv_i64 rsh = tcg_temp_new_i64();
4168 TCGv_i64 zero = tcg_const_i64(0);
4169 TCGv_i64 max = tcg_const_i64(63);
4172 * Rely on the TCG guarantee that out of range shifts produce
4173 * unspecified results, not undefined behaviour (i.e. no trap).
4174 * Discard out-of-range results after the fact.
4176 tcg_gen_ext8s_i64(lsh, shift);
4177 tcg_gen_neg_i64(rsh, lsh);
4178 tcg_gen_shl_i64(lval, src, lsh);
4179 tcg_gen_umin_i64(rsh, rsh, max);
4180 tcg_gen_sar_i64(rval, src, rsh);
4181 tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
4182 tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
4184 tcg_temp_free_i64(lval);
4185 tcg_temp_free_i64(rval);
4186 tcg_temp_free_i64(lsh);
4187 tcg_temp_free_i64(rsh);
4188 tcg_temp_free_i64(zero);
4189 tcg_temp_free_i64(max);
4192 static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
4193 TCGv_vec src, TCGv_vec shift)
4195 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4196 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4197 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4198 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4199 TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
4202 * Rely on the TCG guarantee that out of range shifts produce
4203 * unspecified results, not undefined behaviour (i.e. no trap).
4204 * Discard out-of-range results after the fact.
4206 tcg_gen_neg_vec(vece, rsh, shift);
4207 if (vece == MO_8) {
4208 tcg_gen_mov_vec(lsh, shift);
4209 } else {
4210 tcg_gen_dupi_vec(vece, tmp, 0xff);
4211 tcg_gen_and_vec(vece, lsh, shift, tmp);
4212 tcg_gen_and_vec(vece, rsh, rsh, tmp);
4215 /* Bound rsh so out of bound right shift gets -1. */
4216 tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
4217 tcg_gen_umin_vec(vece, rsh, rsh, tmp);
4218 tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
4220 tcg_gen_shlv_vec(vece, lval, src, lsh);
4221 tcg_gen_sarv_vec(vece, rval, src, rsh);
4223 /* Select in-bound left shift. */
4224 tcg_gen_andc_vec(vece, lval, lval, tmp);
4226 /* Select between left and right shift. */
4227 if (vece == MO_8) {
4228 tcg_gen_dupi_vec(vece, tmp, 0);
4229 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
4230 } else {
4231 tcg_gen_dupi_vec(vece, tmp, 0x80);
4232 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
4235 tcg_temp_free_vec(lval);
4236 tcg_temp_free_vec(rval);
4237 tcg_temp_free_vec(lsh);
4238 tcg_temp_free_vec(rsh);
4239 tcg_temp_free_vec(tmp);
4242 void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4243 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4245 static const TCGOpcode vecop_list[] = {
4246 INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
4247 INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
4249 static const GVecGen3 ops[4] = {
4250 { .fniv = gen_sshl_vec,
4251 .fno = gen_helper_gvec_sshl_b,
4252 .opt_opc = vecop_list,
4253 .vece = MO_8 },
4254 { .fniv = gen_sshl_vec,
4255 .fno = gen_helper_gvec_sshl_h,
4256 .opt_opc = vecop_list,
4257 .vece = MO_16 },
4258 { .fni4 = gen_sshl_i32,
4259 .fniv = gen_sshl_vec,
4260 .opt_opc = vecop_list,
4261 .vece = MO_32 },
4262 { .fni8 = gen_sshl_i64,
4263 .fniv = gen_sshl_vec,
4264 .opt_opc = vecop_list,
4265 .vece = MO_64 },
4267 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4270 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4271 TCGv_vec a, TCGv_vec b)
4273 TCGv_vec x = tcg_temp_new_vec_matching(t);
4274 tcg_gen_add_vec(vece, x, a, b);
4275 tcg_gen_usadd_vec(vece, t, a, b);
4276 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4277 tcg_gen_or_vec(vece, sat, sat, x);
4278 tcg_temp_free_vec(x);
4281 void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4282 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4284 static const TCGOpcode vecop_list[] = {
4285 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4287 static const GVecGen4 ops[4] = {
4288 { .fniv = gen_uqadd_vec,
4289 .fno = gen_helper_gvec_uqadd_b,
4290 .write_aofs = true,
4291 .opt_opc = vecop_list,
4292 .vece = MO_8 },
4293 { .fniv = gen_uqadd_vec,
4294 .fno = gen_helper_gvec_uqadd_h,
4295 .write_aofs = true,
4296 .opt_opc = vecop_list,
4297 .vece = MO_16 },
4298 { .fniv = gen_uqadd_vec,
4299 .fno = gen_helper_gvec_uqadd_s,
4300 .write_aofs = true,
4301 .opt_opc = vecop_list,
4302 .vece = MO_32 },
4303 { .fniv = gen_uqadd_vec,
4304 .fno = gen_helper_gvec_uqadd_d,
4305 .write_aofs = true,
4306 .opt_opc = vecop_list,
4307 .vece = MO_64 },
4309 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4310 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4313 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4314 TCGv_vec a, TCGv_vec b)
4316 TCGv_vec x = tcg_temp_new_vec_matching(t);
4317 tcg_gen_add_vec(vece, x, a, b);
4318 tcg_gen_ssadd_vec(vece, t, a, b);
4319 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4320 tcg_gen_or_vec(vece, sat, sat, x);
4321 tcg_temp_free_vec(x);
4324 void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4325 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4327 static const TCGOpcode vecop_list[] = {
4328 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4330 static const GVecGen4 ops[4] = {
4331 { .fniv = gen_sqadd_vec,
4332 .fno = gen_helper_gvec_sqadd_b,
4333 .opt_opc = vecop_list,
4334 .write_aofs = true,
4335 .vece = MO_8 },
4336 { .fniv = gen_sqadd_vec,
4337 .fno = gen_helper_gvec_sqadd_h,
4338 .opt_opc = vecop_list,
4339 .write_aofs = true,
4340 .vece = MO_16 },
4341 { .fniv = gen_sqadd_vec,
4342 .fno = gen_helper_gvec_sqadd_s,
4343 .opt_opc = vecop_list,
4344 .write_aofs = true,
4345 .vece = MO_32 },
4346 { .fniv = gen_sqadd_vec,
4347 .fno = gen_helper_gvec_sqadd_d,
4348 .opt_opc = vecop_list,
4349 .write_aofs = true,
4350 .vece = MO_64 },
4352 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4353 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4356 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4357 TCGv_vec a, TCGv_vec b)
4359 TCGv_vec x = tcg_temp_new_vec_matching(t);
4360 tcg_gen_sub_vec(vece, x, a, b);
4361 tcg_gen_ussub_vec(vece, t, a, b);
4362 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4363 tcg_gen_or_vec(vece, sat, sat, x);
4364 tcg_temp_free_vec(x);
4367 void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4368 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4370 static const TCGOpcode vecop_list[] = {
4371 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4373 static const GVecGen4 ops[4] = {
4374 { .fniv = gen_uqsub_vec,
4375 .fno = gen_helper_gvec_uqsub_b,
4376 .opt_opc = vecop_list,
4377 .write_aofs = true,
4378 .vece = MO_8 },
4379 { .fniv = gen_uqsub_vec,
4380 .fno = gen_helper_gvec_uqsub_h,
4381 .opt_opc = vecop_list,
4382 .write_aofs = true,
4383 .vece = MO_16 },
4384 { .fniv = gen_uqsub_vec,
4385 .fno = gen_helper_gvec_uqsub_s,
4386 .opt_opc = vecop_list,
4387 .write_aofs = true,
4388 .vece = MO_32 },
4389 { .fniv = gen_uqsub_vec,
4390 .fno = gen_helper_gvec_uqsub_d,
4391 .opt_opc = vecop_list,
4392 .write_aofs = true,
4393 .vece = MO_64 },
4395 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4396 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4399 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4400 TCGv_vec a, TCGv_vec b)
4402 TCGv_vec x = tcg_temp_new_vec_matching(t);
4403 tcg_gen_sub_vec(vece, x, a, b);
4404 tcg_gen_sssub_vec(vece, t, a, b);
4405 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4406 tcg_gen_or_vec(vece, sat, sat, x);
4407 tcg_temp_free_vec(x);
4410 void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4411 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4413 static const TCGOpcode vecop_list[] = {
4414 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4416 static const GVecGen4 ops[4] = {
4417 { .fniv = gen_sqsub_vec,
4418 .fno = gen_helper_gvec_sqsub_b,
4419 .opt_opc = vecop_list,
4420 .write_aofs = true,
4421 .vece = MO_8 },
4422 { .fniv = gen_sqsub_vec,
4423 .fno = gen_helper_gvec_sqsub_h,
4424 .opt_opc = vecop_list,
4425 .write_aofs = true,
4426 .vece = MO_16 },
4427 { .fniv = gen_sqsub_vec,
4428 .fno = gen_helper_gvec_sqsub_s,
4429 .opt_opc = vecop_list,
4430 .write_aofs = true,
4431 .vece = MO_32 },
4432 { .fniv = gen_sqsub_vec,
4433 .fno = gen_helper_gvec_sqsub_d,
4434 .opt_opc = vecop_list,
4435 .write_aofs = true,
4436 .vece = MO_64 },
4438 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4439 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4442 static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4444 TCGv_i32 t = tcg_temp_new_i32();
4446 tcg_gen_sub_i32(t, a, b);
4447 tcg_gen_sub_i32(d, b, a);
4448 tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
4449 tcg_temp_free_i32(t);
4452 static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4454 TCGv_i64 t = tcg_temp_new_i64();
4456 tcg_gen_sub_i64(t, a, b);
4457 tcg_gen_sub_i64(d, b, a);
4458 tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
4459 tcg_temp_free_i64(t);
4462 static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4464 TCGv_vec t = tcg_temp_new_vec_matching(d);
4466 tcg_gen_smin_vec(vece, t, a, b);
4467 tcg_gen_smax_vec(vece, d, a, b);
4468 tcg_gen_sub_vec(vece, d, d, t);
4469 tcg_temp_free_vec(t);
4472 void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4473 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4475 static const TCGOpcode vecop_list[] = {
4476 INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4478 static const GVecGen3 ops[4] = {
4479 { .fniv = gen_sabd_vec,
4480 .fno = gen_helper_gvec_sabd_b,
4481 .opt_opc = vecop_list,
4482 .vece = MO_8 },
4483 { .fniv = gen_sabd_vec,
4484 .fno = gen_helper_gvec_sabd_h,
4485 .opt_opc = vecop_list,
4486 .vece = MO_16 },
4487 { .fni4 = gen_sabd_i32,
4488 .fniv = gen_sabd_vec,
4489 .fno = gen_helper_gvec_sabd_s,
4490 .opt_opc = vecop_list,
4491 .vece = MO_32 },
4492 { .fni8 = gen_sabd_i64,
4493 .fniv = gen_sabd_vec,
4494 .fno = gen_helper_gvec_sabd_d,
4495 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4496 .opt_opc = vecop_list,
4497 .vece = MO_64 },
4499 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4502 static void gen_uabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4504 TCGv_i32 t = tcg_temp_new_i32();
4506 tcg_gen_sub_i32(t, a, b);
4507 tcg_gen_sub_i32(d, b, a);
4508 tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, d, t);
4509 tcg_temp_free_i32(t);
4512 static void gen_uabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4514 TCGv_i64 t = tcg_temp_new_i64();
4516 tcg_gen_sub_i64(t, a, b);
4517 tcg_gen_sub_i64(d, b, a);
4518 tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, d, t);
4519 tcg_temp_free_i64(t);
4522 static void gen_uabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4524 TCGv_vec t = tcg_temp_new_vec_matching(d);
4526 tcg_gen_umin_vec(vece, t, a, b);
4527 tcg_gen_umax_vec(vece, d, a, b);
4528 tcg_gen_sub_vec(vece, d, d, t);
4529 tcg_temp_free_vec(t);
4532 void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4533 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4535 static const TCGOpcode vecop_list[] = {
4536 INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
4538 static const GVecGen3 ops[4] = {
4539 { .fniv = gen_uabd_vec,
4540 .fno = gen_helper_gvec_uabd_b,
4541 .opt_opc = vecop_list,
4542 .vece = MO_8 },
4543 { .fniv = gen_uabd_vec,
4544 .fno = gen_helper_gvec_uabd_h,
4545 .opt_opc = vecop_list,
4546 .vece = MO_16 },
4547 { .fni4 = gen_uabd_i32,
4548 .fniv = gen_uabd_vec,
4549 .fno = gen_helper_gvec_uabd_s,
4550 .opt_opc = vecop_list,
4551 .vece = MO_32 },
4552 { .fni8 = gen_uabd_i64,
4553 .fniv = gen_uabd_vec,
4554 .fno = gen_helper_gvec_uabd_d,
4555 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4556 .opt_opc = vecop_list,
4557 .vece = MO_64 },
4559 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4562 static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4564 TCGv_i32 t = tcg_temp_new_i32();
4565 gen_sabd_i32(t, a, b);
4566 tcg_gen_add_i32(d, d, t);
4567 tcg_temp_free_i32(t);
4570 static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4572 TCGv_i64 t = tcg_temp_new_i64();
4573 gen_sabd_i64(t, a, b);
4574 tcg_gen_add_i64(d, d, t);
4575 tcg_temp_free_i64(t);
4578 static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4580 TCGv_vec t = tcg_temp_new_vec_matching(d);
4581 gen_sabd_vec(vece, t, a, b);
4582 tcg_gen_add_vec(vece, d, d, t);
4583 tcg_temp_free_vec(t);
4586 void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4587 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4589 static const TCGOpcode vecop_list[] = {
4590 INDEX_op_sub_vec, INDEX_op_add_vec,
4591 INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4593 static const GVecGen3 ops[4] = {
4594 { .fniv = gen_saba_vec,
4595 .fno = gen_helper_gvec_saba_b,
4596 .opt_opc = vecop_list,
4597 .load_dest = true,
4598 .vece = MO_8 },
4599 { .fniv = gen_saba_vec,
4600 .fno = gen_helper_gvec_saba_h,
4601 .opt_opc = vecop_list,
4602 .load_dest = true,
4603 .vece = MO_16 },
4604 { .fni4 = gen_saba_i32,
4605 .fniv = gen_saba_vec,
4606 .fno = gen_helper_gvec_saba_s,
4607 .opt_opc = vecop_list,
4608 .load_dest = true,
4609 .vece = MO_32 },
4610 { .fni8 = gen_saba_i64,
4611 .fniv = gen_saba_vec,
4612 .fno = gen_helper_gvec_saba_d,
4613 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4614 .opt_opc = vecop_list,
4615 .load_dest = true,
4616 .vece = MO_64 },
4618 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4621 static void gen_uaba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4623 TCGv_i32 t = tcg_temp_new_i32();
4624 gen_uabd_i32(t, a, b);
4625 tcg_gen_add_i32(d, d, t);
4626 tcg_temp_free_i32(t);
4629 static void gen_uaba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4631 TCGv_i64 t = tcg_temp_new_i64();
4632 gen_uabd_i64(t, a, b);
4633 tcg_gen_add_i64(d, d, t);
4634 tcg_temp_free_i64(t);
4637 static void gen_uaba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4639 TCGv_vec t = tcg_temp_new_vec_matching(d);
4640 gen_uabd_vec(vece, t, a, b);
4641 tcg_gen_add_vec(vece, d, d, t);
4642 tcg_temp_free_vec(t);
4645 void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4646 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4648 static const TCGOpcode vecop_list[] = {
4649 INDEX_op_sub_vec, INDEX_op_add_vec,
4650 INDEX_op_umin_vec, INDEX_op_umax_vec, 0
4652 static const GVecGen3 ops[4] = {
4653 { .fniv = gen_uaba_vec,
4654 .fno = gen_helper_gvec_uaba_b,
4655 .opt_opc = vecop_list,
4656 .load_dest = true,
4657 .vece = MO_8 },
4658 { .fniv = gen_uaba_vec,
4659 .fno = gen_helper_gvec_uaba_h,
4660 .opt_opc = vecop_list,
4661 .load_dest = true,
4662 .vece = MO_16 },
4663 { .fni4 = gen_uaba_i32,
4664 .fniv = gen_uaba_vec,
4665 .fno = gen_helper_gvec_uaba_s,
4666 .opt_opc = vecop_list,
4667 .load_dest = true,
4668 .vece = MO_32 },
4669 { .fni8 = gen_uaba_i64,
4670 .fniv = gen_uaba_vec,
4671 .fno = gen_helper_gvec_uaba_d,
4672 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4673 .opt_opc = vecop_list,
4674 .load_dest = true,
4675 .vece = MO_64 },
4677 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4680 static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
4681 int opc1, int crn, int crm, int opc2,
4682 bool isread, int rt, int rt2)
4684 const ARMCPRegInfo *ri;
4686 ri = get_arm_cp_reginfo(s->cp_regs,
4687 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
4688 if (ri) {
4689 bool need_exit_tb;
4691 /* Check access permissions */
4692 if (!cp_access_ok(s->current_el, ri, isread)) {
4693 unallocated_encoding(s);
4694 return;
4697 if (s->hstr_active || ri->accessfn ||
4698 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
4699 /* Emit code to perform further access permissions checks at
4700 * runtime; this may result in an exception.
4701 * Note that on XScale all cp0..c13 registers do an access check
4702 * call in order to handle c15_cpar.
4704 TCGv_ptr tmpptr;
4705 TCGv_i32 tcg_syn, tcg_isread;
4706 uint32_t syndrome;
4708 /* Note that since we are an implementation which takes an
4709 * exception on a trapped conditional instruction only if the
4710 * instruction passes its condition code check, we can take
4711 * advantage of the clause in the ARM ARM that allows us to set
4712 * the COND field in the instruction to 0xE in all cases.
4713 * We could fish the actual condition out of the insn (ARM)
4714 * or the condexec bits (Thumb) but it isn't necessary.
4716 switch (cpnum) {
4717 case 14:
4718 if (is64) {
4719 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
4720 isread, false);
4721 } else {
4722 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
4723 rt, isread, false);
4725 break;
4726 case 15:
4727 if (is64) {
4728 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
4729 isread, false);
4730 } else {
4731 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
4732 rt, isread, false);
4734 break;
4735 default:
4736 /* ARMv8 defines that only coprocessors 14 and 15 exist,
4737 * so this can only happen if this is an ARMv7 or earlier CPU,
4738 * in which case the syndrome information won't actually be
4739 * guest visible.
4741 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
4742 syndrome = syn_uncategorized();
4743 break;
4746 gen_set_condexec(s);
4747 gen_set_pc_im(s, s->pc_curr);
4748 tmpptr = tcg_const_ptr(ri);
4749 tcg_syn = tcg_const_i32(syndrome);
4750 tcg_isread = tcg_const_i32(isread);
4751 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
4752 tcg_isread);
4753 tcg_temp_free_ptr(tmpptr);
4754 tcg_temp_free_i32(tcg_syn);
4755 tcg_temp_free_i32(tcg_isread);
4756 } else if (ri->type & ARM_CP_RAISES_EXC) {
4758 * The readfn or writefn might raise an exception;
4759 * synchronize the CPU state in case it does.
4761 gen_set_condexec(s);
4762 gen_set_pc_im(s, s->pc_curr);
4765 /* Handle special cases first */
4766 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
4767 case ARM_CP_NOP:
4768 return;
4769 case ARM_CP_WFI:
4770 if (isread) {
4771 unallocated_encoding(s);
4772 return;
4774 gen_set_pc_im(s, s->base.pc_next);
4775 s->base.is_jmp = DISAS_WFI;
4776 return;
4777 default:
4778 break;
4781 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
4782 gen_io_start();
4785 if (isread) {
4786 /* Read */
4787 if (is64) {
4788 TCGv_i64 tmp64;
4789 TCGv_i32 tmp;
4790 if (ri->type & ARM_CP_CONST) {
4791 tmp64 = tcg_const_i64(ri->resetvalue);
4792 } else if (ri->readfn) {
4793 TCGv_ptr tmpptr;
4794 tmp64 = tcg_temp_new_i64();
4795 tmpptr = tcg_const_ptr(ri);
4796 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
4797 tcg_temp_free_ptr(tmpptr);
4798 } else {
4799 tmp64 = tcg_temp_new_i64();
4800 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
4802 tmp = tcg_temp_new_i32();
4803 tcg_gen_extrl_i64_i32(tmp, tmp64);
4804 store_reg(s, rt, tmp);
4805 tmp = tcg_temp_new_i32();
4806 tcg_gen_extrh_i64_i32(tmp, tmp64);
4807 tcg_temp_free_i64(tmp64);
4808 store_reg(s, rt2, tmp);
4809 } else {
4810 TCGv_i32 tmp;
4811 if (ri->type & ARM_CP_CONST) {
4812 tmp = tcg_const_i32(ri->resetvalue);
4813 } else if (ri->readfn) {
4814 TCGv_ptr tmpptr;
4815 tmp = tcg_temp_new_i32();
4816 tmpptr = tcg_const_ptr(ri);
4817 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
4818 tcg_temp_free_ptr(tmpptr);
4819 } else {
4820 tmp = load_cpu_offset(ri->fieldoffset);
4822 if (rt == 15) {
4823 /* Destination register of r15 for 32 bit loads sets
4824 * the condition codes from the high 4 bits of the value
4826 gen_set_nzcv(tmp);
4827 tcg_temp_free_i32(tmp);
4828 } else {
4829 store_reg(s, rt, tmp);
4832 } else {
4833 /* Write */
4834 if (ri->type & ARM_CP_CONST) {
4835 /* If not forbidden by access permissions, treat as WI */
4836 return;
4839 if (is64) {
4840 TCGv_i32 tmplo, tmphi;
4841 TCGv_i64 tmp64 = tcg_temp_new_i64();
4842 tmplo = load_reg(s, rt);
4843 tmphi = load_reg(s, rt2);
4844 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
4845 tcg_temp_free_i32(tmplo);
4846 tcg_temp_free_i32(tmphi);
4847 if (ri->writefn) {
4848 TCGv_ptr tmpptr = tcg_const_ptr(ri);
4849 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
4850 tcg_temp_free_ptr(tmpptr);
4851 } else {
4852 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
4854 tcg_temp_free_i64(tmp64);
4855 } else {
4856 if (ri->writefn) {
4857 TCGv_i32 tmp;
4858 TCGv_ptr tmpptr;
4859 tmp = load_reg(s, rt);
4860 tmpptr = tcg_const_ptr(ri);
4861 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
4862 tcg_temp_free_ptr(tmpptr);
4863 tcg_temp_free_i32(tmp);
4864 } else {
4865 TCGv_i32 tmp = load_reg(s, rt);
4866 store_cpu_offset(tmp, ri->fieldoffset);
4871 /* I/O operations must end the TB here (whether read or write) */
4872 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
4873 (ri->type & ARM_CP_IO));
4875 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
4877 * A write to any coprocessor register that ends a TB
4878 * must rebuild the hflags for the next TB.
4880 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
4881 if (arm_dc_feature(s, ARM_FEATURE_M)) {
4882 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
4883 } else {
4884 if (ri->type & ARM_CP_NEWEL) {
4885 gen_helper_rebuild_hflags_a32_newel(cpu_env);
4886 } else {
4887 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
4890 tcg_temp_free_i32(tcg_el);
4892 * We default to ending the TB on a coprocessor register write,
4893 * but allow this to be suppressed by the register definition
4894 * (usually only necessary to work around guest bugs).
4896 need_exit_tb = true;
4898 if (need_exit_tb) {
4899 gen_lookup_tb(s);
4902 return;
4905 /* Unknown register; this might be a guest error or a QEMU
4906 * unimplemented feature.
4908 if (is64) {
4909 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
4910 "64 bit system register cp:%d opc1: %d crm:%d "
4911 "(%s)\n",
4912 isread ? "read" : "write", cpnum, opc1, crm,
4913 s->ns ? "non-secure" : "secure");
4914 } else {
4915 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
4916 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
4917 "(%s)\n",
4918 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
4919 s->ns ? "non-secure" : "secure");
4922 unallocated_encoding(s);
4923 return;
4926 /* Decode XScale DSP or iWMMXt insn (in the copro space, cp=0 or 1) */
4927 static void disas_xscale_insn(DisasContext *s, uint32_t insn)
4929 int cpnum = (insn >> 8) & 0xf;
4931 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
4932 unallocated_encoding(s);
4933 } else if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
4934 if (disas_iwmmxt_insn(s, insn)) {
4935 unallocated_encoding(s);
4937 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
4938 if (disas_dsp_insn(s, insn)) {
4939 unallocated_encoding(s);
4944 /* Store a 64-bit value to a register pair. Clobbers val. */
4945 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
4947 TCGv_i32 tmp;
4948 tmp = tcg_temp_new_i32();
4949 tcg_gen_extrl_i64_i32(tmp, val);
4950 store_reg(s, rlow, tmp);
4951 tmp = tcg_temp_new_i32();
4952 tcg_gen_extrh_i64_i32(tmp, val);
4953 store_reg(s, rhigh, tmp);
4956 /* load and add a 64-bit value from a register pair. */
4957 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
4959 TCGv_i64 tmp;
4960 TCGv_i32 tmpl;
4961 TCGv_i32 tmph;
4963 /* Load 64-bit value rd:rn. */
4964 tmpl = load_reg(s, rlow);
4965 tmph = load_reg(s, rhigh);
4966 tmp = tcg_temp_new_i64();
4967 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
4968 tcg_temp_free_i32(tmpl);
4969 tcg_temp_free_i32(tmph);
4970 tcg_gen_add_i64(val, val, tmp);
4971 tcg_temp_free_i64(tmp);
4974 /* Set N and Z flags from hi|lo. */
4975 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
4977 tcg_gen_mov_i32(cpu_NF, hi);
4978 tcg_gen_or_i32(cpu_ZF, lo, hi);
4981 /* Load/Store exclusive instructions are implemented by remembering
4982 the value/address loaded, and seeing if these are the same
4983 when the store is performed. This should be sufficient to implement
4984 the architecturally mandated semantics, and avoids having to monitor
4985 regular stores. The compare vs the remembered value is done during
4986 the cmpxchg operation, but we must compare the addresses manually. */
4987 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
4988 TCGv_i32 addr, int size)
4990 TCGv_i32 tmp = tcg_temp_new_i32();
4991 MemOp opc = size | MO_ALIGN | s->be_data;
4993 s->is_ldex = true;
4995 if (size == 3) {
4996 TCGv_i32 tmp2 = tcg_temp_new_i32();
4997 TCGv_i64 t64 = tcg_temp_new_i64();
5000 * For AArch32, architecturally the 32-bit word at the lowest
5001 * address is always Rt and the one at addr+4 is Rt2, even if
5002 * the CPU is big-endian. That means we don't want to do a
5003 * gen_aa32_ld_i64(), which checks SCTLR_B as if for an
5004 * architecturally 64-bit access, but instead do a 64-bit access
5005 * using MO_BE if appropriate and then split the two halves.
5007 TCGv taddr = gen_aa32_addr(s, addr, opc);
5009 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
5010 tcg_temp_free(taddr);
5011 tcg_gen_mov_i64(cpu_exclusive_val, t64);
5012 if (s->be_data == MO_BE) {
5013 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
5014 } else {
5015 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
5017 tcg_temp_free_i64(t64);
5019 store_reg(s, rt2, tmp2);
5020 } else {
5021 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
5022 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
5025 store_reg(s, rt, tmp);
5026 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
5029 static void gen_clrex(DisasContext *s)
5031 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
5034 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5035 TCGv_i32 addr, int size)
5037 TCGv_i32 t0, t1, t2;
5038 TCGv_i64 extaddr;
5039 TCGv taddr;
5040 TCGLabel *done_label;
5041 TCGLabel *fail_label;
5042 MemOp opc = size | MO_ALIGN | s->be_data;
5044 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
5045 [addr] = {Rt};
5046 {Rd} = 0;
5047 } else {
5048 {Rd} = 1;
5049 } */
5050 fail_label = gen_new_label();
5051 done_label = gen_new_label();
5052 extaddr = tcg_temp_new_i64();
5053 tcg_gen_extu_i32_i64(extaddr, addr);
5054 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
5055 tcg_temp_free_i64(extaddr);
5057 taddr = gen_aa32_addr(s, addr, opc);
5058 t0 = tcg_temp_new_i32();
5059 t1 = load_reg(s, rt);
5060 if (size == 3) {
5061 TCGv_i64 o64 = tcg_temp_new_i64();
5062 TCGv_i64 n64 = tcg_temp_new_i64();
5064 t2 = load_reg(s, rt2);
5067 * For AArch32, architecturally the 32-bit word at the lowest
5068 * address is always Rt and the one at addr+4 is Rt2, even if
5069 * the CPU is big-endian. Since we're going to treat this as a
5070 * single 64-bit BE store, we need to put the two halves in the
5071 * opposite order for BE to LE, so that they end up in the right
5072 * places. We don't want gen_aa32_st_i64, because that checks
5073 * SCTLR_B as if for an architectural 64-bit access.
5075 if (s->be_data == MO_BE) {
5076 tcg_gen_concat_i32_i64(n64, t2, t1);
5077 } else {
5078 tcg_gen_concat_i32_i64(n64, t1, t2);
5080 tcg_temp_free_i32(t2);
5082 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
5083 get_mem_index(s), opc);
5084 tcg_temp_free_i64(n64);
5086 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
5087 tcg_gen_extrl_i64_i32(t0, o64);
5089 tcg_temp_free_i64(o64);
5090 } else {
5091 t2 = tcg_temp_new_i32();
5092 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
5093 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
5094 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
5095 tcg_temp_free_i32(t2);
5097 tcg_temp_free_i32(t1);
5098 tcg_temp_free(taddr);
5099 tcg_gen_mov_i32(cpu_R[rd], t0);
5100 tcg_temp_free_i32(t0);
5101 tcg_gen_br(done_label);
5103 gen_set_label(fail_label);
5104 tcg_gen_movi_i32(cpu_R[rd], 1);
5105 gen_set_label(done_label);
5106 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
5109 /* gen_srs:
5110 * @env: CPUARMState
5111 * @s: DisasContext
5112 * @mode: mode field from insn (which stack to store to)
5113 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
5114 * @writeback: true if writeback bit set
5116 * Generate code for the SRS (Store Return State) insn.
5118 static void gen_srs(DisasContext *s,
5119 uint32_t mode, uint32_t amode, bool writeback)
5121 int32_t offset;
5122 TCGv_i32 addr, tmp;
5123 bool undef = false;
5125 /* SRS is:
5126 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
5127 * and specified mode is monitor mode
5128 * - UNDEFINED in Hyp mode
5129 * - UNPREDICTABLE in User or System mode
5130 * - UNPREDICTABLE if the specified mode is:
5131 * -- not implemented
5132 * -- not a valid mode number
5133 * -- a mode that's at a higher exception level
5134 * -- Monitor, if we are Non-secure
5135 * For the UNPREDICTABLE cases we choose to UNDEF.
5137 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
5138 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
5139 return;
5142 if (s->current_el == 0 || s->current_el == 2) {
5143 undef = true;
5146 switch (mode) {
5147 case ARM_CPU_MODE_USR:
5148 case ARM_CPU_MODE_FIQ:
5149 case ARM_CPU_MODE_IRQ:
5150 case ARM_CPU_MODE_SVC:
5151 case ARM_CPU_MODE_ABT:
5152 case ARM_CPU_MODE_UND:
5153 case ARM_CPU_MODE_SYS:
5154 break;
5155 case ARM_CPU_MODE_HYP:
5156 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
5157 undef = true;
5159 break;
5160 case ARM_CPU_MODE_MON:
5161 /* No need to check specifically for "are we non-secure" because
5162 * we've already made EL0 UNDEF and handled the trap for S-EL1;
5163 * so if this isn't EL3 then we must be non-secure.
5165 if (s->current_el != 3) {
5166 undef = true;
5168 break;
5169 default:
5170 undef = true;
5173 if (undef) {
5174 unallocated_encoding(s);
5175 return;
5178 addr = tcg_temp_new_i32();
5179 tmp = tcg_const_i32(mode);
5180 /* get_r13_banked() will raise an exception if called from System mode */
5181 gen_set_condexec(s);
5182 gen_set_pc_im(s, s->pc_curr);
5183 gen_helper_get_r13_banked(addr, cpu_env, tmp);
5184 tcg_temp_free_i32(tmp);
5185 switch (amode) {
5186 case 0: /* DA */
5187 offset = -4;
5188 break;
5189 case 1: /* IA */
5190 offset = 0;
5191 break;
5192 case 2: /* DB */
5193 offset = -8;
5194 break;
5195 case 3: /* IB */
5196 offset = 4;
5197 break;
5198 default:
5199 abort();
5201 tcg_gen_addi_i32(addr, addr, offset);
5202 tmp = load_reg(s, 14);
5203 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5204 tcg_temp_free_i32(tmp);
5205 tmp = load_cpu_field(spsr);
5206 tcg_gen_addi_i32(addr, addr, 4);
5207 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5208 tcg_temp_free_i32(tmp);
5209 if (writeback) {
5210 switch (amode) {
5211 case 0:
5212 offset = -8;
5213 break;
5214 case 1:
5215 offset = 4;
5216 break;
5217 case 2:
5218 offset = -4;
5219 break;
5220 case 3:
5221 offset = 0;
5222 break;
5223 default:
5224 abort();
5226 tcg_gen_addi_i32(addr, addr, offset);
5227 tmp = tcg_const_i32(mode);
5228 gen_helper_set_r13_banked(cpu_env, tmp, addr);
5229 tcg_temp_free_i32(tmp);
5231 tcg_temp_free_i32(addr);
5232 s->base.is_jmp = DISAS_UPDATE_EXIT;
5235 /* Skip this instruction if the ARM condition is false */
5236 static void arm_skip_unless(DisasContext *s, uint32_t cond)
5238 arm_gen_condlabel(s);
5239 arm_gen_test_cc(cond ^ 1, s->condlabel);
5244 * Constant expanders used by T16/T32 decode
5247 /* Return only the rotation part of T32ExpandImm. */
5248 static int t32_expandimm_rot(DisasContext *s, int x)
5250 return x & 0xc00 ? extract32(x, 7, 5) : 0;
5253 /* Return the unrotated immediate from T32ExpandImm. */
5254 static int t32_expandimm_imm(DisasContext *s, int x)
5256 int imm = extract32(x, 0, 8);
5258 switch (extract32(x, 8, 4)) {
5259 case 0: /* XY */
5260 /* Nothing to do. */
5261 break;
5262 case 1: /* 00XY00XY */
5263 imm *= 0x00010001;
5264 break;
5265 case 2: /* XY00XY00 */
5266 imm *= 0x01000100;
5267 break;
5268 case 3: /* XYXYXYXY */
5269 imm *= 0x01010101;
5270 break;
5271 default:
5272 /* Rotated constant. */
5273 imm |= 0x80;
5274 break;
5276 return imm;
5279 static int t32_branch24(DisasContext *s, int x)
5281 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
5282 x ^= !(x < 0) * (3 << 21);
5283 /* Append the final zero. */
5284 return x << 1;
5287 static int t16_setflags(DisasContext *s)
5289 return s->condexec_mask == 0;
5292 static int t16_push_list(DisasContext *s, int x)
5294 return (x & 0xff) | (x & 0x100) << (14 - 8);
5297 static int t16_pop_list(DisasContext *s, int x)
5299 return (x & 0xff) | (x & 0x100) << (15 - 8);
5303 * Include the generated decoders.
5306 #include "decode-a32.c.inc"
5307 #include "decode-a32-uncond.c.inc"
5308 #include "decode-t32.c.inc"
5309 #include "decode-t16.c.inc"
5311 static bool valid_cp(DisasContext *s, int cp)
5314 * Return true if this coprocessor field indicates something
5315 * that's really a possible coprocessor.
5316 * For v7 and earlier, coprocessors 8..15 were reserved for Arm use,
5317 * and of those only cp14 and cp15 were used for registers.
5318 * cp10 and cp11 were used for VFP and Neon, whose decode is
5319 * dealt with elsewhere. With the advent of fp16, cp9 is also
5320 * now part of VFP.
5321 * For v8A and later, the encoding has been tightened so that
5322 * only cp14 and cp15 are valid, and other values aren't considered
5323 * to be in the coprocessor-instruction space at all. v8M still
5324 * permits coprocessors 0..7.
5325 * For XScale, we must not decode the XScale cp0, cp1 space as
5326 * a standard coprocessor insn, because we want to fall through to
5327 * the legacy disas_xscale_insn() decoder after decodetree is done.
5329 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cp == 0 || cp == 1)) {
5330 return false;
5333 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
5334 !arm_dc_feature(s, ARM_FEATURE_M)) {
5335 return cp >= 14;
5337 return cp < 8 || cp >= 14;
5340 static bool trans_MCR(DisasContext *s, arg_MCR *a)
5342 if (!valid_cp(s, a->cp)) {
5343 return false;
5345 do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
5346 false, a->rt, 0);
5347 return true;
5350 static bool trans_MRC(DisasContext *s, arg_MRC *a)
5352 if (!valid_cp(s, a->cp)) {
5353 return false;
5355 do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
5356 true, a->rt, 0);
5357 return true;
5360 static bool trans_MCRR(DisasContext *s, arg_MCRR *a)
5362 if (!valid_cp(s, a->cp)) {
5363 return false;
5365 do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
5366 false, a->rt, a->rt2);
5367 return true;
5370 static bool trans_MRRC(DisasContext *s, arg_MRRC *a)
5372 if (!valid_cp(s, a->cp)) {
5373 return false;
5375 do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
5376 true, a->rt, a->rt2);
5377 return true;
5380 /* Helpers to swap operands for reverse-subtract. */
5381 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
5383 tcg_gen_sub_i32(dst, b, a);
5386 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
5388 gen_sub_CC(dst, b, a);
5391 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
5393 gen_sub_carry(dest, b, a);
5396 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
5398 gen_sbc_CC(dest, b, a);
5402 * Helpers for the data processing routines.
5404 * After the computation store the results back.
5405 * This may be suppressed altogether (STREG_NONE), require a runtime
5406 * check against the stack limits (STREG_SP_CHECK), or generate an
5407 * exception return. Oh, or store into a register.
5409 * Always return true, indicating success for a trans_* function.
5411 typedef enum {
5412 STREG_NONE,
5413 STREG_NORMAL,
5414 STREG_SP_CHECK,
5415 STREG_EXC_RET,
5416 } StoreRegKind;
5418 static bool store_reg_kind(DisasContext *s, int rd,
5419 TCGv_i32 val, StoreRegKind kind)
5421 switch (kind) {
5422 case STREG_NONE:
5423 tcg_temp_free_i32(val);
5424 return true;
5425 case STREG_NORMAL:
5426 /* See ALUWritePC: Interworking only from a32 mode. */
5427 if (s->thumb) {
5428 store_reg(s, rd, val);
5429 } else {
5430 store_reg_bx(s, rd, val);
5432 return true;
5433 case STREG_SP_CHECK:
5434 store_sp_checked(s, val);
5435 return true;
5436 case STREG_EXC_RET:
5437 gen_exception_return(s, val);
5438 return true;
5440 g_assert_not_reached();
5444 * Data Processing (register)
5446 * Operate, with set flags, one register source,
5447 * one immediate shifted register source, and a destination.
5449 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
5450 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5451 int logic_cc, StoreRegKind kind)
5453 TCGv_i32 tmp1, tmp2;
5455 tmp2 = load_reg(s, a->rm);
5456 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
5457 tmp1 = load_reg(s, a->rn);
5459 gen(tmp1, tmp1, tmp2);
5460 tcg_temp_free_i32(tmp2);
5462 if (logic_cc) {
5463 gen_logic_CC(tmp1);
5465 return store_reg_kind(s, a->rd, tmp1, kind);
5468 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
5469 void (*gen)(TCGv_i32, TCGv_i32),
5470 int logic_cc, StoreRegKind kind)
5472 TCGv_i32 tmp;
5474 tmp = load_reg(s, a->rm);
5475 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
5477 gen(tmp, tmp);
5478 if (logic_cc) {
5479 gen_logic_CC(tmp);
5481 return store_reg_kind(s, a->rd, tmp, kind);
5485 * Data-processing (register-shifted register)
5487 * Operate, with set flags, one register source,
5488 * one register shifted register source, and a destination.
5490 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
5491 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5492 int logic_cc, StoreRegKind kind)
5494 TCGv_i32 tmp1, tmp2;
5496 tmp1 = load_reg(s, a->rs);
5497 tmp2 = load_reg(s, a->rm);
5498 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
5499 tmp1 = load_reg(s, a->rn);
5501 gen(tmp1, tmp1, tmp2);
5502 tcg_temp_free_i32(tmp2);
5504 if (logic_cc) {
5505 gen_logic_CC(tmp1);
5507 return store_reg_kind(s, a->rd, tmp1, kind);
5510 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
5511 void (*gen)(TCGv_i32, TCGv_i32),
5512 int logic_cc, StoreRegKind kind)
5514 TCGv_i32 tmp1, tmp2;
5516 tmp1 = load_reg(s, a->rs);
5517 tmp2 = load_reg(s, a->rm);
5518 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
5520 gen(tmp2, tmp2);
5521 if (logic_cc) {
5522 gen_logic_CC(tmp2);
5524 return store_reg_kind(s, a->rd, tmp2, kind);
5528 * Data-processing (immediate)
5530 * Operate, with set flags, one register source,
5531 * one rotated immediate, and a destination.
5533 * Note that logic_cc && a->rot setting CF based on the msb of the
5534 * immediate is the reason why we must pass in the unrotated form
5535 * of the immediate.
5537 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
5538 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5539 int logic_cc, StoreRegKind kind)
5541 TCGv_i32 tmp1, tmp2;
5542 uint32_t imm;
5544 imm = ror32(a->imm, a->rot);
5545 if (logic_cc && a->rot) {
5546 tcg_gen_movi_i32(cpu_CF, imm >> 31);
5548 tmp2 = tcg_const_i32(imm);
5549 tmp1 = load_reg(s, a->rn);
5551 gen(tmp1, tmp1, tmp2);
5552 tcg_temp_free_i32(tmp2);
5554 if (logic_cc) {
5555 gen_logic_CC(tmp1);
5557 return store_reg_kind(s, a->rd, tmp1, kind);
5560 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
5561 void (*gen)(TCGv_i32, TCGv_i32),
5562 int logic_cc, StoreRegKind kind)
5564 TCGv_i32 tmp;
5565 uint32_t imm;
5567 imm = ror32(a->imm, a->rot);
5568 if (logic_cc && a->rot) {
5569 tcg_gen_movi_i32(cpu_CF, imm >> 31);
5571 tmp = tcg_const_i32(imm);
5573 gen(tmp, tmp);
5574 if (logic_cc) {
5575 gen_logic_CC(tmp);
5577 return store_reg_kind(s, a->rd, tmp, kind);
5580 #define DO_ANY3(NAME, OP, L, K) \
5581 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
5582 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
5583 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
5584 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
5585 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
5586 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
5588 #define DO_ANY2(NAME, OP, L, K) \
5589 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
5590 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
5591 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
5592 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
5593 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
5594 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
5596 #define DO_CMP2(NAME, OP, L) \
5597 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
5598 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
5599 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
5600 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
5601 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
5602 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
5604 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
5605 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
5606 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
5607 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
5609 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
5610 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
5611 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
5612 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
5614 DO_CMP2(TST, tcg_gen_and_i32, true)
5615 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
5616 DO_CMP2(CMN, gen_add_CC, false)
5617 DO_CMP2(CMP, gen_sub_CC, false)
5619 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
5620 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
5623 * Note for the computation of StoreRegKind we return out of the
5624 * middle of the functions that are expanded by DO_ANY3, and that
5625 * we modify a->s via that parameter before it is used by OP.
5627 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
5629 StoreRegKind ret = STREG_NORMAL;
5630 if (a->rd == 15 && a->s) {
5632 * See ALUExceptionReturn:
5633 * In User mode, UNPREDICTABLE; we choose UNDEF.
5634 * In Hyp mode, UNDEFINED.
5636 if (IS_USER(s) || s->current_el == 2) {
5637 unallocated_encoding(s);
5638 return true;
5640 /* There is no writeback of nzcv to PSTATE. */
5641 a->s = 0;
5642 ret = STREG_EXC_RET;
5643 } else if (a->rd == 13 && a->rn == 13) {
5644 ret = STREG_SP_CHECK;
5646 ret;
5649 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
5651 StoreRegKind ret = STREG_NORMAL;
5652 if (a->rd == 15 && a->s) {
5654 * See ALUExceptionReturn:
5655 * In User mode, UNPREDICTABLE; we choose UNDEF.
5656 * In Hyp mode, UNDEFINED.
5658 if (IS_USER(s) || s->current_el == 2) {
5659 unallocated_encoding(s);
5660 return true;
5662 /* There is no writeback of nzcv to PSTATE. */
5663 a->s = 0;
5664 ret = STREG_EXC_RET;
5665 } else if (a->rd == 13) {
5666 ret = STREG_SP_CHECK;
5668 ret;
5671 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
5674 * ORN is only available with T32, so there is no register-shifted-register
5675 * form of the insn. Using the DO_ANY3 macro would create an unused function.
5677 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
5679 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
5682 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
5684 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
5687 #undef DO_ANY3
5688 #undef DO_ANY2
5689 #undef DO_CMP2
5691 static bool trans_ADR(DisasContext *s, arg_ri *a)
5693 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
5694 return true;
5697 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
5699 TCGv_i32 tmp;
5701 if (!ENABLE_ARCH_6T2) {
5702 return false;
5705 tmp = tcg_const_i32(a->imm);
5706 store_reg(s, a->rd, tmp);
5707 return true;
5710 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
5712 TCGv_i32 tmp;
5714 if (!ENABLE_ARCH_6T2) {
5715 return false;
5718 tmp = load_reg(s, a->rd);
5719 tcg_gen_ext16u_i32(tmp, tmp);
5720 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
5721 store_reg(s, a->rd, tmp);
5722 return true;
5726 * Multiply and multiply accumulate
5729 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
5731 TCGv_i32 t1, t2;
5733 t1 = load_reg(s, a->rn);
5734 t2 = load_reg(s, a->rm);
5735 tcg_gen_mul_i32(t1, t1, t2);
5736 tcg_temp_free_i32(t2);
5737 if (add) {
5738 t2 = load_reg(s, a->ra);
5739 tcg_gen_add_i32(t1, t1, t2);
5740 tcg_temp_free_i32(t2);
5742 if (a->s) {
5743 gen_logic_CC(t1);
5745 store_reg(s, a->rd, t1);
5746 return true;
5749 static bool trans_MUL(DisasContext *s, arg_MUL *a)
5751 return op_mla(s, a, false);
5754 static bool trans_MLA(DisasContext *s, arg_MLA *a)
5756 return op_mla(s, a, true);
5759 static bool trans_MLS(DisasContext *s, arg_MLS *a)
5761 TCGv_i32 t1, t2;
5763 if (!ENABLE_ARCH_6T2) {
5764 return false;
5766 t1 = load_reg(s, a->rn);
5767 t2 = load_reg(s, a->rm);
5768 tcg_gen_mul_i32(t1, t1, t2);
5769 tcg_temp_free_i32(t2);
5770 t2 = load_reg(s, a->ra);
5771 tcg_gen_sub_i32(t1, t2, t1);
5772 tcg_temp_free_i32(t2);
5773 store_reg(s, a->rd, t1);
5774 return true;
5777 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
5779 TCGv_i32 t0, t1, t2, t3;
5781 t0 = load_reg(s, a->rm);
5782 t1 = load_reg(s, a->rn);
5783 if (uns) {
5784 tcg_gen_mulu2_i32(t0, t1, t0, t1);
5785 } else {
5786 tcg_gen_muls2_i32(t0, t1, t0, t1);
5788 if (add) {
5789 t2 = load_reg(s, a->ra);
5790 t3 = load_reg(s, a->rd);
5791 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
5792 tcg_temp_free_i32(t2);
5793 tcg_temp_free_i32(t3);
5795 if (a->s) {
5796 gen_logicq_cc(t0, t1);
5798 store_reg(s, a->ra, t0);
5799 store_reg(s, a->rd, t1);
5800 return true;
5803 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
5805 return op_mlal(s, a, true, false);
5808 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
5810 return op_mlal(s, a, false, false);
5813 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
5815 return op_mlal(s, a, true, true);
5818 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
5820 return op_mlal(s, a, false, true);
5823 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
5825 TCGv_i32 t0, t1, t2, zero;
5827 if (s->thumb
5828 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
5829 : !ENABLE_ARCH_6) {
5830 return false;
5833 t0 = load_reg(s, a->rm);
5834 t1 = load_reg(s, a->rn);
5835 tcg_gen_mulu2_i32(t0, t1, t0, t1);
5836 zero = tcg_const_i32(0);
5837 t2 = load_reg(s, a->ra);
5838 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
5839 tcg_temp_free_i32(t2);
5840 t2 = load_reg(s, a->rd);
5841 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
5842 tcg_temp_free_i32(t2);
5843 tcg_temp_free_i32(zero);
5844 store_reg(s, a->ra, t0);
5845 store_reg(s, a->rd, t1);
5846 return true;
5850 * Saturating addition and subtraction
5853 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
5855 TCGv_i32 t0, t1;
5857 if (s->thumb
5858 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
5859 : !ENABLE_ARCH_5TE) {
5860 return false;
5863 t0 = load_reg(s, a->rm);
5864 t1 = load_reg(s, a->rn);
5865 if (doub) {
5866 gen_helper_add_saturate(t1, cpu_env, t1, t1);
5868 if (add) {
5869 gen_helper_add_saturate(t0, cpu_env, t0, t1);
5870 } else {
5871 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
5873 tcg_temp_free_i32(t1);
5874 store_reg(s, a->rd, t0);
5875 return true;
5878 #define DO_QADDSUB(NAME, ADD, DOUB) \
5879 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
5881 return op_qaddsub(s, a, ADD, DOUB); \
5884 DO_QADDSUB(QADD, true, false)
5885 DO_QADDSUB(QSUB, false, false)
5886 DO_QADDSUB(QDADD, true, true)
5887 DO_QADDSUB(QDSUB, false, true)
5889 #undef DO_QADDSUB
5892 * Halfword multiply and multiply accumulate
5895 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
5896 int add_long, bool nt, bool mt)
5898 TCGv_i32 t0, t1, tl, th;
5900 if (s->thumb
5901 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
5902 : !ENABLE_ARCH_5TE) {
5903 return false;
5906 t0 = load_reg(s, a->rn);
5907 t1 = load_reg(s, a->rm);
5908 gen_mulxy(t0, t1, nt, mt);
5909 tcg_temp_free_i32(t1);
5911 switch (add_long) {
5912 case 0:
5913 store_reg(s, a->rd, t0);
5914 break;
5915 case 1:
5916 t1 = load_reg(s, a->ra);
5917 gen_helper_add_setq(t0, cpu_env, t0, t1);
5918 tcg_temp_free_i32(t1);
5919 store_reg(s, a->rd, t0);
5920 break;
5921 case 2:
5922 tl = load_reg(s, a->ra);
5923 th = load_reg(s, a->rd);
5924 /* Sign-extend the 32-bit product to 64 bits. */
5925 t1 = tcg_temp_new_i32();
5926 tcg_gen_sari_i32(t1, t0, 31);
5927 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
5928 tcg_temp_free_i32(t0);
5929 tcg_temp_free_i32(t1);
5930 store_reg(s, a->ra, tl);
5931 store_reg(s, a->rd, th);
5932 break;
5933 default:
5934 g_assert_not_reached();
5936 return true;
5939 #define DO_SMLAX(NAME, add, nt, mt) \
5940 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
5942 return op_smlaxxx(s, a, add, nt, mt); \
5945 DO_SMLAX(SMULBB, 0, 0, 0)
5946 DO_SMLAX(SMULBT, 0, 0, 1)
5947 DO_SMLAX(SMULTB, 0, 1, 0)
5948 DO_SMLAX(SMULTT, 0, 1, 1)
5950 DO_SMLAX(SMLABB, 1, 0, 0)
5951 DO_SMLAX(SMLABT, 1, 0, 1)
5952 DO_SMLAX(SMLATB, 1, 1, 0)
5953 DO_SMLAX(SMLATT, 1, 1, 1)
5955 DO_SMLAX(SMLALBB, 2, 0, 0)
5956 DO_SMLAX(SMLALBT, 2, 0, 1)
5957 DO_SMLAX(SMLALTB, 2, 1, 0)
5958 DO_SMLAX(SMLALTT, 2, 1, 1)
5960 #undef DO_SMLAX
5962 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
5964 TCGv_i32 t0, t1;
5966 if (!ENABLE_ARCH_5TE) {
5967 return false;
5970 t0 = load_reg(s, a->rn);
5971 t1 = load_reg(s, a->rm);
5973 * Since the nominal result is product<47:16>, shift the 16-bit
5974 * input up by 16 bits, so that the result is at product<63:32>.
5976 if (mt) {
5977 tcg_gen_andi_i32(t1, t1, 0xffff0000);
5978 } else {
5979 tcg_gen_shli_i32(t1, t1, 16);
5981 tcg_gen_muls2_i32(t0, t1, t0, t1);
5982 tcg_temp_free_i32(t0);
5983 if (add) {
5984 t0 = load_reg(s, a->ra);
5985 gen_helper_add_setq(t1, cpu_env, t1, t0);
5986 tcg_temp_free_i32(t0);
5988 store_reg(s, a->rd, t1);
5989 return true;
5992 #define DO_SMLAWX(NAME, add, mt) \
5993 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
5995 return op_smlawx(s, a, add, mt); \
5998 DO_SMLAWX(SMULWB, 0, 0)
5999 DO_SMLAWX(SMULWT, 0, 1)
6000 DO_SMLAWX(SMLAWB, 1, 0)
6001 DO_SMLAWX(SMLAWT, 1, 1)
6003 #undef DO_SMLAWX
6006 * MSR (immediate) and hints
6009 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
6012 * When running single-threaded TCG code, use the helper to ensure that
6013 * the next round-robin scheduled vCPU gets a crack. When running in
6014 * MTTCG we don't generate jumps to the helper as it won't affect the
6015 * scheduling of other vCPUs.
6017 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
6018 gen_set_pc_im(s, s->base.pc_next);
6019 s->base.is_jmp = DISAS_YIELD;
6021 return true;
6024 static bool trans_WFE(DisasContext *s, arg_WFE *a)
6027 * When running single-threaded TCG code, use the helper to ensure that
6028 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
6029 * just skip this instruction. Currently the SEV/SEVL instructions,
6030 * which are *one* of many ways to wake the CPU from WFE, are not
6031 * implemented so we can't sleep like WFI does.
6033 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
6034 gen_set_pc_im(s, s->base.pc_next);
6035 s->base.is_jmp = DISAS_WFE;
6037 return true;
6040 static bool trans_WFI(DisasContext *s, arg_WFI *a)
6042 /* For WFI, halt the vCPU until an IRQ. */
6043 gen_set_pc_im(s, s->base.pc_next);
6044 s->base.is_jmp = DISAS_WFI;
6045 return true;
6048 static bool trans_NOP(DisasContext *s, arg_NOP *a)
6050 return true;
6053 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
6055 uint32_t val = ror32(a->imm, a->rot * 2);
6056 uint32_t mask = msr_mask(s, a->mask, a->r);
6058 if (gen_set_psr_im(s, mask, a->r, val)) {
6059 unallocated_encoding(s);
6061 return true;
6065 * Cyclic Redundancy Check
6068 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
6070 TCGv_i32 t1, t2, t3;
6072 if (!dc_isar_feature(aa32_crc32, s)) {
6073 return false;
6076 t1 = load_reg(s, a->rn);
6077 t2 = load_reg(s, a->rm);
6078 switch (sz) {
6079 case MO_8:
6080 gen_uxtb(t2);
6081 break;
6082 case MO_16:
6083 gen_uxth(t2);
6084 break;
6085 case MO_32:
6086 break;
6087 default:
6088 g_assert_not_reached();
6090 t3 = tcg_const_i32(1 << sz);
6091 if (c) {
6092 gen_helper_crc32c(t1, t1, t2, t3);
6093 } else {
6094 gen_helper_crc32(t1, t1, t2, t3);
6096 tcg_temp_free_i32(t2);
6097 tcg_temp_free_i32(t3);
6098 store_reg(s, a->rd, t1);
6099 return true;
6102 #define DO_CRC32(NAME, c, sz) \
6103 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6104 { return op_crc32(s, a, c, sz); }
6106 DO_CRC32(CRC32B, false, MO_8)
6107 DO_CRC32(CRC32H, false, MO_16)
6108 DO_CRC32(CRC32W, false, MO_32)
6109 DO_CRC32(CRC32CB, true, MO_8)
6110 DO_CRC32(CRC32CH, true, MO_16)
6111 DO_CRC32(CRC32CW, true, MO_32)
6113 #undef DO_CRC32
6116 * Miscellaneous instructions
6119 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
6121 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6122 return false;
6124 gen_mrs_banked(s, a->r, a->sysm, a->rd);
6125 return true;
6128 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
6130 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6131 return false;
6133 gen_msr_banked(s, a->r, a->sysm, a->rn);
6134 return true;
6137 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
6139 TCGv_i32 tmp;
6141 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6142 return false;
6144 if (a->r) {
6145 if (IS_USER(s)) {
6146 unallocated_encoding(s);
6147 return true;
6149 tmp = load_cpu_field(spsr);
6150 } else {
6151 tmp = tcg_temp_new_i32();
6152 gen_helper_cpsr_read(tmp, cpu_env);
6154 store_reg(s, a->rd, tmp);
6155 return true;
6158 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
6160 TCGv_i32 tmp;
6161 uint32_t mask = msr_mask(s, a->mask, a->r);
6163 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6164 return false;
6166 tmp = load_reg(s, a->rn);
6167 if (gen_set_psr(s, mask, a->r, tmp)) {
6168 unallocated_encoding(s);
6170 return true;
6173 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
6175 TCGv_i32 tmp;
6177 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
6178 return false;
6180 tmp = tcg_const_i32(a->sysm);
6181 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
6182 store_reg(s, a->rd, tmp);
6183 return true;
6186 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
6188 TCGv_i32 addr, reg;
6190 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
6191 return false;
6193 addr = tcg_const_i32((a->mask << 10) | a->sysm);
6194 reg = load_reg(s, a->rn);
6195 gen_helper_v7m_msr(cpu_env, addr, reg);
6196 tcg_temp_free_i32(addr);
6197 tcg_temp_free_i32(reg);
6198 /* If we wrote to CONTROL, the EL might have changed */
6199 gen_helper_rebuild_hflags_m32_newel(cpu_env);
6200 gen_lookup_tb(s);
6201 return true;
6204 static bool trans_BX(DisasContext *s, arg_BX *a)
6206 if (!ENABLE_ARCH_4T) {
6207 return false;
6209 gen_bx_excret(s, load_reg(s, a->rm));
6210 return true;
6213 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
6215 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
6216 return false;
6218 /* Trivial implementation equivalent to bx. */
6219 gen_bx(s, load_reg(s, a->rm));
6220 return true;
6223 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
6225 TCGv_i32 tmp;
6227 if (!ENABLE_ARCH_5) {
6228 return false;
6230 tmp = load_reg(s, a->rm);
6231 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
6232 gen_bx(s, tmp);
6233 return true;
6237 * BXNS/BLXNS: only exist for v8M with the security extensions,
6238 * and always UNDEF if NonSecure. We don't implement these in
6239 * the user-only mode either (in theory you can use them from
6240 * Secure User mode but they are too tied in to system emulation).
6242 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
6244 if (!s->v8m_secure || IS_USER_ONLY) {
6245 unallocated_encoding(s);
6246 } else {
6247 gen_bxns(s, a->rm);
6249 return true;
6252 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
6254 if (!s->v8m_secure || IS_USER_ONLY) {
6255 unallocated_encoding(s);
6256 } else {
6257 gen_blxns(s, a->rm);
6259 return true;
6262 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
6264 TCGv_i32 tmp;
6266 if (!ENABLE_ARCH_5) {
6267 return false;
6269 tmp = load_reg(s, a->rm);
6270 tcg_gen_clzi_i32(tmp, tmp, 32);
6271 store_reg(s, a->rd, tmp);
6272 return true;
6275 static bool trans_ERET(DisasContext *s, arg_ERET *a)
6277 TCGv_i32 tmp;
6279 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
6280 return false;
6282 if (IS_USER(s)) {
6283 unallocated_encoding(s);
6284 return true;
6286 if (s->current_el == 2) {
6287 /* ERET from Hyp uses ELR_Hyp, not LR */
6288 tmp = load_cpu_field(elr_el[2]);
6289 } else {
6290 tmp = load_reg(s, 14);
6292 gen_exception_return(s, tmp);
6293 return true;
6296 static bool trans_HLT(DisasContext *s, arg_HLT *a)
6298 gen_hlt(s, a->imm);
6299 return true;
6302 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
6304 if (!ENABLE_ARCH_5) {
6305 return false;
6307 if (arm_dc_feature(s, ARM_FEATURE_M) &&
6308 semihosting_enabled() &&
6309 #ifndef CONFIG_USER_ONLY
6310 !IS_USER(s) &&
6311 #endif
6312 (a->imm == 0xab)) {
6313 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
6314 } else {
6315 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
6317 return true;
6320 static bool trans_HVC(DisasContext *s, arg_HVC *a)
6322 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
6323 return false;
6325 if (IS_USER(s)) {
6326 unallocated_encoding(s);
6327 } else {
6328 gen_hvc(s, a->imm);
6330 return true;
6333 static bool trans_SMC(DisasContext *s, arg_SMC *a)
6335 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
6336 return false;
6338 if (IS_USER(s)) {
6339 unallocated_encoding(s);
6340 } else {
6341 gen_smc(s);
6343 return true;
6346 static bool trans_SG(DisasContext *s, arg_SG *a)
6348 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
6349 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6350 return false;
6353 * SG (v8M only)
6354 * The bulk of the behaviour for this instruction is implemented
6355 * in v7m_handle_execute_nsc(), which deals with the insn when
6356 * it is executed by a CPU in non-secure state from memory
6357 * which is Secure & NonSecure-Callable.
6358 * Here we only need to handle the remaining cases:
6359 * * in NS memory (including the "security extension not
6360 * implemented" case) : NOP
6361 * * in S memory but CPU already secure (clear IT bits)
6362 * We know that the attribute for the memory this insn is
6363 * in must match the current CPU state, because otherwise
6364 * get_phys_addr_pmsav8 would have generated an exception.
6366 if (s->v8m_secure) {
6367 /* Like the IT insn, we don't need to generate any code */
6368 s->condexec_cond = 0;
6369 s->condexec_mask = 0;
6371 return true;
6374 static bool trans_TT(DisasContext *s, arg_TT *a)
6376 TCGv_i32 addr, tmp;
6378 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
6379 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6380 return false;
6382 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
6383 /* We UNDEF for these UNPREDICTABLE cases */
6384 unallocated_encoding(s);
6385 return true;
6387 if (a->A && !s->v8m_secure) {
6388 /* This case is UNDEFINED. */
6389 unallocated_encoding(s);
6390 return true;
6393 addr = load_reg(s, a->rn);
6394 tmp = tcg_const_i32((a->A << 1) | a->T);
6395 gen_helper_v7m_tt(tmp, cpu_env, addr, tmp);
6396 tcg_temp_free_i32(addr);
6397 store_reg(s, a->rd, tmp);
6398 return true;
6402 * Load/store register index
6405 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
6407 ISSInfo ret;
6409 /* ISS not valid if writeback */
6410 if (p && !w) {
6411 ret = rd;
6412 if (s->base.pc_next - s->pc_curr == 2) {
6413 ret |= ISSIs16Bit;
6415 } else {
6416 ret = ISSInvalid;
6418 return ret;
6421 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
6423 TCGv_i32 addr = load_reg(s, a->rn);
6425 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
6426 gen_helper_v8m_stackcheck(cpu_env, addr);
6429 if (a->p) {
6430 TCGv_i32 ofs = load_reg(s, a->rm);
6431 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
6432 if (a->u) {
6433 tcg_gen_add_i32(addr, addr, ofs);
6434 } else {
6435 tcg_gen_sub_i32(addr, addr, ofs);
6437 tcg_temp_free_i32(ofs);
6439 return addr;
6442 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
6443 TCGv_i32 addr, int address_offset)
6445 if (!a->p) {
6446 TCGv_i32 ofs = load_reg(s, a->rm);
6447 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
6448 if (a->u) {
6449 tcg_gen_add_i32(addr, addr, ofs);
6450 } else {
6451 tcg_gen_sub_i32(addr, addr, ofs);
6453 tcg_temp_free_i32(ofs);
6454 } else if (!a->w) {
6455 tcg_temp_free_i32(addr);
6456 return;
6458 tcg_gen_addi_i32(addr, addr, address_offset);
6459 store_reg(s, a->rn, addr);
6462 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
6463 MemOp mop, int mem_idx)
6465 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
6466 TCGv_i32 addr, tmp;
6468 addr = op_addr_rr_pre(s, a);
6470 tmp = tcg_temp_new_i32();
6471 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
6472 disas_set_da_iss(s, mop, issinfo);
6475 * Perform base writeback before the loaded value to
6476 * ensure correct behavior with overlapping index registers.
6478 op_addr_rr_post(s, a, addr, 0);
6479 store_reg_from_load(s, a->rt, tmp);
6480 return true;
6483 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
6484 MemOp mop, int mem_idx)
6486 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
6487 TCGv_i32 addr, tmp;
6490 * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
6491 * is either UNPREDICTABLE or has defined behaviour
6493 if (s->thumb && a->rn == 15) {
6494 return false;
6497 addr = op_addr_rr_pre(s, a);
6499 tmp = load_reg(s, a->rt);
6500 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
6501 disas_set_da_iss(s, mop, issinfo);
6502 tcg_temp_free_i32(tmp);
6504 op_addr_rr_post(s, a, addr, 0);
6505 return true;
6508 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
6510 int mem_idx = get_mem_index(s);
6511 TCGv_i32 addr, tmp;
6513 if (!ENABLE_ARCH_5TE) {
6514 return false;
6516 if (a->rt & 1) {
6517 unallocated_encoding(s);
6518 return true;
6520 addr = op_addr_rr_pre(s, a);
6522 tmp = tcg_temp_new_i32();
6523 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6524 store_reg(s, a->rt, tmp);
6526 tcg_gen_addi_i32(addr, addr, 4);
6528 tmp = tcg_temp_new_i32();
6529 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6530 store_reg(s, a->rt + 1, tmp);
6532 /* LDRD w/ base writeback is undefined if the registers overlap. */
6533 op_addr_rr_post(s, a, addr, -4);
6534 return true;
6537 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
6539 int mem_idx = get_mem_index(s);
6540 TCGv_i32 addr, tmp;
6542 if (!ENABLE_ARCH_5TE) {
6543 return false;
6545 if (a->rt & 1) {
6546 unallocated_encoding(s);
6547 return true;
6549 addr = op_addr_rr_pre(s, a);
6551 tmp = load_reg(s, a->rt);
6552 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6553 tcg_temp_free_i32(tmp);
6555 tcg_gen_addi_i32(addr, addr, 4);
6557 tmp = load_reg(s, a->rt + 1);
6558 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6559 tcg_temp_free_i32(tmp);
6561 op_addr_rr_post(s, a, addr, -4);
6562 return true;
6566 * Load/store immediate index
6569 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
6571 int ofs = a->imm;
6573 if (!a->u) {
6574 ofs = -ofs;
6577 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
6579 * Stackcheck. Here we know 'addr' is the current SP;
6580 * U is set if we're moving SP up, else down. It is
6581 * UNKNOWN whether the limit check triggers when SP starts
6582 * below the limit and ends up above it; we chose to do so.
6584 if (!a->u) {
6585 TCGv_i32 newsp = tcg_temp_new_i32();
6586 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
6587 gen_helper_v8m_stackcheck(cpu_env, newsp);
6588 tcg_temp_free_i32(newsp);
6589 } else {
6590 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
6594 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
6597 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
6598 TCGv_i32 addr, int address_offset)
6600 if (!a->p) {
6601 if (a->u) {
6602 address_offset += a->imm;
6603 } else {
6604 address_offset -= a->imm;
6606 } else if (!a->w) {
6607 tcg_temp_free_i32(addr);
6608 return;
6610 tcg_gen_addi_i32(addr, addr, address_offset);
6611 store_reg(s, a->rn, addr);
6614 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
6615 MemOp mop, int mem_idx)
6617 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
6618 TCGv_i32 addr, tmp;
6620 addr = op_addr_ri_pre(s, a);
6622 tmp = tcg_temp_new_i32();
6623 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
6624 disas_set_da_iss(s, mop, issinfo);
6627 * Perform base writeback before the loaded value to
6628 * ensure correct behavior with overlapping index registers.
6630 op_addr_ri_post(s, a, addr, 0);
6631 store_reg_from_load(s, a->rt, tmp);
6632 return true;
6635 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
6636 MemOp mop, int mem_idx)
6638 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
6639 TCGv_i32 addr, tmp;
6642 * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
6643 * is either UNPREDICTABLE or has defined behaviour
6645 if (s->thumb && a->rn == 15) {
6646 return false;
6649 addr = op_addr_ri_pre(s, a);
6651 tmp = load_reg(s, a->rt);
6652 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
6653 disas_set_da_iss(s, mop, issinfo);
6654 tcg_temp_free_i32(tmp);
6656 op_addr_ri_post(s, a, addr, 0);
6657 return true;
6660 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
6662 int mem_idx = get_mem_index(s);
6663 TCGv_i32 addr, tmp;
6665 addr = op_addr_ri_pre(s, a);
6667 tmp = tcg_temp_new_i32();
6668 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6669 store_reg(s, a->rt, tmp);
6671 tcg_gen_addi_i32(addr, addr, 4);
6673 tmp = tcg_temp_new_i32();
6674 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6675 store_reg(s, rt2, tmp);
6677 /* LDRD w/ base writeback is undefined if the registers overlap. */
6678 op_addr_ri_post(s, a, addr, -4);
6679 return true;
6682 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
6684 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
6685 return false;
6687 return op_ldrd_ri(s, a, a->rt + 1);
6690 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
6692 arg_ldst_ri b = {
6693 .u = a->u, .w = a->w, .p = a->p,
6694 .rn = a->rn, .rt = a->rt, .imm = a->imm
6696 return op_ldrd_ri(s, &b, a->rt2);
6699 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
6701 int mem_idx = get_mem_index(s);
6702 TCGv_i32 addr, tmp;
6704 addr = op_addr_ri_pre(s, a);
6706 tmp = load_reg(s, a->rt);
6707 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6708 tcg_temp_free_i32(tmp);
6710 tcg_gen_addi_i32(addr, addr, 4);
6712 tmp = load_reg(s, rt2);
6713 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6714 tcg_temp_free_i32(tmp);
6716 op_addr_ri_post(s, a, addr, -4);
6717 return true;
6720 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
6722 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
6723 return false;
6725 return op_strd_ri(s, a, a->rt + 1);
6728 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
6730 arg_ldst_ri b = {
6731 .u = a->u, .w = a->w, .p = a->p,
6732 .rn = a->rn, .rt = a->rt, .imm = a->imm
6734 return op_strd_ri(s, &b, a->rt2);
6737 #define DO_LDST(NAME, WHICH, MEMOP) \
6738 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
6740 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
6742 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
6744 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
6746 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
6748 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
6750 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
6752 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
6755 DO_LDST(LDR, load, MO_UL)
6756 DO_LDST(LDRB, load, MO_UB)
6757 DO_LDST(LDRH, load, MO_UW)
6758 DO_LDST(LDRSB, load, MO_SB)
6759 DO_LDST(LDRSH, load, MO_SW)
6761 DO_LDST(STR, store, MO_UL)
6762 DO_LDST(STRB, store, MO_UB)
6763 DO_LDST(STRH, store, MO_UW)
6765 #undef DO_LDST
6768 * Synchronization primitives
6771 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
6773 TCGv_i32 addr, tmp;
6774 TCGv taddr;
6776 opc |= s->be_data;
6777 addr = load_reg(s, a->rn);
6778 taddr = gen_aa32_addr(s, addr, opc);
6779 tcg_temp_free_i32(addr);
6781 tmp = load_reg(s, a->rt2);
6782 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
6783 tcg_temp_free(taddr);
6785 store_reg(s, a->rt, tmp);
6786 return true;
6789 static bool trans_SWP(DisasContext *s, arg_SWP *a)
6791 return op_swp(s, a, MO_UL | MO_ALIGN);
6794 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
6796 return op_swp(s, a, MO_UB);
6800 * Load/Store Exclusive and Load-Acquire/Store-Release
6803 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
6805 TCGv_i32 addr;
6806 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
6807 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
6809 /* We UNDEF for these UNPREDICTABLE cases. */
6810 if (a->rd == 15 || a->rn == 15 || a->rt == 15
6811 || a->rd == a->rn || a->rd == a->rt
6812 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
6813 || (mop == MO_64
6814 && (a->rt2 == 15
6815 || a->rd == a->rt2
6816 || (!v8a && s->thumb && a->rt2 == 13)))) {
6817 unallocated_encoding(s);
6818 return true;
6821 if (rel) {
6822 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
6825 addr = tcg_temp_local_new_i32();
6826 load_reg_var(s, addr, a->rn);
6827 tcg_gen_addi_i32(addr, addr, a->imm);
6829 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
6830 tcg_temp_free_i32(addr);
6831 return true;
6834 static bool trans_STREX(DisasContext *s, arg_STREX *a)
6836 if (!ENABLE_ARCH_6) {
6837 return false;
6839 return op_strex(s, a, MO_32, false);
6842 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
6844 if (!ENABLE_ARCH_6K) {
6845 return false;
6847 /* We UNDEF for these UNPREDICTABLE cases. */
6848 if (a->rt & 1) {
6849 unallocated_encoding(s);
6850 return true;
6852 a->rt2 = a->rt + 1;
6853 return op_strex(s, a, MO_64, false);
6856 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
6858 return op_strex(s, a, MO_64, false);
6861 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
6863 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
6864 return false;
6866 return op_strex(s, a, MO_8, false);
6869 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
6871 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
6872 return false;
6874 return op_strex(s, a, MO_16, false);
6877 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
6879 if (!ENABLE_ARCH_8) {
6880 return false;
6882 return op_strex(s, a, MO_32, true);
6885 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
6887 if (!ENABLE_ARCH_8) {
6888 return false;
6890 /* We UNDEF for these UNPREDICTABLE cases. */
6891 if (a->rt & 1) {
6892 unallocated_encoding(s);
6893 return true;
6895 a->rt2 = a->rt + 1;
6896 return op_strex(s, a, MO_64, true);
6899 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
6901 if (!ENABLE_ARCH_8) {
6902 return false;
6904 return op_strex(s, a, MO_64, true);
6907 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
6909 if (!ENABLE_ARCH_8) {
6910 return false;
6912 return op_strex(s, a, MO_8, true);
6915 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
6917 if (!ENABLE_ARCH_8) {
6918 return false;
6920 return op_strex(s, a, MO_16, true);
6923 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
6925 TCGv_i32 addr, tmp;
6927 if (!ENABLE_ARCH_8) {
6928 return false;
6930 /* We UNDEF for these UNPREDICTABLE cases. */
6931 if (a->rn == 15 || a->rt == 15) {
6932 unallocated_encoding(s);
6933 return true;
6936 addr = load_reg(s, a->rn);
6937 tmp = load_reg(s, a->rt);
6938 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
6939 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop);
6940 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
6942 tcg_temp_free_i32(tmp);
6943 tcg_temp_free_i32(addr);
6944 return true;
6947 static bool trans_STL(DisasContext *s, arg_STL *a)
6949 return op_stl(s, a, MO_UL);
6952 static bool trans_STLB(DisasContext *s, arg_STL *a)
6954 return op_stl(s, a, MO_UB);
6957 static bool trans_STLH(DisasContext *s, arg_STL *a)
6959 return op_stl(s, a, MO_UW);
6962 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
6964 TCGv_i32 addr;
6965 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
6966 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
6968 /* We UNDEF for these UNPREDICTABLE cases. */
6969 if (a->rn == 15 || a->rt == 15
6970 || (!v8a && s->thumb && a->rt == 13)
6971 || (mop == MO_64
6972 && (a->rt2 == 15 || a->rt == a->rt2
6973 || (!v8a && s->thumb && a->rt2 == 13)))) {
6974 unallocated_encoding(s);
6975 return true;
6978 addr = tcg_temp_local_new_i32();
6979 load_reg_var(s, addr, a->rn);
6980 tcg_gen_addi_i32(addr, addr, a->imm);
6982 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
6983 tcg_temp_free_i32(addr);
6985 if (acq) {
6986 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
6988 return true;
6991 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
6993 if (!ENABLE_ARCH_6) {
6994 return false;
6996 return op_ldrex(s, a, MO_32, false);
6999 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
7001 if (!ENABLE_ARCH_6K) {
7002 return false;
7004 /* We UNDEF for these UNPREDICTABLE cases. */
7005 if (a->rt & 1) {
7006 unallocated_encoding(s);
7007 return true;
7009 a->rt2 = a->rt + 1;
7010 return op_ldrex(s, a, MO_64, false);
7013 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
7015 return op_ldrex(s, a, MO_64, false);
7018 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
7020 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7021 return false;
7023 return op_ldrex(s, a, MO_8, false);
7026 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
7028 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7029 return false;
7031 return op_ldrex(s, a, MO_16, false);
7034 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
7036 if (!ENABLE_ARCH_8) {
7037 return false;
7039 return op_ldrex(s, a, MO_32, true);
7042 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
7044 if (!ENABLE_ARCH_8) {
7045 return false;
7047 /* We UNDEF for these UNPREDICTABLE cases. */
7048 if (a->rt & 1) {
7049 unallocated_encoding(s);
7050 return true;
7052 a->rt2 = a->rt + 1;
7053 return op_ldrex(s, a, MO_64, true);
7056 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
7058 if (!ENABLE_ARCH_8) {
7059 return false;
7061 return op_ldrex(s, a, MO_64, true);
7064 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
7066 if (!ENABLE_ARCH_8) {
7067 return false;
7069 return op_ldrex(s, a, MO_8, true);
7072 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
7074 if (!ENABLE_ARCH_8) {
7075 return false;
7077 return op_ldrex(s, a, MO_16, true);
7080 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
7082 TCGv_i32 addr, tmp;
7084 if (!ENABLE_ARCH_8) {
7085 return false;
7087 /* We UNDEF for these UNPREDICTABLE cases. */
7088 if (a->rn == 15 || a->rt == 15) {
7089 unallocated_encoding(s);
7090 return true;
7093 addr = load_reg(s, a->rn);
7094 tmp = tcg_temp_new_i32();
7095 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop);
7096 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
7097 tcg_temp_free_i32(addr);
7099 store_reg(s, a->rt, tmp);
7100 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7101 return true;
7104 static bool trans_LDA(DisasContext *s, arg_LDA *a)
7106 return op_lda(s, a, MO_UL);
7109 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
7111 return op_lda(s, a, MO_UB);
7114 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
7116 return op_lda(s, a, MO_UW);
7120 * Media instructions
7123 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
7125 TCGv_i32 t1, t2;
7127 if (!ENABLE_ARCH_6) {
7128 return false;
7131 t1 = load_reg(s, a->rn);
7132 t2 = load_reg(s, a->rm);
7133 gen_helper_usad8(t1, t1, t2);
7134 tcg_temp_free_i32(t2);
7135 if (a->ra != 15) {
7136 t2 = load_reg(s, a->ra);
7137 tcg_gen_add_i32(t1, t1, t2);
7138 tcg_temp_free_i32(t2);
7140 store_reg(s, a->rd, t1);
7141 return true;
7144 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
7146 TCGv_i32 tmp;
7147 int width = a->widthm1 + 1;
7148 int shift = a->lsb;
7150 if (!ENABLE_ARCH_6T2) {
7151 return false;
7153 if (shift + width > 32) {
7154 /* UNPREDICTABLE; we choose to UNDEF */
7155 unallocated_encoding(s);
7156 return true;
7159 tmp = load_reg(s, a->rn);
7160 if (u) {
7161 tcg_gen_extract_i32(tmp, tmp, shift, width);
7162 } else {
7163 tcg_gen_sextract_i32(tmp, tmp, shift, width);
7165 store_reg(s, a->rd, tmp);
7166 return true;
7169 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
7171 return op_bfx(s, a, false);
7174 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
7176 return op_bfx(s, a, true);
7179 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
7181 TCGv_i32 tmp;
7182 int msb = a->msb, lsb = a->lsb;
7183 int width;
7185 if (!ENABLE_ARCH_6T2) {
7186 return false;
7188 if (msb < lsb) {
7189 /* UNPREDICTABLE; we choose to UNDEF */
7190 unallocated_encoding(s);
7191 return true;
7194 width = msb + 1 - lsb;
7195 if (a->rn == 15) {
7196 /* BFC */
7197 tmp = tcg_const_i32(0);
7198 } else {
7199 /* BFI */
7200 tmp = load_reg(s, a->rn);
7202 if (width != 32) {
7203 TCGv_i32 tmp2 = load_reg(s, a->rd);
7204 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
7205 tcg_temp_free_i32(tmp2);
7207 store_reg(s, a->rd, tmp);
7208 return true;
7211 static bool trans_UDF(DisasContext *s, arg_UDF *a)
7213 unallocated_encoding(s);
7214 return true;
7218 * Parallel addition and subtraction
7221 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
7222 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
7224 TCGv_i32 t0, t1;
7226 if (s->thumb
7227 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7228 : !ENABLE_ARCH_6) {
7229 return false;
7232 t0 = load_reg(s, a->rn);
7233 t1 = load_reg(s, a->rm);
7235 gen(t0, t0, t1);
7237 tcg_temp_free_i32(t1);
7238 store_reg(s, a->rd, t0);
7239 return true;
7242 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
7243 void (*gen)(TCGv_i32, TCGv_i32,
7244 TCGv_i32, TCGv_ptr))
7246 TCGv_i32 t0, t1;
7247 TCGv_ptr ge;
7249 if (s->thumb
7250 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7251 : !ENABLE_ARCH_6) {
7252 return false;
7255 t0 = load_reg(s, a->rn);
7256 t1 = load_reg(s, a->rm);
7258 ge = tcg_temp_new_ptr();
7259 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
7260 gen(t0, t0, t1, ge);
7262 tcg_temp_free_ptr(ge);
7263 tcg_temp_free_i32(t1);
7264 store_reg(s, a->rd, t0);
7265 return true;
7268 #define DO_PAR_ADDSUB(NAME, helper) \
7269 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7271 return op_par_addsub(s, a, helper); \
7274 #define DO_PAR_ADDSUB_GE(NAME, helper) \
7275 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7277 return op_par_addsub_ge(s, a, helper); \
7280 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
7281 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
7282 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
7283 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
7284 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
7285 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
7287 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
7288 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
7289 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
7290 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
7291 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
7292 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
7294 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
7295 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
7296 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
7297 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
7298 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
7299 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
7301 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
7302 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
7303 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
7304 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
7305 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
7306 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
7308 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
7309 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
7310 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
7311 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
7312 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
7313 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
7315 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
7316 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
7317 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
7318 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
7319 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
7320 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
7322 #undef DO_PAR_ADDSUB
7323 #undef DO_PAR_ADDSUB_GE
7326 * Packing, unpacking, saturation, and reversal
7329 static bool trans_PKH(DisasContext *s, arg_PKH *a)
7331 TCGv_i32 tn, tm;
7332 int shift = a->imm;
7334 if (s->thumb
7335 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7336 : !ENABLE_ARCH_6) {
7337 return false;
7340 tn = load_reg(s, a->rn);
7341 tm = load_reg(s, a->rm);
7342 if (a->tb) {
7343 /* PKHTB */
7344 if (shift == 0) {
7345 shift = 31;
7347 tcg_gen_sari_i32(tm, tm, shift);
7348 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
7349 } else {
7350 /* PKHBT */
7351 tcg_gen_shli_i32(tm, tm, shift);
7352 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
7354 tcg_temp_free_i32(tm);
7355 store_reg(s, a->rd, tn);
7356 return true;
7359 static bool op_sat(DisasContext *s, arg_sat *a,
7360 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
7362 TCGv_i32 tmp, satimm;
7363 int shift = a->imm;
7365 if (!ENABLE_ARCH_6) {
7366 return false;
7369 tmp = load_reg(s, a->rn);
7370 if (a->sh) {
7371 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
7372 } else {
7373 tcg_gen_shli_i32(tmp, tmp, shift);
7376 satimm = tcg_const_i32(a->satimm);
7377 gen(tmp, cpu_env, tmp, satimm);
7378 tcg_temp_free_i32(satimm);
7380 store_reg(s, a->rd, tmp);
7381 return true;
7384 static bool trans_SSAT(DisasContext *s, arg_sat *a)
7386 return op_sat(s, a, gen_helper_ssat);
7389 static bool trans_USAT(DisasContext *s, arg_sat *a)
7391 return op_sat(s, a, gen_helper_usat);
7394 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
7396 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7397 return false;
7399 return op_sat(s, a, gen_helper_ssat16);
7402 static bool trans_USAT16(DisasContext *s, arg_sat *a)
7404 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7405 return false;
7407 return op_sat(s, a, gen_helper_usat16);
7410 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
7411 void (*gen_extract)(TCGv_i32, TCGv_i32),
7412 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
7414 TCGv_i32 tmp;
7416 if (!ENABLE_ARCH_6) {
7417 return false;
7420 tmp = load_reg(s, a->rm);
7422 * TODO: In many cases we could do a shift instead of a rotate.
7423 * Combined with a simple extend, that becomes an extract.
7425 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
7426 gen_extract(tmp, tmp);
7428 if (a->rn != 15) {
7429 TCGv_i32 tmp2 = load_reg(s, a->rn);
7430 gen_add(tmp, tmp, tmp2);
7431 tcg_temp_free_i32(tmp2);
7433 store_reg(s, a->rd, tmp);
7434 return true;
7437 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
7439 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
7442 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
7444 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
7447 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
7449 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7450 return false;
7452 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
7455 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
7457 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
7460 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
7462 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
7465 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
7467 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7468 return false;
7470 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
7473 static bool trans_SEL(DisasContext *s, arg_rrr *a)
7475 TCGv_i32 t1, t2, t3;
7477 if (s->thumb
7478 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7479 : !ENABLE_ARCH_6) {
7480 return false;
7483 t1 = load_reg(s, a->rn);
7484 t2 = load_reg(s, a->rm);
7485 t3 = tcg_temp_new_i32();
7486 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
7487 gen_helper_sel_flags(t1, t3, t1, t2);
7488 tcg_temp_free_i32(t3);
7489 tcg_temp_free_i32(t2);
7490 store_reg(s, a->rd, t1);
7491 return true;
7494 static bool op_rr(DisasContext *s, arg_rr *a,
7495 void (*gen)(TCGv_i32, TCGv_i32))
7497 TCGv_i32 tmp;
7499 tmp = load_reg(s, a->rm);
7500 gen(tmp, tmp);
7501 store_reg(s, a->rd, tmp);
7502 return true;
7505 static bool trans_REV(DisasContext *s, arg_rr *a)
7507 if (!ENABLE_ARCH_6) {
7508 return false;
7510 return op_rr(s, a, tcg_gen_bswap32_i32);
7513 static bool trans_REV16(DisasContext *s, arg_rr *a)
7515 if (!ENABLE_ARCH_6) {
7516 return false;
7518 return op_rr(s, a, gen_rev16);
7521 static bool trans_REVSH(DisasContext *s, arg_rr *a)
7523 if (!ENABLE_ARCH_6) {
7524 return false;
7526 return op_rr(s, a, gen_revsh);
7529 static bool trans_RBIT(DisasContext *s, arg_rr *a)
7531 if (!ENABLE_ARCH_6T2) {
7532 return false;
7534 return op_rr(s, a, gen_helper_rbit);
7538 * Signed multiply, signed and unsigned divide
7541 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
7543 TCGv_i32 t1, t2;
7545 if (!ENABLE_ARCH_6) {
7546 return false;
7549 t1 = load_reg(s, a->rn);
7550 t2 = load_reg(s, a->rm);
7551 if (m_swap) {
7552 gen_swap_half(t2, t2);
7554 gen_smul_dual(t1, t2);
7556 if (sub) {
7558 * This subtraction cannot overflow, so we can do a simple
7559 * 32-bit subtraction and then a possible 32-bit saturating
7560 * addition of Ra.
7562 tcg_gen_sub_i32(t1, t1, t2);
7563 tcg_temp_free_i32(t2);
7565 if (a->ra != 15) {
7566 t2 = load_reg(s, a->ra);
7567 gen_helper_add_setq(t1, cpu_env, t1, t2);
7568 tcg_temp_free_i32(t2);
7570 } else if (a->ra == 15) {
7571 /* Single saturation-checking addition */
7572 gen_helper_add_setq(t1, cpu_env, t1, t2);
7573 tcg_temp_free_i32(t2);
7574 } else {
7576 * We need to add the products and Ra together and then
7577 * determine whether the final result overflowed. Doing
7578 * this as two separate add-and-check-overflow steps incorrectly
7579 * sets Q for cases like (-32768 * -32768) + (-32768 * -32768) + -1.
7580 * Do all the arithmetic at 64-bits and then check for overflow.
7582 TCGv_i64 p64, q64;
7583 TCGv_i32 t3, qf, one;
7585 p64 = tcg_temp_new_i64();
7586 q64 = tcg_temp_new_i64();
7587 tcg_gen_ext_i32_i64(p64, t1);
7588 tcg_gen_ext_i32_i64(q64, t2);
7589 tcg_gen_add_i64(p64, p64, q64);
7590 load_reg_var(s, t2, a->ra);
7591 tcg_gen_ext_i32_i64(q64, t2);
7592 tcg_gen_add_i64(p64, p64, q64);
7593 tcg_temp_free_i64(q64);
7595 tcg_gen_extr_i64_i32(t1, t2, p64);
7596 tcg_temp_free_i64(p64);
7598 * t1 is the low half of the result which goes into Rd.
7599 * We have overflow and must set Q if the high half (t2)
7600 * is different from the sign-extension of t1.
7602 t3 = tcg_temp_new_i32();
7603 tcg_gen_sari_i32(t3, t1, 31);
7604 qf = load_cpu_field(QF);
7605 one = tcg_const_i32(1);
7606 tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
7607 store_cpu_field(qf, QF);
7608 tcg_temp_free_i32(one);
7609 tcg_temp_free_i32(t3);
7610 tcg_temp_free_i32(t2);
7612 store_reg(s, a->rd, t1);
7613 return true;
7616 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
7618 return op_smlad(s, a, false, false);
7621 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
7623 return op_smlad(s, a, true, false);
7626 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
7628 return op_smlad(s, a, false, true);
7631 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
7633 return op_smlad(s, a, true, true);
7636 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
7638 TCGv_i32 t1, t2;
7639 TCGv_i64 l1, l2;
7641 if (!ENABLE_ARCH_6) {
7642 return false;
7645 t1 = load_reg(s, a->rn);
7646 t2 = load_reg(s, a->rm);
7647 if (m_swap) {
7648 gen_swap_half(t2, t2);
7650 gen_smul_dual(t1, t2);
7652 l1 = tcg_temp_new_i64();
7653 l2 = tcg_temp_new_i64();
7654 tcg_gen_ext_i32_i64(l1, t1);
7655 tcg_gen_ext_i32_i64(l2, t2);
7656 tcg_temp_free_i32(t1);
7657 tcg_temp_free_i32(t2);
7659 if (sub) {
7660 tcg_gen_sub_i64(l1, l1, l2);
7661 } else {
7662 tcg_gen_add_i64(l1, l1, l2);
7664 tcg_temp_free_i64(l2);
7666 gen_addq(s, l1, a->ra, a->rd);
7667 gen_storeq_reg(s, a->ra, a->rd, l1);
7668 tcg_temp_free_i64(l1);
7669 return true;
7672 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
7674 return op_smlald(s, a, false, false);
7677 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
7679 return op_smlald(s, a, true, false);
7682 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
7684 return op_smlald(s, a, false, true);
7687 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
7689 return op_smlald(s, a, true, true);
7692 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
7694 TCGv_i32 t1, t2;
7696 if (s->thumb
7697 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7698 : !ENABLE_ARCH_6) {
7699 return false;
7702 t1 = load_reg(s, a->rn);
7703 t2 = load_reg(s, a->rm);
7704 tcg_gen_muls2_i32(t2, t1, t1, t2);
7706 if (a->ra != 15) {
7707 TCGv_i32 t3 = load_reg(s, a->ra);
7708 if (sub) {
7710 * For SMMLS, we need a 64-bit subtract. Borrow caused by
7711 * a non-zero multiplicand lowpart, and the correct result
7712 * lowpart for rounding.
7714 TCGv_i32 zero = tcg_const_i32(0);
7715 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
7716 tcg_temp_free_i32(zero);
7717 } else {
7718 tcg_gen_add_i32(t1, t1, t3);
7720 tcg_temp_free_i32(t3);
7722 if (round) {
7724 * Adding 0x80000000 to the 64-bit quantity means that we have
7725 * carry in to the high word when the low word has the msb set.
7727 tcg_gen_shri_i32(t2, t2, 31);
7728 tcg_gen_add_i32(t1, t1, t2);
7730 tcg_temp_free_i32(t2);
7731 store_reg(s, a->rd, t1);
7732 return true;
7735 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
7737 return op_smmla(s, a, false, false);
7740 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
7742 return op_smmla(s, a, true, false);
7745 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
7747 return op_smmla(s, a, false, true);
7750 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
7752 return op_smmla(s, a, true, true);
7755 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
7757 TCGv_i32 t1, t2;
7759 if (s->thumb
7760 ? !dc_isar_feature(aa32_thumb_div, s)
7761 : !dc_isar_feature(aa32_arm_div, s)) {
7762 return false;
7765 t1 = load_reg(s, a->rn);
7766 t2 = load_reg(s, a->rm);
7767 if (u) {
7768 gen_helper_udiv(t1, t1, t2);
7769 } else {
7770 gen_helper_sdiv(t1, t1, t2);
7772 tcg_temp_free_i32(t2);
7773 store_reg(s, a->rd, t1);
7774 return true;
7777 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
7779 return op_div(s, a, false);
7782 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
7784 return op_div(s, a, true);
7788 * Block data transfer
7791 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
7793 TCGv_i32 addr = load_reg(s, a->rn);
7795 if (a->b) {
7796 if (a->i) {
7797 /* pre increment */
7798 tcg_gen_addi_i32(addr, addr, 4);
7799 } else {
7800 /* pre decrement */
7801 tcg_gen_addi_i32(addr, addr, -(n * 4));
7803 } else if (!a->i && n != 1) {
7804 /* post decrement */
7805 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7808 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
7810 * If the writeback is incrementing SP rather than
7811 * decrementing it, and the initial SP is below the
7812 * stack limit but the final written-back SP would
7813 * be above, then then we must not perform any memory
7814 * accesses, but it is IMPDEF whether we generate
7815 * an exception. We choose to do so in this case.
7816 * At this point 'addr' is the lowest address, so
7817 * either the original SP (if incrementing) or our
7818 * final SP (if decrementing), so that's what we check.
7820 gen_helper_v8m_stackcheck(cpu_env, addr);
7823 return addr;
7826 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
7827 TCGv_i32 addr, int n)
7829 if (a->w) {
7830 /* write back */
7831 if (!a->b) {
7832 if (a->i) {
7833 /* post increment */
7834 tcg_gen_addi_i32(addr, addr, 4);
7835 } else {
7836 /* post decrement */
7837 tcg_gen_addi_i32(addr, addr, -(n * 4));
7839 } else if (!a->i && n != 1) {
7840 /* pre decrement */
7841 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7843 store_reg(s, a->rn, addr);
7844 } else {
7845 tcg_temp_free_i32(addr);
7849 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
7851 int i, j, n, list, mem_idx;
7852 bool user = a->u;
7853 TCGv_i32 addr, tmp, tmp2;
7855 if (user) {
7856 /* STM (user) */
7857 if (IS_USER(s)) {
7858 /* Only usable in supervisor mode. */
7859 unallocated_encoding(s);
7860 return true;
7864 list = a->list;
7865 n = ctpop16(list);
7866 if (n < min_n || a->rn == 15) {
7867 unallocated_encoding(s);
7868 return true;
7871 addr = op_addr_block_pre(s, a, n);
7872 mem_idx = get_mem_index(s);
7874 for (i = j = 0; i < 16; i++) {
7875 if (!(list & (1 << i))) {
7876 continue;
7879 if (user && i != 15) {
7880 tmp = tcg_temp_new_i32();
7881 tmp2 = tcg_const_i32(i);
7882 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
7883 tcg_temp_free_i32(tmp2);
7884 } else {
7885 tmp = load_reg(s, i);
7887 gen_aa32_st32(s, tmp, addr, mem_idx);
7888 tcg_temp_free_i32(tmp);
7890 /* No need to add after the last transfer. */
7891 if (++j != n) {
7892 tcg_gen_addi_i32(addr, addr, 4);
7896 op_addr_block_post(s, a, addr, n);
7897 return true;
7900 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
7902 /* BitCount(list) < 1 is UNPREDICTABLE */
7903 return op_stm(s, a, 1);
7906 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
7908 /* Writeback register in register list is UNPREDICTABLE for T32. */
7909 if (a->w && (a->list & (1 << a->rn))) {
7910 unallocated_encoding(s);
7911 return true;
7913 /* BitCount(list) < 2 is UNPREDICTABLE */
7914 return op_stm(s, a, 2);
7917 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
7919 int i, j, n, list, mem_idx;
7920 bool loaded_base;
7921 bool user = a->u;
7922 bool exc_return = false;
7923 TCGv_i32 addr, tmp, tmp2, loaded_var;
7925 if (user) {
7926 /* LDM (user), LDM (exception return) */
7927 if (IS_USER(s)) {
7928 /* Only usable in supervisor mode. */
7929 unallocated_encoding(s);
7930 return true;
7932 if (extract32(a->list, 15, 1)) {
7933 exc_return = true;
7934 user = false;
7935 } else {
7936 /* LDM (user) does not allow writeback. */
7937 if (a->w) {
7938 unallocated_encoding(s);
7939 return true;
7944 list = a->list;
7945 n = ctpop16(list);
7946 if (n < min_n || a->rn == 15) {
7947 unallocated_encoding(s);
7948 return true;
7951 addr = op_addr_block_pre(s, a, n);
7952 mem_idx = get_mem_index(s);
7953 loaded_base = false;
7954 loaded_var = NULL;
7956 for (i = j = 0; i < 16; i++) {
7957 if (!(list & (1 << i))) {
7958 continue;
7961 tmp = tcg_temp_new_i32();
7962 gen_aa32_ld32u(s, tmp, addr, mem_idx);
7963 if (user) {
7964 tmp2 = tcg_const_i32(i);
7965 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
7966 tcg_temp_free_i32(tmp2);
7967 tcg_temp_free_i32(tmp);
7968 } else if (i == a->rn) {
7969 loaded_var = tmp;
7970 loaded_base = true;
7971 } else if (i == 15 && exc_return) {
7972 store_pc_exc_ret(s, tmp);
7973 } else {
7974 store_reg_from_load(s, i, tmp);
7977 /* No need to add after the last transfer. */
7978 if (++j != n) {
7979 tcg_gen_addi_i32(addr, addr, 4);
7983 op_addr_block_post(s, a, addr, n);
7985 if (loaded_base) {
7986 /* Note that we reject base == pc above. */
7987 store_reg(s, a->rn, loaded_var);
7990 if (exc_return) {
7991 /* Restore CPSR from SPSR. */
7992 tmp = load_cpu_field(spsr);
7993 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
7994 gen_io_start();
7996 gen_helper_cpsr_write_eret(cpu_env, tmp);
7997 tcg_temp_free_i32(tmp);
7998 /* Must exit loop to check un-masked IRQs */
7999 s->base.is_jmp = DISAS_EXIT;
8001 return true;
8004 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
8007 * Writeback register in register list is UNPREDICTABLE
8008 * for ArchVersion() >= 7. Prior to v7, A32 would write
8009 * an UNKNOWN value to the base register.
8011 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
8012 unallocated_encoding(s);
8013 return true;
8015 /* BitCount(list) < 1 is UNPREDICTABLE */
8016 return do_ldm(s, a, 1);
8019 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
8021 /* Writeback register in register list is UNPREDICTABLE for T32. */
8022 if (a->w && (a->list & (1 << a->rn))) {
8023 unallocated_encoding(s);
8024 return true;
8026 /* BitCount(list) < 2 is UNPREDICTABLE */
8027 return do_ldm(s, a, 2);
8030 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
8032 /* Writeback is conditional on the base register not being loaded. */
8033 a->w = !(a->list & (1 << a->rn));
8034 /* BitCount(list) < 1 is UNPREDICTABLE */
8035 return do_ldm(s, a, 1);
8038 static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
8040 int i;
8041 TCGv_i32 zero;
8043 if (!dc_isar_feature(aa32_m_sec_state, s)) {
8044 return false;
8047 if (extract32(a->list, 13, 1)) {
8048 return false;
8051 if (!a->list) {
8052 /* UNPREDICTABLE; we choose to UNDEF */
8053 return false;
8056 zero = tcg_const_i32(0);
8057 for (i = 0; i < 15; i++) {
8058 if (extract32(a->list, i, 1)) {
8059 /* Clear R[i] */
8060 tcg_gen_mov_i32(cpu_R[i], zero);
8063 if (extract32(a->list, 15, 1)) {
8065 * Clear APSR (by calling the MSR helper with the same argument
8066 * as for "MSR APSR_nzcvqg, Rn": mask = 0b1100, SYSM=0)
8068 TCGv_i32 maskreg = tcg_const_i32(0xc << 8);
8069 gen_helper_v7m_msr(cpu_env, maskreg, zero);
8070 tcg_temp_free_i32(maskreg);
8072 tcg_temp_free_i32(zero);
8073 return true;
8077 * Branch, branch with link
8080 static bool trans_B(DisasContext *s, arg_i *a)
8082 gen_jmp(s, read_pc(s) + a->imm);
8083 return true;
8086 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
8088 /* This has cond from encoding, required to be outside IT block. */
8089 if (a->cond >= 0xe) {
8090 return false;
8092 if (s->condexec_mask) {
8093 unallocated_encoding(s);
8094 return true;
8096 arm_skip_unless(s, a->cond);
8097 gen_jmp(s, read_pc(s) + a->imm);
8098 return true;
8101 static bool trans_BL(DisasContext *s, arg_i *a)
8103 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8104 gen_jmp(s, read_pc(s) + a->imm);
8105 return true;
8108 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
8110 TCGv_i32 tmp;
8113 * BLX <imm> would be useless on M-profile; the encoding space
8114 * is used for other insns from v8.1M onward, and UNDEFs before that.
8116 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8117 return false;
8120 /* For A32, ARM_FEATURE_V5 is checked near the start of the uncond block. */
8121 if (s->thumb && (a->imm & 2)) {
8122 return false;
8124 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8125 tmp = tcg_const_i32(!s->thumb);
8126 store_cpu_field(tmp, thumb);
8127 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
8128 return true;
8131 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
8133 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8134 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
8135 return true;
8138 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
8140 TCGv_i32 tmp = tcg_temp_new_i32();
8142 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8143 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
8144 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
8145 gen_bx(s, tmp);
8146 return true;
8149 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
8151 TCGv_i32 tmp;
8153 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8154 if (!ENABLE_ARCH_5) {
8155 return false;
8157 tmp = tcg_temp_new_i32();
8158 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
8159 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8160 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
8161 gen_bx(s, tmp);
8162 return true;
8165 static bool trans_BF(DisasContext *s, arg_BF *a)
8168 * M-profile branch future insns. The architecture permits an
8169 * implementation to implement these as NOPs (equivalent to
8170 * discarding the LO_BRANCH_INFO cache immediately), and we
8171 * take that IMPDEF option because for QEMU a "real" implementation
8172 * would be complicated and wouldn't execute any faster.
8174 if (!dc_isar_feature(aa32_lob, s)) {
8175 return false;
8177 if (a->boff == 0) {
8178 /* SEE "Related encodings" (loop insns) */
8179 return false;
8181 /* Handle as NOP */
8182 return true;
8185 static bool trans_DLS(DisasContext *s, arg_DLS *a)
8187 /* M-profile low-overhead loop start */
8188 TCGv_i32 tmp;
8190 if (!dc_isar_feature(aa32_lob, s)) {
8191 return false;
8193 if (a->rn == 13 || a->rn == 15) {
8194 /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
8195 return false;
8198 /* Not a while loop, no tail predication: just set LR to the count */
8199 tmp = load_reg(s, a->rn);
8200 store_reg(s, 14, tmp);
8201 return true;
8204 static bool trans_WLS(DisasContext *s, arg_WLS *a)
8206 /* M-profile low-overhead while-loop start */
8207 TCGv_i32 tmp;
8208 TCGLabel *nextlabel;
8210 if (!dc_isar_feature(aa32_lob, s)) {
8211 return false;
8213 if (a->rn == 13 || a->rn == 15) {
8214 /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
8215 return false;
8217 if (s->condexec_mask) {
8219 * WLS in an IT block is CONSTRAINED UNPREDICTABLE;
8220 * we choose to UNDEF, because otherwise our use of
8221 * gen_goto_tb(1) would clash with the use of TB exit 1
8222 * in the dc->condjmp condition-failed codepath in
8223 * arm_tr_tb_stop() and we'd get an assertion.
8225 return false;
8227 nextlabel = gen_new_label();
8228 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
8229 tmp = load_reg(s, a->rn);
8230 store_reg(s, 14, tmp);
8231 gen_jmp_tb(s, s->base.pc_next, 1);
8233 gen_set_label(nextlabel);
8234 gen_jmp(s, read_pc(s) + a->imm);
8235 return true;
8238 static bool trans_LE(DisasContext *s, arg_LE *a)
8241 * M-profile low-overhead loop end. The architecture permits an
8242 * implementation to discard the LO_BRANCH_INFO cache at any time,
8243 * and we take the IMPDEF option to never set it in the first place
8244 * (equivalent to always discarding it immediately), because for QEMU
8245 * a "real" implementation would be complicated and wouldn't execute
8246 * any faster.
8248 TCGv_i32 tmp;
8250 if (!dc_isar_feature(aa32_lob, s)) {
8251 return false;
8254 if (!a->f) {
8255 /* Not loop-forever. If LR <= 1 this is the last loop: do nothing. */
8256 arm_gen_condlabel(s);
8257 tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, s->condlabel);
8258 /* Decrement LR */
8259 tmp = load_reg(s, 14);
8260 tcg_gen_addi_i32(tmp, tmp, -1);
8261 store_reg(s, 14, tmp);
8263 /* Jump back to the loop start */
8264 gen_jmp(s, read_pc(s) - a->imm);
8265 return true;
8268 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
8270 TCGv_i32 addr, tmp;
8272 tmp = load_reg(s, a->rm);
8273 if (half) {
8274 tcg_gen_add_i32(tmp, tmp, tmp);
8276 addr = load_reg(s, a->rn);
8277 tcg_gen_add_i32(addr, addr, tmp);
8279 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
8280 tcg_temp_free_i32(addr);
8282 tcg_gen_add_i32(tmp, tmp, tmp);
8283 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
8284 store_reg(s, 15, tmp);
8285 return true;
8288 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
8290 return op_tbranch(s, a, false);
8293 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
8295 return op_tbranch(s, a, true);
8298 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
8300 TCGv_i32 tmp = load_reg(s, a->rn);
8302 arm_gen_condlabel(s);
8303 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
8304 tmp, 0, s->condlabel);
8305 tcg_temp_free_i32(tmp);
8306 gen_jmp(s, read_pc(s) + a->imm);
8307 return true;
8311 * Supervisor call - both T32 & A32 come here so we need to check
8312 * which mode we are in when checking for semihosting.
8315 static bool trans_SVC(DisasContext *s, arg_SVC *a)
8317 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
8319 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
8320 #ifndef CONFIG_USER_ONLY
8321 !IS_USER(s) &&
8322 #endif
8323 (a->imm == semihost_imm)) {
8324 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
8325 } else {
8326 gen_set_pc_im(s, s->base.pc_next);
8327 s->svc_imm = a->imm;
8328 s->base.is_jmp = DISAS_SWI;
8330 return true;
8334 * Unconditional system instructions
8337 static bool trans_RFE(DisasContext *s, arg_RFE *a)
8339 static const int8_t pre_offset[4] = {
8340 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
8342 static const int8_t post_offset[4] = {
8343 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
8345 TCGv_i32 addr, t1, t2;
8347 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8348 return false;
8350 if (IS_USER(s)) {
8351 unallocated_encoding(s);
8352 return true;
8355 addr = load_reg(s, a->rn);
8356 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
8358 /* Load PC into tmp and CPSR into tmp2. */
8359 t1 = tcg_temp_new_i32();
8360 gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
8361 tcg_gen_addi_i32(addr, addr, 4);
8362 t2 = tcg_temp_new_i32();
8363 gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
8365 if (a->w) {
8366 /* Base writeback. */
8367 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
8368 store_reg(s, a->rn, addr);
8369 } else {
8370 tcg_temp_free_i32(addr);
8372 gen_rfe(s, t1, t2);
8373 return true;
8376 static bool trans_SRS(DisasContext *s, arg_SRS *a)
8378 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8379 return false;
8381 gen_srs(s, a->mode, a->pu, a->w);
8382 return true;
8385 static bool trans_CPS(DisasContext *s, arg_CPS *a)
8387 uint32_t mask, val;
8389 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8390 return false;
8392 if (IS_USER(s)) {
8393 /* Implemented as NOP in user mode. */
8394 return true;
8396 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
8398 mask = val = 0;
8399 if (a->imod & 2) {
8400 if (a->A) {
8401 mask |= CPSR_A;
8403 if (a->I) {
8404 mask |= CPSR_I;
8406 if (a->F) {
8407 mask |= CPSR_F;
8409 if (a->imod & 1) {
8410 val |= mask;
8413 if (a->M) {
8414 mask |= CPSR_M;
8415 val |= a->mode;
8417 if (mask) {
8418 gen_set_psr_im(s, mask, 0, val);
8420 return true;
8423 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
8425 TCGv_i32 tmp, addr, el;
8427 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8428 return false;
8430 if (IS_USER(s)) {
8431 /* Implemented as NOP in user mode. */
8432 return true;
8435 tmp = tcg_const_i32(a->im);
8436 /* FAULTMASK */
8437 if (a->F) {
8438 addr = tcg_const_i32(19);
8439 gen_helper_v7m_msr(cpu_env, addr, tmp);
8440 tcg_temp_free_i32(addr);
8442 /* PRIMASK */
8443 if (a->I) {
8444 addr = tcg_const_i32(16);
8445 gen_helper_v7m_msr(cpu_env, addr, tmp);
8446 tcg_temp_free_i32(addr);
8448 el = tcg_const_i32(s->current_el);
8449 gen_helper_rebuild_hflags_m32(cpu_env, el);
8450 tcg_temp_free_i32(el);
8451 tcg_temp_free_i32(tmp);
8452 gen_lookup_tb(s);
8453 return true;
8457 * Clear-Exclusive, Barriers
8460 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
8462 if (s->thumb
8463 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
8464 : !ENABLE_ARCH_6K) {
8465 return false;
8467 gen_clrex(s);
8468 return true;
8471 static bool trans_DSB(DisasContext *s, arg_DSB *a)
8473 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
8474 return false;
8476 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8477 return true;
8480 static bool trans_DMB(DisasContext *s, arg_DMB *a)
8482 return trans_DSB(s, NULL);
8485 static bool trans_ISB(DisasContext *s, arg_ISB *a)
8487 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
8488 return false;
8491 * We need to break the TB after this insn to execute
8492 * self-modifying code correctly and also to take
8493 * any pending interrupts immediately.
8495 gen_goto_tb(s, 0, s->base.pc_next);
8496 return true;
8499 static bool trans_SB(DisasContext *s, arg_SB *a)
8501 if (!dc_isar_feature(aa32_sb, s)) {
8502 return false;
8505 * TODO: There is no speculation barrier opcode
8506 * for TCG; MB and end the TB instead.
8508 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8509 gen_goto_tb(s, 0, s->base.pc_next);
8510 return true;
8513 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
8515 if (!ENABLE_ARCH_6) {
8516 return false;
8518 if (a->E != (s->be_data == MO_BE)) {
8519 gen_helper_setend(cpu_env);
8520 s->base.is_jmp = DISAS_UPDATE_EXIT;
8522 return true;
8526 * Preload instructions
8527 * All are nops, contingent on the appropriate arch level.
8530 static bool trans_PLD(DisasContext *s, arg_PLD *a)
8532 return ENABLE_ARCH_5TE;
8535 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
8537 return arm_dc_feature(s, ARM_FEATURE_V7MP);
8540 static bool trans_PLI(DisasContext *s, arg_PLD *a)
8542 return ENABLE_ARCH_7;
8546 * If-then
8549 static bool trans_IT(DisasContext *s, arg_IT *a)
8551 int cond_mask = a->cond_mask;
8554 * No actual code generated for this insn, just setup state.
8556 * Combinations of firstcond and mask which set up an 0b1111
8557 * condition are UNPREDICTABLE; we take the CONSTRAINED
8558 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
8559 * i.e. both meaning "execute always".
8561 s->condexec_cond = (cond_mask >> 4) & 0xe;
8562 s->condexec_mask = cond_mask & 0x1f;
8563 return true;
8566 /* v8.1M CSEL/CSINC/CSNEG/CSINV */
8567 static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
8569 TCGv_i32 rn, rm, zero;
8570 DisasCompare c;
8572 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
8573 return false;
8576 if (a->rm == 13) {
8577 /* SEE "Related encodings" (MVE shifts) */
8578 return false;
8581 if (a->rd == 13 || a->rd == 15 || a->rn == 13 || a->fcond >= 14) {
8582 /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
8583 return false;
8586 /* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
8587 if (a->rn == 15) {
8588 rn = tcg_const_i32(0);
8589 } else {
8590 rn = load_reg(s, a->rn);
8592 if (a->rm == 15) {
8593 rm = tcg_const_i32(0);
8594 } else {
8595 rm = load_reg(s, a->rm);
8598 switch (a->op) {
8599 case 0: /* CSEL */
8600 break;
8601 case 1: /* CSINC */
8602 tcg_gen_addi_i32(rm, rm, 1);
8603 break;
8604 case 2: /* CSINV */
8605 tcg_gen_not_i32(rm, rm);
8606 break;
8607 case 3: /* CSNEG */
8608 tcg_gen_neg_i32(rm, rm);
8609 break;
8610 default:
8611 g_assert_not_reached();
8614 arm_test_cc(&c, a->fcond);
8615 zero = tcg_const_i32(0);
8616 tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
8617 arm_free_cc(&c);
8618 tcg_temp_free_i32(zero);
8620 store_reg(s, a->rd, rn);
8621 tcg_temp_free_i32(rm);
8623 return true;
8627 * Legacy decoder.
8630 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8632 unsigned int cond = insn >> 28;
8634 /* M variants do not implement ARM mode; this must raise the INVSTATE
8635 * UsageFault exception.
8637 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8638 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
8639 default_exception_el(s));
8640 return;
8643 if (cond == 0xf) {
8644 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8645 * choose to UNDEF. In ARMv5 and above the space is used
8646 * for miscellaneous unconditional instructions.
8648 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
8649 unallocated_encoding(s);
8650 return;
8653 /* Unconditional instructions. */
8654 /* TODO: Perhaps merge these into one decodetree output file. */
8655 if (disas_a32_uncond(s, insn) ||
8656 disas_vfp_uncond(s, insn) ||
8657 disas_neon_dp(s, insn) ||
8658 disas_neon_ls(s, insn) ||
8659 disas_neon_shared(s, insn)) {
8660 return;
8662 /* fall back to legacy decoder */
8664 if ((insn & 0x0e000f00) == 0x0c000100) {
8665 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8666 /* iWMMXt register transfer. */
8667 if (extract32(s->c15_cpar, 1, 1)) {
8668 if (!disas_iwmmxt_insn(s, insn)) {
8669 return;
8674 goto illegal_op;
8676 if (cond != 0xe) {
8677 /* if not always execute, we generate a conditional jump to
8678 next instruction */
8679 arm_skip_unless(s, cond);
8682 /* TODO: Perhaps merge these into one decodetree output file. */
8683 if (disas_a32(s, insn) ||
8684 disas_vfp(s, insn)) {
8685 return;
8687 /* fall back to legacy decoder */
8688 /* TODO: convert xscale/iwmmxt decoder to decodetree ?? */
8689 if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
8690 if (((insn & 0x0c000e00) == 0x0c000000)
8691 && ((insn & 0x03000000) != 0x03000000)) {
8692 /* Coprocessor insn, coprocessor 0 or 1 */
8693 disas_xscale_insn(s, insn);
8694 return;
8698 illegal_op:
8699 unallocated_encoding(s);
8702 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
8705 * Return true if this is a 16 bit instruction. We must be precise
8706 * about this (matching the decode).
8708 if ((insn >> 11) < 0x1d) {
8709 /* Definitely a 16-bit instruction */
8710 return true;
8713 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
8714 * first half of a 32-bit Thumb insn. Thumb-1 cores might
8715 * end up actually treating this as two 16-bit insns, though,
8716 * if it's half of a bl/blx pair that might span a page boundary.
8718 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
8719 arm_dc_feature(s, ARM_FEATURE_M)) {
8720 /* Thumb2 cores (including all M profile ones) always treat
8721 * 32-bit insns as 32-bit.
8723 return false;
8726 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
8727 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
8728 * is not on the next page; we merge this into a 32-bit
8729 * insn.
8731 return false;
8733 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
8734 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
8735 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
8736 * -- handle as single 16 bit insn
8738 return true;
8741 /* Translate a 32-bit thumb instruction. */
8742 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
8745 * ARMv6-M supports a limited subset of Thumb2 instructions.
8746 * Other Thumb1 architectures allow only 32-bit
8747 * combined BL/BLX prefix and suffix.
8749 if (arm_dc_feature(s, ARM_FEATURE_M) &&
8750 !arm_dc_feature(s, ARM_FEATURE_V7)) {
8751 int i;
8752 bool found = false;
8753 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
8754 0xf3b08040 /* dsb */,
8755 0xf3b08050 /* dmb */,
8756 0xf3b08060 /* isb */,
8757 0xf3e08000 /* mrs */,
8758 0xf000d000 /* bl */};
8759 static const uint32_t armv6m_mask[] = {0xffe0d000,
8760 0xfff0d0f0,
8761 0xfff0d0f0,
8762 0xfff0d0f0,
8763 0xffe0d000,
8764 0xf800d000};
8766 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
8767 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
8768 found = true;
8769 break;
8772 if (!found) {
8773 goto illegal_op;
8775 } else if ((insn & 0xf800e800) != 0xf000e800) {
8776 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
8777 unallocated_encoding(s);
8778 return;
8782 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8784 * NOCP takes precedence over any UNDEF for (almost) the
8785 * entire wide range of coprocessor-space encodings, so check
8786 * for it first before proceeding to actually decode eg VFP
8787 * insns. This decode also handles the few insns which are
8788 * in copro space but do not have NOCP checks (eg VLLDM, VLSTM).
8790 if (disas_m_nocp(s, insn)) {
8791 return;
8795 if ((insn & 0xef000000) == 0xef000000) {
8797 * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
8798 * transform into
8799 * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
8801 uint32_t a32_insn = (insn & 0xe2ffffff) |
8802 ((insn & (1 << 28)) >> 4) | (1 << 28);
8804 if (disas_neon_dp(s, a32_insn)) {
8805 return;
8809 if ((insn & 0xff100000) == 0xf9000000) {
8811 * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
8812 * transform into
8813 * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
8815 uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
8817 if (disas_neon_ls(s, a32_insn)) {
8818 return;
8823 * TODO: Perhaps merge these into one decodetree output file.
8824 * Note disas_vfp is written for a32 with cond field in the
8825 * top nibble. The t32 encoding requires 0xe in the top nibble.
8827 if (disas_t32(s, insn) ||
8828 disas_vfp_uncond(s, insn) ||
8829 disas_neon_shared(s, insn) ||
8830 ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
8831 return;
8834 illegal_op:
8835 unallocated_encoding(s);
8838 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
8840 if (!disas_t16(s, insn)) {
8841 unallocated_encoding(s);
8845 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
8847 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
8848 * (False positives are OK, false negatives are not.)
8849 * We know this is a Thumb insn, and our caller ensures we are
8850 * only called if dc->base.pc_next is less than 4 bytes from the page
8851 * boundary, so we cross the page if the first 16 bits indicate
8852 * that this is a 32 bit insn.
8854 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
8856 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
8859 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
8861 DisasContext *dc = container_of(dcbase, DisasContext, base);
8862 CPUARMState *env = cs->env_ptr;
8863 ARMCPU *cpu = env_archcpu(env);
8864 CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
8865 uint32_t condexec, core_mmu_idx;
8867 dc->isar = &cpu->isar;
8868 dc->condjmp = 0;
8870 dc->aarch64 = 0;
8871 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
8872 * there is no secure EL1, so we route exceptions to EL3.
8874 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
8875 !arm_el_is_aa64(env, 3);
8876 dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
8877 dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
8878 condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
8879 dc->condexec_mask = (condexec & 0xf) << 1;
8880 dc->condexec_cond = condexec >> 4;
8882 core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
8883 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
8884 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
8885 #if !defined(CONFIG_USER_ONLY)
8886 dc->user = (dc->current_el == 0);
8887 #endif
8888 dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
8889 dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
8891 if (arm_feature(env, ARM_FEATURE_M)) {
8892 dc->vfp_enabled = 1;
8893 dc->be_data = MO_TE;
8894 dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
8895 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
8896 regime_is_secure(env, dc->mmu_idx);
8897 dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
8898 dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
8899 dc->v7m_new_fp_ctxt_needed =
8900 EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
8901 dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
8902 } else {
8903 dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
8904 dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
8905 dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
8906 dc->ns = EX_TBFLAG_A32(tb_flags, NS);
8907 dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
8908 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
8909 dc->c15_cpar = EX_TBFLAG_A32(tb_flags, XSCALE_CPAR);
8910 } else {
8911 dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
8912 dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
8915 dc->cp_regs = cpu->cp_regs;
8916 dc->features = env->features;
8918 /* Single step state. The code-generation logic here is:
8919 * SS_ACTIVE == 0:
8920 * generate code with no special handling for single-stepping (except
8921 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
8922 * this happens anyway because those changes are all system register or
8923 * PSTATE writes).
8924 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
8925 * emit code for one insn
8926 * emit code to clear PSTATE.SS
8927 * emit code to generate software step exception for completed step
8928 * end TB (as usual for having generated an exception)
8929 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
8930 * emit code to generate a software step exception
8931 * end the TB
8933 dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
8934 dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
8935 dc->is_ldex = false;
8937 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
8939 /* If architectural single step active, limit to 1. */
8940 if (is_singlestepping(dc)) {
8941 dc->base.max_insns = 1;
8944 /* ARM is a fixed-length ISA. Bound the number of insns to execute
8945 to those left on the page. */
8946 if (!dc->thumb) {
8947 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
8948 dc->base.max_insns = MIN(dc->base.max_insns, bound);
8951 cpu_V0 = tcg_temp_new_i64();
8952 cpu_V1 = tcg_temp_new_i64();
8953 cpu_M0 = tcg_temp_new_i64();
8956 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
8958 DisasContext *dc = container_of(dcbase, DisasContext, base);
8960 /* A note on handling of the condexec (IT) bits:
8962 * We want to avoid the overhead of having to write the updated condexec
8963 * bits back to the CPUARMState for every instruction in an IT block. So:
8964 * (1) if the condexec bits are not already zero then we write
8965 * zero back into the CPUARMState now. This avoids complications trying
8966 * to do it at the end of the block. (For example if we don't do this
8967 * it's hard to identify whether we can safely skip writing condexec
8968 * at the end of the TB, which we definitely want to do for the case
8969 * where a TB doesn't do anything with the IT state at all.)
8970 * (2) if we are going to leave the TB then we call gen_set_condexec()
8971 * which will write the correct value into CPUARMState if zero is wrong.
8972 * This is done both for leaving the TB at the end, and for leaving
8973 * it because of an exception we know will happen, which is done in
8974 * gen_exception_insn(). The latter is necessary because we need to
8975 * leave the TB with the PC/IT state just prior to execution of the
8976 * instruction which caused the exception.
8977 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
8978 * then the CPUARMState will be wrong and we need to reset it.
8979 * This is handled in the same way as restoration of the
8980 * PC in these situations; we save the value of the condexec bits
8981 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
8982 * then uses this to restore them after an exception.
8984 * Note that there are no instructions which can read the condexec
8985 * bits, and none which can write non-static values to them, so
8986 * we don't need to care about whether CPUARMState is correct in the
8987 * middle of a TB.
8990 /* Reset the conditional execution bits immediately. This avoids
8991 complications trying to do it at the end of the block. */
8992 if (dc->condexec_mask || dc->condexec_cond) {
8993 TCGv_i32 tmp = tcg_temp_new_i32();
8994 tcg_gen_movi_i32(tmp, 0);
8995 store_cpu_field(tmp, condexec_bits);
8999 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
9001 DisasContext *dc = container_of(dcbase, DisasContext, base);
9003 tcg_gen_insn_start(dc->base.pc_next,
9004 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
9006 dc->insn_start = tcg_last_op();
9009 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
9010 const CPUBreakpoint *bp)
9012 DisasContext *dc = container_of(dcbase, DisasContext, base);
9014 if (bp->flags & BP_CPU) {
9015 gen_set_condexec(dc);
9016 gen_set_pc_im(dc, dc->base.pc_next);
9017 gen_helper_check_breakpoints(cpu_env);
9018 /* End the TB early; it's likely not going to be executed */
9019 dc->base.is_jmp = DISAS_TOO_MANY;
9020 } else {
9021 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
9022 /* The address covered by the breakpoint must be
9023 included in [tb->pc, tb->pc + tb->size) in order
9024 to for it to be properly cleared -- thus we
9025 increment the PC here so that the logic setting
9026 tb->size below does the right thing. */
9027 /* TODO: Advance PC by correct instruction length to
9028 * avoid disassembler error messages */
9029 dc->base.pc_next += 2;
9030 dc->base.is_jmp = DISAS_NORETURN;
9033 return true;
9036 static bool arm_pre_translate_insn(DisasContext *dc)
9038 #ifdef CONFIG_USER_ONLY
9039 /* Intercept jump to the magic kernel page. */
9040 if (dc->base.pc_next >= 0xffff0000) {
9041 /* We always get here via a jump, so know we are not in a
9042 conditional execution block. */
9043 gen_exception_internal(EXCP_KERNEL_TRAP);
9044 dc->base.is_jmp = DISAS_NORETURN;
9045 return true;
9047 #endif
9049 if (dc->ss_active && !dc->pstate_ss) {
9050 /* Singlestep state is Active-pending.
9051 * If we're in this state at the start of a TB then either
9052 * a) we just took an exception to an EL which is being debugged
9053 * and this is the first insn in the exception handler
9054 * b) debug exceptions were masked and we just unmasked them
9055 * without changing EL (eg by clearing PSTATE.D)
9056 * In either case we're going to take a swstep exception in the
9057 * "did not step an insn" case, and so the syndrome ISV and EX
9058 * bits should be zero.
9060 assert(dc->base.num_insns == 1);
9061 gen_swstep_exception(dc, 0, 0);
9062 dc->base.is_jmp = DISAS_NORETURN;
9063 return true;
9066 return false;
9069 static void arm_post_translate_insn(DisasContext *dc)
9071 if (dc->condjmp && !dc->base.is_jmp) {
9072 gen_set_label(dc->condlabel);
9073 dc->condjmp = 0;
9075 translator_loop_temp_check(&dc->base);
9078 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
9080 DisasContext *dc = container_of(dcbase, DisasContext, base);
9081 CPUARMState *env = cpu->env_ptr;
9082 unsigned int insn;
9084 if (arm_pre_translate_insn(dc)) {
9085 return;
9088 dc->pc_curr = dc->base.pc_next;
9089 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
9090 dc->insn = insn;
9091 dc->base.pc_next += 4;
9092 disas_arm_insn(dc, insn);
9094 arm_post_translate_insn(dc);
9096 /* ARM is a fixed-length ISA. We performed the cross-page check
9097 in init_disas_context by adjusting max_insns. */
9100 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
9102 /* Return true if this Thumb insn is always unconditional,
9103 * even inside an IT block. This is true of only a very few
9104 * instructions: BKPT, HLT, and SG.
9106 * A larger class of instructions are UNPREDICTABLE if used
9107 * inside an IT block; we do not need to detect those here, because
9108 * what we do by default (perform the cc check and update the IT
9109 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
9110 * choice for those situations.
9112 * insn is either a 16-bit or a 32-bit instruction; the two are
9113 * distinguishable because for the 16-bit case the top 16 bits
9114 * are zeroes, and that isn't a valid 32-bit encoding.
9116 if ((insn & 0xffffff00) == 0xbe00) {
9117 /* BKPT */
9118 return true;
9121 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
9122 !arm_dc_feature(s, ARM_FEATURE_M)) {
9123 /* HLT: v8A only. This is unconditional even when it is going to
9124 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
9125 * For v7 cores this was a plain old undefined encoding and so
9126 * honours its cc check. (We might be using the encoding as
9127 * a semihosting trap, but we don't change the cc check behaviour
9128 * on that account, because a debugger connected to a real v7A
9129 * core and emulating semihosting traps by catching the UNDEF
9130 * exception would also only see cases where the cc check passed.
9131 * No guest code should be trying to do a HLT semihosting trap
9132 * in an IT block anyway.
9134 return true;
9137 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
9138 arm_dc_feature(s, ARM_FEATURE_M)) {
9139 /* SG: v8M only */
9140 return true;
9143 return false;
9146 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
9148 DisasContext *dc = container_of(dcbase, DisasContext, base);
9149 CPUARMState *env = cpu->env_ptr;
9150 uint32_t insn;
9151 bool is_16bit;
9153 if (arm_pre_translate_insn(dc)) {
9154 return;
9157 dc->pc_curr = dc->base.pc_next;
9158 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
9159 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
9160 dc->base.pc_next += 2;
9161 if (!is_16bit) {
9162 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
9164 insn = insn << 16 | insn2;
9165 dc->base.pc_next += 2;
9167 dc->insn = insn;
9169 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
9170 uint32_t cond = dc->condexec_cond;
9173 * Conditionally skip the insn. Note that both 0xe and 0xf mean
9174 * "always"; 0xf is not "never".
9176 if (cond < 0x0e) {
9177 arm_skip_unless(dc, cond);
9181 if (is_16bit) {
9182 disas_thumb_insn(dc, insn);
9183 } else {
9184 disas_thumb2_insn(dc, insn);
9187 /* Advance the Thumb condexec condition. */
9188 if (dc->condexec_mask) {
9189 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
9190 ((dc->condexec_mask >> 4) & 1));
9191 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9192 if (dc->condexec_mask == 0) {
9193 dc->condexec_cond = 0;
9197 arm_post_translate_insn(dc);
9199 /* Thumb is a variable-length ISA. Stop translation when the next insn
9200 * will touch a new page. This ensures that prefetch aborts occur at
9201 * the right place.
9203 * We want to stop the TB if the next insn starts in a new page,
9204 * or if it spans between this page and the next. This means that
9205 * if we're looking at the last halfword in the page we need to
9206 * see if it's a 16-bit Thumb insn (which will fit in this TB)
9207 * or a 32-bit Thumb insn (which won't).
9208 * This is to avoid generating a silly TB with a single 16-bit insn
9209 * in it at the end of this page (which would execute correctly
9210 * but isn't very efficient).
9212 if (dc->base.is_jmp == DISAS_NEXT
9213 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
9214 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
9215 && insn_crosses_page(env, dc)))) {
9216 dc->base.is_jmp = DISAS_TOO_MANY;
9220 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
9222 DisasContext *dc = container_of(dcbase, DisasContext, base);
9224 /* At this stage dc->condjmp will only be set when the skipped
9225 instruction was a conditional branch or trap, and the PC has
9226 already been written. */
9227 gen_set_condexec(dc);
9228 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
9229 /* Exception return branches need some special case code at the
9230 * end of the TB, which is complex enough that it has to
9231 * handle the single-step vs not and the condition-failed
9232 * insn codepath itself.
9234 gen_bx_excret_final_code(dc);
9235 } else if (unlikely(is_singlestepping(dc))) {
9236 /* Unconditional and "condition passed" instruction codepath. */
9237 switch (dc->base.is_jmp) {
9238 case DISAS_SWI:
9239 gen_ss_advance(dc);
9240 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
9241 default_exception_el(dc));
9242 break;
9243 case DISAS_HVC:
9244 gen_ss_advance(dc);
9245 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
9246 break;
9247 case DISAS_SMC:
9248 gen_ss_advance(dc);
9249 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
9250 break;
9251 case DISAS_NEXT:
9252 case DISAS_TOO_MANY:
9253 case DISAS_UPDATE_EXIT:
9254 case DISAS_UPDATE_NOCHAIN:
9255 gen_set_pc_im(dc, dc->base.pc_next);
9256 /* fall through */
9257 default:
9258 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
9259 gen_singlestep_exception(dc);
9260 break;
9261 case DISAS_NORETURN:
9262 break;
9264 } else {
9265 /* While branches must always occur at the end of an IT block,
9266 there are a few other things that can cause us to terminate
9267 the TB in the middle of an IT block:
9268 - Exception generating instructions (bkpt, swi, undefined).
9269 - Page boundaries.
9270 - Hardware watchpoints.
9271 Hardware breakpoints have already been handled and skip this code.
9273 switch (dc->base.is_jmp) {
9274 case DISAS_NEXT:
9275 case DISAS_TOO_MANY:
9276 gen_goto_tb(dc, 1, dc->base.pc_next);
9277 break;
9278 case DISAS_UPDATE_NOCHAIN:
9279 gen_set_pc_im(dc, dc->base.pc_next);
9280 /* fall through */
9281 case DISAS_JUMP:
9282 gen_goto_ptr();
9283 break;
9284 case DISAS_UPDATE_EXIT:
9285 gen_set_pc_im(dc, dc->base.pc_next);
9286 /* fall through */
9287 default:
9288 /* indicate that the hash table must be used to find the next TB */
9289 tcg_gen_exit_tb(NULL, 0);
9290 break;
9291 case DISAS_NORETURN:
9292 /* nothing more to generate */
9293 break;
9294 case DISAS_WFI:
9296 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
9297 !(dc->insn & (1U << 31))) ? 2 : 4);
9299 gen_helper_wfi(cpu_env, tmp);
9300 tcg_temp_free_i32(tmp);
9301 /* The helper doesn't necessarily throw an exception, but we
9302 * must go back to the main loop to check for interrupts anyway.
9304 tcg_gen_exit_tb(NULL, 0);
9305 break;
9307 case DISAS_WFE:
9308 gen_helper_wfe(cpu_env);
9309 break;
9310 case DISAS_YIELD:
9311 gen_helper_yield(cpu_env);
9312 break;
9313 case DISAS_SWI:
9314 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
9315 default_exception_el(dc));
9316 break;
9317 case DISAS_HVC:
9318 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
9319 break;
9320 case DISAS_SMC:
9321 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
9322 break;
9326 if (dc->condjmp) {
9327 /* "Condition failed" instruction codepath for the branch/trap insn */
9328 gen_set_label(dc->condlabel);
9329 gen_set_condexec(dc);
9330 if (unlikely(is_singlestepping(dc))) {
9331 gen_set_pc_im(dc, dc->base.pc_next);
9332 gen_singlestep_exception(dc);
9333 } else {
9334 gen_goto_tb(dc, 1, dc->base.pc_next);
9339 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
9341 DisasContext *dc = container_of(dcbase, DisasContext, base);
9343 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
9344 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
9347 static const TranslatorOps arm_translator_ops = {
9348 .init_disas_context = arm_tr_init_disas_context,
9349 .tb_start = arm_tr_tb_start,
9350 .insn_start = arm_tr_insn_start,
9351 .breakpoint_check = arm_tr_breakpoint_check,
9352 .translate_insn = arm_tr_translate_insn,
9353 .tb_stop = arm_tr_tb_stop,
9354 .disas_log = arm_tr_disas_log,
9357 static const TranslatorOps thumb_translator_ops = {
9358 .init_disas_context = arm_tr_init_disas_context,
9359 .tb_start = arm_tr_tb_start,
9360 .insn_start = arm_tr_insn_start,
9361 .breakpoint_check = arm_tr_breakpoint_check,
9362 .translate_insn = thumb_tr_translate_insn,
9363 .tb_stop = arm_tr_tb_stop,
9364 .disas_log = arm_tr_disas_log,
9367 /* generate intermediate code for basic block 'tb'. */
9368 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
9370 DisasContext dc = { };
9371 const TranslatorOps *ops = &arm_translator_ops;
9372 CPUARMTBFlags tb_flags = arm_tbflags_from_tb(tb);
9374 if (EX_TBFLAG_AM32(tb_flags, THUMB)) {
9375 ops = &thumb_translator_ops;
9377 #ifdef TARGET_AARCH64
9378 if (EX_TBFLAG_ANY(tb_flags, AARCH64_STATE)) {
9379 ops = &aarch64_translator_ops;
9381 #endif
9383 translator_loop(ops, &dc.base, cpu, tb, max_insns);
9386 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
9387 target_ulong *data)
9389 if (is_a64(env)) {
9390 env->pc = data[0];
9391 env->condexec_bits = 0;
9392 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
9393 } else {
9394 env->regs[15] = data[0];
9395 env->condexec_bits = data[1];
9396 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;