target/arm: Rename helper_exception_with_syndrome
[qemu/ar7.git] / target / arm / translate.c
blobdc033600c0eed554551866346fc567521fb951d4
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"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "exec/log.h"
36 #include "cpregs.h"
39 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
40 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
41 /* currently all emulated v5 cores are also v5TE, so don't bother */
42 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
43 #define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
44 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
45 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
46 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
47 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
48 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
50 #include "translate.h"
51 #include "translate-a32.h"
53 /* These are TCG temporaries used only by the legacy iwMMXt decoder */
54 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
55 /* These are TCG globals which alias CPUARMState fields */
56 static TCGv_i32 cpu_R[16];
57 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
58 TCGv_i64 cpu_exclusive_addr;
59 TCGv_i64 cpu_exclusive_val;
61 #include "exec/gen-icount.h"
63 static const char * const regnames[] =
64 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
65 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
68 /* initialize TCG globals. */
69 void arm_translate_init(void)
71 int i;
73 for (i = 0; i < 16; i++) {
74 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
75 offsetof(CPUARMState, regs[i]),
76 regnames[i]);
78 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
79 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
80 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
81 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
83 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
84 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
85 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
86 offsetof(CPUARMState, exclusive_val), "exclusive_val");
88 a64_translate_init();
91 uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
93 /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
94 switch (cmode) {
95 case 0: case 1:
96 /* no-op */
97 break;
98 case 2: case 3:
99 imm <<= 8;
100 break;
101 case 4: case 5:
102 imm <<= 16;
103 break;
104 case 6: case 7:
105 imm <<= 24;
106 break;
107 case 8: case 9:
108 imm |= imm << 16;
109 break;
110 case 10: case 11:
111 imm = (imm << 8) | (imm << 24);
112 break;
113 case 12:
114 imm = (imm << 8) | 0xff;
115 break;
116 case 13:
117 imm = (imm << 16) | 0xffff;
118 break;
119 case 14:
120 if (op) {
122 * This and cmode == 15 op == 1 are the only cases where
123 * the top and bottom 32 bits of the encoded constant differ.
125 uint64_t imm64 = 0;
126 int n;
128 for (n = 0; n < 8; n++) {
129 if (imm & (1 << n)) {
130 imm64 |= (0xffULL << (n * 8));
133 return imm64;
135 imm |= (imm << 8) | (imm << 16) | (imm << 24);
136 break;
137 case 15:
138 if (op) {
139 /* Reserved encoding for AArch32; valid for AArch64 */
140 uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
141 if (imm & 0x80) {
142 imm64 |= 0x8000000000000000ULL;
144 if (imm & 0x40) {
145 imm64 |= 0x3fc0000000000000ULL;
146 } else {
147 imm64 |= 0x4000000000000000ULL;
149 return imm64;
151 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
152 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
153 break;
155 if (op) {
156 imm = ~imm;
158 return dup_const(MO_32, imm);
161 /* Generate a label used for skipping this instruction */
162 void arm_gen_condlabel(DisasContext *s)
164 if (!s->condjmp) {
165 s->condlabel = gen_new_label();
166 s->condjmp = 1;
170 /* Flags for the disas_set_da_iss info argument:
171 * lower bits hold the Rt register number, higher bits are flags.
173 typedef enum ISSInfo {
174 ISSNone = 0,
175 ISSRegMask = 0x1f,
176 ISSInvalid = (1 << 5),
177 ISSIsAcqRel = (1 << 6),
178 ISSIsWrite = (1 << 7),
179 ISSIs16Bit = (1 << 8),
180 } ISSInfo;
183 * Store var into env + offset to a member with size bytes.
184 * Free var after use.
186 void store_cpu_offset(TCGv_i32 var, int offset, int size)
188 switch (size) {
189 case 1:
190 tcg_gen_st8_i32(var, cpu_env, offset);
191 break;
192 case 4:
193 tcg_gen_st_i32(var, cpu_env, offset);
194 break;
195 default:
196 g_assert_not_reached();
198 tcg_temp_free_i32(var);
201 /* Save the syndrome information for a Data Abort */
202 static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
204 uint32_t syn;
205 int sas = memop & MO_SIZE;
206 bool sse = memop & MO_SIGN;
207 bool is_acqrel = issinfo & ISSIsAcqRel;
208 bool is_write = issinfo & ISSIsWrite;
209 bool is_16bit = issinfo & ISSIs16Bit;
210 int srt = issinfo & ISSRegMask;
212 if (issinfo & ISSInvalid) {
213 /* Some callsites want to conditionally provide ISS info,
214 * eg "only if this was not a writeback"
216 return;
219 if (srt == 15) {
220 /* For AArch32, insns where the src/dest is R15 never generate
221 * ISS information. Catching that here saves checking at all
222 * the call sites.
224 return;
227 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
228 0, 0, 0, is_write, 0, is_16bit);
229 disas_set_insn_syndrome(s, syn);
232 static inline int get_a32_user_mem_index(DisasContext *s)
234 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
235 * insns:
236 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
237 * otherwise, access as if at PL0.
239 switch (s->mmu_idx) {
240 case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
241 case ARMMMUIdx_E10_0:
242 case ARMMMUIdx_E10_1:
243 case ARMMMUIdx_E10_1_PAN:
244 return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
245 case ARMMMUIdx_SE3:
246 case ARMMMUIdx_SE10_0:
247 case ARMMMUIdx_SE10_1:
248 case ARMMMUIdx_SE10_1_PAN:
249 return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
250 case ARMMMUIdx_MUser:
251 case ARMMMUIdx_MPriv:
252 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
253 case ARMMMUIdx_MUserNegPri:
254 case ARMMMUIdx_MPrivNegPri:
255 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
256 case ARMMMUIdx_MSUser:
257 case ARMMMUIdx_MSPriv:
258 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
259 case ARMMMUIdx_MSUserNegPri:
260 case ARMMMUIdx_MSPrivNegPri:
261 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
262 default:
263 g_assert_not_reached();
267 /* The architectural value of PC. */
268 static uint32_t read_pc(DisasContext *s)
270 return s->pc_curr + (s->thumb ? 4 : 8);
273 /* Set a variable to the value of a CPU register. */
274 void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
276 if (reg == 15) {
277 tcg_gen_movi_i32(var, read_pc(s));
278 } else {
279 tcg_gen_mov_i32(var, cpu_R[reg]);
284 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
285 * This is used for load/store for which use of PC implies (literal),
286 * or ADD that implies ADR.
288 TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
290 TCGv_i32 tmp = tcg_temp_new_i32();
292 if (reg == 15) {
293 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
294 } else {
295 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
297 return tmp;
300 /* Set a CPU register. The source must be a temporary and will be
301 marked as dead. */
302 void store_reg(DisasContext *s, int reg, TCGv_i32 var)
304 if (reg == 15) {
305 /* In Thumb mode, we must ignore bit 0.
306 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
307 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
308 * We choose to ignore [1:0] in ARM mode for all architecture versions.
310 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
311 s->base.is_jmp = DISAS_JUMP;
312 } else if (reg == 13 && arm_dc_feature(s, ARM_FEATURE_M)) {
313 /* For M-profile SP bits [1:0] are always zero */
314 tcg_gen_andi_i32(var, var, ~3);
316 tcg_gen_mov_i32(cpu_R[reg], var);
317 tcg_temp_free_i32(var);
321 * Variant of store_reg which applies v8M stack-limit checks before updating
322 * SP. If the check fails this will result in an exception being taken.
323 * We disable the stack checks for CONFIG_USER_ONLY because we have
324 * no idea what the stack limits should be in that case.
325 * If stack checking is not being done this just acts like store_reg().
327 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
329 #ifndef CONFIG_USER_ONLY
330 if (s->v8m_stackcheck) {
331 gen_helper_v8m_stackcheck(cpu_env, var);
333 #endif
334 store_reg(s, 13, var);
337 /* Value extensions. */
338 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
339 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
340 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
341 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
343 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
344 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
346 void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
348 gen_helper_cpsr_write(cpu_env, var, tcg_constant_i32(mask));
351 static void gen_rebuild_hflags(DisasContext *s, bool new_el)
353 bool m_profile = arm_dc_feature(s, ARM_FEATURE_M);
355 if (new_el) {
356 if (m_profile) {
357 gen_helper_rebuild_hflags_m32_newel(cpu_env);
358 } else {
359 gen_helper_rebuild_hflags_a32_newel(cpu_env);
361 } else {
362 TCGv_i32 tcg_el = tcg_constant_i32(s->current_el);
363 if (m_profile) {
364 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
365 } else {
366 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
371 static void gen_exception_internal(int excp)
373 assert(excp_is_internal(excp));
374 gen_helper_exception_internal(cpu_env, tcg_constant_i32(excp));
377 static void gen_singlestep_exception(DisasContext *s)
379 /* We just completed step of an insn. Move from Active-not-pending
380 * to Active-pending, and then also take the swstep exception.
381 * This corresponds to making the (IMPDEF) choice to prioritize
382 * swstep exceptions over asynchronous exceptions taken to an exception
383 * level where debug is disabled. This choice has the advantage that
384 * we do not need to maintain internal state corresponding to the
385 * ISV/EX syndrome bits between completion of the step and generation
386 * of the exception, and our syndrome information is always correct.
388 gen_ss_advance(s);
389 gen_swstep_exception(s, 1, s->is_ldex);
390 s->base.is_jmp = DISAS_NORETURN;
393 void clear_eci_state(DisasContext *s)
396 * Clear any ECI/ICI state: used when a load multiple/store
397 * multiple insn executes.
399 if (s->eci) {
400 store_cpu_field_constant(0, condexec_bits);
401 s->eci = 0;
405 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
407 TCGv_i32 tmp1 = tcg_temp_new_i32();
408 TCGv_i32 tmp2 = tcg_temp_new_i32();
409 tcg_gen_ext16s_i32(tmp1, a);
410 tcg_gen_ext16s_i32(tmp2, b);
411 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
412 tcg_temp_free_i32(tmp2);
413 tcg_gen_sari_i32(a, a, 16);
414 tcg_gen_sari_i32(b, b, 16);
415 tcg_gen_mul_i32(b, b, a);
416 tcg_gen_mov_i32(a, tmp1);
417 tcg_temp_free_i32(tmp1);
420 /* Byteswap each halfword. */
421 void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
423 TCGv_i32 tmp = tcg_temp_new_i32();
424 TCGv_i32 mask = tcg_constant_i32(0x00ff00ff);
425 tcg_gen_shri_i32(tmp, var, 8);
426 tcg_gen_and_i32(tmp, tmp, mask);
427 tcg_gen_and_i32(var, var, mask);
428 tcg_gen_shli_i32(var, var, 8);
429 tcg_gen_or_i32(dest, var, tmp);
430 tcg_temp_free_i32(tmp);
433 /* Byteswap low halfword and sign extend. */
434 static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
436 tcg_gen_bswap16_i32(var, var, TCG_BSWAP_OS);
439 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
440 tmp = (t0 ^ t1) & 0x8000;
441 t0 &= ~0x8000;
442 t1 &= ~0x8000;
443 t0 = (t0 + t1) ^ tmp;
446 static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
448 TCGv_i32 tmp = tcg_temp_new_i32();
449 tcg_gen_xor_i32(tmp, t0, t1);
450 tcg_gen_andi_i32(tmp, tmp, 0x8000);
451 tcg_gen_andi_i32(t0, t0, ~0x8000);
452 tcg_gen_andi_i32(t1, t1, ~0x8000);
453 tcg_gen_add_i32(t0, t0, t1);
454 tcg_gen_xor_i32(dest, t0, tmp);
455 tcg_temp_free_i32(tmp);
458 /* Set N and Z flags from var. */
459 static inline void gen_logic_CC(TCGv_i32 var)
461 tcg_gen_mov_i32(cpu_NF, var);
462 tcg_gen_mov_i32(cpu_ZF, var);
465 /* dest = T0 + T1 + CF. */
466 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
468 tcg_gen_add_i32(dest, t0, t1);
469 tcg_gen_add_i32(dest, dest, cpu_CF);
472 /* dest = T0 - T1 + CF - 1. */
473 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
475 tcg_gen_sub_i32(dest, t0, t1);
476 tcg_gen_add_i32(dest, dest, cpu_CF);
477 tcg_gen_subi_i32(dest, dest, 1);
480 /* dest = T0 + T1. Compute C, N, V and Z flags */
481 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
483 TCGv_i32 tmp = tcg_temp_new_i32();
484 tcg_gen_movi_i32(tmp, 0);
485 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
486 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
487 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
488 tcg_gen_xor_i32(tmp, t0, t1);
489 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
490 tcg_temp_free_i32(tmp);
491 tcg_gen_mov_i32(dest, cpu_NF);
494 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
495 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
497 TCGv_i32 tmp = tcg_temp_new_i32();
498 if (TCG_TARGET_HAS_add2_i32) {
499 tcg_gen_movi_i32(tmp, 0);
500 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
501 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
502 } else {
503 TCGv_i64 q0 = tcg_temp_new_i64();
504 TCGv_i64 q1 = tcg_temp_new_i64();
505 tcg_gen_extu_i32_i64(q0, t0);
506 tcg_gen_extu_i32_i64(q1, t1);
507 tcg_gen_add_i64(q0, q0, q1);
508 tcg_gen_extu_i32_i64(q1, cpu_CF);
509 tcg_gen_add_i64(q0, q0, q1);
510 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
511 tcg_temp_free_i64(q0);
512 tcg_temp_free_i64(q1);
514 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
515 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
516 tcg_gen_xor_i32(tmp, t0, t1);
517 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
518 tcg_temp_free_i32(tmp);
519 tcg_gen_mov_i32(dest, cpu_NF);
522 /* dest = T0 - T1. Compute C, N, V and Z flags */
523 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
525 TCGv_i32 tmp;
526 tcg_gen_sub_i32(cpu_NF, t0, t1);
527 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
528 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
529 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
530 tmp = tcg_temp_new_i32();
531 tcg_gen_xor_i32(tmp, t0, t1);
532 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
533 tcg_temp_free_i32(tmp);
534 tcg_gen_mov_i32(dest, cpu_NF);
537 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
538 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
540 TCGv_i32 tmp = tcg_temp_new_i32();
541 tcg_gen_not_i32(tmp, t1);
542 gen_adc_CC(dest, t0, tmp);
543 tcg_temp_free_i32(tmp);
546 #define GEN_SHIFT(name) \
547 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
549 TCGv_i32 tmpd = tcg_temp_new_i32(); \
550 TCGv_i32 tmp1 = tcg_temp_new_i32(); \
551 TCGv_i32 zero = tcg_constant_i32(0); \
552 tcg_gen_andi_i32(tmp1, t1, 0x1f); \
553 tcg_gen_##name##_i32(tmpd, t0, tmp1); \
554 tcg_gen_andi_i32(tmp1, t1, 0xe0); \
555 tcg_gen_movcond_i32(TCG_COND_NE, dest, tmp1, zero, zero, tmpd); \
556 tcg_temp_free_i32(tmpd); \
557 tcg_temp_free_i32(tmp1); \
559 GEN_SHIFT(shl)
560 GEN_SHIFT(shr)
561 #undef GEN_SHIFT
563 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
565 TCGv_i32 tmp1 = tcg_temp_new_i32();
567 tcg_gen_andi_i32(tmp1, t1, 0xff);
568 tcg_gen_umin_i32(tmp1, tmp1, tcg_constant_i32(31));
569 tcg_gen_sar_i32(dest, t0, tmp1);
570 tcg_temp_free_i32(tmp1);
573 static void shifter_out_im(TCGv_i32 var, int shift)
575 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
578 /* Shift by immediate. Includes special handling for shift == 0. */
579 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
580 int shift, int flags)
582 switch (shiftop) {
583 case 0: /* LSL */
584 if (shift != 0) {
585 if (flags)
586 shifter_out_im(var, 32 - shift);
587 tcg_gen_shli_i32(var, var, shift);
589 break;
590 case 1: /* LSR */
591 if (shift == 0) {
592 if (flags) {
593 tcg_gen_shri_i32(cpu_CF, var, 31);
595 tcg_gen_movi_i32(var, 0);
596 } else {
597 if (flags)
598 shifter_out_im(var, shift - 1);
599 tcg_gen_shri_i32(var, var, shift);
601 break;
602 case 2: /* ASR */
603 if (shift == 0)
604 shift = 32;
605 if (flags)
606 shifter_out_im(var, shift - 1);
607 if (shift == 32)
608 shift = 31;
609 tcg_gen_sari_i32(var, var, shift);
610 break;
611 case 3: /* ROR/RRX */
612 if (shift != 0) {
613 if (flags)
614 shifter_out_im(var, shift - 1);
615 tcg_gen_rotri_i32(var, var, shift); break;
616 } else {
617 TCGv_i32 tmp = tcg_temp_new_i32();
618 tcg_gen_shli_i32(tmp, cpu_CF, 31);
619 if (flags)
620 shifter_out_im(var, 0);
621 tcg_gen_shri_i32(var, var, 1);
622 tcg_gen_or_i32(var, var, tmp);
623 tcg_temp_free_i32(tmp);
628 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
629 TCGv_i32 shift, int flags)
631 if (flags) {
632 switch (shiftop) {
633 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
634 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
635 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
636 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
638 } else {
639 switch (shiftop) {
640 case 0:
641 gen_shl(var, var, shift);
642 break;
643 case 1:
644 gen_shr(var, var, shift);
645 break;
646 case 2:
647 gen_sar(var, var, shift);
648 break;
649 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
650 tcg_gen_rotr_i32(var, var, shift); break;
653 tcg_temp_free_i32(shift);
657 * Generate a conditional based on ARM condition code cc.
658 * This is common between ARM and Aarch64 targets.
660 void arm_test_cc(DisasCompare *cmp, int cc)
662 TCGv_i32 value;
663 TCGCond cond;
664 bool global = true;
666 switch (cc) {
667 case 0: /* eq: Z */
668 case 1: /* ne: !Z */
669 cond = TCG_COND_EQ;
670 value = cpu_ZF;
671 break;
673 case 2: /* cs: C */
674 case 3: /* cc: !C */
675 cond = TCG_COND_NE;
676 value = cpu_CF;
677 break;
679 case 4: /* mi: N */
680 case 5: /* pl: !N */
681 cond = TCG_COND_LT;
682 value = cpu_NF;
683 break;
685 case 6: /* vs: V */
686 case 7: /* vc: !V */
687 cond = TCG_COND_LT;
688 value = cpu_VF;
689 break;
691 case 8: /* hi: C && !Z */
692 case 9: /* ls: !C || Z -> !(C && !Z) */
693 cond = TCG_COND_NE;
694 value = tcg_temp_new_i32();
695 global = false;
696 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
697 ZF is non-zero for !Z; so AND the two subexpressions. */
698 tcg_gen_neg_i32(value, cpu_CF);
699 tcg_gen_and_i32(value, value, cpu_ZF);
700 break;
702 case 10: /* ge: N == V -> N ^ V == 0 */
703 case 11: /* lt: N != V -> N ^ V != 0 */
704 /* Since we're only interested in the sign bit, == 0 is >= 0. */
705 cond = TCG_COND_GE;
706 value = tcg_temp_new_i32();
707 global = false;
708 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
709 break;
711 case 12: /* gt: !Z && N == V */
712 case 13: /* le: Z || N != V */
713 cond = TCG_COND_NE;
714 value = tcg_temp_new_i32();
715 global = false;
716 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
717 * the sign bit then AND with ZF to yield the result. */
718 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
719 tcg_gen_sari_i32(value, value, 31);
720 tcg_gen_andc_i32(value, cpu_ZF, value);
721 break;
723 case 14: /* always */
724 case 15: /* always */
725 /* Use the ALWAYS condition, which will fold early.
726 * It doesn't matter what we use for the value. */
727 cond = TCG_COND_ALWAYS;
728 value = cpu_ZF;
729 goto no_invert;
731 default:
732 fprintf(stderr, "Bad condition code 0x%x\n", cc);
733 abort();
736 if (cc & 1) {
737 cond = tcg_invert_cond(cond);
740 no_invert:
741 cmp->cond = cond;
742 cmp->value = value;
743 cmp->value_global = global;
746 void arm_free_cc(DisasCompare *cmp)
748 if (!cmp->value_global) {
749 tcg_temp_free_i32(cmp->value);
753 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
755 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
758 void arm_gen_test_cc(int cc, TCGLabel *label)
760 DisasCompare cmp;
761 arm_test_cc(&cmp, cc);
762 arm_jump_cc(&cmp, label);
763 arm_free_cc(&cmp);
766 void gen_set_condexec(DisasContext *s)
768 if (s->condexec_mask) {
769 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
771 store_cpu_field_constant(val, condexec_bits);
775 void gen_set_pc_im(DisasContext *s, target_ulong val)
777 tcg_gen_movi_i32(cpu_R[15], val);
780 /* Set PC and Thumb state from var. var is marked as dead. */
781 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
783 s->base.is_jmp = DISAS_JUMP;
784 tcg_gen_andi_i32(cpu_R[15], var, ~1);
785 tcg_gen_andi_i32(var, var, 1);
786 store_cpu_field(var, thumb);
790 * Set PC and Thumb state from var. var is marked as dead.
791 * For M-profile CPUs, include logic to detect exception-return
792 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
793 * and BX reg, and no others, and happens only for code in Handler mode.
794 * The Security Extension also requires us to check for the FNC_RETURN
795 * which signals a function return from non-secure state; this can happen
796 * in both Handler and Thread mode.
797 * To avoid having to do multiple comparisons in inline generated code,
798 * we make the check we do here loose, so it will match for EXC_RETURN
799 * in Thread mode. For system emulation do_v7m_exception_exit() checks
800 * for these spurious cases and returns without doing anything (giving
801 * the same behaviour as for a branch to a non-magic address).
803 * In linux-user mode it is unclear what the right behaviour for an
804 * attempted FNC_RETURN should be, because in real hardware this will go
805 * directly to Secure code (ie not the Linux kernel) which will then treat
806 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
807 * attempt behave the way it would on a CPU without the security extension,
808 * which is to say "like a normal branch". That means we can simply treat
809 * all branches as normal with no magic address behaviour.
811 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
813 /* Generate the same code here as for a simple bx, but flag via
814 * s->base.is_jmp that we need to do the rest of the work later.
816 gen_bx(s, var);
817 #ifndef CONFIG_USER_ONLY
818 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
819 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
820 s->base.is_jmp = DISAS_BX_EXCRET;
822 #endif
825 static inline void gen_bx_excret_final_code(DisasContext *s)
827 /* Generate the code to finish possible exception return and end the TB */
828 TCGLabel *excret_label = gen_new_label();
829 uint32_t min_magic;
831 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
832 /* Covers FNC_RETURN and EXC_RETURN magic */
833 min_magic = FNC_RETURN_MIN_MAGIC;
834 } else {
835 /* EXC_RETURN magic only */
836 min_magic = EXC_RETURN_MIN_MAGIC;
839 /* Is the new PC value in the magic range indicating exception return? */
840 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
841 /* No: end the TB as we would for a DISAS_JMP */
842 if (s->ss_active) {
843 gen_singlestep_exception(s);
844 } else {
845 tcg_gen_exit_tb(NULL, 0);
847 gen_set_label(excret_label);
848 /* Yes: this is an exception return.
849 * At this point in runtime env->regs[15] and env->thumb will hold
850 * the exception-return magic number, which do_v7m_exception_exit()
851 * will read. Nothing else will be able to see those values because
852 * the cpu-exec main loop guarantees that we will always go straight
853 * from raising the exception to the exception-handling code.
855 * gen_ss_advance(s) does nothing on M profile currently but
856 * calling it is conceptually the right thing as we have executed
857 * this instruction (compare SWI, HVC, SMC handling).
859 gen_ss_advance(s);
860 gen_exception_internal(EXCP_EXCEPTION_EXIT);
863 static inline void gen_bxns(DisasContext *s, int rm)
865 TCGv_i32 var = load_reg(s, rm);
867 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
868 * we need to sync state before calling it, but:
869 * - we don't need to do gen_set_pc_im() because the bxns helper will
870 * always set the PC itself
871 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
872 * unless it's outside an IT block or the last insn in an IT block,
873 * so we know that condexec == 0 (already set at the top of the TB)
874 * is correct in the non-UNPREDICTABLE cases, and we can choose
875 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
877 gen_helper_v7m_bxns(cpu_env, var);
878 tcg_temp_free_i32(var);
879 s->base.is_jmp = DISAS_EXIT;
882 static inline void gen_blxns(DisasContext *s, int rm)
884 TCGv_i32 var = load_reg(s, rm);
886 /* We don't need to sync condexec state, for the same reason as bxns.
887 * We do however need to set the PC, because the blxns helper reads it.
888 * The blxns helper may throw an exception.
890 gen_set_pc_im(s, s->base.pc_next);
891 gen_helper_v7m_blxns(cpu_env, var);
892 tcg_temp_free_i32(var);
893 s->base.is_jmp = DISAS_EXIT;
896 /* Variant of store_reg which uses branch&exchange logic when storing
897 to r15 in ARM architecture v7 and above. The source must be a temporary
898 and will be marked as dead. */
899 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
901 if (reg == 15 && ENABLE_ARCH_7) {
902 gen_bx(s, var);
903 } else {
904 store_reg(s, reg, var);
908 /* Variant of store_reg which uses branch&exchange logic when storing
909 * to r15 in ARM architecture v5T and above. This is used for storing
910 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
911 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
912 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
914 if (reg == 15 && ENABLE_ARCH_5) {
915 gen_bx_excret(s, var);
916 } else {
917 store_reg(s, reg, var);
921 #ifdef CONFIG_USER_ONLY
922 #define IS_USER_ONLY 1
923 #else
924 #define IS_USER_ONLY 0
925 #endif
927 MemOp pow2_align(unsigned i)
929 static const MemOp mop_align[] = {
930 0, MO_ALIGN_2, MO_ALIGN_4, MO_ALIGN_8, MO_ALIGN_16,
932 * FIXME: TARGET_PAGE_BITS_MIN affects TLB_FLAGS_MASK such
933 * that 256-bit alignment (MO_ALIGN_32) cannot be supported:
934 * see get_alignment_bits(). Enforce only 128-bit alignment for now.
936 MO_ALIGN_16
938 g_assert(i < ARRAY_SIZE(mop_align));
939 return mop_align[i];
943 * Abstractions of "generate code to do a guest load/store for
944 * AArch32", where a vaddr is always 32 bits (and is zero
945 * extended if we're a 64 bit core) and data is also
946 * 32 bits unless specifically doing a 64 bit access.
947 * These functions work like tcg_gen_qemu_{ld,st}* except
948 * that the address argument is TCGv_i32 rather than TCGv.
951 static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
953 TCGv addr = tcg_temp_new();
954 tcg_gen_extu_i32_tl(addr, a32);
956 /* Not needed for user-mode BE32, where we use MO_BE instead. */
957 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
958 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
960 return addr;
964 * Internal routines are used for NEON cases where the endianness
965 * and/or alignment has already been taken into account and manipulated.
967 void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
968 TCGv_i32 a32, int index, MemOp opc)
970 TCGv addr = gen_aa32_addr(s, a32, opc);
971 tcg_gen_qemu_ld_i32(val, addr, index, opc);
972 tcg_temp_free(addr);
975 void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
976 TCGv_i32 a32, int index, MemOp opc)
978 TCGv addr = gen_aa32_addr(s, a32, opc);
979 tcg_gen_qemu_st_i32(val, addr, index, opc);
980 tcg_temp_free(addr);
983 void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
984 TCGv_i32 a32, int index, MemOp opc)
986 TCGv addr = gen_aa32_addr(s, a32, opc);
988 tcg_gen_qemu_ld_i64(val, addr, index, opc);
990 /* Not needed for user-mode BE32, where we use MO_BE instead. */
991 if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
992 tcg_gen_rotri_i64(val, val, 32);
994 tcg_temp_free(addr);
997 void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
998 TCGv_i32 a32, int index, MemOp opc)
1000 TCGv addr = gen_aa32_addr(s, a32, opc);
1002 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1003 if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
1004 TCGv_i64 tmp = tcg_temp_new_i64();
1005 tcg_gen_rotri_i64(tmp, val, 32);
1006 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1007 tcg_temp_free_i64(tmp);
1008 } else {
1009 tcg_gen_qemu_st_i64(val, addr, index, opc);
1011 tcg_temp_free(addr);
1014 void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1015 int index, MemOp opc)
1017 gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
1020 void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1021 int index, MemOp opc)
1023 gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
1026 void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1027 int index, MemOp opc)
1029 gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
1032 void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1033 int index, MemOp opc)
1035 gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
1038 #define DO_GEN_LD(SUFF, OPC) \
1039 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1040 TCGv_i32 a32, int index) \
1042 gen_aa32_ld_i32(s, val, a32, index, OPC); \
1045 #define DO_GEN_ST(SUFF, OPC) \
1046 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1047 TCGv_i32 a32, int index) \
1049 gen_aa32_st_i32(s, val, a32, index, OPC); \
1052 static inline void gen_hvc(DisasContext *s, int imm16)
1054 /* The pre HVC helper handles cases when HVC gets trapped
1055 * as an undefined insn by runtime configuration (ie before
1056 * the insn really executes).
1058 gen_set_pc_im(s, s->pc_curr);
1059 gen_helper_pre_hvc(cpu_env);
1060 /* Otherwise we will treat this as a real exception which
1061 * happens after execution of the insn. (The distinction matters
1062 * for the PC value reported to the exception handler and also
1063 * for single stepping.)
1065 s->svc_imm = imm16;
1066 gen_set_pc_im(s, s->base.pc_next);
1067 s->base.is_jmp = DISAS_HVC;
1070 static inline void gen_smc(DisasContext *s)
1072 /* As with HVC, we may take an exception either before or after
1073 * the insn executes.
1075 gen_set_pc_im(s, s->pc_curr);
1076 gen_helper_pre_smc(cpu_env, tcg_constant_i32(syn_aa32_smc()));
1077 gen_set_pc_im(s, s->base.pc_next);
1078 s->base.is_jmp = DISAS_SMC;
1081 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1083 gen_set_condexec(s);
1084 gen_set_pc_im(s, pc);
1085 gen_exception_internal(excp);
1086 s->base.is_jmp = DISAS_NORETURN;
1089 void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
1090 uint32_t syn, uint32_t target_el)
1092 if (s->aarch64) {
1093 gen_a64_set_pc_im(pc);
1094 } else {
1095 gen_set_condexec(s);
1096 gen_set_pc_im(s, pc);
1098 gen_exception(excp, syn, target_el);
1099 s->base.is_jmp = DISAS_NORETURN;
1102 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1104 gen_set_condexec(s);
1105 gen_set_pc_im(s, s->pc_curr);
1106 gen_helper_exception_bkpt_insn(cpu_env, tcg_constant_i32(syn));
1107 s->base.is_jmp = DISAS_NORETURN;
1110 void unallocated_encoding(DisasContext *s)
1112 /* Unallocated and reserved encodings are uncategorized */
1113 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1114 default_exception_el(s));
1117 static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
1118 TCGv_i32 tcg_el)
1120 gen_set_condexec(s);
1121 gen_set_pc_im(s, s->pc_curr);
1122 gen_helper_exception_with_syndrome_el(cpu_env,
1123 tcg_constant_i32(excp),
1124 tcg_constant_i32(syn), tcg_el);
1125 s->base.is_jmp = DISAS_NORETURN;
1128 /* Force a TB lookup after an instruction that changes the CPU state. */
1129 void gen_lookup_tb(DisasContext *s)
1131 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1132 s->base.is_jmp = DISAS_EXIT;
1135 static inline void gen_hlt(DisasContext *s, int imm)
1137 /* HLT. This has two purposes.
1138 * Architecturally, it is an external halting debug instruction.
1139 * Since QEMU doesn't implement external debug, we treat this as
1140 * it is required for halting debug disabled: it will UNDEF.
1141 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1142 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1143 * must trigger semihosting even for ARMv7 and earlier, where
1144 * HLT was an undefined encoding.
1145 * In system mode, we don't allow userspace access to
1146 * semihosting, to provide some semblance of security
1147 * (and for consistency with our 32-bit semihosting).
1149 if (semihosting_enabled() &&
1150 #ifndef CONFIG_USER_ONLY
1151 s->current_el != 0 &&
1152 #endif
1153 (imm == (s->thumb ? 0x3c : 0xf000))) {
1154 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
1155 return;
1158 unallocated_encoding(s);
1162 * Return the offset of a "full" NEON Dreg.
1164 long neon_full_reg_offset(unsigned reg)
1166 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1170 * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1171 * where 0 is the least significant end of the register.
1173 long neon_element_offset(int reg, int element, MemOp memop)
1175 int element_size = 1 << (memop & MO_SIZE);
1176 int ofs = element * element_size;
1177 #if HOST_BIG_ENDIAN
1179 * Calculate the offset assuming fully little-endian,
1180 * then XOR to account for the order of the 8-byte units.
1182 if (element_size < 8) {
1183 ofs ^= 8 - element_size;
1185 #endif
1186 return neon_full_reg_offset(reg) + ofs;
1189 /* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
1190 long vfp_reg_offset(bool dp, unsigned reg)
1192 if (dp) {
1193 return neon_element_offset(reg, 0, MO_64);
1194 } else {
1195 return neon_element_offset(reg >> 1, reg & 1, MO_32);
1199 void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
1201 long off = neon_element_offset(reg, ele, memop);
1203 switch (memop) {
1204 case MO_SB:
1205 tcg_gen_ld8s_i32(dest, cpu_env, off);
1206 break;
1207 case MO_UB:
1208 tcg_gen_ld8u_i32(dest, cpu_env, off);
1209 break;
1210 case MO_SW:
1211 tcg_gen_ld16s_i32(dest, cpu_env, off);
1212 break;
1213 case MO_UW:
1214 tcg_gen_ld16u_i32(dest, cpu_env, off);
1215 break;
1216 case MO_UL:
1217 case MO_SL:
1218 tcg_gen_ld_i32(dest, cpu_env, off);
1219 break;
1220 default:
1221 g_assert_not_reached();
1225 void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
1227 long off = neon_element_offset(reg, ele, memop);
1229 switch (memop) {
1230 case MO_SL:
1231 tcg_gen_ld32s_i64(dest, cpu_env, off);
1232 break;
1233 case MO_UL:
1234 tcg_gen_ld32u_i64(dest, cpu_env, off);
1235 break;
1236 case MO_UQ:
1237 tcg_gen_ld_i64(dest, cpu_env, off);
1238 break;
1239 default:
1240 g_assert_not_reached();
1244 void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
1246 long off = neon_element_offset(reg, ele, memop);
1248 switch (memop) {
1249 case MO_8:
1250 tcg_gen_st8_i32(src, cpu_env, off);
1251 break;
1252 case MO_16:
1253 tcg_gen_st16_i32(src, cpu_env, off);
1254 break;
1255 case MO_32:
1256 tcg_gen_st_i32(src, cpu_env, off);
1257 break;
1258 default:
1259 g_assert_not_reached();
1263 void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
1265 long off = neon_element_offset(reg, ele, memop);
1267 switch (memop) {
1268 case MO_32:
1269 tcg_gen_st32_i64(src, cpu_env, off);
1270 break;
1271 case MO_64:
1272 tcg_gen_st_i64(src, cpu_env, off);
1273 break;
1274 default:
1275 g_assert_not_reached();
1279 #define ARM_CP_RW_BIT (1 << 20)
1281 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1283 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1286 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1288 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1291 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1293 TCGv_i32 var = tcg_temp_new_i32();
1294 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1295 return var;
1298 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1300 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1301 tcg_temp_free_i32(var);
1304 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1306 iwmmxt_store_reg(cpu_M0, rn);
1309 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1311 iwmmxt_load_reg(cpu_M0, rn);
1314 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1316 iwmmxt_load_reg(cpu_V1, rn);
1317 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1320 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1322 iwmmxt_load_reg(cpu_V1, rn);
1323 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1326 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1328 iwmmxt_load_reg(cpu_V1, rn);
1329 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1332 #define IWMMXT_OP(name) \
1333 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1335 iwmmxt_load_reg(cpu_V1, rn); \
1336 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1339 #define IWMMXT_OP_ENV(name) \
1340 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1342 iwmmxt_load_reg(cpu_V1, rn); \
1343 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1346 #define IWMMXT_OP_ENV_SIZE(name) \
1347 IWMMXT_OP_ENV(name##b) \
1348 IWMMXT_OP_ENV(name##w) \
1349 IWMMXT_OP_ENV(name##l)
1351 #define IWMMXT_OP_ENV1(name) \
1352 static inline void gen_op_iwmmxt_##name##_M0(void) \
1354 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1357 IWMMXT_OP(maddsq)
1358 IWMMXT_OP(madduq)
1359 IWMMXT_OP(sadb)
1360 IWMMXT_OP(sadw)
1361 IWMMXT_OP(mulslw)
1362 IWMMXT_OP(mulshw)
1363 IWMMXT_OP(mululw)
1364 IWMMXT_OP(muluhw)
1365 IWMMXT_OP(macsw)
1366 IWMMXT_OP(macuw)
1368 IWMMXT_OP_ENV_SIZE(unpackl)
1369 IWMMXT_OP_ENV_SIZE(unpackh)
1371 IWMMXT_OP_ENV1(unpacklub)
1372 IWMMXT_OP_ENV1(unpackluw)
1373 IWMMXT_OP_ENV1(unpacklul)
1374 IWMMXT_OP_ENV1(unpackhub)
1375 IWMMXT_OP_ENV1(unpackhuw)
1376 IWMMXT_OP_ENV1(unpackhul)
1377 IWMMXT_OP_ENV1(unpacklsb)
1378 IWMMXT_OP_ENV1(unpacklsw)
1379 IWMMXT_OP_ENV1(unpacklsl)
1380 IWMMXT_OP_ENV1(unpackhsb)
1381 IWMMXT_OP_ENV1(unpackhsw)
1382 IWMMXT_OP_ENV1(unpackhsl)
1384 IWMMXT_OP_ENV_SIZE(cmpeq)
1385 IWMMXT_OP_ENV_SIZE(cmpgtu)
1386 IWMMXT_OP_ENV_SIZE(cmpgts)
1388 IWMMXT_OP_ENV_SIZE(mins)
1389 IWMMXT_OP_ENV_SIZE(minu)
1390 IWMMXT_OP_ENV_SIZE(maxs)
1391 IWMMXT_OP_ENV_SIZE(maxu)
1393 IWMMXT_OP_ENV_SIZE(subn)
1394 IWMMXT_OP_ENV_SIZE(addn)
1395 IWMMXT_OP_ENV_SIZE(subu)
1396 IWMMXT_OP_ENV_SIZE(addu)
1397 IWMMXT_OP_ENV_SIZE(subs)
1398 IWMMXT_OP_ENV_SIZE(adds)
1400 IWMMXT_OP_ENV(avgb0)
1401 IWMMXT_OP_ENV(avgb1)
1402 IWMMXT_OP_ENV(avgw0)
1403 IWMMXT_OP_ENV(avgw1)
1405 IWMMXT_OP_ENV(packuw)
1406 IWMMXT_OP_ENV(packul)
1407 IWMMXT_OP_ENV(packuq)
1408 IWMMXT_OP_ENV(packsw)
1409 IWMMXT_OP_ENV(packsl)
1410 IWMMXT_OP_ENV(packsq)
1412 static void gen_op_iwmmxt_set_mup(void)
1414 TCGv_i32 tmp;
1415 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1416 tcg_gen_ori_i32(tmp, tmp, 2);
1417 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1420 static void gen_op_iwmmxt_set_cup(void)
1422 TCGv_i32 tmp;
1423 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1424 tcg_gen_ori_i32(tmp, tmp, 1);
1425 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1428 static void gen_op_iwmmxt_setpsr_nz(void)
1430 TCGv_i32 tmp = tcg_temp_new_i32();
1431 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1432 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1435 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1437 iwmmxt_load_reg(cpu_V1, rn);
1438 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1439 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1442 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1443 TCGv_i32 dest)
1445 int rd;
1446 uint32_t offset;
1447 TCGv_i32 tmp;
1449 rd = (insn >> 16) & 0xf;
1450 tmp = load_reg(s, rd);
1452 offset = (insn & 0xff) << ((insn >> 7) & 2);
1453 if (insn & (1 << 24)) {
1454 /* Pre indexed */
1455 if (insn & (1 << 23))
1456 tcg_gen_addi_i32(tmp, tmp, offset);
1457 else
1458 tcg_gen_addi_i32(tmp, tmp, -offset);
1459 tcg_gen_mov_i32(dest, tmp);
1460 if (insn & (1 << 21))
1461 store_reg(s, rd, tmp);
1462 else
1463 tcg_temp_free_i32(tmp);
1464 } else if (insn & (1 << 21)) {
1465 /* Post indexed */
1466 tcg_gen_mov_i32(dest, tmp);
1467 if (insn & (1 << 23))
1468 tcg_gen_addi_i32(tmp, tmp, offset);
1469 else
1470 tcg_gen_addi_i32(tmp, tmp, -offset);
1471 store_reg(s, rd, tmp);
1472 } else if (!(insn & (1 << 23)))
1473 return 1;
1474 return 0;
1477 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1479 int rd = (insn >> 0) & 0xf;
1480 TCGv_i32 tmp;
1482 if (insn & (1 << 8)) {
1483 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1484 return 1;
1485 } else {
1486 tmp = iwmmxt_load_creg(rd);
1488 } else {
1489 tmp = tcg_temp_new_i32();
1490 iwmmxt_load_reg(cpu_V0, rd);
1491 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1493 tcg_gen_andi_i32(tmp, tmp, mask);
1494 tcg_gen_mov_i32(dest, tmp);
1495 tcg_temp_free_i32(tmp);
1496 return 0;
1499 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1500 (ie. an undefined instruction). */
1501 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1503 int rd, wrd;
1504 int rdhi, rdlo, rd0, rd1, i;
1505 TCGv_i32 addr;
1506 TCGv_i32 tmp, tmp2, tmp3;
1508 if ((insn & 0x0e000e00) == 0x0c000000) {
1509 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1510 wrd = insn & 0xf;
1511 rdlo = (insn >> 12) & 0xf;
1512 rdhi = (insn >> 16) & 0xf;
1513 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1514 iwmmxt_load_reg(cpu_V0, wrd);
1515 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1516 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1517 } else { /* TMCRR */
1518 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1519 iwmmxt_store_reg(cpu_V0, wrd);
1520 gen_op_iwmmxt_set_mup();
1522 return 0;
1525 wrd = (insn >> 12) & 0xf;
1526 addr = tcg_temp_new_i32();
1527 if (gen_iwmmxt_address(s, insn, addr)) {
1528 tcg_temp_free_i32(addr);
1529 return 1;
1531 if (insn & ARM_CP_RW_BIT) {
1532 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1533 tmp = tcg_temp_new_i32();
1534 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1535 iwmmxt_store_creg(wrd, tmp);
1536 } else {
1537 i = 1;
1538 if (insn & (1 << 8)) {
1539 if (insn & (1 << 22)) { /* WLDRD */
1540 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1541 i = 0;
1542 } else { /* WLDRW wRd */
1543 tmp = tcg_temp_new_i32();
1544 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1546 } else {
1547 tmp = tcg_temp_new_i32();
1548 if (insn & (1 << 22)) { /* WLDRH */
1549 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1550 } else { /* WLDRB */
1551 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1554 if (i) {
1555 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1556 tcg_temp_free_i32(tmp);
1558 gen_op_iwmmxt_movq_wRn_M0(wrd);
1560 } else {
1561 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1562 tmp = iwmmxt_load_creg(wrd);
1563 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1564 } else {
1565 gen_op_iwmmxt_movq_M0_wRn(wrd);
1566 tmp = tcg_temp_new_i32();
1567 if (insn & (1 << 8)) {
1568 if (insn & (1 << 22)) { /* WSTRD */
1569 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1570 } else { /* WSTRW wRd */
1571 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1572 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1574 } else {
1575 if (insn & (1 << 22)) { /* WSTRH */
1576 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1577 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1578 } else { /* WSTRB */
1579 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1580 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1584 tcg_temp_free_i32(tmp);
1586 tcg_temp_free_i32(addr);
1587 return 0;
1590 if ((insn & 0x0f000000) != 0x0e000000)
1591 return 1;
1593 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1594 case 0x000: /* WOR */
1595 wrd = (insn >> 12) & 0xf;
1596 rd0 = (insn >> 0) & 0xf;
1597 rd1 = (insn >> 16) & 0xf;
1598 gen_op_iwmmxt_movq_M0_wRn(rd0);
1599 gen_op_iwmmxt_orq_M0_wRn(rd1);
1600 gen_op_iwmmxt_setpsr_nz();
1601 gen_op_iwmmxt_movq_wRn_M0(wrd);
1602 gen_op_iwmmxt_set_mup();
1603 gen_op_iwmmxt_set_cup();
1604 break;
1605 case 0x011: /* TMCR */
1606 if (insn & 0xf)
1607 return 1;
1608 rd = (insn >> 12) & 0xf;
1609 wrd = (insn >> 16) & 0xf;
1610 switch (wrd) {
1611 case ARM_IWMMXT_wCID:
1612 case ARM_IWMMXT_wCASF:
1613 break;
1614 case ARM_IWMMXT_wCon:
1615 gen_op_iwmmxt_set_cup();
1616 /* Fall through. */
1617 case ARM_IWMMXT_wCSSF:
1618 tmp = iwmmxt_load_creg(wrd);
1619 tmp2 = load_reg(s, rd);
1620 tcg_gen_andc_i32(tmp, tmp, tmp2);
1621 tcg_temp_free_i32(tmp2);
1622 iwmmxt_store_creg(wrd, tmp);
1623 break;
1624 case ARM_IWMMXT_wCGR0:
1625 case ARM_IWMMXT_wCGR1:
1626 case ARM_IWMMXT_wCGR2:
1627 case ARM_IWMMXT_wCGR3:
1628 gen_op_iwmmxt_set_cup();
1629 tmp = load_reg(s, rd);
1630 iwmmxt_store_creg(wrd, tmp);
1631 break;
1632 default:
1633 return 1;
1635 break;
1636 case 0x100: /* WXOR */
1637 wrd = (insn >> 12) & 0xf;
1638 rd0 = (insn >> 0) & 0xf;
1639 rd1 = (insn >> 16) & 0xf;
1640 gen_op_iwmmxt_movq_M0_wRn(rd0);
1641 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1642 gen_op_iwmmxt_setpsr_nz();
1643 gen_op_iwmmxt_movq_wRn_M0(wrd);
1644 gen_op_iwmmxt_set_mup();
1645 gen_op_iwmmxt_set_cup();
1646 break;
1647 case 0x111: /* TMRC */
1648 if (insn & 0xf)
1649 return 1;
1650 rd = (insn >> 12) & 0xf;
1651 wrd = (insn >> 16) & 0xf;
1652 tmp = iwmmxt_load_creg(wrd);
1653 store_reg(s, rd, tmp);
1654 break;
1655 case 0x300: /* WANDN */
1656 wrd = (insn >> 12) & 0xf;
1657 rd0 = (insn >> 0) & 0xf;
1658 rd1 = (insn >> 16) & 0xf;
1659 gen_op_iwmmxt_movq_M0_wRn(rd0);
1660 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1661 gen_op_iwmmxt_andq_M0_wRn(rd1);
1662 gen_op_iwmmxt_setpsr_nz();
1663 gen_op_iwmmxt_movq_wRn_M0(wrd);
1664 gen_op_iwmmxt_set_mup();
1665 gen_op_iwmmxt_set_cup();
1666 break;
1667 case 0x200: /* WAND */
1668 wrd = (insn >> 12) & 0xf;
1669 rd0 = (insn >> 0) & 0xf;
1670 rd1 = (insn >> 16) & 0xf;
1671 gen_op_iwmmxt_movq_M0_wRn(rd0);
1672 gen_op_iwmmxt_andq_M0_wRn(rd1);
1673 gen_op_iwmmxt_setpsr_nz();
1674 gen_op_iwmmxt_movq_wRn_M0(wrd);
1675 gen_op_iwmmxt_set_mup();
1676 gen_op_iwmmxt_set_cup();
1677 break;
1678 case 0x810: case 0xa10: /* WMADD */
1679 wrd = (insn >> 12) & 0xf;
1680 rd0 = (insn >> 0) & 0xf;
1681 rd1 = (insn >> 16) & 0xf;
1682 gen_op_iwmmxt_movq_M0_wRn(rd0);
1683 if (insn & (1 << 21))
1684 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1685 else
1686 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1687 gen_op_iwmmxt_movq_wRn_M0(wrd);
1688 gen_op_iwmmxt_set_mup();
1689 break;
1690 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1691 wrd = (insn >> 12) & 0xf;
1692 rd0 = (insn >> 16) & 0xf;
1693 rd1 = (insn >> 0) & 0xf;
1694 gen_op_iwmmxt_movq_M0_wRn(rd0);
1695 switch ((insn >> 22) & 3) {
1696 case 0:
1697 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1698 break;
1699 case 1:
1700 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1701 break;
1702 case 2:
1703 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1704 break;
1705 case 3:
1706 return 1;
1708 gen_op_iwmmxt_movq_wRn_M0(wrd);
1709 gen_op_iwmmxt_set_mup();
1710 gen_op_iwmmxt_set_cup();
1711 break;
1712 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1713 wrd = (insn >> 12) & 0xf;
1714 rd0 = (insn >> 16) & 0xf;
1715 rd1 = (insn >> 0) & 0xf;
1716 gen_op_iwmmxt_movq_M0_wRn(rd0);
1717 switch ((insn >> 22) & 3) {
1718 case 0:
1719 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1720 break;
1721 case 1:
1722 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1723 break;
1724 case 2:
1725 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1726 break;
1727 case 3:
1728 return 1;
1730 gen_op_iwmmxt_movq_wRn_M0(wrd);
1731 gen_op_iwmmxt_set_mup();
1732 gen_op_iwmmxt_set_cup();
1733 break;
1734 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1735 wrd = (insn >> 12) & 0xf;
1736 rd0 = (insn >> 16) & 0xf;
1737 rd1 = (insn >> 0) & 0xf;
1738 gen_op_iwmmxt_movq_M0_wRn(rd0);
1739 if (insn & (1 << 22))
1740 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1741 else
1742 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1743 if (!(insn & (1 << 20)))
1744 gen_op_iwmmxt_addl_M0_wRn(wrd);
1745 gen_op_iwmmxt_movq_wRn_M0(wrd);
1746 gen_op_iwmmxt_set_mup();
1747 break;
1748 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1749 wrd = (insn >> 12) & 0xf;
1750 rd0 = (insn >> 16) & 0xf;
1751 rd1 = (insn >> 0) & 0xf;
1752 gen_op_iwmmxt_movq_M0_wRn(rd0);
1753 if (insn & (1 << 21)) {
1754 if (insn & (1 << 20))
1755 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1756 else
1757 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1758 } else {
1759 if (insn & (1 << 20))
1760 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1761 else
1762 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1764 gen_op_iwmmxt_movq_wRn_M0(wrd);
1765 gen_op_iwmmxt_set_mup();
1766 break;
1767 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1768 wrd = (insn >> 12) & 0xf;
1769 rd0 = (insn >> 16) & 0xf;
1770 rd1 = (insn >> 0) & 0xf;
1771 gen_op_iwmmxt_movq_M0_wRn(rd0);
1772 if (insn & (1 << 21))
1773 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1774 else
1775 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1776 if (!(insn & (1 << 20))) {
1777 iwmmxt_load_reg(cpu_V1, wrd);
1778 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1780 gen_op_iwmmxt_movq_wRn_M0(wrd);
1781 gen_op_iwmmxt_set_mup();
1782 break;
1783 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1784 wrd = (insn >> 12) & 0xf;
1785 rd0 = (insn >> 16) & 0xf;
1786 rd1 = (insn >> 0) & 0xf;
1787 gen_op_iwmmxt_movq_M0_wRn(rd0);
1788 switch ((insn >> 22) & 3) {
1789 case 0:
1790 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1791 break;
1792 case 1:
1793 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1794 break;
1795 case 2:
1796 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1797 break;
1798 case 3:
1799 return 1;
1801 gen_op_iwmmxt_movq_wRn_M0(wrd);
1802 gen_op_iwmmxt_set_mup();
1803 gen_op_iwmmxt_set_cup();
1804 break;
1805 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1806 wrd = (insn >> 12) & 0xf;
1807 rd0 = (insn >> 16) & 0xf;
1808 rd1 = (insn >> 0) & 0xf;
1809 gen_op_iwmmxt_movq_M0_wRn(rd0);
1810 if (insn & (1 << 22)) {
1811 if (insn & (1 << 20))
1812 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1813 else
1814 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1815 } else {
1816 if (insn & (1 << 20))
1817 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1818 else
1819 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1821 gen_op_iwmmxt_movq_wRn_M0(wrd);
1822 gen_op_iwmmxt_set_mup();
1823 gen_op_iwmmxt_set_cup();
1824 break;
1825 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1826 wrd = (insn >> 12) & 0xf;
1827 rd0 = (insn >> 16) & 0xf;
1828 rd1 = (insn >> 0) & 0xf;
1829 gen_op_iwmmxt_movq_M0_wRn(rd0);
1830 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1831 tcg_gen_andi_i32(tmp, tmp, 7);
1832 iwmmxt_load_reg(cpu_V1, rd1);
1833 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1834 tcg_temp_free_i32(tmp);
1835 gen_op_iwmmxt_movq_wRn_M0(wrd);
1836 gen_op_iwmmxt_set_mup();
1837 break;
1838 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1839 if (((insn >> 6) & 3) == 3)
1840 return 1;
1841 rd = (insn >> 12) & 0xf;
1842 wrd = (insn >> 16) & 0xf;
1843 tmp = load_reg(s, rd);
1844 gen_op_iwmmxt_movq_M0_wRn(wrd);
1845 switch ((insn >> 6) & 3) {
1846 case 0:
1847 tmp2 = tcg_constant_i32(0xff);
1848 tmp3 = tcg_constant_i32((insn & 7) << 3);
1849 break;
1850 case 1:
1851 tmp2 = tcg_constant_i32(0xffff);
1852 tmp3 = tcg_constant_i32((insn & 3) << 4);
1853 break;
1854 case 2:
1855 tmp2 = tcg_constant_i32(0xffffffff);
1856 tmp3 = tcg_constant_i32((insn & 1) << 5);
1857 break;
1858 default:
1859 g_assert_not_reached();
1861 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1862 tcg_temp_free_i32(tmp);
1863 gen_op_iwmmxt_movq_wRn_M0(wrd);
1864 gen_op_iwmmxt_set_mup();
1865 break;
1866 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1867 rd = (insn >> 12) & 0xf;
1868 wrd = (insn >> 16) & 0xf;
1869 if (rd == 15 || ((insn >> 22) & 3) == 3)
1870 return 1;
1871 gen_op_iwmmxt_movq_M0_wRn(wrd);
1872 tmp = tcg_temp_new_i32();
1873 switch ((insn >> 22) & 3) {
1874 case 0:
1875 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1876 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1877 if (insn & 8) {
1878 tcg_gen_ext8s_i32(tmp, tmp);
1879 } else {
1880 tcg_gen_andi_i32(tmp, tmp, 0xff);
1882 break;
1883 case 1:
1884 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1885 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1886 if (insn & 8) {
1887 tcg_gen_ext16s_i32(tmp, tmp);
1888 } else {
1889 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1891 break;
1892 case 2:
1893 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1894 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1895 break;
1897 store_reg(s, rd, tmp);
1898 break;
1899 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1900 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1901 return 1;
1902 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1903 switch ((insn >> 22) & 3) {
1904 case 0:
1905 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1906 break;
1907 case 1:
1908 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1909 break;
1910 case 2:
1911 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1912 break;
1914 tcg_gen_shli_i32(tmp, tmp, 28);
1915 gen_set_nzcv(tmp);
1916 tcg_temp_free_i32(tmp);
1917 break;
1918 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1919 if (((insn >> 6) & 3) == 3)
1920 return 1;
1921 rd = (insn >> 12) & 0xf;
1922 wrd = (insn >> 16) & 0xf;
1923 tmp = load_reg(s, rd);
1924 switch ((insn >> 6) & 3) {
1925 case 0:
1926 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1927 break;
1928 case 1:
1929 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1930 break;
1931 case 2:
1932 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1933 break;
1935 tcg_temp_free_i32(tmp);
1936 gen_op_iwmmxt_movq_wRn_M0(wrd);
1937 gen_op_iwmmxt_set_mup();
1938 break;
1939 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1940 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1941 return 1;
1942 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1943 tmp2 = tcg_temp_new_i32();
1944 tcg_gen_mov_i32(tmp2, tmp);
1945 switch ((insn >> 22) & 3) {
1946 case 0:
1947 for (i = 0; i < 7; i ++) {
1948 tcg_gen_shli_i32(tmp2, tmp2, 4);
1949 tcg_gen_and_i32(tmp, tmp, tmp2);
1951 break;
1952 case 1:
1953 for (i = 0; i < 3; i ++) {
1954 tcg_gen_shli_i32(tmp2, tmp2, 8);
1955 tcg_gen_and_i32(tmp, tmp, tmp2);
1957 break;
1958 case 2:
1959 tcg_gen_shli_i32(tmp2, tmp2, 16);
1960 tcg_gen_and_i32(tmp, tmp, tmp2);
1961 break;
1963 gen_set_nzcv(tmp);
1964 tcg_temp_free_i32(tmp2);
1965 tcg_temp_free_i32(tmp);
1966 break;
1967 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1968 wrd = (insn >> 12) & 0xf;
1969 rd0 = (insn >> 16) & 0xf;
1970 gen_op_iwmmxt_movq_M0_wRn(rd0);
1971 switch ((insn >> 22) & 3) {
1972 case 0:
1973 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1974 break;
1975 case 1:
1976 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1977 break;
1978 case 2:
1979 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1980 break;
1981 case 3:
1982 return 1;
1984 gen_op_iwmmxt_movq_wRn_M0(wrd);
1985 gen_op_iwmmxt_set_mup();
1986 break;
1987 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1988 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1989 return 1;
1990 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1991 tmp2 = tcg_temp_new_i32();
1992 tcg_gen_mov_i32(tmp2, tmp);
1993 switch ((insn >> 22) & 3) {
1994 case 0:
1995 for (i = 0; i < 7; i ++) {
1996 tcg_gen_shli_i32(tmp2, tmp2, 4);
1997 tcg_gen_or_i32(tmp, tmp, tmp2);
1999 break;
2000 case 1:
2001 for (i = 0; i < 3; i ++) {
2002 tcg_gen_shli_i32(tmp2, tmp2, 8);
2003 tcg_gen_or_i32(tmp, tmp, tmp2);
2005 break;
2006 case 2:
2007 tcg_gen_shli_i32(tmp2, tmp2, 16);
2008 tcg_gen_or_i32(tmp, tmp, tmp2);
2009 break;
2011 gen_set_nzcv(tmp);
2012 tcg_temp_free_i32(tmp2);
2013 tcg_temp_free_i32(tmp);
2014 break;
2015 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2016 rd = (insn >> 12) & 0xf;
2017 rd0 = (insn >> 16) & 0xf;
2018 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2019 return 1;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0);
2021 tmp = tcg_temp_new_i32();
2022 switch ((insn >> 22) & 3) {
2023 case 0:
2024 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2025 break;
2026 case 1:
2027 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2028 break;
2029 case 2:
2030 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2031 break;
2033 store_reg(s, rd, tmp);
2034 break;
2035 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2036 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2037 wrd = (insn >> 12) & 0xf;
2038 rd0 = (insn >> 16) & 0xf;
2039 rd1 = (insn >> 0) & 0xf;
2040 gen_op_iwmmxt_movq_M0_wRn(rd0);
2041 switch ((insn >> 22) & 3) {
2042 case 0:
2043 if (insn & (1 << 21))
2044 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2045 else
2046 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2047 break;
2048 case 1:
2049 if (insn & (1 << 21))
2050 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2051 else
2052 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2053 break;
2054 case 2:
2055 if (insn & (1 << 21))
2056 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2057 else
2058 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2059 break;
2060 case 3:
2061 return 1;
2063 gen_op_iwmmxt_movq_wRn_M0(wrd);
2064 gen_op_iwmmxt_set_mup();
2065 gen_op_iwmmxt_set_cup();
2066 break;
2067 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2068 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2069 wrd = (insn >> 12) & 0xf;
2070 rd0 = (insn >> 16) & 0xf;
2071 gen_op_iwmmxt_movq_M0_wRn(rd0);
2072 switch ((insn >> 22) & 3) {
2073 case 0:
2074 if (insn & (1 << 21))
2075 gen_op_iwmmxt_unpacklsb_M0();
2076 else
2077 gen_op_iwmmxt_unpacklub_M0();
2078 break;
2079 case 1:
2080 if (insn & (1 << 21))
2081 gen_op_iwmmxt_unpacklsw_M0();
2082 else
2083 gen_op_iwmmxt_unpackluw_M0();
2084 break;
2085 case 2:
2086 if (insn & (1 << 21))
2087 gen_op_iwmmxt_unpacklsl_M0();
2088 else
2089 gen_op_iwmmxt_unpacklul_M0();
2090 break;
2091 case 3:
2092 return 1;
2094 gen_op_iwmmxt_movq_wRn_M0(wrd);
2095 gen_op_iwmmxt_set_mup();
2096 gen_op_iwmmxt_set_cup();
2097 break;
2098 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2099 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2100 wrd = (insn >> 12) & 0xf;
2101 rd0 = (insn >> 16) & 0xf;
2102 gen_op_iwmmxt_movq_M0_wRn(rd0);
2103 switch ((insn >> 22) & 3) {
2104 case 0:
2105 if (insn & (1 << 21))
2106 gen_op_iwmmxt_unpackhsb_M0();
2107 else
2108 gen_op_iwmmxt_unpackhub_M0();
2109 break;
2110 case 1:
2111 if (insn & (1 << 21))
2112 gen_op_iwmmxt_unpackhsw_M0();
2113 else
2114 gen_op_iwmmxt_unpackhuw_M0();
2115 break;
2116 case 2:
2117 if (insn & (1 << 21))
2118 gen_op_iwmmxt_unpackhsl_M0();
2119 else
2120 gen_op_iwmmxt_unpackhul_M0();
2121 break;
2122 case 3:
2123 return 1;
2125 gen_op_iwmmxt_movq_wRn_M0(wrd);
2126 gen_op_iwmmxt_set_mup();
2127 gen_op_iwmmxt_set_cup();
2128 break;
2129 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2130 case 0x214: case 0x614: case 0xa14: case 0xe14:
2131 if (((insn >> 22) & 3) == 0)
2132 return 1;
2133 wrd = (insn >> 12) & 0xf;
2134 rd0 = (insn >> 16) & 0xf;
2135 gen_op_iwmmxt_movq_M0_wRn(rd0);
2136 tmp = tcg_temp_new_i32();
2137 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2138 tcg_temp_free_i32(tmp);
2139 return 1;
2141 switch ((insn >> 22) & 3) {
2142 case 1:
2143 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2144 break;
2145 case 2:
2146 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2147 break;
2148 case 3:
2149 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2150 break;
2152 tcg_temp_free_i32(tmp);
2153 gen_op_iwmmxt_movq_wRn_M0(wrd);
2154 gen_op_iwmmxt_set_mup();
2155 gen_op_iwmmxt_set_cup();
2156 break;
2157 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2158 case 0x014: case 0x414: case 0x814: case 0xc14:
2159 if (((insn >> 22) & 3) == 0)
2160 return 1;
2161 wrd = (insn >> 12) & 0xf;
2162 rd0 = (insn >> 16) & 0xf;
2163 gen_op_iwmmxt_movq_M0_wRn(rd0);
2164 tmp = tcg_temp_new_i32();
2165 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2166 tcg_temp_free_i32(tmp);
2167 return 1;
2169 switch ((insn >> 22) & 3) {
2170 case 1:
2171 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2172 break;
2173 case 2:
2174 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2175 break;
2176 case 3:
2177 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2178 break;
2180 tcg_temp_free_i32(tmp);
2181 gen_op_iwmmxt_movq_wRn_M0(wrd);
2182 gen_op_iwmmxt_set_mup();
2183 gen_op_iwmmxt_set_cup();
2184 break;
2185 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2186 case 0x114: case 0x514: case 0x914: case 0xd14:
2187 if (((insn >> 22) & 3) == 0)
2188 return 1;
2189 wrd = (insn >> 12) & 0xf;
2190 rd0 = (insn >> 16) & 0xf;
2191 gen_op_iwmmxt_movq_M0_wRn(rd0);
2192 tmp = tcg_temp_new_i32();
2193 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2194 tcg_temp_free_i32(tmp);
2195 return 1;
2197 switch ((insn >> 22) & 3) {
2198 case 1:
2199 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2200 break;
2201 case 2:
2202 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2203 break;
2204 case 3:
2205 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2206 break;
2208 tcg_temp_free_i32(tmp);
2209 gen_op_iwmmxt_movq_wRn_M0(wrd);
2210 gen_op_iwmmxt_set_mup();
2211 gen_op_iwmmxt_set_cup();
2212 break;
2213 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2214 case 0x314: case 0x714: case 0xb14: case 0xf14:
2215 if (((insn >> 22) & 3) == 0)
2216 return 1;
2217 wrd = (insn >> 12) & 0xf;
2218 rd0 = (insn >> 16) & 0xf;
2219 gen_op_iwmmxt_movq_M0_wRn(rd0);
2220 tmp = tcg_temp_new_i32();
2221 switch ((insn >> 22) & 3) {
2222 case 1:
2223 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2224 tcg_temp_free_i32(tmp);
2225 return 1;
2227 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2228 break;
2229 case 2:
2230 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2231 tcg_temp_free_i32(tmp);
2232 return 1;
2234 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2235 break;
2236 case 3:
2237 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2238 tcg_temp_free_i32(tmp);
2239 return 1;
2241 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2242 break;
2244 tcg_temp_free_i32(tmp);
2245 gen_op_iwmmxt_movq_wRn_M0(wrd);
2246 gen_op_iwmmxt_set_mup();
2247 gen_op_iwmmxt_set_cup();
2248 break;
2249 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2250 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2251 wrd = (insn >> 12) & 0xf;
2252 rd0 = (insn >> 16) & 0xf;
2253 rd1 = (insn >> 0) & 0xf;
2254 gen_op_iwmmxt_movq_M0_wRn(rd0);
2255 switch ((insn >> 22) & 3) {
2256 case 0:
2257 if (insn & (1 << 21))
2258 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2259 else
2260 gen_op_iwmmxt_minub_M0_wRn(rd1);
2261 break;
2262 case 1:
2263 if (insn & (1 << 21))
2264 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2265 else
2266 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2267 break;
2268 case 2:
2269 if (insn & (1 << 21))
2270 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2271 else
2272 gen_op_iwmmxt_minul_M0_wRn(rd1);
2273 break;
2274 case 3:
2275 return 1;
2277 gen_op_iwmmxt_movq_wRn_M0(wrd);
2278 gen_op_iwmmxt_set_mup();
2279 break;
2280 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2281 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2282 wrd = (insn >> 12) & 0xf;
2283 rd0 = (insn >> 16) & 0xf;
2284 rd1 = (insn >> 0) & 0xf;
2285 gen_op_iwmmxt_movq_M0_wRn(rd0);
2286 switch ((insn >> 22) & 3) {
2287 case 0:
2288 if (insn & (1 << 21))
2289 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2290 else
2291 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2292 break;
2293 case 1:
2294 if (insn & (1 << 21))
2295 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2296 else
2297 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2298 break;
2299 case 2:
2300 if (insn & (1 << 21))
2301 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2302 else
2303 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2304 break;
2305 case 3:
2306 return 1;
2308 gen_op_iwmmxt_movq_wRn_M0(wrd);
2309 gen_op_iwmmxt_set_mup();
2310 break;
2311 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2312 case 0x402: case 0x502: case 0x602: case 0x702:
2313 wrd = (insn >> 12) & 0xf;
2314 rd0 = (insn >> 16) & 0xf;
2315 rd1 = (insn >> 0) & 0xf;
2316 gen_op_iwmmxt_movq_M0_wRn(rd0);
2317 iwmmxt_load_reg(cpu_V1, rd1);
2318 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1,
2319 tcg_constant_i32((insn >> 20) & 3));
2320 gen_op_iwmmxt_movq_wRn_M0(wrd);
2321 gen_op_iwmmxt_set_mup();
2322 break;
2323 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2324 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2325 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2326 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2327 wrd = (insn >> 12) & 0xf;
2328 rd0 = (insn >> 16) & 0xf;
2329 rd1 = (insn >> 0) & 0xf;
2330 gen_op_iwmmxt_movq_M0_wRn(rd0);
2331 switch ((insn >> 20) & 0xf) {
2332 case 0x0:
2333 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2334 break;
2335 case 0x1:
2336 gen_op_iwmmxt_subub_M0_wRn(rd1);
2337 break;
2338 case 0x3:
2339 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2340 break;
2341 case 0x4:
2342 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2343 break;
2344 case 0x5:
2345 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2346 break;
2347 case 0x7:
2348 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2349 break;
2350 case 0x8:
2351 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2352 break;
2353 case 0x9:
2354 gen_op_iwmmxt_subul_M0_wRn(rd1);
2355 break;
2356 case 0xb:
2357 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2358 break;
2359 default:
2360 return 1;
2362 gen_op_iwmmxt_movq_wRn_M0(wrd);
2363 gen_op_iwmmxt_set_mup();
2364 gen_op_iwmmxt_set_cup();
2365 break;
2366 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2367 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2368 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2369 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2370 wrd = (insn >> 12) & 0xf;
2371 rd0 = (insn >> 16) & 0xf;
2372 gen_op_iwmmxt_movq_M0_wRn(rd0);
2373 tmp = tcg_constant_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2374 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2375 gen_op_iwmmxt_movq_wRn_M0(wrd);
2376 gen_op_iwmmxt_set_mup();
2377 gen_op_iwmmxt_set_cup();
2378 break;
2379 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2380 case 0x418: case 0x518: case 0x618: case 0x718:
2381 case 0x818: case 0x918: case 0xa18: case 0xb18:
2382 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2383 wrd = (insn >> 12) & 0xf;
2384 rd0 = (insn >> 16) & 0xf;
2385 rd1 = (insn >> 0) & 0xf;
2386 gen_op_iwmmxt_movq_M0_wRn(rd0);
2387 switch ((insn >> 20) & 0xf) {
2388 case 0x0:
2389 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2390 break;
2391 case 0x1:
2392 gen_op_iwmmxt_addub_M0_wRn(rd1);
2393 break;
2394 case 0x3:
2395 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2396 break;
2397 case 0x4:
2398 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2399 break;
2400 case 0x5:
2401 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2402 break;
2403 case 0x7:
2404 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2405 break;
2406 case 0x8:
2407 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2408 break;
2409 case 0x9:
2410 gen_op_iwmmxt_addul_M0_wRn(rd1);
2411 break;
2412 case 0xb:
2413 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2414 break;
2415 default:
2416 return 1;
2418 gen_op_iwmmxt_movq_wRn_M0(wrd);
2419 gen_op_iwmmxt_set_mup();
2420 gen_op_iwmmxt_set_cup();
2421 break;
2422 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2423 case 0x408: case 0x508: case 0x608: case 0x708:
2424 case 0x808: case 0x908: case 0xa08: case 0xb08:
2425 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2426 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2427 return 1;
2428 wrd = (insn >> 12) & 0xf;
2429 rd0 = (insn >> 16) & 0xf;
2430 rd1 = (insn >> 0) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0);
2432 switch ((insn >> 22) & 3) {
2433 case 1:
2434 if (insn & (1 << 21))
2435 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2436 else
2437 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2438 break;
2439 case 2:
2440 if (insn & (1 << 21))
2441 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2442 else
2443 gen_op_iwmmxt_packul_M0_wRn(rd1);
2444 break;
2445 case 3:
2446 if (insn & (1 << 21))
2447 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2448 else
2449 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2450 break;
2452 gen_op_iwmmxt_movq_wRn_M0(wrd);
2453 gen_op_iwmmxt_set_mup();
2454 gen_op_iwmmxt_set_cup();
2455 break;
2456 case 0x201: case 0x203: case 0x205: case 0x207:
2457 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2458 case 0x211: case 0x213: case 0x215: case 0x217:
2459 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2460 wrd = (insn >> 5) & 0xf;
2461 rd0 = (insn >> 12) & 0xf;
2462 rd1 = (insn >> 0) & 0xf;
2463 if (rd0 == 0xf || rd1 == 0xf)
2464 return 1;
2465 gen_op_iwmmxt_movq_M0_wRn(wrd);
2466 tmp = load_reg(s, rd0);
2467 tmp2 = load_reg(s, rd1);
2468 switch ((insn >> 16) & 0xf) {
2469 case 0x0: /* TMIA */
2470 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2471 break;
2472 case 0x8: /* TMIAPH */
2473 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2474 break;
2475 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2476 if (insn & (1 << 16))
2477 tcg_gen_shri_i32(tmp, tmp, 16);
2478 if (insn & (1 << 17))
2479 tcg_gen_shri_i32(tmp2, tmp2, 16);
2480 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2481 break;
2482 default:
2483 tcg_temp_free_i32(tmp2);
2484 tcg_temp_free_i32(tmp);
2485 return 1;
2487 tcg_temp_free_i32(tmp2);
2488 tcg_temp_free_i32(tmp);
2489 gen_op_iwmmxt_movq_wRn_M0(wrd);
2490 gen_op_iwmmxt_set_mup();
2491 break;
2492 default:
2493 return 1;
2496 return 0;
2499 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2500 (ie. an undefined instruction). */
2501 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2503 int acc, rd0, rd1, rdhi, rdlo;
2504 TCGv_i32 tmp, tmp2;
2506 if ((insn & 0x0ff00f10) == 0x0e200010) {
2507 /* Multiply with Internal Accumulate Format */
2508 rd0 = (insn >> 12) & 0xf;
2509 rd1 = insn & 0xf;
2510 acc = (insn >> 5) & 7;
2512 if (acc != 0)
2513 return 1;
2515 tmp = load_reg(s, rd0);
2516 tmp2 = load_reg(s, rd1);
2517 switch ((insn >> 16) & 0xf) {
2518 case 0x0: /* MIA */
2519 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2520 break;
2521 case 0x8: /* MIAPH */
2522 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2523 break;
2524 case 0xc: /* MIABB */
2525 case 0xd: /* MIABT */
2526 case 0xe: /* MIATB */
2527 case 0xf: /* MIATT */
2528 if (insn & (1 << 16))
2529 tcg_gen_shri_i32(tmp, tmp, 16);
2530 if (insn & (1 << 17))
2531 tcg_gen_shri_i32(tmp2, tmp2, 16);
2532 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2533 break;
2534 default:
2535 return 1;
2537 tcg_temp_free_i32(tmp2);
2538 tcg_temp_free_i32(tmp);
2540 gen_op_iwmmxt_movq_wRn_M0(acc);
2541 return 0;
2544 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2545 /* Internal Accumulator Access Format */
2546 rdhi = (insn >> 16) & 0xf;
2547 rdlo = (insn >> 12) & 0xf;
2548 acc = insn & 7;
2550 if (acc != 0)
2551 return 1;
2553 if (insn & ARM_CP_RW_BIT) { /* MRA */
2554 iwmmxt_load_reg(cpu_V0, acc);
2555 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2556 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2557 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2558 } else { /* MAR */
2559 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2560 iwmmxt_store_reg(cpu_V0, acc);
2562 return 0;
2565 return 1;
2568 static void gen_goto_ptr(void)
2570 tcg_gen_lookup_and_goto_ptr();
2573 /* This will end the TB but doesn't guarantee we'll return to
2574 * cpu_loop_exec. Any live exit_requests will be processed as we
2575 * enter the next TB.
2577 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2579 if (translator_use_goto_tb(&s->base, dest)) {
2580 tcg_gen_goto_tb(n);
2581 gen_set_pc_im(s, dest);
2582 tcg_gen_exit_tb(s->base.tb, n);
2583 } else {
2584 gen_set_pc_im(s, dest);
2585 gen_goto_ptr();
2587 s->base.is_jmp = DISAS_NORETURN;
2590 /* Jump, specifying which TB number to use if we gen_goto_tb() */
2591 static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
2593 if (unlikely(s->ss_active)) {
2594 /* An indirect jump so that we still trigger the debug exception. */
2595 gen_set_pc_im(s, dest);
2596 s->base.is_jmp = DISAS_JUMP;
2597 return;
2599 switch (s->base.is_jmp) {
2600 case DISAS_NEXT:
2601 case DISAS_TOO_MANY:
2602 case DISAS_NORETURN:
2604 * The normal case: just go to the destination TB.
2605 * NB: NORETURN happens if we generate code like
2606 * gen_brcondi(l);
2607 * gen_jmp();
2608 * gen_set_label(l);
2609 * gen_jmp();
2610 * on the second call to gen_jmp().
2612 gen_goto_tb(s, tbno, dest);
2613 break;
2614 case DISAS_UPDATE_NOCHAIN:
2615 case DISAS_UPDATE_EXIT:
2617 * We already decided we're leaving the TB for some other reason.
2618 * Avoid using goto_tb so we really do exit back to the main loop
2619 * and don't chain to another TB.
2621 gen_set_pc_im(s, dest);
2622 gen_goto_ptr();
2623 s->base.is_jmp = DISAS_NORETURN;
2624 break;
2625 default:
2627 * We shouldn't be emitting code for a jump and also have
2628 * is_jmp set to one of the special cases like DISAS_SWI.
2630 g_assert_not_reached();
2634 static inline void gen_jmp(DisasContext *s, uint32_t dest)
2636 gen_jmp_tb(s, dest, 0);
2639 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2641 if (x)
2642 tcg_gen_sari_i32(t0, t0, 16);
2643 else
2644 gen_sxth(t0);
2645 if (y)
2646 tcg_gen_sari_i32(t1, t1, 16);
2647 else
2648 gen_sxth(t1);
2649 tcg_gen_mul_i32(t0, t0, t1);
2652 /* Return the mask of PSR bits set by a MSR instruction. */
2653 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2655 uint32_t mask = 0;
2657 if (flags & (1 << 0)) {
2658 mask |= 0xff;
2660 if (flags & (1 << 1)) {
2661 mask |= 0xff00;
2663 if (flags & (1 << 2)) {
2664 mask |= 0xff0000;
2666 if (flags & (1 << 3)) {
2667 mask |= 0xff000000;
2670 /* Mask out undefined and reserved bits. */
2671 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2673 /* Mask out execution state. */
2674 if (!spsr) {
2675 mask &= ~CPSR_EXEC;
2678 /* Mask out privileged bits. */
2679 if (IS_USER(s)) {
2680 mask &= CPSR_USER;
2682 return mask;
2685 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2686 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2688 TCGv_i32 tmp;
2689 if (spsr) {
2690 /* ??? This is also undefined in system mode. */
2691 if (IS_USER(s))
2692 return 1;
2694 tmp = load_cpu_field(spsr);
2695 tcg_gen_andi_i32(tmp, tmp, ~mask);
2696 tcg_gen_andi_i32(t0, t0, mask);
2697 tcg_gen_or_i32(tmp, tmp, t0);
2698 store_cpu_field(tmp, spsr);
2699 } else {
2700 gen_set_cpsr(t0, mask);
2702 tcg_temp_free_i32(t0);
2703 gen_lookup_tb(s);
2704 return 0;
2707 /* Returns nonzero if access to the PSR is not permitted. */
2708 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2710 TCGv_i32 tmp;
2711 tmp = tcg_temp_new_i32();
2712 tcg_gen_movi_i32(tmp, val);
2713 return gen_set_psr(s, mask, spsr, tmp);
2716 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2717 int *tgtmode, int *regno)
2719 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2720 * the target mode and register number, and identify the various
2721 * unpredictable cases.
2722 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2723 * + executed in user mode
2724 * + using R15 as the src/dest register
2725 * + accessing an unimplemented register
2726 * + accessing a register that's inaccessible at current PL/security state*
2727 * + accessing a register that you could access with a different insn
2728 * We choose to UNDEF in all these cases.
2729 * Since we don't know which of the various AArch32 modes we are in
2730 * we have to defer some checks to runtime.
2731 * Accesses to Monitor mode registers from Secure EL1 (which implies
2732 * that EL3 is AArch64) must trap to EL3.
2734 * If the access checks fail this function will emit code to take
2735 * an exception and return false. Otherwise it will return true,
2736 * and set *tgtmode and *regno appropriately.
2738 int exc_target = default_exception_el(s);
2740 /* These instructions are present only in ARMv8, or in ARMv7 with the
2741 * Virtualization Extensions.
2743 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2744 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2745 goto undef;
2748 if (IS_USER(s) || rn == 15) {
2749 goto undef;
2752 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2753 * of registers into (r, sysm).
2755 if (r) {
2756 /* SPSRs for other modes */
2757 switch (sysm) {
2758 case 0xe: /* SPSR_fiq */
2759 *tgtmode = ARM_CPU_MODE_FIQ;
2760 break;
2761 case 0x10: /* SPSR_irq */
2762 *tgtmode = ARM_CPU_MODE_IRQ;
2763 break;
2764 case 0x12: /* SPSR_svc */
2765 *tgtmode = ARM_CPU_MODE_SVC;
2766 break;
2767 case 0x14: /* SPSR_abt */
2768 *tgtmode = ARM_CPU_MODE_ABT;
2769 break;
2770 case 0x16: /* SPSR_und */
2771 *tgtmode = ARM_CPU_MODE_UND;
2772 break;
2773 case 0x1c: /* SPSR_mon */
2774 *tgtmode = ARM_CPU_MODE_MON;
2775 break;
2776 case 0x1e: /* SPSR_hyp */
2777 *tgtmode = ARM_CPU_MODE_HYP;
2778 break;
2779 default: /* unallocated */
2780 goto undef;
2782 /* We arbitrarily assign SPSR a register number of 16. */
2783 *regno = 16;
2784 } else {
2785 /* general purpose registers for other modes */
2786 switch (sysm) {
2787 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2788 *tgtmode = ARM_CPU_MODE_USR;
2789 *regno = sysm + 8;
2790 break;
2791 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2792 *tgtmode = ARM_CPU_MODE_FIQ;
2793 *regno = sysm;
2794 break;
2795 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2796 *tgtmode = ARM_CPU_MODE_IRQ;
2797 *regno = sysm & 1 ? 13 : 14;
2798 break;
2799 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2800 *tgtmode = ARM_CPU_MODE_SVC;
2801 *regno = sysm & 1 ? 13 : 14;
2802 break;
2803 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2804 *tgtmode = ARM_CPU_MODE_ABT;
2805 *regno = sysm & 1 ? 13 : 14;
2806 break;
2807 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2808 *tgtmode = ARM_CPU_MODE_UND;
2809 *regno = sysm & 1 ? 13 : 14;
2810 break;
2811 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2812 *tgtmode = ARM_CPU_MODE_MON;
2813 *regno = sysm & 1 ? 13 : 14;
2814 break;
2815 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2816 *tgtmode = ARM_CPU_MODE_HYP;
2817 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2818 *regno = sysm & 1 ? 13 : 17;
2819 break;
2820 default: /* unallocated */
2821 goto undef;
2825 /* Catch the 'accessing inaccessible register' cases we can detect
2826 * at translate time.
2828 switch (*tgtmode) {
2829 case ARM_CPU_MODE_MON:
2830 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2831 goto undef;
2833 if (s->current_el == 1) {
2834 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2835 * then accesses to Mon registers trap to Secure EL2, if it exists,
2836 * otherwise EL3.
2838 TCGv_i32 tcg_el;
2840 if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
2841 dc_isar_feature(aa64_sel2, s)) {
2842 /* Target EL is EL<3 minus SCR_EL3.EEL2> */
2843 tcg_el = load_cpu_field(cp15.scr_el3);
2844 tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
2845 tcg_gen_addi_i32(tcg_el, tcg_el, 3);
2846 } else {
2847 tcg_el = tcg_constant_i32(3);
2850 gen_exception_el(s, EXCP_UDEF, syn_uncategorized(), tcg_el);
2851 tcg_temp_free_i32(tcg_el);
2852 return false;
2854 break;
2855 case ARM_CPU_MODE_HYP:
2857 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2858 * (and so we can forbid accesses from EL2 or below). elr_hyp
2859 * can be accessed also from Hyp mode, so forbid accesses from
2860 * EL0 or EL1.
2862 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2863 (s->current_el < 3 && *regno != 17)) {
2864 goto undef;
2866 break;
2867 default:
2868 break;
2871 return true;
2873 undef:
2874 /* If we get here then some access check did not pass */
2875 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2876 syn_uncategorized(), exc_target);
2877 return false;
2880 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2882 TCGv_i32 tcg_reg;
2883 int tgtmode = 0, regno = 0;
2885 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2886 return;
2889 /* Sync state because msr_banked() can raise exceptions */
2890 gen_set_condexec(s);
2891 gen_set_pc_im(s, s->pc_curr);
2892 tcg_reg = load_reg(s, rn);
2893 gen_helper_msr_banked(cpu_env, tcg_reg,
2894 tcg_constant_i32(tgtmode),
2895 tcg_constant_i32(regno));
2896 tcg_temp_free_i32(tcg_reg);
2897 s->base.is_jmp = DISAS_UPDATE_EXIT;
2900 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2902 TCGv_i32 tcg_reg;
2903 int tgtmode = 0, regno = 0;
2905 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2906 return;
2909 /* Sync state because mrs_banked() can raise exceptions */
2910 gen_set_condexec(s);
2911 gen_set_pc_im(s, s->pc_curr);
2912 tcg_reg = tcg_temp_new_i32();
2913 gen_helper_mrs_banked(tcg_reg, cpu_env,
2914 tcg_constant_i32(tgtmode),
2915 tcg_constant_i32(regno));
2916 store_reg(s, rn, tcg_reg);
2917 s->base.is_jmp = DISAS_UPDATE_EXIT;
2920 /* Store value to PC as for an exception return (ie don't
2921 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2922 * will do the masking based on the new value of the Thumb bit.
2924 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2926 tcg_gen_mov_i32(cpu_R[15], pc);
2927 tcg_temp_free_i32(pc);
2930 /* Generate a v6 exception return. Marks both values as dead. */
2931 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2933 store_pc_exc_ret(s, pc);
2934 /* The cpsr_write_eret helper will mask the low bits of PC
2935 * appropriately depending on the new Thumb bit, so it must
2936 * be called after storing the new PC.
2938 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2939 gen_io_start();
2941 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2942 tcg_temp_free_i32(cpsr);
2943 /* Must exit loop to check un-masked IRQs */
2944 s->base.is_jmp = DISAS_EXIT;
2947 /* Generate an old-style exception return. Marks pc as dead. */
2948 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2950 gen_rfe(s, pc, load_cpu_field(spsr));
2953 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
2954 uint32_t opr_sz, uint32_t max_sz,
2955 gen_helper_gvec_3_ptr *fn)
2957 TCGv_ptr qc_ptr = tcg_temp_new_ptr();
2959 tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
2960 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
2961 opr_sz, max_sz, 0, fn);
2962 tcg_temp_free_ptr(qc_ptr);
2965 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2966 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2968 static gen_helper_gvec_3_ptr * const fns[2] = {
2969 gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
2971 tcg_debug_assert(vece >= 1 && vece <= 2);
2972 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2975 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2976 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2978 static gen_helper_gvec_3_ptr * const fns[2] = {
2979 gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
2981 tcg_debug_assert(vece >= 1 && vece <= 2);
2982 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2985 #define GEN_CMP0(NAME, COND) \
2986 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
2988 tcg_gen_setcondi_i32(COND, d, a, 0); \
2989 tcg_gen_neg_i32(d, d); \
2991 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
2993 tcg_gen_setcondi_i64(COND, d, a, 0); \
2994 tcg_gen_neg_i64(d, d); \
2996 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
2998 TCGv_vec zero = tcg_constant_vec_matching(d, vece, 0); \
2999 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
3001 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
3002 uint32_t opr_sz, uint32_t max_sz) \
3004 const GVecGen2 op[4] = { \
3005 { .fno = gen_helper_gvec_##NAME##0_b, \
3006 .fniv = gen_##NAME##0_vec, \
3007 .opt_opc = vecop_list_cmp, \
3008 .vece = MO_8 }, \
3009 { .fno = gen_helper_gvec_##NAME##0_h, \
3010 .fniv = gen_##NAME##0_vec, \
3011 .opt_opc = vecop_list_cmp, \
3012 .vece = MO_16 }, \
3013 { .fni4 = gen_##NAME##0_i32, \
3014 .fniv = gen_##NAME##0_vec, \
3015 .opt_opc = vecop_list_cmp, \
3016 .vece = MO_32 }, \
3017 { .fni8 = gen_##NAME##0_i64, \
3018 .fniv = gen_##NAME##0_vec, \
3019 .opt_opc = vecop_list_cmp, \
3020 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
3021 .vece = MO_64 }, \
3022 }; \
3023 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
3026 static const TCGOpcode vecop_list_cmp[] = {
3027 INDEX_op_cmp_vec, 0
3030 GEN_CMP0(ceq, TCG_COND_EQ)
3031 GEN_CMP0(cle, TCG_COND_LE)
3032 GEN_CMP0(cge, TCG_COND_GE)
3033 GEN_CMP0(clt, TCG_COND_LT)
3034 GEN_CMP0(cgt, TCG_COND_GT)
3036 #undef GEN_CMP0
3038 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3040 tcg_gen_vec_sar8i_i64(a, a, shift);
3041 tcg_gen_vec_add8_i64(d, d, a);
3044 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3046 tcg_gen_vec_sar16i_i64(a, a, shift);
3047 tcg_gen_vec_add16_i64(d, d, a);
3050 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3052 tcg_gen_sari_i32(a, a, shift);
3053 tcg_gen_add_i32(d, d, a);
3056 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3058 tcg_gen_sari_i64(a, a, shift);
3059 tcg_gen_add_i64(d, d, a);
3062 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3064 tcg_gen_sari_vec(vece, a, a, sh);
3065 tcg_gen_add_vec(vece, d, d, a);
3068 void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3069 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3071 static const TCGOpcode vecop_list[] = {
3072 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3074 static const GVecGen2i ops[4] = {
3075 { .fni8 = gen_ssra8_i64,
3076 .fniv = gen_ssra_vec,
3077 .fno = gen_helper_gvec_ssra_b,
3078 .load_dest = true,
3079 .opt_opc = vecop_list,
3080 .vece = MO_8 },
3081 { .fni8 = gen_ssra16_i64,
3082 .fniv = gen_ssra_vec,
3083 .fno = gen_helper_gvec_ssra_h,
3084 .load_dest = true,
3085 .opt_opc = vecop_list,
3086 .vece = MO_16 },
3087 { .fni4 = gen_ssra32_i32,
3088 .fniv = gen_ssra_vec,
3089 .fno = gen_helper_gvec_ssra_s,
3090 .load_dest = true,
3091 .opt_opc = vecop_list,
3092 .vece = MO_32 },
3093 { .fni8 = gen_ssra64_i64,
3094 .fniv = gen_ssra_vec,
3095 .fno = gen_helper_gvec_ssra_b,
3096 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3097 .opt_opc = vecop_list,
3098 .load_dest = true,
3099 .vece = MO_64 },
3102 /* tszimm encoding produces immediates in the range [1..esize]. */
3103 tcg_debug_assert(shift > 0);
3104 tcg_debug_assert(shift <= (8 << vece));
3107 * Shifts larger than the element size are architecturally valid.
3108 * Signed results in all sign bits.
3110 shift = MIN(shift, (8 << vece) - 1);
3111 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3114 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3116 tcg_gen_vec_shr8i_i64(a, a, shift);
3117 tcg_gen_vec_add8_i64(d, d, a);
3120 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3122 tcg_gen_vec_shr16i_i64(a, a, shift);
3123 tcg_gen_vec_add16_i64(d, d, a);
3126 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3128 tcg_gen_shri_i32(a, a, shift);
3129 tcg_gen_add_i32(d, d, a);
3132 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3134 tcg_gen_shri_i64(a, a, shift);
3135 tcg_gen_add_i64(d, d, a);
3138 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3140 tcg_gen_shri_vec(vece, a, a, sh);
3141 tcg_gen_add_vec(vece, d, d, a);
3144 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3145 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3147 static const TCGOpcode vecop_list[] = {
3148 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3150 static const GVecGen2i ops[4] = {
3151 { .fni8 = gen_usra8_i64,
3152 .fniv = gen_usra_vec,
3153 .fno = gen_helper_gvec_usra_b,
3154 .load_dest = true,
3155 .opt_opc = vecop_list,
3156 .vece = MO_8, },
3157 { .fni8 = gen_usra16_i64,
3158 .fniv = gen_usra_vec,
3159 .fno = gen_helper_gvec_usra_h,
3160 .load_dest = true,
3161 .opt_opc = vecop_list,
3162 .vece = MO_16, },
3163 { .fni4 = gen_usra32_i32,
3164 .fniv = gen_usra_vec,
3165 .fno = gen_helper_gvec_usra_s,
3166 .load_dest = true,
3167 .opt_opc = vecop_list,
3168 .vece = MO_32, },
3169 { .fni8 = gen_usra64_i64,
3170 .fniv = gen_usra_vec,
3171 .fno = gen_helper_gvec_usra_d,
3172 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3173 .load_dest = true,
3174 .opt_opc = vecop_list,
3175 .vece = MO_64, },
3178 /* tszimm encoding produces immediates in the range [1..esize]. */
3179 tcg_debug_assert(shift > 0);
3180 tcg_debug_assert(shift <= (8 << vece));
3183 * Shifts larger than the element size are architecturally valid.
3184 * Unsigned results in all zeros as input to accumulate: nop.
3186 if (shift < (8 << vece)) {
3187 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3188 } else {
3189 /* Nop, but we do need to clear the tail. */
3190 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3195 * Shift one less than the requested amount, and the low bit is
3196 * the rounding bit. For the 8 and 16-bit operations, because we
3197 * mask the low bit, we can perform a normal integer shift instead
3198 * of a vector shift.
3200 static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3202 TCGv_i64 t = tcg_temp_new_i64();
3204 tcg_gen_shri_i64(t, a, sh - 1);
3205 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3206 tcg_gen_vec_sar8i_i64(d, a, sh);
3207 tcg_gen_vec_add8_i64(d, d, t);
3208 tcg_temp_free_i64(t);
3211 static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3213 TCGv_i64 t = tcg_temp_new_i64();
3215 tcg_gen_shri_i64(t, a, sh - 1);
3216 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3217 tcg_gen_vec_sar16i_i64(d, a, sh);
3218 tcg_gen_vec_add16_i64(d, d, t);
3219 tcg_temp_free_i64(t);
3222 static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3224 TCGv_i32 t;
3226 /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
3227 if (sh == 32) {
3228 tcg_gen_movi_i32(d, 0);
3229 return;
3231 t = tcg_temp_new_i32();
3232 tcg_gen_extract_i32(t, a, sh - 1, 1);
3233 tcg_gen_sari_i32(d, a, sh);
3234 tcg_gen_add_i32(d, d, t);
3235 tcg_temp_free_i32(t);
3238 static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3240 TCGv_i64 t = tcg_temp_new_i64();
3242 tcg_gen_extract_i64(t, a, sh - 1, 1);
3243 tcg_gen_sari_i64(d, a, sh);
3244 tcg_gen_add_i64(d, d, t);
3245 tcg_temp_free_i64(t);
3248 static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3250 TCGv_vec t = tcg_temp_new_vec_matching(d);
3251 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3253 tcg_gen_shri_vec(vece, t, a, sh - 1);
3254 tcg_gen_dupi_vec(vece, ones, 1);
3255 tcg_gen_and_vec(vece, t, t, ones);
3256 tcg_gen_sari_vec(vece, d, a, sh);
3257 tcg_gen_add_vec(vece, d, d, t);
3259 tcg_temp_free_vec(t);
3260 tcg_temp_free_vec(ones);
3263 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3264 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3266 static const TCGOpcode vecop_list[] = {
3267 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3269 static const GVecGen2i ops[4] = {
3270 { .fni8 = gen_srshr8_i64,
3271 .fniv = gen_srshr_vec,
3272 .fno = gen_helper_gvec_srshr_b,
3273 .opt_opc = vecop_list,
3274 .vece = MO_8 },
3275 { .fni8 = gen_srshr16_i64,
3276 .fniv = gen_srshr_vec,
3277 .fno = gen_helper_gvec_srshr_h,
3278 .opt_opc = vecop_list,
3279 .vece = MO_16 },
3280 { .fni4 = gen_srshr32_i32,
3281 .fniv = gen_srshr_vec,
3282 .fno = gen_helper_gvec_srshr_s,
3283 .opt_opc = vecop_list,
3284 .vece = MO_32 },
3285 { .fni8 = gen_srshr64_i64,
3286 .fniv = gen_srshr_vec,
3287 .fno = gen_helper_gvec_srshr_d,
3288 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3289 .opt_opc = vecop_list,
3290 .vece = MO_64 },
3293 /* tszimm encoding produces immediates in the range [1..esize] */
3294 tcg_debug_assert(shift > 0);
3295 tcg_debug_assert(shift <= (8 << vece));
3297 if (shift == (8 << vece)) {
3299 * Shifts larger than the element size are architecturally valid.
3300 * Signed results in all sign bits. With rounding, this produces
3301 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3302 * I.e. always zero.
3304 tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
3305 } else {
3306 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3310 static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3312 TCGv_i64 t = tcg_temp_new_i64();
3314 gen_srshr8_i64(t, a, sh);
3315 tcg_gen_vec_add8_i64(d, d, t);
3316 tcg_temp_free_i64(t);
3319 static void gen_srsra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3321 TCGv_i64 t = tcg_temp_new_i64();
3323 gen_srshr16_i64(t, a, sh);
3324 tcg_gen_vec_add16_i64(d, d, t);
3325 tcg_temp_free_i64(t);
3328 static void gen_srsra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3330 TCGv_i32 t = tcg_temp_new_i32();
3332 gen_srshr32_i32(t, a, sh);
3333 tcg_gen_add_i32(d, d, t);
3334 tcg_temp_free_i32(t);
3337 static void gen_srsra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3339 TCGv_i64 t = tcg_temp_new_i64();
3341 gen_srshr64_i64(t, a, sh);
3342 tcg_gen_add_i64(d, d, t);
3343 tcg_temp_free_i64(t);
3346 static void gen_srsra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3348 TCGv_vec t = tcg_temp_new_vec_matching(d);
3350 gen_srshr_vec(vece, t, a, sh);
3351 tcg_gen_add_vec(vece, d, d, t);
3352 tcg_temp_free_vec(t);
3355 void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3356 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3358 static const TCGOpcode vecop_list[] = {
3359 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3361 static const GVecGen2i ops[4] = {
3362 { .fni8 = gen_srsra8_i64,
3363 .fniv = gen_srsra_vec,
3364 .fno = gen_helper_gvec_srsra_b,
3365 .opt_opc = vecop_list,
3366 .load_dest = true,
3367 .vece = MO_8 },
3368 { .fni8 = gen_srsra16_i64,
3369 .fniv = gen_srsra_vec,
3370 .fno = gen_helper_gvec_srsra_h,
3371 .opt_opc = vecop_list,
3372 .load_dest = true,
3373 .vece = MO_16 },
3374 { .fni4 = gen_srsra32_i32,
3375 .fniv = gen_srsra_vec,
3376 .fno = gen_helper_gvec_srsra_s,
3377 .opt_opc = vecop_list,
3378 .load_dest = true,
3379 .vece = MO_32 },
3380 { .fni8 = gen_srsra64_i64,
3381 .fniv = gen_srsra_vec,
3382 .fno = gen_helper_gvec_srsra_d,
3383 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3384 .opt_opc = vecop_list,
3385 .load_dest = true,
3386 .vece = MO_64 },
3389 /* tszimm encoding produces immediates in the range [1..esize] */
3390 tcg_debug_assert(shift > 0);
3391 tcg_debug_assert(shift <= (8 << vece));
3394 * Shifts larger than the element size are architecturally valid.
3395 * Signed results in all sign bits. With rounding, this produces
3396 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3397 * I.e. always zero. With accumulation, this leaves D unchanged.
3399 if (shift == (8 << vece)) {
3400 /* Nop, but we do need to clear the tail. */
3401 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3402 } else {
3403 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3407 static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3409 TCGv_i64 t = tcg_temp_new_i64();
3411 tcg_gen_shri_i64(t, a, sh - 1);
3412 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3413 tcg_gen_vec_shr8i_i64(d, a, sh);
3414 tcg_gen_vec_add8_i64(d, d, t);
3415 tcg_temp_free_i64(t);
3418 static void gen_urshr16_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_16, 1));
3424 tcg_gen_vec_shr16i_i64(d, a, sh);
3425 tcg_gen_vec_add16_i64(d, d, t);
3426 tcg_temp_free_i64(t);
3429 static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3431 TCGv_i32 t;
3433 /* Handle shift by the input size for the benefit of trans_URSHR_ri */
3434 if (sh == 32) {
3435 tcg_gen_extract_i32(d, a, sh - 1, 1);
3436 return;
3438 t = tcg_temp_new_i32();
3439 tcg_gen_extract_i32(t, a, sh - 1, 1);
3440 tcg_gen_shri_i32(d, a, sh);
3441 tcg_gen_add_i32(d, d, t);
3442 tcg_temp_free_i32(t);
3445 static void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3447 TCGv_i64 t = tcg_temp_new_i64();
3449 tcg_gen_extract_i64(t, a, sh - 1, 1);
3450 tcg_gen_shri_i64(d, a, sh);
3451 tcg_gen_add_i64(d, d, t);
3452 tcg_temp_free_i64(t);
3455 static void gen_urshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t shift)
3457 TCGv_vec t = tcg_temp_new_vec_matching(d);
3458 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3460 tcg_gen_shri_vec(vece, t, a, shift - 1);
3461 tcg_gen_dupi_vec(vece, ones, 1);
3462 tcg_gen_and_vec(vece, t, t, ones);
3463 tcg_gen_shri_vec(vece, d, a, shift);
3464 tcg_gen_add_vec(vece, d, d, t);
3466 tcg_temp_free_vec(t);
3467 tcg_temp_free_vec(ones);
3470 void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3471 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3473 static const TCGOpcode vecop_list[] = {
3474 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3476 static const GVecGen2i ops[4] = {
3477 { .fni8 = gen_urshr8_i64,
3478 .fniv = gen_urshr_vec,
3479 .fno = gen_helper_gvec_urshr_b,
3480 .opt_opc = vecop_list,
3481 .vece = MO_8 },
3482 { .fni8 = gen_urshr16_i64,
3483 .fniv = gen_urshr_vec,
3484 .fno = gen_helper_gvec_urshr_h,
3485 .opt_opc = vecop_list,
3486 .vece = MO_16 },
3487 { .fni4 = gen_urshr32_i32,
3488 .fniv = gen_urshr_vec,
3489 .fno = gen_helper_gvec_urshr_s,
3490 .opt_opc = vecop_list,
3491 .vece = MO_32 },
3492 { .fni8 = gen_urshr64_i64,
3493 .fniv = gen_urshr_vec,
3494 .fno = gen_helper_gvec_urshr_d,
3495 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3496 .opt_opc = vecop_list,
3497 .vece = MO_64 },
3500 /* tszimm encoding produces immediates in the range [1..esize] */
3501 tcg_debug_assert(shift > 0);
3502 tcg_debug_assert(shift <= (8 << vece));
3504 if (shift == (8 << vece)) {
3506 * Shifts larger than the element size are architecturally valid.
3507 * Unsigned results in zero. With rounding, this produces a
3508 * copy of the most significant bit.
3510 tcg_gen_gvec_shri(vece, rd_ofs, rm_ofs, shift - 1, opr_sz, max_sz);
3511 } else {
3512 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3516 static void gen_ursra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3518 TCGv_i64 t = tcg_temp_new_i64();
3520 if (sh == 8) {
3521 tcg_gen_vec_shr8i_i64(t, a, 7);
3522 } else {
3523 gen_urshr8_i64(t, a, sh);
3525 tcg_gen_vec_add8_i64(d, d, t);
3526 tcg_temp_free_i64(t);
3529 static void gen_ursra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3531 TCGv_i64 t = tcg_temp_new_i64();
3533 if (sh == 16) {
3534 tcg_gen_vec_shr16i_i64(t, a, 15);
3535 } else {
3536 gen_urshr16_i64(t, a, sh);
3538 tcg_gen_vec_add16_i64(d, d, t);
3539 tcg_temp_free_i64(t);
3542 static void gen_ursra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3544 TCGv_i32 t = tcg_temp_new_i32();
3546 if (sh == 32) {
3547 tcg_gen_shri_i32(t, a, 31);
3548 } else {
3549 gen_urshr32_i32(t, a, sh);
3551 tcg_gen_add_i32(d, d, t);
3552 tcg_temp_free_i32(t);
3555 static void gen_ursra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3557 TCGv_i64 t = tcg_temp_new_i64();
3559 if (sh == 64) {
3560 tcg_gen_shri_i64(t, a, 63);
3561 } else {
3562 gen_urshr64_i64(t, a, sh);
3564 tcg_gen_add_i64(d, d, t);
3565 tcg_temp_free_i64(t);
3568 static void gen_ursra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3570 TCGv_vec t = tcg_temp_new_vec_matching(d);
3572 if (sh == (8 << vece)) {
3573 tcg_gen_shri_vec(vece, t, a, sh - 1);
3574 } else {
3575 gen_urshr_vec(vece, t, a, sh);
3577 tcg_gen_add_vec(vece, d, d, t);
3578 tcg_temp_free_vec(t);
3581 void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3582 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3584 static const TCGOpcode vecop_list[] = {
3585 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3587 static const GVecGen2i ops[4] = {
3588 { .fni8 = gen_ursra8_i64,
3589 .fniv = gen_ursra_vec,
3590 .fno = gen_helper_gvec_ursra_b,
3591 .opt_opc = vecop_list,
3592 .load_dest = true,
3593 .vece = MO_8 },
3594 { .fni8 = gen_ursra16_i64,
3595 .fniv = gen_ursra_vec,
3596 .fno = gen_helper_gvec_ursra_h,
3597 .opt_opc = vecop_list,
3598 .load_dest = true,
3599 .vece = MO_16 },
3600 { .fni4 = gen_ursra32_i32,
3601 .fniv = gen_ursra_vec,
3602 .fno = gen_helper_gvec_ursra_s,
3603 .opt_opc = vecop_list,
3604 .load_dest = true,
3605 .vece = MO_32 },
3606 { .fni8 = gen_ursra64_i64,
3607 .fniv = gen_ursra_vec,
3608 .fno = gen_helper_gvec_ursra_d,
3609 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3610 .opt_opc = vecop_list,
3611 .load_dest = true,
3612 .vece = MO_64 },
3615 /* tszimm encoding produces immediates in the range [1..esize] */
3616 tcg_debug_assert(shift > 0);
3617 tcg_debug_assert(shift <= (8 << vece));
3619 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3622 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3624 uint64_t mask = dup_const(MO_8, 0xff >> shift);
3625 TCGv_i64 t = tcg_temp_new_i64();
3627 tcg_gen_shri_i64(t, a, shift);
3628 tcg_gen_andi_i64(t, t, mask);
3629 tcg_gen_andi_i64(d, d, ~mask);
3630 tcg_gen_or_i64(d, d, t);
3631 tcg_temp_free_i64(t);
3634 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3636 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
3637 TCGv_i64 t = tcg_temp_new_i64();
3639 tcg_gen_shri_i64(t, a, shift);
3640 tcg_gen_andi_i64(t, t, mask);
3641 tcg_gen_andi_i64(d, d, ~mask);
3642 tcg_gen_or_i64(d, d, t);
3643 tcg_temp_free_i64(t);
3646 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3648 tcg_gen_shri_i32(a, a, shift);
3649 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
3652 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3654 tcg_gen_shri_i64(a, a, shift);
3655 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
3658 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3660 TCGv_vec t = tcg_temp_new_vec_matching(d);
3661 TCGv_vec m = tcg_temp_new_vec_matching(d);
3663 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
3664 tcg_gen_shri_vec(vece, t, a, sh);
3665 tcg_gen_and_vec(vece, d, d, m);
3666 tcg_gen_or_vec(vece, d, d, t);
3668 tcg_temp_free_vec(t);
3669 tcg_temp_free_vec(m);
3672 void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3673 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3675 static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
3676 const GVecGen2i ops[4] = {
3677 { .fni8 = gen_shr8_ins_i64,
3678 .fniv = gen_shr_ins_vec,
3679 .fno = gen_helper_gvec_sri_b,
3680 .load_dest = true,
3681 .opt_opc = vecop_list,
3682 .vece = MO_8 },
3683 { .fni8 = gen_shr16_ins_i64,
3684 .fniv = gen_shr_ins_vec,
3685 .fno = gen_helper_gvec_sri_h,
3686 .load_dest = true,
3687 .opt_opc = vecop_list,
3688 .vece = MO_16 },
3689 { .fni4 = gen_shr32_ins_i32,
3690 .fniv = gen_shr_ins_vec,
3691 .fno = gen_helper_gvec_sri_s,
3692 .load_dest = true,
3693 .opt_opc = vecop_list,
3694 .vece = MO_32 },
3695 { .fni8 = gen_shr64_ins_i64,
3696 .fniv = gen_shr_ins_vec,
3697 .fno = gen_helper_gvec_sri_d,
3698 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3699 .load_dest = true,
3700 .opt_opc = vecop_list,
3701 .vece = MO_64 },
3704 /* tszimm encoding produces immediates in the range [1..esize]. */
3705 tcg_debug_assert(shift > 0);
3706 tcg_debug_assert(shift <= (8 << vece));
3708 /* Shift of esize leaves destination unchanged. */
3709 if (shift < (8 << vece)) {
3710 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3711 } else {
3712 /* Nop, but we do need to clear the tail. */
3713 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3717 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3719 uint64_t mask = dup_const(MO_8, 0xff << shift);
3720 TCGv_i64 t = tcg_temp_new_i64();
3722 tcg_gen_shli_i64(t, a, shift);
3723 tcg_gen_andi_i64(t, t, mask);
3724 tcg_gen_andi_i64(d, d, ~mask);
3725 tcg_gen_or_i64(d, d, t);
3726 tcg_temp_free_i64(t);
3729 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3731 uint64_t mask = dup_const(MO_16, 0xffff << shift);
3732 TCGv_i64 t = tcg_temp_new_i64();
3734 tcg_gen_shli_i64(t, a, shift);
3735 tcg_gen_andi_i64(t, t, mask);
3736 tcg_gen_andi_i64(d, d, ~mask);
3737 tcg_gen_or_i64(d, d, t);
3738 tcg_temp_free_i64(t);
3741 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3743 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
3746 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3748 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
3751 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3753 TCGv_vec t = tcg_temp_new_vec_matching(d);
3754 TCGv_vec m = tcg_temp_new_vec_matching(d);
3756 tcg_gen_shli_vec(vece, t, a, sh);
3757 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
3758 tcg_gen_and_vec(vece, d, d, m);
3759 tcg_gen_or_vec(vece, d, d, t);
3761 tcg_temp_free_vec(t);
3762 tcg_temp_free_vec(m);
3765 void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3766 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3768 static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
3769 const GVecGen2i ops[4] = {
3770 { .fni8 = gen_shl8_ins_i64,
3771 .fniv = gen_shl_ins_vec,
3772 .fno = gen_helper_gvec_sli_b,
3773 .load_dest = true,
3774 .opt_opc = vecop_list,
3775 .vece = MO_8 },
3776 { .fni8 = gen_shl16_ins_i64,
3777 .fniv = gen_shl_ins_vec,
3778 .fno = gen_helper_gvec_sli_h,
3779 .load_dest = true,
3780 .opt_opc = vecop_list,
3781 .vece = MO_16 },
3782 { .fni4 = gen_shl32_ins_i32,
3783 .fniv = gen_shl_ins_vec,
3784 .fno = gen_helper_gvec_sli_s,
3785 .load_dest = true,
3786 .opt_opc = vecop_list,
3787 .vece = MO_32 },
3788 { .fni8 = gen_shl64_ins_i64,
3789 .fniv = gen_shl_ins_vec,
3790 .fno = gen_helper_gvec_sli_d,
3791 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3792 .load_dest = true,
3793 .opt_opc = vecop_list,
3794 .vece = MO_64 },
3797 /* tszimm encoding produces immediates in the range [0..esize-1]. */
3798 tcg_debug_assert(shift >= 0);
3799 tcg_debug_assert(shift < (8 << vece));
3801 if (shift == 0) {
3802 tcg_gen_gvec_mov(vece, rd_ofs, rm_ofs, opr_sz, max_sz);
3803 } else {
3804 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3808 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3810 gen_helper_neon_mul_u8(a, a, b);
3811 gen_helper_neon_add_u8(d, d, a);
3814 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3816 gen_helper_neon_mul_u8(a, a, b);
3817 gen_helper_neon_sub_u8(d, d, a);
3820 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3822 gen_helper_neon_mul_u16(a, a, b);
3823 gen_helper_neon_add_u16(d, d, a);
3826 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3828 gen_helper_neon_mul_u16(a, a, b);
3829 gen_helper_neon_sub_u16(d, d, a);
3832 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3834 tcg_gen_mul_i32(a, a, b);
3835 tcg_gen_add_i32(d, d, a);
3838 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3840 tcg_gen_mul_i32(a, a, b);
3841 tcg_gen_sub_i32(d, d, a);
3844 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3846 tcg_gen_mul_i64(a, a, b);
3847 tcg_gen_add_i64(d, d, a);
3850 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3852 tcg_gen_mul_i64(a, a, b);
3853 tcg_gen_sub_i64(d, d, a);
3856 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3858 tcg_gen_mul_vec(vece, a, a, b);
3859 tcg_gen_add_vec(vece, d, d, a);
3862 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3864 tcg_gen_mul_vec(vece, a, a, b);
3865 tcg_gen_sub_vec(vece, d, d, a);
3868 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
3869 * these tables are shared with AArch64 which does support them.
3871 void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3872 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3874 static const TCGOpcode vecop_list[] = {
3875 INDEX_op_mul_vec, INDEX_op_add_vec, 0
3877 static const GVecGen3 ops[4] = {
3878 { .fni4 = gen_mla8_i32,
3879 .fniv = gen_mla_vec,
3880 .load_dest = true,
3881 .opt_opc = vecop_list,
3882 .vece = MO_8 },
3883 { .fni4 = gen_mla16_i32,
3884 .fniv = gen_mla_vec,
3885 .load_dest = true,
3886 .opt_opc = vecop_list,
3887 .vece = MO_16 },
3888 { .fni4 = gen_mla32_i32,
3889 .fniv = gen_mla_vec,
3890 .load_dest = true,
3891 .opt_opc = vecop_list,
3892 .vece = MO_32 },
3893 { .fni8 = gen_mla64_i64,
3894 .fniv = gen_mla_vec,
3895 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3896 .load_dest = true,
3897 .opt_opc = vecop_list,
3898 .vece = MO_64 },
3900 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3903 void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3904 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3906 static const TCGOpcode vecop_list[] = {
3907 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
3909 static const GVecGen3 ops[4] = {
3910 { .fni4 = gen_mls8_i32,
3911 .fniv = gen_mls_vec,
3912 .load_dest = true,
3913 .opt_opc = vecop_list,
3914 .vece = MO_8 },
3915 { .fni4 = gen_mls16_i32,
3916 .fniv = gen_mls_vec,
3917 .load_dest = true,
3918 .opt_opc = vecop_list,
3919 .vece = MO_16 },
3920 { .fni4 = gen_mls32_i32,
3921 .fniv = gen_mls_vec,
3922 .load_dest = true,
3923 .opt_opc = vecop_list,
3924 .vece = MO_32 },
3925 { .fni8 = gen_mls64_i64,
3926 .fniv = gen_mls_vec,
3927 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3928 .load_dest = true,
3929 .opt_opc = vecop_list,
3930 .vece = MO_64 },
3932 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3935 /* CMTST : test is "if (X & Y != 0)". */
3936 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3938 tcg_gen_and_i32(d, a, b);
3939 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
3940 tcg_gen_neg_i32(d, d);
3943 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3945 tcg_gen_and_i64(d, a, b);
3946 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
3947 tcg_gen_neg_i64(d, d);
3950 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3952 tcg_gen_and_vec(vece, d, a, b);
3953 tcg_gen_dupi_vec(vece, a, 0);
3954 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
3957 void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3958 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3960 static const TCGOpcode vecop_list[] = { INDEX_op_cmp_vec, 0 };
3961 static const GVecGen3 ops[4] = {
3962 { .fni4 = gen_helper_neon_tst_u8,
3963 .fniv = gen_cmtst_vec,
3964 .opt_opc = vecop_list,
3965 .vece = MO_8 },
3966 { .fni4 = gen_helper_neon_tst_u16,
3967 .fniv = gen_cmtst_vec,
3968 .opt_opc = vecop_list,
3969 .vece = MO_16 },
3970 { .fni4 = gen_cmtst_i32,
3971 .fniv = gen_cmtst_vec,
3972 .opt_opc = vecop_list,
3973 .vece = MO_32 },
3974 { .fni8 = gen_cmtst_i64,
3975 .fniv = gen_cmtst_vec,
3976 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3977 .opt_opc = vecop_list,
3978 .vece = MO_64 },
3980 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3983 void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
3985 TCGv_i32 lval = tcg_temp_new_i32();
3986 TCGv_i32 rval = tcg_temp_new_i32();
3987 TCGv_i32 lsh = tcg_temp_new_i32();
3988 TCGv_i32 rsh = tcg_temp_new_i32();
3989 TCGv_i32 zero = tcg_constant_i32(0);
3990 TCGv_i32 max = tcg_constant_i32(32);
3993 * Rely on the TCG guarantee that out of range shifts produce
3994 * unspecified results, not undefined behaviour (i.e. no trap).
3995 * Discard out-of-range results after the fact.
3997 tcg_gen_ext8s_i32(lsh, shift);
3998 tcg_gen_neg_i32(rsh, lsh);
3999 tcg_gen_shl_i32(lval, src, lsh);
4000 tcg_gen_shr_i32(rval, src, rsh);
4001 tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
4002 tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
4004 tcg_temp_free_i32(lval);
4005 tcg_temp_free_i32(rval);
4006 tcg_temp_free_i32(lsh);
4007 tcg_temp_free_i32(rsh);
4010 void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4012 TCGv_i64 lval = tcg_temp_new_i64();
4013 TCGv_i64 rval = tcg_temp_new_i64();
4014 TCGv_i64 lsh = tcg_temp_new_i64();
4015 TCGv_i64 rsh = tcg_temp_new_i64();
4016 TCGv_i64 zero = tcg_constant_i64(0);
4017 TCGv_i64 max = tcg_constant_i64(64);
4020 * Rely on the TCG guarantee that out of range shifts produce
4021 * unspecified results, not undefined behaviour (i.e. no trap).
4022 * Discard out-of-range results after the fact.
4024 tcg_gen_ext8s_i64(lsh, shift);
4025 tcg_gen_neg_i64(rsh, lsh);
4026 tcg_gen_shl_i64(lval, src, lsh);
4027 tcg_gen_shr_i64(rval, src, rsh);
4028 tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
4029 tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
4031 tcg_temp_free_i64(lval);
4032 tcg_temp_free_i64(rval);
4033 tcg_temp_free_i64(lsh);
4034 tcg_temp_free_i64(rsh);
4037 static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
4038 TCGv_vec src, TCGv_vec shift)
4040 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4041 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4042 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4043 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4044 TCGv_vec msk, max;
4046 tcg_gen_neg_vec(vece, rsh, shift);
4047 if (vece == MO_8) {
4048 tcg_gen_mov_vec(lsh, shift);
4049 } else {
4050 msk = tcg_temp_new_vec_matching(dst);
4051 tcg_gen_dupi_vec(vece, msk, 0xff);
4052 tcg_gen_and_vec(vece, lsh, shift, msk);
4053 tcg_gen_and_vec(vece, rsh, rsh, msk);
4054 tcg_temp_free_vec(msk);
4058 * Rely on the TCG guarantee that out of range shifts produce
4059 * unspecified results, not undefined behaviour (i.e. no trap).
4060 * Discard out-of-range results after the fact.
4062 tcg_gen_shlv_vec(vece, lval, src, lsh);
4063 tcg_gen_shrv_vec(vece, rval, src, rsh);
4065 max = tcg_temp_new_vec_matching(dst);
4066 tcg_gen_dupi_vec(vece, max, 8 << vece);
4069 * The choice of LT (signed) and GEU (unsigned) are biased toward
4070 * the instructions of the x86_64 host. For MO_8, the whole byte
4071 * is significant so we must use an unsigned compare; otherwise we
4072 * have already masked to a byte and so a signed compare works.
4073 * Other tcg hosts have a full set of comparisons and do not care.
4075 if (vece == MO_8) {
4076 tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
4077 tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
4078 tcg_gen_andc_vec(vece, lval, lval, lsh);
4079 tcg_gen_andc_vec(vece, rval, rval, rsh);
4080 } else {
4081 tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
4082 tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
4083 tcg_gen_and_vec(vece, lval, lval, lsh);
4084 tcg_gen_and_vec(vece, rval, rval, rsh);
4086 tcg_gen_or_vec(vece, dst, lval, rval);
4088 tcg_temp_free_vec(max);
4089 tcg_temp_free_vec(lval);
4090 tcg_temp_free_vec(rval);
4091 tcg_temp_free_vec(lsh);
4092 tcg_temp_free_vec(rsh);
4095 void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4096 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4098 static const TCGOpcode vecop_list[] = {
4099 INDEX_op_neg_vec, INDEX_op_shlv_vec,
4100 INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
4102 static const GVecGen3 ops[4] = {
4103 { .fniv = gen_ushl_vec,
4104 .fno = gen_helper_gvec_ushl_b,
4105 .opt_opc = vecop_list,
4106 .vece = MO_8 },
4107 { .fniv = gen_ushl_vec,
4108 .fno = gen_helper_gvec_ushl_h,
4109 .opt_opc = vecop_list,
4110 .vece = MO_16 },
4111 { .fni4 = gen_ushl_i32,
4112 .fniv = gen_ushl_vec,
4113 .opt_opc = vecop_list,
4114 .vece = MO_32 },
4115 { .fni8 = gen_ushl_i64,
4116 .fniv = gen_ushl_vec,
4117 .opt_opc = vecop_list,
4118 .vece = MO_64 },
4120 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4123 void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4125 TCGv_i32 lval = tcg_temp_new_i32();
4126 TCGv_i32 rval = tcg_temp_new_i32();
4127 TCGv_i32 lsh = tcg_temp_new_i32();
4128 TCGv_i32 rsh = tcg_temp_new_i32();
4129 TCGv_i32 zero = tcg_constant_i32(0);
4130 TCGv_i32 max = tcg_constant_i32(31);
4133 * Rely on the TCG guarantee that out of range shifts produce
4134 * unspecified results, not undefined behaviour (i.e. no trap).
4135 * Discard out-of-range results after the fact.
4137 tcg_gen_ext8s_i32(lsh, shift);
4138 tcg_gen_neg_i32(rsh, lsh);
4139 tcg_gen_shl_i32(lval, src, lsh);
4140 tcg_gen_umin_i32(rsh, rsh, max);
4141 tcg_gen_sar_i32(rval, src, rsh);
4142 tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
4143 tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
4145 tcg_temp_free_i32(lval);
4146 tcg_temp_free_i32(rval);
4147 tcg_temp_free_i32(lsh);
4148 tcg_temp_free_i32(rsh);
4151 void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4153 TCGv_i64 lval = tcg_temp_new_i64();
4154 TCGv_i64 rval = tcg_temp_new_i64();
4155 TCGv_i64 lsh = tcg_temp_new_i64();
4156 TCGv_i64 rsh = tcg_temp_new_i64();
4157 TCGv_i64 zero = tcg_constant_i64(0);
4158 TCGv_i64 max = tcg_constant_i64(63);
4161 * Rely on the TCG guarantee that out of range shifts produce
4162 * unspecified results, not undefined behaviour (i.e. no trap).
4163 * Discard out-of-range results after the fact.
4165 tcg_gen_ext8s_i64(lsh, shift);
4166 tcg_gen_neg_i64(rsh, lsh);
4167 tcg_gen_shl_i64(lval, src, lsh);
4168 tcg_gen_umin_i64(rsh, rsh, max);
4169 tcg_gen_sar_i64(rval, src, rsh);
4170 tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
4171 tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
4173 tcg_temp_free_i64(lval);
4174 tcg_temp_free_i64(rval);
4175 tcg_temp_free_i64(lsh);
4176 tcg_temp_free_i64(rsh);
4179 static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
4180 TCGv_vec src, TCGv_vec shift)
4182 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4183 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4184 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4185 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4186 TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
4189 * Rely on the TCG guarantee that out of range shifts produce
4190 * unspecified results, not undefined behaviour (i.e. no trap).
4191 * Discard out-of-range results after the fact.
4193 tcg_gen_neg_vec(vece, rsh, shift);
4194 if (vece == MO_8) {
4195 tcg_gen_mov_vec(lsh, shift);
4196 } else {
4197 tcg_gen_dupi_vec(vece, tmp, 0xff);
4198 tcg_gen_and_vec(vece, lsh, shift, tmp);
4199 tcg_gen_and_vec(vece, rsh, rsh, tmp);
4202 /* Bound rsh so out of bound right shift gets -1. */
4203 tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
4204 tcg_gen_umin_vec(vece, rsh, rsh, tmp);
4205 tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
4207 tcg_gen_shlv_vec(vece, lval, src, lsh);
4208 tcg_gen_sarv_vec(vece, rval, src, rsh);
4210 /* Select in-bound left shift. */
4211 tcg_gen_andc_vec(vece, lval, lval, tmp);
4213 /* Select between left and right shift. */
4214 if (vece == MO_8) {
4215 tcg_gen_dupi_vec(vece, tmp, 0);
4216 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
4217 } else {
4218 tcg_gen_dupi_vec(vece, tmp, 0x80);
4219 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
4222 tcg_temp_free_vec(lval);
4223 tcg_temp_free_vec(rval);
4224 tcg_temp_free_vec(lsh);
4225 tcg_temp_free_vec(rsh);
4226 tcg_temp_free_vec(tmp);
4229 void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4230 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4232 static const TCGOpcode vecop_list[] = {
4233 INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
4234 INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
4236 static const GVecGen3 ops[4] = {
4237 { .fniv = gen_sshl_vec,
4238 .fno = gen_helper_gvec_sshl_b,
4239 .opt_opc = vecop_list,
4240 .vece = MO_8 },
4241 { .fniv = gen_sshl_vec,
4242 .fno = gen_helper_gvec_sshl_h,
4243 .opt_opc = vecop_list,
4244 .vece = MO_16 },
4245 { .fni4 = gen_sshl_i32,
4246 .fniv = gen_sshl_vec,
4247 .opt_opc = vecop_list,
4248 .vece = MO_32 },
4249 { .fni8 = gen_sshl_i64,
4250 .fniv = gen_sshl_vec,
4251 .opt_opc = vecop_list,
4252 .vece = MO_64 },
4254 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4257 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4258 TCGv_vec a, TCGv_vec b)
4260 TCGv_vec x = tcg_temp_new_vec_matching(t);
4261 tcg_gen_add_vec(vece, x, a, b);
4262 tcg_gen_usadd_vec(vece, t, a, b);
4263 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4264 tcg_gen_or_vec(vece, sat, sat, x);
4265 tcg_temp_free_vec(x);
4268 void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4269 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4271 static const TCGOpcode vecop_list[] = {
4272 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4274 static const GVecGen4 ops[4] = {
4275 { .fniv = gen_uqadd_vec,
4276 .fno = gen_helper_gvec_uqadd_b,
4277 .write_aofs = true,
4278 .opt_opc = vecop_list,
4279 .vece = MO_8 },
4280 { .fniv = gen_uqadd_vec,
4281 .fno = gen_helper_gvec_uqadd_h,
4282 .write_aofs = true,
4283 .opt_opc = vecop_list,
4284 .vece = MO_16 },
4285 { .fniv = gen_uqadd_vec,
4286 .fno = gen_helper_gvec_uqadd_s,
4287 .write_aofs = true,
4288 .opt_opc = vecop_list,
4289 .vece = MO_32 },
4290 { .fniv = gen_uqadd_vec,
4291 .fno = gen_helper_gvec_uqadd_d,
4292 .write_aofs = true,
4293 .opt_opc = vecop_list,
4294 .vece = MO_64 },
4296 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4297 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4300 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4301 TCGv_vec a, TCGv_vec b)
4303 TCGv_vec x = tcg_temp_new_vec_matching(t);
4304 tcg_gen_add_vec(vece, x, a, b);
4305 tcg_gen_ssadd_vec(vece, t, a, b);
4306 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4307 tcg_gen_or_vec(vece, sat, sat, x);
4308 tcg_temp_free_vec(x);
4311 void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4312 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4314 static const TCGOpcode vecop_list[] = {
4315 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4317 static const GVecGen4 ops[4] = {
4318 { .fniv = gen_sqadd_vec,
4319 .fno = gen_helper_gvec_sqadd_b,
4320 .opt_opc = vecop_list,
4321 .write_aofs = true,
4322 .vece = MO_8 },
4323 { .fniv = gen_sqadd_vec,
4324 .fno = gen_helper_gvec_sqadd_h,
4325 .opt_opc = vecop_list,
4326 .write_aofs = true,
4327 .vece = MO_16 },
4328 { .fniv = gen_sqadd_vec,
4329 .fno = gen_helper_gvec_sqadd_s,
4330 .opt_opc = vecop_list,
4331 .write_aofs = true,
4332 .vece = MO_32 },
4333 { .fniv = gen_sqadd_vec,
4334 .fno = gen_helper_gvec_sqadd_d,
4335 .opt_opc = vecop_list,
4336 .write_aofs = true,
4337 .vece = MO_64 },
4339 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4340 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4343 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4344 TCGv_vec a, TCGv_vec b)
4346 TCGv_vec x = tcg_temp_new_vec_matching(t);
4347 tcg_gen_sub_vec(vece, x, a, b);
4348 tcg_gen_ussub_vec(vece, t, a, b);
4349 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4350 tcg_gen_or_vec(vece, sat, sat, x);
4351 tcg_temp_free_vec(x);
4354 void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4355 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4357 static const TCGOpcode vecop_list[] = {
4358 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4360 static const GVecGen4 ops[4] = {
4361 { .fniv = gen_uqsub_vec,
4362 .fno = gen_helper_gvec_uqsub_b,
4363 .opt_opc = vecop_list,
4364 .write_aofs = true,
4365 .vece = MO_8 },
4366 { .fniv = gen_uqsub_vec,
4367 .fno = gen_helper_gvec_uqsub_h,
4368 .opt_opc = vecop_list,
4369 .write_aofs = true,
4370 .vece = MO_16 },
4371 { .fniv = gen_uqsub_vec,
4372 .fno = gen_helper_gvec_uqsub_s,
4373 .opt_opc = vecop_list,
4374 .write_aofs = true,
4375 .vece = MO_32 },
4376 { .fniv = gen_uqsub_vec,
4377 .fno = gen_helper_gvec_uqsub_d,
4378 .opt_opc = vecop_list,
4379 .write_aofs = true,
4380 .vece = MO_64 },
4382 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4383 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4386 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4387 TCGv_vec a, TCGv_vec b)
4389 TCGv_vec x = tcg_temp_new_vec_matching(t);
4390 tcg_gen_sub_vec(vece, x, a, b);
4391 tcg_gen_sssub_vec(vece, t, a, b);
4392 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4393 tcg_gen_or_vec(vece, sat, sat, x);
4394 tcg_temp_free_vec(x);
4397 void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4398 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4400 static const TCGOpcode vecop_list[] = {
4401 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4403 static const GVecGen4 ops[4] = {
4404 { .fniv = gen_sqsub_vec,
4405 .fno = gen_helper_gvec_sqsub_b,
4406 .opt_opc = vecop_list,
4407 .write_aofs = true,
4408 .vece = MO_8 },
4409 { .fniv = gen_sqsub_vec,
4410 .fno = gen_helper_gvec_sqsub_h,
4411 .opt_opc = vecop_list,
4412 .write_aofs = true,
4413 .vece = MO_16 },
4414 { .fniv = gen_sqsub_vec,
4415 .fno = gen_helper_gvec_sqsub_s,
4416 .opt_opc = vecop_list,
4417 .write_aofs = true,
4418 .vece = MO_32 },
4419 { .fniv = gen_sqsub_vec,
4420 .fno = gen_helper_gvec_sqsub_d,
4421 .opt_opc = vecop_list,
4422 .write_aofs = true,
4423 .vece = MO_64 },
4425 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4426 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4429 static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4431 TCGv_i32 t = tcg_temp_new_i32();
4433 tcg_gen_sub_i32(t, a, b);
4434 tcg_gen_sub_i32(d, b, a);
4435 tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
4436 tcg_temp_free_i32(t);
4439 static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4441 TCGv_i64 t = tcg_temp_new_i64();
4443 tcg_gen_sub_i64(t, a, b);
4444 tcg_gen_sub_i64(d, b, a);
4445 tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
4446 tcg_temp_free_i64(t);
4449 static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4451 TCGv_vec t = tcg_temp_new_vec_matching(d);
4453 tcg_gen_smin_vec(vece, t, a, b);
4454 tcg_gen_smax_vec(vece, d, a, b);
4455 tcg_gen_sub_vec(vece, d, d, t);
4456 tcg_temp_free_vec(t);
4459 void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4460 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4462 static const TCGOpcode vecop_list[] = {
4463 INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4465 static const GVecGen3 ops[4] = {
4466 { .fniv = gen_sabd_vec,
4467 .fno = gen_helper_gvec_sabd_b,
4468 .opt_opc = vecop_list,
4469 .vece = MO_8 },
4470 { .fniv = gen_sabd_vec,
4471 .fno = gen_helper_gvec_sabd_h,
4472 .opt_opc = vecop_list,
4473 .vece = MO_16 },
4474 { .fni4 = gen_sabd_i32,
4475 .fniv = gen_sabd_vec,
4476 .fno = gen_helper_gvec_sabd_s,
4477 .opt_opc = vecop_list,
4478 .vece = MO_32 },
4479 { .fni8 = gen_sabd_i64,
4480 .fniv = gen_sabd_vec,
4481 .fno = gen_helper_gvec_sabd_d,
4482 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4483 .opt_opc = vecop_list,
4484 .vece = MO_64 },
4486 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4489 static void gen_uabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4491 TCGv_i32 t = tcg_temp_new_i32();
4493 tcg_gen_sub_i32(t, a, b);
4494 tcg_gen_sub_i32(d, b, a);
4495 tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, d, t);
4496 tcg_temp_free_i32(t);
4499 static void gen_uabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4501 TCGv_i64 t = tcg_temp_new_i64();
4503 tcg_gen_sub_i64(t, a, b);
4504 tcg_gen_sub_i64(d, b, a);
4505 tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, d, t);
4506 tcg_temp_free_i64(t);
4509 static void gen_uabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4511 TCGv_vec t = tcg_temp_new_vec_matching(d);
4513 tcg_gen_umin_vec(vece, t, a, b);
4514 tcg_gen_umax_vec(vece, d, a, b);
4515 tcg_gen_sub_vec(vece, d, d, t);
4516 tcg_temp_free_vec(t);
4519 void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4520 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4522 static const TCGOpcode vecop_list[] = {
4523 INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
4525 static const GVecGen3 ops[4] = {
4526 { .fniv = gen_uabd_vec,
4527 .fno = gen_helper_gvec_uabd_b,
4528 .opt_opc = vecop_list,
4529 .vece = MO_8 },
4530 { .fniv = gen_uabd_vec,
4531 .fno = gen_helper_gvec_uabd_h,
4532 .opt_opc = vecop_list,
4533 .vece = MO_16 },
4534 { .fni4 = gen_uabd_i32,
4535 .fniv = gen_uabd_vec,
4536 .fno = gen_helper_gvec_uabd_s,
4537 .opt_opc = vecop_list,
4538 .vece = MO_32 },
4539 { .fni8 = gen_uabd_i64,
4540 .fniv = gen_uabd_vec,
4541 .fno = gen_helper_gvec_uabd_d,
4542 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4543 .opt_opc = vecop_list,
4544 .vece = MO_64 },
4546 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4549 static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4551 TCGv_i32 t = tcg_temp_new_i32();
4552 gen_sabd_i32(t, a, b);
4553 tcg_gen_add_i32(d, d, t);
4554 tcg_temp_free_i32(t);
4557 static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4559 TCGv_i64 t = tcg_temp_new_i64();
4560 gen_sabd_i64(t, a, b);
4561 tcg_gen_add_i64(d, d, t);
4562 tcg_temp_free_i64(t);
4565 static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4567 TCGv_vec t = tcg_temp_new_vec_matching(d);
4568 gen_sabd_vec(vece, t, a, b);
4569 tcg_gen_add_vec(vece, d, d, t);
4570 tcg_temp_free_vec(t);
4573 void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4574 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4576 static const TCGOpcode vecop_list[] = {
4577 INDEX_op_sub_vec, INDEX_op_add_vec,
4578 INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4580 static const GVecGen3 ops[4] = {
4581 { .fniv = gen_saba_vec,
4582 .fno = gen_helper_gvec_saba_b,
4583 .opt_opc = vecop_list,
4584 .load_dest = true,
4585 .vece = MO_8 },
4586 { .fniv = gen_saba_vec,
4587 .fno = gen_helper_gvec_saba_h,
4588 .opt_opc = vecop_list,
4589 .load_dest = true,
4590 .vece = MO_16 },
4591 { .fni4 = gen_saba_i32,
4592 .fniv = gen_saba_vec,
4593 .fno = gen_helper_gvec_saba_s,
4594 .opt_opc = vecop_list,
4595 .load_dest = true,
4596 .vece = MO_32 },
4597 { .fni8 = gen_saba_i64,
4598 .fniv = gen_saba_vec,
4599 .fno = gen_helper_gvec_saba_d,
4600 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4601 .opt_opc = vecop_list,
4602 .load_dest = true,
4603 .vece = MO_64 },
4605 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4608 static void gen_uaba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4610 TCGv_i32 t = tcg_temp_new_i32();
4611 gen_uabd_i32(t, a, b);
4612 tcg_gen_add_i32(d, d, t);
4613 tcg_temp_free_i32(t);
4616 static void gen_uaba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4618 TCGv_i64 t = tcg_temp_new_i64();
4619 gen_uabd_i64(t, a, b);
4620 tcg_gen_add_i64(d, d, t);
4621 tcg_temp_free_i64(t);
4624 static void gen_uaba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4626 TCGv_vec t = tcg_temp_new_vec_matching(d);
4627 gen_uabd_vec(vece, t, a, b);
4628 tcg_gen_add_vec(vece, d, d, t);
4629 tcg_temp_free_vec(t);
4632 void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4633 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4635 static const TCGOpcode vecop_list[] = {
4636 INDEX_op_sub_vec, INDEX_op_add_vec,
4637 INDEX_op_umin_vec, INDEX_op_umax_vec, 0
4639 static const GVecGen3 ops[4] = {
4640 { .fniv = gen_uaba_vec,
4641 .fno = gen_helper_gvec_uaba_b,
4642 .opt_opc = vecop_list,
4643 .load_dest = true,
4644 .vece = MO_8 },
4645 { .fniv = gen_uaba_vec,
4646 .fno = gen_helper_gvec_uaba_h,
4647 .opt_opc = vecop_list,
4648 .load_dest = true,
4649 .vece = MO_16 },
4650 { .fni4 = gen_uaba_i32,
4651 .fniv = gen_uaba_vec,
4652 .fno = gen_helper_gvec_uaba_s,
4653 .opt_opc = vecop_list,
4654 .load_dest = true,
4655 .vece = MO_32 },
4656 { .fni8 = gen_uaba_i64,
4657 .fniv = gen_uaba_vec,
4658 .fno = gen_helper_gvec_uaba_d,
4659 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4660 .opt_opc = vecop_list,
4661 .load_dest = true,
4662 .vece = MO_64 },
4664 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4667 static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
4668 int opc1, int crn, int crm, int opc2,
4669 bool isread, int rt, int rt2)
4671 const ARMCPRegInfo *ri;
4673 ri = get_arm_cp_reginfo(s->cp_regs,
4674 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
4675 if (ri) {
4676 bool need_exit_tb;
4678 /* Check access permissions */
4679 if (!cp_access_ok(s->current_el, ri, isread)) {
4680 unallocated_encoding(s);
4681 return;
4684 if (s->hstr_active || ri->accessfn ||
4685 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
4686 /* Emit code to perform further access permissions checks at
4687 * runtime; this may result in an exception.
4688 * Note that on XScale all cp0..c13 registers do an access check
4689 * call in order to handle c15_cpar.
4691 uint32_t syndrome;
4693 /* Note that since we are an implementation which takes an
4694 * exception on a trapped conditional instruction only if the
4695 * instruction passes its condition code check, we can take
4696 * advantage of the clause in the ARM ARM that allows us to set
4697 * the COND field in the instruction to 0xE in all cases.
4698 * We could fish the actual condition out of the insn (ARM)
4699 * or the condexec bits (Thumb) but it isn't necessary.
4701 switch (cpnum) {
4702 case 14:
4703 if (is64) {
4704 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
4705 isread, false);
4706 } else {
4707 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
4708 rt, isread, false);
4710 break;
4711 case 15:
4712 if (is64) {
4713 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
4714 isread, false);
4715 } else {
4716 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
4717 rt, isread, false);
4719 break;
4720 default:
4721 /* ARMv8 defines that only coprocessors 14 and 15 exist,
4722 * so this can only happen if this is an ARMv7 or earlier CPU,
4723 * in which case the syndrome information won't actually be
4724 * guest visible.
4726 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
4727 syndrome = syn_uncategorized();
4728 break;
4731 gen_set_condexec(s);
4732 gen_set_pc_im(s, s->pc_curr);
4733 gen_helper_access_check_cp_reg(cpu_env,
4734 tcg_constant_ptr(ri),
4735 tcg_constant_i32(syndrome),
4736 tcg_constant_i32(isread));
4737 } else if (ri->type & ARM_CP_RAISES_EXC) {
4739 * The readfn or writefn might raise an exception;
4740 * synchronize the CPU state in case it does.
4742 gen_set_condexec(s);
4743 gen_set_pc_im(s, s->pc_curr);
4746 /* Handle special cases first */
4747 switch (ri->type & ARM_CP_SPECIAL_MASK) {
4748 case 0:
4749 break;
4750 case ARM_CP_NOP:
4751 return;
4752 case ARM_CP_WFI:
4753 if (isread) {
4754 unallocated_encoding(s);
4755 return;
4757 gen_set_pc_im(s, s->base.pc_next);
4758 s->base.is_jmp = DISAS_WFI;
4759 return;
4760 default:
4761 g_assert_not_reached();
4764 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
4765 gen_io_start();
4768 if (isread) {
4769 /* Read */
4770 if (is64) {
4771 TCGv_i64 tmp64;
4772 TCGv_i32 tmp;
4773 if (ri->type & ARM_CP_CONST) {
4774 tmp64 = tcg_constant_i64(ri->resetvalue);
4775 } else if (ri->readfn) {
4776 tmp64 = tcg_temp_new_i64();
4777 gen_helper_get_cp_reg64(tmp64, cpu_env,
4778 tcg_constant_ptr(ri));
4779 } else {
4780 tmp64 = tcg_temp_new_i64();
4781 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
4783 tmp = tcg_temp_new_i32();
4784 tcg_gen_extrl_i64_i32(tmp, tmp64);
4785 store_reg(s, rt, tmp);
4786 tmp = tcg_temp_new_i32();
4787 tcg_gen_extrh_i64_i32(tmp, tmp64);
4788 tcg_temp_free_i64(tmp64);
4789 store_reg(s, rt2, tmp);
4790 } else {
4791 TCGv_i32 tmp;
4792 if (ri->type & ARM_CP_CONST) {
4793 tmp = tcg_constant_i32(ri->resetvalue);
4794 } else if (ri->readfn) {
4795 tmp = tcg_temp_new_i32();
4796 gen_helper_get_cp_reg(tmp, cpu_env, tcg_constant_ptr(ri));
4797 } else {
4798 tmp = load_cpu_offset(ri->fieldoffset);
4800 if (rt == 15) {
4801 /* Destination register of r15 for 32 bit loads sets
4802 * the condition codes from the high 4 bits of the value
4804 gen_set_nzcv(tmp);
4805 tcg_temp_free_i32(tmp);
4806 } else {
4807 store_reg(s, rt, tmp);
4810 } else {
4811 /* Write */
4812 if (ri->type & ARM_CP_CONST) {
4813 /* If not forbidden by access permissions, treat as WI */
4814 return;
4817 if (is64) {
4818 TCGv_i32 tmplo, tmphi;
4819 TCGv_i64 tmp64 = tcg_temp_new_i64();
4820 tmplo = load_reg(s, rt);
4821 tmphi = load_reg(s, rt2);
4822 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
4823 tcg_temp_free_i32(tmplo);
4824 tcg_temp_free_i32(tmphi);
4825 if (ri->writefn) {
4826 gen_helper_set_cp_reg64(cpu_env, tcg_constant_ptr(ri),
4827 tmp64);
4828 } else {
4829 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
4831 tcg_temp_free_i64(tmp64);
4832 } else {
4833 TCGv_i32 tmp = load_reg(s, rt);
4834 if (ri->writefn) {
4835 gen_helper_set_cp_reg(cpu_env, tcg_constant_ptr(ri), tmp);
4836 tcg_temp_free_i32(tmp);
4837 } else {
4838 store_cpu_offset(tmp, ri->fieldoffset, 4);
4843 /* I/O operations must end the TB here (whether read or write) */
4844 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
4845 (ri->type & ARM_CP_IO));
4847 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
4849 * A write to any coprocessor register that ends a TB
4850 * must rebuild the hflags for the next TB.
4852 gen_rebuild_hflags(s, ri->type & ARM_CP_NEWEL);
4854 * We default to ending the TB on a coprocessor register write,
4855 * but allow this to be suppressed by the register definition
4856 * (usually only necessary to work around guest bugs).
4858 need_exit_tb = true;
4860 if (need_exit_tb) {
4861 gen_lookup_tb(s);
4864 return;
4867 /* Unknown register; this might be a guest error or a QEMU
4868 * unimplemented feature.
4870 if (is64) {
4871 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
4872 "64 bit system register cp:%d opc1: %d crm:%d "
4873 "(%s)\n",
4874 isread ? "read" : "write", cpnum, opc1, crm,
4875 s->ns ? "non-secure" : "secure");
4876 } else {
4877 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
4878 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
4879 "(%s)\n",
4880 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
4881 s->ns ? "non-secure" : "secure");
4884 unallocated_encoding(s);
4885 return;
4888 /* Decode XScale DSP or iWMMXt insn (in the copro space, cp=0 or 1) */
4889 static void disas_xscale_insn(DisasContext *s, uint32_t insn)
4891 int cpnum = (insn >> 8) & 0xf;
4893 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
4894 unallocated_encoding(s);
4895 } else if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
4896 if (disas_iwmmxt_insn(s, insn)) {
4897 unallocated_encoding(s);
4899 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
4900 if (disas_dsp_insn(s, insn)) {
4901 unallocated_encoding(s);
4906 /* Store a 64-bit value to a register pair. Clobbers val. */
4907 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
4909 TCGv_i32 tmp;
4910 tmp = tcg_temp_new_i32();
4911 tcg_gen_extrl_i64_i32(tmp, val);
4912 store_reg(s, rlow, tmp);
4913 tmp = tcg_temp_new_i32();
4914 tcg_gen_extrh_i64_i32(tmp, val);
4915 store_reg(s, rhigh, tmp);
4918 /* load and add a 64-bit value from a register pair. */
4919 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
4921 TCGv_i64 tmp;
4922 TCGv_i32 tmpl;
4923 TCGv_i32 tmph;
4925 /* Load 64-bit value rd:rn. */
4926 tmpl = load_reg(s, rlow);
4927 tmph = load_reg(s, rhigh);
4928 tmp = tcg_temp_new_i64();
4929 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
4930 tcg_temp_free_i32(tmpl);
4931 tcg_temp_free_i32(tmph);
4932 tcg_gen_add_i64(val, val, tmp);
4933 tcg_temp_free_i64(tmp);
4936 /* Set N and Z flags from hi|lo. */
4937 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
4939 tcg_gen_mov_i32(cpu_NF, hi);
4940 tcg_gen_or_i32(cpu_ZF, lo, hi);
4943 /* Load/Store exclusive instructions are implemented by remembering
4944 the value/address loaded, and seeing if these are the same
4945 when the store is performed. This should be sufficient to implement
4946 the architecturally mandated semantics, and avoids having to monitor
4947 regular stores. The compare vs the remembered value is done during
4948 the cmpxchg operation, but we must compare the addresses manually. */
4949 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
4950 TCGv_i32 addr, int size)
4952 TCGv_i32 tmp = tcg_temp_new_i32();
4953 MemOp opc = size | MO_ALIGN | s->be_data;
4955 s->is_ldex = true;
4957 if (size == 3) {
4958 TCGv_i32 tmp2 = tcg_temp_new_i32();
4959 TCGv_i64 t64 = tcg_temp_new_i64();
4962 * For AArch32, architecturally the 32-bit word at the lowest
4963 * address is always Rt and the one at addr+4 is Rt2, even if
4964 * the CPU is big-endian. That means we don't want to do a
4965 * gen_aa32_ld_i64(), which checks SCTLR_B as if for an
4966 * architecturally 64-bit access, but instead do a 64-bit access
4967 * using MO_BE if appropriate and then split the two halves.
4969 TCGv taddr = gen_aa32_addr(s, addr, opc);
4971 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
4972 tcg_temp_free(taddr);
4973 tcg_gen_mov_i64(cpu_exclusive_val, t64);
4974 if (s->be_data == MO_BE) {
4975 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
4976 } else {
4977 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
4979 tcg_temp_free_i64(t64);
4981 store_reg(s, rt2, tmp2);
4982 } else {
4983 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
4984 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
4987 store_reg(s, rt, tmp);
4988 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
4991 static void gen_clrex(DisasContext *s)
4993 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
4996 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
4997 TCGv_i32 addr, int size)
4999 TCGv_i32 t0, t1, t2;
5000 TCGv_i64 extaddr;
5001 TCGv taddr;
5002 TCGLabel *done_label;
5003 TCGLabel *fail_label;
5004 MemOp opc = size | MO_ALIGN | s->be_data;
5006 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
5007 [addr] = {Rt};
5008 {Rd} = 0;
5009 } else {
5010 {Rd} = 1;
5011 } */
5012 fail_label = gen_new_label();
5013 done_label = gen_new_label();
5014 extaddr = tcg_temp_new_i64();
5015 tcg_gen_extu_i32_i64(extaddr, addr);
5016 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
5017 tcg_temp_free_i64(extaddr);
5019 taddr = gen_aa32_addr(s, addr, opc);
5020 t0 = tcg_temp_new_i32();
5021 t1 = load_reg(s, rt);
5022 if (size == 3) {
5023 TCGv_i64 o64 = tcg_temp_new_i64();
5024 TCGv_i64 n64 = tcg_temp_new_i64();
5026 t2 = load_reg(s, rt2);
5029 * For AArch32, architecturally the 32-bit word at the lowest
5030 * address is always Rt and the one at addr+4 is Rt2, even if
5031 * the CPU is big-endian. Since we're going to treat this as a
5032 * single 64-bit BE store, we need to put the two halves in the
5033 * opposite order for BE to LE, so that they end up in the right
5034 * places. We don't want gen_aa32_st_i64, because that checks
5035 * SCTLR_B as if for an architectural 64-bit access.
5037 if (s->be_data == MO_BE) {
5038 tcg_gen_concat_i32_i64(n64, t2, t1);
5039 } else {
5040 tcg_gen_concat_i32_i64(n64, t1, t2);
5042 tcg_temp_free_i32(t2);
5044 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
5045 get_mem_index(s), opc);
5046 tcg_temp_free_i64(n64);
5048 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
5049 tcg_gen_extrl_i64_i32(t0, o64);
5051 tcg_temp_free_i64(o64);
5052 } else {
5053 t2 = tcg_temp_new_i32();
5054 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
5055 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
5056 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
5057 tcg_temp_free_i32(t2);
5059 tcg_temp_free_i32(t1);
5060 tcg_temp_free(taddr);
5061 tcg_gen_mov_i32(cpu_R[rd], t0);
5062 tcg_temp_free_i32(t0);
5063 tcg_gen_br(done_label);
5065 gen_set_label(fail_label);
5066 tcg_gen_movi_i32(cpu_R[rd], 1);
5067 gen_set_label(done_label);
5068 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
5071 /* gen_srs:
5072 * @env: CPUARMState
5073 * @s: DisasContext
5074 * @mode: mode field from insn (which stack to store to)
5075 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
5076 * @writeback: true if writeback bit set
5078 * Generate code for the SRS (Store Return State) insn.
5080 static void gen_srs(DisasContext *s,
5081 uint32_t mode, uint32_t amode, bool writeback)
5083 int32_t offset;
5084 TCGv_i32 addr, tmp;
5085 bool undef = false;
5087 /* SRS is:
5088 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
5089 * and specified mode is monitor mode
5090 * - UNDEFINED in Hyp mode
5091 * - UNPREDICTABLE in User or System mode
5092 * - UNPREDICTABLE if the specified mode is:
5093 * -- not implemented
5094 * -- not a valid mode number
5095 * -- a mode that's at a higher exception level
5096 * -- Monitor, if we are Non-secure
5097 * For the UNPREDICTABLE cases we choose to UNDEF.
5099 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
5100 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
5101 return;
5104 if (s->current_el == 0 || s->current_el == 2) {
5105 undef = true;
5108 switch (mode) {
5109 case ARM_CPU_MODE_USR:
5110 case ARM_CPU_MODE_FIQ:
5111 case ARM_CPU_MODE_IRQ:
5112 case ARM_CPU_MODE_SVC:
5113 case ARM_CPU_MODE_ABT:
5114 case ARM_CPU_MODE_UND:
5115 case ARM_CPU_MODE_SYS:
5116 break;
5117 case ARM_CPU_MODE_HYP:
5118 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
5119 undef = true;
5121 break;
5122 case ARM_CPU_MODE_MON:
5123 /* No need to check specifically for "are we non-secure" because
5124 * we've already made EL0 UNDEF and handled the trap for S-EL1;
5125 * so if this isn't EL3 then we must be non-secure.
5127 if (s->current_el != 3) {
5128 undef = true;
5130 break;
5131 default:
5132 undef = true;
5135 if (undef) {
5136 unallocated_encoding(s);
5137 return;
5140 addr = tcg_temp_new_i32();
5141 /* get_r13_banked() will raise an exception if called from System mode */
5142 gen_set_condexec(s);
5143 gen_set_pc_im(s, s->pc_curr);
5144 gen_helper_get_r13_banked(addr, cpu_env, tcg_constant_i32(mode));
5145 switch (amode) {
5146 case 0: /* DA */
5147 offset = -4;
5148 break;
5149 case 1: /* IA */
5150 offset = 0;
5151 break;
5152 case 2: /* DB */
5153 offset = -8;
5154 break;
5155 case 3: /* IB */
5156 offset = 4;
5157 break;
5158 default:
5159 g_assert_not_reached();
5161 tcg_gen_addi_i32(addr, addr, offset);
5162 tmp = load_reg(s, 14);
5163 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
5164 tcg_temp_free_i32(tmp);
5165 tmp = load_cpu_field(spsr);
5166 tcg_gen_addi_i32(addr, addr, 4);
5167 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
5168 tcg_temp_free_i32(tmp);
5169 if (writeback) {
5170 switch (amode) {
5171 case 0:
5172 offset = -8;
5173 break;
5174 case 1:
5175 offset = 4;
5176 break;
5177 case 2:
5178 offset = -4;
5179 break;
5180 case 3:
5181 offset = 0;
5182 break;
5183 default:
5184 g_assert_not_reached();
5186 tcg_gen_addi_i32(addr, addr, offset);
5187 gen_helper_set_r13_banked(cpu_env, tcg_constant_i32(mode), addr);
5189 tcg_temp_free_i32(addr);
5190 s->base.is_jmp = DISAS_UPDATE_EXIT;
5193 /* Skip this instruction if the ARM condition is false */
5194 static void arm_skip_unless(DisasContext *s, uint32_t cond)
5196 arm_gen_condlabel(s);
5197 arm_gen_test_cc(cond ^ 1, s->condlabel);
5202 * Constant expanders used by T16/T32 decode
5205 /* Return only the rotation part of T32ExpandImm. */
5206 static int t32_expandimm_rot(DisasContext *s, int x)
5208 return x & 0xc00 ? extract32(x, 7, 5) : 0;
5211 /* Return the unrotated immediate from T32ExpandImm. */
5212 static int t32_expandimm_imm(DisasContext *s, int x)
5214 int imm = extract32(x, 0, 8);
5216 switch (extract32(x, 8, 4)) {
5217 case 0: /* XY */
5218 /* Nothing to do. */
5219 break;
5220 case 1: /* 00XY00XY */
5221 imm *= 0x00010001;
5222 break;
5223 case 2: /* XY00XY00 */
5224 imm *= 0x01000100;
5225 break;
5226 case 3: /* XYXYXYXY */
5227 imm *= 0x01010101;
5228 break;
5229 default:
5230 /* Rotated constant. */
5231 imm |= 0x80;
5232 break;
5234 return imm;
5237 static int t32_branch24(DisasContext *s, int x)
5239 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
5240 x ^= !(x < 0) * (3 << 21);
5241 /* Append the final zero. */
5242 return x << 1;
5245 static int t16_setflags(DisasContext *s)
5247 return s->condexec_mask == 0;
5250 static int t16_push_list(DisasContext *s, int x)
5252 return (x & 0xff) | (x & 0x100) << (14 - 8);
5255 static int t16_pop_list(DisasContext *s, int x)
5257 return (x & 0xff) | (x & 0x100) << (15 - 8);
5261 * Include the generated decoders.
5264 #include "decode-a32.c.inc"
5265 #include "decode-a32-uncond.c.inc"
5266 #include "decode-t32.c.inc"
5267 #include "decode-t16.c.inc"
5269 static bool valid_cp(DisasContext *s, int cp)
5272 * Return true if this coprocessor field indicates something
5273 * that's really a possible coprocessor.
5274 * For v7 and earlier, coprocessors 8..15 were reserved for Arm use,
5275 * and of those only cp14 and cp15 were used for registers.
5276 * cp10 and cp11 were used for VFP and Neon, whose decode is
5277 * dealt with elsewhere. With the advent of fp16, cp9 is also
5278 * now part of VFP.
5279 * For v8A and later, the encoding has been tightened so that
5280 * only cp14 and cp15 are valid, and other values aren't considered
5281 * to be in the coprocessor-instruction space at all. v8M still
5282 * permits coprocessors 0..7.
5283 * For XScale, we must not decode the XScale cp0, cp1 space as
5284 * a standard coprocessor insn, because we want to fall through to
5285 * the legacy disas_xscale_insn() decoder after decodetree is done.
5287 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cp == 0 || cp == 1)) {
5288 return false;
5291 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
5292 !arm_dc_feature(s, ARM_FEATURE_M)) {
5293 return cp >= 14;
5295 return cp < 8 || cp >= 14;
5298 static bool trans_MCR(DisasContext *s, arg_MCR *a)
5300 if (!valid_cp(s, a->cp)) {
5301 return false;
5303 do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
5304 false, a->rt, 0);
5305 return true;
5308 static bool trans_MRC(DisasContext *s, arg_MRC *a)
5310 if (!valid_cp(s, a->cp)) {
5311 return false;
5313 do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
5314 true, a->rt, 0);
5315 return true;
5318 static bool trans_MCRR(DisasContext *s, arg_MCRR *a)
5320 if (!valid_cp(s, a->cp)) {
5321 return false;
5323 do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
5324 false, a->rt, a->rt2);
5325 return true;
5328 static bool trans_MRRC(DisasContext *s, arg_MRRC *a)
5330 if (!valid_cp(s, a->cp)) {
5331 return false;
5333 do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
5334 true, a->rt, a->rt2);
5335 return true;
5338 /* Helpers to swap operands for reverse-subtract. */
5339 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
5341 tcg_gen_sub_i32(dst, b, a);
5344 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
5346 gen_sub_CC(dst, b, a);
5349 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
5351 gen_sub_carry(dest, b, a);
5354 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
5356 gen_sbc_CC(dest, b, a);
5360 * Helpers for the data processing routines.
5362 * After the computation store the results back.
5363 * This may be suppressed altogether (STREG_NONE), require a runtime
5364 * check against the stack limits (STREG_SP_CHECK), or generate an
5365 * exception return. Oh, or store into a register.
5367 * Always return true, indicating success for a trans_* function.
5369 typedef enum {
5370 STREG_NONE,
5371 STREG_NORMAL,
5372 STREG_SP_CHECK,
5373 STREG_EXC_RET,
5374 } StoreRegKind;
5376 static bool store_reg_kind(DisasContext *s, int rd,
5377 TCGv_i32 val, StoreRegKind kind)
5379 switch (kind) {
5380 case STREG_NONE:
5381 tcg_temp_free_i32(val);
5382 return true;
5383 case STREG_NORMAL:
5384 /* See ALUWritePC: Interworking only from a32 mode. */
5385 if (s->thumb) {
5386 store_reg(s, rd, val);
5387 } else {
5388 store_reg_bx(s, rd, val);
5390 return true;
5391 case STREG_SP_CHECK:
5392 store_sp_checked(s, val);
5393 return true;
5394 case STREG_EXC_RET:
5395 gen_exception_return(s, val);
5396 return true;
5398 g_assert_not_reached();
5402 * Data Processing (register)
5404 * Operate, with set flags, one register source,
5405 * one immediate shifted register source, and a destination.
5407 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
5408 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5409 int logic_cc, StoreRegKind kind)
5411 TCGv_i32 tmp1, tmp2;
5413 tmp2 = load_reg(s, a->rm);
5414 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
5415 tmp1 = load_reg(s, a->rn);
5417 gen(tmp1, tmp1, tmp2);
5418 tcg_temp_free_i32(tmp2);
5420 if (logic_cc) {
5421 gen_logic_CC(tmp1);
5423 return store_reg_kind(s, a->rd, tmp1, kind);
5426 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
5427 void (*gen)(TCGv_i32, TCGv_i32),
5428 int logic_cc, StoreRegKind kind)
5430 TCGv_i32 tmp;
5432 tmp = load_reg(s, a->rm);
5433 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
5435 gen(tmp, tmp);
5436 if (logic_cc) {
5437 gen_logic_CC(tmp);
5439 return store_reg_kind(s, a->rd, tmp, kind);
5443 * Data-processing (register-shifted register)
5445 * Operate, with set flags, one register source,
5446 * one register shifted register source, and a destination.
5448 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
5449 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5450 int logic_cc, StoreRegKind kind)
5452 TCGv_i32 tmp1, tmp2;
5454 tmp1 = load_reg(s, a->rs);
5455 tmp2 = load_reg(s, a->rm);
5456 gen_arm_shift_reg(tmp2, a->shty, tmp1, 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_shr(DisasContext *s, arg_s_rrr_shr *a,
5469 void (*gen)(TCGv_i32, TCGv_i32),
5470 int logic_cc, StoreRegKind kind)
5472 TCGv_i32 tmp1, tmp2;
5474 tmp1 = load_reg(s, a->rs);
5475 tmp2 = load_reg(s, a->rm);
5476 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
5478 gen(tmp2, tmp2);
5479 if (logic_cc) {
5480 gen_logic_CC(tmp2);
5482 return store_reg_kind(s, a->rd, tmp2, kind);
5486 * Data-processing (immediate)
5488 * Operate, with set flags, one register source,
5489 * one rotated immediate, and a destination.
5491 * Note that logic_cc && a->rot setting CF based on the msb of the
5492 * immediate is the reason why we must pass in the unrotated form
5493 * of the immediate.
5495 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
5496 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5497 int logic_cc, StoreRegKind kind)
5499 TCGv_i32 tmp1;
5500 uint32_t imm;
5502 imm = ror32(a->imm, a->rot);
5503 if (logic_cc && a->rot) {
5504 tcg_gen_movi_i32(cpu_CF, imm >> 31);
5506 tmp1 = load_reg(s, a->rn);
5508 gen(tmp1, tmp1, tcg_constant_i32(imm));
5510 if (logic_cc) {
5511 gen_logic_CC(tmp1);
5513 return store_reg_kind(s, a->rd, tmp1, kind);
5516 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
5517 void (*gen)(TCGv_i32, TCGv_i32),
5518 int logic_cc, StoreRegKind kind)
5520 TCGv_i32 tmp;
5521 uint32_t imm;
5523 imm = ror32(a->imm, a->rot);
5524 if (logic_cc && a->rot) {
5525 tcg_gen_movi_i32(cpu_CF, imm >> 31);
5528 tmp = tcg_temp_new_i32();
5529 gen(tmp, tcg_constant_i32(imm));
5531 if (logic_cc) {
5532 gen_logic_CC(tmp);
5534 return store_reg_kind(s, a->rd, tmp, kind);
5537 #define DO_ANY3(NAME, OP, L, K) \
5538 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
5539 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
5540 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
5541 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
5542 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
5543 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
5545 #define DO_ANY2(NAME, OP, L, K) \
5546 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
5547 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
5548 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
5549 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
5550 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
5551 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
5553 #define DO_CMP2(NAME, OP, L) \
5554 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
5555 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
5556 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
5557 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
5558 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
5559 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
5561 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
5562 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
5563 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
5564 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
5566 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
5567 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
5568 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
5569 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
5571 DO_CMP2(TST, tcg_gen_and_i32, true)
5572 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
5573 DO_CMP2(CMN, gen_add_CC, false)
5574 DO_CMP2(CMP, gen_sub_CC, false)
5576 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
5577 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
5580 * Note for the computation of StoreRegKind we return out of the
5581 * middle of the functions that are expanded by DO_ANY3, and that
5582 * we modify a->s via that parameter before it is used by OP.
5584 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
5586 StoreRegKind ret = STREG_NORMAL;
5587 if (a->rd == 15 && a->s) {
5589 * See ALUExceptionReturn:
5590 * In User mode, UNPREDICTABLE; we choose UNDEF.
5591 * In Hyp mode, UNDEFINED.
5593 if (IS_USER(s) || s->current_el == 2) {
5594 unallocated_encoding(s);
5595 return true;
5597 /* There is no writeback of nzcv to PSTATE. */
5598 a->s = 0;
5599 ret = STREG_EXC_RET;
5600 } else if (a->rd == 13 && a->rn == 13) {
5601 ret = STREG_SP_CHECK;
5603 ret;
5606 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
5608 StoreRegKind ret = STREG_NORMAL;
5609 if (a->rd == 15 && a->s) {
5611 * See ALUExceptionReturn:
5612 * In User mode, UNPREDICTABLE; we choose UNDEF.
5613 * In Hyp mode, UNDEFINED.
5615 if (IS_USER(s) || s->current_el == 2) {
5616 unallocated_encoding(s);
5617 return true;
5619 /* There is no writeback of nzcv to PSTATE. */
5620 a->s = 0;
5621 ret = STREG_EXC_RET;
5622 } else if (a->rd == 13) {
5623 ret = STREG_SP_CHECK;
5625 ret;
5628 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
5631 * ORN is only available with T32, so there is no register-shifted-register
5632 * form of the insn. Using the DO_ANY3 macro would create an unused function.
5634 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
5636 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
5639 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
5641 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
5644 #undef DO_ANY3
5645 #undef DO_ANY2
5646 #undef DO_CMP2
5648 static bool trans_ADR(DisasContext *s, arg_ri *a)
5650 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
5651 return true;
5654 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
5656 if (!ENABLE_ARCH_6T2) {
5657 return false;
5660 store_reg(s, a->rd, tcg_constant_i32(a->imm));
5661 return true;
5664 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
5666 TCGv_i32 tmp;
5668 if (!ENABLE_ARCH_6T2) {
5669 return false;
5672 tmp = load_reg(s, a->rd);
5673 tcg_gen_ext16u_i32(tmp, tmp);
5674 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
5675 store_reg(s, a->rd, tmp);
5676 return true;
5680 * v8.1M MVE wide-shifts
5682 static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
5683 WideShiftImmFn *fn)
5685 TCGv_i64 rda;
5686 TCGv_i32 rdalo, rdahi;
5688 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5689 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5690 return false;
5692 if (a->rdahi == 15) {
5693 /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
5694 return false;
5696 if (!dc_isar_feature(aa32_mve, s) ||
5697 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5698 a->rdahi == 13) {
5699 /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
5700 unallocated_encoding(s);
5701 return true;
5704 if (a->shim == 0) {
5705 a->shim = 32;
5708 rda = tcg_temp_new_i64();
5709 rdalo = load_reg(s, a->rdalo);
5710 rdahi = load_reg(s, a->rdahi);
5711 tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
5713 fn(rda, rda, a->shim);
5715 tcg_gen_extrl_i64_i32(rdalo, rda);
5716 tcg_gen_extrh_i64_i32(rdahi, rda);
5717 store_reg(s, a->rdalo, rdalo);
5718 store_reg(s, a->rdahi, rdahi);
5719 tcg_temp_free_i64(rda);
5721 return true;
5724 static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5726 return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
5729 static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
5731 return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
5734 static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5736 return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
5739 static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
5741 gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
5744 static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
5746 return do_mve_shl_ri(s, a, gen_mve_sqshll);
5749 static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
5751 gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
5754 static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
5756 return do_mve_shl_ri(s, a, gen_mve_uqshll);
5759 static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5761 return do_mve_shl_ri(s, a, gen_srshr64_i64);
5764 static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5766 return do_mve_shl_ri(s, a, gen_urshr64_i64);
5769 static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
5771 TCGv_i64 rda;
5772 TCGv_i32 rdalo, rdahi;
5774 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5775 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5776 return false;
5778 if (a->rdahi == 15) {
5779 /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
5780 return false;
5782 if (!dc_isar_feature(aa32_mve, s) ||
5783 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5784 a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
5785 a->rm == a->rdahi || a->rm == a->rdalo) {
5786 /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
5787 unallocated_encoding(s);
5788 return true;
5791 rda = tcg_temp_new_i64();
5792 rdalo = load_reg(s, a->rdalo);
5793 rdahi = load_reg(s, a->rdahi);
5794 tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
5796 /* The helper takes care of the sign-extension of the low 8 bits of Rm */
5797 fn(rda, cpu_env, rda, cpu_R[a->rm]);
5799 tcg_gen_extrl_i64_i32(rdalo, rda);
5800 tcg_gen_extrh_i64_i32(rdahi, rda);
5801 store_reg(s, a->rdalo, rdalo);
5802 store_reg(s, a->rdahi, rdahi);
5803 tcg_temp_free_i64(rda);
5805 return true;
5808 static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
5810 return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
5813 static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
5815 return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
5818 static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
5820 return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
5823 static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
5825 return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
5828 static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
5830 return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
5833 static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
5835 return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
5838 static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
5840 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5841 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5842 return false;
5844 if (!dc_isar_feature(aa32_mve, s) ||
5845 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5846 a->rda == 13 || a->rda == 15) {
5847 /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
5848 unallocated_encoding(s);
5849 return true;
5852 if (a->shim == 0) {
5853 a->shim = 32;
5855 fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
5857 return true;
5860 static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
5862 return do_mve_sh_ri(s, a, gen_urshr32_i32);
5865 static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
5867 return do_mve_sh_ri(s, a, gen_srshr32_i32);
5870 static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
5872 gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
5875 static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
5877 return do_mve_sh_ri(s, a, gen_mve_sqshl);
5880 static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
5882 gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
5885 static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
5887 return do_mve_sh_ri(s, a, gen_mve_uqshl);
5890 static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
5892 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5893 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5894 return false;
5896 if (!dc_isar_feature(aa32_mve, s) ||
5897 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5898 a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
5899 a->rm == a->rda) {
5900 /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
5901 unallocated_encoding(s);
5902 return true;
5905 /* The helper takes care of the sign-extension of the low 8 bits of Rm */
5906 fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
5907 return true;
5910 static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
5912 return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
5915 static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
5917 return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
5921 * Multiply and multiply accumulate
5924 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
5926 TCGv_i32 t1, t2;
5928 t1 = load_reg(s, a->rn);
5929 t2 = load_reg(s, a->rm);
5930 tcg_gen_mul_i32(t1, t1, t2);
5931 tcg_temp_free_i32(t2);
5932 if (add) {
5933 t2 = load_reg(s, a->ra);
5934 tcg_gen_add_i32(t1, t1, t2);
5935 tcg_temp_free_i32(t2);
5937 if (a->s) {
5938 gen_logic_CC(t1);
5940 store_reg(s, a->rd, t1);
5941 return true;
5944 static bool trans_MUL(DisasContext *s, arg_MUL *a)
5946 return op_mla(s, a, false);
5949 static bool trans_MLA(DisasContext *s, arg_MLA *a)
5951 return op_mla(s, a, true);
5954 static bool trans_MLS(DisasContext *s, arg_MLS *a)
5956 TCGv_i32 t1, t2;
5958 if (!ENABLE_ARCH_6T2) {
5959 return false;
5961 t1 = load_reg(s, a->rn);
5962 t2 = load_reg(s, a->rm);
5963 tcg_gen_mul_i32(t1, t1, t2);
5964 tcg_temp_free_i32(t2);
5965 t2 = load_reg(s, a->ra);
5966 tcg_gen_sub_i32(t1, t2, t1);
5967 tcg_temp_free_i32(t2);
5968 store_reg(s, a->rd, t1);
5969 return true;
5972 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
5974 TCGv_i32 t0, t1, t2, t3;
5976 t0 = load_reg(s, a->rm);
5977 t1 = load_reg(s, a->rn);
5978 if (uns) {
5979 tcg_gen_mulu2_i32(t0, t1, t0, t1);
5980 } else {
5981 tcg_gen_muls2_i32(t0, t1, t0, t1);
5983 if (add) {
5984 t2 = load_reg(s, a->ra);
5985 t3 = load_reg(s, a->rd);
5986 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
5987 tcg_temp_free_i32(t2);
5988 tcg_temp_free_i32(t3);
5990 if (a->s) {
5991 gen_logicq_cc(t0, t1);
5993 store_reg(s, a->ra, t0);
5994 store_reg(s, a->rd, t1);
5995 return true;
5998 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
6000 return op_mlal(s, a, true, false);
6003 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
6005 return op_mlal(s, a, false, false);
6008 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
6010 return op_mlal(s, a, true, true);
6013 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
6015 return op_mlal(s, a, false, true);
6018 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
6020 TCGv_i32 t0, t1, t2, zero;
6022 if (s->thumb
6023 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
6024 : !ENABLE_ARCH_6) {
6025 return false;
6028 t0 = load_reg(s, a->rm);
6029 t1 = load_reg(s, a->rn);
6030 tcg_gen_mulu2_i32(t0, t1, t0, t1);
6031 zero = tcg_constant_i32(0);
6032 t2 = load_reg(s, a->ra);
6033 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
6034 tcg_temp_free_i32(t2);
6035 t2 = load_reg(s, a->rd);
6036 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
6037 tcg_temp_free_i32(t2);
6038 store_reg(s, a->ra, t0);
6039 store_reg(s, a->rd, t1);
6040 return true;
6044 * Saturating addition and subtraction
6047 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
6049 TCGv_i32 t0, t1;
6051 if (s->thumb
6052 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
6053 : !ENABLE_ARCH_5TE) {
6054 return false;
6057 t0 = load_reg(s, a->rm);
6058 t1 = load_reg(s, a->rn);
6059 if (doub) {
6060 gen_helper_add_saturate(t1, cpu_env, t1, t1);
6062 if (add) {
6063 gen_helper_add_saturate(t0, cpu_env, t0, t1);
6064 } else {
6065 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
6067 tcg_temp_free_i32(t1);
6068 store_reg(s, a->rd, t0);
6069 return true;
6072 #define DO_QADDSUB(NAME, ADD, DOUB) \
6073 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6075 return op_qaddsub(s, a, ADD, DOUB); \
6078 DO_QADDSUB(QADD, true, false)
6079 DO_QADDSUB(QSUB, false, false)
6080 DO_QADDSUB(QDADD, true, true)
6081 DO_QADDSUB(QDSUB, false, true)
6083 #undef DO_QADDSUB
6086 * Halfword multiply and multiply accumulate
6089 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
6090 int add_long, bool nt, bool mt)
6092 TCGv_i32 t0, t1, tl, th;
6094 if (s->thumb
6095 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
6096 : !ENABLE_ARCH_5TE) {
6097 return false;
6100 t0 = load_reg(s, a->rn);
6101 t1 = load_reg(s, a->rm);
6102 gen_mulxy(t0, t1, nt, mt);
6103 tcg_temp_free_i32(t1);
6105 switch (add_long) {
6106 case 0:
6107 store_reg(s, a->rd, t0);
6108 break;
6109 case 1:
6110 t1 = load_reg(s, a->ra);
6111 gen_helper_add_setq(t0, cpu_env, t0, t1);
6112 tcg_temp_free_i32(t1);
6113 store_reg(s, a->rd, t0);
6114 break;
6115 case 2:
6116 tl = load_reg(s, a->ra);
6117 th = load_reg(s, a->rd);
6118 /* Sign-extend the 32-bit product to 64 bits. */
6119 t1 = tcg_temp_new_i32();
6120 tcg_gen_sari_i32(t1, t0, 31);
6121 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
6122 tcg_temp_free_i32(t0);
6123 tcg_temp_free_i32(t1);
6124 store_reg(s, a->ra, tl);
6125 store_reg(s, a->rd, th);
6126 break;
6127 default:
6128 g_assert_not_reached();
6130 return true;
6133 #define DO_SMLAX(NAME, add, nt, mt) \
6134 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
6136 return op_smlaxxx(s, a, add, nt, mt); \
6139 DO_SMLAX(SMULBB, 0, 0, 0)
6140 DO_SMLAX(SMULBT, 0, 0, 1)
6141 DO_SMLAX(SMULTB, 0, 1, 0)
6142 DO_SMLAX(SMULTT, 0, 1, 1)
6144 DO_SMLAX(SMLABB, 1, 0, 0)
6145 DO_SMLAX(SMLABT, 1, 0, 1)
6146 DO_SMLAX(SMLATB, 1, 1, 0)
6147 DO_SMLAX(SMLATT, 1, 1, 1)
6149 DO_SMLAX(SMLALBB, 2, 0, 0)
6150 DO_SMLAX(SMLALBT, 2, 0, 1)
6151 DO_SMLAX(SMLALTB, 2, 1, 0)
6152 DO_SMLAX(SMLALTT, 2, 1, 1)
6154 #undef DO_SMLAX
6156 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
6158 TCGv_i32 t0, t1;
6160 if (!ENABLE_ARCH_5TE) {
6161 return false;
6164 t0 = load_reg(s, a->rn);
6165 t1 = load_reg(s, a->rm);
6167 * Since the nominal result is product<47:16>, shift the 16-bit
6168 * input up by 16 bits, so that the result is at product<63:32>.
6170 if (mt) {
6171 tcg_gen_andi_i32(t1, t1, 0xffff0000);
6172 } else {
6173 tcg_gen_shli_i32(t1, t1, 16);
6175 tcg_gen_muls2_i32(t0, t1, t0, t1);
6176 tcg_temp_free_i32(t0);
6177 if (add) {
6178 t0 = load_reg(s, a->ra);
6179 gen_helper_add_setq(t1, cpu_env, t1, t0);
6180 tcg_temp_free_i32(t0);
6182 store_reg(s, a->rd, t1);
6183 return true;
6186 #define DO_SMLAWX(NAME, add, mt) \
6187 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
6189 return op_smlawx(s, a, add, mt); \
6192 DO_SMLAWX(SMULWB, 0, 0)
6193 DO_SMLAWX(SMULWT, 0, 1)
6194 DO_SMLAWX(SMLAWB, 1, 0)
6195 DO_SMLAWX(SMLAWT, 1, 1)
6197 #undef DO_SMLAWX
6200 * MSR (immediate) and hints
6203 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
6206 * When running single-threaded TCG code, use the helper to ensure that
6207 * the next round-robin scheduled vCPU gets a crack. When running in
6208 * MTTCG we don't generate jumps to the helper as it won't affect the
6209 * scheduling of other vCPUs.
6211 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
6212 gen_set_pc_im(s, s->base.pc_next);
6213 s->base.is_jmp = DISAS_YIELD;
6215 return true;
6218 static bool trans_WFE(DisasContext *s, arg_WFE *a)
6221 * When running single-threaded TCG code, use the helper to ensure that
6222 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
6223 * just skip this instruction. Currently the SEV/SEVL instructions,
6224 * which are *one* of many ways to wake the CPU from WFE, are not
6225 * implemented so we can't sleep like WFI does.
6227 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
6228 gen_set_pc_im(s, s->base.pc_next);
6229 s->base.is_jmp = DISAS_WFE;
6231 return true;
6234 static bool trans_WFI(DisasContext *s, arg_WFI *a)
6236 /* For WFI, halt the vCPU until an IRQ. */
6237 gen_set_pc_im(s, s->base.pc_next);
6238 s->base.is_jmp = DISAS_WFI;
6239 return true;
6242 static bool trans_ESB(DisasContext *s, arg_ESB *a)
6245 * For M-profile, minimal-RAS ESB can be a NOP.
6246 * Without RAS, we must implement this as NOP.
6248 if (!arm_dc_feature(s, ARM_FEATURE_M) && dc_isar_feature(aa32_ras, s)) {
6250 * QEMU does not have a source of physical SErrors,
6251 * so we are only concerned with virtual SErrors.
6252 * The pseudocode in the ARM for this case is
6253 * if PSTATE.EL IN {EL0, EL1} && EL2Enabled() then
6254 * AArch32.vESBOperation();
6255 * Most of the condition can be evaluated at translation time.
6256 * Test for EL2 present, and defer test for SEL2 to runtime.
6258 if (s->current_el <= 1 && arm_dc_feature(s, ARM_FEATURE_EL2)) {
6259 gen_helper_vesb(cpu_env);
6262 return true;
6265 static bool trans_NOP(DisasContext *s, arg_NOP *a)
6267 return true;
6270 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
6272 uint32_t val = ror32(a->imm, a->rot * 2);
6273 uint32_t mask = msr_mask(s, a->mask, a->r);
6275 if (gen_set_psr_im(s, mask, a->r, val)) {
6276 unallocated_encoding(s);
6278 return true;
6282 * Cyclic Redundancy Check
6285 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
6287 TCGv_i32 t1, t2, t3;
6289 if (!dc_isar_feature(aa32_crc32, s)) {
6290 return false;
6293 t1 = load_reg(s, a->rn);
6294 t2 = load_reg(s, a->rm);
6295 switch (sz) {
6296 case MO_8:
6297 gen_uxtb(t2);
6298 break;
6299 case MO_16:
6300 gen_uxth(t2);
6301 break;
6302 case MO_32:
6303 break;
6304 default:
6305 g_assert_not_reached();
6307 t3 = tcg_constant_i32(1 << sz);
6308 if (c) {
6309 gen_helper_crc32c(t1, t1, t2, t3);
6310 } else {
6311 gen_helper_crc32(t1, t1, t2, t3);
6313 tcg_temp_free_i32(t2);
6314 store_reg(s, a->rd, t1);
6315 return true;
6318 #define DO_CRC32(NAME, c, sz) \
6319 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6320 { return op_crc32(s, a, c, sz); }
6322 DO_CRC32(CRC32B, false, MO_8)
6323 DO_CRC32(CRC32H, false, MO_16)
6324 DO_CRC32(CRC32W, false, MO_32)
6325 DO_CRC32(CRC32CB, true, MO_8)
6326 DO_CRC32(CRC32CH, true, MO_16)
6327 DO_CRC32(CRC32CW, true, MO_32)
6329 #undef DO_CRC32
6332 * Miscellaneous instructions
6335 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
6337 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6338 return false;
6340 gen_mrs_banked(s, a->r, a->sysm, a->rd);
6341 return true;
6344 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
6346 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6347 return false;
6349 gen_msr_banked(s, a->r, a->sysm, a->rn);
6350 return true;
6353 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
6355 TCGv_i32 tmp;
6357 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6358 return false;
6360 if (a->r) {
6361 if (IS_USER(s)) {
6362 unallocated_encoding(s);
6363 return true;
6365 tmp = load_cpu_field(spsr);
6366 } else {
6367 tmp = tcg_temp_new_i32();
6368 gen_helper_cpsr_read(tmp, cpu_env);
6370 store_reg(s, a->rd, tmp);
6371 return true;
6374 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
6376 TCGv_i32 tmp;
6377 uint32_t mask = msr_mask(s, a->mask, a->r);
6379 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6380 return false;
6382 tmp = load_reg(s, a->rn);
6383 if (gen_set_psr(s, mask, a->r, tmp)) {
6384 unallocated_encoding(s);
6386 return true;
6389 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
6391 TCGv_i32 tmp;
6393 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
6394 return false;
6396 tmp = tcg_temp_new_i32();
6397 gen_helper_v7m_mrs(tmp, cpu_env, tcg_constant_i32(a->sysm));
6398 store_reg(s, a->rd, tmp);
6399 return true;
6402 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
6404 TCGv_i32 addr, reg;
6406 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
6407 return false;
6409 addr = tcg_constant_i32((a->mask << 10) | a->sysm);
6410 reg = load_reg(s, a->rn);
6411 gen_helper_v7m_msr(cpu_env, addr, reg);
6412 tcg_temp_free_i32(reg);
6413 /* If we wrote to CONTROL, the EL might have changed */
6414 gen_rebuild_hflags(s, true);
6415 gen_lookup_tb(s);
6416 return true;
6419 static bool trans_BX(DisasContext *s, arg_BX *a)
6421 if (!ENABLE_ARCH_4T) {
6422 return false;
6424 gen_bx_excret(s, load_reg(s, a->rm));
6425 return true;
6428 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
6430 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
6431 return false;
6434 * v7A allows BXJ to be trapped via HSTR.TJDBX. We don't waste a
6435 * TBFLAGS bit on a basically-never-happens case, so call a helper
6436 * function to check for the trap and raise the exception if needed
6437 * (passing it the register number for the syndrome value).
6438 * v8A doesn't have this HSTR bit.
6440 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
6441 arm_dc_feature(s, ARM_FEATURE_EL2) &&
6442 s->current_el < 2 && s->ns) {
6443 gen_helper_check_bxj_trap(cpu_env, tcg_constant_i32(a->rm));
6445 /* Trivial implementation equivalent to bx. */
6446 gen_bx(s, load_reg(s, a->rm));
6447 return true;
6450 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
6452 TCGv_i32 tmp;
6454 if (!ENABLE_ARCH_5) {
6455 return false;
6457 tmp = load_reg(s, a->rm);
6458 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
6459 gen_bx(s, tmp);
6460 return true;
6464 * BXNS/BLXNS: only exist for v8M with the security extensions,
6465 * and always UNDEF if NonSecure. We don't implement these in
6466 * the user-only mode either (in theory you can use them from
6467 * Secure User mode but they are too tied in to system emulation).
6469 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
6471 if (!s->v8m_secure || IS_USER_ONLY) {
6472 unallocated_encoding(s);
6473 } else {
6474 gen_bxns(s, a->rm);
6476 return true;
6479 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
6481 if (!s->v8m_secure || IS_USER_ONLY) {
6482 unallocated_encoding(s);
6483 } else {
6484 gen_blxns(s, a->rm);
6486 return true;
6489 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
6491 TCGv_i32 tmp;
6493 if (!ENABLE_ARCH_5) {
6494 return false;
6496 tmp = load_reg(s, a->rm);
6497 tcg_gen_clzi_i32(tmp, tmp, 32);
6498 store_reg(s, a->rd, tmp);
6499 return true;
6502 static bool trans_ERET(DisasContext *s, arg_ERET *a)
6504 TCGv_i32 tmp;
6506 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
6507 return false;
6509 if (IS_USER(s)) {
6510 unallocated_encoding(s);
6511 return true;
6513 if (s->current_el == 2) {
6514 /* ERET from Hyp uses ELR_Hyp, not LR */
6515 tmp = load_cpu_field(elr_el[2]);
6516 } else {
6517 tmp = load_reg(s, 14);
6519 gen_exception_return(s, tmp);
6520 return true;
6523 static bool trans_HLT(DisasContext *s, arg_HLT *a)
6525 gen_hlt(s, a->imm);
6526 return true;
6529 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
6531 if (!ENABLE_ARCH_5) {
6532 return false;
6534 /* BKPT is OK with ECI set and leaves it untouched */
6535 s->eci_handled = true;
6536 if (arm_dc_feature(s, ARM_FEATURE_M) &&
6537 semihosting_enabled() &&
6538 #ifndef CONFIG_USER_ONLY
6539 !IS_USER(s) &&
6540 #endif
6541 (a->imm == 0xab)) {
6542 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
6543 } else {
6544 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
6546 return true;
6549 static bool trans_HVC(DisasContext *s, arg_HVC *a)
6551 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
6552 return false;
6554 if (IS_USER(s)) {
6555 unallocated_encoding(s);
6556 } else {
6557 gen_hvc(s, a->imm);
6559 return true;
6562 static bool trans_SMC(DisasContext *s, arg_SMC *a)
6564 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
6565 return false;
6567 if (IS_USER(s)) {
6568 unallocated_encoding(s);
6569 } else {
6570 gen_smc(s);
6572 return true;
6575 static bool trans_SG(DisasContext *s, arg_SG *a)
6577 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
6578 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6579 return false;
6582 * SG (v8M only)
6583 * The bulk of the behaviour for this instruction is implemented
6584 * in v7m_handle_execute_nsc(), which deals with the insn when
6585 * it is executed by a CPU in non-secure state from memory
6586 * which is Secure & NonSecure-Callable.
6587 * Here we only need to handle the remaining cases:
6588 * * in NS memory (including the "security extension not
6589 * implemented" case) : NOP
6590 * * in S memory but CPU already secure (clear IT bits)
6591 * We know that the attribute for the memory this insn is
6592 * in must match the current CPU state, because otherwise
6593 * get_phys_addr_pmsav8 would have generated an exception.
6595 if (s->v8m_secure) {
6596 /* Like the IT insn, we don't need to generate any code */
6597 s->condexec_cond = 0;
6598 s->condexec_mask = 0;
6600 return true;
6603 static bool trans_TT(DisasContext *s, arg_TT *a)
6605 TCGv_i32 addr, tmp;
6607 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
6608 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6609 return false;
6611 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
6612 /* We UNDEF for these UNPREDICTABLE cases */
6613 unallocated_encoding(s);
6614 return true;
6616 if (a->A && !s->v8m_secure) {
6617 /* This case is UNDEFINED. */
6618 unallocated_encoding(s);
6619 return true;
6622 addr = load_reg(s, a->rn);
6623 tmp = tcg_temp_new_i32();
6624 gen_helper_v7m_tt(tmp, cpu_env, addr, tcg_constant_i32((a->A << 1) | a->T));
6625 tcg_temp_free_i32(addr);
6626 store_reg(s, a->rd, tmp);
6627 return true;
6631 * Load/store register index
6634 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
6636 ISSInfo ret;
6638 /* ISS not valid if writeback */
6639 if (p && !w) {
6640 ret = rd;
6641 if (s->base.pc_next - s->pc_curr == 2) {
6642 ret |= ISSIs16Bit;
6644 } else {
6645 ret = ISSInvalid;
6647 return ret;
6650 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
6652 TCGv_i32 addr = load_reg(s, a->rn);
6654 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
6655 gen_helper_v8m_stackcheck(cpu_env, addr);
6658 if (a->p) {
6659 TCGv_i32 ofs = load_reg(s, a->rm);
6660 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
6661 if (a->u) {
6662 tcg_gen_add_i32(addr, addr, ofs);
6663 } else {
6664 tcg_gen_sub_i32(addr, addr, ofs);
6666 tcg_temp_free_i32(ofs);
6668 return addr;
6671 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
6672 TCGv_i32 addr, int address_offset)
6674 if (!a->p) {
6675 TCGv_i32 ofs = load_reg(s, a->rm);
6676 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
6677 if (a->u) {
6678 tcg_gen_add_i32(addr, addr, ofs);
6679 } else {
6680 tcg_gen_sub_i32(addr, addr, ofs);
6682 tcg_temp_free_i32(ofs);
6683 } else if (!a->w) {
6684 tcg_temp_free_i32(addr);
6685 return;
6687 tcg_gen_addi_i32(addr, addr, address_offset);
6688 store_reg(s, a->rn, addr);
6691 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
6692 MemOp mop, int mem_idx)
6694 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
6695 TCGv_i32 addr, tmp;
6697 addr = op_addr_rr_pre(s, a);
6699 tmp = tcg_temp_new_i32();
6700 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
6701 disas_set_da_iss(s, mop, issinfo);
6704 * Perform base writeback before the loaded value to
6705 * ensure correct behavior with overlapping index registers.
6707 op_addr_rr_post(s, a, addr, 0);
6708 store_reg_from_load(s, a->rt, tmp);
6709 return true;
6712 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
6713 MemOp mop, int mem_idx)
6715 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
6716 TCGv_i32 addr, tmp;
6719 * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
6720 * is either UNPREDICTABLE or has defined behaviour
6722 if (s->thumb && a->rn == 15) {
6723 return false;
6726 addr = op_addr_rr_pre(s, a);
6728 tmp = load_reg(s, a->rt);
6729 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
6730 disas_set_da_iss(s, mop, issinfo);
6731 tcg_temp_free_i32(tmp);
6733 op_addr_rr_post(s, a, addr, 0);
6734 return true;
6737 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
6739 int mem_idx = get_mem_index(s);
6740 TCGv_i32 addr, tmp;
6742 if (!ENABLE_ARCH_5TE) {
6743 return false;
6745 if (a->rt & 1) {
6746 unallocated_encoding(s);
6747 return true;
6749 addr = op_addr_rr_pre(s, a);
6751 tmp = tcg_temp_new_i32();
6752 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6753 store_reg(s, a->rt, tmp);
6755 tcg_gen_addi_i32(addr, addr, 4);
6757 tmp = tcg_temp_new_i32();
6758 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6759 store_reg(s, a->rt + 1, tmp);
6761 /* LDRD w/ base writeback is undefined if the registers overlap. */
6762 op_addr_rr_post(s, a, addr, -4);
6763 return true;
6766 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
6768 int mem_idx = get_mem_index(s);
6769 TCGv_i32 addr, tmp;
6771 if (!ENABLE_ARCH_5TE) {
6772 return false;
6774 if (a->rt & 1) {
6775 unallocated_encoding(s);
6776 return true;
6778 addr = op_addr_rr_pre(s, a);
6780 tmp = load_reg(s, a->rt);
6781 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6782 tcg_temp_free_i32(tmp);
6784 tcg_gen_addi_i32(addr, addr, 4);
6786 tmp = load_reg(s, a->rt + 1);
6787 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6788 tcg_temp_free_i32(tmp);
6790 op_addr_rr_post(s, a, addr, -4);
6791 return true;
6795 * Load/store immediate index
6798 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
6800 int ofs = a->imm;
6802 if (!a->u) {
6803 ofs = -ofs;
6806 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
6808 * Stackcheck. Here we know 'addr' is the current SP;
6809 * U is set if we're moving SP up, else down. It is
6810 * UNKNOWN whether the limit check triggers when SP starts
6811 * below the limit and ends up above it; we chose to do so.
6813 if (!a->u) {
6814 TCGv_i32 newsp = tcg_temp_new_i32();
6815 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
6816 gen_helper_v8m_stackcheck(cpu_env, newsp);
6817 tcg_temp_free_i32(newsp);
6818 } else {
6819 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
6823 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
6826 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
6827 TCGv_i32 addr, int address_offset)
6829 if (!a->p) {
6830 if (a->u) {
6831 address_offset += a->imm;
6832 } else {
6833 address_offset -= a->imm;
6835 } else if (!a->w) {
6836 tcg_temp_free_i32(addr);
6837 return;
6839 tcg_gen_addi_i32(addr, addr, address_offset);
6840 store_reg(s, a->rn, addr);
6843 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
6844 MemOp mop, int mem_idx)
6846 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
6847 TCGv_i32 addr, tmp;
6849 addr = op_addr_ri_pre(s, a);
6851 tmp = tcg_temp_new_i32();
6852 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
6853 disas_set_da_iss(s, mop, issinfo);
6856 * Perform base writeback before the loaded value to
6857 * ensure correct behavior with overlapping index registers.
6859 op_addr_ri_post(s, a, addr, 0);
6860 store_reg_from_load(s, a->rt, tmp);
6861 return true;
6864 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
6865 MemOp mop, int mem_idx)
6867 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
6868 TCGv_i32 addr, tmp;
6871 * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
6872 * is either UNPREDICTABLE or has defined behaviour
6874 if (s->thumb && a->rn == 15) {
6875 return false;
6878 addr = op_addr_ri_pre(s, a);
6880 tmp = load_reg(s, a->rt);
6881 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
6882 disas_set_da_iss(s, mop, issinfo);
6883 tcg_temp_free_i32(tmp);
6885 op_addr_ri_post(s, a, addr, 0);
6886 return true;
6889 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
6891 int mem_idx = get_mem_index(s);
6892 TCGv_i32 addr, tmp;
6894 addr = op_addr_ri_pre(s, a);
6896 tmp = tcg_temp_new_i32();
6897 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6898 store_reg(s, a->rt, tmp);
6900 tcg_gen_addi_i32(addr, addr, 4);
6902 tmp = tcg_temp_new_i32();
6903 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6904 store_reg(s, rt2, tmp);
6906 /* LDRD w/ base writeback is undefined if the registers overlap. */
6907 op_addr_ri_post(s, a, addr, -4);
6908 return true;
6911 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
6913 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
6914 return false;
6916 return op_ldrd_ri(s, a, a->rt + 1);
6919 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
6921 arg_ldst_ri b = {
6922 .u = a->u, .w = a->w, .p = a->p,
6923 .rn = a->rn, .rt = a->rt, .imm = a->imm
6925 return op_ldrd_ri(s, &b, a->rt2);
6928 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
6930 int mem_idx = get_mem_index(s);
6931 TCGv_i32 addr, tmp;
6933 addr = op_addr_ri_pre(s, a);
6935 tmp = load_reg(s, a->rt);
6936 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6937 tcg_temp_free_i32(tmp);
6939 tcg_gen_addi_i32(addr, addr, 4);
6941 tmp = load_reg(s, rt2);
6942 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6943 tcg_temp_free_i32(tmp);
6945 op_addr_ri_post(s, a, addr, -4);
6946 return true;
6949 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
6951 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
6952 return false;
6954 return op_strd_ri(s, a, a->rt + 1);
6957 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
6959 arg_ldst_ri b = {
6960 .u = a->u, .w = a->w, .p = a->p,
6961 .rn = a->rn, .rt = a->rt, .imm = a->imm
6963 return op_strd_ri(s, &b, a->rt2);
6966 #define DO_LDST(NAME, WHICH, MEMOP) \
6967 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
6969 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
6971 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
6973 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
6975 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
6977 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
6979 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
6981 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
6984 DO_LDST(LDR, load, MO_UL)
6985 DO_LDST(LDRB, load, MO_UB)
6986 DO_LDST(LDRH, load, MO_UW)
6987 DO_LDST(LDRSB, load, MO_SB)
6988 DO_LDST(LDRSH, load, MO_SW)
6990 DO_LDST(STR, store, MO_UL)
6991 DO_LDST(STRB, store, MO_UB)
6992 DO_LDST(STRH, store, MO_UW)
6994 #undef DO_LDST
6997 * Synchronization primitives
7000 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
7002 TCGv_i32 addr, tmp;
7003 TCGv taddr;
7005 opc |= s->be_data;
7006 addr = load_reg(s, a->rn);
7007 taddr = gen_aa32_addr(s, addr, opc);
7008 tcg_temp_free_i32(addr);
7010 tmp = load_reg(s, a->rt2);
7011 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
7012 tcg_temp_free(taddr);
7014 store_reg(s, a->rt, tmp);
7015 return true;
7018 static bool trans_SWP(DisasContext *s, arg_SWP *a)
7020 return op_swp(s, a, MO_UL | MO_ALIGN);
7023 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
7025 return op_swp(s, a, MO_UB);
7029 * Load/Store Exclusive and Load-Acquire/Store-Release
7032 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
7034 TCGv_i32 addr;
7035 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
7036 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
7038 /* We UNDEF for these UNPREDICTABLE cases. */
7039 if (a->rd == 15 || a->rn == 15 || a->rt == 15
7040 || a->rd == a->rn || a->rd == a->rt
7041 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
7042 || (mop == MO_64
7043 && (a->rt2 == 15
7044 || a->rd == a->rt2
7045 || (!v8a && s->thumb && a->rt2 == 13)))) {
7046 unallocated_encoding(s);
7047 return true;
7050 if (rel) {
7051 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7054 addr = tcg_temp_local_new_i32();
7055 load_reg_var(s, addr, a->rn);
7056 tcg_gen_addi_i32(addr, addr, a->imm);
7058 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
7059 tcg_temp_free_i32(addr);
7060 return true;
7063 static bool trans_STREX(DisasContext *s, arg_STREX *a)
7065 if (!ENABLE_ARCH_6) {
7066 return false;
7068 return op_strex(s, a, MO_32, false);
7071 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
7073 if (!ENABLE_ARCH_6K) {
7074 return false;
7076 /* We UNDEF for these UNPREDICTABLE cases. */
7077 if (a->rt & 1) {
7078 unallocated_encoding(s);
7079 return true;
7081 a->rt2 = a->rt + 1;
7082 return op_strex(s, a, MO_64, false);
7085 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
7087 return op_strex(s, a, MO_64, false);
7090 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
7092 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7093 return false;
7095 return op_strex(s, a, MO_8, false);
7098 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
7100 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7101 return false;
7103 return op_strex(s, a, MO_16, false);
7106 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
7108 if (!ENABLE_ARCH_8) {
7109 return false;
7111 return op_strex(s, a, MO_32, true);
7114 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
7116 if (!ENABLE_ARCH_8) {
7117 return false;
7119 /* We UNDEF for these UNPREDICTABLE cases. */
7120 if (a->rt & 1) {
7121 unallocated_encoding(s);
7122 return true;
7124 a->rt2 = a->rt + 1;
7125 return op_strex(s, a, MO_64, true);
7128 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
7130 if (!ENABLE_ARCH_8) {
7131 return false;
7133 return op_strex(s, a, MO_64, true);
7136 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
7138 if (!ENABLE_ARCH_8) {
7139 return false;
7141 return op_strex(s, a, MO_8, true);
7144 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
7146 if (!ENABLE_ARCH_8) {
7147 return false;
7149 return op_strex(s, a, MO_16, true);
7152 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
7154 TCGv_i32 addr, tmp;
7156 if (!ENABLE_ARCH_8) {
7157 return false;
7159 /* We UNDEF for these UNPREDICTABLE cases. */
7160 if (a->rn == 15 || a->rt == 15) {
7161 unallocated_encoding(s);
7162 return true;
7165 addr = load_reg(s, a->rn);
7166 tmp = load_reg(s, a->rt);
7167 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7168 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
7169 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
7171 tcg_temp_free_i32(tmp);
7172 tcg_temp_free_i32(addr);
7173 return true;
7176 static bool trans_STL(DisasContext *s, arg_STL *a)
7178 return op_stl(s, a, MO_UL);
7181 static bool trans_STLB(DisasContext *s, arg_STL *a)
7183 return op_stl(s, a, MO_UB);
7186 static bool trans_STLH(DisasContext *s, arg_STL *a)
7188 return op_stl(s, a, MO_UW);
7191 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
7193 TCGv_i32 addr;
7194 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
7195 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
7197 /* We UNDEF for these UNPREDICTABLE cases. */
7198 if (a->rn == 15 || a->rt == 15
7199 || (!v8a && s->thumb && a->rt == 13)
7200 || (mop == MO_64
7201 && (a->rt2 == 15 || a->rt == a->rt2
7202 || (!v8a && s->thumb && a->rt2 == 13)))) {
7203 unallocated_encoding(s);
7204 return true;
7207 addr = tcg_temp_local_new_i32();
7208 load_reg_var(s, addr, a->rn);
7209 tcg_gen_addi_i32(addr, addr, a->imm);
7211 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
7212 tcg_temp_free_i32(addr);
7214 if (acq) {
7215 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
7217 return true;
7220 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
7222 if (!ENABLE_ARCH_6) {
7223 return false;
7225 return op_ldrex(s, a, MO_32, false);
7228 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
7230 if (!ENABLE_ARCH_6K) {
7231 return false;
7233 /* We UNDEF for these UNPREDICTABLE cases. */
7234 if (a->rt & 1) {
7235 unallocated_encoding(s);
7236 return true;
7238 a->rt2 = a->rt + 1;
7239 return op_ldrex(s, a, MO_64, false);
7242 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
7244 return op_ldrex(s, a, MO_64, false);
7247 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
7249 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7250 return false;
7252 return op_ldrex(s, a, MO_8, false);
7255 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
7257 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7258 return false;
7260 return op_ldrex(s, a, MO_16, false);
7263 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
7265 if (!ENABLE_ARCH_8) {
7266 return false;
7268 return op_ldrex(s, a, MO_32, true);
7271 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
7273 if (!ENABLE_ARCH_8) {
7274 return false;
7276 /* We UNDEF for these UNPREDICTABLE cases. */
7277 if (a->rt & 1) {
7278 unallocated_encoding(s);
7279 return true;
7281 a->rt2 = a->rt + 1;
7282 return op_ldrex(s, a, MO_64, true);
7285 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
7287 if (!ENABLE_ARCH_8) {
7288 return false;
7290 return op_ldrex(s, a, MO_64, true);
7293 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
7295 if (!ENABLE_ARCH_8) {
7296 return false;
7298 return op_ldrex(s, a, MO_8, true);
7301 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
7303 if (!ENABLE_ARCH_8) {
7304 return false;
7306 return op_ldrex(s, a, MO_16, true);
7309 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
7311 TCGv_i32 addr, tmp;
7313 if (!ENABLE_ARCH_8) {
7314 return false;
7316 /* We UNDEF for these UNPREDICTABLE cases. */
7317 if (a->rn == 15 || a->rt == 15) {
7318 unallocated_encoding(s);
7319 return true;
7322 addr = load_reg(s, a->rn);
7323 tmp = tcg_temp_new_i32();
7324 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
7325 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
7326 tcg_temp_free_i32(addr);
7328 store_reg(s, a->rt, tmp);
7329 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7330 return true;
7333 static bool trans_LDA(DisasContext *s, arg_LDA *a)
7335 return op_lda(s, a, MO_UL);
7338 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
7340 return op_lda(s, a, MO_UB);
7343 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
7345 return op_lda(s, a, MO_UW);
7349 * Media instructions
7352 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
7354 TCGv_i32 t1, t2;
7356 if (!ENABLE_ARCH_6) {
7357 return false;
7360 t1 = load_reg(s, a->rn);
7361 t2 = load_reg(s, a->rm);
7362 gen_helper_usad8(t1, t1, t2);
7363 tcg_temp_free_i32(t2);
7364 if (a->ra != 15) {
7365 t2 = load_reg(s, a->ra);
7366 tcg_gen_add_i32(t1, t1, t2);
7367 tcg_temp_free_i32(t2);
7369 store_reg(s, a->rd, t1);
7370 return true;
7373 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
7375 TCGv_i32 tmp;
7376 int width = a->widthm1 + 1;
7377 int shift = a->lsb;
7379 if (!ENABLE_ARCH_6T2) {
7380 return false;
7382 if (shift + width > 32) {
7383 /* UNPREDICTABLE; we choose to UNDEF */
7384 unallocated_encoding(s);
7385 return true;
7388 tmp = load_reg(s, a->rn);
7389 if (u) {
7390 tcg_gen_extract_i32(tmp, tmp, shift, width);
7391 } else {
7392 tcg_gen_sextract_i32(tmp, tmp, shift, width);
7394 store_reg(s, a->rd, tmp);
7395 return true;
7398 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
7400 return op_bfx(s, a, false);
7403 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
7405 return op_bfx(s, a, true);
7408 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
7410 TCGv_i32 tmp;
7411 int msb = a->msb, lsb = a->lsb;
7412 int width;
7414 if (!ENABLE_ARCH_6T2) {
7415 return false;
7417 if (msb < lsb) {
7418 /* UNPREDICTABLE; we choose to UNDEF */
7419 unallocated_encoding(s);
7420 return true;
7423 width = msb + 1 - lsb;
7424 if (a->rn == 15) {
7425 /* BFC */
7426 tmp = tcg_const_i32(0);
7427 } else {
7428 /* BFI */
7429 tmp = load_reg(s, a->rn);
7431 if (width != 32) {
7432 TCGv_i32 tmp2 = load_reg(s, a->rd);
7433 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
7434 tcg_temp_free_i32(tmp2);
7436 store_reg(s, a->rd, tmp);
7437 return true;
7440 static bool trans_UDF(DisasContext *s, arg_UDF *a)
7442 unallocated_encoding(s);
7443 return true;
7447 * Parallel addition and subtraction
7450 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
7451 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
7453 TCGv_i32 t0, t1;
7455 if (s->thumb
7456 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7457 : !ENABLE_ARCH_6) {
7458 return false;
7461 t0 = load_reg(s, a->rn);
7462 t1 = load_reg(s, a->rm);
7464 gen(t0, t0, t1);
7466 tcg_temp_free_i32(t1);
7467 store_reg(s, a->rd, t0);
7468 return true;
7471 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
7472 void (*gen)(TCGv_i32, TCGv_i32,
7473 TCGv_i32, TCGv_ptr))
7475 TCGv_i32 t0, t1;
7476 TCGv_ptr ge;
7478 if (s->thumb
7479 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7480 : !ENABLE_ARCH_6) {
7481 return false;
7484 t0 = load_reg(s, a->rn);
7485 t1 = load_reg(s, a->rm);
7487 ge = tcg_temp_new_ptr();
7488 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
7489 gen(t0, t0, t1, ge);
7491 tcg_temp_free_ptr(ge);
7492 tcg_temp_free_i32(t1);
7493 store_reg(s, a->rd, t0);
7494 return true;
7497 #define DO_PAR_ADDSUB(NAME, helper) \
7498 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7500 return op_par_addsub(s, a, helper); \
7503 #define DO_PAR_ADDSUB_GE(NAME, helper) \
7504 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7506 return op_par_addsub_ge(s, a, helper); \
7509 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
7510 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
7511 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
7512 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
7513 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
7514 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
7516 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
7517 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
7518 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
7519 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
7520 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
7521 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
7523 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
7524 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
7525 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
7526 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
7527 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
7528 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
7530 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
7531 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
7532 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
7533 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
7534 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
7535 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
7537 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
7538 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
7539 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
7540 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
7541 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
7542 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
7544 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
7545 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
7546 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
7547 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
7548 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
7549 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
7551 #undef DO_PAR_ADDSUB
7552 #undef DO_PAR_ADDSUB_GE
7555 * Packing, unpacking, saturation, and reversal
7558 static bool trans_PKH(DisasContext *s, arg_PKH *a)
7560 TCGv_i32 tn, tm;
7561 int shift = a->imm;
7563 if (s->thumb
7564 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7565 : !ENABLE_ARCH_6) {
7566 return false;
7569 tn = load_reg(s, a->rn);
7570 tm = load_reg(s, a->rm);
7571 if (a->tb) {
7572 /* PKHTB */
7573 if (shift == 0) {
7574 shift = 31;
7576 tcg_gen_sari_i32(tm, tm, shift);
7577 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
7578 } else {
7579 /* PKHBT */
7580 tcg_gen_shli_i32(tm, tm, shift);
7581 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
7583 tcg_temp_free_i32(tm);
7584 store_reg(s, a->rd, tn);
7585 return true;
7588 static bool op_sat(DisasContext *s, arg_sat *a,
7589 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
7591 TCGv_i32 tmp;
7592 int shift = a->imm;
7594 if (!ENABLE_ARCH_6) {
7595 return false;
7598 tmp = load_reg(s, a->rn);
7599 if (a->sh) {
7600 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
7601 } else {
7602 tcg_gen_shli_i32(tmp, tmp, shift);
7605 gen(tmp, cpu_env, tmp, tcg_constant_i32(a->satimm));
7607 store_reg(s, a->rd, tmp);
7608 return true;
7611 static bool trans_SSAT(DisasContext *s, arg_sat *a)
7613 return op_sat(s, a, gen_helper_ssat);
7616 static bool trans_USAT(DisasContext *s, arg_sat *a)
7618 return op_sat(s, a, gen_helper_usat);
7621 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
7623 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7624 return false;
7626 return op_sat(s, a, gen_helper_ssat16);
7629 static bool trans_USAT16(DisasContext *s, arg_sat *a)
7631 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7632 return false;
7634 return op_sat(s, a, gen_helper_usat16);
7637 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
7638 void (*gen_extract)(TCGv_i32, TCGv_i32),
7639 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
7641 TCGv_i32 tmp;
7643 if (!ENABLE_ARCH_6) {
7644 return false;
7647 tmp = load_reg(s, a->rm);
7649 * TODO: In many cases we could do a shift instead of a rotate.
7650 * Combined with a simple extend, that becomes an extract.
7652 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
7653 gen_extract(tmp, tmp);
7655 if (a->rn != 15) {
7656 TCGv_i32 tmp2 = load_reg(s, a->rn);
7657 gen_add(tmp, tmp, tmp2);
7658 tcg_temp_free_i32(tmp2);
7660 store_reg(s, a->rd, tmp);
7661 return true;
7664 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
7666 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
7669 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
7671 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
7674 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
7676 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7677 return false;
7679 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
7682 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
7684 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
7687 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
7689 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
7692 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
7694 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7695 return false;
7697 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
7700 static bool trans_SEL(DisasContext *s, arg_rrr *a)
7702 TCGv_i32 t1, t2, t3;
7704 if (s->thumb
7705 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7706 : !ENABLE_ARCH_6) {
7707 return false;
7710 t1 = load_reg(s, a->rn);
7711 t2 = load_reg(s, a->rm);
7712 t3 = tcg_temp_new_i32();
7713 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
7714 gen_helper_sel_flags(t1, t3, t1, t2);
7715 tcg_temp_free_i32(t3);
7716 tcg_temp_free_i32(t2);
7717 store_reg(s, a->rd, t1);
7718 return true;
7721 static bool op_rr(DisasContext *s, arg_rr *a,
7722 void (*gen)(TCGv_i32, TCGv_i32))
7724 TCGv_i32 tmp;
7726 tmp = load_reg(s, a->rm);
7727 gen(tmp, tmp);
7728 store_reg(s, a->rd, tmp);
7729 return true;
7732 static bool trans_REV(DisasContext *s, arg_rr *a)
7734 if (!ENABLE_ARCH_6) {
7735 return false;
7737 return op_rr(s, a, tcg_gen_bswap32_i32);
7740 static bool trans_REV16(DisasContext *s, arg_rr *a)
7742 if (!ENABLE_ARCH_6) {
7743 return false;
7745 return op_rr(s, a, gen_rev16);
7748 static bool trans_REVSH(DisasContext *s, arg_rr *a)
7750 if (!ENABLE_ARCH_6) {
7751 return false;
7753 return op_rr(s, a, gen_revsh);
7756 static bool trans_RBIT(DisasContext *s, arg_rr *a)
7758 if (!ENABLE_ARCH_6T2) {
7759 return false;
7761 return op_rr(s, a, gen_helper_rbit);
7765 * Signed multiply, signed and unsigned divide
7768 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
7770 TCGv_i32 t1, t2;
7772 if (!ENABLE_ARCH_6) {
7773 return false;
7776 t1 = load_reg(s, a->rn);
7777 t2 = load_reg(s, a->rm);
7778 if (m_swap) {
7779 gen_swap_half(t2, t2);
7781 gen_smul_dual(t1, t2);
7783 if (sub) {
7785 * This subtraction cannot overflow, so we can do a simple
7786 * 32-bit subtraction and then a possible 32-bit saturating
7787 * addition of Ra.
7789 tcg_gen_sub_i32(t1, t1, t2);
7790 tcg_temp_free_i32(t2);
7792 if (a->ra != 15) {
7793 t2 = load_reg(s, a->ra);
7794 gen_helper_add_setq(t1, cpu_env, t1, t2);
7795 tcg_temp_free_i32(t2);
7797 } else if (a->ra == 15) {
7798 /* Single saturation-checking addition */
7799 gen_helper_add_setq(t1, cpu_env, t1, t2);
7800 tcg_temp_free_i32(t2);
7801 } else {
7803 * We need to add the products and Ra together and then
7804 * determine whether the final result overflowed. Doing
7805 * this as two separate add-and-check-overflow steps incorrectly
7806 * sets Q for cases like (-32768 * -32768) + (-32768 * -32768) + -1.
7807 * Do all the arithmetic at 64-bits and then check for overflow.
7809 TCGv_i64 p64, q64;
7810 TCGv_i32 t3, qf, one;
7812 p64 = tcg_temp_new_i64();
7813 q64 = tcg_temp_new_i64();
7814 tcg_gen_ext_i32_i64(p64, t1);
7815 tcg_gen_ext_i32_i64(q64, t2);
7816 tcg_gen_add_i64(p64, p64, q64);
7817 load_reg_var(s, t2, a->ra);
7818 tcg_gen_ext_i32_i64(q64, t2);
7819 tcg_gen_add_i64(p64, p64, q64);
7820 tcg_temp_free_i64(q64);
7822 tcg_gen_extr_i64_i32(t1, t2, p64);
7823 tcg_temp_free_i64(p64);
7825 * t1 is the low half of the result which goes into Rd.
7826 * We have overflow and must set Q if the high half (t2)
7827 * is different from the sign-extension of t1.
7829 t3 = tcg_temp_new_i32();
7830 tcg_gen_sari_i32(t3, t1, 31);
7831 qf = load_cpu_field(QF);
7832 one = tcg_constant_i32(1);
7833 tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
7834 store_cpu_field(qf, QF);
7835 tcg_temp_free_i32(t3);
7836 tcg_temp_free_i32(t2);
7838 store_reg(s, a->rd, t1);
7839 return true;
7842 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
7844 return op_smlad(s, a, false, false);
7847 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
7849 return op_smlad(s, a, true, false);
7852 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
7854 return op_smlad(s, a, false, true);
7857 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
7859 return op_smlad(s, a, true, true);
7862 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
7864 TCGv_i32 t1, t2;
7865 TCGv_i64 l1, l2;
7867 if (!ENABLE_ARCH_6) {
7868 return false;
7871 t1 = load_reg(s, a->rn);
7872 t2 = load_reg(s, a->rm);
7873 if (m_swap) {
7874 gen_swap_half(t2, t2);
7876 gen_smul_dual(t1, t2);
7878 l1 = tcg_temp_new_i64();
7879 l2 = tcg_temp_new_i64();
7880 tcg_gen_ext_i32_i64(l1, t1);
7881 tcg_gen_ext_i32_i64(l2, t2);
7882 tcg_temp_free_i32(t1);
7883 tcg_temp_free_i32(t2);
7885 if (sub) {
7886 tcg_gen_sub_i64(l1, l1, l2);
7887 } else {
7888 tcg_gen_add_i64(l1, l1, l2);
7890 tcg_temp_free_i64(l2);
7892 gen_addq(s, l1, a->ra, a->rd);
7893 gen_storeq_reg(s, a->ra, a->rd, l1);
7894 tcg_temp_free_i64(l1);
7895 return true;
7898 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
7900 return op_smlald(s, a, false, false);
7903 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
7905 return op_smlald(s, a, true, false);
7908 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
7910 return op_smlald(s, a, false, true);
7913 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
7915 return op_smlald(s, a, true, true);
7918 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
7920 TCGv_i32 t1, t2;
7922 if (s->thumb
7923 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7924 : !ENABLE_ARCH_6) {
7925 return false;
7928 t1 = load_reg(s, a->rn);
7929 t2 = load_reg(s, a->rm);
7930 tcg_gen_muls2_i32(t2, t1, t1, t2);
7932 if (a->ra != 15) {
7933 TCGv_i32 t3 = load_reg(s, a->ra);
7934 if (sub) {
7936 * For SMMLS, we need a 64-bit subtract. Borrow caused by
7937 * a non-zero multiplicand lowpart, and the correct result
7938 * lowpart for rounding.
7940 tcg_gen_sub2_i32(t2, t1, tcg_constant_i32(0), t3, t2, t1);
7941 } else {
7942 tcg_gen_add_i32(t1, t1, t3);
7944 tcg_temp_free_i32(t3);
7946 if (round) {
7948 * Adding 0x80000000 to the 64-bit quantity means that we have
7949 * carry in to the high word when the low word has the msb set.
7951 tcg_gen_shri_i32(t2, t2, 31);
7952 tcg_gen_add_i32(t1, t1, t2);
7954 tcg_temp_free_i32(t2);
7955 store_reg(s, a->rd, t1);
7956 return true;
7959 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
7961 return op_smmla(s, a, false, false);
7964 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
7966 return op_smmla(s, a, true, false);
7969 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
7971 return op_smmla(s, a, false, true);
7974 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
7976 return op_smmla(s, a, true, true);
7979 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
7981 TCGv_i32 t1, t2;
7983 if (s->thumb
7984 ? !dc_isar_feature(aa32_thumb_div, s)
7985 : !dc_isar_feature(aa32_arm_div, s)) {
7986 return false;
7989 t1 = load_reg(s, a->rn);
7990 t2 = load_reg(s, a->rm);
7991 if (u) {
7992 gen_helper_udiv(t1, cpu_env, t1, t2);
7993 } else {
7994 gen_helper_sdiv(t1, cpu_env, t1, t2);
7996 tcg_temp_free_i32(t2);
7997 store_reg(s, a->rd, t1);
7998 return true;
8001 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
8003 return op_div(s, a, false);
8006 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
8008 return op_div(s, a, true);
8012 * Block data transfer
8015 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
8017 TCGv_i32 addr = load_reg(s, a->rn);
8019 if (a->b) {
8020 if (a->i) {
8021 /* pre increment */
8022 tcg_gen_addi_i32(addr, addr, 4);
8023 } else {
8024 /* pre decrement */
8025 tcg_gen_addi_i32(addr, addr, -(n * 4));
8027 } else if (!a->i && n != 1) {
8028 /* post decrement */
8029 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8032 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8034 * If the writeback is incrementing SP rather than
8035 * decrementing it, and the initial SP is below the
8036 * stack limit but the final written-back SP would
8037 * be above, then then we must not perform any memory
8038 * accesses, but it is IMPDEF whether we generate
8039 * an exception. We choose to do so in this case.
8040 * At this point 'addr' is the lowest address, so
8041 * either the original SP (if incrementing) or our
8042 * final SP (if decrementing), so that's what we check.
8044 gen_helper_v8m_stackcheck(cpu_env, addr);
8047 return addr;
8050 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
8051 TCGv_i32 addr, int n)
8053 if (a->w) {
8054 /* write back */
8055 if (!a->b) {
8056 if (a->i) {
8057 /* post increment */
8058 tcg_gen_addi_i32(addr, addr, 4);
8059 } else {
8060 /* post decrement */
8061 tcg_gen_addi_i32(addr, addr, -(n * 4));
8063 } else if (!a->i && n != 1) {
8064 /* pre decrement */
8065 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8067 store_reg(s, a->rn, addr);
8068 } else {
8069 tcg_temp_free_i32(addr);
8073 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
8075 int i, j, n, list, mem_idx;
8076 bool user = a->u;
8077 TCGv_i32 addr, tmp;
8079 if (user) {
8080 /* STM (user) */
8081 if (IS_USER(s)) {
8082 /* Only usable in supervisor mode. */
8083 unallocated_encoding(s);
8084 return true;
8088 list = a->list;
8089 n = ctpop16(list);
8090 if (n < min_n || a->rn == 15) {
8091 unallocated_encoding(s);
8092 return true;
8095 s->eci_handled = true;
8097 addr = op_addr_block_pre(s, a, n);
8098 mem_idx = get_mem_index(s);
8100 for (i = j = 0; i < 16; i++) {
8101 if (!(list & (1 << i))) {
8102 continue;
8105 if (user && i != 15) {
8106 tmp = tcg_temp_new_i32();
8107 gen_helper_get_user_reg(tmp, cpu_env, tcg_constant_i32(i));
8108 } else {
8109 tmp = load_reg(s, i);
8111 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
8112 tcg_temp_free_i32(tmp);
8114 /* No need to add after the last transfer. */
8115 if (++j != n) {
8116 tcg_gen_addi_i32(addr, addr, 4);
8120 op_addr_block_post(s, a, addr, n);
8121 clear_eci_state(s);
8122 return true;
8125 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
8127 /* BitCount(list) < 1 is UNPREDICTABLE */
8128 return op_stm(s, a, 1);
8131 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
8133 /* Writeback register in register list is UNPREDICTABLE for T32. */
8134 if (a->w && (a->list & (1 << a->rn))) {
8135 unallocated_encoding(s);
8136 return true;
8138 /* BitCount(list) < 2 is UNPREDICTABLE */
8139 return op_stm(s, a, 2);
8142 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
8144 int i, j, n, list, mem_idx;
8145 bool loaded_base;
8146 bool user = a->u;
8147 bool exc_return = false;
8148 TCGv_i32 addr, tmp, loaded_var;
8150 if (user) {
8151 /* LDM (user), LDM (exception return) */
8152 if (IS_USER(s)) {
8153 /* Only usable in supervisor mode. */
8154 unallocated_encoding(s);
8155 return true;
8157 if (extract32(a->list, 15, 1)) {
8158 exc_return = true;
8159 user = false;
8160 } else {
8161 /* LDM (user) does not allow writeback. */
8162 if (a->w) {
8163 unallocated_encoding(s);
8164 return true;
8169 list = a->list;
8170 n = ctpop16(list);
8171 if (n < min_n || a->rn == 15) {
8172 unallocated_encoding(s);
8173 return true;
8176 s->eci_handled = true;
8178 addr = op_addr_block_pre(s, a, n);
8179 mem_idx = get_mem_index(s);
8180 loaded_base = false;
8181 loaded_var = NULL;
8183 for (i = j = 0; i < 16; i++) {
8184 if (!(list & (1 << i))) {
8185 continue;
8188 tmp = tcg_temp_new_i32();
8189 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
8190 if (user) {
8191 gen_helper_set_user_reg(cpu_env, tcg_constant_i32(i), tmp);
8192 tcg_temp_free_i32(tmp);
8193 } else if (i == a->rn) {
8194 loaded_var = tmp;
8195 loaded_base = true;
8196 } else if (i == 15 && exc_return) {
8197 store_pc_exc_ret(s, tmp);
8198 } else {
8199 store_reg_from_load(s, i, tmp);
8202 /* No need to add after the last transfer. */
8203 if (++j != n) {
8204 tcg_gen_addi_i32(addr, addr, 4);
8208 op_addr_block_post(s, a, addr, n);
8210 if (loaded_base) {
8211 /* Note that we reject base == pc above. */
8212 store_reg(s, a->rn, loaded_var);
8215 if (exc_return) {
8216 /* Restore CPSR from SPSR. */
8217 tmp = load_cpu_field(spsr);
8218 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
8219 gen_io_start();
8221 gen_helper_cpsr_write_eret(cpu_env, tmp);
8222 tcg_temp_free_i32(tmp);
8223 /* Must exit loop to check un-masked IRQs */
8224 s->base.is_jmp = DISAS_EXIT;
8226 clear_eci_state(s);
8227 return true;
8230 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
8233 * Writeback register in register list is UNPREDICTABLE
8234 * for ArchVersion() >= 7. Prior to v7, A32 would write
8235 * an UNKNOWN value to the base register.
8237 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
8238 unallocated_encoding(s);
8239 return true;
8241 /* BitCount(list) < 1 is UNPREDICTABLE */
8242 return do_ldm(s, a, 1);
8245 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
8247 /* Writeback register in register list is UNPREDICTABLE for T32. */
8248 if (a->w && (a->list & (1 << a->rn))) {
8249 unallocated_encoding(s);
8250 return true;
8252 /* BitCount(list) < 2 is UNPREDICTABLE */
8253 return do_ldm(s, a, 2);
8256 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
8258 /* Writeback is conditional on the base register not being loaded. */
8259 a->w = !(a->list & (1 << a->rn));
8260 /* BitCount(list) < 1 is UNPREDICTABLE */
8261 return do_ldm(s, a, 1);
8264 static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
8266 int i;
8267 TCGv_i32 zero;
8269 if (!dc_isar_feature(aa32_m_sec_state, s)) {
8270 return false;
8273 if (extract32(a->list, 13, 1)) {
8274 return false;
8277 if (!a->list) {
8278 /* UNPREDICTABLE; we choose to UNDEF */
8279 return false;
8282 s->eci_handled = true;
8284 zero = tcg_constant_i32(0);
8285 for (i = 0; i < 15; i++) {
8286 if (extract32(a->list, i, 1)) {
8287 /* Clear R[i] */
8288 tcg_gen_mov_i32(cpu_R[i], zero);
8291 if (extract32(a->list, 15, 1)) {
8293 * Clear APSR (by calling the MSR helper with the same argument
8294 * as for "MSR APSR_nzcvqg, Rn": mask = 0b1100, SYSM=0)
8296 gen_helper_v7m_msr(cpu_env, tcg_constant_i32(0xc00), zero);
8298 clear_eci_state(s);
8299 return true;
8303 * Branch, branch with link
8306 static bool trans_B(DisasContext *s, arg_i *a)
8308 gen_jmp(s, read_pc(s) + a->imm);
8309 return true;
8312 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
8314 /* This has cond from encoding, required to be outside IT block. */
8315 if (a->cond >= 0xe) {
8316 return false;
8318 if (s->condexec_mask) {
8319 unallocated_encoding(s);
8320 return true;
8322 arm_skip_unless(s, a->cond);
8323 gen_jmp(s, read_pc(s) + a->imm);
8324 return true;
8327 static bool trans_BL(DisasContext *s, arg_i *a)
8329 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8330 gen_jmp(s, read_pc(s) + a->imm);
8331 return true;
8334 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
8337 * BLX <imm> would be useless on M-profile; the encoding space
8338 * is used for other insns from v8.1M onward, and UNDEFs before that.
8340 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8341 return false;
8344 /* For A32, ARM_FEATURE_V5 is checked near the start of the uncond block. */
8345 if (s->thumb && (a->imm & 2)) {
8346 return false;
8348 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8349 store_cpu_field_constant(!s->thumb, thumb);
8350 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
8351 return true;
8354 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
8356 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8357 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
8358 return true;
8361 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
8363 TCGv_i32 tmp = tcg_temp_new_i32();
8365 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8366 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
8367 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
8368 gen_bx(s, tmp);
8369 return true;
8372 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
8374 TCGv_i32 tmp;
8376 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8377 if (!ENABLE_ARCH_5) {
8378 return false;
8380 tmp = tcg_temp_new_i32();
8381 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
8382 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8383 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
8384 gen_bx(s, tmp);
8385 return true;
8388 static bool trans_BF(DisasContext *s, arg_BF *a)
8391 * M-profile branch future insns. The architecture permits an
8392 * implementation to implement these as NOPs (equivalent to
8393 * discarding the LO_BRANCH_INFO cache immediately), and we
8394 * take that IMPDEF option because for QEMU a "real" implementation
8395 * would be complicated and wouldn't execute any faster.
8397 if (!dc_isar_feature(aa32_lob, s)) {
8398 return false;
8400 if (a->boff == 0) {
8401 /* SEE "Related encodings" (loop insns) */
8402 return false;
8404 /* Handle as NOP */
8405 return true;
8408 static bool trans_DLS(DisasContext *s, arg_DLS *a)
8410 /* M-profile low-overhead loop start */
8411 TCGv_i32 tmp;
8413 if (!dc_isar_feature(aa32_lob, s)) {
8414 return false;
8416 if (a->rn == 13 || a->rn == 15) {
8418 * For DLSTP rn == 15 is a related encoding (LCTP); the
8419 * other cases caught by this condition are all
8420 * CONSTRAINED UNPREDICTABLE: we choose to UNDEF
8422 return false;
8425 if (a->size != 4) {
8426 /* DLSTP */
8427 if (!dc_isar_feature(aa32_mve, s)) {
8428 return false;
8430 if (!vfp_access_check(s)) {
8431 return true;
8435 /* Not a while loop: set LR to the count, and set LTPSIZE for DLSTP */
8436 tmp = load_reg(s, a->rn);
8437 store_reg(s, 14, tmp);
8438 if (a->size != 4) {
8439 /* DLSTP: set FPSCR.LTPSIZE */
8440 store_cpu_field(tcg_constant_i32(a->size), v7m.ltpsize);
8441 s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
8443 return true;
8446 static bool trans_WLS(DisasContext *s, arg_WLS *a)
8448 /* M-profile low-overhead while-loop start */
8449 TCGv_i32 tmp;
8450 TCGLabel *nextlabel;
8452 if (!dc_isar_feature(aa32_lob, s)) {
8453 return false;
8455 if (a->rn == 13 || a->rn == 15) {
8457 * For WLSTP rn == 15 is a related encoding (LE); the
8458 * other cases caught by this condition are all
8459 * CONSTRAINED UNPREDICTABLE: we choose to UNDEF
8461 return false;
8463 if (s->condexec_mask) {
8465 * WLS in an IT block is CONSTRAINED UNPREDICTABLE;
8466 * we choose to UNDEF, because otherwise our use of
8467 * gen_goto_tb(1) would clash with the use of TB exit 1
8468 * in the dc->condjmp condition-failed codepath in
8469 * arm_tr_tb_stop() and we'd get an assertion.
8471 return false;
8473 if (a->size != 4) {
8474 /* WLSTP */
8475 if (!dc_isar_feature(aa32_mve, s)) {
8476 return false;
8479 * We need to check that the FPU is enabled here, but mustn't
8480 * call vfp_access_check() to do that because we don't want to
8481 * do the lazy state preservation in the "loop count is zero" case.
8482 * Do the check-and-raise-exception by hand.
8484 if (s->fp_excp_el) {
8485 gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
8486 syn_uncategorized(), s->fp_excp_el);
8487 return true;
8491 nextlabel = gen_new_label();
8492 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
8493 tmp = load_reg(s, a->rn);
8494 store_reg(s, 14, tmp);
8495 if (a->size != 4) {
8497 * WLSTP: set FPSCR.LTPSIZE. This requires that we do the
8498 * lazy state preservation, new FP context creation, etc,
8499 * that vfp_access_check() does. We know that the actual
8500 * access check will succeed (ie it won't generate code that
8501 * throws an exception) because we did that check by hand earlier.
8503 bool ok = vfp_access_check(s);
8504 assert(ok);
8505 store_cpu_field(tcg_constant_i32(a->size), v7m.ltpsize);
8507 * LTPSIZE updated, but MVE_NO_PRED will always be the same thing (0)
8508 * when we take this upcoming exit from this TB, so gen_jmp_tb() is OK.
8511 gen_jmp_tb(s, s->base.pc_next, 1);
8513 gen_set_label(nextlabel);
8514 gen_jmp(s, read_pc(s) + a->imm);
8515 return true;
8518 static bool trans_LE(DisasContext *s, arg_LE *a)
8521 * M-profile low-overhead loop end. The architecture permits an
8522 * implementation to discard the LO_BRANCH_INFO cache at any time,
8523 * and we take the IMPDEF option to never set it in the first place
8524 * (equivalent to always discarding it immediately), because for QEMU
8525 * a "real" implementation would be complicated and wouldn't execute
8526 * any faster.
8528 TCGv_i32 tmp;
8529 TCGLabel *loopend;
8530 bool fpu_active;
8532 if (!dc_isar_feature(aa32_lob, s)) {
8533 return false;
8535 if (a->f && a->tp) {
8536 return false;
8538 if (s->condexec_mask) {
8540 * LE in an IT block is CONSTRAINED UNPREDICTABLE;
8541 * we choose to UNDEF, because otherwise our use of
8542 * gen_goto_tb(1) would clash with the use of TB exit 1
8543 * in the dc->condjmp condition-failed codepath in
8544 * arm_tr_tb_stop() and we'd get an assertion.
8546 return false;
8548 if (a->tp) {
8549 /* LETP */
8550 if (!dc_isar_feature(aa32_mve, s)) {
8551 return false;
8553 if (!vfp_access_check(s)) {
8554 s->eci_handled = true;
8555 return true;
8559 /* LE/LETP is OK with ECI set and leaves it untouched */
8560 s->eci_handled = true;
8563 * With MVE, LTPSIZE might not be 4, and we must emit an INVSTATE
8564 * UsageFault exception for the LE insn in that case. Note that we
8565 * are not directly checking FPSCR.LTPSIZE but instead check the
8566 * pseudocode LTPSIZE() function, which returns 4 if the FPU is
8567 * not currently active (ie ActiveFPState() returns false). We
8568 * can identify not-active purely from our TB state flags, as the
8569 * FPU is active only if:
8570 * the FPU is enabled
8571 * AND lazy state preservation is not active
8572 * AND we do not need a new fp context (this is the ASPEN/FPCA check)
8574 * Usually we don't need to care about this distinction between
8575 * LTPSIZE and FPSCR.LTPSIZE, because the code in vfp_access_check()
8576 * will either take an exception or clear the conditions that make
8577 * the FPU not active. But LE is an unusual case of a non-FP insn
8578 * that looks at LTPSIZE.
8580 fpu_active = !s->fp_excp_el && !s->v7m_lspact && !s->v7m_new_fp_ctxt_needed;
8582 if (!a->tp && dc_isar_feature(aa32_mve, s) && fpu_active) {
8583 /* Need to do a runtime check for LTPSIZE != 4 */
8584 TCGLabel *skipexc = gen_new_label();
8585 tmp = load_cpu_field(v7m.ltpsize);
8586 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc);
8587 tcg_temp_free_i32(tmp);
8588 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
8589 default_exception_el(s));
8590 gen_set_label(skipexc);
8593 if (a->f) {
8594 /* Loop-forever: just jump back to the loop start */
8595 gen_jmp(s, read_pc(s) - a->imm);
8596 return true;
8600 * Not loop-forever. If LR <= loop-decrement-value this is the last loop.
8601 * For LE, we know at this point that LTPSIZE must be 4 and the
8602 * loop decrement value is 1. For LETP we need to calculate the decrement
8603 * value from LTPSIZE.
8605 loopend = gen_new_label();
8606 if (!a->tp) {
8607 tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend);
8608 tcg_gen_addi_i32(cpu_R[14], cpu_R[14], -1);
8609 } else {
8611 * Decrement by 1 << (4 - LTPSIZE). We need to use a TCG local
8612 * so that decr stays live after the brcondi.
8614 TCGv_i32 decr = tcg_temp_local_new_i32();
8615 TCGv_i32 ltpsize = load_cpu_field(v7m.ltpsize);
8616 tcg_gen_sub_i32(decr, tcg_constant_i32(4), ltpsize);
8617 tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr);
8618 tcg_temp_free_i32(ltpsize);
8620 tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend);
8622 tcg_gen_sub_i32(cpu_R[14], cpu_R[14], decr);
8623 tcg_temp_free_i32(decr);
8625 /* Jump back to the loop start */
8626 gen_jmp(s, read_pc(s) - a->imm);
8628 gen_set_label(loopend);
8629 if (a->tp) {
8630 /* Exits from tail-pred loops must reset LTPSIZE to 4 */
8631 store_cpu_field(tcg_constant_i32(4), v7m.ltpsize);
8633 /* End TB, continuing to following insn */
8634 gen_jmp_tb(s, s->base.pc_next, 1);
8635 return true;
8638 static bool trans_LCTP(DisasContext *s, arg_LCTP *a)
8641 * M-profile Loop Clear with Tail Predication. Since our implementation
8642 * doesn't cache branch information, all we need to do is reset
8643 * FPSCR.LTPSIZE to 4.
8646 if (!dc_isar_feature(aa32_lob, s) ||
8647 !dc_isar_feature(aa32_mve, s)) {
8648 return false;
8651 if (!vfp_access_check(s)) {
8652 return true;
8655 store_cpu_field_constant(4, v7m.ltpsize);
8656 return true;
8659 static bool trans_VCTP(DisasContext *s, arg_VCTP *a)
8662 * M-profile Create Vector Tail Predicate. This insn is itself
8663 * predicated and is subject to beatwise execution.
8665 TCGv_i32 rn_shifted, masklen;
8667 if (!dc_isar_feature(aa32_mve, s) || a->rn == 13 || a->rn == 15) {
8668 return false;
8671 if (!mve_eci_check(s) || !vfp_access_check(s)) {
8672 return true;
8676 * We pre-calculate the mask length here to avoid having
8677 * to have multiple helpers specialized for size.
8678 * We pass the helper "rn <= (1 << (4 - size)) ? (rn << size) : 16".
8680 rn_shifted = tcg_temp_new_i32();
8681 masklen = load_reg(s, a->rn);
8682 tcg_gen_shli_i32(rn_shifted, masklen, a->size);
8683 tcg_gen_movcond_i32(TCG_COND_LEU, masklen,
8684 masklen, tcg_constant_i32(1 << (4 - a->size)),
8685 rn_shifted, tcg_constant_i32(16));
8686 gen_helper_mve_vctp(cpu_env, masklen);
8687 tcg_temp_free_i32(masklen);
8688 tcg_temp_free_i32(rn_shifted);
8689 /* This insn updates predication bits */
8690 s->base.is_jmp = DISAS_UPDATE_NOCHAIN;
8691 mve_update_eci(s);
8692 return true;
8695 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
8697 TCGv_i32 addr, tmp;
8699 tmp = load_reg(s, a->rm);
8700 if (half) {
8701 tcg_gen_add_i32(tmp, tmp, tmp);
8703 addr = load_reg(s, a->rn);
8704 tcg_gen_add_i32(addr, addr, tmp);
8706 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
8707 tcg_temp_free_i32(addr);
8709 tcg_gen_add_i32(tmp, tmp, tmp);
8710 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
8711 store_reg(s, 15, tmp);
8712 return true;
8715 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
8717 return op_tbranch(s, a, false);
8720 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
8722 return op_tbranch(s, a, true);
8725 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
8727 TCGv_i32 tmp = load_reg(s, a->rn);
8729 arm_gen_condlabel(s);
8730 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
8731 tmp, 0, s->condlabel);
8732 tcg_temp_free_i32(tmp);
8733 gen_jmp(s, read_pc(s) + a->imm);
8734 return true;
8738 * Supervisor call - both T32 & A32 come here so we need to check
8739 * which mode we are in when checking for semihosting.
8742 static bool trans_SVC(DisasContext *s, arg_SVC *a)
8744 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
8746 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
8747 #ifndef CONFIG_USER_ONLY
8748 !IS_USER(s) &&
8749 #endif
8750 (a->imm == semihost_imm)) {
8751 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
8752 } else {
8753 gen_set_pc_im(s, s->base.pc_next);
8754 s->svc_imm = a->imm;
8755 s->base.is_jmp = DISAS_SWI;
8757 return true;
8761 * Unconditional system instructions
8764 static bool trans_RFE(DisasContext *s, arg_RFE *a)
8766 static const int8_t pre_offset[4] = {
8767 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
8769 static const int8_t post_offset[4] = {
8770 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
8772 TCGv_i32 addr, t1, t2;
8774 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8775 return false;
8777 if (IS_USER(s)) {
8778 unallocated_encoding(s);
8779 return true;
8782 addr = load_reg(s, a->rn);
8783 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
8785 /* Load PC into tmp and CPSR into tmp2. */
8786 t1 = tcg_temp_new_i32();
8787 gen_aa32_ld_i32(s, t1, addr, get_mem_index(s), MO_UL | MO_ALIGN);
8788 tcg_gen_addi_i32(addr, addr, 4);
8789 t2 = tcg_temp_new_i32();
8790 gen_aa32_ld_i32(s, t2, addr, get_mem_index(s), MO_UL | MO_ALIGN);
8792 if (a->w) {
8793 /* Base writeback. */
8794 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
8795 store_reg(s, a->rn, addr);
8796 } else {
8797 tcg_temp_free_i32(addr);
8799 gen_rfe(s, t1, t2);
8800 return true;
8803 static bool trans_SRS(DisasContext *s, arg_SRS *a)
8805 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8806 return false;
8808 gen_srs(s, a->mode, a->pu, a->w);
8809 return true;
8812 static bool trans_CPS(DisasContext *s, arg_CPS *a)
8814 uint32_t mask, val;
8816 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8817 return false;
8819 if (IS_USER(s)) {
8820 /* Implemented as NOP in user mode. */
8821 return true;
8823 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
8825 mask = val = 0;
8826 if (a->imod & 2) {
8827 if (a->A) {
8828 mask |= CPSR_A;
8830 if (a->I) {
8831 mask |= CPSR_I;
8833 if (a->F) {
8834 mask |= CPSR_F;
8836 if (a->imod & 1) {
8837 val |= mask;
8840 if (a->M) {
8841 mask |= CPSR_M;
8842 val |= a->mode;
8844 if (mask) {
8845 gen_set_psr_im(s, mask, 0, val);
8847 return true;
8850 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
8852 TCGv_i32 tmp, addr;
8854 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8855 return false;
8857 if (IS_USER(s)) {
8858 /* Implemented as NOP in user mode. */
8859 return true;
8862 tmp = tcg_constant_i32(a->im);
8863 /* FAULTMASK */
8864 if (a->F) {
8865 addr = tcg_constant_i32(19);
8866 gen_helper_v7m_msr(cpu_env, addr, tmp);
8868 /* PRIMASK */
8869 if (a->I) {
8870 addr = tcg_constant_i32(16);
8871 gen_helper_v7m_msr(cpu_env, addr, tmp);
8873 gen_rebuild_hflags(s, false);
8874 gen_lookup_tb(s);
8875 return true;
8879 * Clear-Exclusive, Barriers
8882 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
8884 if (s->thumb
8885 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
8886 : !ENABLE_ARCH_6K) {
8887 return false;
8889 gen_clrex(s);
8890 return true;
8893 static bool trans_DSB(DisasContext *s, arg_DSB *a)
8895 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
8896 return false;
8898 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8899 return true;
8902 static bool trans_DMB(DisasContext *s, arg_DMB *a)
8904 return trans_DSB(s, NULL);
8907 static bool trans_ISB(DisasContext *s, arg_ISB *a)
8909 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
8910 return false;
8913 * We need to break the TB after this insn to execute
8914 * self-modifying code correctly and also to take
8915 * any pending interrupts immediately.
8917 s->base.is_jmp = DISAS_TOO_MANY;
8918 return true;
8921 static bool trans_SB(DisasContext *s, arg_SB *a)
8923 if (!dc_isar_feature(aa32_sb, s)) {
8924 return false;
8927 * TODO: There is no speculation barrier opcode
8928 * for TCG; MB and end the TB instead.
8930 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8931 s->base.is_jmp = DISAS_TOO_MANY;
8932 return true;
8935 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
8937 if (!ENABLE_ARCH_6) {
8938 return false;
8940 if (a->E != (s->be_data == MO_BE)) {
8941 gen_helper_setend(cpu_env);
8942 s->base.is_jmp = DISAS_UPDATE_EXIT;
8944 return true;
8948 * Preload instructions
8949 * All are nops, contingent on the appropriate arch level.
8952 static bool trans_PLD(DisasContext *s, arg_PLD *a)
8954 return ENABLE_ARCH_5TE;
8957 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
8959 return arm_dc_feature(s, ARM_FEATURE_V7MP);
8962 static bool trans_PLI(DisasContext *s, arg_PLD *a)
8964 return ENABLE_ARCH_7;
8968 * If-then
8971 static bool trans_IT(DisasContext *s, arg_IT *a)
8973 int cond_mask = a->cond_mask;
8976 * No actual code generated for this insn, just setup state.
8978 * Combinations of firstcond and mask which set up an 0b1111
8979 * condition are UNPREDICTABLE; we take the CONSTRAINED
8980 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
8981 * i.e. both meaning "execute always".
8983 s->condexec_cond = (cond_mask >> 4) & 0xe;
8984 s->condexec_mask = cond_mask & 0x1f;
8985 return true;
8988 /* v8.1M CSEL/CSINC/CSNEG/CSINV */
8989 static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
8991 TCGv_i32 rn, rm, zero;
8992 DisasCompare c;
8994 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
8995 return false;
8998 if (a->rm == 13) {
8999 /* SEE "Related encodings" (MVE shifts) */
9000 return false;
9003 if (a->rd == 13 || a->rd == 15 || a->rn == 13 || a->fcond >= 14) {
9004 /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
9005 return false;
9008 /* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
9009 zero = tcg_constant_i32(0);
9010 if (a->rn == 15) {
9011 rn = zero;
9012 } else {
9013 rn = load_reg(s, a->rn);
9015 if (a->rm == 15) {
9016 rm = zero;
9017 } else {
9018 rm = load_reg(s, a->rm);
9021 switch (a->op) {
9022 case 0: /* CSEL */
9023 break;
9024 case 1: /* CSINC */
9025 tcg_gen_addi_i32(rm, rm, 1);
9026 break;
9027 case 2: /* CSINV */
9028 tcg_gen_not_i32(rm, rm);
9029 break;
9030 case 3: /* CSNEG */
9031 tcg_gen_neg_i32(rm, rm);
9032 break;
9033 default:
9034 g_assert_not_reached();
9037 arm_test_cc(&c, a->fcond);
9038 tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
9039 arm_free_cc(&c);
9041 store_reg(s, a->rd, rn);
9042 tcg_temp_free_i32(rm);
9044 return true;
9048 * Legacy decoder.
9051 static void disas_arm_insn(DisasContext *s, unsigned int insn)
9053 unsigned int cond = insn >> 28;
9055 /* M variants do not implement ARM mode; this must raise the INVSTATE
9056 * UsageFault exception.
9058 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9059 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
9060 default_exception_el(s));
9061 return;
9064 if (s->pstate_il) {
9066 * Illegal execution state. This has priority over BTI
9067 * exceptions, but comes after instruction abort exceptions.
9069 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
9070 syn_illegalstate(), default_exception_el(s));
9071 return;
9074 if (cond == 0xf) {
9075 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
9076 * choose to UNDEF. In ARMv5 and above the space is used
9077 * for miscellaneous unconditional instructions.
9079 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
9080 unallocated_encoding(s);
9081 return;
9084 /* Unconditional instructions. */
9085 /* TODO: Perhaps merge these into one decodetree output file. */
9086 if (disas_a32_uncond(s, insn) ||
9087 disas_vfp_uncond(s, insn) ||
9088 disas_neon_dp(s, insn) ||
9089 disas_neon_ls(s, insn) ||
9090 disas_neon_shared(s, insn)) {
9091 return;
9093 /* fall back to legacy decoder */
9095 if ((insn & 0x0e000f00) == 0x0c000100) {
9096 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9097 /* iWMMXt register transfer. */
9098 if (extract32(s->c15_cpar, 1, 1)) {
9099 if (!disas_iwmmxt_insn(s, insn)) {
9100 return;
9105 goto illegal_op;
9107 if (cond != 0xe) {
9108 /* if not always execute, we generate a conditional jump to
9109 next instruction */
9110 arm_skip_unless(s, cond);
9113 /* TODO: Perhaps merge these into one decodetree output file. */
9114 if (disas_a32(s, insn) ||
9115 disas_vfp(s, insn)) {
9116 return;
9118 /* fall back to legacy decoder */
9119 /* TODO: convert xscale/iwmmxt decoder to decodetree ?? */
9120 if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
9121 if (((insn & 0x0c000e00) == 0x0c000000)
9122 && ((insn & 0x03000000) != 0x03000000)) {
9123 /* Coprocessor insn, coprocessor 0 or 1 */
9124 disas_xscale_insn(s, insn);
9125 return;
9129 illegal_op:
9130 unallocated_encoding(s);
9133 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
9136 * Return true if this is a 16 bit instruction. We must be precise
9137 * about this (matching the decode).
9139 if ((insn >> 11) < 0x1d) {
9140 /* Definitely a 16-bit instruction */
9141 return true;
9144 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9145 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9146 * end up actually treating this as two 16-bit insns, though,
9147 * if it's half of a bl/blx pair that might span a page boundary.
9149 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9150 arm_dc_feature(s, ARM_FEATURE_M)) {
9151 /* Thumb2 cores (including all M profile ones) always treat
9152 * 32-bit insns as 32-bit.
9154 return false;
9157 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9158 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9159 * is not on the next page; we merge this into a 32-bit
9160 * insn.
9162 return false;
9164 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9165 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9166 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9167 * -- handle as single 16 bit insn
9169 return true;
9172 /* Translate a 32-bit thumb instruction. */
9173 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9176 * ARMv6-M supports a limited subset of Thumb2 instructions.
9177 * Other Thumb1 architectures allow only 32-bit
9178 * combined BL/BLX prefix and suffix.
9180 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9181 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9182 int i;
9183 bool found = false;
9184 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9185 0xf3b08040 /* dsb */,
9186 0xf3b08050 /* dmb */,
9187 0xf3b08060 /* isb */,
9188 0xf3e08000 /* mrs */,
9189 0xf000d000 /* bl */};
9190 static const uint32_t armv6m_mask[] = {0xffe0d000,
9191 0xfff0d0f0,
9192 0xfff0d0f0,
9193 0xfff0d0f0,
9194 0xffe0d000,
9195 0xf800d000};
9197 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9198 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9199 found = true;
9200 break;
9203 if (!found) {
9204 goto illegal_op;
9206 } else if ((insn & 0xf800e800) != 0xf000e800) {
9207 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
9208 unallocated_encoding(s);
9209 return;
9213 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9215 * NOCP takes precedence over any UNDEF for (almost) the
9216 * entire wide range of coprocessor-space encodings, so check
9217 * for it first before proceeding to actually decode eg VFP
9218 * insns. This decode also handles the few insns which are
9219 * in copro space but do not have NOCP checks (eg VLLDM, VLSTM).
9221 if (disas_m_nocp(s, insn)) {
9222 return;
9226 if ((insn & 0xef000000) == 0xef000000) {
9228 * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9229 * transform into
9230 * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9232 uint32_t a32_insn = (insn & 0xe2ffffff) |
9233 ((insn & (1 << 28)) >> 4) | (1 << 28);
9235 if (disas_neon_dp(s, a32_insn)) {
9236 return;
9240 if ((insn & 0xff100000) == 0xf9000000) {
9242 * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9243 * transform into
9244 * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9246 uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
9248 if (disas_neon_ls(s, a32_insn)) {
9249 return;
9254 * TODO: Perhaps merge these into one decodetree output file.
9255 * Note disas_vfp is written for a32 with cond field in the
9256 * top nibble. The t32 encoding requires 0xe in the top nibble.
9258 if (disas_t32(s, insn) ||
9259 disas_vfp_uncond(s, insn) ||
9260 disas_neon_shared(s, insn) ||
9261 disas_mve(s, insn) ||
9262 ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
9263 return;
9266 illegal_op:
9267 unallocated_encoding(s);
9270 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
9272 if (!disas_t16(s, insn)) {
9273 unallocated_encoding(s);
9277 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
9279 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
9280 * (False positives are OK, false negatives are not.)
9281 * We know this is a Thumb insn, and our caller ensures we are
9282 * only called if dc->base.pc_next is less than 4 bytes from the page
9283 * boundary, so we cross the page if the first 16 bits indicate
9284 * that this is a 32 bit insn.
9286 uint16_t insn = arm_lduw_code(env, &s->base, s->base.pc_next, s->sctlr_b);
9288 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
9291 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
9293 DisasContext *dc = container_of(dcbase, DisasContext, base);
9294 CPUARMState *env = cs->env_ptr;
9295 ARMCPU *cpu = env_archcpu(env);
9296 CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
9297 uint32_t condexec, core_mmu_idx;
9299 dc->isar = &cpu->isar;
9300 dc->condjmp = 0;
9302 dc->aarch64 = false;
9303 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
9304 * there is no secure EL1, so we route exceptions to EL3.
9306 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
9307 !arm_el_is_aa64(env, 3);
9308 dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
9309 dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
9310 condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
9312 * the CONDEXEC TB flags are CPSR bits [15:10][26:25]. On A-profile this
9313 * is always the IT bits. On M-profile, some of the reserved encodings
9314 * of IT are used instead to indicate either ICI or ECI, which
9315 * indicate partial progress of a restartable insn that was interrupted
9316 * partway through by an exception:
9317 * * if CONDEXEC[3:0] != 0b0000 : CONDEXEC is IT bits
9318 * * if CONDEXEC[3:0] == 0b0000 : CONDEXEC is ICI or ECI bits
9319 * In all cases CONDEXEC == 0 means "not in IT block or restartable
9320 * insn, behave normally".
9322 dc->eci = dc->condexec_mask = dc->condexec_cond = 0;
9323 dc->eci_handled = false;
9324 dc->insn_eci_rewind = NULL;
9325 if (condexec & 0xf) {
9326 dc->condexec_mask = (condexec & 0xf) << 1;
9327 dc->condexec_cond = condexec >> 4;
9328 } else {
9329 if (arm_feature(env, ARM_FEATURE_M)) {
9330 dc->eci = condexec >> 4;
9334 core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
9335 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
9336 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
9337 #if !defined(CONFIG_USER_ONLY)
9338 dc->user = (dc->current_el == 0);
9339 #endif
9340 dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
9341 dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
9342 dc->pstate_il = EX_TBFLAG_ANY(tb_flags, PSTATE__IL);
9344 if (arm_feature(env, ARM_FEATURE_M)) {
9345 dc->vfp_enabled = 1;
9346 dc->be_data = MO_TE;
9347 dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
9348 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
9349 regime_is_secure(env, dc->mmu_idx);
9350 dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
9351 dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
9352 dc->v7m_new_fp_ctxt_needed =
9353 EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
9354 dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
9355 dc->mve_no_pred = EX_TBFLAG_M32(tb_flags, MVE_NO_PRED);
9356 } else {
9357 dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
9358 dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
9359 dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
9360 dc->ns = EX_TBFLAG_A32(tb_flags, NS);
9361 dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
9362 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
9363 dc->c15_cpar = EX_TBFLAG_A32(tb_flags, XSCALE_CPAR);
9364 } else {
9365 dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
9366 dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
9369 dc->cp_regs = cpu->cp_regs;
9370 dc->features = env->features;
9372 /* Single step state. The code-generation logic here is:
9373 * SS_ACTIVE == 0:
9374 * generate code with no special handling for single-stepping (except
9375 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
9376 * this happens anyway because those changes are all system register or
9377 * PSTATE writes).
9378 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
9379 * emit code for one insn
9380 * emit code to clear PSTATE.SS
9381 * emit code to generate software step exception for completed step
9382 * end TB (as usual for having generated an exception)
9383 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
9384 * emit code to generate a software step exception
9385 * end the TB
9387 dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
9388 dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
9389 dc->is_ldex = false;
9391 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
9393 /* If architectural single step active, limit to 1. */
9394 if (dc->ss_active) {
9395 dc->base.max_insns = 1;
9398 /* ARM is a fixed-length ISA. Bound the number of insns to execute
9399 to those left on the page. */
9400 if (!dc->thumb) {
9401 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
9402 dc->base.max_insns = MIN(dc->base.max_insns, bound);
9405 cpu_V0 = tcg_temp_new_i64();
9406 cpu_V1 = tcg_temp_new_i64();
9407 cpu_M0 = tcg_temp_new_i64();
9410 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
9412 DisasContext *dc = container_of(dcbase, DisasContext, base);
9414 /* A note on handling of the condexec (IT) bits:
9416 * We want to avoid the overhead of having to write the updated condexec
9417 * bits back to the CPUARMState for every instruction in an IT block. So:
9418 * (1) if the condexec bits are not already zero then we write
9419 * zero back into the CPUARMState now. This avoids complications trying
9420 * to do it at the end of the block. (For example if we don't do this
9421 * it's hard to identify whether we can safely skip writing condexec
9422 * at the end of the TB, which we definitely want to do for the case
9423 * where a TB doesn't do anything with the IT state at all.)
9424 * (2) if we are going to leave the TB then we call gen_set_condexec()
9425 * which will write the correct value into CPUARMState if zero is wrong.
9426 * This is done both for leaving the TB at the end, and for leaving
9427 * it because of an exception we know will happen, which is done in
9428 * gen_exception_insn(). The latter is necessary because we need to
9429 * leave the TB with the PC/IT state just prior to execution of the
9430 * instruction which caused the exception.
9431 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9432 * then the CPUARMState will be wrong and we need to reset it.
9433 * This is handled in the same way as restoration of the
9434 * PC in these situations; we save the value of the condexec bits
9435 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
9436 * then uses this to restore them after an exception.
9438 * Note that there are no instructions which can read the condexec
9439 * bits, and none which can write non-static values to them, so
9440 * we don't need to care about whether CPUARMState is correct in the
9441 * middle of a TB.
9444 /* Reset the conditional execution bits immediately. This avoids
9445 complications trying to do it at the end of the block. */
9446 if (dc->condexec_mask || dc->condexec_cond) {
9447 store_cpu_field_constant(0, condexec_bits);
9451 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
9453 DisasContext *dc = container_of(dcbase, DisasContext, base);
9455 * The ECI/ICI bits share PSR bits with the IT bits, so we
9456 * need to reconstitute the bits from the split-out DisasContext
9457 * fields here.
9459 uint32_t condexec_bits;
9461 if (dc->eci) {
9462 condexec_bits = dc->eci << 4;
9463 } else {
9464 condexec_bits = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9466 tcg_gen_insn_start(dc->base.pc_next, condexec_bits, 0);
9467 dc->insn_start = tcg_last_op();
9470 static bool arm_check_kernelpage(DisasContext *dc)
9472 #ifdef CONFIG_USER_ONLY
9473 /* Intercept jump to the magic kernel page. */
9474 if (dc->base.pc_next >= 0xffff0000) {
9475 /* We always get here via a jump, so know we are not in a
9476 conditional execution block. */
9477 gen_exception_internal(EXCP_KERNEL_TRAP);
9478 dc->base.is_jmp = DISAS_NORETURN;
9479 return true;
9481 #endif
9482 return false;
9485 static bool arm_check_ss_active(DisasContext *dc)
9487 if (dc->ss_active && !dc->pstate_ss) {
9488 /* Singlestep state is Active-pending.
9489 * If we're in this state at the start of a TB then either
9490 * a) we just took an exception to an EL which is being debugged
9491 * and this is the first insn in the exception handler
9492 * b) debug exceptions were masked and we just unmasked them
9493 * without changing EL (eg by clearing PSTATE.D)
9494 * In either case we're going to take a swstep exception in the
9495 * "did not step an insn" case, and so the syndrome ISV and EX
9496 * bits should be zero.
9498 assert(dc->base.num_insns == 1);
9499 gen_swstep_exception(dc, 0, 0);
9500 dc->base.is_jmp = DISAS_NORETURN;
9501 return true;
9504 return false;
9507 static void arm_post_translate_insn(DisasContext *dc)
9509 if (dc->condjmp && !dc->base.is_jmp) {
9510 gen_set_label(dc->condlabel);
9511 dc->condjmp = 0;
9513 translator_loop_temp_check(&dc->base);
9516 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
9518 DisasContext *dc = container_of(dcbase, DisasContext, base);
9519 CPUARMState *env = cpu->env_ptr;
9520 uint32_t pc = dc->base.pc_next;
9521 unsigned int insn;
9523 /* Singlestep exceptions have the highest priority. */
9524 if (arm_check_ss_active(dc)) {
9525 dc->base.pc_next = pc + 4;
9526 return;
9529 if (pc & 3) {
9531 * PC alignment fault. This has priority over the instruction abort
9532 * that we would receive from a translation fault via arm_ldl_code
9533 * (or the execution of the kernelpage entrypoint). This should only
9534 * be possible after an indirect branch, at the start of the TB.
9536 assert(dc->base.num_insns == 1);
9537 gen_helper_exception_pc_alignment(cpu_env, tcg_constant_tl(pc));
9538 dc->base.is_jmp = DISAS_NORETURN;
9539 dc->base.pc_next = QEMU_ALIGN_UP(pc, 4);
9540 return;
9543 if (arm_check_kernelpage(dc)) {
9544 dc->base.pc_next = pc + 4;
9545 return;
9548 dc->pc_curr = pc;
9549 insn = arm_ldl_code(env, &dc->base, pc, dc->sctlr_b);
9550 dc->insn = insn;
9551 dc->base.pc_next = pc + 4;
9552 disas_arm_insn(dc, insn);
9554 arm_post_translate_insn(dc);
9556 /* ARM is a fixed-length ISA. We performed the cross-page check
9557 in init_disas_context by adjusting max_insns. */
9560 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
9562 /* Return true if this Thumb insn is always unconditional,
9563 * even inside an IT block. This is true of only a very few
9564 * instructions: BKPT, HLT, and SG.
9566 * A larger class of instructions are UNPREDICTABLE if used
9567 * inside an IT block; we do not need to detect those here, because
9568 * what we do by default (perform the cc check and update the IT
9569 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
9570 * choice for those situations.
9572 * insn is either a 16-bit or a 32-bit instruction; the two are
9573 * distinguishable because for the 16-bit case the top 16 bits
9574 * are zeroes, and that isn't a valid 32-bit encoding.
9576 if ((insn & 0xffffff00) == 0xbe00) {
9577 /* BKPT */
9578 return true;
9581 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
9582 !arm_dc_feature(s, ARM_FEATURE_M)) {
9583 /* HLT: v8A only. This is unconditional even when it is going to
9584 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
9585 * For v7 cores this was a plain old undefined encoding and so
9586 * honours its cc check. (We might be using the encoding as
9587 * a semihosting trap, but we don't change the cc check behaviour
9588 * on that account, because a debugger connected to a real v7A
9589 * core and emulating semihosting traps by catching the UNDEF
9590 * exception would also only see cases where the cc check passed.
9591 * No guest code should be trying to do a HLT semihosting trap
9592 * in an IT block anyway.
9594 return true;
9597 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
9598 arm_dc_feature(s, ARM_FEATURE_M)) {
9599 /* SG: v8M only */
9600 return true;
9603 return false;
9606 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
9608 DisasContext *dc = container_of(dcbase, DisasContext, base);
9609 CPUARMState *env = cpu->env_ptr;
9610 uint32_t pc = dc->base.pc_next;
9611 uint32_t insn;
9612 bool is_16bit;
9614 /* Misaligned thumb PC is architecturally impossible. */
9615 assert((dc->base.pc_next & 1) == 0);
9617 if (arm_check_ss_active(dc) || arm_check_kernelpage(dc)) {
9618 dc->base.pc_next = pc + 2;
9619 return;
9622 dc->pc_curr = pc;
9623 insn = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
9624 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
9625 pc += 2;
9626 if (!is_16bit) {
9627 uint32_t insn2 = arm_lduw_code(env, &dc->base, pc, dc->sctlr_b);
9628 insn = insn << 16 | insn2;
9629 pc += 2;
9631 dc->base.pc_next = pc;
9632 dc->insn = insn;
9634 if (dc->pstate_il) {
9636 * Illegal execution state. This has priority over BTI
9637 * exceptions, but comes after instruction abort exceptions.
9639 gen_exception_insn(dc, dc->pc_curr, EXCP_UDEF,
9640 syn_illegalstate(), default_exception_el(dc));
9641 return;
9644 if (dc->eci) {
9646 * For M-profile continuable instructions, ECI/ICI handling
9647 * falls into these cases:
9648 * - interrupt-continuable instructions
9649 * These are the various load/store multiple insns (both
9650 * integer and fp). The ICI bits indicate the register
9651 * where the load/store can resume. We make the IMPDEF
9652 * choice to always do "instruction restart", ie ignore
9653 * the ICI value and always execute the ldm/stm from the
9654 * start. So all we need to do is zero PSR.ICI if the
9655 * insn executes.
9656 * - MVE instructions subject to beat-wise execution
9657 * Here the ECI bits indicate which beats have already been
9658 * executed, and we must honour this. Each insn of this
9659 * type will handle it correctly. We will update PSR.ECI
9660 * in the helper function for the insn (some ECI values
9661 * mean that the following insn also has been partially
9662 * executed).
9663 * - Special cases which don't advance ECI
9664 * The insns LE, LETP and BKPT leave the ECI/ICI state
9665 * bits untouched.
9666 * - all other insns (the common case)
9667 * Non-zero ECI/ICI means an INVSTATE UsageFault.
9668 * We place a rewind-marker here. Insns in the previous
9669 * three categories will set a flag in the DisasContext.
9670 * If the flag isn't set after we call disas_thumb_insn()
9671 * or disas_thumb2_insn() then we know we have a "some other
9672 * insn" case. We will rewind to the marker (ie throwing away
9673 * all the generated code) and instead emit "take exception".
9675 dc->insn_eci_rewind = tcg_last_op();
9678 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
9679 uint32_t cond = dc->condexec_cond;
9682 * Conditionally skip the insn. Note that both 0xe and 0xf mean
9683 * "always"; 0xf is not "never".
9685 if (cond < 0x0e) {
9686 arm_skip_unless(dc, cond);
9690 if (is_16bit) {
9691 disas_thumb_insn(dc, insn);
9692 } else {
9693 disas_thumb2_insn(dc, insn);
9696 /* Advance the Thumb condexec condition. */
9697 if (dc->condexec_mask) {
9698 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
9699 ((dc->condexec_mask >> 4) & 1));
9700 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9701 if (dc->condexec_mask == 0) {
9702 dc->condexec_cond = 0;
9706 if (dc->eci && !dc->eci_handled) {
9708 * Insn wasn't valid for ECI/ICI at all: undo what we
9709 * just generated and instead emit an exception
9711 tcg_remove_ops_after(dc->insn_eci_rewind);
9712 dc->condjmp = 0;
9713 gen_exception_insn(dc, dc->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
9714 default_exception_el(dc));
9717 arm_post_translate_insn(dc);
9719 /* Thumb is a variable-length ISA. Stop translation when the next insn
9720 * will touch a new page. This ensures that prefetch aborts occur at
9721 * the right place.
9723 * We want to stop the TB if the next insn starts in a new page,
9724 * or if it spans between this page and the next. This means that
9725 * if we're looking at the last halfword in the page we need to
9726 * see if it's a 16-bit Thumb insn (which will fit in this TB)
9727 * or a 32-bit Thumb insn (which won't).
9728 * This is to avoid generating a silly TB with a single 16-bit insn
9729 * in it at the end of this page (which would execute correctly
9730 * but isn't very efficient).
9732 if (dc->base.is_jmp == DISAS_NEXT
9733 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
9734 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
9735 && insn_crosses_page(env, dc)))) {
9736 dc->base.is_jmp = DISAS_TOO_MANY;
9740 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
9742 DisasContext *dc = container_of(dcbase, DisasContext, base);
9744 /* At this stage dc->condjmp will only be set when the skipped
9745 instruction was a conditional branch or trap, and the PC has
9746 already been written. */
9747 gen_set_condexec(dc);
9748 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
9749 /* Exception return branches need some special case code at the
9750 * end of the TB, which is complex enough that it has to
9751 * handle the single-step vs not and the condition-failed
9752 * insn codepath itself.
9754 gen_bx_excret_final_code(dc);
9755 } else if (unlikely(dc->ss_active)) {
9756 /* Unconditional and "condition passed" instruction codepath. */
9757 switch (dc->base.is_jmp) {
9758 case DISAS_SWI:
9759 gen_ss_advance(dc);
9760 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
9761 default_exception_el(dc));
9762 break;
9763 case DISAS_HVC:
9764 gen_ss_advance(dc);
9765 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
9766 break;
9767 case DISAS_SMC:
9768 gen_ss_advance(dc);
9769 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
9770 break;
9771 case DISAS_NEXT:
9772 case DISAS_TOO_MANY:
9773 case DISAS_UPDATE_EXIT:
9774 case DISAS_UPDATE_NOCHAIN:
9775 gen_set_pc_im(dc, dc->base.pc_next);
9776 /* fall through */
9777 default:
9778 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
9779 gen_singlestep_exception(dc);
9780 break;
9781 case DISAS_NORETURN:
9782 break;
9784 } else {
9785 /* While branches must always occur at the end of an IT block,
9786 there are a few other things that can cause us to terminate
9787 the TB in the middle of an IT block:
9788 - Exception generating instructions (bkpt, swi, undefined).
9789 - Page boundaries.
9790 - Hardware watchpoints.
9791 Hardware breakpoints have already been handled and skip this code.
9793 switch (dc->base.is_jmp) {
9794 case DISAS_NEXT:
9795 case DISAS_TOO_MANY:
9796 gen_goto_tb(dc, 1, dc->base.pc_next);
9797 break;
9798 case DISAS_UPDATE_NOCHAIN:
9799 gen_set_pc_im(dc, dc->base.pc_next);
9800 /* fall through */
9801 case DISAS_JUMP:
9802 gen_goto_ptr();
9803 break;
9804 case DISAS_UPDATE_EXIT:
9805 gen_set_pc_im(dc, dc->base.pc_next);
9806 /* fall through */
9807 default:
9808 /* indicate that the hash table must be used to find the next TB */
9809 tcg_gen_exit_tb(NULL, 0);
9810 break;
9811 case DISAS_NORETURN:
9812 /* nothing more to generate */
9813 break;
9814 case DISAS_WFI:
9815 gen_helper_wfi(cpu_env,
9816 tcg_constant_i32(dc->base.pc_next - dc->pc_curr));
9818 * The helper doesn't necessarily throw an exception, but we
9819 * must go back to the main loop to check for interrupts anyway.
9821 tcg_gen_exit_tb(NULL, 0);
9822 break;
9823 case DISAS_WFE:
9824 gen_helper_wfe(cpu_env);
9825 break;
9826 case DISAS_YIELD:
9827 gen_helper_yield(cpu_env);
9828 break;
9829 case DISAS_SWI:
9830 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
9831 default_exception_el(dc));
9832 break;
9833 case DISAS_HVC:
9834 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
9835 break;
9836 case DISAS_SMC:
9837 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
9838 break;
9842 if (dc->condjmp) {
9843 /* "Condition failed" instruction codepath for the branch/trap insn */
9844 gen_set_label(dc->condlabel);
9845 gen_set_condexec(dc);
9846 if (unlikely(dc->ss_active)) {
9847 gen_set_pc_im(dc, dc->base.pc_next);
9848 gen_singlestep_exception(dc);
9849 } else {
9850 gen_goto_tb(dc, 1, dc->base.pc_next);
9855 static void arm_tr_disas_log(const DisasContextBase *dcbase,
9856 CPUState *cpu, FILE *logfile)
9858 DisasContext *dc = container_of(dcbase, DisasContext, base);
9860 fprintf(logfile, "IN: %s\n", lookup_symbol(dc->base.pc_first));
9861 target_disas(logfile, cpu, dc->base.pc_first, dc->base.tb->size);
9864 static const TranslatorOps arm_translator_ops = {
9865 .init_disas_context = arm_tr_init_disas_context,
9866 .tb_start = arm_tr_tb_start,
9867 .insn_start = arm_tr_insn_start,
9868 .translate_insn = arm_tr_translate_insn,
9869 .tb_stop = arm_tr_tb_stop,
9870 .disas_log = arm_tr_disas_log,
9873 static const TranslatorOps thumb_translator_ops = {
9874 .init_disas_context = arm_tr_init_disas_context,
9875 .tb_start = arm_tr_tb_start,
9876 .insn_start = arm_tr_insn_start,
9877 .translate_insn = thumb_tr_translate_insn,
9878 .tb_stop = arm_tr_tb_stop,
9879 .disas_log = arm_tr_disas_log,
9882 /* generate intermediate code for basic block 'tb'. */
9883 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
9885 DisasContext dc = { };
9886 const TranslatorOps *ops = &arm_translator_ops;
9887 CPUARMTBFlags tb_flags = arm_tbflags_from_tb(tb);
9889 if (EX_TBFLAG_AM32(tb_flags, THUMB)) {
9890 ops = &thumb_translator_ops;
9892 #ifdef TARGET_AARCH64
9893 if (EX_TBFLAG_ANY(tb_flags, AARCH64_STATE)) {
9894 ops = &aarch64_translator_ops;
9896 #endif
9898 translator_loop(ops, &dc.base, cpu, tb, max_insns);
9901 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
9902 target_ulong *data)
9904 if (is_a64(env)) {
9905 env->pc = data[0];
9906 env->condexec_bits = 0;
9907 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
9908 } else {
9909 env->regs[15] = data[0];
9910 env->condexec_bits = data[1];
9911 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;