target/riscv: Use extracts for sraiw and srliw
[qemu/ar7.git] / target / arm / translate.c
blob24b7f49d7674a29efc1e0f27c93ff35dfef8c940
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg/tcg-op.h"
28 #include "tcg/tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "semihosting/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "exec/log.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J dc_isar_feature(aa32_jazelle, s)
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #include "translate.h"
52 #include "translate-a32.h"
54 /* These are TCG temporaries used only by the legacy iwMMXt decoder */
55 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
56 /* These are TCG globals which alias CPUARMState fields */
57 static TCGv_i32 cpu_R[16];
58 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
59 TCGv_i64 cpu_exclusive_addr;
60 TCGv_i64 cpu_exclusive_val;
62 #include "exec/gen-icount.h"
64 static const char * const regnames[] =
65 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
66 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
69 /* initialize TCG globals. */
70 void arm_translate_init(void)
72 int i;
74 for (i = 0; i < 16; i++) {
75 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
76 offsetof(CPUARMState, regs[i]),
77 regnames[i]);
79 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
80 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
81 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
82 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
84 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
85 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
86 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
87 offsetof(CPUARMState, exclusive_val), "exclusive_val");
89 a64_translate_init();
92 uint64_t asimd_imm_const(uint32_t imm, int cmode, int op)
94 /* Expand the encoded constant as per AdvSIMDExpandImm pseudocode */
95 switch (cmode) {
96 case 0: case 1:
97 /* no-op */
98 break;
99 case 2: case 3:
100 imm <<= 8;
101 break;
102 case 4: case 5:
103 imm <<= 16;
104 break;
105 case 6: case 7:
106 imm <<= 24;
107 break;
108 case 8: case 9:
109 imm |= imm << 16;
110 break;
111 case 10: case 11:
112 imm = (imm << 8) | (imm << 24);
113 break;
114 case 12:
115 imm = (imm << 8) | 0xff;
116 break;
117 case 13:
118 imm = (imm << 16) | 0xffff;
119 break;
120 case 14:
121 if (op) {
123 * This and cmode == 15 op == 1 are the only cases where
124 * the top and bottom 32 bits of the encoded constant differ.
126 uint64_t imm64 = 0;
127 int n;
129 for (n = 0; n < 8; n++) {
130 if (imm & (1 << n)) {
131 imm64 |= (0xffULL << (n * 8));
134 return imm64;
136 imm |= (imm << 8) | (imm << 16) | (imm << 24);
137 break;
138 case 15:
139 if (op) {
140 /* Reserved encoding for AArch32; valid for AArch64 */
141 uint64_t imm64 = (uint64_t)(imm & 0x3f) << 48;
142 if (imm & 0x80) {
143 imm64 |= 0x8000000000000000ULL;
145 if (imm & 0x40) {
146 imm64 |= 0x3fc0000000000000ULL;
147 } else {
148 imm64 |= 0x4000000000000000ULL;
150 return imm64;
152 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
153 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
154 break;
156 if (op) {
157 imm = ~imm;
159 return dup_const(MO_32, imm);
162 /* Generate a label used for skipping this instruction */
163 void arm_gen_condlabel(DisasContext *s)
165 if (!s->condjmp) {
166 s->condlabel = gen_new_label();
167 s->condjmp = 1;
171 /* Flags for the disas_set_da_iss info argument:
172 * lower bits hold the Rt register number, higher bits are flags.
174 typedef enum ISSInfo {
175 ISSNone = 0,
176 ISSRegMask = 0x1f,
177 ISSInvalid = (1 << 5),
178 ISSIsAcqRel = (1 << 6),
179 ISSIsWrite = (1 << 7),
180 ISSIs16Bit = (1 << 8),
181 } ISSInfo;
183 /* Save the syndrome information for a Data Abort */
184 static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
186 uint32_t syn;
187 int sas = memop & MO_SIZE;
188 bool sse = memop & MO_SIGN;
189 bool is_acqrel = issinfo & ISSIsAcqRel;
190 bool is_write = issinfo & ISSIsWrite;
191 bool is_16bit = issinfo & ISSIs16Bit;
192 int srt = issinfo & ISSRegMask;
194 if (issinfo & ISSInvalid) {
195 /* Some callsites want to conditionally provide ISS info,
196 * eg "only if this was not a writeback"
198 return;
201 if (srt == 15) {
202 /* For AArch32, insns where the src/dest is R15 never generate
203 * ISS information. Catching that here saves checking at all
204 * the call sites.
206 return;
209 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
210 0, 0, 0, is_write, 0, is_16bit);
211 disas_set_insn_syndrome(s, syn);
214 static inline int get_a32_user_mem_index(DisasContext *s)
216 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
217 * insns:
218 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
219 * otherwise, access as if at PL0.
221 switch (s->mmu_idx) {
222 case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
223 case ARMMMUIdx_E10_0:
224 case ARMMMUIdx_E10_1:
225 case ARMMMUIdx_E10_1_PAN:
226 return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
227 case ARMMMUIdx_SE3:
228 case ARMMMUIdx_SE10_0:
229 case ARMMMUIdx_SE10_1:
230 case ARMMMUIdx_SE10_1_PAN:
231 return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
232 case ARMMMUIdx_MUser:
233 case ARMMMUIdx_MPriv:
234 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
235 case ARMMMUIdx_MUserNegPri:
236 case ARMMMUIdx_MPrivNegPri:
237 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
238 case ARMMMUIdx_MSUser:
239 case ARMMMUIdx_MSPriv:
240 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
241 case ARMMMUIdx_MSUserNegPri:
242 case ARMMMUIdx_MSPrivNegPri:
243 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
244 default:
245 g_assert_not_reached();
249 /* The architectural value of PC. */
250 static uint32_t read_pc(DisasContext *s)
252 return s->pc_curr + (s->thumb ? 4 : 8);
255 /* Set a variable to the value of a CPU register. */
256 void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
258 if (reg == 15) {
259 tcg_gen_movi_i32(var, read_pc(s));
260 } else {
261 tcg_gen_mov_i32(var, cpu_R[reg]);
266 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
267 * This is used for load/store for which use of PC implies (literal),
268 * or ADD that implies ADR.
270 TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
272 TCGv_i32 tmp = tcg_temp_new_i32();
274 if (reg == 15) {
275 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
276 } else {
277 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
279 return tmp;
282 /* Set a CPU register. The source must be a temporary and will be
283 marked as dead. */
284 void store_reg(DisasContext *s, int reg, TCGv_i32 var)
286 if (reg == 15) {
287 /* In Thumb mode, we must ignore bit 0.
288 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
289 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
290 * We choose to ignore [1:0] in ARM mode for all architecture versions.
292 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
293 s->base.is_jmp = DISAS_JUMP;
294 } else if (reg == 13 && arm_dc_feature(s, ARM_FEATURE_M)) {
295 /* For M-profile SP bits [1:0] are always zero */
296 tcg_gen_andi_i32(var, var, ~3);
298 tcg_gen_mov_i32(cpu_R[reg], var);
299 tcg_temp_free_i32(var);
303 * Variant of store_reg which applies v8M stack-limit checks before updating
304 * SP. If the check fails this will result in an exception being taken.
305 * We disable the stack checks for CONFIG_USER_ONLY because we have
306 * no idea what the stack limits should be in that case.
307 * If stack checking is not being done this just acts like store_reg().
309 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
311 #ifndef CONFIG_USER_ONLY
312 if (s->v8m_stackcheck) {
313 gen_helper_v8m_stackcheck(cpu_env, var);
315 #endif
316 store_reg(s, 13, var);
319 /* Value extensions. */
320 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
321 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
322 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
323 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
325 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
326 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
328 void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
330 TCGv_i32 tmp_mask = tcg_const_i32(mask);
331 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
332 tcg_temp_free_i32(tmp_mask);
335 static void gen_exception_internal(int excp)
337 TCGv_i32 tcg_excp = tcg_const_i32(excp);
339 assert(excp_is_internal(excp));
340 gen_helper_exception_internal(cpu_env, tcg_excp);
341 tcg_temp_free_i32(tcg_excp);
344 static void gen_step_complete_exception(DisasContext *s)
346 /* We just completed step of an insn. Move from Active-not-pending
347 * to Active-pending, and then also take the swstep exception.
348 * This corresponds to making the (IMPDEF) choice to prioritize
349 * swstep exceptions over asynchronous exceptions taken to an exception
350 * level where debug is disabled. This choice has the advantage that
351 * we do not need to maintain internal state corresponding to the
352 * ISV/EX syndrome bits between completion of the step and generation
353 * of the exception, and our syndrome information is always correct.
355 gen_ss_advance(s);
356 gen_swstep_exception(s, 1, s->is_ldex);
357 s->base.is_jmp = DISAS_NORETURN;
360 static void gen_singlestep_exception(DisasContext *s)
362 /* Generate the right kind of exception for singlestep, which is
363 * either the architectural singlestep or EXCP_DEBUG for QEMU's
364 * gdb singlestepping.
366 if (s->ss_active) {
367 gen_step_complete_exception(s);
368 } else {
369 gen_exception_internal(EXCP_DEBUG);
373 static inline bool is_singlestepping(DisasContext *s)
375 /* Return true if we are singlestepping either because of
376 * architectural singlestep or QEMU gdbstub singlestep. This does
377 * not include the command line '-singlestep' mode which is rather
378 * misnamed as it only means "one instruction per TB" and doesn't
379 * affect the code we generate.
381 return s->base.singlestep_enabled || s->ss_active;
384 void clear_eci_state(DisasContext *s)
387 * Clear any ECI/ICI state: used when a load multiple/store
388 * multiple insn executes.
390 if (s->eci) {
391 TCGv_i32 tmp = tcg_const_i32(0);
392 store_cpu_field(tmp, condexec_bits);
393 s->eci = 0;
397 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
399 TCGv_i32 tmp1 = tcg_temp_new_i32();
400 TCGv_i32 tmp2 = tcg_temp_new_i32();
401 tcg_gen_ext16s_i32(tmp1, a);
402 tcg_gen_ext16s_i32(tmp2, b);
403 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
404 tcg_temp_free_i32(tmp2);
405 tcg_gen_sari_i32(a, a, 16);
406 tcg_gen_sari_i32(b, b, 16);
407 tcg_gen_mul_i32(b, b, a);
408 tcg_gen_mov_i32(a, tmp1);
409 tcg_temp_free_i32(tmp1);
412 /* Byteswap each halfword. */
413 void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
415 TCGv_i32 tmp = tcg_temp_new_i32();
416 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
417 tcg_gen_shri_i32(tmp, var, 8);
418 tcg_gen_and_i32(tmp, tmp, mask);
419 tcg_gen_and_i32(var, var, mask);
420 tcg_gen_shli_i32(var, var, 8);
421 tcg_gen_or_i32(dest, var, tmp);
422 tcg_temp_free_i32(mask);
423 tcg_temp_free_i32(tmp);
426 /* Byteswap low halfword and sign extend. */
427 static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
429 tcg_gen_bswap16_i32(var, var, TCG_BSWAP_OS);
432 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
433 tmp = (t0 ^ t1) & 0x8000;
434 t0 &= ~0x8000;
435 t1 &= ~0x8000;
436 t0 = (t0 + t1) ^ tmp;
439 static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
441 TCGv_i32 tmp = tcg_temp_new_i32();
442 tcg_gen_xor_i32(tmp, t0, t1);
443 tcg_gen_andi_i32(tmp, tmp, 0x8000);
444 tcg_gen_andi_i32(t0, t0, ~0x8000);
445 tcg_gen_andi_i32(t1, t1, ~0x8000);
446 tcg_gen_add_i32(t0, t0, t1);
447 tcg_gen_xor_i32(dest, t0, tmp);
448 tcg_temp_free_i32(tmp);
451 /* Set N and Z flags from var. */
452 static inline void gen_logic_CC(TCGv_i32 var)
454 tcg_gen_mov_i32(cpu_NF, var);
455 tcg_gen_mov_i32(cpu_ZF, var);
458 /* dest = T0 + T1 + CF. */
459 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
461 tcg_gen_add_i32(dest, t0, t1);
462 tcg_gen_add_i32(dest, dest, cpu_CF);
465 /* dest = T0 - T1 + CF - 1. */
466 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
468 tcg_gen_sub_i32(dest, t0, t1);
469 tcg_gen_add_i32(dest, dest, cpu_CF);
470 tcg_gen_subi_i32(dest, dest, 1);
473 /* dest = T0 + T1. Compute C, N, V and Z flags */
474 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
476 TCGv_i32 tmp = tcg_temp_new_i32();
477 tcg_gen_movi_i32(tmp, 0);
478 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
479 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
480 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
481 tcg_gen_xor_i32(tmp, t0, t1);
482 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
483 tcg_temp_free_i32(tmp);
484 tcg_gen_mov_i32(dest, cpu_NF);
487 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
488 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
490 TCGv_i32 tmp = tcg_temp_new_i32();
491 if (TCG_TARGET_HAS_add2_i32) {
492 tcg_gen_movi_i32(tmp, 0);
493 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
494 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
495 } else {
496 TCGv_i64 q0 = tcg_temp_new_i64();
497 TCGv_i64 q1 = tcg_temp_new_i64();
498 tcg_gen_extu_i32_i64(q0, t0);
499 tcg_gen_extu_i32_i64(q1, t1);
500 tcg_gen_add_i64(q0, q0, q1);
501 tcg_gen_extu_i32_i64(q1, cpu_CF);
502 tcg_gen_add_i64(q0, q0, q1);
503 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
504 tcg_temp_free_i64(q0);
505 tcg_temp_free_i64(q1);
507 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
508 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
509 tcg_gen_xor_i32(tmp, t0, t1);
510 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
511 tcg_temp_free_i32(tmp);
512 tcg_gen_mov_i32(dest, cpu_NF);
515 /* dest = T0 - T1. Compute C, N, V and Z flags */
516 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
518 TCGv_i32 tmp;
519 tcg_gen_sub_i32(cpu_NF, t0, t1);
520 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
521 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
522 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
523 tmp = tcg_temp_new_i32();
524 tcg_gen_xor_i32(tmp, t0, t1);
525 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
526 tcg_temp_free_i32(tmp);
527 tcg_gen_mov_i32(dest, cpu_NF);
530 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
531 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
533 TCGv_i32 tmp = tcg_temp_new_i32();
534 tcg_gen_not_i32(tmp, t1);
535 gen_adc_CC(dest, t0, tmp);
536 tcg_temp_free_i32(tmp);
539 #define GEN_SHIFT(name) \
540 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
542 TCGv_i32 tmp1, tmp2, tmp3; \
543 tmp1 = tcg_temp_new_i32(); \
544 tcg_gen_andi_i32(tmp1, t1, 0xff); \
545 tmp2 = tcg_const_i32(0); \
546 tmp3 = tcg_const_i32(0x1f); \
547 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
548 tcg_temp_free_i32(tmp3); \
549 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
550 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
551 tcg_temp_free_i32(tmp2); \
552 tcg_temp_free_i32(tmp1); \
554 GEN_SHIFT(shl)
555 GEN_SHIFT(shr)
556 #undef GEN_SHIFT
558 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
560 TCGv_i32 tmp1, tmp2;
561 tmp1 = tcg_temp_new_i32();
562 tcg_gen_andi_i32(tmp1, t1, 0xff);
563 tmp2 = tcg_const_i32(0x1f);
564 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
565 tcg_temp_free_i32(tmp2);
566 tcg_gen_sar_i32(dest, t0, tmp1);
567 tcg_temp_free_i32(tmp1);
570 static void shifter_out_im(TCGv_i32 var, int shift)
572 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
575 /* Shift by immediate. Includes special handling for shift == 0. */
576 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
577 int shift, int flags)
579 switch (shiftop) {
580 case 0: /* LSL */
581 if (shift != 0) {
582 if (flags)
583 shifter_out_im(var, 32 - shift);
584 tcg_gen_shli_i32(var, var, shift);
586 break;
587 case 1: /* LSR */
588 if (shift == 0) {
589 if (flags) {
590 tcg_gen_shri_i32(cpu_CF, var, 31);
592 tcg_gen_movi_i32(var, 0);
593 } else {
594 if (flags)
595 shifter_out_im(var, shift - 1);
596 tcg_gen_shri_i32(var, var, shift);
598 break;
599 case 2: /* ASR */
600 if (shift == 0)
601 shift = 32;
602 if (flags)
603 shifter_out_im(var, shift - 1);
604 if (shift == 32)
605 shift = 31;
606 tcg_gen_sari_i32(var, var, shift);
607 break;
608 case 3: /* ROR/RRX */
609 if (shift != 0) {
610 if (flags)
611 shifter_out_im(var, shift - 1);
612 tcg_gen_rotri_i32(var, var, shift); break;
613 } else {
614 TCGv_i32 tmp = tcg_temp_new_i32();
615 tcg_gen_shli_i32(tmp, cpu_CF, 31);
616 if (flags)
617 shifter_out_im(var, 0);
618 tcg_gen_shri_i32(var, var, 1);
619 tcg_gen_or_i32(var, var, tmp);
620 tcg_temp_free_i32(tmp);
625 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
626 TCGv_i32 shift, int flags)
628 if (flags) {
629 switch (shiftop) {
630 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
631 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
632 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
633 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
635 } else {
636 switch (shiftop) {
637 case 0:
638 gen_shl(var, var, shift);
639 break;
640 case 1:
641 gen_shr(var, var, shift);
642 break;
643 case 2:
644 gen_sar(var, var, shift);
645 break;
646 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
647 tcg_gen_rotr_i32(var, var, shift); break;
650 tcg_temp_free_i32(shift);
654 * Generate a conditional based on ARM condition code cc.
655 * This is common between ARM and Aarch64 targets.
657 void arm_test_cc(DisasCompare *cmp, int cc)
659 TCGv_i32 value;
660 TCGCond cond;
661 bool global = true;
663 switch (cc) {
664 case 0: /* eq: Z */
665 case 1: /* ne: !Z */
666 cond = TCG_COND_EQ;
667 value = cpu_ZF;
668 break;
670 case 2: /* cs: C */
671 case 3: /* cc: !C */
672 cond = TCG_COND_NE;
673 value = cpu_CF;
674 break;
676 case 4: /* mi: N */
677 case 5: /* pl: !N */
678 cond = TCG_COND_LT;
679 value = cpu_NF;
680 break;
682 case 6: /* vs: V */
683 case 7: /* vc: !V */
684 cond = TCG_COND_LT;
685 value = cpu_VF;
686 break;
688 case 8: /* hi: C && !Z */
689 case 9: /* ls: !C || Z -> !(C && !Z) */
690 cond = TCG_COND_NE;
691 value = tcg_temp_new_i32();
692 global = false;
693 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
694 ZF is non-zero for !Z; so AND the two subexpressions. */
695 tcg_gen_neg_i32(value, cpu_CF);
696 tcg_gen_and_i32(value, value, cpu_ZF);
697 break;
699 case 10: /* ge: N == V -> N ^ V == 0 */
700 case 11: /* lt: N != V -> N ^ V != 0 */
701 /* Since we're only interested in the sign bit, == 0 is >= 0. */
702 cond = TCG_COND_GE;
703 value = tcg_temp_new_i32();
704 global = false;
705 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
706 break;
708 case 12: /* gt: !Z && N == V */
709 case 13: /* le: Z || N != V */
710 cond = TCG_COND_NE;
711 value = tcg_temp_new_i32();
712 global = false;
713 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
714 * the sign bit then AND with ZF to yield the result. */
715 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
716 tcg_gen_sari_i32(value, value, 31);
717 tcg_gen_andc_i32(value, cpu_ZF, value);
718 break;
720 case 14: /* always */
721 case 15: /* always */
722 /* Use the ALWAYS condition, which will fold early.
723 * It doesn't matter what we use for the value. */
724 cond = TCG_COND_ALWAYS;
725 value = cpu_ZF;
726 goto no_invert;
728 default:
729 fprintf(stderr, "Bad condition code 0x%x\n", cc);
730 abort();
733 if (cc & 1) {
734 cond = tcg_invert_cond(cond);
737 no_invert:
738 cmp->cond = cond;
739 cmp->value = value;
740 cmp->value_global = global;
743 void arm_free_cc(DisasCompare *cmp)
745 if (!cmp->value_global) {
746 tcg_temp_free_i32(cmp->value);
750 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
752 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
755 void arm_gen_test_cc(int cc, TCGLabel *label)
757 DisasCompare cmp;
758 arm_test_cc(&cmp, cc);
759 arm_jump_cc(&cmp, label);
760 arm_free_cc(&cmp);
763 void gen_set_condexec(DisasContext *s)
765 if (s->condexec_mask) {
766 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
767 TCGv_i32 tmp = tcg_temp_new_i32();
768 tcg_gen_movi_i32(tmp, val);
769 store_cpu_field(tmp, condexec_bits);
773 void gen_set_pc_im(DisasContext *s, target_ulong val)
775 tcg_gen_movi_i32(cpu_R[15], val);
778 /* Set PC and Thumb state from var. var is marked as dead. */
779 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
781 s->base.is_jmp = DISAS_JUMP;
782 tcg_gen_andi_i32(cpu_R[15], var, ~1);
783 tcg_gen_andi_i32(var, var, 1);
784 store_cpu_field(var, thumb);
788 * Set PC and Thumb state from var. var is marked as dead.
789 * For M-profile CPUs, include logic to detect exception-return
790 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
791 * and BX reg, and no others, and happens only for code in Handler mode.
792 * The Security Extension also requires us to check for the FNC_RETURN
793 * which signals a function return from non-secure state; this can happen
794 * in both Handler and Thread mode.
795 * To avoid having to do multiple comparisons in inline generated code,
796 * we make the check we do here loose, so it will match for EXC_RETURN
797 * in Thread mode. For system emulation do_v7m_exception_exit() checks
798 * for these spurious cases and returns without doing anything (giving
799 * the same behaviour as for a branch to a non-magic address).
801 * In linux-user mode it is unclear what the right behaviour for an
802 * attempted FNC_RETURN should be, because in real hardware this will go
803 * directly to Secure code (ie not the Linux kernel) which will then treat
804 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
805 * attempt behave the way it would on a CPU without the security extension,
806 * which is to say "like a normal branch". That means we can simply treat
807 * all branches as normal with no magic address behaviour.
809 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
811 /* Generate the same code here as for a simple bx, but flag via
812 * s->base.is_jmp that we need to do the rest of the work later.
814 gen_bx(s, var);
815 #ifndef CONFIG_USER_ONLY
816 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
817 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
818 s->base.is_jmp = DISAS_BX_EXCRET;
820 #endif
823 static inline void gen_bx_excret_final_code(DisasContext *s)
825 /* Generate the code to finish possible exception return and end the TB */
826 TCGLabel *excret_label = gen_new_label();
827 uint32_t min_magic;
829 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
830 /* Covers FNC_RETURN and EXC_RETURN magic */
831 min_magic = FNC_RETURN_MIN_MAGIC;
832 } else {
833 /* EXC_RETURN magic only */
834 min_magic = EXC_RETURN_MIN_MAGIC;
837 /* Is the new PC value in the magic range indicating exception return? */
838 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
839 /* No: end the TB as we would for a DISAS_JMP */
840 if (is_singlestepping(s)) {
841 gen_singlestep_exception(s);
842 } else {
843 tcg_gen_exit_tb(NULL, 0);
845 gen_set_label(excret_label);
846 /* Yes: this is an exception return.
847 * At this point in runtime env->regs[15] and env->thumb will hold
848 * the exception-return magic number, which do_v7m_exception_exit()
849 * will read. Nothing else will be able to see those values because
850 * the cpu-exec main loop guarantees that we will always go straight
851 * from raising the exception to the exception-handling code.
853 * gen_ss_advance(s) does nothing on M profile currently but
854 * calling it is conceptually the right thing as we have executed
855 * this instruction (compare SWI, HVC, SMC handling).
857 gen_ss_advance(s);
858 gen_exception_internal(EXCP_EXCEPTION_EXIT);
861 static inline void gen_bxns(DisasContext *s, int rm)
863 TCGv_i32 var = load_reg(s, rm);
865 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
866 * we need to sync state before calling it, but:
867 * - we don't need to do gen_set_pc_im() because the bxns helper will
868 * always set the PC itself
869 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
870 * unless it's outside an IT block or the last insn in an IT block,
871 * so we know that condexec == 0 (already set at the top of the TB)
872 * is correct in the non-UNPREDICTABLE cases, and we can choose
873 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
875 gen_helper_v7m_bxns(cpu_env, var);
876 tcg_temp_free_i32(var);
877 s->base.is_jmp = DISAS_EXIT;
880 static inline void gen_blxns(DisasContext *s, int rm)
882 TCGv_i32 var = load_reg(s, rm);
884 /* We don't need to sync condexec state, for the same reason as bxns.
885 * We do however need to set the PC, because the blxns helper reads it.
886 * The blxns helper may throw an exception.
888 gen_set_pc_im(s, s->base.pc_next);
889 gen_helper_v7m_blxns(cpu_env, var);
890 tcg_temp_free_i32(var);
891 s->base.is_jmp = DISAS_EXIT;
894 /* Variant of store_reg which uses branch&exchange logic when storing
895 to r15 in ARM architecture v7 and above. The source must be a temporary
896 and will be marked as dead. */
897 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
899 if (reg == 15 && ENABLE_ARCH_7) {
900 gen_bx(s, var);
901 } else {
902 store_reg(s, reg, var);
906 /* Variant of store_reg which uses branch&exchange logic when storing
907 * to r15 in ARM architecture v5T and above. This is used for storing
908 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
909 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
910 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
912 if (reg == 15 && ENABLE_ARCH_5) {
913 gen_bx_excret(s, var);
914 } else {
915 store_reg(s, reg, var);
919 #ifdef CONFIG_USER_ONLY
920 #define IS_USER_ONLY 1
921 #else
922 #define IS_USER_ONLY 0
923 #endif
925 MemOp pow2_align(unsigned i)
927 static const MemOp mop_align[] = {
928 0, MO_ALIGN_2, MO_ALIGN_4, MO_ALIGN_8, MO_ALIGN_16,
930 * FIXME: TARGET_PAGE_BITS_MIN affects TLB_FLAGS_MASK such
931 * that 256-bit alignment (MO_ALIGN_32) cannot be supported:
932 * see get_alignment_bits(). Enforce only 128-bit alignment for now.
934 MO_ALIGN_16
936 g_assert(i < ARRAY_SIZE(mop_align));
937 return mop_align[i];
941 * Abstractions of "generate code to do a guest load/store for
942 * AArch32", where a vaddr is always 32 bits (and is zero
943 * extended if we're a 64 bit core) and data is also
944 * 32 bits unless specifically doing a 64 bit access.
945 * These functions work like tcg_gen_qemu_{ld,st}* except
946 * that the address argument is TCGv_i32 rather than TCGv.
949 static TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
951 TCGv addr = tcg_temp_new();
952 tcg_gen_extu_i32_tl(addr, a32);
954 /* Not needed for user-mode BE32, where we use MO_BE instead. */
955 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
956 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
958 return addr;
962 * Internal routines are used for NEON cases where the endianness
963 * and/or alignment has already been taken into account and manipulated.
965 void gen_aa32_ld_internal_i32(DisasContext *s, TCGv_i32 val,
966 TCGv_i32 a32, int index, MemOp opc)
968 TCGv addr = gen_aa32_addr(s, a32, opc);
969 tcg_gen_qemu_ld_i32(val, addr, index, opc);
970 tcg_temp_free(addr);
973 void gen_aa32_st_internal_i32(DisasContext *s, TCGv_i32 val,
974 TCGv_i32 a32, int index, MemOp opc)
976 TCGv addr = gen_aa32_addr(s, a32, opc);
977 tcg_gen_qemu_st_i32(val, addr, index, opc);
978 tcg_temp_free(addr);
981 void gen_aa32_ld_internal_i64(DisasContext *s, TCGv_i64 val,
982 TCGv_i32 a32, int index, MemOp opc)
984 TCGv addr = gen_aa32_addr(s, a32, opc);
986 tcg_gen_qemu_ld_i64(val, addr, index, opc);
988 /* Not needed for user-mode BE32, where we use MO_BE instead. */
989 if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
990 tcg_gen_rotri_i64(val, val, 32);
992 tcg_temp_free(addr);
995 void gen_aa32_st_internal_i64(DisasContext *s, TCGv_i64 val,
996 TCGv_i32 a32, int index, MemOp opc)
998 TCGv addr = gen_aa32_addr(s, a32, opc);
1000 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1001 if (!IS_USER_ONLY && s->sctlr_b && (opc & MO_SIZE) == MO_64) {
1002 TCGv_i64 tmp = tcg_temp_new_i64();
1003 tcg_gen_rotri_i64(tmp, val, 32);
1004 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1005 tcg_temp_free_i64(tmp);
1006 } else {
1007 tcg_gen_qemu_st_i64(val, addr, index, opc);
1009 tcg_temp_free(addr);
1012 void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1013 int index, MemOp opc)
1015 gen_aa32_ld_internal_i32(s, val, a32, index, finalize_memop(s, opc));
1018 void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1019 int index, MemOp opc)
1021 gen_aa32_st_internal_i32(s, val, a32, index, finalize_memop(s, opc));
1024 void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1025 int index, MemOp opc)
1027 gen_aa32_ld_internal_i64(s, val, a32, index, finalize_memop(s, opc));
1030 void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1031 int index, MemOp opc)
1033 gen_aa32_st_internal_i64(s, val, a32, index, finalize_memop(s, opc));
1036 #define DO_GEN_LD(SUFF, OPC) \
1037 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1038 TCGv_i32 a32, int index) \
1040 gen_aa32_ld_i32(s, val, a32, index, OPC); \
1043 #define DO_GEN_ST(SUFF, OPC) \
1044 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1045 TCGv_i32 a32, int index) \
1047 gen_aa32_st_i32(s, val, a32, index, OPC); \
1050 static inline void gen_hvc(DisasContext *s, int imm16)
1052 /* The pre HVC helper handles cases when HVC gets trapped
1053 * as an undefined insn by runtime configuration (ie before
1054 * the insn really executes).
1056 gen_set_pc_im(s, s->pc_curr);
1057 gen_helper_pre_hvc(cpu_env);
1058 /* Otherwise we will treat this as a real exception which
1059 * happens after execution of the insn. (The distinction matters
1060 * for the PC value reported to the exception handler and also
1061 * for single stepping.)
1063 s->svc_imm = imm16;
1064 gen_set_pc_im(s, s->base.pc_next);
1065 s->base.is_jmp = DISAS_HVC;
1068 static inline void gen_smc(DisasContext *s)
1070 /* As with HVC, we may take an exception either before or after
1071 * the insn executes.
1073 TCGv_i32 tmp;
1075 gen_set_pc_im(s, s->pc_curr);
1076 tmp = tcg_const_i32(syn_aa32_smc());
1077 gen_helper_pre_smc(cpu_env, tmp);
1078 tcg_temp_free_i32(tmp);
1079 gen_set_pc_im(s, s->base.pc_next);
1080 s->base.is_jmp = DISAS_SMC;
1083 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1085 gen_set_condexec(s);
1086 gen_set_pc_im(s, pc);
1087 gen_exception_internal(excp);
1088 s->base.is_jmp = DISAS_NORETURN;
1091 void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
1092 uint32_t syn, uint32_t target_el)
1094 if (s->aarch64) {
1095 gen_a64_set_pc_im(pc);
1096 } else {
1097 gen_set_condexec(s);
1098 gen_set_pc_im(s, pc);
1100 gen_exception(excp, syn, target_el);
1101 s->base.is_jmp = DISAS_NORETURN;
1104 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1106 TCGv_i32 tcg_syn;
1108 gen_set_condexec(s);
1109 gen_set_pc_im(s, s->pc_curr);
1110 tcg_syn = tcg_const_i32(syn);
1111 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1112 tcg_temp_free_i32(tcg_syn);
1113 s->base.is_jmp = DISAS_NORETURN;
1116 void unallocated_encoding(DisasContext *s)
1118 /* Unallocated and reserved encodings are uncategorized */
1119 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1120 default_exception_el(s));
1123 static void gen_exception_el(DisasContext *s, int excp, uint32_t syn,
1124 TCGv_i32 tcg_el)
1126 TCGv_i32 tcg_excp;
1127 TCGv_i32 tcg_syn;
1129 gen_set_condexec(s);
1130 gen_set_pc_im(s, s->pc_curr);
1131 tcg_excp = tcg_const_i32(excp);
1132 tcg_syn = tcg_const_i32(syn);
1133 gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn, tcg_el);
1134 tcg_temp_free_i32(tcg_syn);
1135 tcg_temp_free_i32(tcg_excp);
1136 s->base.is_jmp = DISAS_NORETURN;
1139 /* Force a TB lookup after an instruction that changes the CPU state. */
1140 void gen_lookup_tb(DisasContext *s)
1142 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1143 s->base.is_jmp = DISAS_EXIT;
1146 static inline void gen_hlt(DisasContext *s, int imm)
1148 /* HLT. This has two purposes.
1149 * Architecturally, it is an external halting debug instruction.
1150 * Since QEMU doesn't implement external debug, we treat this as
1151 * it is required for halting debug disabled: it will UNDEF.
1152 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1153 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1154 * must trigger semihosting even for ARMv7 and earlier, where
1155 * HLT was an undefined encoding.
1156 * In system mode, we don't allow userspace access to
1157 * semihosting, to provide some semblance of security
1158 * (and for consistency with our 32-bit semihosting).
1160 if (semihosting_enabled() &&
1161 #ifndef CONFIG_USER_ONLY
1162 s->current_el != 0 &&
1163 #endif
1164 (imm == (s->thumb ? 0x3c : 0xf000))) {
1165 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
1166 return;
1169 unallocated_encoding(s);
1173 * Return the offset of a "full" NEON Dreg.
1175 long neon_full_reg_offset(unsigned reg)
1177 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1181 * Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1182 * where 0 is the least significant end of the register.
1184 long neon_element_offset(int reg, int element, MemOp memop)
1186 int element_size = 1 << (memop & MO_SIZE);
1187 int ofs = element * element_size;
1188 #ifdef HOST_WORDS_BIGENDIAN
1190 * Calculate the offset assuming fully little-endian,
1191 * then XOR to account for the order of the 8-byte units.
1193 if (element_size < 8) {
1194 ofs ^= 8 - element_size;
1196 #endif
1197 return neon_full_reg_offset(reg) + ofs;
1200 /* Return the offset of a VFP Dreg (dp = true) or VFP Sreg (dp = false). */
1201 long vfp_reg_offset(bool dp, unsigned reg)
1203 if (dp) {
1204 return neon_element_offset(reg, 0, MO_64);
1205 } else {
1206 return neon_element_offset(reg >> 1, reg & 1, MO_32);
1210 void read_neon_element32(TCGv_i32 dest, int reg, int ele, MemOp memop)
1212 long off = neon_element_offset(reg, ele, memop);
1214 switch (memop) {
1215 case MO_SB:
1216 tcg_gen_ld8s_i32(dest, cpu_env, off);
1217 break;
1218 case MO_UB:
1219 tcg_gen_ld8u_i32(dest, cpu_env, off);
1220 break;
1221 case MO_SW:
1222 tcg_gen_ld16s_i32(dest, cpu_env, off);
1223 break;
1224 case MO_UW:
1225 tcg_gen_ld16u_i32(dest, cpu_env, off);
1226 break;
1227 case MO_UL:
1228 case MO_SL:
1229 tcg_gen_ld_i32(dest, cpu_env, off);
1230 break;
1231 default:
1232 g_assert_not_reached();
1236 void read_neon_element64(TCGv_i64 dest, int reg, int ele, MemOp memop)
1238 long off = neon_element_offset(reg, ele, memop);
1240 switch (memop) {
1241 case MO_SL:
1242 tcg_gen_ld32s_i64(dest, cpu_env, off);
1243 break;
1244 case MO_UL:
1245 tcg_gen_ld32u_i64(dest, cpu_env, off);
1246 break;
1247 case MO_Q:
1248 tcg_gen_ld_i64(dest, cpu_env, off);
1249 break;
1250 default:
1251 g_assert_not_reached();
1255 void write_neon_element32(TCGv_i32 src, int reg, int ele, MemOp memop)
1257 long off = neon_element_offset(reg, ele, memop);
1259 switch (memop) {
1260 case MO_8:
1261 tcg_gen_st8_i32(src, cpu_env, off);
1262 break;
1263 case MO_16:
1264 tcg_gen_st16_i32(src, cpu_env, off);
1265 break;
1266 case MO_32:
1267 tcg_gen_st_i32(src, cpu_env, off);
1268 break;
1269 default:
1270 g_assert_not_reached();
1274 void write_neon_element64(TCGv_i64 src, int reg, int ele, MemOp memop)
1276 long off = neon_element_offset(reg, ele, memop);
1278 switch (memop) {
1279 case MO_32:
1280 tcg_gen_st32_i64(src, cpu_env, off);
1281 break;
1282 case MO_64:
1283 tcg_gen_st_i64(src, cpu_env, off);
1284 break;
1285 default:
1286 g_assert_not_reached();
1290 #define ARM_CP_RW_BIT (1 << 20)
1292 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1294 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1297 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1299 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1302 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1304 TCGv_i32 var = tcg_temp_new_i32();
1305 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1306 return var;
1309 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1311 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1312 tcg_temp_free_i32(var);
1315 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1317 iwmmxt_store_reg(cpu_M0, rn);
1320 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1322 iwmmxt_load_reg(cpu_M0, rn);
1325 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1327 iwmmxt_load_reg(cpu_V1, rn);
1328 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1331 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1333 iwmmxt_load_reg(cpu_V1, rn);
1334 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1337 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1339 iwmmxt_load_reg(cpu_V1, rn);
1340 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1343 #define IWMMXT_OP(name) \
1344 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1346 iwmmxt_load_reg(cpu_V1, rn); \
1347 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1350 #define IWMMXT_OP_ENV(name) \
1351 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1353 iwmmxt_load_reg(cpu_V1, rn); \
1354 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1357 #define IWMMXT_OP_ENV_SIZE(name) \
1358 IWMMXT_OP_ENV(name##b) \
1359 IWMMXT_OP_ENV(name##w) \
1360 IWMMXT_OP_ENV(name##l)
1362 #define IWMMXT_OP_ENV1(name) \
1363 static inline void gen_op_iwmmxt_##name##_M0(void) \
1365 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1368 IWMMXT_OP(maddsq)
1369 IWMMXT_OP(madduq)
1370 IWMMXT_OP(sadb)
1371 IWMMXT_OP(sadw)
1372 IWMMXT_OP(mulslw)
1373 IWMMXT_OP(mulshw)
1374 IWMMXT_OP(mululw)
1375 IWMMXT_OP(muluhw)
1376 IWMMXT_OP(macsw)
1377 IWMMXT_OP(macuw)
1379 IWMMXT_OP_ENV_SIZE(unpackl)
1380 IWMMXT_OP_ENV_SIZE(unpackh)
1382 IWMMXT_OP_ENV1(unpacklub)
1383 IWMMXT_OP_ENV1(unpackluw)
1384 IWMMXT_OP_ENV1(unpacklul)
1385 IWMMXT_OP_ENV1(unpackhub)
1386 IWMMXT_OP_ENV1(unpackhuw)
1387 IWMMXT_OP_ENV1(unpackhul)
1388 IWMMXT_OP_ENV1(unpacklsb)
1389 IWMMXT_OP_ENV1(unpacklsw)
1390 IWMMXT_OP_ENV1(unpacklsl)
1391 IWMMXT_OP_ENV1(unpackhsb)
1392 IWMMXT_OP_ENV1(unpackhsw)
1393 IWMMXT_OP_ENV1(unpackhsl)
1395 IWMMXT_OP_ENV_SIZE(cmpeq)
1396 IWMMXT_OP_ENV_SIZE(cmpgtu)
1397 IWMMXT_OP_ENV_SIZE(cmpgts)
1399 IWMMXT_OP_ENV_SIZE(mins)
1400 IWMMXT_OP_ENV_SIZE(minu)
1401 IWMMXT_OP_ENV_SIZE(maxs)
1402 IWMMXT_OP_ENV_SIZE(maxu)
1404 IWMMXT_OP_ENV_SIZE(subn)
1405 IWMMXT_OP_ENV_SIZE(addn)
1406 IWMMXT_OP_ENV_SIZE(subu)
1407 IWMMXT_OP_ENV_SIZE(addu)
1408 IWMMXT_OP_ENV_SIZE(subs)
1409 IWMMXT_OP_ENV_SIZE(adds)
1411 IWMMXT_OP_ENV(avgb0)
1412 IWMMXT_OP_ENV(avgb1)
1413 IWMMXT_OP_ENV(avgw0)
1414 IWMMXT_OP_ENV(avgw1)
1416 IWMMXT_OP_ENV(packuw)
1417 IWMMXT_OP_ENV(packul)
1418 IWMMXT_OP_ENV(packuq)
1419 IWMMXT_OP_ENV(packsw)
1420 IWMMXT_OP_ENV(packsl)
1421 IWMMXT_OP_ENV(packsq)
1423 static void gen_op_iwmmxt_set_mup(void)
1425 TCGv_i32 tmp;
1426 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1427 tcg_gen_ori_i32(tmp, tmp, 2);
1428 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1431 static void gen_op_iwmmxt_set_cup(void)
1433 TCGv_i32 tmp;
1434 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1435 tcg_gen_ori_i32(tmp, tmp, 1);
1436 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1439 static void gen_op_iwmmxt_setpsr_nz(void)
1441 TCGv_i32 tmp = tcg_temp_new_i32();
1442 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1443 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1446 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1448 iwmmxt_load_reg(cpu_V1, rn);
1449 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1450 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1453 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1454 TCGv_i32 dest)
1456 int rd;
1457 uint32_t offset;
1458 TCGv_i32 tmp;
1460 rd = (insn >> 16) & 0xf;
1461 tmp = load_reg(s, rd);
1463 offset = (insn & 0xff) << ((insn >> 7) & 2);
1464 if (insn & (1 << 24)) {
1465 /* Pre indexed */
1466 if (insn & (1 << 23))
1467 tcg_gen_addi_i32(tmp, tmp, offset);
1468 else
1469 tcg_gen_addi_i32(tmp, tmp, -offset);
1470 tcg_gen_mov_i32(dest, tmp);
1471 if (insn & (1 << 21))
1472 store_reg(s, rd, tmp);
1473 else
1474 tcg_temp_free_i32(tmp);
1475 } else if (insn & (1 << 21)) {
1476 /* Post indexed */
1477 tcg_gen_mov_i32(dest, tmp);
1478 if (insn & (1 << 23))
1479 tcg_gen_addi_i32(tmp, tmp, offset);
1480 else
1481 tcg_gen_addi_i32(tmp, tmp, -offset);
1482 store_reg(s, rd, tmp);
1483 } else if (!(insn & (1 << 23)))
1484 return 1;
1485 return 0;
1488 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1490 int rd = (insn >> 0) & 0xf;
1491 TCGv_i32 tmp;
1493 if (insn & (1 << 8)) {
1494 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1495 return 1;
1496 } else {
1497 tmp = iwmmxt_load_creg(rd);
1499 } else {
1500 tmp = tcg_temp_new_i32();
1501 iwmmxt_load_reg(cpu_V0, rd);
1502 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1504 tcg_gen_andi_i32(tmp, tmp, mask);
1505 tcg_gen_mov_i32(dest, tmp);
1506 tcg_temp_free_i32(tmp);
1507 return 0;
1510 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1511 (ie. an undefined instruction). */
1512 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1514 int rd, wrd;
1515 int rdhi, rdlo, rd0, rd1, i;
1516 TCGv_i32 addr;
1517 TCGv_i32 tmp, tmp2, tmp3;
1519 if ((insn & 0x0e000e00) == 0x0c000000) {
1520 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1521 wrd = insn & 0xf;
1522 rdlo = (insn >> 12) & 0xf;
1523 rdhi = (insn >> 16) & 0xf;
1524 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1525 iwmmxt_load_reg(cpu_V0, wrd);
1526 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1527 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1528 } else { /* TMCRR */
1529 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1530 iwmmxt_store_reg(cpu_V0, wrd);
1531 gen_op_iwmmxt_set_mup();
1533 return 0;
1536 wrd = (insn >> 12) & 0xf;
1537 addr = tcg_temp_new_i32();
1538 if (gen_iwmmxt_address(s, insn, addr)) {
1539 tcg_temp_free_i32(addr);
1540 return 1;
1542 if (insn & ARM_CP_RW_BIT) {
1543 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1544 tmp = tcg_temp_new_i32();
1545 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1546 iwmmxt_store_creg(wrd, tmp);
1547 } else {
1548 i = 1;
1549 if (insn & (1 << 8)) {
1550 if (insn & (1 << 22)) { /* WLDRD */
1551 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1552 i = 0;
1553 } else { /* WLDRW wRd */
1554 tmp = tcg_temp_new_i32();
1555 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1557 } else {
1558 tmp = tcg_temp_new_i32();
1559 if (insn & (1 << 22)) { /* WLDRH */
1560 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1561 } else { /* WLDRB */
1562 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1565 if (i) {
1566 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1567 tcg_temp_free_i32(tmp);
1569 gen_op_iwmmxt_movq_wRn_M0(wrd);
1571 } else {
1572 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1573 tmp = iwmmxt_load_creg(wrd);
1574 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1575 } else {
1576 gen_op_iwmmxt_movq_M0_wRn(wrd);
1577 tmp = tcg_temp_new_i32();
1578 if (insn & (1 << 8)) {
1579 if (insn & (1 << 22)) { /* WSTRD */
1580 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1581 } else { /* WSTRW wRd */
1582 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1583 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1585 } else {
1586 if (insn & (1 << 22)) { /* WSTRH */
1587 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1588 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1589 } else { /* WSTRB */
1590 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1591 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1595 tcg_temp_free_i32(tmp);
1597 tcg_temp_free_i32(addr);
1598 return 0;
1601 if ((insn & 0x0f000000) != 0x0e000000)
1602 return 1;
1604 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1605 case 0x000: /* WOR */
1606 wrd = (insn >> 12) & 0xf;
1607 rd0 = (insn >> 0) & 0xf;
1608 rd1 = (insn >> 16) & 0xf;
1609 gen_op_iwmmxt_movq_M0_wRn(rd0);
1610 gen_op_iwmmxt_orq_M0_wRn(rd1);
1611 gen_op_iwmmxt_setpsr_nz();
1612 gen_op_iwmmxt_movq_wRn_M0(wrd);
1613 gen_op_iwmmxt_set_mup();
1614 gen_op_iwmmxt_set_cup();
1615 break;
1616 case 0x011: /* TMCR */
1617 if (insn & 0xf)
1618 return 1;
1619 rd = (insn >> 12) & 0xf;
1620 wrd = (insn >> 16) & 0xf;
1621 switch (wrd) {
1622 case ARM_IWMMXT_wCID:
1623 case ARM_IWMMXT_wCASF:
1624 break;
1625 case ARM_IWMMXT_wCon:
1626 gen_op_iwmmxt_set_cup();
1627 /* Fall through. */
1628 case ARM_IWMMXT_wCSSF:
1629 tmp = iwmmxt_load_creg(wrd);
1630 tmp2 = load_reg(s, rd);
1631 tcg_gen_andc_i32(tmp, tmp, tmp2);
1632 tcg_temp_free_i32(tmp2);
1633 iwmmxt_store_creg(wrd, tmp);
1634 break;
1635 case ARM_IWMMXT_wCGR0:
1636 case ARM_IWMMXT_wCGR1:
1637 case ARM_IWMMXT_wCGR2:
1638 case ARM_IWMMXT_wCGR3:
1639 gen_op_iwmmxt_set_cup();
1640 tmp = load_reg(s, rd);
1641 iwmmxt_store_creg(wrd, tmp);
1642 break;
1643 default:
1644 return 1;
1646 break;
1647 case 0x100: /* WXOR */
1648 wrd = (insn >> 12) & 0xf;
1649 rd0 = (insn >> 0) & 0xf;
1650 rd1 = (insn >> 16) & 0xf;
1651 gen_op_iwmmxt_movq_M0_wRn(rd0);
1652 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1653 gen_op_iwmmxt_setpsr_nz();
1654 gen_op_iwmmxt_movq_wRn_M0(wrd);
1655 gen_op_iwmmxt_set_mup();
1656 gen_op_iwmmxt_set_cup();
1657 break;
1658 case 0x111: /* TMRC */
1659 if (insn & 0xf)
1660 return 1;
1661 rd = (insn >> 12) & 0xf;
1662 wrd = (insn >> 16) & 0xf;
1663 tmp = iwmmxt_load_creg(wrd);
1664 store_reg(s, rd, tmp);
1665 break;
1666 case 0x300: /* WANDN */
1667 wrd = (insn >> 12) & 0xf;
1668 rd0 = (insn >> 0) & 0xf;
1669 rd1 = (insn >> 16) & 0xf;
1670 gen_op_iwmmxt_movq_M0_wRn(rd0);
1671 tcg_gen_neg_i64(cpu_M0, cpu_M0);
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 0x200: /* WAND */
1679 wrd = (insn >> 12) & 0xf;
1680 rd0 = (insn >> 0) & 0xf;
1681 rd1 = (insn >> 16) & 0xf;
1682 gen_op_iwmmxt_movq_M0_wRn(rd0);
1683 gen_op_iwmmxt_andq_M0_wRn(rd1);
1684 gen_op_iwmmxt_setpsr_nz();
1685 gen_op_iwmmxt_movq_wRn_M0(wrd);
1686 gen_op_iwmmxt_set_mup();
1687 gen_op_iwmmxt_set_cup();
1688 break;
1689 case 0x810: case 0xa10: /* WMADD */
1690 wrd = (insn >> 12) & 0xf;
1691 rd0 = (insn >> 0) & 0xf;
1692 rd1 = (insn >> 16) & 0xf;
1693 gen_op_iwmmxt_movq_M0_wRn(rd0);
1694 if (insn & (1 << 21))
1695 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1696 else
1697 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1698 gen_op_iwmmxt_movq_wRn_M0(wrd);
1699 gen_op_iwmmxt_set_mup();
1700 break;
1701 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1702 wrd = (insn >> 12) & 0xf;
1703 rd0 = (insn >> 16) & 0xf;
1704 rd1 = (insn >> 0) & 0xf;
1705 gen_op_iwmmxt_movq_M0_wRn(rd0);
1706 switch ((insn >> 22) & 3) {
1707 case 0:
1708 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1709 break;
1710 case 1:
1711 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1712 break;
1713 case 2:
1714 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1715 break;
1716 case 3:
1717 return 1;
1719 gen_op_iwmmxt_movq_wRn_M0(wrd);
1720 gen_op_iwmmxt_set_mup();
1721 gen_op_iwmmxt_set_cup();
1722 break;
1723 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1724 wrd = (insn >> 12) & 0xf;
1725 rd0 = (insn >> 16) & 0xf;
1726 rd1 = (insn >> 0) & 0xf;
1727 gen_op_iwmmxt_movq_M0_wRn(rd0);
1728 switch ((insn >> 22) & 3) {
1729 case 0:
1730 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1731 break;
1732 case 1:
1733 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1734 break;
1735 case 2:
1736 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1737 break;
1738 case 3:
1739 return 1;
1741 gen_op_iwmmxt_movq_wRn_M0(wrd);
1742 gen_op_iwmmxt_set_mup();
1743 gen_op_iwmmxt_set_cup();
1744 break;
1745 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1746 wrd = (insn >> 12) & 0xf;
1747 rd0 = (insn >> 16) & 0xf;
1748 rd1 = (insn >> 0) & 0xf;
1749 gen_op_iwmmxt_movq_M0_wRn(rd0);
1750 if (insn & (1 << 22))
1751 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1752 else
1753 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1754 if (!(insn & (1 << 20)))
1755 gen_op_iwmmxt_addl_M0_wRn(wrd);
1756 gen_op_iwmmxt_movq_wRn_M0(wrd);
1757 gen_op_iwmmxt_set_mup();
1758 break;
1759 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1760 wrd = (insn >> 12) & 0xf;
1761 rd0 = (insn >> 16) & 0xf;
1762 rd1 = (insn >> 0) & 0xf;
1763 gen_op_iwmmxt_movq_M0_wRn(rd0);
1764 if (insn & (1 << 21)) {
1765 if (insn & (1 << 20))
1766 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1767 else
1768 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1769 } else {
1770 if (insn & (1 << 20))
1771 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1772 else
1773 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1775 gen_op_iwmmxt_movq_wRn_M0(wrd);
1776 gen_op_iwmmxt_set_mup();
1777 break;
1778 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1779 wrd = (insn >> 12) & 0xf;
1780 rd0 = (insn >> 16) & 0xf;
1781 rd1 = (insn >> 0) & 0xf;
1782 gen_op_iwmmxt_movq_M0_wRn(rd0);
1783 if (insn & (1 << 21))
1784 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1785 else
1786 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1787 if (!(insn & (1 << 20))) {
1788 iwmmxt_load_reg(cpu_V1, wrd);
1789 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1791 gen_op_iwmmxt_movq_wRn_M0(wrd);
1792 gen_op_iwmmxt_set_mup();
1793 break;
1794 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1795 wrd = (insn >> 12) & 0xf;
1796 rd0 = (insn >> 16) & 0xf;
1797 rd1 = (insn >> 0) & 0xf;
1798 gen_op_iwmmxt_movq_M0_wRn(rd0);
1799 switch ((insn >> 22) & 3) {
1800 case 0:
1801 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1802 break;
1803 case 1:
1804 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1805 break;
1806 case 2:
1807 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1808 break;
1809 case 3:
1810 return 1;
1812 gen_op_iwmmxt_movq_wRn_M0(wrd);
1813 gen_op_iwmmxt_set_mup();
1814 gen_op_iwmmxt_set_cup();
1815 break;
1816 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1817 wrd = (insn >> 12) & 0xf;
1818 rd0 = (insn >> 16) & 0xf;
1819 rd1 = (insn >> 0) & 0xf;
1820 gen_op_iwmmxt_movq_M0_wRn(rd0);
1821 if (insn & (1 << 22)) {
1822 if (insn & (1 << 20))
1823 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1824 else
1825 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1826 } else {
1827 if (insn & (1 << 20))
1828 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1829 else
1830 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1832 gen_op_iwmmxt_movq_wRn_M0(wrd);
1833 gen_op_iwmmxt_set_mup();
1834 gen_op_iwmmxt_set_cup();
1835 break;
1836 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1837 wrd = (insn >> 12) & 0xf;
1838 rd0 = (insn >> 16) & 0xf;
1839 rd1 = (insn >> 0) & 0xf;
1840 gen_op_iwmmxt_movq_M0_wRn(rd0);
1841 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1842 tcg_gen_andi_i32(tmp, tmp, 7);
1843 iwmmxt_load_reg(cpu_V1, rd1);
1844 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1845 tcg_temp_free_i32(tmp);
1846 gen_op_iwmmxt_movq_wRn_M0(wrd);
1847 gen_op_iwmmxt_set_mup();
1848 break;
1849 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1850 if (((insn >> 6) & 3) == 3)
1851 return 1;
1852 rd = (insn >> 12) & 0xf;
1853 wrd = (insn >> 16) & 0xf;
1854 tmp = load_reg(s, rd);
1855 gen_op_iwmmxt_movq_M0_wRn(wrd);
1856 switch ((insn >> 6) & 3) {
1857 case 0:
1858 tmp2 = tcg_const_i32(0xff);
1859 tmp3 = tcg_const_i32((insn & 7) << 3);
1860 break;
1861 case 1:
1862 tmp2 = tcg_const_i32(0xffff);
1863 tmp3 = tcg_const_i32((insn & 3) << 4);
1864 break;
1865 case 2:
1866 tmp2 = tcg_const_i32(0xffffffff);
1867 tmp3 = tcg_const_i32((insn & 1) << 5);
1868 break;
1869 default:
1870 tmp2 = NULL;
1871 tmp3 = NULL;
1873 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1874 tcg_temp_free_i32(tmp3);
1875 tcg_temp_free_i32(tmp2);
1876 tcg_temp_free_i32(tmp);
1877 gen_op_iwmmxt_movq_wRn_M0(wrd);
1878 gen_op_iwmmxt_set_mup();
1879 break;
1880 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1881 rd = (insn >> 12) & 0xf;
1882 wrd = (insn >> 16) & 0xf;
1883 if (rd == 15 || ((insn >> 22) & 3) == 3)
1884 return 1;
1885 gen_op_iwmmxt_movq_M0_wRn(wrd);
1886 tmp = tcg_temp_new_i32();
1887 switch ((insn >> 22) & 3) {
1888 case 0:
1889 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1890 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1891 if (insn & 8) {
1892 tcg_gen_ext8s_i32(tmp, tmp);
1893 } else {
1894 tcg_gen_andi_i32(tmp, tmp, 0xff);
1896 break;
1897 case 1:
1898 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1899 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1900 if (insn & 8) {
1901 tcg_gen_ext16s_i32(tmp, tmp);
1902 } else {
1903 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1905 break;
1906 case 2:
1907 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1908 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1909 break;
1911 store_reg(s, rd, tmp);
1912 break;
1913 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1914 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1915 return 1;
1916 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1917 switch ((insn >> 22) & 3) {
1918 case 0:
1919 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1920 break;
1921 case 1:
1922 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1923 break;
1924 case 2:
1925 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1926 break;
1928 tcg_gen_shli_i32(tmp, tmp, 28);
1929 gen_set_nzcv(tmp);
1930 tcg_temp_free_i32(tmp);
1931 break;
1932 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1933 if (((insn >> 6) & 3) == 3)
1934 return 1;
1935 rd = (insn >> 12) & 0xf;
1936 wrd = (insn >> 16) & 0xf;
1937 tmp = load_reg(s, rd);
1938 switch ((insn >> 6) & 3) {
1939 case 0:
1940 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1941 break;
1942 case 1:
1943 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1944 break;
1945 case 2:
1946 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1947 break;
1949 tcg_temp_free_i32(tmp);
1950 gen_op_iwmmxt_movq_wRn_M0(wrd);
1951 gen_op_iwmmxt_set_mup();
1952 break;
1953 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1954 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1955 return 1;
1956 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1957 tmp2 = tcg_temp_new_i32();
1958 tcg_gen_mov_i32(tmp2, tmp);
1959 switch ((insn >> 22) & 3) {
1960 case 0:
1961 for (i = 0; i < 7; i ++) {
1962 tcg_gen_shli_i32(tmp2, tmp2, 4);
1963 tcg_gen_and_i32(tmp, tmp, tmp2);
1965 break;
1966 case 1:
1967 for (i = 0; i < 3; i ++) {
1968 tcg_gen_shli_i32(tmp2, tmp2, 8);
1969 tcg_gen_and_i32(tmp, tmp, tmp2);
1971 break;
1972 case 2:
1973 tcg_gen_shli_i32(tmp2, tmp2, 16);
1974 tcg_gen_and_i32(tmp, tmp, tmp2);
1975 break;
1977 gen_set_nzcv(tmp);
1978 tcg_temp_free_i32(tmp2);
1979 tcg_temp_free_i32(tmp);
1980 break;
1981 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1982 wrd = (insn >> 12) & 0xf;
1983 rd0 = (insn >> 16) & 0xf;
1984 gen_op_iwmmxt_movq_M0_wRn(rd0);
1985 switch ((insn >> 22) & 3) {
1986 case 0:
1987 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1988 break;
1989 case 1:
1990 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1991 break;
1992 case 2:
1993 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1994 break;
1995 case 3:
1996 return 1;
1998 gen_op_iwmmxt_movq_wRn_M0(wrd);
1999 gen_op_iwmmxt_set_mup();
2000 break;
2001 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2002 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2003 return 1;
2004 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2005 tmp2 = tcg_temp_new_i32();
2006 tcg_gen_mov_i32(tmp2, tmp);
2007 switch ((insn >> 22) & 3) {
2008 case 0:
2009 for (i = 0; i < 7; i ++) {
2010 tcg_gen_shli_i32(tmp2, tmp2, 4);
2011 tcg_gen_or_i32(tmp, tmp, tmp2);
2013 break;
2014 case 1:
2015 for (i = 0; i < 3; i ++) {
2016 tcg_gen_shli_i32(tmp2, tmp2, 8);
2017 tcg_gen_or_i32(tmp, tmp, tmp2);
2019 break;
2020 case 2:
2021 tcg_gen_shli_i32(tmp2, tmp2, 16);
2022 tcg_gen_or_i32(tmp, tmp, tmp2);
2023 break;
2025 gen_set_nzcv(tmp);
2026 tcg_temp_free_i32(tmp2);
2027 tcg_temp_free_i32(tmp);
2028 break;
2029 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2030 rd = (insn >> 12) & 0xf;
2031 rd0 = (insn >> 16) & 0xf;
2032 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2033 return 1;
2034 gen_op_iwmmxt_movq_M0_wRn(rd0);
2035 tmp = tcg_temp_new_i32();
2036 switch ((insn >> 22) & 3) {
2037 case 0:
2038 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2039 break;
2040 case 1:
2041 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2042 break;
2043 case 2:
2044 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2045 break;
2047 store_reg(s, rd, tmp);
2048 break;
2049 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2050 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2051 wrd = (insn >> 12) & 0xf;
2052 rd0 = (insn >> 16) & 0xf;
2053 rd1 = (insn >> 0) & 0xf;
2054 gen_op_iwmmxt_movq_M0_wRn(rd0);
2055 switch ((insn >> 22) & 3) {
2056 case 0:
2057 if (insn & (1 << 21))
2058 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2059 else
2060 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2061 break;
2062 case 1:
2063 if (insn & (1 << 21))
2064 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2065 else
2066 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2067 break;
2068 case 2:
2069 if (insn & (1 << 21))
2070 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2071 else
2072 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2073 break;
2074 case 3:
2075 return 1;
2077 gen_op_iwmmxt_movq_wRn_M0(wrd);
2078 gen_op_iwmmxt_set_mup();
2079 gen_op_iwmmxt_set_cup();
2080 break;
2081 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2082 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2083 wrd = (insn >> 12) & 0xf;
2084 rd0 = (insn >> 16) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0);
2086 switch ((insn >> 22) & 3) {
2087 case 0:
2088 if (insn & (1 << 21))
2089 gen_op_iwmmxt_unpacklsb_M0();
2090 else
2091 gen_op_iwmmxt_unpacklub_M0();
2092 break;
2093 case 1:
2094 if (insn & (1 << 21))
2095 gen_op_iwmmxt_unpacklsw_M0();
2096 else
2097 gen_op_iwmmxt_unpackluw_M0();
2098 break;
2099 case 2:
2100 if (insn & (1 << 21))
2101 gen_op_iwmmxt_unpacklsl_M0();
2102 else
2103 gen_op_iwmmxt_unpacklul_M0();
2104 break;
2105 case 3:
2106 return 1;
2108 gen_op_iwmmxt_movq_wRn_M0(wrd);
2109 gen_op_iwmmxt_set_mup();
2110 gen_op_iwmmxt_set_cup();
2111 break;
2112 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2113 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2114 wrd = (insn >> 12) & 0xf;
2115 rd0 = (insn >> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0);
2117 switch ((insn >> 22) & 3) {
2118 case 0:
2119 if (insn & (1 << 21))
2120 gen_op_iwmmxt_unpackhsb_M0();
2121 else
2122 gen_op_iwmmxt_unpackhub_M0();
2123 break;
2124 case 1:
2125 if (insn & (1 << 21))
2126 gen_op_iwmmxt_unpackhsw_M0();
2127 else
2128 gen_op_iwmmxt_unpackhuw_M0();
2129 break;
2130 case 2:
2131 if (insn & (1 << 21))
2132 gen_op_iwmmxt_unpackhsl_M0();
2133 else
2134 gen_op_iwmmxt_unpackhul_M0();
2135 break;
2136 case 3:
2137 return 1;
2139 gen_op_iwmmxt_movq_wRn_M0(wrd);
2140 gen_op_iwmmxt_set_mup();
2141 gen_op_iwmmxt_set_cup();
2142 break;
2143 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2144 case 0x214: case 0x614: case 0xa14: case 0xe14:
2145 if (((insn >> 22) & 3) == 0)
2146 return 1;
2147 wrd = (insn >> 12) & 0xf;
2148 rd0 = (insn >> 16) & 0xf;
2149 gen_op_iwmmxt_movq_M0_wRn(rd0);
2150 tmp = tcg_temp_new_i32();
2151 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2152 tcg_temp_free_i32(tmp);
2153 return 1;
2155 switch ((insn >> 22) & 3) {
2156 case 1:
2157 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2158 break;
2159 case 2:
2160 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2161 break;
2162 case 3:
2163 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2164 break;
2166 tcg_temp_free_i32(tmp);
2167 gen_op_iwmmxt_movq_wRn_M0(wrd);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2170 break;
2171 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2172 case 0x014: case 0x414: case 0x814: case 0xc14:
2173 if (((insn >> 22) & 3) == 0)
2174 return 1;
2175 wrd = (insn >> 12) & 0xf;
2176 rd0 = (insn >> 16) & 0xf;
2177 gen_op_iwmmxt_movq_M0_wRn(rd0);
2178 tmp = tcg_temp_new_i32();
2179 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2180 tcg_temp_free_i32(tmp);
2181 return 1;
2183 switch ((insn >> 22) & 3) {
2184 case 1:
2185 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2186 break;
2187 case 2:
2188 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2189 break;
2190 case 3:
2191 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2192 break;
2194 tcg_temp_free_i32(tmp);
2195 gen_op_iwmmxt_movq_wRn_M0(wrd);
2196 gen_op_iwmmxt_set_mup();
2197 gen_op_iwmmxt_set_cup();
2198 break;
2199 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2200 case 0x114: case 0x514: case 0x914: case 0xd14:
2201 if (((insn >> 22) & 3) == 0)
2202 return 1;
2203 wrd = (insn >> 12) & 0xf;
2204 rd0 = (insn >> 16) & 0xf;
2205 gen_op_iwmmxt_movq_M0_wRn(rd0);
2206 tmp = tcg_temp_new_i32();
2207 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2208 tcg_temp_free_i32(tmp);
2209 return 1;
2211 switch ((insn >> 22) & 3) {
2212 case 1:
2213 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2214 break;
2215 case 2:
2216 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2217 break;
2218 case 3:
2219 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2220 break;
2222 tcg_temp_free_i32(tmp);
2223 gen_op_iwmmxt_movq_wRn_M0(wrd);
2224 gen_op_iwmmxt_set_mup();
2225 gen_op_iwmmxt_set_cup();
2226 break;
2227 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2228 case 0x314: case 0x714: case 0xb14: case 0xf14:
2229 if (((insn >> 22) & 3) == 0)
2230 return 1;
2231 wrd = (insn >> 12) & 0xf;
2232 rd0 = (insn >> 16) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0);
2234 tmp = tcg_temp_new_i32();
2235 switch ((insn >> 22) & 3) {
2236 case 1:
2237 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2238 tcg_temp_free_i32(tmp);
2239 return 1;
2241 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2242 break;
2243 case 2:
2244 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2245 tcg_temp_free_i32(tmp);
2246 return 1;
2248 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2249 break;
2250 case 3:
2251 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2252 tcg_temp_free_i32(tmp);
2253 return 1;
2255 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2256 break;
2258 tcg_temp_free_i32(tmp);
2259 gen_op_iwmmxt_movq_wRn_M0(wrd);
2260 gen_op_iwmmxt_set_mup();
2261 gen_op_iwmmxt_set_cup();
2262 break;
2263 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2264 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2265 wrd = (insn >> 12) & 0xf;
2266 rd0 = (insn >> 16) & 0xf;
2267 rd1 = (insn >> 0) & 0xf;
2268 gen_op_iwmmxt_movq_M0_wRn(rd0);
2269 switch ((insn >> 22) & 3) {
2270 case 0:
2271 if (insn & (1 << 21))
2272 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2273 else
2274 gen_op_iwmmxt_minub_M0_wRn(rd1);
2275 break;
2276 case 1:
2277 if (insn & (1 << 21))
2278 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2279 else
2280 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2281 break;
2282 case 2:
2283 if (insn & (1 << 21))
2284 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2285 else
2286 gen_op_iwmmxt_minul_M0_wRn(rd1);
2287 break;
2288 case 3:
2289 return 1;
2291 gen_op_iwmmxt_movq_wRn_M0(wrd);
2292 gen_op_iwmmxt_set_mup();
2293 break;
2294 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2295 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2296 wrd = (insn >> 12) & 0xf;
2297 rd0 = (insn >> 16) & 0xf;
2298 rd1 = (insn >> 0) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0);
2300 switch ((insn >> 22) & 3) {
2301 case 0:
2302 if (insn & (1 << 21))
2303 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2304 else
2305 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2306 break;
2307 case 1:
2308 if (insn & (1 << 21))
2309 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2310 else
2311 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2312 break;
2313 case 2:
2314 if (insn & (1 << 21))
2315 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2316 else
2317 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2318 break;
2319 case 3:
2320 return 1;
2322 gen_op_iwmmxt_movq_wRn_M0(wrd);
2323 gen_op_iwmmxt_set_mup();
2324 break;
2325 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2326 case 0x402: case 0x502: case 0x602: case 0x702:
2327 wrd = (insn >> 12) & 0xf;
2328 rd0 = (insn >> 16) & 0xf;
2329 rd1 = (insn >> 0) & 0xf;
2330 gen_op_iwmmxt_movq_M0_wRn(rd0);
2331 tmp = tcg_const_i32((insn >> 20) & 3);
2332 iwmmxt_load_reg(cpu_V1, rd1);
2333 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2334 tcg_temp_free_i32(tmp);
2335 gen_op_iwmmxt_movq_wRn_M0(wrd);
2336 gen_op_iwmmxt_set_mup();
2337 break;
2338 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2339 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2340 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2341 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2342 wrd = (insn >> 12) & 0xf;
2343 rd0 = (insn >> 16) & 0xf;
2344 rd1 = (insn >> 0) & 0xf;
2345 gen_op_iwmmxt_movq_M0_wRn(rd0);
2346 switch ((insn >> 20) & 0xf) {
2347 case 0x0:
2348 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2349 break;
2350 case 0x1:
2351 gen_op_iwmmxt_subub_M0_wRn(rd1);
2352 break;
2353 case 0x3:
2354 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2355 break;
2356 case 0x4:
2357 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2358 break;
2359 case 0x5:
2360 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2361 break;
2362 case 0x7:
2363 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2364 break;
2365 case 0x8:
2366 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2367 break;
2368 case 0x9:
2369 gen_op_iwmmxt_subul_M0_wRn(rd1);
2370 break;
2371 case 0xb:
2372 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2373 break;
2374 default:
2375 return 1;
2377 gen_op_iwmmxt_movq_wRn_M0(wrd);
2378 gen_op_iwmmxt_set_mup();
2379 gen_op_iwmmxt_set_cup();
2380 break;
2381 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2382 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2383 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2384 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2385 wrd = (insn >> 12) & 0xf;
2386 rd0 = (insn >> 16) & 0xf;
2387 gen_op_iwmmxt_movq_M0_wRn(rd0);
2388 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2389 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2390 tcg_temp_free_i32(tmp);
2391 gen_op_iwmmxt_movq_wRn_M0(wrd);
2392 gen_op_iwmmxt_set_mup();
2393 gen_op_iwmmxt_set_cup();
2394 break;
2395 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2396 case 0x418: case 0x518: case 0x618: case 0x718:
2397 case 0x818: case 0x918: case 0xa18: case 0xb18:
2398 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2399 wrd = (insn >> 12) & 0xf;
2400 rd0 = (insn >> 16) & 0xf;
2401 rd1 = (insn >> 0) & 0xf;
2402 gen_op_iwmmxt_movq_M0_wRn(rd0);
2403 switch ((insn >> 20) & 0xf) {
2404 case 0x0:
2405 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2406 break;
2407 case 0x1:
2408 gen_op_iwmmxt_addub_M0_wRn(rd1);
2409 break;
2410 case 0x3:
2411 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2412 break;
2413 case 0x4:
2414 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2415 break;
2416 case 0x5:
2417 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2418 break;
2419 case 0x7:
2420 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2421 break;
2422 case 0x8:
2423 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2424 break;
2425 case 0x9:
2426 gen_op_iwmmxt_addul_M0_wRn(rd1);
2427 break;
2428 case 0xb:
2429 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2430 break;
2431 default:
2432 return 1;
2434 gen_op_iwmmxt_movq_wRn_M0(wrd);
2435 gen_op_iwmmxt_set_mup();
2436 gen_op_iwmmxt_set_cup();
2437 break;
2438 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2439 case 0x408: case 0x508: case 0x608: case 0x708:
2440 case 0x808: case 0x908: case 0xa08: case 0xb08:
2441 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2442 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2443 return 1;
2444 wrd = (insn >> 12) & 0xf;
2445 rd0 = (insn >> 16) & 0xf;
2446 rd1 = (insn >> 0) & 0xf;
2447 gen_op_iwmmxt_movq_M0_wRn(rd0);
2448 switch ((insn >> 22) & 3) {
2449 case 1:
2450 if (insn & (1 << 21))
2451 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2452 else
2453 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2454 break;
2455 case 2:
2456 if (insn & (1 << 21))
2457 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2458 else
2459 gen_op_iwmmxt_packul_M0_wRn(rd1);
2460 break;
2461 case 3:
2462 if (insn & (1 << 21))
2463 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2464 else
2465 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2466 break;
2468 gen_op_iwmmxt_movq_wRn_M0(wrd);
2469 gen_op_iwmmxt_set_mup();
2470 gen_op_iwmmxt_set_cup();
2471 break;
2472 case 0x201: case 0x203: case 0x205: case 0x207:
2473 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2474 case 0x211: case 0x213: case 0x215: case 0x217:
2475 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2476 wrd = (insn >> 5) & 0xf;
2477 rd0 = (insn >> 12) & 0xf;
2478 rd1 = (insn >> 0) & 0xf;
2479 if (rd0 == 0xf || rd1 == 0xf)
2480 return 1;
2481 gen_op_iwmmxt_movq_M0_wRn(wrd);
2482 tmp = load_reg(s, rd0);
2483 tmp2 = load_reg(s, rd1);
2484 switch ((insn >> 16) & 0xf) {
2485 case 0x0: /* TMIA */
2486 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2487 break;
2488 case 0x8: /* TMIAPH */
2489 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2490 break;
2491 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2492 if (insn & (1 << 16))
2493 tcg_gen_shri_i32(tmp, tmp, 16);
2494 if (insn & (1 << 17))
2495 tcg_gen_shri_i32(tmp2, tmp2, 16);
2496 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2497 break;
2498 default:
2499 tcg_temp_free_i32(tmp2);
2500 tcg_temp_free_i32(tmp);
2501 return 1;
2503 tcg_temp_free_i32(tmp2);
2504 tcg_temp_free_i32(tmp);
2505 gen_op_iwmmxt_movq_wRn_M0(wrd);
2506 gen_op_iwmmxt_set_mup();
2507 break;
2508 default:
2509 return 1;
2512 return 0;
2515 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2516 (ie. an undefined instruction). */
2517 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2519 int acc, rd0, rd1, rdhi, rdlo;
2520 TCGv_i32 tmp, tmp2;
2522 if ((insn & 0x0ff00f10) == 0x0e200010) {
2523 /* Multiply with Internal Accumulate Format */
2524 rd0 = (insn >> 12) & 0xf;
2525 rd1 = insn & 0xf;
2526 acc = (insn >> 5) & 7;
2528 if (acc != 0)
2529 return 1;
2531 tmp = load_reg(s, rd0);
2532 tmp2 = load_reg(s, rd1);
2533 switch ((insn >> 16) & 0xf) {
2534 case 0x0: /* MIA */
2535 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2536 break;
2537 case 0x8: /* MIAPH */
2538 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2539 break;
2540 case 0xc: /* MIABB */
2541 case 0xd: /* MIABT */
2542 case 0xe: /* MIATB */
2543 case 0xf: /* MIATT */
2544 if (insn & (1 << 16))
2545 tcg_gen_shri_i32(tmp, tmp, 16);
2546 if (insn & (1 << 17))
2547 tcg_gen_shri_i32(tmp2, tmp2, 16);
2548 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2549 break;
2550 default:
2551 return 1;
2553 tcg_temp_free_i32(tmp2);
2554 tcg_temp_free_i32(tmp);
2556 gen_op_iwmmxt_movq_wRn_M0(acc);
2557 return 0;
2560 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2561 /* Internal Accumulator Access Format */
2562 rdhi = (insn >> 16) & 0xf;
2563 rdlo = (insn >> 12) & 0xf;
2564 acc = insn & 7;
2566 if (acc != 0)
2567 return 1;
2569 if (insn & ARM_CP_RW_BIT) { /* MRA */
2570 iwmmxt_load_reg(cpu_V0, acc);
2571 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2572 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2573 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2574 } else { /* MAR */
2575 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2576 iwmmxt_store_reg(cpu_V0, acc);
2578 return 0;
2581 return 1;
2584 static void gen_goto_ptr(void)
2586 tcg_gen_lookup_and_goto_ptr();
2589 /* This will end the TB but doesn't guarantee we'll return to
2590 * cpu_loop_exec. Any live exit_requests will be processed as we
2591 * enter the next TB.
2593 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2595 if (translator_use_goto_tb(&s->base, dest)) {
2596 tcg_gen_goto_tb(n);
2597 gen_set_pc_im(s, dest);
2598 tcg_gen_exit_tb(s->base.tb, n);
2599 } else {
2600 gen_set_pc_im(s, dest);
2601 gen_goto_ptr();
2603 s->base.is_jmp = DISAS_NORETURN;
2606 /* Jump, specifying which TB number to use if we gen_goto_tb() */
2607 static inline void gen_jmp_tb(DisasContext *s, uint32_t dest, int tbno)
2609 if (unlikely(is_singlestepping(s))) {
2610 /* An indirect jump so that we still trigger the debug exception. */
2611 gen_set_pc_im(s, dest);
2612 s->base.is_jmp = DISAS_JUMP;
2613 } else {
2614 gen_goto_tb(s, tbno, dest);
2618 static inline void gen_jmp(DisasContext *s, uint32_t dest)
2620 gen_jmp_tb(s, dest, 0);
2623 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2625 if (x)
2626 tcg_gen_sari_i32(t0, t0, 16);
2627 else
2628 gen_sxth(t0);
2629 if (y)
2630 tcg_gen_sari_i32(t1, t1, 16);
2631 else
2632 gen_sxth(t1);
2633 tcg_gen_mul_i32(t0, t0, t1);
2636 /* Return the mask of PSR bits set by a MSR instruction. */
2637 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2639 uint32_t mask = 0;
2641 if (flags & (1 << 0)) {
2642 mask |= 0xff;
2644 if (flags & (1 << 1)) {
2645 mask |= 0xff00;
2647 if (flags & (1 << 2)) {
2648 mask |= 0xff0000;
2650 if (flags & (1 << 3)) {
2651 mask |= 0xff000000;
2654 /* Mask out undefined and reserved bits. */
2655 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2657 /* Mask out execution state. */
2658 if (!spsr) {
2659 mask &= ~CPSR_EXEC;
2662 /* Mask out privileged bits. */
2663 if (IS_USER(s)) {
2664 mask &= CPSR_USER;
2666 return mask;
2669 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2670 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2672 TCGv_i32 tmp;
2673 if (spsr) {
2674 /* ??? This is also undefined in system mode. */
2675 if (IS_USER(s))
2676 return 1;
2678 tmp = load_cpu_field(spsr);
2679 tcg_gen_andi_i32(tmp, tmp, ~mask);
2680 tcg_gen_andi_i32(t0, t0, mask);
2681 tcg_gen_or_i32(tmp, tmp, t0);
2682 store_cpu_field(tmp, spsr);
2683 } else {
2684 gen_set_cpsr(t0, mask);
2686 tcg_temp_free_i32(t0);
2687 gen_lookup_tb(s);
2688 return 0;
2691 /* Returns nonzero if access to the PSR is not permitted. */
2692 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2694 TCGv_i32 tmp;
2695 tmp = tcg_temp_new_i32();
2696 tcg_gen_movi_i32(tmp, val);
2697 return gen_set_psr(s, mask, spsr, tmp);
2700 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2701 int *tgtmode, int *regno)
2703 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2704 * the target mode and register number, and identify the various
2705 * unpredictable cases.
2706 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2707 * + executed in user mode
2708 * + using R15 as the src/dest register
2709 * + accessing an unimplemented register
2710 * + accessing a register that's inaccessible at current PL/security state*
2711 * + accessing a register that you could access with a different insn
2712 * We choose to UNDEF in all these cases.
2713 * Since we don't know which of the various AArch32 modes we are in
2714 * we have to defer some checks to runtime.
2715 * Accesses to Monitor mode registers from Secure EL1 (which implies
2716 * that EL3 is AArch64) must trap to EL3.
2718 * If the access checks fail this function will emit code to take
2719 * an exception and return false. Otherwise it will return true,
2720 * and set *tgtmode and *regno appropriately.
2722 int exc_target = default_exception_el(s);
2724 /* These instructions are present only in ARMv8, or in ARMv7 with the
2725 * Virtualization Extensions.
2727 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2728 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2729 goto undef;
2732 if (IS_USER(s) || rn == 15) {
2733 goto undef;
2736 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2737 * of registers into (r, sysm).
2739 if (r) {
2740 /* SPSRs for other modes */
2741 switch (sysm) {
2742 case 0xe: /* SPSR_fiq */
2743 *tgtmode = ARM_CPU_MODE_FIQ;
2744 break;
2745 case 0x10: /* SPSR_irq */
2746 *tgtmode = ARM_CPU_MODE_IRQ;
2747 break;
2748 case 0x12: /* SPSR_svc */
2749 *tgtmode = ARM_CPU_MODE_SVC;
2750 break;
2751 case 0x14: /* SPSR_abt */
2752 *tgtmode = ARM_CPU_MODE_ABT;
2753 break;
2754 case 0x16: /* SPSR_und */
2755 *tgtmode = ARM_CPU_MODE_UND;
2756 break;
2757 case 0x1c: /* SPSR_mon */
2758 *tgtmode = ARM_CPU_MODE_MON;
2759 break;
2760 case 0x1e: /* SPSR_hyp */
2761 *tgtmode = ARM_CPU_MODE_HYP;
2762 break;
2763 default: /* unallocated */
2764 goto undef;
2766 /* We arbitrarily assign SPSR a register number of 16. */
2767 *regno = 16;
2768 } else {
2769 /* general purpose registers for other modes */
2770 switch (sysm) {
2771 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2772 *tgtmode = ARM_CPU_MODE_USR;
2773 *regno = sysm + 8;
2774 break;
2775 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2776 *tgtmode = ARM_CPU_MODE_FIQ;
2777 *regno = sysm;
2778 break;
2779 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2780 *tgtmode = ARM_CPU_MODE_IRQ;
2781 *regno = sysm & 1 ? 13 : 14;
2782 break;
2783 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2784 *tgtmode = ARM_CPU_MODE_SVC;
2785 *regno = sysm & 1 ? 13 : 14;
2786 break;
2787 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2788 *tgtmode = ARM_CPU_MODE_ABT;
2789 *regno = sysm & 1 ? 13 : 14;
2790 break;
2791 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2792 *tgtmode = ARM_CPU_MODE_UND;
2793 *regno = sysm & 1 ? 13 : 14;
2794 break;
2795 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2796 *tgtmode = ARM_CPU_MODE_MON;
2797 *regno = sysm & 1 ? 13 : 14;
2798 break;
2799 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2800 *tgtmode = ARM_CPU_MODE_HYP;
2801 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2802 *regno = sysm & 1 ? 13 : 17;
2803 break;
2804 default: /* unallocated */
2805 goto undef;
2809 /* Catch the 'accessing inaccessible register' cases we can detect
2810 * at translate time.
2812 switch (*tgtmode) {
2813 case ARM_CPU_MODE_MON:
2814 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2815 goto undef;
2817 if (s->current_el == 1) {
2818 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2819 * then accesses to Mon registers trap to Secure EL2, if it exists,
2820 * otherwise EL3.
2822 TCGv_i32 tcg_el;
2824 if (arm_dc_feature(s, ARM_FEATURE_AARCH64) &&
2825 dc_isar_feature(aa64_sel2, s)) {
2826 /* Target EL is EL<3 minus SCR_EL3.EEL2> */
2827 tcg_el = load_cpu_field(cp15.scr_el3);
2828 tcg_gen_sextract_i32(tcg_el, tcg_el, ctz32(SCR_EEL2), 1);
2829 tcg_gen_addi_i32(tcg_el, tcg_el, 3);
2830 } else {
2831 tcg_el = tcg_const_i32(3);
2834 gen_exception_el(s, EXCP_UDEF, syn_uncategorized(), tcg_el);
2835 tcg_temp_free_i32(tcg_el);
2836 return false;
2838 break;
2839 case ARM_CPU_MODE_HYP:
2841 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2842 * (and so we can forbid accesses from EL2 or below). elr_hyp
2843 * can be accessed also from Hyp mode, so forbid accesses from
2844 * EL0 or EL1.
2846 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2847 (s->current_el < 3 && *regno != 17)) {
2848 goto undef;
2850 break;
2851 default:
2852 break;
2855 return true;
2857 undef:
2858 /* If we get here then some access check did not pass */
2859 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2860 syn_uncategorized(), exc_target);
2861 return false;
2864 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2866 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2867 int tgtmode = 0, regno = 0;
2869 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2870 return;
2873 /* Sync state because msr_banked() can raise exceptions */
2874 gen_set_condexec(s);
2875 gen_set_pc_im(s, s->pc_curr);
2876 tcg_reg = load_reg(s, rn);
2877 tcg_tgtmode = tcg_const_i32(tgtmode);
2878 tcg_regno = tcg_const_i32(regno);
2879 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2880 tcg_temp_free_i32(tcg_tgtmode);
2881 tcg_temp_free_i32(tcg_regno);
2882 tcg_temp_free_i32(tcg_reg);
2883 s->base.is_jmp = DISAS_UPDATE_EXIT;
2886 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2888 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2889 int tgtmode = 0, regno = 0;
2891 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2892 return;
2895 /* Sync state because mrs_banked() can raise exceptions */
2896 gen_set_condexec(s);
2897 gen_set_pc_im(s, s->pc_curr);
2898 tcg_reg = tcg_temp_new_i32();
2899 tcg_tgtmode = tcg_const_i32(tgtmode);
2900 tcg_regno = tcg_const_i32(regno);
2901 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2902 tcg_temp_free_i32(tcg_tgtmode);
2903 tcg_temp_free_i32(tcg_regno);
2904 store_reg(s, rn, tcg_reg);
2905 s->base.is_jmp = DISAS_UPDATE_EXIT;
2908 /* Store value to PC as for an exception return (ie don't
2909 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2910 * will do the masking based on the new value of the Thumb bit.
2912 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2914 tcg_gen_mov_i32(cpu_R[15], pc);
2915 tcg_temp_free_i32(pc);
2918 /* Generate a v6 exception return. Marks both values as dead. */
2919 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2921 store_pc_exc_ret(s, pc);
2922 /* The cpsr_write_eret helper will mask the low bits of PC
2923 * appropriately depending on the new Thumb bit, so it must
2924 * be called after storing the new PC.
2926 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2927 gen_io_start();
2929 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2930 tcg_temp_free_i32(cpsr);
2931 /* Must exit loop to check un-masked IRQs */
2932 s->base.is_jmp = DISAS_EXIT;
2935 /* Generate an old-style exception return. Marks pc as dead. */
2936 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2938 gen_rfe(s, pc, load_cpu_field(spsr));
2941 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
2942 uint32_t opr_sz, uint32_t max_sz,
2943 gen_helper_gvec_3_ptr *fn)
2945 TCGv_ptr qc_ptr = tcg_temp_new_ptr();
2947 tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
2948 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
2949 opr_sz, max_sz, 0, fn);
2950 tcg_temp_free_ptr(qc_ptr);
2953 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2954 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2956 static gen_helper_gvec_3_ptr * const fns[2] = {
2957 gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
2959 tcg_debug_assert(vece >= 1 && vece <= 2);
2960 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2963 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
2964 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
2966 static gen_helper_gvec_3_ptr * const fns[2] = {
2967 gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
2969 tcg_debug_assert(vece >= 1 && vece <= 2);
2970 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
2973 #define GEN_CMP0(NAME, COND) \
2974 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
2976 tcg_gen_setcondi_i32(COND, d, a, 0); \
2977 tcg_gen_neg_i32(d, d); \
2979 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
2981 tcg_gen_setcondi_i64(COND, d, a, 0); \
2982 tcg_gen_neg_i64(d, d); \
2984 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
2986 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
2987 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
2988 tcg_temp_free_vec(zero); \
2990 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
2991 uint32_t opr_sz, uint32_t max_sz) \
2993 const GVecGen2 op[4] = { \
2994 { .fno = gen_helper_gvec_##NAME##0_b, \
2995 .fniv = gen_##NAME##0_vec, \
2996 .opt_opc = vecop_list_cmp, \
2997 .vece = MO_8 }, \
2998 { .fno = gen_helper_gvec_##NAME##0_h, \
2999 .fniv = gen_##NAME##0_vec, \
3000 .opt_opc = vecop_list_cmp, \
3001 .vece = MO_16 }, \
3002 { .fni4 = gen_##NAME##0_i32, \
3003 .fniv = gen_##NAME##0_vec, \
3004 .opt_opc = vecop_list_cmp, \
3005 .vece = MO_32 }, \
3006 { .fni8 = gen_##NAME##0_i64, \
3007 .fniv = gen_##NAME##0_vec, \
3008 .opt_opc = vecop_list_cmp, \
3009 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
3010 .vece = MO_64 }, \
3011 }; \
3012 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
3015 static const TCGOpcode vecop_list_cmp[] = {
3016 INDEX_op_cmp_vec, 0
3019 GEN_CMP0(ceq, TCG_COND_EQ)
3020 GEN_CMP0(cle, TCG_COND_LE)
3021 GEN_CMP0(cge, TCG_COND_GE)
3022 GEN_CMP0(clt, TCG_COND_LT)
3023 GEN_CMP0(cgt, TCG_COND_GT)
3025 #undef GEN_CMP0
3027 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3029 tcg_gen_vec_sar8i_i64(a, a, shift);
3030 tcg_gen_vec_add8_i64(d, d, a);
3033 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3035 tcg_gen_vec_sar16i_i64(a, a, shift);
3036 tcg_gen_vec_add16_i64(d, d, a);
3039 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3041 tcg_gen_sari_i32(a, a, shift);
3042 tcg_gen_add_i32(d, d, a);
3045 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3047 tcg_gen_sari_i64(a, a, shift);
3048 tcg_gen_add_i64(d, d, a);
3051 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3053 tcg_gen_sari_vec(vece, a, a, sh);
3054 tcg_gen_add_vec(vece, d, d, a);
3057 void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3058 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3060 static const TCGOpcode vecop_list[] = {
3061 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3063 static const GVecGen2i ops[4] = {
3064 { .fni8 = gen_ssra8_i64,
3065 .fniv = gen_ssra_vec,
3066 .fno = gen_helper_gvec_ssra_b,
3067 .load_dest = true,
3068 .opt_opc = vecop_list,
3069 .vece = MO_8 },
3070 { .fni8 = gen_ssra16_i64,
3071 .fniv = gen_ssra_vec,
3072 .fno = gen_helper_gvec_ssra_h,
3073 .load_dest = true,
3074 .opt_opc = vecop_list,
3075 .vece = MO_16 },
3076 { .fni4 = gen_ssra32_i32,
3077 .fniv = gen_ssra_vec,
3078 .fno = gen_helper_gvec_ssra_s,
3079 .load_dest = true,
3080 .opt_opc = vecop_list,
3081 .vece = MO_32 },
3082 { .fni8 = gen_ssra64_i64,
3083 .fniv = gen_ssra_vec,
3084 .fno = gen_helper_gvec_ssra_b,
3085 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3086 .opt_opc = vecop_list,
3087 .load_dest = true,
3088 .vece = MO_64 },
3091 /* tszimm encoding produces immediates in the range [1..esize]. */
3092 tcg_debug_assert(shift > 0);
3093 tcg_debug_assert(shift <= (8 << vece));
3096 * Shifts larger than the element size are architecturally valid.
3097 * Signed results in all sign bits.
3099 shift = MIN(shift, (8 << vece) - 1);
3100 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3103 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3105 tcg_gen_vec_shr8i_i64(a, a, shift);
3106 tcg_gen_vec_add8_i64(d, d, a);
3109 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3111 tcg_gen_vec_shr16i_i64(a, a, shift);
3112 tcg_gen_vec_add16_i64(d, d, a);
3115 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3117 tcg_gen_shri_i32(a, a, shift);
3118 tcg_gen_add_i32(d, d, a);
3121 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3123 tcg_gen_shri_i64(a, a, shift);
3124 tcg_gen_add_i64(d, d, a);
3127 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3129 tcg_gen_shri_vec(vece, a, a, sh);
3130 tcg_gen_add_vec(vece, d, d, a);
3133 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3134 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3136 static const TCGOpcode vecop_list[] = {
3137 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3139 static const GVecGen2i ops[4] = {
3140 { .fni8 = gen_usra8_i64,
3141 .fniv = gen_usra_vec,
3142 .fno = gen_helper_gvec_usra_b,
3143 .load_dest = true,
3144 .opt_opc = vecop_list,
3145 .vece = MO_8, },
3146 { .fni8 = gen_usra16_i64,
3147 .fniv = gen_usra_vec,
3148 .fno = gen_helper_gvec_usra_h,
3149 .load_dest = true,
3150 .opt_opc = vecop_list,
3151 .vece = MO_16, },
3152 { .fni4 = gen_usra32_i32,
3153 .fniv = gen_usra_vec,
3154 .fno = gen_helper_gvec_usra_s,
3155 .load_dest = true,
3156 .opt_opc = vecop_list,
3157 .vece = MO_32, },
3158 { .fni8 = gen_usra64_i64,
3159 .fniv = gen_usra_vec,
3160 .fno = gen_helper_gvec_usra_d,
3161 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3162 .load_dest = true,
3163 .opt_opc = vecop_list,
3164 .vece = MO_64, },
3167 /* tszimm encoding produces immediates in the range [1..esize]. */
3168 tcg_debug_assert(shift > 0);
3169 tcg_debug_assert(shift <= (8 << vece));
3172 * Shifts larger than the element size are architecturally valid.
3173 * Unsigned results in all zeros as input to accumulate: nop.
3175 if (shift < (8 << vece)) {
3176 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3177 } else {
3178 /* Nop, but we do need to clear the tail. */
3179 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3184 * Shift one less than the requested amount, and the low bit is
3185 * the rounding bit. For the 8 and 16-bit operations, because we
3186 * mask the low bit, we can perform a normal integer shift instead
3187 * of a vector shift.
3189 static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3191 TCGv_i64 t = tcg_temp_new_i64();
3193 tcg_gen_shri_i64(t, a, sh - 1);
3194 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3195 tcg_gen_vec_sar8i_i64(d, a, sh);
3196 tcg_gen_vec_add8_i64(d, d, t);
3197 tcg_temp_free_i64(t);
3200 static void gen_srshr16_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_16, 1));
3206 tcg_gen_vec_sar16i_i64(d, a, sh);
3207 tcg_gen_vec_add16_i64(d, d, t);
3208 tcg_temp_free_i64(t);
3211 static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3213 TCGv_i32 t;
3215 /* Handle shift by the input size for the benefit of trans_SRSHR_ri */
3216 if (sh == 32) {
3217 tcg_gen_movi_i32(d, 0);
3218 return;
3220 t = tcg_temp_new_i32();
3221 tcg_gen_extract_i32(t, a, sh - 1, 1);
3222 tcg_gen_sari_i32(d, a, sh);
3223 tcg_gen_add_i32(d, d, t);
3224 tcg_temp_free_i32(t);
3227 static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3229 TCGv_i64 t = tcg_temp_new_i64();
3231 tcg_gen_extract_i64(t, a, sh - 1, 1);
3232 tcg_gen_sari_i64(d, a, sh);
3233 tcg_gen_add_i64(d, d, t);
3234 tcg_temp_free_i64(t);
3237 static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3239 TCGv_vec t = tcg_temp_new_vec_matching(d);
3240 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3242 tcg_gen_shri_vec(vece, t, a, sh - 1);
3243 tcg_gen_dupi_vec(vece, ones, 1);
3244 tcg_gen_and_vec(vece, t, t, ones);
3245 tcg_gen_sari_vec(vece, d, a, sh);
3246 tcg_gen_add_vec(vece, d, d, t);
3248 tcg_temp_free_vec(t);
3249 tcg_temp_free_vec(ones);
3252 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3253 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3255 static const TCGOpcode vecop_list[] = {
3256 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3258 static const GVecGen2i ops[4] = {
3259 { .fni8 = gen_srshr8_i64,
3260 .fniv = gen_srshr_vec,
3261 .fno = gen_helper_gvec_srshr_b,
3262 .opt_opc = vecop_list,
3263 .vece = MO_8 },
3264 { .fni8 = gen_srshr16_i64,
3265 .fniv = gen_srshr_vec,
3266 .fno = gen_helper_gvec_srshr_h,
3267 .opt_opc = vecop_list,
3268 .vece = MO_16 },
3269 { .fni4 = gen_srshr32_i32,
3270 .fniv = gen_srshr_vec,
3271 .fno = gen_helper_gvec_srshr_s,
3272 .opt_opc = vecop_list,
3273 .vece = MO_32 },
3274 { .fni8 = gen_srshr64_i64,
3275 .fniv = gen_srshr_vec,
3276 .fno = gen_helper_gvec_srshr_d,
3277 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3278 .opt_opc = vecop_list,
3279 .vece = MO_64 },
3282 /* tszimm encoding produces immediates in the range [1..esize] */
3283 tcg_debug_assert(shift > 0);
3284 tcg_debug_assert(shift <= (8 << vece));
3286 if (shift == (8 << vece)) {
3288 * Shifts larger than the element size are architecturally valid.
3289 * Signed results in all sign bits. With rounding, this produces
3290 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3291 * I.e. always zero.
3293 tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
3294 } else {
3295 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3299 static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3301 TCGv_i64 t = tcg_temp_new_i64();
3303 gen_srshr8_i64(t, a, sh);
3304 tcg_gen_vec_add8_i64(d, d, t);
3305 tcg_temp_free_i64(t);
3308 static void gen_srsra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3310 TCGv_i64 t = tcg_temp_new_i64();
3312 gen_srshr16_i64(t, a, sh);
3313 tcg_gen_vec_add16_i64(d, d, t);
3314 tcg_temp_free_i64(t);
3317 static void gen_srsra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3319 TCGv_i32 t = tcg_temp_new_i32();
3321 gen_srshr32_i32(t, a, sh);
3322 tcg_gen_add_i32(d, d, t);
3323 tcg_temp_free_i32(t);
3326 static void gen_srsra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3328 TCGv_i64 t = tcg_temp_new_i64();
3330 gen_srshr64_i64(t, a, sh);
3331 tcg_gen_add_i64(d, d, t);
3332 tcg_temp_free_i64(t);
3335 static void gen_srsra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3337 TCGv_vec t = tcg_temp_new_vec_matching(d);
3339 gen_srshr_vec(vece, t, a, sh);
3340 tcg_gen_add_vec(vece, d, d, t);
3341 tcg_temp_free_vec(t);
3344 void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3345 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3347 static const TCGOpcode vecop_list[] = {
3348 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3350 static const GVecGen2i ops[4] = {
3351 { .fni8 = gen_srsra8_i64,
3352 .fniv = gen_srsra_vec,
3353 .fno = gen_helper_gvec_srsra_b,
3354 .opt_opc = vecop_list,
3355 .load_dest = true,
3356 .vece = MO_8 },
3357 { .fni8 = gen_srsra16_i64,
3358 .fniv = gen_srsra_vec,
3359 .fno = gen_helper_gvec_srsra_h,
3360 .opt_opc = vecop_list,
3361 .load_dest = true,
3362 .vece = MO_16 },
3363 { .fni4 = gen_srsra32_i32,
3364 .fniv = gen_srsra_vec,
3365 .fno = gen_helper_gvec_srsra_s,
3366 .opt_opc = vecop_list,
3367 .load_dest = true,
3368 .vece = MO_32 },
3369 { .fni8 = gen_srsra64_i64,
3370 .fniv = gen_srsra_vec,
3371 .fno = gen_helper_gvec_srsra_d,
3372 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3373 .opt_opc = vecop_list,
3374 .load_dest = true,
3375 .vece = MO_64 },
3378 /* tszimm encoding produces immediates in the range [1..esize] */
3379 tcg_debug_assert(shift > 0);
3380 tcg_debug_assert(shift <= (8 << vece));
3383 * Shifts larger than the element size are architecturally valid.
3384 * Signed results in all sign bits. With rounding, this produces
3385 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3386 * I.e. always zero. With accumulation, this leaves D unchanged.
3388 if (shift == (8 << vece)) {
3389 /* Nop, but we do need to clear the tail. */
3390 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3391 } else {
3392 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3396 static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3398 TCGv_i64 t = tcg_temp_new_i64();
3400 tcg_gen_shri_i64(t, a, sh - 1);
3401 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3402 tcg_gen_vec_shr8i_i64(d, a, sh);
3403 tcg_gen_vec_add8_i64(d, d, t);
3404 tcg_temp_free_i64(t);
3407 static void gen_urshr16_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_16, 1));
3413 tcg_gen_vec_shr16i_i64(d, a, sh);
3414 tcg_gen_vec_add16_i64(d, d, t);
3415 tcg_temp_free_i64(t);
3418 static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3420 TCGv_i32 t;
3422 /* Handle shift by the input size for the benefit of trans_URSHR_ri */
3423 if (sh == 32) {
3424 tcg_gen_extract_i32(d, a, sh - 1, 1);
3425 return;
3427 t = tcg_temp_new_i32();
3428 tcg_gen_extract_i32(t, a, sh - 1, 1);
3429 tcg_gen_shri_i32(d, a, sh);
3430 tcg_gen_add_i32(d, d, t);
3431 tcg_temp_free_i32(t);
3434 static void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3436 TCGv_i64 t = tcg_temp_new_i64();
3438 tcg_gen_extract_i64(t, a, sh - 1, 1);
3439 tcg_gen_shri_i64(d, a, sh);
3440 tcg_gen_add_i64(d, d, t);
3441 tcg_temp_free_i64(t);
3444 static void gen_urshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t shift)
3446 TCGv_vec t = tcg_temp_new_vec_matching(d);
3447 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3449 tcg_gen_shri_vec(vece, t, a, shift - 1);
3450 tcg_gen_dupi_vec(vece, ones, 1);
3451 tcg_gen_and_vec(vece, t, t, ones);
3452 tcg_gen_shri_vec(vece, d, a, shift);
3453 tcg_gen_add_vec(vece, d, d, t);
3455 tcg_temp_free_vec(t);
3456 tcg_temp_free_vec(ones);
3459 void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3460 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3462 static const TCGOpcode vecop_list[] = {
3463 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3465 static const GVecGen2i ops[4] = {
3466 { .fni8 = gen_urshr8_i64,
3467 .fniv = gen_urshr_vec,
3468 .fno = gen_helper_gvec_urshr_b,
3469 .opt_opc = vecop_list,
3470 .vece = MO_8 },
3471 { .fni8 = gen_urshr16_i64,
3472 .fniv = gen_urshr_vec,
3473 .fno = gen_helper_gvec_urshr_h,
3474 .opt_opc = vecop_list,
3475 .vece = MO_16 },
3476 { .fni4 = gen_urshr32_i32,
3477 .fniv = gen_urshr_vec,
3478 .fno = gen_helper_gvec_urshr_s,
3479 .opt_opc = vecop_list,
3480 .vece = MO_32 },
3481 { .fni8 = gen_urshr64_i64,
3482 .fniv = gen_urshr_vec,
3483 .fno = gen_helper_gvec_urshr_d,
3484 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3485 .opt_opc = vecop_list,
3486 .vece = MO_64 },
3489 /* tszimm encoding produces immediates in the range [1..esize] */
3490 tcg_debug_assert(shift > 0);
3491 tcg_debug_assert(shift <= (8 << vece));
3493 if (shift == (8 << vece)) {
3495 * Shifts larger than the element size are architecturally valid.
3496 * Unsigned results in zero. With rounding, this produces a
3497 * copy of the most significant bit.
3499 tcg_gen_gvec_shri(vece, rd_ofs, rm_ofs, shift - 1, opr_sz, max_sz);
3500 } else {
3501 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3505 static void gen_ursra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3507 TCGv_i64 t = tcg_temp_new_i64();
3509 if (sh == 8) {
3510 tcg_gen_vec_shr8i_i64(t, a, 7);
3511 } else {
3512 gen_urshr8_i64(t, a, sh);
3514 tcg_gen_vec_add8_i64(d, d, t);
3515 tcg_temp_free_i64(t);
3518 static void gen_ursra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3520 TCGv_i64 t = tcg_temp_new_i64();
3522 if (sh == 16) {
3523 tcg_gen_vec_shr16i_i64(t, a, 15);
3524 } else {
3525 gen_urshr16_i64(t, a, sh);
3527 tcg_gen_vec_add16_i64(d, d, t);
3528 tcg_temp_free_i64(t);
3531 static void gen_ursra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3533 TCGv_i32 t = tcg_temp_new_i32();
3535 if (sh == 32) {
3536 tcg_gen_shri_i32(t, a, 31);
3537 } else {
3538 gen_urshr32_i32(t, a, sh);
3540 tcg_gen_add_i32(d, d, t);
3541 tcg_temp_free_i32(t);
3544 static void gen_ursra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3546 TCGv_i64 t = tcg_temp_new_i64();
3548 if (sh == 64) {
3549 tcg_gen_shri_i64(t, a, 63);
3550 } else {
3551 gen_urshr64_i64(t, a, sh);
3553 tcg_gen_add_i64(d, d, t);
3554 tcg_temp_free_i64(t);
3557 static void gen_ursra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3559 TCGv_vec t = tcg_temp_new_vec_matching(d);
3561 if (sh == (8 << vece)) {
3562 tcg_gen_shri_vec(vece, t, a, sh - 1);
3563 } else {
3564 gen_urshr_vec(vece, t, a, sh);
3566 tcg_gen_add_vec(vece, d, d, t);
3567 tcg_temp_free_vec(t);
3570 void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3571 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3573 static const TCGOpcode vecop_list[] = {
3574 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3576 static const GVecGen2i ops[4] = {
3577 { .fni8 = gen_ursra8_i64,
3578 .fniv = gen_ursra_vec,
3579 .fno = gen_helper_gvec_ursra_b,
3580 .opt_opc = vecop_list,
3581 .load_dest = true,
3582 .vece = MO_8 },
3583 { .fni8 = gen_ursra16_i64,
3584 .fniv = gen_ursra_vec,
3585 .fno = gen_helper_gvec_ursra_h,
3586 .opt_opc = vecop_list,
3587 .load_dest = true,
3588 .vece = MO_16 },
3589 { .fni4 = gen_ursra32_i32,
3590 .fniv = gen_ursra_vec,
3591 .fno = gen_helper_gvec_ursra_s,
3592 .opt_opc = vecop_list,
3593 .load_dest = true,
3594 .vece = MO_32 },
3595 { .fni8 = gen_ursra64_i64,
3596 .fniv = gen_ursra_vec,
3597 .fno = gen_helper_gvec_ursra_d,
3598 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3599 .opt_opc = vecop_list,
3600 .load_dest = true,
3601 .vece = MO_64 },
3604 /* tszimm encoding produces immediates in the range [1..esize] */
3605 tcg_debug_assert(shift > 0);
3606 tcg_debug_assert(shift <= (8 << vece));
3608 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3611 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3613 uint64_t mask = dup_const(MO_8, 0xff >> shift);
3614 TCGv_i64 t = tcg_temp_new_i64();
3616 tcg_gen_shri_i64(t, a, shift);
3617 tcg_gen_andi_i64(t, t, mask);
3618 tcg_gen_andi_i64(d, d, ~mask);
3619 tcg_gen_or_i64(d, d, t);
3620 tcg_temp_free_i64(t);
3623 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3625 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
3626 TCGv_i64 t = tcg_temp_new_i64();
3628 tcg_gen_shri_i64(t, a, shift);
3629 tcg_gen_andi_i64(t, t, mask);
3630 tcg_gen_andi_i64(d, d, ~mask);
3631 tcg_gen_or_i64(d, d, t);
3632 tcg_temp_free_i64(t);
3635 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3637 tcg_gen_shri_i32(a, a, shift);
3638 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
3641 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3643 tcg_gen_shri_i64(a, a, shift);
3644 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
3647 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3649 TCGv_vec t = tcg_temp_new_vec_matching(d);
3650 TCGv_vec m = tcg_temp_new_vec_matching(d);
3652 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
3653 tcg_gen_shri_vec(vece, t, a, sh);
3654 tcg_gen_and_vec(vece, d, d, m);
3655 tcg_gen_or_vec(vece, d, d, t);
3657 tcg_temp_free_vec(t);
3658 tcg_temp_free_vec(m);
3661 void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3662 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3664 static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
3665 const GVecGen2i ops[4] = {
3666 { .fni8 = gen_shr8_ins_i64,
3667 .fniv = gen_shr_ins_vec,
3668 .fno = gen_helper_gvec_sri_b,
3669 .load_dest = true,
3670 .opt_opc = vecop_list,
3671 .vece = MO_8 },
3672 { .fni8 = gen_shr16_ins_i64,
3673 .fniv = gen_shr_ins_vec,
3674 .fno = gen_helper_gvec_sri_h,
3675 .load_dest = true,
3676 .opt_opc = vecop_list,
3677 .vece = MO_16 },
3678 { .fni4 = gen_shr32_ins_i32,
3679 .fniv = gen_shr_ins_vec,
3680 .fno = gen_helper_gvec_sri_s,
3681 .load_dest = true,
3682 .opt_opc = vecop_list,
3683 .vece = MO_32 },
3684 { .fni8 = gen_shr64_ins_i64,
3685 .fniv = gen_shr_ins_vec,
3686 .fno = gen_helper_gvec_sri_d,
3687 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3688 .load_dest = true,
3689 .opt_opc = vecop_list,
3690 .vece = MO_64 },
3693 /* tszimm encoding produces immediates in the range [1..esize]. */
3694 tcg_debug_assert(shift > 0);
3695 tcg_debug_assert(shift <= (8 << vece));
3697 /* Shift of esize leaves destination unchanged. */
3698 if (shift < (8 << vece)) {
3699 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3700 } else {
3701 /* Nop, but we do need to clear the tail. */
3702 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3706 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3708 uint64_t mask = dup_const(MO_8, 0xff << shift);
3709 TCGv_i64 t = tcg_temp_new_i64();
3711 tcg_gen_shli_i64(t, a, shift);
3712 tcg_gen_andi_i64(t, t, mask);
3713 tcg_gen_andi_i64(d, d, ~mask);
3714 tcg_gen_or_i64(d, d, t);
3715 tcg_temp_free_i64(t);
3718 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3720 uint64_t mask = dup_const(MO_16, 0xffff << shift);
3721 TCGv_i64 t = tcg_temp_new_i64();
3723 tcg_gen_shli_i64(t, a, shift);
3724 tcg_gen_andi_i64(t, t, mask);
3725 tcg_gen_andi_i64(d, d, ~mask);
3726 tcg_gen_or_i64(d, d, t);
3727 tcg_temp_free_i64(t);
3730 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3732 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
3735 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3737 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
3740 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3742 TCGv_vec t = tcg_temp_new_vec_matching(d);
3743 TCGv_vec m = tcg_temp_new_vec_matching(d);
3745 tcg_gen_shli_vec(vece, t, a, sh);
3746 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
3747 tcg_gen_and_vec(vece, d, d, m);
3748 tcg_gen_or_vec(vece, d, d, t);
3750 tcg_temp_free_vec(t);
3751 tcg_temp_free_vec(m);
3754 void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3755 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3757 static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
3758 const GVecGen2i ops[4] = {
3759 { .fni8 = gen_shl8_ins_i64,
3760 .fniv = gen_shl_ins_vec,
3761 .fno = gen_helper_gvec_sli_b,
3762 .load_dest = true,
3763 .opt_opc = vecop_list,
3764 .vece = MO_8 },
3765 { .fni8 = gen_shl16_ins_i64,
3766 .fniv = gen_shl_ins_vec,
3767 .fno = gen_helper_gvec_sli_h,
3768 .load_dest = true,
3769 .opt_opc = vecop_list,
3770 .vece = MO_16 },
3771 { .fni4 = gen_shl32_ins_i32,
3772 .fniv = gen_shl_ins_vec,
3773 .fno = gen_helper_gvec_sli_s,
3774 .load_dest = true,
3775 .opt_opc = vecop_list,
3776 .vece = MO_32 },
3777 { .fni8 = gen_shl64_ins_i64,
3778 .fniv = gen_shl_ins_vec,
3779 .fno = gen_helper_gvec_sli_d,
3780 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3781 .load_dest = true,
3782 .opt_opc = vecop_list,
3783 .vece = MO_64 },
3786 /* tszimm encoding produces immediates in the range [0..esize-1]. */
3787 tcg_debug_assert(shift >= 0);
3788 tcg_debug_assert(shift < (8 << vece));
3790 if (shift == 0) {
3791 tcg_gen_gvec_mov(vece, rd_ofs, rm_ofs, opr_sz, max_sz);
3792 } else {
3793 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3797 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3799 gen_helper_neon_mul_u8(a, a, b);
3800 gen_helper_neon_add_u8(d, d, a);
3803 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3805 gen_helper_neon_mul_u8(a, a, b);
3806 gen_helper_neon_sub_u8(d, d, a);
3809 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3811 gen_helper_neon_mul_u16(a, a, b);
3812 gen_helper_neon_add_u16(d, d, a);
3815 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3817 gen_helper_neon_mul_u16(a, a, b);
3818 gen_helper_neon_sub_u16(d, d, a);
3821 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3823 tcg_gen_mul_i32(a, a, b);
3824 tcg_gen_add_i32(d, d, a);
3827 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3829 tcg_gen_mul_i32(a, a, b);
3830 tcg_gen_sub_i32(d, d, a);
3833 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3835 tcg_gen_mul_i64(a, a, b);
3836 tcg_gen_add_i64(d, d, a);
3839 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3841 tcg_gen_mul_i64(a, a, b);
3842 tcg_gen_sub_i64(d, d, a);
3845 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3847 tcg_gen_mul_vec(vece, a, a, b);
3848 tcg_gen_add_vec(vece, d, d, a);
3851 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3853 tcg_gen_mul_vec(vece, a, a, b);
3854 tcg_gen_sub_vec(vece, d, d, a);
3857 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
3858 * these tables are shared with AArch64 which does support them.
3860 void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3861 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3863 static const TCGOpcode vecop_list[] = {
3864 INDEX_op_mul_vec, INDEX_op_add_vec, 0
3866 static const GVecGen3 ops[4] = {
3867 { .fni4 = gen_mla8_i32,
3868 .fniv = gen_mla_vec,
3869 .load_dest = true,
3870 .opt_opc = vecop_list,
3871 .vece = MO_8 },
3872 { .fni4 = gen_mla16_i32,
3873 .fniv = gen_mla_vec,
3874 .load_dest = true,
3875 .opt_opc = vecop_list,
3876 .vece = MO_16 },
3877 { .fni4 = gen_mla32_i32,
3878 .fniv = gen_mla_vec,
3879 .load_dest = true,
3880 .opt_opc = vecop_list,
3881 .vece = MO_32 },
3882 { .fni8 = gen_mla64_i64,
3883 .fniv = gen_mla_vec,
3884 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3885 .load_dest = true,
3886 .opt_opc = vecop_list,
3887 .vece = MO_64 },
3889 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3892 void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3893 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3895 static const TCGOpcode vecop_list[] = {
3896 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
3898 static const GVecGen3 ops[4] = {
3899 { .fni4 = gen_mls8_i32,
3900 .fniv = gen_mls_vec,
3901 .load_dest = true,
3902 .opt_opc = vecop_list,
3903 .vece = MO_8 },
3904 { .fni4 = gen_mls16_i32,
3905 .fniv = gen_mls_vec,
3906 .load_dest = true,
3907 .opt_opc = vecop_list,
3908 .vece = MO_16 },
3909 { .fni4 = gen_mls32_i32,
3910 .fniv = gen_mls_vec,
3911 .load_dest = true,
3912 .opt_opc = vecop_list,
3913 .vece = MO_32 },
3914 { .fni8 = gen_mls64_i64,
3915 .fniv = gen_mls_vec,
3916 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3917 .load_dest = true,
3918 .opt_opc = vecop_list,
3919 .vece = MO_64 },
3921 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3924 /* CMTST : test is "if (X & Y != 0)". */
3925 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
3927 tcg_gen_and_i32(d, a, b);
3928 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
3929 tcg_gen_neg_i32(d, d);
3932 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
3934 tcg_gen_and_i64(d, a, b);
3935 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
3936 tcg_gen_neg_i64(d, d);
3939 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
3941 tcg_gen_and_vec(vece, d, a, b);
3942 tcg_gen_dupi_vec(vece, a, 0);
3943 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
3946 void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3947 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3949 static const TCGOpcode vecop_list[] = { INDEX_op_cmp_vec, 0 };
3950 static const GVecGen3 ops[4] = {
3951 { .fni4 = gen_helper_neon_tst_u8,
3952 .fniv = gen_cmtst_vec,
3953 .opt_opc = vecop_list,
3954 .vece = MO_8 },
3955 { .fni4 = gen_helper_neon_tst_u16,
3956 .fniv = gen_cmtst_vec,
3957 .opt_opc = vecop_list,
3958 .vece = MO_16 },
3959 { .fni4 = gen_cmtst_i32,
3960 .fniv = gen_cmtst_vec,
3961 .opt_opc = vecop_list,
3962 .vece = MO_32 },
3963 { .fni8 = gen_cmtst_i64,
3964 .fniv = gen_cmtst_vec,
3965 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3966 .opt_opc = vecop_list,
3967 .vece = MO_64 },
3969 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
3972 void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
3974 TCGv_i32 lval = tcg_temp_new_i32();
3975 TCGv_i32 rval = tcg_temp_new_i32();
3976 TCGv_i32 lsh = tcg_temp_new_i32();
3977 TCGv_i32 rsh = tcg_temp_new_i32();
3978 TCGv_i32 zero = tcg_const_i32(0);
3979 TCGv_i32 max = tcg_const_i32(32);
3982 * Rely on the TCG guarantee that out of range shifts produce
3983 * unspecified results, not undefined behaviour (i.e. no trap).
3984 * Discard out-of-range results after the fact.
3986 tcg_gen_ext8s_i32(lsh, shift);
3987 tcg_gen_neg_i32(rsh, lsh);
3988 tcg_gen_shl_i32(lval, src, lsh);
3989 tcg_gen_shr_i32(rval, src, rsh);
3990 tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
3991 tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
3993 tcg_temp_free_i32(lval);
3994 tcg_temp_free_i32(rval);
3995 tcg_temp_free_i32(lsh);
3996 tcg_temp_free_i32(rsh);
3997 tcg_temp_free_i32(zero);
3998 tcg_temp_free_i32(max);
4001 void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4003 TCGv_i64 lval = tcg_temp_new_i64();
4004 TCGv_i64 rval = tcg_temp_new_i64();
4005 TCGv_i64 lsh = tcg_temp_new_i64();
4006 TCGv_i64 rsh = tcg_temp_new_i64();
4007 TCGv_i64 zero = tcg_const_i64(0);
4008 TCGv_i64 max = tcg_const_i64(64);
4011 * Rely on the TCG guarantee that out of range shifts produce
4012 * unspecified results, not undefined behaviour (i.e. no trap).
4013 * Discard out-of-range results after the fact.
4015 tcg_gen_ext8s_i64(lsh, shift);
4016 tcg_gen_neg_i64(rsh, lsh);
4017 tcg_gen_shl_i64(lval, src, lsh);
4018 tcg_gen_shr_i64(rval, src, rsh);
4019 tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
4020 tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
4022 tcg_temp_free_i64(lval);
4023 tcg_temp_free_i64(rval);
4024 tcg_temp_free_i64(lsh);
4025 tcg_temp_free_i64(rsh);
4026 tcg_temp_free_i64(zero);
4027 tcg_temp_free_i64(max);
4030 static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
4031 TCGv_vec src, TCGv_vec shift)
4033 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4034 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4035 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4036 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4037 TCGv_vec msk, max;
4039 tcg_gen_neg_vec(vece, rsh, shift);
4040 if (vece == MO_8) {
4041 tcg_gen_mov_vec(lsh, shift);
4042 } else {
4043 msk = tcg_temp_new_vec_matching(dst);
4044 tcg_gen_dupi_vec(vece, msk, 0xff);
4045 tcg_gen_and_vec(vece, lsh, shift, msk);
4046 tcg_gen_and_vec(vece, rsh, rsh, msk);
4047 tcg_temp_free_vec(msk);
4051 * Rely on the TCG guarantee that out of range shifts produce
4052 * unspecified results, not undefined behaviour (i.e. no trap).
4053 * Discard out-of-range results after the fact.
4055 tcg_gen_shlv_vec(vece, lval, src, lsh);
4056 tcg_gen_shrv_vec(vece, rval, src, rsh);
4058 max = tcg_temp_new_vec_matching(dst);
4059 tcg_gen_dupi_vec(vece, max, 8 << vece);
4062 * The choice of LT (signed) and GEU (unsigned) are biased toward
4063 * the instructions of the x86_64 host. For MO_8, the whole byte
4064 * is significant so we must use an unsigned compare; otherwise we
4065 * have already masked to a byte and so a signed compare works.
4066 * Other tcg hosts have a full set of comparisons and do not care.
4068 if (vece == MO_8) {
4069 tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
4070 tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
4071 tcg_gen_andc_vec(vece, lval, lval, lsh);
4072 tcg_gen_andc_vec(vece, rval, rval, rsh);
4073 } else {
4074 tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
4075 tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
4076 tcg_gen_and_vec(vece, lval, lval, lsh);
4077 tcg_gen_and_vec(vece, rval, rval, rsh);
4079 tcg_gen_or_vec(vece, dst, lval, rval);
4081 tcg_temp_free_vec(max);
4082 tcg_temp_free_vec(lval);
4083 tcg_temp_free_vec(rval);
4084 tcg_temp_free_vec(lsh);
4085 tcg_temp_free_vec(rsh);
4088 void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4089 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4091 static const TCGOpcode vecop_list[] = {
4092 INDEX_op_neg_vec, INDEX_op_shlv_vec,
4093 INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
4095 static const GVecGen3 ops[4] = {
4096 { .fniv = gen_ushl_vec,
4097 .fno = gen_helper_gvec_ushl_b,
4098 .opt_opc = vecop_list,
4099 .vece = MO_8 },
4100 { .fniv = gen_ushl_vec,
4101 .fno = gen_helper_gvec_ushl_h,
4102 .opt_opc = vecop_list,
4103 .vece = MO_16 },
4104 { .fni4 = gen_ushl_i32,
4105 .fniv = gen_ushl_vec,
4106 .opt_opc = vecop_list,
4107 .vece = MO_32 },
4108 { .fni8 = gen_ushl_i64,
4109 .fniv = gen_ushl_vec,
4110 .opt_opc = vecop_list,
4111 .vece = MO_64 },
4113 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4116 void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4118 TCGv_i32 lval = tcg_temp_new_i32();
4119 TCGv_i32 rval = tcg_temp_new_i32();
4120 TCGv_i32 lsh = tcg_temp_new_i32();
4121 TCGv_i32 rsh = tcg_temp_new_i32();
4122 TCGv_i32 zero = tcg_const_i32(0);
4123 TCGv_i32 max = tcg_const_i32(31);
4126 * Rely on the TCG guarantee that out of range shifts produce
4127 * unspecified results, not undefined behaviour (i.e. no trap).
4128 * Discard out-of-range results after the fact.
4130 tcg_gen_ext8s_i32(lsh, shift);
4131 tcg_gen_neg_i32(rsh, lsh);
4132 tcg_gen_shl_i32(lval, src, lsh);
4133 tcg_gen_umin_i32(rsh, rsh, max);
4134 tcg_gen_sar_i32(rval, src, rsh);
4135 tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
4136 tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
4138 tcg_temp_free_i32(lval);
4139 tcg_temp_free_i32(rval);
4140 tcg_temp_free_i32(lsh);
4141 tcg_temp_free_i32(rsh);
4142 tcg_temp_free_i32(zero);
4143 tcg_temp_free_i32(max);
4146 void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4148 TCGv_i64 lval = tcg_temp_new_i64();
4149 TCGv_i64 rval = tcg_temp_new_i64();
4150 TCGv_i64 lsh = tcg_temp_new_i64();
4151 TCGv_i64 rsh = tcg_temp_new_i64();
4152 TCGv_i64 zero = tcg_const_i64(0);
4153 TCGv_i64 max = tcg_const_i64(63);
4156 * Rely on the TCG guarantee that out of range shifts produce
4157 * unspecified results, not undefined behaviour (i.e. no trap).
4158 * Discard out-of-range results after the fact.
4160 tcg_gen_ext8s_i64(lsh, shift);
4161 tcg_gen_neg_i64(rsh, lsh);
4162 tcg_gen_shl_i64(lval, src, lsh);
4163 tcg_gen_umin_i64(rsh, rsh, max);
4164 tcg_gen_sar_i64(rval, src, rsh);
4165 tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
4166 tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
4168 tcg_temp_free_i64(lval);
4169 tcg_temp_free_i64(rval);
4170 tcg_temp_free_i64(lsh);
4171 tcg_temp_free_i64(rsh);
4172 tcg_temp_free_i64(zero);
4173 tcg_temp_free_i64(max);
4176 static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
4177 TCGv_vec src, TCGv_vec shift)
4179 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4180 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4181 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4182 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4183 TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
4186 * Rely on the TCG guarantee that out of range shifts produce
4187 * unspecified results, not undefined behaviour (i.e. no trap).
4188 * Discard out-of-range results after the fact.
4190 tcg_gen_neg_vec(vece, rsh, shift);
4191 if (vece == MO_8) {
4192 tcg_gen_mov_vec(lsh, shift);
4193 } else {
4194 tcg_gen_dupi_vec(vece, tmp, 0xff);
4195 tcg_gen_and_vec(vece, lsh, shift, tmp);
4196 tcg_gen_and_vec(vece, rsh, rsh, tmp);
4199 /* Bound rsh so out of bound right shift gets -1. */
4200 tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
4201 tcg_gen_umin_vec(vece, rsh, rsh, tmp);
4202 tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
4204 tcg_gen_shlv_vec(vece, lval, src, lsh);
4205 tcg_gen_sarv_vec(vece, rval, src, rsh);
4207 /* Select in-bound left shift. */
4208 tcg_gen_andc_vec(vece, lval, lval, tmp);
4210 /* Select between left and right shift. */
4211 if (vece == MO_8) {
4212 tcg_gen_dupi_vec(vece, tmp, 0);
4213 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
4214 } else {
4215 tcg_gen_dupi_vec(vece, tmp, 0x80);
4216 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
4219 tcg_temp_free_vec(lval);
4220 tcg_temp_free_vec(rval);
4221 tcg_temp_free_vec(lsh);
4222 tcg_temp_free_vec(rsh);
4223 tcg_temp_free_vec(tmp);
4226 void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4227 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4229 static const TCGOpcode vecop_list[] = {
4230 INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
4231 INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
4233 static const GVecGen3 ops[4] = {
4234 { .fniv = gen_sshl_vec,
4235 .fno = gen_helper_gvec_sshl_b,
4236 .opt_opc = vecop_list,
4237 .vece = MO_8 },
4238 { .fniv = gen_sshl_vec,
4239 .fno = gen_helper_gvec_sshl_h,
4240 .opt_opc = vecop_list,
4241 .vece = MO_16 },
4242 { .fni4 = gen_sshl_i32,
4243 .fniv = gen_sshl_vec,
4244 .opt_opc = vecop_list,
4245 .vece = MO_32 },
4246 { .fni8 = gen_sshl_i64,
4247 .fniv = gen_sshl_vec,
4248 .opt_opc = vecop_list,
4249 .vece = MO_64 },
4251 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4254 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4255 TCGv_vec a, TCGv_vec b)
4257 TCGv_vec x = tcg_temp_new_vec_matching(t);
4258 tcg_gen_add_vec(vece, x, a, b);
4259 tcg_gen_usadd_vec(vece, t, a, b);
4260 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4261 tcg_gen_or_vec(vece, sat, sat, x);
4262 tcg_temp_free_vec(x);
4265 void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4266 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4268 static const TCGOpcode vecop_list[] = {
4269 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4271 static const GVecGen4 ops[4] = {
4272 { .fniv = gen_uqadd_vec,
4273 .fno = gen_helper_gvec_uqadd_b,
4274 .write_aofs = true,
4275 .opt_opc = vecop_list,
4276 .vece = MO_8 },
4277 { .fniv = gen_uqadd_vec,
4278 .fno = gen_helper_gvec_uqadd_h,
4279 .write_aofs = true,
4280 .opt_opc = vecop_list,
4281 .vece = MO_16 },
4282 { .fniv = gen_uqadd_vec,
4283 .fno = gen_helper_gvec_uqadd_s,
4284 .write_aofs = true,
4285 .opt_opc = vecop_list,
4286 .vece = MO_32 },
4287 { .fniv = gen_uqadd_vec,
4288 .fno = gen_helper_gvec_uqadd_d,
4289 .write_aofs = true,
4290 .opt_opc = vecop_list,
4291 .vece = MO_64 },
4293 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4294 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4297 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4298 TCGv_vec a, TCGv_vec b)
4300 TCGv_vec x = tcg_temp_new_vec_matching(t);
4301 tcg_gen_add_vec(vece, x, a, b);
4302 tcg_gen_ssadd_vec(vece, t, a, b);
4303 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4304 tcg_gen_or_vec(vece, sat, sat, x);
4305 tcg_temp_free_vec(x);
4308 void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4309 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4311 static const TCGOpcode vecop_list[] = {
4312 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4314 static const GVecGen4 ops[4] = {
4315 { .fniv = gen_sqadd_vec,
4316 .fno = gen_helper_gvec_sqadd_b,
4317 .opt_opc = vecop_list,
4318 .write_aofs = true,
4319 .vece = MO_8 },
4320 { .fniv = gen_sqadd_vec,
4321 .fno = gen_helper_gvec_sqadd_h,
4322 .opt_opc = vecop_list,
4323 .write_aofs = true,
4324 .vece = MO_16 },
4325 { .fniv = gen_sqadd_vec,
4326 .fno = gen_helper_gvec_sqadd_s,
4327 .opt_opc = vecop_list,
4328 .write_aofs = true,
4329 .vece = MO_32 },
4330 { .fniv = gen_sqadd_vec,
4331 .fno = gen_helper_gvec_sqadd_d,
4332 .opt_opc = vecop_list,
4333 .write_aofs = true,
4334 .vece = MO_64 },
4336 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4337 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4340 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4341 TCGv_vec a, TCGv_vec b)
4343 TCGv_vec x = tcg_temp_new_vec_matching(t);
4344 tcg_gen_sub_vec(vece, x, a, b);
4345 tcg_gen_ussub_vec(vece, t, a, b);
4346 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4347 tcg_gen_or_vec(vece, sat, sat, x);
4348 tcg_temp_free_vec(x);
4351 void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4352 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4354 static const TCGOpcode vecop_list[] = {
4355 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4357 static const GVecGen4 ops[4] = {
4358 { .fniv = gen_uqsub_vec,
4359 .fno = gen_helper_gvec_uqsub_b,
4360 .opt_opc = vecop_list,
4361 .write_aofs = true,
4362 .vece = MO_8 },
4363 { .fniv = gen_uqsub_vec,
4364 .fno = gen_helper_gvec_uqsub_h,
4365 .opt_opc = vecop_list,
4366 .write_aofs = true,
4367 .vece = MO_16 },
4368 { .fniv = gen_uqsub_vec,
4369 .fno = gen_helper_gvec_uqsub_s,
4370 .opt_opc = vecop_list,
4371 .write_aofs = true,
4372 .vece = MO_32 },
4373 { .fniv = gen_uqsub_vec,
4374 .fno = gen_helper_gvec_uqsub_d,
4375 .opt_opc = vecop_list,
4376 .write_aofs = true,
4377 .vece = MO_64 },
4379 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4380 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4383 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4384 TCGv_vec a, TCGv_vec b)
4386 TCGv_vec x = tcg_temp_new_vec_matching(t);
4387 tcg_gen_sub_vec(vece, x, a, b);
4388 tcg_gen_sssub_vec(vece, t, a, b);
4389 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4390 tcg_gen_or_vec(vece, sat, sat, x);
4391 tcg_temp_free_vec(x);
4394 void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4395 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4397 static const TCGOpcode vecop_list[] = {
4398 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4400 static const GVecGen4 ops[4] = {
4401 { .fniv = gen_sqsub_vec,
4402 .fno = gen_helper_gvec_sqsub_b,
4403 .opt_opc = vecop_list,
4404 .write_aofs = true,
4405 .vece = MO_8 },
4406 { .fniv = gen_sqsub_vec,
4407 .fno = gen_helper_gvec_sqsub_h,
4408 .opt_opc = vecop_list,
4409 .write_aofs = true,
4410 .vece = MO_16 },
4411 { .fniv = gen_sqsub_vec,
4412 .fno = gen_helper_gvec_sqsub_s,
4413 .opt_opc = vecop_list,
4414 .write_aofs = true,
4415 .vece = MO_32 },
4416 { .fniv = gen_sqsub_vec,
4417 .fno = gen_helper_gvec_sqsub_d,
4418 .opt_opc = vecop_list,
4419 .write_aofs = true,
4420 .vece = MO_64 },
4422 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4423 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4426 static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4428 TCGv_i32 t = tcg_temp_new_i32();
4430 tcg_gen_sub_i32(t, a, b);
4431 tcg_gen_sub_i32(d, b, a);
4432 tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
4433 tcg_temp_free_i32(t);
4436 static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4438 TCGv_i64 t = tcg_temp_new_i64();
4440 tcg_gen_sub_i64(t, a, b);
4441 tcg_gen_sub_i64(d, b, a);
4442 tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
4443 tcg_temp_free_i64(t);
4446 static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4448 TCGv_vec t = tcg_temp_new_vec_matching(d);
4450 tcg_gen_smin_vec(vece, t, a, b);
4451 tcg_gen_smax_vec(vece, d, a, b);
4452 tcg_gen_sub_vec(vece, d, d, t);
4453 tcg_temp_free_vec(t);
4456 void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4457 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4459 static const TCGOpcode vecop_list[] = {
4460 INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4462 static const GVecGen3 ops[4] = {
4463 { .fniv = gen_sabd_vec,
4464 .fno = gen_helper_gvec_sabd_b,
4465 .opt_opc = vecop_list,
4466 .vece = MO_8 },
4467 { .fniv = gen_sabd_vec,
4468 .fno = gen_helper_gvec_sabd_h,
4469 .opt_opc = vecop_list,
4470 .vece = MO_16 },
4471 { .fni4 = gen_sabd_i32,
4472 .fniv = gen_sabd_vec,
4473 .fno = gen_helper_gvec_sabd_s,
4474 .opt_opc = vecop_list,
4475 .vece = MO_32 },
4476 { .fni8 = gen_sabd_i64,
4477 .fniv = gen_sabd_vec,
4478 .fno = gen_helper_gvec_sabd_d,
4479 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4480 .opt_opc = vecop_list,
4481 .vece = MO_64 },
4483 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4486 static void gen_uabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4488 TCGv_i32 t = tcg_temp_new_i32();
4490 tcg_gen_sub_i32(t, a, b);
4491 tcg_gen_sub_i32(d, b, a);
4492 tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, d, t);
4493 tcg_temp_free_i32(t);
4496 static void gen_uabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4498 TCGv_i64 t = tcg_temp_new_i64();
4500 tcg_gen_sub_i64(t, a, b);
4501 tcg_gen_sub_i64(d, b, a);
4502 tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, d, t);
4503 tcg_temp_free_i64(t);
4506 static void gen_uabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4508 TCGv_vec t = tcg_temp_new_vec_matching(d);
4510 tcg_gen_umin_vec(vece, t, a, b);
4511 tcg_gen_umax_vec(vece, d, a, b);
4512 tcg_gen_sub_vec(vece, d, d, t);
4513 tcg_temp_free_vec(t);
4516 void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4517 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4519 static const TCGOpcode vecop_list[] = {
4520 INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
4522 static const GVecGen3 ops[4] = {
4523 { .fniv = gen_uabd_vec,
4524 .fno = gen_helper_gvec_uabd_b,
4525 .opt_opc = vecop_list,
4526 .vece = MO_8 },
4527 { .fniv = gen_uabd_vec,
4528 .fno = gen_helper_gvec_uabd_h,
4529 .opt_opc = vecop_list,
4530 .vece = MO_16 },
4531 { .fni4 = gen_uabd_i32,
4532 .fniv = gen_uabd_vec,
4533 .fno = gen_helper_gvec_uabd_s,
4534 .opt_opc = vecop_list,
4535 .vece = MO_32 },
4536 { .fni8 = gen_uabd_i64,
4537 .fniv = gen_uabd_vec,
4538 .fno = gen_helper_gvec_uabd_d,
4539 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4540 .opt_opc = vecop_list,
4541 .vece = MO_64 },
4543 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4546 static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4548 TCGv_i32 t = tcg_temp_new_i32();
4549 gen_sabd_i32(t, a, b);
4550 tcg_gen_add_i32(d, d, t);
4551 tcg_temp_free_i32(t);
4554 static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4556 TCGv_i64 t = tcg_temp_new_i64();
4557 gen_sabd_i64(t, a, b);
4558 tcg_gen_add_i64(d, d, t);
4559 tcg_temp_free_i64(t);
4562 static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4564 TCGv_vec t = tcg_temp_new_vec_matching(d);
4565 gen_sabd_vec(vece, t, a, b);
4566 tcg_gen_add_vec(vece, d, d, t);
4567 tcg_temp_free_vec(t);
4570 void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4571 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4573 static const TCGOpcode vecop_list[] = {
4574 INDEX_op_sub_vec, INDEX_op_add_vec,
4575 INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4577 static const GVecGen3 ops[4] = {
4578 { .fniv = gen_saba_vec,
4579 .fno = gen_helper_gvec_saba_b,
4580 .opt_opc = vecop_list,
4581 .load_dest = true,
4582 .vece = MO_8 },
4583 { .fniv = gen_saba_vec,
4584 .fno = gen_helper_gvec_saba_h,
4585 .opt_opc = vecop_list,
4586 .load_dest = true,
4587 .vece = MO_16 },
4588 { .fni4 = gen_saba_i32,
4589 .fniv = gen_saba_vec,
4590 .fno = gen_helper_gvec_saba_s,
4591 .opt_opc = vecop_list,
4592 .load_dest = true,
4593 .vece = MO_32 },
4594 { .fni8 = gen_saba_i64,
4595 .fniv = gen_saba_vec,
4596 .fno = gen_helper_gvec_saba_d,
4597 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4598 .opt_opc = vecop_list,
4599 .load_dest = true,
4600 .vece = MO_64 },
4602 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4605 static void gen_uaba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4607 TCGv_i32 t = tcg_temp_new_i32();
4608 gen_uabd_i32(t, a, b);
4609 tcg_gen_add_i32(d, d, t);
4610 tcg_temp_free_i32(t);
4613 static void gen_uaba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4615 TCGv_i64 t = tcg_temp_new_i64();
4616 gen_uabd_i64(t, a, b);
4617 tcg_gen_add_i64(d, d, t);
4618 tcg_temp_free_i64(t);
4621 static void gen_uaba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4623 TCGv_vec t = tcg_temp_new_vec_matching(d);
4624 gen_uabd_vec(vece, t, a, b);
4625 tcg_gen_add_vec(vece, d, d, t);
4626 tcg_temp_free_vec(t);
4629 void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4630 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4632 static const TCGOpcode vecop_list[] = {
4633 INDEX_op_sub_vec, INDEX_op_add_vec,
4634 INDEX_op_umin_vec, INDEX_op_umax_vec, 0
4636 static const GVecGen3 ops[4] = {
4637 { .fniv = gen_uaba_vec,
4638 .fno = gen_helper_gvec_uaba_b,
4639 .opt_opc = vecop_list,
4640 .load_dest = true,
4641 .vece = MO_8 },
4642 { .fniv = gen_uaba_vec,
4643 .fno = gen_helper_gvec_uaba_h,
4644 .opt_opc = vecop_list,
4645 .load_dest = true,
4646 .vece = MO_16 },
4647 { .fni4 = gen_uaba_i32,
4648 .fniv = gen_uaba_vec,
4649 .fno = gen_helper_gvec_uaba_s,
4650 .opt_opc = vecop_list,
4651 .load_dest = true,
4652 .vece = MO_32 },
4653 { .fni8 = gen_uaba_i64,
4654 .fniv = gen_uaba_vec,
4655 .fno = gen_helper_gvec_uaba_d,
4656 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4657 .opt_opc = vecop_list,
4658 .load_dest = true,
4659 .vece = MO_64 },
4661 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4664 static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
4665 int opc1, int crn, int crm, int opc2,
4666 bool isread, int rt, int rt2)
4668 const ARMCPRegInfo *ri;
4670 ri = get_arm_cp_reginfo(s->cp_regs,
4671 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
4672 if (ri) {
4673 bool need_exit_tb;
4675 /* Check access permissions */
4676 if (!cp_access_ok(s->current_el, ri, isread)) {
4677 unallocated_encoding(s);
4678 return;
4681 if (s->hstr_active || ri->accessfn ||
4682 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
4683 /* Emit code to perform further access permissions checks at
4684 * runtime; this may result in an exception.
4685 * Note that on XScale all cp0..c13 registers do an access check
4686 * call in order to handle c15_cpar.
4688 TCGv_ptr tmpptr;
4689 TCGv_i32 tcg_syn, tcg_isread;
4690 uint32_t syndrome;
4692 /* Note that since we are an implementation which takes an
4693 * exception on a trapped conditional instruction only if the
4694 * instruction passes its condition code check, we can take
4695 * advantage of the clause in the ARM ARM that allows us to set
4696 * the COND field in the instruction to 0xE in all cases.
4697 * We could fish the actual condition out of the insn (ARM)
4698 * or the condexec bits (Thumb) but it isn't necessary.
4700 switch (cpnum) {
4701 case 14:
4702 if (is64) {
4703 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
4704 isread, false);
4705 } else {
4706 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
4707 rt, isread, false);
4709 break;
4710 case 15:
4711 if (is64) {
4712 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
4713 isread, false);
4714 } else {
4715 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
4716 rt, isread, false);
4718 break;
4719 default:
4720 /* ARMv8 defines that only coprocessors 14 and 15 exist,
4721 * so this can only happen if this is an ARMv7 or earlier CPU,
4722 * in which case the syndrome information won't actually be
4723 * guest visible.
4725 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
4726 syndrome = syn_uncategorized();
4727 break;
4730 gen_set_condexec(s);
4731 gen_set_pc_im(s, s->pc_curr);
4732 tmpptr = tcg_const_ptr(ri);
4733 tcg_syn = tcg_const_i32(syndrome);
4734 tcg_isread = tcg_const_i32(isread);
4735 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
4736 tcg_isread);
4737 tcg_temp_free_ptr(tmpptr);
4738 tcg_temp_free_i32(tcg_syn);
4739 tcg_temp_free_i32(tcg_isread);
4740 } else if (ri->type & ARM_CP_RAISES_EXC) {
4742 * The readfn or writefn might raise an exception;
4743 * synchronize the CPU state in case it does.
4745 gen_set_condexec(s);
4746 gen_set_pc_im(s, s->pc_curr);
4749 /* Handle special cases first */
4750 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
4751 case ARM_CP_NOP:
4752 return;
4753 case ARM_CP_WFI:
4754 if (isread) {
4755 unallocated_encoding(s);
4756 return;
4758 gen_set_pc_im(s, s->base.pc_next);
4759 s->base.is_jmp = DISAS_WFI;
4760 return;
4761 default:
4762 break;
4765 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
4766 gen_io_start();
4769 if (isread) {
4770 /* Read */
4771 if (is64) {
4772 TCGv_i64 tmp64;
4773 TCGv_i32 tmp;
4774 if (ri->type & ARM_CP_CONST) {
4775 tmp64 = tcg_const_i64(ri->resetvalue);
4776 } else if (ri->readfn) {
4777 TCGv_ptr tmpptr;
4778 tmp64 = tcg_temp_new_i64();
4779 tmpptr = tcg_const_ptr(ri);
4780 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
4781 tcg_temp_free_ptr(tmpptr);
4782 } else {
4783 tmp64 = tcg_temp_new_i64();
4784 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
4786 tmp = tcg_temp_new_i32();
4787 tcg_gen_extrl_i64_i32(tmp, tmp64);
4788 store_reg(s, rt, tmp);
4789 tmp = tcg_temp_new_i32();
4790 tcg_gen_extrh_i64_i32(tmp, tmp64);
4791 tcg_temp_free_i64(tmp64);
4792 store_reg(s, rt2, tmp);
4793 } else {
4794 TCGv_i32 tmp;
4795 if (ri->type & ARM_CP_CONST) {
4796 tmp = tcg_const_i32(ri->resetvalue);
4797 } else if (ri->readfn) {
4798 TCGv_ptr tmpptr;
4799 tmp = tcg_temp_new_i32();
4800 tmpptr = tcg_const_ptr(ri);
4801 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
4802 tcg_temp_free_ptr(tmpptr);
4803 } else {
4804 tmp = load_cpu_offset(ri->fieldoffset);
4806 if (rt == 15) {
4807 /* Destination register of r15 for 32 bit loads sets
4808 * the condition codes from the high 4 bits of the value
4810 gen_set_nzcv(tmp);
4811 tcg_temp_free_i32(tmp);
4812 } else {
4813 store_reg(s, rt, tmp);
4816 } else {
4817 /* Write */
4818 if (ri->type & ARM_CP_CONST) {
4819 /* If not forbidden by access permissions, treat as WI */
4820 return;
4823 if (is64) {
4824 TCGv_i32 tmplo, tmphi;
4825 TCGv_i64 tmp64 = tcg_temp_new_i64();
4826 tmplo = load_reg(s, rt);
4827 tmphi = load_reg(s, rt2);
4828 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
4829 tcg_temp_free_i32(tmplo);
4830 tcg_temp_free_i32(tmphi);
4831 if (ri->writefn) {
4832 TCGv_ptr tmpptr = tcg_const_ptr(ri);
4833 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
4834 tcg_temp_free_ptr(tmpptr);
4835 } else {
4836 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
4838 tcg_temp_free_i64(tmp64);
4839 } else {
4840 if (ri->writefn) {
4841 TCGv_i32 tmp;
4842 TCGv_ptr tmpptr;
4843 tmp = load_reg(s, rt);
4844 tmpptr = tcg_const_ptr(ri);
4845 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
4846 tcg_temp_free_ptr(tmpptr);
4847 tcg_temp_free_i32(tmp);
4848 } else {
4849 TCGv_i32 tmp = load_reg(s, rt);
4850 store_cpu_offset(tmp, ri->fieldoffset);
4855 /* I/O operations must end the TB here (whether read or write) */
4856 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
4857 (ri->type & ARM_CP_IO));
4859 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
4861 * A write to any coprocessor register that ends a TB
4862 * must rebuild the hflags for the next TB.
4864 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
4865 if (arm_dc_feature(s, ARM_FEATURE_M)) {
4866 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
4867 } else {
4868 if (ri->type & ARM_CP_NEWEL) {
4869 gen_helper_rebuild_hflags_a32_newel(cpu_env);
4870 } else {
4871 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
4874 tcg_temp_free_i32(tcg_el);
4876 * We default to ending the TB on a coprocessor register write,
4877 * but allow this to be suppressed by the register definition
4878 * (usually only necessary to work around guest bugs).
4880 need_exit_tb = true;
4882 if (need_exit_tb) {
4883 gen_lookup_tb(s);
4886 return;
4889 /* Unknown register; this might be a guest error or a QEMU
4890 * unimplemented feature.
4892 if (is64) {
4893 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
4894 "64 bit system register cp:%d opc1: %d crm:%d "
4895 "(%s)\n",
4896 isread ? "read" : "write", cpnum, opc1, crm,
4897 s->ns ? "non-secure" : "secure");
4898 } else {
4899 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
4900 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
4901 "(%s)\n",
4902 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
4903 s->ns ? "non-secure" : "secure");
4906 unallocated_encoding(s);
4907 return;
4910 /* Decode XScale DSP or iWMMXt insn (in the copro space, cp=0 or 1) */
4911 static void disas_xscale_insn(DisasContext *s, uint32_t insn)
4913 int cpnum = (insn >> 8) & 0xf;
4915 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
4916 unallocated_encoding(s);
4917 } else if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
4918 if (disas_iwmmxt_insn(s, insn)) {
4919 unallocated_encoding(s);
4921 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
4922 if (disas_dsp_insn(s, insn)) {
4923 unallocated_encoding(s);
4928 /* Store a 64-bit value to a register pair. Clobbers val. */
4929 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
4931 TCGv_i32 tmp;
4932 tmp = tcg_temp_new_i32();
4933 tcg_gen_extrl_i64_i32(tmp, val);
4934 store_reg(s, rlow, tmp);
4935 tmp = tcg_temp_new_i32();
4936 tcg_gen_extrh_i64_i32(tmp, val);
4937 store_reg(s, rhigh, tmp);
4940 /* load and add a 64-bit value from a register pair. */
4941 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
4943 TCGv_i64 tmp;
4944 TCGv_i32 tmpl;
4945 TCGv_i32 tmph;
4947 /* Load 64-bit value rd:rn. */
4948 tmpl = load_reg(s, rlow);
4949 tmph = load_reg(s, rhigh);
4950 tmp = tcg_temp_new_i64();
4951 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
4952 tcg_temp_free_i32(tmpl);
4953 tcg_temp_free_i32(tmph);
4954 tcg_gen_add_i64(val, val, tmp);
4955 tcg_temp_free_i64(tmp);
4958 /* Set N and Z flags from hi|lo. */
4959 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
4961 tcg_gen_mov_i32(cpu_NF, hi);
4962 tcg_gen_or_i32(cpu_ZF, lo, hi);
4965 /* Load/Store exclusive instructions are implemented by remembering
4966 the value/address loaded, and seeing if these are the same
4967 when the store is performed. This should be sufficient to implement
4968 the architecturally mandated semantics, and avoids having to monitor
4969 regular stores. The compare vs the remembered value is done during
4970 the cmpxchg operation, but we must compare the addresses manually. */
4971 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
4972 TCGv_i32 addr, int size)
4974 TCGv_i32 tmp = tcg_temp_new_i32();
4975 MemOp opc = size | MO_ALIGN | s->be_data;
4977 s->is_ldex = true;
4979 if (size == 3) {
4980 TCGv_i32 tmp2 = tcg_temp_new_i32();
4981 TCGv_i64 t64 = tcg_temp_new_i64();
4984 * For AArch32, architecturally the 32-bit word at the lowest
4985 * address is always Rt and the one at addr+4 is Rt2, even if
4986 * the CPU is big-endian. That means we don't want to do a
4987 * gen_aa32_ld_i64(), which checks SCTLR_B as if for an
4988 * architecturally 64-bit access, but instead do a 64-bit access
4989 * using MO_BE if appropriate and then split the two halves.
4991 TCGv taddr = gen_aa32_addr(s, addr, opc);
4993 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
4994 tcg_temp_free(taddr);
4995 tcg_gen_mov_i64(cpu_exclusive_val, t64);
4996 if (s->be_data == MO_BE) {
4997 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
4998 } else {
4999 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
5001 tcg_temp_free_i64(t64);
5003 store_reg(s, rt2, tmp2);
5004 } else {
5005 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
5006 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
5009 store_reg(s, rt, tmp);
5010 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
5013 static void gen_clrex(DisasContext *s)
5015 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
5018 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
5019 TCGv_i32 addr, int size)
5021 TCGv_i32 t0, t1, t2;
5022 TCGv_i64 extaddr;
5023 TCGv taddr;
5024 TCGLabel *done_label;
5025 TCGLabel *fail_label;
5026 MemOp opc = size | MO_ALIGN | s->be_data;
5028 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
5029 [addr] = {Rt};
5030 {Rd} = 0;
5031 } else {
5032 {Rd} = 1;
5033 } */
5034 fail_label = gen_new_label();
5035 done_label = gen_new_label();
5036 extaddr = tcg_temp_new_i64();
5037 tcg_gen_extu_i32_i64(extaddr, addr);
5038 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
5039 tcg_temp_free_i64(extaddr);
5041 taddr = gen_aa32_addr(s, addr, opc);
5042 t0 = tcg_temp_new_i32();
5043 t1 = load_reg(s, rt);
5044 if (size == 3) {
5045 TCGv_i64 o64 = tcg_temp_new_i64();
5046 TCGv_i64 n64 = tcg_temp_new_i64();
5048 t2 = load_reg(s, rt2);
5051 * For AArch32, architecturally the 32-bit word at the lowest
5052 * address is always Rt and the one at addr+4 is Rt2, even if
5053 * the CPU is big-endian. Since we're going to treat this as a
5054 * single 64-bit BE store, we need to put the two halves in the
5055 * opposite order for BE to LE, so that they end up in the right
5056 * places. We don't want gen_aa32_st_i64, because that checks
5057 * SCTLR_B as if for an architectural 64-bit access.
5059 if (s->be_data == MO_BE) {
5060 tcg_gen_concat_i32_i64(n64, t2, t1);
5061 } else {
5062 tcg_gen_concat_i32_i64(n64, t1, t2);
5064 tcg_temp_free_i32(t2);
5066 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
5067 get_mem_index(s), opc);
5068 tcg_temp_free_i64(n64);
5070 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
5071 tcg_gen_extrl_i64_i32(t0, o64);
5073 tcg_temp_free_i64(o64);
5074 } else {
5075 t2 = tcg_temp_new_i32();
5076 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
5077 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
5078 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
5079 tcg_temp_free_i32(t2);
5081 tcg_temp_free_i32(t1);
5082 tcg_temp_free(taddr);
5083 tcg_gen_mov_i32(cpu_R[rd], t0);
5084 tcg_temp_free_i32(t0);
5085 tcg_gen_br(done_label);
5087 gen_set_label(fail_label);
5088 tcg_gen_movi_i32(cpu_R[rd], 1);
5089 gen_set_label(done_label);
5090 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
5093 /* gen_srs:
5094 * @env: CPUARMState
5095 * @s: DisasContext
5096 * @mode: mode field from insn (which stack to store to)
5097 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
5098 * @writeback: true if writeback bit set
5100 * Generate code for the SRS (Store Return State) insn.
5102 static void gen_srs(DisasContext *s,
5103 uint32_t mode, uint32_t amode, bool writeback)
5105 int32_t offset;
5106 TCGv_i32 addr, tmp;
5107 bool undef = false;
5109 /* SRS is:
5110 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
5111 * and specified mode is monitor mode
5112 * - UNDEFINED in Hyp mode
5113 * - UNPREDICTABLE in User or System mode
5114 * - UNPREDICTABLE if the specified mode is:
5115 * -- not implemented
5116 * -- not a valid mode number
5117 * -- a mode that's at a higher exception level
5118 * -- Monitor, if we are Non-secure
5119 * For the UNPREDICTABLE cases we choose to UNDEF.
5121 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
5122 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
5123 return;
5126 if (s->current_el == 0 || s->current_el == 2) {
5127 undef = true;
5130 switch (mode) {
5131 case ARM_CPU_MODE_USR:
5132 case ARM_CPU_MODE_FIQ:
5133 case ARM_CPU_MODE_IRQ:
5134 case ARM_CPU_MODE_SVC:
5135 case ARM_CPU_MODE_ABT:
5136 case ARM_CPU_MODE_UND:
5137 case ARM_CPU_MODE_SYS:
5138 break;
5139 case ARM_CPU_MODE_HYP:
5140 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
5141 undef = true;
5143 break;
5144 case ARM_CPU_MODE_MON:
5145 /* No need to check specifically for "are we non-secure" because
5146 * we've already made EL0 UNDEF and handled the trap for S-EL1;
5147 * so if this isn't EL3 then we must be non-secure.
5149 if (s->current_el != 3) {
5150 undef = true;
5152 break;
5153 default:
5154 undef = true;
5157 if (undef) {
5158 unallocated_encoding(s);
5159 return;
5162 addr = tcg_temp_new_i32();
5163 tmp = tcg_const_i32(mode);
5164 /* get_r13_banked() will raise an exception if called from System mode */
5165 gen_set_condexec(s);
5166 gen_set_pc_im(s, s->pc_curr);
5167 gen_helper_get_r13_banked(addr, cpu_env, tmp);
5168 tcg_temp_free_i32(tmp);
5169 switch (amode) {
5170 case 0: /* DA */
5171 offset = -4;
5172 break;
5173 case 1: /* IA */
5174 offset = 0;
5175 break;
5176 case 2: /* DB */
5177 offset = -8;
5178 break;
5179 case 3: /* IB */
5180 offset = 4;
5181 break;
5182 default:
5183 abort();
5185 tcg_gen_addi_i32(addr, addr, offset);
5186 tmp = load_reg(s, 14);
5187 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
5188 tcg_temp_free_i32(tmp);
5189 tmp = load_cpu_field(spsr);
5190 tcg_gen_addi_i32(addr, addr, 4);
5191 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), MO_UL | MO_ALIGN);
5192 tcg_temp_free_i32(tmp);
5193 if (writeback) {
5194 switch (amode) {
5195 case 0:
5196 offset = -8;
5197 break;
5198 case 1:
5199 offset = 4;
5200 break;
5201 case 2:
5202 offset = -4;
5203 break;
5204 case 3:
5205 offset = 0;
5206 break;
5207 default:
5208 abort();
5210 tcg_gen_addi_i32(addr, addr, offset);
5211 tmp = tcg_const_i32(mode);
5212 gen_helper_set_r13_banked(cpu_env, tmp, addr);
5213 tcg_temp_free_i32(tmp);
5215 tcg_temp_free_i32(addr);
5216 s->base.is_jmp = DISAS_UPDATE_EXIT;
5219 /* Skip this instruction if the ARM condition is false */
5220 static void arm_skip_unless(DisasContext *s, uint32_t cond)
5222 arm_gen_condlabel(s);
5223 arm_gen_test_cc(cond ^ 1, s->condlabel);
5228 * Constant expanders used by T16/T32 decode
5231 /* Return only the rotation part of T32ExpandImm. */
5232 static int t32_expandimm_rot(DisasContext *s, int x)
5234 return x & 0xc00 ? extract32(x, 7, 5) : 0;
5237 /* Return the unrotated immediate from T32ExpandImm. */
5238 static int t32_expandimm_imm(DisasContext *s, int x)
5240 int imm = extract32(x, 0, 8);
5242 switch (extract32(x, 8, 4)) {
5243 case 0: /* XY */
5244 /* Nothing to do. */
5245 break;
5246 case 1: /* 00XY00XY */
5247 imm *= 0x00010001;
5248 break;
5249 case 2: /* XY00XY00 */
5250 imm *= 0x01000100;
5251 break;
5252 case 3: /* XYXYXYXY */
5253 imm *= 0x01010101;
5254 break;
5255 default:
5256 /* Rotated constant. */
5257 imm |= 0x80;
5258 break;
5260 return imm;
5263 static int t32_branch24(DisasContext *s, int x)
5265 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
5266 x ^= !(x < 0) * (3 << 21);
5267 /* Append the final zero. */
5268 return x << 1;
5271 static int t16_setflags(DisasContext *s)
5273 return s->condexec_mask == 0;
5276 static int t16_push_list(DisasContext *s, int x)
5278 return (x & 0xff) | (x & 0x100) << (14 - 8);
5281 static int t16_pop_list(DisasContext *s, int x)
5283 return (x & 0xff) | (x & 0x100) << (15 - 8);
5287 * Include the generated decoders.
5290 #include "decode-a32.c.inc"
5291 #include "decode-a32-uncond.c.inc"
5292 #include "decode-t32.c.inc"
5293 #include "decode-t16.c.inc"
5295 static bool valid_cp(DisasContext *s, int cp)
5298 * Return true if this coprocessor field indicates something
5299 * that's really a possible coprocessor.
5300 * For v7 and earlier, coprocessors 8..15 were reserved for Arm use,
5301 * and of those only cp14 and cp15 were used for registers.
5302 * cp10 and cp11 were used for VFP and Neon, whose decode is
5303 * dealt with elsewhere. With the advent of fp16, cp9 is also
5304 * now part of VFP.
5305 * For v8A and later, the encoding has been tightened so that
5306 * only cp14 and cp15 are valid, and other values aren't considered
5307 * to be in the coprocessor-instruction space at all. v8M still
5308 * permits coprocessors 0..7.
5309 * For XScale, we must not decode the XScale cp0, cp1 space as
5310 * a standard coprocessor insn, because we want to fall through to
5311 * the legacy disas_xscale_insn() decoder after decodetree is done.
5313 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cp == 0 || cp == 1)) {
5314 return false;
5317 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
5318 !arm_dc_feature(s, ARM_FEATURE_M)) {
5319 return cp >= 14;
5321 return cp < 8 || cp >= 14;
5324 static bool trans_MCR(DisasContext *s, arg_MCR *a)
5326 if (!valid_cp(s, a->cp)) {
5327 return false;
5329 do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
5330 false, a->rt, 0);
5331 return true;
5334 static bool trans_MRC(DisasContext *s, arg_MRC *a)
5336 if (!valid_cp(s, a->cp)) {
5337 return false;
5339 do_coproc_insn(s, a->cp, false, a->opc1, a->crn, a->crm, a->opc2,
5340 true, a->rt, 0);
5341 return true;
5344 static bool trans_MCRR(DisasContext *s, arg_MCRR *a)
5346 if (!valid_cp(s, a->cp)) {
5347 return false;
5349 do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
5350 false, a->rt, a->rt2);
5351 return true;
5354 static bool trans_MRRC(DisasContext *s, arg_MRRC *a)
5356 if (!valid_cp(s, a->cp)) {
5357 return false;
5359 do_coproc_insn(s, a->cp, true, a->opc1, 0, a->crm, 0,
5360 true, a->rt, a->rt2);
5361 return true;
5364 /* Helpers to swap operands for reverse-subtract. */
5365 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
5367 tcg_gen_sub_i32(dst, b, a);
5370 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
5372 gen_sub_CC(dst, b, a);
5375 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
5377 gen_sub_carry(dest, b, a);
5380 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
5382 gen_sbc_CC(dest, b, a);
5386 * Helpers for the data processing routines.
5388 * After the computation store the results back.
5389 * This may be suppressed altogether (STREG_NONE), require a runtime
5390 * check against the stack limits (STREG_SP_CHECK), or generate an
5391 * exception return. Oh, or store into a register.
5393 * Always return true, indicating success for a trans_* function.
5395 typedef enum {
5396 STREG_NONE,
5397 STREG_NORMAL,
5398 STREG_SP_CHECK,
5399 STREG_EXC_RET,
5400 } StoreRegKind;
5402 static bool store_reg_kind(DisasContext *s, int rd,
5403 TCGv_i32 val, StoreRegKind kind)
5405 switch (kind) {
5406 case STREG_NONE:
5407 tcg_temp_free_i32(val);
5408 return true;
5409 case STREG_NORMAL:
5410 /* See ALUWritePC: Interworking only from a32 mode. */
5411 if (s->thumb) {
5412 store_reg(s, rd, val);
5413 } else {
5414 store_reg_bx(s, rd, val);
5416 return true;
5417 case STREG_SP_CHECK:
5418 store_sp_checked(s, val);
5419 return true;
5420 case STREG_EXC_RET:
5421 gen_exception_return(s, val);
5422 return true;
5424 g_assert_not_reached();
5428 * Data Processing (register)
5430 * Operate, with set flags, one register source,
5431 * one immediate shifted register source, and a destination.
5433 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
5434 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5435 int logic_cc, StoreRegKind kind)
5437 TCGv_i32 tmp1, tmp2;
5439 tmp2 = load_reg(s, a->rm);
5440 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
5441 tmp1 = load_reg(s, a->rn);
5443 gen(tmp1, tmp1, tmp2);
5444 tcg_temp_free_i32(tmp2);
5446 if (logic_cc) {
5447 gen_logic_CC(tmp1);
5449 return store_reg_kind(s, a->rd, tmp1, kind);
5452 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
5453 void (*gen)(TCGv_i32, TCGv_i32),
5454 int logic_cc, StoreRegKind kind)
5456 TCGv_i32 tmp;
5458 tmp = load_reg(s, a->rm);
5459 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
5461 gen(tmp, tmp);
5462 if (logic_cc) {
5463 gen_logic_CC(tmp);
5465 return store_reg_kind(s, a->rd, tmp, kind);
5469 * Data-processing (register-shifted register)
5471 * Operate, with set flags, one register source,
5472 * one register shifted register source, and a destination.
5474 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
5475 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5476 int logic_cc, StoreRegKind kind)
5478 TCGv_i32 tmp1, tmp2;
5480 tmp1 = load_reg(s, a->rs);
5481 tmp2 = load_reg(s, a->rm);
5482 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
5483 tmp1 = load_reg(s, a->rn);
5485 gen(tmp1, tmp1, tmp2);
5486 tcg_temp_free_i32(tmp2);
5488 if (logic_cc) {
5489 gen_logic_CC(tmp1);
5491 return store_reg_kind(s, a->rd, tmp1, kind);
5494 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
5495 void (*gen)(TCGv_i32, TCGv_i32),
5496 int logic_cc, StoreRegKind kind)
5498 TCGv_i32 tmp1, tmp2;
5500 tmp1 = load_reg(s, a->rs);
5501 tmp2 = load_reg(s, a->rm);
5502 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
5504 gen(tmp2, tmp2);
5505 if (logic_cc) {
5506 gen_logic_CC(tmp2);
5508 return store_reg_kind(s, a->rd, tmp2, kind);
5512 * Data-processing (immediate)
5514 * Operate, with set flags, one register source,
5515 * one rotated immediate, and a destination.
5517 * Note that logic_cc && a->rot setting CF based on the msb of the
5518 * immediate is the reason why we must pass in the unrotated form
5519 * of the immediate.
5521 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
5522 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
5523 int logic_cc, StoreRegKind kind)
5525 TCGv_i32 tmp1, tmp2;
5526 uint32_t imm;
5528 imm = ror32(a->imm, a->rot);
5529 if (logic_cc && a->rot) {
5530 tcg_gen_movi_i32(cpu_CF, imm >> 31);
5532 tmp2 = tcg_const_i32(imm);
5533 tmp1 = load_reg(s, a->rn);
5535 gen(tmp1, tmp1, tmp2);
5536 tcg_temp_free_i32(tmp2);
5538 if (logic_cc) {
5539 gen_logic_CC(tmp1);
5541 return store_reg_kind(s, a->rd, tmp1, kind);
5544 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
5545 void (*gen)(TCGv_i32, TCGv_i32),
5546 int logic_cc, StoreRegKind kind)
5548 TCGv_i32 tmp;
5549 uint32_t imm;
5551 imm = ror32(a->imm, a->rot);
5552 if (logic_cc && a->rot) {
5553 tcg_gen_movi_i32(cpu_CF, imm >> 31);
5555 tmp = tcg_const_i32(imm);
5557 gen(tmp, tmp);
5558 if (logic_cc) {
5559 gen_logic_CC(tmp);
5561 return store_reg_kind(s, a->rd, tmp, kind);
5564 #define DO_ANY3(NAME, OP, L, K) \
5565 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
5566 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
5567 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
5568 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
5569 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
5570 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
5572 #define DO_ANY2(NAME, OP, L, K) \
5573 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
5574 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
5575 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
5576 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
5577 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
5578 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
5580 #define DO_CMP2(NAME, OP, L) \
5581 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
5582 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
5583 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
5584 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
5585 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
5586 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
5588 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
5589 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
5590 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
5591 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
5593 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
5594 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
5595 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
5596 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
5598 DO_CMP2(TST, tcg_gen_and_i32, true)
5599 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
5600 DO_CMP2(CMN, gen_add_CC, false)
5601 DO_CMP2(CMP, gen_sub_CC, false)
5603 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
5604 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
5607 * Note for the computation of StoreRegKind we return out of the
5608 * middle of the functions that are expanded by DO_ANY3, and that
5609 * we modify a->s via that parameter before it is used by OP.
5611 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
5613 StoreRegKind ret = STREG_NORMAL;
5614 if (a->rd == 15 && a->s) {
5616 * See ALUExceptionReturn:
5617 * In User mode, UNPREDICTABLE; we choose UNDEF.
5618 * In Hyp mode, UNDEFINED.
5620 if (IS_USER(s) || s->current_el == 2) {
5621 unallocated_encoding(s);
5622 return true;
5624 /* There is no writeback of nzcv to PSTATE. */
5625 a->s = 0;
5626 ret = STREG_EXC_RET;
5627 } else if (a->rd == 13 && a->rn == 13) {
5628 ret = STREG_SP_CHECK;
5630 ret;
5633 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
5635 StoreRegKind ret = STREG_NORMAL;
5636 if (a->rd == 15 && a->s) {
5638 * See ALUExceptionReturn:
5639 * In User mode, UNPREDICTABLE; we choose UNDEF.
5640 * In Hyp mode, UNDEFINED.
5642 if (IS_USER(s) || s->current_el == 2) {
5643 unallocated_encoding(s);
5644 return true;
5646 /* There is no writeback of nzcv to PSTATE. */
5647 a->s = 0;
5648 ret = STREG_EXC_RET;
5649 } else if (a->rd == 13) {
5650 ret = STREG_SP_CHECK;
5652 ret;
5655 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
5658 * ORN is only available with T32, so there is no register-shifted-register
5659 * form of the insn. Using the DO_ANY3 macro would create an unused function.
5661 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
5663 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
5666 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
5668 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
5671 #undef DO_ANY3
5672 #undef DO_ANY2
5673 #undef DO_CMP2
5675 static bool trans_ADR(DisasContext *s, arg_ri *a)
5677 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
5678 return true;
5681 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
5683 TCGv_i32 tmp;
5685 if (!ENABLE_ARCH_6T2) {
5686 return false;
5689 tmp = tcg_const_i32(a->imm);
5690 store_reg(s, a->rd, tmp);
5691 return true;
5694 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
5696 TCGv_i32 tmp;
5698 if (!ENABLE_ARCH_6T2) {
5699 return false;
5702 tmp = load_reg(s, a->rd);
5703 tcg_gen_ext16u_i32(tmp, tmp);
5704 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
5705 store_reg(s, a->rd, tmp);
5706 return true;
5710 * v8.1M MVE wide-shifts
5712 static bool do_mve_shl_ri(DisasContext *s, arg_mve_shl_ri *a,
5713 WideShiftImmFn *fn)
5715 TCGv_i64 rda;
5716 TCGv_i32 rdalo, rdahi;
5718 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5719 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5720 return false;
5722 if (a->rdahi == 15) {
5723 /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
5724 return false;
5726 if (!dc_isar_feature(aa32_mve, s) ||
5727 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5728 a->rdahi == 13) {
5729 /* RdaHi == 13 is UNPREDICTABLE; we choose to UNDEF */
5730 unallocated_encoding(s);
5731 return true;
5734 if (a->shim == 0) {
5735 a->shim = 32;
5738 rda = tcg_temp_new_i64();
5739 rdalo = load_reg(s, a->rdalo);
5740 rdahi = load_reg(s, a->rdahi);
5741 tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
5743 fn(rda, rda, a->shim);
5745 tcg_gen_extrl_i64_i32(rdalo, rda);
5746 tcg_gen_extrh_i64_i32(rdahi, rda);
5747 store_reg(s, a->rdalo, rdalo);
5748 store_reg(s, a->rdahi, rdahi);
5749 tcg_temp_free_i64(rda);
5751 return true;
5754 static bool trans_ASRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5756 return do_mve_shl_ri(s, a, tcg_gen_sari_i64);
5759 static bool trans_LSLL_ri(DisasContext *s, arg_mve_shl_ri *a)
5761 return do_mve_shl_ri(s, a, tcg_gen_shli_i64);
5764 static bool trans_LSRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5766 return do_mve_shl_ri(s, a, tcg_gen_shri_i64);
5769 static void gen_mve_sqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
5771 gen_helper_mve_sqshll(r, cpu_env, n, tcg_constant_i32(shift));
5774 static bool trans_SQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
5776 return do_mve_shl_ri(s, a, gen_mve_sqshll);
5779 static void gen_mve_uqshll(TCGv_i64 r, TCGv_i64 n, int64_t shift)
5781 gen_helper_mve_uqshll(r, cpu_env, n, tcg_constant_i32(shift));
5784 static bool trans_UQSHLL_ri(DisasContext *s, arg_mve_shl_ri *a)
5786 return do_mve_shl_ri(s, a, gen_mve_uqshll);
5789 static bool trans_SRSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5791 return do_mve_shl_ri(s, a, gen_srshr64_i64);
5794 static bool trans_URSHRL_ri(DisasContext *s, arg_mve_shl_ri *a)
5796 return do_mve_shl_ri(s, a, gen_urshr64_i64);
5799 static bool do_mve_shl_rr(DisasContext *s, arg_mve_shl_rr *a, WideShiftFn *fn)
5801 TCGv_i64 rda;
5802 TCGv_i32 rdalo, rdahi;
5804 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5805 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5806 return false;
5808 if (a->rdahi == 15) {
5809 /* These are a different encoding (SQSHL/SRSHR/UQSHL/URSHR) */
5810 return false;
5812 if (!dc_isar_feature(aa32_mve, s) ||
5813 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5814 a->rdahi == 13 || a->rm == 13 || a->rm == 15 ||
5815 a->rm == a->rdahi || a->rm == a->rdalo) {
5816 /* These rdahi/rdalo/rm cases are UNPREDICTABLE; we choose to UNDEF */
5817 unallocated_encoding(s);
5818 return true;
5821 rda = tcg_temp_new_i64();
5822 rdalo = load_reg(s, a->rdalo);
5823 rdahi = load_reg(s, a->rdahi);
5824 tcg_gen_concat_i32_i64(rda, rdalo, rdahi);
5826 /* The helper takes care of the sign-extension of the low 8 bits of Rm */
5827 fn(rda, cpu_env, rda, cpu_R[a->rm]);
5829 tcg_gen_extrl_i64_i32(rdalo, rda);
5830 tcg_gen_extrh_i64_i32(rdahi, rda);
5831 store_reg(s, a->rdalo, rdalo);
5832 store_reg(s, a->rdahi, rdahi);
5833 tcg_temp_free_i64(rda);
5835 return true;
5838 static bool trans_LSLL_rr(DisasContext *s, arg_mve_shl_rr *a)
5840 return do_mve_shl_rr(s, a, gen_helper_mve_ushll);
5843 static bool trans_ASRL_rr(DisasContext *s, arg_mve_shl_rr *a)
5845 return do_mve_shl_rr(s, a, gen_helper_mve_sshrl);
5848 static bool trans_UQRSHLL64_rr(DisasContext *s, arg_mve_shl_rr *a)
5850 return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll);
5853 static bool trans_SQRSHRL64_rr(DisasContext *s, arg_mve_shl_rr *a)
5855 return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl);
5858 static bool trans_UQRSHLL48_rr(DisasContext *s, arg_mve_shl_rr *a)
5860 return do_mve_shl_rr(s, a, gen_helper_mve_uqrshll48);
5863 static bool trans_SQRSHRL48_rr(DisasContext *s, arg_mve_shl_rr *a)
5865 return do_mve_shl_rr(s, a, gen_helper_mve_sqrshrl48);
5868 static bool do_mve_sh_ri(DisasContext *s, arg_mve_sh_ri *a, ShiftImmFn *fn)
5870 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5871 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5872 return false;
5874 if (!dc_isar_feature(aa32_mve, s) ||
5875 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5876 a->rda == 13 || a->rda == 15) {
5877 /* These rda cases are UNPREDICTABLE; we choose to UNDEF */
5878 unallocated_encoding(s);
5879 return true;
5882 if (a->shim == 0) {
5883 a->shim = 32;
5885 fn(cpu_R[a->rda], cpu_R[a->rda], a->shim);
5887 return true;
5890 static bool trans_URSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
5892 return do_mve_sh_ri(s, a, gen_urshr32_i32);
5895 static bool trans_SRSHR_ri(DisasContext *s, arg_mve_sh_ri *a)
5897 return do_mve_sh_ri(s, a, gen_srshr32_i32);
5900 static void gen_mve_sqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
5902 gen_helper_mve_sqshl(r, cpu_env, n, tcg_constant_i32(shift));
5905 static bool trans_SQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
5907 return do_mve_sh_ri(s, a, gen_mve_sqshl);
5910 static void gen_mve_uqshl(TCGv_i32 r, TCGv_i32 n, int32_t shift)
5912 gen_helper_mve_uqshl(r, cpu_env, n, tcg_constant_i32(shift));
5915 static bool trans_UQSHL_ri(DisasContext *s, arg_mve_sh_ri *a)
5917 return do_mve_sh_ri(s, a, gen_mve_uqshl);
5920 static bool do_mve_sh_rr(DisasContext *s, arg_mve_sh_rr *a, ShiftFn *fn)
5922 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
5923 /* Decode falls through to ORR/MOV UNPREDICTABLE handling */
5924 return false;
5926 if (!dc_isar_feature(aa32_mve, s) ||
5927 !arm_dc_feature(s, ARM_FEATURE_M_MAIN) ||
5928 a->rda == 13 || a->rda == 15 || a->rm == 13 || a->rm == 15 ||
5929 a->rm == a->rda) {
5930 /* These rda/rm cases are UNPREDICTABLE; we choose to UNDEF */
5931 unallocated_encoding(s);
5932 return true;
5935 /* The helper takes care of the sign-extension of the low 8 bits of Rm */
5936 fn(cpu_R[a->rda], cpu_env, cpu_R[a->rda], cpu_R[a->rm]);
5937 return true;
5940 static bool trans_SQRSHR_rr(DisasContext *s, arg_mve_sh_rr *a)
5942 return do_mve_sh_rr(s, a, gen_helper_mve_sqrshr);
5945 static bool trans_UQRSHL_rr(DisasContext *s, arg_mve_sh_rr *a)
5947 return do_mve_sh_rr(s, a, gen_helper_mve_uqrshl);
5951 * Multiply and multiply accumulate
5954 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
5956 TCGv_i32 t1, t2;
5958 t1 = load_reg(s, a->rn);
5959 t2 = load_reg(s, a->rm);
5960 tcg_gen_mul_i32(t1, t1, t2);
5961 tcg_temp_free_i32(t2);
5962 if (add) {
5963 t2 = load_reg(s, a->ra);
5964 tcg_gen_add_i32(t1, t1, t2);
5965 tcg_temp_free_i32(t2);
5967 if (a->s) {
5968 gen_logic_CC(t1);
5970 store_reg(s, a->rd, t1);
5971 return true;
5974 static bool trans_MUL(DisasContext *s, arg_MUL *a)
5976 return op_mla(s, a, false);
5979 static bool trans_MLA(DisasContext *s, arg_MLA *a)
5981 return op_mla(s, a, true);
5984 static bool trans_MLS(DisasContext *s, arg_MLS *a)
5986 TCGv_i32 t1, t2;
5988 if (!ENABLE_ARCH_6T2) {
5989 return false;
5991 t1 = load_reg(s, a->rn);
5992 t2 = load_reg(s, a->rm);
5993 tcg_gen_mul_i32(t1, t1, t2);
5994 tcg_temp_free_i32(t2);
5995 t2 = load_reg(s, a->ra);
5996 tcg_gen_sub_i32(t1, t2, t1);
5997 tcg_temp_free_i32(t2);
5998 store_reg(s, a->rd, t1);
5999 return true;
6002 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
6004 TCGv_i32 t0, t1, t2, t3;
6006 t0 = load_reg(s, a->rm);
6007 t1 = load_reg(s, a->rn);
6008 if (uns) {
6009 tcg_gen_mulu2_i32(t0, t1, t0, t1);
6010 } else {
6011 tcg_gen_muls2_i32(t0, t1, t0, t1);
6013 if (add) {
6014 t2 = load_reg(s, a->ra);
6015 t3 = load_reg(s, a->rd);
6016 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
6017 tcg_temp_free_i32(t2);
6018 tcg_temp_free_i32(t3);
6020 if (a->s) {
6021 gen_logicq_cc(t0, t1);
6023 store_reg(s, a->ra, t0);
6024 store_reg(s, a->rd, t1);
6025 return true;
6028 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
6030 return op_mlal(s, a, true, false);
6033 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
6035 return op_mlal(s, a, false, false);
6038 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
6040 return op_mlal(s, a, true, true);
6043 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
6045 return op_mlal(s, a, false, true);
6048 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
6050 TCGv_i32 t0, t1, t2, zero;
6052 if (s->thumb
6053 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
6054 : !ENABLE_ARCH_6) {
6055 return false;
6058 t0 = load_reg(s, a->rm);
6059 t1 = load_reg(s, a->rn);
6060 tcg_gen_mulu2_i32(t0, t1, t0, t1);
6061 zero = tcg_const_i32(0);
6062 t2 = load_reg(s, a->ra);
6063 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
6064 tcg_temp_free_i32(t2);
6065 t2 = load_reg(s, a->rd);
6066 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
6067 tcg_temp_free_i32(t2);
6068 tcg_temp_free_i32(zero);
6069 store_reg(s, a->ra, t0);
6070 store_reg(s, a->rd, t1);
6071 return true;
6075 * Saturating addition and subtraction
6078 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
6080 TCGv_i32 t0, t1;
6082 if (s->thumb
6083 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
6084 : !ENABLE_ARCH_5TE) {
6085 return false;
6088 t0 = load_reg(s, a->rm);
6089 t1 = load_reg(s, a->rn);
6090 if (doub) {
6091 gen_helper_add_saturate(t1, cpu_env, t1, t1);
6093 if (add) {
6094 gen_helper_add_saturate(t0, cpu_env, t0, t1);
6095 } else {
6096 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
6098 tcg_temp_free_i32(t1);
6099 store_reg(s, a->rd, t0);
6100 return true;
6103 #define DO_QADDSUB(NAME, ADD, DOUB) \
6104 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6106 return op_qaddsub(s, a, ADD, DOUB); \
6109 DO_QADDSUB(QADD, true, false)
6110 DO_QADDSUB(QSUB, false, false)
6111 DO_QADDSUB(QDADD, true, true)
6112 DO_QADDSUB(QDSUB, false, true)
6114 #undef DO_QADDSUB
6117 * Halfword multiply and multiply accumulate
6120 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
6121 int add_long, bool nt, bool mt)
6123 TCGv_i32 t0, t1, tl, th;
6125 if (s->thumb
6126 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
6127 : !ENABLE_ARCH_5TE) {
6128 return false;
6131 t0 = load_reg(s, a->rn);
6132 t1 = load_reg(s, a->rm);
6133 gen_mulxy(t0, t1, nt, mt);
6134 tcg_temp_free_i32(t1);
6136 switch (add_long) {
6137 case 0:
6138 store_reg(s, a->rd, t0);
6139 break;
6140 case 1:
6141 t1 = load_reg(s, a->ra);
6142 gen_helper_add_setq(t0, cpu_env, t0, t1);
6143 tcg_temp_free_i32(t1);
6144 store_reg(s, a->rd, t0);
6145 break;
6146 case 2:
6147 tl = load_reg(s, a->ra);
6148 th = load_reg(s, a->rd);
6149 /* Sign-extend the 32-bit product to 64 bits. */
6150 t1 = tcg_temp_new_i32();
6151 tcg_gen_sari_i32(t1, t0, 31);
6152 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
6153 tcg_temp_free_i32(t0);
6154 tcg_temp_free_i32(t1);
6155 store_reg(s, a->ra, tl);
6156 store_reg(s, a->rd, th);
6157 break;
6158 default:
6159 g_assert_not_reached();
6161 return true;
6164 #define DO_SMLAX(NAME, add, nt, mt) \
6165 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
6167 return op_smlaxxx(s, a, add, nt, mt); \
6170 DO_SMLAX(SMULBB, 0, 0, 0)
6171 DO_SMLAX(SMULBT, 0, 0, 1)
6172 DO_SMLAX(SMULTB, 0, 1, 0)
6173 DO_SMLAX(SMULTT, 0, 1, 1)
6175 DO_SMLAX(SMLABB, 1, 0, 0)
6176 DO_SMLAX(SMLABT, 1, 0, 1)
6177 DO_SMLAX(SMLATB, 1, 1, 0)
6178 DO_SMLAX(SMLATT, 1, 1, 1)
6180 DO_SMLAX(SMLALBB, 2, 0, 0)
6181 DO_SMLAX(SMLALBT, 2, 0, 1)
6182 DO_SMLAX(SMLALTB, 2, 1, 0)
6183 DO_SMLAX(SMLALTT, 2, 1, 1)
6185 #undef DO_SMLAX
6187 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
6189 TCGv_i32 t0, t1;
6191 if (!ENABLE_ARCH_5TE) {
6192 return false;
6195 t0 = load_reg(s, a->rn);
6196 t1 = load_reg(s, a->rm);
6198 * Since the nominal result is product<47:16>, shift the 16-bit
6199 * input up by 16 bits, so that the result is at product<63:32>.
6201 if (mt) {
6202 tcg_gen_andi_i32(t1, t1, 0xffff0000);
6203 } else {
6204 tcg_gen_shli_i32(t1, t1, 16);
6206 tcg_gen_muls2_i32(t0, t1, t0, t1);
6207 tcg_temp_free_i32(t0);
6208 if (add) {
6209 t0 = load_reg(s, a->ra);
6210 gen_helper_add_setq(t1, cpu_env, t1, t0);
6211 tcg_temp_free_i32(t0);
6213 store_reg(s, a->rd, t1);
6214 return true;
6217 #define DO_SMLAWX(NAME, add, mt) \
6218 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
6220 return op_smlawx(s, a, add, mt); \
6223 DO_SMLAWX(SMULWB, 0, 0)
6224 DO_SMLAWX(SMULWT, 0, 1)
6225 DO_SMLAWX(SMLAWB, 1, 0)
6226 DO_SMLAWX(SMLAWT, 1, 1)
6228 #undef DO_SMLAWX
6231 * MSR (immediate) and hints
6234 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
6237 * When running single-threaded TCG code, use the helper to ensure that
6238 * the next round-robin scheduled vCPU gets a crack. When running in
6239 * MTTCG we don't generate jumps to the helper as it won't affect the
6240 * scheduling of other vCPUs.
6242 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
6243 gen_set_pc_im(s, s->base.pc_next);
6244 s->base.is_jmp = DISAS_YIELD;
6246 return true;
6249 static bool trans_WFE(DisasContext *s, arg_WFE *a)
6252 * When running single-threaded TCG code, use the helper to ensure that
6253 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
6254 * just skip this instruction. Currently the SEV/SEVL instructions,
6255 * which are *one* of many ways to wake the CPU from WFE, are not
6256 * implemented so we can't sleep like WFI does.
6258 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
6259 gen_set_pc_im(s, s->base.pc_next);
6260 s->base.is_jmp = DISAS_WFE;
6262 return true;
6265 static bool trans_WFI(DisasContext *s, arg_WFI *a)
6267 /* For WFI, halt the vCPU until an IRQ. */
6268 gen_set_pc_im(s, s->base.pc_next);
6269 s->base.is_jmp = DISAS_WFI;
6270 return true;
6273 static bool trans_NOP(DisasContext *s, arg_NOP *a)
6275 return true;
6278 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
6280 uint32_t val = ror32(a->imm, a->rot * 2);
6281 uint32_t mask = msr_mask(s, a->mask, a->r);
6283 if (gen_set_psr_im(s, mask, a->r, val)) {
6284 unallocated_encoding(s);
6286 return true;
6290 * Cyclic Redundancy Check
6293 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
6295 TCGv_i32 t1, t2, t3;
6297 if (!dc_isar_feature(aa32_crc32, s)) {
6298 return false;
6301 t1 = load_reg(s, a->rn);
6302 t2 = load_reg(s, a->rm);
6303 switch (sz) {
6304 case MO_8:
6305 gen_uxtb(t2);
6306 break;
6307 case MO_16:
6308 gen_uxth(t2);
6309 break;
6310 case MO_32:
6311 break;
6312 default:
6313 g_assert_not_reached();
6315 t3 = tcg_const_i32(1 << sz);
6316 if (c) {
6317 gen_helper_crc32c(t1, t1, t2, t3);
6318 } else {
6319 gen_helper_crc32(t1, t1, t2, t3);
6321 tcg_temp_free_i32(t2);
6322 tcg_temp_free_i32(t3);
6323 store_reg(s, a->rd, t1);
6324 return true;
6327 #define DO_CRC32(NAME, c, sz) \
6328 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
6329 { return op_crc32(s, a, c, sz); }
6331 DO_CRC32(CRC32B, false, MO_8)
6332 DO_CRC32(CRC32H, false, MO_16)
6333 DO_CRC32(CRC32W, false, MO_32)
6334 DO_CRC32(CRC32CB, true, MO_8)
6335 DO_CRC32(CRC32CH, true, MO_16)
6336 DO_CRC32(CRC32CW, true, MO_32)
6338 #undef DO_CRC32
6341 * Miscellaneous instructions
6344 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
6346 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6347 return false;
6349 gen_mrs_banked(s, a->r, a->sysm, a->rd);
6350 return true;
6353 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
6355 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6356 return false;
6358 gen_msr_banked(s, a->r, a->sysm, a->rn);
6359 return true;
6362 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
6364 TCGv_i32 tmp;
6366 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6367 return false;
6369 if (a->r) {
6370 if (IS_USER(s)) {
6371 unallocated_encoding(s);
6372 return true;
6374 tmp = load_cpu_field(spsr);
6375 } else {
6376 tmp = tcg_temp_new_i32();
6377 gen_helper_cpsr_read(tmp, cpu_env);
6379 store_reg(s, a->rd, tmp);
6380 return true;
6383 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
6385 TCGv_i32 tmp;
6386 uint32_t mask = msr_mask(s, a->mask, a->r);
6388 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6389 return false;
6391 tmp = load_reg(s, a->rn);
6392 if (gen_set_psr(s, mask, a->r, tmp)) {
6393 unallocated_encoding(s);
6395 return true;
6398 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
6400 TCGv_i32 tmp;
6402 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
6403 return false;
6405 tmp = tcg_const_i32(a->sysm);
6406 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
6407 store_reg(s, a->rd, tmp);
6408 return true;
6411 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
6413 TCGv_i32 addr, reg;
6415 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
6416 return false;
6418 addr = tcg_const_i32((a->mask << 10) | a->sysm);
6419 reg = load_reg(s, a->rn);
6420 gen_helper_v7m_msr(cpu_env, addr, reg);
6421 tcg_temp_free_i32(addr);
6422 tcg_temp_free_i32(reg);
6423 /* If we wrote to CONTROL, the EL might have changed */
6424 gen_helper_rebuild_hflags_m32_newel(cpu_env);
6425 gen_lookup_tb(s);
6426 return true;
6429 static bool trans_BX(DisasContext *s, arg_BX *a)
6431 if (!ENABLE_ARCH_4T) {
6432 return false;
6434 gen_bx_excret(s, load_reg(s, a->rm));
6435 return true;
6438 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
6440 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
6441 return false;
6444 * v7A allows BXJ to be trapped via HSTR.TJDBX. We don't waste a
6445 * TBFLAGS bit on a basically-never-happens case, so call a helper
6446 * function to check for the trap and raise the exception if needed
6447 * (passing it the register number for the syndrome value).
6448 * v8A doesn't have this HSTR bit.
6450 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
6451 arm_dc_feature(s, ARM_FEATURE_EL2) &&
6452 s->current_el < 2 && s->ns) {
6453 gen_helper_check_bxj_trap(cpu_env, tcg_constant_i32(a->rm));
6455 /* Trivial implementation equivalent to bx. */
6456 gen_bx(s, load_reg(s, a->rm));
6457 return true;
6460 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
6462 TCGv_i32 tmp;
6464 if (!ENABLE_ARCH_5) {
6465 return false;
6467 tmp = load_reg(s, a->rm);
6468 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
6469 gen_bx(s, tmp);
6470 return true;
6474 * BXNS/BLXNS: only exist for v8M with the security extensions,
6475 * and always UNDEF if NonSecure. We don't implement these in
6476 * the user-only mode either (in theory you can use them from
6477 * Secure User mode but they are too tied in to system emulation).
6479 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
6481 if (!s->v8m_secure || IS_USER_ONLY) {
6482 unallocated_encoding(s);
6483 } else {
6484 gen_bxns(s, a->rm);
6486 return true;
6489 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
6491 if (!s->v8m_secure || IS_USER_ONLY) {
6492 unallocated_encoding(s);
6493 } else {
6494 gen_blxns(s, a->rm);
6496 return true;
6499 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
6501 TCGv_i32 tmp;
6503 if (!ENABLE_ARCH_5) {
6504 return false;
6506 tmp = load_reg(s, a->rm);
6507 tcg_gen_clzi_i32(tmp, tmp, 32);
6508 store_reg(s, a->rd, tmp);
6509 return true;
6512 static bool trans_ERET(DisasContext *s, arg_ERET *a)
6514 TCGv_i32 tmp;
6516 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
6517 return false;
6519 if (IS_USER(s)) {
6520 unallocated_encoding(s);
6521 return true;
6523 if (s->current_el == 2) {
6524 /* ERET from Hyp uses ELR_Hyp, not LR */
6525 tmp = load_cpu_field(elr_el[2]);
6526 } else {
6527 tmp = load_reg(s, 14);
6529 gen_exception_return(s, tmp);
6530 return true;
6533 static bool trans_HLT(DisasContext *s, arg_HLT *a)
6535 gen_hlt(s, a->imm);
6536 return true;
6539 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
6541 if (!ENABLE_ARCH_5) {
6542 return false;
6544 /* BKPT is OK with ECI set and leaves it untouched */
6545 s->eci_handled = true;
6546 if (arm_dc_feature(s, ARM_FEATURE_M) &&
6547 semihosting_enabled() &&
6548 #ifndef CONFIG_USER_ONLY
6549 !IS_USER(s) &&
6550 #endif
6551 (a->imm == 0xab)) {
6552 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
6553 } else {
6554 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
6556 return true;
6559 static bool trans_HVC(DisasContext *s, arg_HVC *a)
6561 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
6562 return false;
6564 if (IS_USER(s)) {
6565 unallocated_encoding(s);
6566 } else {
6567 gen_hvc(s, a->imm);
6569 return true;
6572 static bool trans_SMC(DisasContext *s, arg_SMC *a)
6574 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
6575 return false;
6577 if (IS_USER(s)) {
6578 unallocated_encoding(s);
6579 } else {
6580 gen_smc(s);
6582 return true;
6585 static bool trans_SG(DisasContext *s, arg_SG *a)
6587 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
6588 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6589 return false;
6592 * SG (v8M only)
6593 * The bulk of the behaviour for this instruction is implemented
6594 * in v7m_handle_execute_nsc(), which deals with the insn when
6595 * it is executed by a CPU in non-secure state from memory
6596 * which is Secure & NonSecure-Callable.
6597 * Here we only need to handle the remaining cases:
6598 * * in NS memory (including the "security extension not
6599 * implemented" case) : NOP
6600 * * in S memory but CPU already secure (clear IT bits)
6601 * We know that the attribute for the memory this insn is
6602 * in must match the current CPU state, because otherwise
6603 * get_phys_addr_pmsav8 would have generated an exception.
6605 if (s->v8m_secure) {
6606 /* Like the IT insn, we don't need to generate any code */
6607 s->condexec_cond = 0;
6608 s->condexec_mask = 0;
6610 return true;
6613 static bool trans_TT(DisasContext *s, arg_TT *a)
6615 TCGv_i32 addr, tmp;
6617 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
6618 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6619 return false;
6621 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
6622 /* We UNDEF for these UNPREDICTABLE cases */
6623 unallocated_encoding(s);
6624 return true;
6626 if (a->A && !s->v8m_secure) {
6627 /* This case is UNDEFINED. */
6628 unallocated_encoding(s);
6629 return true;
6632 addr = load_reg(s, a->rn);
6633 tmp = tcg_const_i32((a->A << 1) | a->T);
6634 gen_helper_v7m_tt(tmp, cpu_env, addr, tmp);
6635 tcg_temp_free_i32(addr);
6636 store_reg(s, a->rd, tmp);
6637 return true;
6641 * Load/store register index
6644 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
6646 ISSInfo ret;
6648 /* ISS not valid if writeback */
6649 if (p && !w) {
6650 ret = rd;
6651 if (s->base.pc_next - s->pc_curr == 2) {
6652 ret |= ISSIs16Bit;
6654 } else {
6655 ret = ISSInvalid;
6657 return ret;
6660 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
6662 TCGv_i32 addr = load_reg(s, a->rn);
6664 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
6665 gen_helper_v8m_stackcheck(cpu_env, addr);
6668 if (a->p) {
6669 TCGv_i32 ofs = load_reg(s, a->rm);
6670 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
6671 if (a->u) {
6672 tcg_gen_add_i32(addr, addr, ofs);
6673 } else {
6674 tcg_gen_sub_i32(addr, addr, ofs);
6676 tcg_temp_free_i32(ofs);
6678 return addr;
6681 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
6682 TCGv_i32 addr, int address_offset)
6684 if (!a->p) {
6685 TCGv_i32 ofs = load_reg(s, a->rm);
6686 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
6687 if (a->u) {
6688 tcg_gen_add_i32(addr, addr, ofs);
6689 } else {
6690 tcg_gen_sub_i32(addr, addr, ofs);
6692 tcg_temp_free_i32(ofs);
6693 } else if (!a->w) {
6694 tcg_temp_free_i32(addr);
6695 return;
6697 tcg_gen_addi_i32(addr, addr, address_offset);
6698 store_reg(s, a->rn, addr);
6701 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
6702 MemOp mop, int mem_idx)
6704 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
6705 TCGv_i32 addr, tmp;
6707 addr = op_addr_rr_pre(s, a);
6709 tmp = tcg_temp_new_i32();
6710 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
6711 disas_set_da_iss(s, mop, issinfo);
6714 * Perform base writeback before the loaded value to
6715 * ensure correct behavior with overlapping index registers.
6717 op_addr_rr_post(s, a, addr, 0);
6718 store_reg_from_load(s, a->rt, tmp);
6719 return true;
6722 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
6723 MemOp mop, int mem_idx)
6725 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
6726 TCGv_i32 addr, tmp;
6729 * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
6730 * is either UNPREDICTABLE or has defined behaviour
6732 if (s->thumb && a->rn == 15) {
6733 return false;
6736 addr = op_addr_rr_pre(s, a);
6738 tmp = load_reg(s, a->rt);
6739 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
6740 disas_set_da_iss(s, mop, issinfo);
6741 tcg_temp_free_i32(tmp);
6743 op_addr_rr_post(s, a, addr, 0);
6744 return true;
6747 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
6749 int mem_idx = get_mem_index(s);
6750 TCGv_i32 addr, tmp;
6752 if (!ENABLE_ARCH_5TE) {
6753 return false;
6755 if (a->rt & 1) {
6756 unallocated_encoding(s);
6757 return true;
6759 addr = op_addr_rr_pre(s, a);
6761 tmp = tcg_temp_new_i32();
6762 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6763 store_reg(s, a->rt, tmp);
6765 tcg_gen_addi_i32(addr, addr, 4);
6767 tmp = tcg_temp_new_i32();
6768 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6769 store_reg(s, a->rt + 1, tmp);
6771 /* LDRD w/ base writeback is undefined if the registers overlap. */
6772 op_addr_rr_post(s, a, addr, -4);
6773 return true;
6776 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
6778 int mem_idx = get_mem_index(s);
6779 TCGv_i32 addr, tmp;
6781 if (!ENABLE_ARCH_5TE) {
6782 return false;
6784 if (a->rt & 1) {
6785 unallocated_encoding(s);
6786 return true;
6788 addr = op_addr_rr_pre(s, a);
6790 tmp = load_reg(s, a->rt);
6791 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6792 tcg_temp_free_i32(tmp);
6794 tcg_gen_addi_i32(addr, addr, 4);
6796 tmp = load_reg(s, a->rt + 1);
6797 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6798 tcg_temp_free_i32(tmp);
6800 op_addr_rr_post(s, a, addr, -4);
6801 return true;
6805 * Load/store immediate index
6808 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
6810 int ofs = a->imm;
6812 if (!a->u) {
6813 ofs = -ofs;
6816 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
6818 * Stackcheck. Here we know 'addr' is the current SP;
6819 * U is set if we're moving SP up, else down. It is
6820 * UNKNOWN whether the limit check triggers when SP starts
6821 * below the limit and ends up above it; we chose to do so.
6823 if (!a->u) {
6824 TCGv_i32 newsp = tcg_temp_new_i32();
6825 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
6826 gen_helper_v8m_stackcheck(cpu_env, newsp);
6827 tcg_temp_free_i32(newsp);
6828 } else {
6829 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
6833 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
6836 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
6837 TCGv_i32 addr, int address_offset)
6839 if (!a->p) {
6840 if (a->u) {
6841 address_offset += a->imm;
6842 } else {
6843 address_offset -= a->imm;
6845 } else if (!a->w) {
6846 tcg_temp_free_i32(addr);
6847 return;
6849 tcg_gen_addi_i32(addr, addr, address_offset);
6850 store_reg(s, a->rn, addr);
6853 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
6854 MemOp mop, int mem_idx)
6856 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
6857 TCGv_i32 addr, tmp;
6859 addr = op_addr_ri_pre(s, a);
6861 tmp = tcg_temp_new_i32();
6862 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop);
6863 disas_set_da_iss(s, mop, issinfo);
6866 * Perform base writeback before the loaded value to
6867 * ensure correct behavior with overlapping index registers.
6869 op_addr_ri_post(s, a, addr, 0);
6870 store_reg_from_load(s, a->rt, tmp);
6871 return true;
6874 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
6875 MemOp mop, int mem_idx)
6877 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
6878 TCGv_i32 addr, tmp;
6881 * In Thumb encodings of stores Rn=1111 is UNDEF; for Arm it
6882 * is either UNPREDICTABLE or has defined behaviour
6884 if (s->thumb && a->rn == 15) {
6885 return false;
6888 addr = op_addr_ri_pre(s, a);
6890 tmp = load_reg(s, a->rt);
6891 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop);
6892 disas_set_da_iss(s, mop, issinfo);
6893 tcg_temp_free_i32(tmp);
6895 op_addr_ri_post(s, a, addr, 0);
6896 return true;
6899 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
6901 int mem_idx = get_mem_index(s);
6902 TCGv_i32 addr, tmp;
6904 addr = op_addr_ri_pre(s, a);
6906 tmp = tcg_temp_new_i32();
6907 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6908 store_reg(s, a->rt, tmp);
6910 tcg_gen_addi_i32(addr, addr, 4);
6912 tmp = tcg_temp_new_i32();
6913 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6914 store_reg(s, rt2, tmp);
6916 /* LDRD w/ base writeback is undefined if the registers overlap. */
6917 op_addr_ri_post(s, a, addr, -4);
6918 return true;
6921 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
6923 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
6924 return false;
6926 return op_ldrd_ri(s, a, a->rt + 1);
6929 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
6931 arg_ldst_ri b = {
6932 .u = a->u, .w = a->w, .p = a->p,
6933 .rn = a->rn, .rt = a->rt, .imm = a->imm
6935 return op_ldrd_ri(s, &b, a->rt2);
6938 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
6940 int mem_idx = get_mem_index(s);
6941 TCGv_i32 addr, tmp;
6943 addr = op_addr_ri_pre(s, a);
6945 tmp = load_reg(s, a->rt);
6946 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6947 tcg_temp_free_i32(tmp);
6949 tcg_gen_addi_i32(addr, addr, 4);
6951 tmp = load_reg(s, rt2);
6952 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
6953 tcg_temp_free_i32(tmp);
6955 op_addr_ri_post(s, a, addr, -4);
6956 return true;
6959 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
6961 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
6962 return false;
6964 return op_strd_ri(s, a, a->rt + 1);
6967 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
6969 arg_ldst_ri b = {
6970 .u = a->u, .w = a->w, .p = a->p,
6971 .rn = a->rn, .rt = a->rt, .imm = a->imm
6973 return op_strd_ri(s, &b, a->rt2);
6976 #define DO_LDST(NAME, WHICH, MEMOP) \
6977 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
6979 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
6981 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
6983 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
6985 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
6987 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
6989 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
6991 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
6994 DO_LDST(LDR, load, MO_UL)
6995 DO_LDST(LDRB, load, MO_UB)
6996 DO_LDST(LDRH, load, MO_UW)
6997 DO_LDST(LDRSB, load, MO_SB)
6998 DO_LDST(LDRSH, load, MO_SW)
7000 DO_LDST(STR, store, MO_UL)
7001 DO_LDST(STRB, store, MO_UB)
7002 DO_LDST(STRH, store, MO_UW)
7004 #undef DO_LDST
7007 * Synchronization primitives
7010 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
7012 TCGv_i32 addr, tmp;
7013 TCGv taddr;
7015 opc |= s->be_data;
7016 addr = load_reg(s, a->rn);
7017 taddr = gen_aa32_addr(s, addr, opc);
7018 tcg_temp_free_i32(addr);
7020 tmp = load_reg(s, a->rt2);
7021 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
7022 tcg_temp_free(taddr);
7024 store_reg(s, a->rt, tmp);
7025 return true;
7028 static bool trans_SWP(DisasContext *s, arg_SWP *a)
7030 return op_swp(s, a, MO_UL | MO_ALIGN);
7033 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
7035 return op_swp(s, a, MO_UB);
7039 * Load/Store Exclusive and Load-Acquire/Store-Release
7042 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
7044 TCGv_i32 addr;
7045 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
7046 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
7048 /* We UNDEF for these UNPREDICTABLE cases. */
7049 if (a->rd == 15 || a->rn == 15 || a->rt == 15
7050 || a->rd == a->rn || a->rd == a->rt
7051 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
7052 || (mop == MO_64
7053 && (a->rt2 == 15
7054 || a->rd == a->rt2
7055 || (!v8a && s->thumb && a->rt2 == 13)))) {
7056 unallocated_encoding(s);
7057 return true;
7060 if (rel) {
7061 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7064 addr = tcg_temp_local_new_i32();
7065 load_reg_var(s, addr, a->rn);
7066 tcg_gen_addi_i32(addr, addr, a->imm);
7068 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
7069 tcg_temp_free_i32(addr);
7070 return true;
7073 static bool trans_STREX(DisasContext *s, arg_STREX *a)
7075 if (!ENABLE_ARCH_6) {
7076 return false;
7078 return op_strex(s, a, MO_32, false);
7081 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
7083 if (!ENABLE_ARCH_6K) {
7084 return false;
7086 /* We UNDEF for these UNPREDICTABLE cases. */
7087 if (a->rt & 1) {
7088 unallocated_encoding(s);
7089 return true;
7091 a->rt2 = a->rt + 1;
7092 return op_strex(s, a, MO_64, false);
7095 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
7097 return op_strex(s, a, MO_64, false);
7100 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
7102 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7103 return false;
7105 return op_strex(s, a, MO_8, false);
7108 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
7110 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7111 return false;
7113 return op_strex(s, a, MO_16, false);
7116 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
7118 if (!ENABLE_ARCH_8) {
7119 return false;
7121 return op_strex(s, a, MO_32, true);
7124 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
7126 if (!ENABLE_ARCH_8) {
7127 return false;
7129 /* We UNDEF for these UNPREDICTABLE cases. */
7130 if (a->rt & 1) {
7131 unallocated_encoding(s);
7132 return true;
7134 a->rt2 = a->rt + 1;
7135 return op_strex(s, a, MO_64, true);
7138 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
7140 if (!ENABLE_ARCH_8) {
7141 return false;
7143 return op_strex(s, a, MO_64, true);
7146 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
7148 if (!ENABLE_ARCH_8) {
7149 return false;
7151 return op_strex(s, a, MO_8, true);
7154 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
7156 if (!ENABLE_ARCH_8) {
7157 return false;
7159 return op_strex(s, a, MO_16, true);
7162 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
7164 TCGv_i32 addr, tmp;
7166 if (!ENABLE_ARCH_8) {
7167 return false;
7169 /* We UNDEF for these UNPREDICTABLE cases. */
7170 if (a->rn == 15 || a->rt == 15) {
7171 unallocated_encoding(s);
7172 return true;
7175 addr = load_reg(s, a->rn);
7176 tmp = load_reg(s, a->rt);
7177 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7178 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
7179 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
7181 tcg_temp_free_i32(tmp);
7182 tcg_temp_free_i32(addr);
7183 return true;
7186 static bool trans_STL(DisasContext *s, arg_STL *a)
7188 return op_stl(s, a, MO_UL);
7191 static bool trans_STLB(DisasContext *s, arg_STL *a)
7193 return op_stl(s, a, MO_UB);
7196 static bool trans_STLH(DisasContext *s, arg_STL *a)
7198 return op_stl(s, a, MO_UW);
7201 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
7203 TCGv_i32 addr;
7204 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
7205 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
7207 /* We UNDEF for these UNPREDICTABLE cases. */
7208 if (a->rn == 15 || a->rt == 15
7209 || (!v8a && s->thumb && a->rt == 13)
7210 || (mop == MO_64
7211 && (a->rt2 == 15 || a->rt == a->rt2
7212 || (!v8a && s->thumb && a->rt2 == 13)))) {
7213 unallocated_encoding(s);
7214 return true;
7217 addr = tcg_temp_local_new_i32();
7218 load_reg_var(s, addr, a->rn);
7219 tcg_gen_addi_i32(addr, addr, a->imm);
7221 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
7222 tcg_temp_free_i32(addr);
7224 if (acq) {
7225 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
7227 return true;
7230 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
7232 if (!ENABLE_ARCH_6) {
7233 return false;
7235 return op_ldrex(s, a, MO_32, false);
7238 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
7240 if (!ENABLE_ARCH_6K) {
7241 return false;
7243 /* We UNDEF for these UNPREDICTABLE cases. */
7244 if (a->rt & 1) {
7245 unallocated_encoding(s);
7246 return true;
7248 a->rt2 = a->rt + 1;
7249 return op_ldrex(s, a, MO_64, false);
7252 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
7254 return op_ldrex(s, a, MO_64, false);
7257 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
7259 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7260 return false;
7262 return op_ldrex(s, a, MO_8, false);
7265 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
7267 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
7268 return false;
7270 return op_ldrex(s, a, MO_16, false);
7273 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
7275 if (!ENABLE_ARCH_8) {
7276 return false;
7278 return op_ldrex(s, a, MO_32, true);
7281 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
7283 if (!ENABLE_ARCH_8) {
7284 return false;
7286 /* We UNDEF for these UNPREDICTABLE cases. */
7287 if (a->rt & 1) {
7288 unallocated_encoding(s);
7289 return true;
7291 a->rt2 = a->rt + 1;
7292 return op_ldrex(s, a, MO_64, true);
7295 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
7297 if (!ENABLE_ARCH_8) {
7298 return false;
7300 return op_ldrex(s, a, MO_64, true);
7303 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
7305 if (!ENABLE_ARCH_8) {
7306 return false;
7308 return op_ldrex(s, a, MO_8, true);
7311 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
7313 if (!ENABLE_ARCH_8) {
7314 return false;
7316 return op_ldrex(s, a, MO_16, true);
7319 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
7321 TCGv_i32 addr, tmp;
7323 if (!ENABLE_ARCH_8) {
7324 return false;
7326 /* We UNDEF for these UNPREDICTABLE cases. */
7327 if (a->rn == 15 || a->rt == 15) {
7328 unallocated_encoding(s);
7329 return true;
7332 addr = load_reg(s, a->rn);
7333 tmp = tcg_temp_new_i32();
7334 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | MO_ALIGN);
7335 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
7336 tcg_temp_free_i32(addr);
7338 store_reg(s, a->rt, tmp);
7339 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7340 return true;
7343 static bool trans_LDA(DisasContext *s, arg_LDA *a)
7345 return op_lda(s, a, MO_UL);
7348 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
7350 return op_lda(s, a, MO_UB);
7353 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
7355 return op_lda(s, a, MO_UW);
7359 * Media instructions
7362 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
7364 TCGv_i32 t1, t2;
7366 if (!ENABLE_ARCH_6) {
7367 return false;
7370 t1 = load_reg(s, a->rn);
7371 t2 = load_reg(s, a->rm);
7372 gen_helper_usad8(t1, t1, t2);
7373 tcg_temp_free_i32(t2);
7374 if (a->ra != 15) {
7375 t2 = load_reg(s, a->ra);
7376 tcg_gen_add_i32(t1, t1, t2);
7377 tcg_temp_free_i32(t2);
7379 store_reg(s, a->rd, t1);
7380 return true;
7383 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
7385 TCGv_i32 tmp;
7386 int width = a->widthm1 + 1;
7387 int shift = a->lsb;
7389 if (!ENABLE_ARCH_6T2) {
7390 return false;
7392 if (shift + width > 32) {
7393 /* UNPREDICTABLE; we choose to UNDEF */
7394 unallocated_encoding(s);
7395 return true;
7398 tmp = load_reg(s, a->rn);
7399 if (u) {
7400 tcg_gen_extract_i32(tmp, tmp, shift, width);
7401 } else {
7402 tcg_gen_sextract_i32(tmp, tmp, shift, width);
7404 store_reg(s, a->rd, tmp);
7405 return true;
7408 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
7410 return op_bfx(s, a, false);
7413 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
7415 return op_bfx(s, a, true);
7418 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
7420 TCGv_i32 tmp;
7421 int msb = a->msb, lsb = a->lsb;
7422 int width;
7424 if (!ENABLE_ARCH_6T2) {
7425 return false;
7427 if (msb < lsb) {
7428 /* UNPREDICTABLE; we choose to UNDEF */
7429 unallocated_encoding(s);
7430 return true;
7433 width = msb + 1 - lsb;
7434 if (a->rn == 15) {
7435 /* BFC */
7436 tmp = tcg_const_i32(0);
7437 } else {
7438 /* BFI */
7439 tmp = load_reg(s, a->rn);
7441 if (width != 32) {
7442 TCGv_i32 tmp2 = load_reg(s, a->rd);
7443 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
7444 tcg_temp_free_i32(tmp2);
7446 store_reg(s, a->rd, tmp);
7447 return true;
7450 static bool trans_UDF(DisasContext *s, arg_UDF *a)
7452 unallocated_encoding(s);
7453 return true;
7457 * Parallel addition and subtraction
7460 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
7461 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
7463 TCGv_i32 t0, t1;
7465 if (s->thumb
7466 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7467 : !ENABLE_ARCH_6) {
7468 return false;
7471 t0 = load_reg(s, a->rn);
7472 t1 = load_reg(s, a->rm);
7474 gen(t0, t0, t1);
7476 tcg_temp_free_i32(t1);
7477 store_reg(s, a->rd, t0);
7478 return true;
7481 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
7482 void (*gen)(TCGv_i32, TCGv_i32,
7483 TCGv_i32, TCGv_ptr))
7485 TCGv_i32 t0, t1;
7486 TCGv_ptr ge;
7488 if (s->thumb
7489 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7490 : !ENABLE_ARCH_6) {
7491 return false;
7494 t0 = load_reg(s, a->rn);
7495 t1 = load_reg(s, a->rm);
7497 ge = tcg_temp_new_ptr();
7498 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
7499 gen(t0, t0, t1, ge);
7501 tcg_temp_free_ptr(ge);
7502 tcg_temp_free_i32(t1);
7503 store_reg(s, a->rd, t0);
7504 return true;
7507 #define DO_PAR_ADDSUB(NAME, helper) \
7508 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7510 return op_par_addsub(s, a, helper); \
7513 #define DO_PAR_ADDSUB_GE(NAME, helper) \
7514 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7516 return op_par_addsub_ge(s, a, helper); \
7519 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
7520 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
7521 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
7522 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
7523 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
7524 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
7526 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
7527 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
7528 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
7529 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
7530 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
7531 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
7533 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
7534 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
7535 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
7536 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
7537 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
7538 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
7540 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
7541 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
7542 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
7543 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
7544 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
7545 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
7547 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
7548 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
7549 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
7550 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
7551 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
7552 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
7554 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
7555 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
7556 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
7557 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
7558 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
7559 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
7561 #undef DO_PAR_ADDSUB
7562 #undef DO_PAR_ADDSUB_GE
7565 * Packing, unpacking, saturation, and reversal
7568 static bool trans_PKH(DisasContext *s, arg_PKH *a)
7570 TCGv_i32 tn, tm;
7571 int shift = a->imm;
7573 if (s->thumb
7574 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7575 : !ENABLE_ARCH_6) {
7576 return false;
7579 tn = load_reg(s, a->rn);
7580 tm = load_reg(s, a->rm);
7581 if (a->tb) {
7582 /* PKHTB */
7583 if (shift == 0) {
7584 shift = 31;
7586 tcg_gen_sari_i32(tm, tm, shift);
7587 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
7588 } else {
7589 /* PKHBT */
7590 tcg_gen_shli_i32(tm, tm, shift);
7591 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
7593 tcg_temp_free_i32(tm);
7594 store_reg(s, a->rd, tn);
7595 return true;
7598 static bool op_sat(DisasContext *s, arg_sat *a,
7599 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
7601 TCGv_i32 tmp, satimm;
7602 int shift = a->imm;
7604 if (!ENABLE_ARCH_6) {
7605 return false;
7608 tmp = load_reg(s, a->rn);
7609 if (a->sh) {
7610 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
7611 } else {
7612 tcg_gen_shli_i32(tmp, tmp, shift);
7615 satimm = tcg_const_i32(a->satimm);
7616 gen(tmp, cpu_env, tmp, satimm);
7617 tcg_temp_free_i32(satimm);
7619 store_reg(s, a->rd, tmp);
7620 return true;
7623 static bool trans_SSAT(DisasContext *s, arg_sat *a)
7625 return op_sat(s, a, gen_helper_ssat);
7628 static bool trans_USAT(DisasContext *s, arg_sat *a)
7630 return op_sat(s, a, gen_helper_usat);
7633 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
7635 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7636 return false;
7638 return op_sat(s, a, gen_helper_ssat16);
7641 static bool trans_USAT16(DisasContext *s, arg_sat *a)
7643 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7644 return false;
7646 return op_sat(s, a, gen_helper_usat16);
7649 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
7650 void (*gen_extract)(TCGv_i32, TCGv_i32),
7651 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
7653 TCGv_i32 tmp;
7655 if (!ENABLE_ARCH_6) {
7656 return false;
7659 tmp = load_reg(s, a->rm);
7661 * TODO: In many cases we could do a shift instead of a rotate.
7662 * Combined with a simple extend, that becomes an extract.
7664 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
7665 gen_extract(tmp, tmp);
7667 if (a->rn != 15) {
7668 TCGv_i32 tmp2 = load_reg(s, a->rn);
7669 gen_add(tmp, tmp, tmp2);
7670 tcg_temp_free_i32(tmp2);
7672 store_reg(s, a->rd, tmp);
7673 return true;
7676 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
7678 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
7681 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
7683 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
7686 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
7688 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7689 return false;
7691 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
7694 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
7696 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
7699 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
7701 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
7704 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
7706 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
7707 return false;
7709 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
7712 static bool trans_SEL(DisasContext *s, arg_rrr *a)
7714 TCGv_i32 t1, t2, t3;
7716 if (s->thumb
7717 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7718 : !ENABLE_ARCH_6) {
7719 return false;
7722 t1 = load_reg(s, a->rn);
7723 t2 = load_reg(s, a->rm);
7724 t3 = tcg_temp_new_i32();
7725 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
7726 gen_helper_sel_flags(t1, t3, t1, t2);
7727 tcg_temp_free_i32(t3);
7728 tcg_temp_free_i32(t2);
7729 store_reg(s, a->rd, t1);
7730 return true;
7733 static bool op_rr(DisasContext *s, arg_rr *a,
7734 void (*gen)(TCGv_i32, TCGv_i32))
7736 TCGv_i32 tmp;
7738 tmp = load_reg(s, a->rm);
7739 gen(tmp, tmp);
7740 store_reg(s, a->rd, tmp);
7741 return true;
7744 static bool trans_REV(DisasContext *s, arg_rr *a)
7746 if (!ENABLE_ARCH_6) {
7747 return false;
7749 return op_rr(s, a, tcg_gen_bswap32_i32);
7752 static bool trans_REV16(DisasContext *s, arg_rr *a)
7754 if (!ENABLE_ARCH_6) {
7755 return false;
7757 return op_rr(s, a, gen_rev16);
7760 static bool trans_REVSH(DisasContext *s, arg_rr *a)
7762 if (!ENABLE_ARCH_6) {
7763 return false;
7765 return op_rr(s, a, gen_revsh);
7768 static bool trans_RBIT(DisasContext *s, arg_rr *a)
7770 if (!ENABLE_ARCH_6T2) {
7771 return false;
7773 return op_rr(s, a, gen_helper_rbit);
7777 * Signed multiply, signed and unsigned divide
7780 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
7782 TCGv_i32 t1, t2;
7784 if (!ENABLE_ARCH_6) {
7785 return false;
7788 t1 = load_reg(s, a->rn);
7789 t2 = load_reg(s, a->rm);
7790 if (m_swap) {
7791 gen_swap_half(t2, t2);
7793 gen_smul_dual(t1, t2);
7795 if (sub) {
7797 * This subtraction cannot overflow, so we can do a simple
7798 * 32-bit subtraction and then a possible 32-bit saturating
7799 * addition of Ra.
7801 tcg_gen_sub_i32(t1, t1, t2);
7802 tcg_temp_free_i32(t2);
7804 if (a->ra != 15) {
7805 t2 = load_reg(s, a->ra);
7806 gen_helper_add_setq(t1, cpu_env, t1, t2);
7807 tcg_temp_free_i32(t2);
7809 } else if (a->ra == 15) {
7810 /* Single saturation-checking addition */
7811 gen_helper_add_setq(t1, cpu_env, t1, t2);
7812 tcg_temp_free_i32(t2);
7813 } else {
7815 * We need to add the products and Ra together and then
7816 * determine whether the final result overflowed. Doing
7817 * this as two separate add-and-check-overflow steps incorrectly
7818 * sets Q for cases like (-32768 * -32768) + (-32768 * -32768) + -1.
7819 * Do all the arithmetic at 64-bits and then check for overflow.
7821 TCGv_i64 p64, q64;
7822 TCGv_i32 t3, qf, one;
7824 p64 = tcg_temp_new_i64();
7825 q64 = tcg_temp_new_i64();
7826 tcg_gen_ext_i32_i64(p64, t1);
7827 tcg_gen_ext_i32_i64(q64, t2);
7828 tcg_gen_add_i64(p64, p64, q64);
7829 load_reg_var(s, t2, a->ra);
7830 tcg_gen_ext_i32_i64(q64, t2);
7831 tcg_gen_add_i64(p64, p64, q64);
7832 tcg_temp_free_i64(q64);
7834 tcg_gen_extr_i64_i32(t1, t2, p64);
7835 tcg_temp_free_i64(p64);
7837 * t1 is the low half of the result which goes into Rd.
7838 * We have overflow and must set Q if the high half (t2)
7839 * is different from the sign-extension of t1.
7841 t3 = tcg_temp_new_i32();
7842 tcg_gen_sari_i32(t3, t1, 31);
7843 qf = load_cpu_field(QF);
7844 one = tcg_const_i32(1);
7845 tcg_gen_movcond_i32(TCG_COND_NE, qf, t2, t3, one, qf);
7846 store_cpu_field(qf, QF);
7847 tcg_temp_free_i32(one);
7848 tcg_temp_free_i32(t3);
7849 tcg_temp_free_i32(t2);
7851 store_reg(s, a->rd, t1);
7852 return true;
7855 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
7857 return op_smlad(s, a, false, false);
7860 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
7862 return op_smlad(s, a, true, false);
7865 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
7867 return op_smlad(s, a, false, true);
7870 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
7872 return op_smlad(s, a, true, true);
7875 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
7877 TCGv_i32 t1, t2;
7878 TCGv_i64 l1, l2;
7880 if (!ENABLE_ARCH_6) {
7881 return false;
7884 t1 = load_reg(s, a->rn);
7885 t2 = load_reg(s, a->rm);
7886 if (m_swap) {
7887 gen_swap_half(t2, t2);
7889 gen_smul_dual(t1, t2);
7891 l1 = tcg_temp_new_i64();
7892 l2 = tcg_temp_new_i64();
7893 tcg_gen_ext_i32_i64(l1, t1);
7894 tcg_gen_ext_i32_i64(l2, t2);
7895 tcg_temp_free_i32(t1);
7896 tcg_temp_free_i32(t2);
7898 if (sub) {
7899 tcg_gen_sub_i64(l1, l1, l2);
7900 } else {
7901 tcg_gen_add_i64(l1, l1, l2);
7903 tcg_temp_free_i64(l2);
7905 gen_addq(s, l1, a->ra, a->rd);
7906 gen_storeq_reg(s, a->ra, a->rd, l1);
7907 tcg_temp_free_i64(l1);
7908 return true;
7911 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
7913 return op_smlald(s, a, false, false);
7916 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
7918 return op_smlald(s, a, true, false);
7921 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
7923 return op_smlald(s, a, false, true);
7926 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
7928 return op_smlald(s, a, true, true);
7931 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
7933 TCGv_i32 t1, t2;
7935 if (s->thumb
7936 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7937 : !ENABLE_ARCH_6) {
7938 return false;
7941 t1 = load_reg(s, a->rn);
7942 t2 = load_reg(s, a->rm);
7943 tcg_gen_muls2_i32(t2, t1, t1, t2);
7945 if (a->ra != 15) {
7946 TCGv_i32 t3 = load_reg(s, a->ra);
7947 if (sub) {
7949 * For SMMLS, we need a 64-bit subtract. Borrow caused by
7950 * a non-zero multiplicand lowpart, and the correct result
7951 * lowpart for rounding.
7953 TCGv_i32 zero = tcg_const_i32(0);
7954 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
7955 tcg_temp_free_i32(zero);
7956 } else {
7957 tcg_gen_add_i32(t1, t1, t3);
7959 tcg_temp_free_i32(t3);
7961 if (round) {
7963 * Adding 0x80000000 to the 64-bit quantity means that we have
7964 * carry in to the high word when the low word has the msb set.
7966 tcg_gen_shri_i32(t2, t2, 31);
7967 tcg_gen_add_i32(t1, t1, t2);
7969 tcg_temp_free_i32(t2);
7970 store_reg(s, a->rd, t1);
7971 return true;
7974 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
7976 return op_smmla(s, a, false, false);
7979 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
7981 return op_smmla(s, a, true, false);
7984 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
7986 return op_smmla(s, a, false, true);
7989 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
7991 return op_smmla(s, a, true, true);
7994 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
7996 TCGv_i32 t1, t2;
7998 if (s->thumb
7999 ? !dc_isar_feature(aa32_thumb_div, s)
8000 : !dc_isar_feature(aa32_arm_div, s)) {
8001 return false;
8004 t1 = load_reg(s, a->rn);
8005 t2 = load_reg(s, a->rm);
8006 if (u) {
8007 gen_helper_udiv(t1, cpu_env, t1, t2);
8008 } else {
8009 gen_helper_sdiv(t1, cpu_env, t1, t2);
8011 tcg_temp_free_i32(t2);
8012 store_reg(s, a->rd, t1);
8013 return true;
8016 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
8018 return op_div(s, a, false);
8021 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
8023 return op_div(s, a, true);
8027 * Block data transfer
8030 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
8032 TCGv_i32 addr = load_reg(s, a->rn);
8034 if (a->b) {
8035 if (a->i) {
8036 /* pre increment */
8037 tcg_gen_addi_i32(addr, addr, 4);
8038 } else {
8039 /* pre decrement */
8040 tcg_gen_addi_i32(addr, addr, -(n * 4));
8042 } else if (!a->i && n != 1) {
8043 /* post decrement */
8044 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8047 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8049 * If the writeback is incrementing SP rather than
8050 * decrementing it, and the initial SP is below the
8051 * stack limit but the final written-back SP would
8052 * be above, then then we must not perform any memory
8053 * accesses, but it is IMPDEF whether we generate
8054 * an exception. We choose to do so in this case.
8055 * At this point 'addr' is the lowest address, so
8056 * either the original SP (if incrementing) or our
8057 * final SP (if decrementing), so that's what we check.
8059 gen_helper_v8m_stackcheck(cpu_env, addr);
8062 return addr;
8065 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
8066 TCGv_i32 addr, int n)
8068 if (a->w) {
8069 /* write back */
8070 if (!a->b) {
8071 if (a->i) {
8072 /* post increment */
8073 tcg_gen_addi_i32(addr, addr, 4);
8074 } else {
8075 /* post decrement */
8076 tcg_gen_addi_i32(addr, addr, -(n * 4));
8078 } else if (!a->i && n != 1) {
8079 /* pre decrement */
8080 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8082 store_reg(s, a->rn, addr);
8083 } else {
8084 tcg_temp_free_i32(addr);
8088 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
8090 int i, j, n, list, mem_idx;
8091 bool user = a->u;
8092 TCGv_i32 addr, tmp, tmp2;
8094 if (user) {
8095 /* STM (user) */
8096 if (IS_USER(s)) {
8097 /* Only usable in supervisor mode. */
8098 unallocated_encoding(s);
8099 return true;
8103 list = a->list;
8104 n = ctpop16(list);
8105 if (n < min_n || a->rn == 15) {
8106 unallocated_encoding(s);
8107 return true;
8110 s->eci_handled = true;
8112 addr = op_addr_block_pre(s, a, n);
8113 mem_idx = get_mem_index(s);
8115 for (i = j = 0; i < 16; i++) {
8116 if (!(list & (1 << i))) {
8117 continue;
8120 if (user && i != 15) {
8121 tmp = tcg_temp_new_i32();
8122 tmp2 = tcg_const_i32(i);
8123 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8124 tcg_temp_free_i32(tmp2);
8125 } else {
8126 tmp = load_reg(s, i);
8128 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
8129 tcg_temp_free_i32(tmp);
8131 /* No need to add after the last transfer. */
8132 if (++j != n) {
8133 tcg_gen_addi_i32(addr, addr, 4);
8137 op_addr_block_post(s, a, addr, n);
8138 clear_eci_state(s);
8139 return true;
8142 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
8144 /* BitCount(list) < 1 is UNPREDICTABLE */
8145 return op_stm(s, a, 1);
8148 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
8150 /* Writeback register in register list is UNPREDICTABLE for T32. */
8151 if (a->w && (a->list & (1 << a->rn))) {
8152 unallocated_encoding(s);
8153 return true;
8155 /* BitCount(list) < 2 is UNPREDICTABLE */
8156 return op_stm(s, a, 2);
8159 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
8161 int i, j, n, list, mem_idx;
8162 bool loaded_base;
8163 bool user = a->u;
8164 bool exc_return = false;
8165 TCGv_i32 addr, tmp, tmp2, loaded_var;
8167 if (user) {
8168 /* LDM (user), LDM (exception return) */
8169 if (IS_USER(s)) {
8170 /* Only usable in supervisor mode. */
8171 unallocated_encoding(s);
8172 return true;
8174 if (extract32(a->list, 15, 1)) {
8175 exc_return = true;
8176 user = false;
8177 } else {
8178 /* LDM (user) does not allow writeback. */
8179 if (a->w) {
8180 unallocated_encoding(s);
8181 return true;
8186 list = a->list;
8187 n = ctpop16(list);
8188 if (n < min_n || a->rn == 15) {
8189 unallocated_encoding(s);
8190 return true;
8193 s->eci_handled = true;
8195 addr = op_addr_block_pre(s, a, n);
8196 mem_idx = get_mem_index(s);
8197 loaded_base = false;
8198 loaded_var = NULL;
8200 for (i = j = 0; i < 16; i++) {
8201 if (!(list & (1 << i))) {
8202 continue;
8205 tmp = tcg_temp_new_i32();
8206 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | MO_ALIGN);
8207 if (user) {
8208 tmp2 = tcg_const_i32(i);
8209 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8210 tcg_temp_free_i32(tmp2);
8211 tcg_temp_free_i32(tmp);
8212 } else if (i == a->rn) {
8213 loaded_var = tmp;
8214 loaded_base = true;
8215 } else if (i == 15 && exc_return) {
8216 store_pc_exc_ret(s, tmp);
8217 } else {
8218 store_reg_from_load(s, i, tmp);
8221 /* No need to add after the last transfer. */
8222 if (++j != n) {
8223 tcg_gen_addi_i32(addr, addr, 4);
8227 op_addr_block_post(s, a, addr, n);
8229 if (loaded_base) {
8230 /* Note that we reject base == pc above. */
8231 store_reg(s, a->rn, loaded_var);
8234 if (exc_return) {
8235 /* Restore CPSR from SPSR. */
8236 tmp = load_cpu_field(spsr);
8237 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
8238 gen_io_start();
8240 gen_helper_cpsr_write_eret(cpu_env, tmp);
8241 tcg_temp_free_i32(tmp);
8242 /* Must exit loop to check un-masked IRQs */
8243 s->base.is_jmp = DISAS_EXIT;
8245 clear_eci_state(s);
8246 return true;
8249 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
8252 * Writeback register in register list is UNPREDICTABLE
8253 * for ArchVersion() >= 7. Prior to v7, A32 would write
8254 * an UNKNOWN value to the base register.
8256 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
8257 unallocated_encoding(s);
8258 return true;
8260 /* BitCount(list) < 1 is UNPREDICTABLE */
8261 return do_ldm(s, a, 1);
8264 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
8266 /* Writeback register in register list is UNPREDICTABLE for T32. */
8267 if (a->w && (a->list & (1 << a->rn))) {
8268 unallocated_encoding(s);
8269 return true;
8271 /* BitCount(list) < 2 is UNPREDICTABLE */
8272 return do_ldm(s, a, 2);
8275 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
8277 /* Writeback is conditional on the base register not being loaded. */
8278 a->w = !(a->list & (1 << a->rn));
8279 /* BitCount(list) < 1 is UNPREDICTABLE */
8280 return do_ldm(s, a, 1);
8283 static bool trans_CLRM(DisasContext *s, arg_CLRM *a)
8285 int i;
8286 TCGv_i32 zero;
8288 if (!dc_isar_feature(aa32_m_sec_state, s)) {
8289 return false;
8292 if (extract32(a->list, 13, 1)) {
8293 return false;
8296 if (!a->list) {
8297 /* UNPREDICTABLE; we choose to UNDEF */
8298 return false;
8301 s->eci_handled = true;
8303 zero = tcg_const_i32(0);
8304 for (i = 0; i < 15; i++) {
8305 if (extract32(a->list, i, 1)) {
8306 /* Clear R[i] */
8307 tcg_gen_mov_i32(cpu_R[i], zero);
8310 if (extract32(a->list, 15, 1)) {
8312 * Clear APSR (by calling the MSR helper with the same argument
8313 * as for "MSR APSR_nzcvqg, Rn": mask = 0b1100, SYSM=0)
8315 TCGv_i32 maskreg = tcg_const_i32(0xc << 8);
8316 gen_helper_v7m_msr(cpu_env, maskreg, zero);
8317 tcg_temp_free_i32(maskreg);
8319 tcg_temp_free_i32(zero);
8320 clear_eci_state(s);
8321 return true;
8325 * Branch, branch with link
8328 static bool trans_B(DisasContext *s, arg_i *a)
8330 gen_jmp(s, read_pc(s) + a->imm);
8331 return true;
8334 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
8336 /* This has cond from encoding, required to be outside IT block. */
8337 if (a->cond >= 0xe) {
8338 return false;
8340 if (s->condexec_mask) {
8341 unallocated_encoding(s);
8342 return true;
8344 arm_skip_unless(s, a->cond);
8345 gen_jmp(s, read_pc(s) + a->imm);
8346 return true;
8349 static bool trans_BL(DisasContext *s, arg_i *a)
8351 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8352 gen_jmp(s, read_pc(s) + a->imm);
8353 return true;
8356 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
8358 TCGv_i32 tmp;
8361 * BLX <imm> would be useless on M-profile; the encoding space
8362 * is used for other insns from v8.1M onward, and UNDEFs before that.
8364 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8365 return false;
8368 /* For A32, ARM_FEATURE_V5 is checked near the start of the uncond block. */
8369 if (s->thumb && (a->imm & 2)) {
8370 return false;
8372 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8373 tmp = tcg_const_i32(!s->thumb);
8374 store_cpu_field(tmp, thumb);
8375 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
8376 return true;
8379 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
8381 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8382 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
8383 return true;
8386 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
8388 TCGv_i32 tmp = tcg_temp_new_i32();
8390 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8391 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
8392 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
8393 gen_bx(s, tmp);
8394 return true;
8397 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
8399 TCGv_i32 tmp;
8401 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
8402 if (!ENABLE_ARCH_5) {
8403 return false;
8405 tmp = tcg_temp_new_i32();
8406 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
8407 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8408 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
8409 gen_bx(s, tmp);
8410 return true;
8413 static bool trans_BF(DisasContext *s, arg_BF *a)
8416 * M-profile branch future insns. The architecture permits an
8417 * implementation to implement these as NOPs (equivalent to
8418 * discarding the LO_BRANCH_INFO cache immediately), and we
8419 * take that IMPDEF option because for QEMU a "real" implementation
8420 * would be complicated and wouldn't execute any faster.
8422 if (!dc_isar_feature(aa32_lob, s)) {
8423 return false;
8425 if (a->boff == 0) {
8426 /* SEE "Related encodings" (loop insns) */
8427 return false;
8429 /* Handle as NOP */
8430 return true;
8433 static bool trans_DLS(DisasContext *s, arg_DLS *a)
8435 /* M-profile low-overhead loop start */
8436 TCGv_i32 tmp;
8438 if (!dc_isar_feature(aa32_lob, s)) {
8439 return false;
8441 if (a->rn == 13 || a->rn == 15) {
8443 * For DLSTP rn == 15 is a related encoding (LCTP); the
8444 * other cases caught by this condition are all
8445 * CONSTRAINED UNPREDICTABLE: we choose to UNDEF
8447 return false;
8450 if (a->size != 4) {
8451 /* DLSTP */
8452 if (!dc_isar_feature(aa32_mve, s)) {
8453 return false;
8455 if (!vfp_access_check(s)) {
8456 return true;
8460 /* Not a while loop: set LR to the count, and set LTPSIZE for DLSTP */
8461 tmp = load_reg(s, a->rn);
8462 store_reg(s, 14, tmp);
8463 if (a->size != 4) {
8464 /* DLSTP: set FPSCR.LTPSIZE */
8465 tmp = tcg_const_i32(a->size);
8466 store_cpu_field(tmp, v7m.ltpsize);
8468 return true;
8471 static bool trans_WLS(DisasContext *s, arg_WLS *a)
8473 /* M-profile low-overhead while-loop start */
8474 TCGv_i32 tmp;
8475 TCGLabel *nextlabel;
8477 if (!dc_isar_feature(aa32_lob, s)) {
8478 return false;
8480 if (a->rn == 13 || a->rn == 15) {
8482 * For WLSTP rn == 15 is a related encoding (LE); the
8483 * other cases caught by this condition are all
8484 * CONSTRAINED UNPREDICTABLE: we choose to UNDEF
8486 return false;
8488 if (s->condexec_mask) {
8490 * WLS in an IT block is CONSTRAINED UNPREDICTABLE;
8491 * we choose to UNDEF, because otherwise our use of
8492 * gen_goto_tb(1) would clash with the use of TB exit 1
8493 * in the dc->condjmp condition-failed codepath in
8494 * arm_tr_tb_stop() and we'd get an assertion.
8496 return false;
8498 if (a->size != 4) {
8499 /* WLSTP */
8500 if (!dc_isar_feature(aa32_mve, s)) {
8501 return false;
8504 * We need to check that the FPU is enabled here, but mustn't
8505 * call vfp_access_check() to do that because we don't want to
8506 * do the lazy state preservation in the "loop count is zero" case.
8507 * Do the check-and-raise-exception by hand.
8509 if (s->fp_excp_el) {
8510 gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
8511 syn_uncategorized(), s->fp_excp_el);
8512 return true;
8516 nextlabel = gen_new_label();
8517 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_R[a->rn], 0, nextlabel);
8518 tmp = load_reg(s, a->rn);
8519 store_reg(s, 14, tmp);
8520 if (a->size != 4) {
8522 * WLSTP: set FPSCR.LTPSIZE. This requires that we do the
8523 * lazy state preservation, new FP context creation, etc,
8524 * that vfp_access_check() does. We know that the actual
8525 * access check will succeed (ie it won't generate code that
8526 * throws an exception) because we did that check by hand earlier.
8528 bool ok = vfp_access_check(s);
8529 assert(ok);
8530 tmp = tcg_const_i32(a->size);
8531 store_cpu_field(tmp, v7m.ltpsize);
8533 gen_jmp_tb(s, s->base.pc_next, 1);
8535 gen_set_label(nextlabel);
8536 gen_jmp(s, read_pc(s) + a->imm);
8537 return true;
8540 static bool trans_LE(DisasContext *s, arg_LE *a)
8543 * M-profile low-overhead loop end. The architecture permits an
8544 * implementation to discard the LO_BRANCH_INFO cache at any time,
8545 * and we take the IMPDEF option to never set it in the first place
8546 * (equivalent to always discarding it immediately), because for QEMU
8547 * a "real" implementation would be complicated and wouldn't execute
8548 * any faster.
8550 TCGv_i32 tmp;
8551 TCGLabel *loopend;
8552 bool fpu_active;
8554 if (!dc_isar_feature(aa32_lob, s)) {
8555 return false;
8557 if (a->f && a->tp) {
8558 return false;
8560 if (s->condexec_mask) {
8562 * LE in an IT block is CONSTRAINED UNPREDICTABLE;
8563 * we choose to UNDEF, because otherwise our use of
8564 * gen_goto_tb(1) would clash with the use of TB exit 1
8565 * in the dc->condjmp condition-failed codepath in
8566 * arm_tr_tb_stop() and we'd get an assertion.
8568 return false;
8570 if (a->tp) {
8571 /* LETP */
8572 if (!dc_isar_feature(aa32_mve, s)) {
8573 return false;
8575 if (!vfp_access_check(s)) {
8576 s->eci_handled = true;
8577 return true;
8581 /* LE/LETP is OK with ECI set and leaves it untouched */
8582 s->eci_handled = true;
8585 * With MVE, LTPSIZE might not be 4, and we must emit an INVSTATE
8586 * UsageFault exception for the LE insn in that case. Note that we
8587 * are not directly checking FPSCR.LTPSIZE but instead check the
8588 * pseudocode LTPSIZE() function, which returns 4 if the FPU is
8589 * not currently active (ie ActiveFPState() returns false). We
8590 * can identify not-active purely from our TB state flags, as the
8591 * FPU is active only if:
8592 * the FPU is enabled
8593 * AND lazy state preservation is not active
8594 * AND we do not need a new fp context (this is the ASPEN/FPCA check)
8596 * Usually we don't need to care about this distinction between
8597 * LTPSIZE and FPSCR.LTPSIZE, because the code in vfp_access_check()
8598 * will either take an exception or clear the conditions that make
8599 * the FPU not active. But LE is an unusual case of a non-FP insn
8600 * that looks at LTPSIZE.
8602 fpu_active = !s->fp_excp_el && !s->v7m_lspact && !s->v7m_new_fp_ctxt_needed;
8604 if (!a->tp && dc_isar_feature(aa32_mve, s) && fpu_active) {
8605 /* Need to do a runtime check for LTPSIZE != 4 */
8606 TCGLabel *skipexc = gen_new_label();
8607 tmp = load_cpu_field(v7m.ltpsize);
8608 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 4, skipexc);
8609 tcg_temp_free_i32(tmp);
8610 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
8611 default_exception_el(s));
8612 gen_set_label(skipexc);
8615 if (a->f) {
8616 /* Loop-forever: just jump back to the loop start */
8617 gen_jmp(s, read_pc(s) - a->imm);
8618 return true;
8622 * Not loop-forever. If LR <= loop-decrement-value this is the last loop.
8623 * For LE, we know at this point that LTPSIZE must be 4 and the
8624 * loop decrement value is 1. For LETP we need to calculate the decrement
8625 * value from LTPSIZE.
8627 loopend = gen_new_label();
8628 if (!a->tp) {
8629 tcg_gen_brcondi_i32(TCG_COND_LEU, cpu_R[14], 1, loopend);
8630 tcg_gen_addi_i32(cpu_R[14], cpu_R[14], -1);
8631 } else {
8633 * Decrement by 1 << (4 - LTPSIZE). We need to use a TCG local
8634 * so that decr stays live after the brcondi.
8636 TCGv_i32 decr = tcg_temp_local_new_i32();
8637 TCGv_i32 ltpsize = load_cpu_field(v7m.ltpsize);
8638 tcg_gen_sub_i32(decr, tcg_constant_i32(4), ltpsize);
8639 tcg_gen_shl_i32(decr, tcg_constant_i32(1), decr);
8640 tcg_temp_free_i32(ltpsize);
8642 tcg_gen_brcond_i32(TCG_COND_LEU, cpu_R[14], decr, loopend);
8644 tcg_gen_sub_i32(cpu_R[14], cpu_R[14], decr);
8645 tcg_temp_free_i32(decr);
8647 /* Jump back to the loop start */
8648 gen_jmp(s, read_pc(s) - a->imm);
8650 gen_set_label(loopend);
8651 if (a->tp) {
8652 /* Exits from tail-pred loops must reset LTPSIZE to 4 */
8653 tmp = tcg_const_i32(4);
8654 store_cpu_field(tmp, v7m.ltpsize);
8656 /* End TB, continuing to following insn */
8657 gen_jmp_tb(s, s->base.pc_next, 1);
8658 return true;
8661 static bool trans_LCTP(DisasContext *s, arg_LCTP *a)
8664 * M-profile Loop Clear with Tail Predication. Since our implementation
8665 * doesn't cache branch information, all we need to do is reset
8666 * FPSCR.LTPSIZE to 4.
8668 TCGv_i32 ltpsize;
8670 if (!dc_isar_feature(aa32_lob, s) ||
8671 !dc_isar_feature(aa32_mve, s)) {
8672 return false;
8675 if (!vfp_access_check(s)) {
8676 return true;
8679 ltpsize = tcg_const_i32(4);
8680 store_cpu_field(ltpsize, v7m.ltpsize);
8681 return true;
8684 static bool trans_VCTP(DisasContext *s, arg_VCTP *a)
8687 * M-profile Create Vector Tail Predicate. This insn is itself
8688 * predicated and is subject to beatwise execution.
8690 TCGv_i32 rn_shifted, masklen;
8692 if (!dc_isar_feature(aa32_mve, s) || a->rn == 13 || a->rn == 15) {
8693 return false;
8696 if (!mve_eci_check(s) || !vfp_access_check(s)) {
8697 return true;
8701 * We pre-calculate the mask length here to avoid having
8702 * to have multiple helpers specialized for size.
8703 * We pass the helper "rn <= (1 << (4 - size)) ? (rn << size) : 16".
8705 rn_shifted = tcg_temp_new_i32();
8706 masklen = load_reg(s, a->rn);
8707 tcg_gen_shli_i32(rn_shifted, masklen, a->size);
8708 tcg_gen_movcond_i32(TCG_COND_LEU, masklen,
8709 masklen, tcg_constant_i32(1 << (4 - a->size)),
8710 rn_shifted, tcg_constant_i32(16));
8711 gen_helper_mve_vctp(cpu_env, masklen);
8712 tcg_temp_free_i32(masklen);
8713 tcg_temp_free_i32(rn_shifted);
8714 mve_update_eci(s);
8715 return true;
8718 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
8720 TCGv_i32 addr, tmp;
8722 tmp = load_reg(s, a->rm);
8723 if (half) {
8724 tcg_gen_add_i32(tmp, tmp, tmp);
8726 addr = load_reg(s, a->rn);
8727 tcg_gen_add_i32(addr, addr, tmp);
8729 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), half ? MO_UW : MO_UB);
8730 tcg_temp_free_i32(addr);
8732 tcg_gen_add_i32(tmp, tmp, tmp);
8733 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
8734 store_reg(s, 15, tmp);
8735 return true;
8738 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
8740 return op_tbranch(s, a, false);
8743 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
8745 return op_tbranch(s, a, true);
8748 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
8750 TCGv_i32 tmp = load_reg(s, a->rn);
8752 arm_gen_condlabel(s);
8753 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
8754 tmp, 0, s->condlabel);
8755 tcg_temp_free_i32(tmp);
8756 gen_jmp(s, read_pc(s) + a->imm);
8757 return true;
8761 * Supervisor call - both T32 & A32 come here so we need to check
8762 * which mode we are in when checking for semihosting.
8765 static bool trans_SVC(DisasContext *s, arg_SVC *a)
8767 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
8769 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
8770 #ifndef CONFIG_USER_ONLY
8771 !IS_USER(s) &&
8772 #endif
8773 (a->imm == semihost_imm)) {
8774 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
8775 } else {
8776 gen_set_pc_im(s, s->base.pc_next);
8777 s->svc_imm = a->imm;
8778 s->base.is_jmp = DISAS_SWI;
8780 return true;
8784 * Unconditional system instructions
8787 static bool trans_RFE(DisasContext *s, arg_RFE *a)
8789 static const int8_t pre_offset[4] = {
8790 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
8792 static const int8_t post_offset[4] = {
8793 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
8795 TCGv_i32 addr, t1, t2;
8797 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8798 return false;
8800 if (IS_USER(s)) {
8801 unallocated_encoding(s);
8802 return true;
8805 addr = load_reg(s, a->rn);
8806 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
8808 /* Load PC into tmp and CPSR into tmp2. */
8809 t1 = tcg_temp_new_i32();
8810 gen_aa32_ld_i32(s, t1, addr, get_mem_index(s), MO_UL | MO_ALIGN);
8811 tcg_gen_addi_i32(addr, addr, 4);
8812 t2 = tcg_temp_new_i32();
8813 gen_aa32_ld_i32(s, t2, addr, get_mem_index(s), MO_UL | MO_ALIGN);
8815 if (a->w) {
8816 /* Base writeback. */
8817 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
8818 store_reg(s, a->rn, addr);
8819 } else {
8820 tcg_temp_free_i32(addr);
8822 gen_rfe(s, t1, t2);
8823 return true;
8826 static bool trans_SRS(DisasContext *s, arg_SRS *a)
8828 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8829 return false;
8831 gen_srs(s, a->mode, a->pu, a->w);
8832 return true;
8835 static bool trans_CPS(DisasContext *s, arg_CPS *a)
8837 uint32_t mask, val;
8839 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
8840 return false;
8842 if (IS_USER(s)) {
8843 /* Implemented as NOP in user mode. */
8844 return true;
8846 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
8848 mask = val = 0;
8849 if (a->imod & 2) {
8850 if (a->A) {
8851 mask |= CPSR_A;
8853 if (a->I) {
8854 mask |= CPSR_I;
8856 if (a->F) {
8857 mask |= CPSR_F;
8859 if (a->imod & 1) {
8860 val |= mask;
8863 if (a->M) {
8864 mask |= CPSR_M;
8865 val |= a->mode;
8867 if (mask) {
8868 gen_set_psr_im(s, mask, 0, val);
8870 return true;
8873 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
8875 TCGv_i32 tmp, addr, el;
8877 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8878 return false;
8880 if (IS_USER(s)) {
8881 /* Implemented as NOP in user mode. */
8882 return true;
8885 tmp = tcg_const_i32(a->im);
8886 /* FAULTMASK */
8887 if (a->F) {
8888 addr = tcg_const_i32(19);
8889 gen_helper_v7m_msr(cpu_env, addr, tmp);
8890 tcg_temp_free_i32(addr);
8892 /* PRIMASK */
8893 if (a->I) {
8894 addr = tcg_const_i32(16);
8895 gen_helper_v7m_msr(cpu_env, addr, tmp);
8896 tcg_temp_free_i32(addr);
8898 el = tcg_const_i32(s->current_el);
8899 gen_helper_rebuild_hflags_m32(cpu_env, el);
8900 tcg_temp_free_i32(el);
8901 tcg_temp_free_i32(tmp);
8902 gen_lookup_tb(s);
8903 return true;
8907 * Clear-Exclusive, Barriers
8910 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
8912 if (s->thumb
8913 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
8914 : !ENABLE_ARCH_6K) {
8915 return false;
8917 gen_clrex(s);
8918 return true;
8921 static bool trans_DSB(DisasContext *s, arg_DSB *a)
8923 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
8924 return false;
8926 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8927 return true;
8930 static bool trans_DMB(DisasContext *s, arg_DMB *a)
8932 return trans_DSB(s, NULL);
8935 static bool trans_ISB(DisasContext *s, arg_ISB *a)
8937 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
8938 return false;
8941 * We need to break the TB after this insn to execute
8942 * self-modifying code correctly and also to take
8943 * any pending interrupts immediately.
8945 s->base.is_jmp = DISAS_TOO_MANY;
8946 return true;
8949 static bool trans_SB(DisasContext *s, arg_SB *a)
8951 if (!dc_isar_feature(aa32_sb, s)) {
8952 return false;
8955 * TODO: There is no speculation barrier opcode
8956 * for TCG; MB and end the TB instead.
8958 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8959 s->base.is_jmp = DISAS_TOO_MANY;
8960 return true;
8963 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
8965 if (!ENABLE_ARCH_6) {
8966 return false;
8968 if (a->E != (s->be_data == MO_BE)) {
8969 gen_helper_setend(cpu_env);
8970 s->base.is_jmp = DISAS_UPDATE_EXIT;
8972 return true;
8976 * Preload instructions
8977 * All are nops, contingent on the appropriate arch level.
8980 static bool trans_PLD(DisasContext *s, arg_PLD *a)
8982 return ENABLE_ARCH_5TE;
8985 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
8987 return arm_dc_feature(s, ARM_FEATURE_V7MP);
8990 static bool trans_PLI(DisasContext *s, arg_PLD *a)
8992 return ENABLE_ARCH_7;
8996 * If-then
8999 static bool trans_IT(DisasContext *s, arg_IT *a)
9001 int cond_mask = a->cond_mask;
9004 * No actual code generated for this insn, just setup state.
9006 * Combinations of firstcond and mask which set up an 0b1111
9007 * condition are UNPREDICTABLE; we take the CONSTRAINED
9008 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
9009 * i.e. both meaning "execute always".
9011 s->condexec_cond = (cond_mask >> 4) & 0xe;
9012 s->condexec_mask = cond_mask & 0x1f;
9013 return true;
9016 /* v8.1M CSEL/CSINC/CSNEG/CSINV */
9017 static bool trans_CSEL(DisasContext *s, arg_CSEL *a)
9019 TCGv_i32 rn, rm, zero;
9020 DisasCompare c;
9022 if (!arm_dc_feature(s, ARM_FEATURE_V8_1M)) {
9023 return false;
9026 if (a->rm == 13) {
9027 /* SEE "Related encodings" (MVE shifts) */
9028 return false;
9031 if (a->rd == 13 || a->rd == 15 || a->rn == 13 || a->fcond >= 14) {
9032 /* CONSTRAINED UNPREDICTABLE: we choose to UNDEF */
9033 return false;
9036 /* In this insn input reg fields of 0b1111 mean "zero", not "PC" */
9037 if (a->rn == 15) {
9038 rn = tcg_const_i32(0);
9039 } else {
9040 rn = load_reg(s, a->rn);
9042 if (a->rm == 15) {
9043 rm = tcg_const_i32(0);
9044 } else {
9045 rm = load_reg(s, a->rm);
9048 switch (a->op) {
9049 case 0: /* CSEL */
9050 break;
9051 case 1: /* CSINC */
9052 tcg_gen_addi_i32(rm, rm, 1);
9053 break;
9054 case 2: /* CSINV */
9055 tcg_gen_not_i32(rm, rm);
9056 break;
9057 case 3: /* CSNEG */
9058 tcg_gen_neg_i32(rm, rm);
9059 break;
9060 default:
9061 g_assert_not_reached();
9064 arm_test_cc(&c, a->fcond);
9065 zero = tcg_const_i32(0);
9066 tcg_gen_movcond_i32(c.cond, rn, c.value, zero, rn, rm);
9067 arm_free_cc(&c);
9068 tcg_temp_free_i32(zero);
9070 store_reg(s, a->rd, rn);
9071 tcg_temp_free_i32(rm);
9073 return true;
9077 * Legacy decoder.
9080 static void disas_arm_insn(DisasContext *s, unsigned int insn)
9082 unsigned int cond = insn >> 28;
9084 /* M variants do not implement ARM mode; this must raise the INVSTATE
9085 * UsageFault exception.
9087 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9088 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
9089 default_exception_el(s));
9090 return;
9093 if (cond == 0xf) {
9094 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
9095 * choose to UNDEF. In ARMv5 and above the space is used
9096 * for miscellaneous unconditional instructions.
9098 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
9099 unallocated_encoding(s);
9100 return;
9103 /* Unconditional instructions. */
9104 /* TODO: Perhaps merge these into one decodetree output file. */
9105 if (disas_a32_uncond(s, insn) ||
9106 disas_vfp_uncond(s, insn) ||
9107 disas_neon_dp(s, insn) ||
9108 disas_neon_ls(s, insn) ||
9109 disas_neon_shared(s, insn)) {
9110 return;
9112 /* fall back to legacy decoder */
9114 if ((insn & 0x0e000f00) == 0x0c000100) {
9115 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9116 /* iWMMXt register transfer. */
9117 if (extract32(s->c15_cpar, 1, 1)) {
9118 if (!disas_iwmmxt_insn(s, insn)) {
9119 return;
9124 goto illegal_op;
9126 if (cond != 0xe) {
9127 /* if not always execute, we generate a conditional jump to
9128 next instruction */
9129 arm_skip_unless(s, cond);
9132 /* TODO: Perhaps merge these into one decodetree output file. */
9133 if (disas_a32(s, insn) ||
9134 disas_vfp(s, insn)) {
9135 return;
9137 /* fall back to legacy decoder */
9138 /* TODO: convert xscale/iwmmxt decoder to decodetree ?? */
9139 if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
9140 if (((insn & 0x0c000e00) == 0x0c000000)
9141 && ((insn & 0x03000000) != 0x03000000)) {
9142 /* Coprocessor insn, coprocessor 0 or 1 */
9143 disas_xscale_insn(s, insn);
9144 return;
9148 illegal_op:
9149 unallocated_encoding(s);
9152 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
9155 * Return true if this is a 16 bit instruction. We must be precise
9156 * about this (matching the decode).
9158 if ((insn >> 11) < 0x1d) {
9159 /* Definitely a 16-bit instruction */
9160 return true;
9163 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9164 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9165 * end up actually treating this as two 16-bit insns, though,
9166 * if it's half of a bl/blx pair that might span a page boundary.
9168 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9169 arm_dc_feature(s, ARM_FEATURE_M)) {
9170 /* Thumb2 cores (including all M profile ones) always treat
9171 * 32-bit insns as 32-bit.
9173 return false;
9176 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9177 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9178 * is not on the next page; we merge this into a 32-bit
9179 * insn.
9181 return false;
9183 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9184 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9185 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9186 * -- handle as single 16 bit insn
9188 return true;
9191 /* Translate a 32-bit thumb instruction. */
9192 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9195 * ARMv6-M supports a limited subset of Thumb2 instructions.
9196 * Other Thumb1 architectures allow only 32-bit
9197 * combined BL/BLX prefix and suffix.
9199 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9200 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9201 int i;
9202 bool found = false;
9203 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9204 0xf3b08040 /* dsb */,
9205 0xf3b08050 /* dmb */,
9206 0xf3b08060 /* isb */,
9207 0xf3e08000 /* mrs */,
9208 0xf000d000 /* bl */};
9209 static const uint32_t armv6m_mask[] = {0xffe0d000,
9210 0xfff0d0f0,
9211 0xfff0d0f0,
9212 0xfff0d0f0,
9213 0xffe0d000,
9214 0xf800d000};
9216 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9217 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9218 found = true;
9219 break;
9222 if (!found) {
9223 goto illegal_op;
9225 } else if ((insn & 0xf800e800) != 0xf000e800) {
9226 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
9227 unallocated_encoding(s);
9228 return;
9232 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9234 * NOCP takes precedence over any UNDEF for (almost) the
9235 * entire wide range of coprocessor-space encodings, so check
9236 * for it first before proceeding to actually decode eg VFP
9237 * insns. This decode also handles the few insns which are
9238 * in copro space but do not have NOCP checks (eg VLLDM, VLSTM).
9240 if (disas_m_nocp(s, insn)) {
9241 return;
9245 if ((insn & 0xef000000) == 0xef000000) {
9247 * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9248 * transform into
9249 * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9251 uint32_t a32_insn = (insn & 0xe2ffffff) |
9252 ((insn & (1 << 28)) >> 4) | (1 << 28);
9254 if (disas_neon_dp(s, a32_insn)) {
9255 return;
9259 if ((insn & 0xff100000) == 0xf9000000) {
9261 * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9262 * transform into
9263 * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9265 uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
9267 if (disas_neon_ls(s, a32_insn)) {
9268 return;
9273 * TODO: Perhaps merge these into one decodetree output file.
9274 * Note disas_vfp is written for a32 with cond field in the
9275 * top nibble. The t32 encoding requires 0xe in the top nibble.
9277 if (disas_t32(s, insn) ||
9278 disas_vfp_uncond(s, insn) ||
9279 disas_neon_shared(s, insn) ||
9280 disas_mve(s, insn) ||
9281 ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
9282 return;
9285 illegal_op:
9286 unallocated_encoding(s);
9289 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
9291 if (!disas_t16(s, insn)) {
9292 unallocated_encoding(s);
9296 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
9298 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
9299 * (False positives are OK, false negatives are not.)
9300 * We know this is a Thumb insn, and our caller ensures we are
9301 * only called if dc->base.pc_next is less than 4 bytes from the page
9302 * boundary, so we cross the page if the first 16 bits indicate
9303 * that this is a 32 bit insn.
9305 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
9307 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
9310 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
9312 DisasContext *dc = container_of(dcbase, DisasContext, base);
9313 CPUARMState *env = cs->env_ptr;
9314 ARMCPU *cpu = env_archcpu(env);
9315 CPUARMTBFlags tb_flags = arm_tbflags_from_tb(dc->base.tb);
9316 uint32_t condexec, core_mmu_idx;
9318 dc->isar = &cpu->isar;
9319 dc->condjmp = 0;
9321 dc->aarch64 = 0;
9322 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
9323 * there is no secure EL1, so we route exceptions to EL3.
9325 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
9326 !arm_el_is_aa64(env, 3);
9327 dc->thumb = EX_TBFLAG_AM32(tb_flags, THUMB);
9328 dc->be_data = EX_TBFLAG_ANY(tb_flags, BE_DATA) ? MO_BE : MO_LE;
9329 condexec = EX_TBFLAG_AM32(tb_flags, CONDEXEC);
9331 * the CONDEXEC TB flags are CPSR bits [15:10][26:25]. On A-profile this
9332 * is always the IT bits. On M-profile, some of the reserved encodings
9333 * of IT are used instead to indicate either ICI or ECI, which
9334 * indicate partial progress of a restartable insn that was interrupted
9335 * partway through by an exception:
9336 * * if CONDEXEC[3:0] != 0b0000 : CONDEXEC is IT bits
9337 * * if CONDEXEC[3:0] == 0b0000 : CONDEXEC is ICI or ECI bits
9338 * In all cases CONDEXEC == 0 means "not in IT block or restartable
9339 * insn, behave normally".
9341 dc->eci = dc->condexec_mask = dc->condexec_cond = 0;
9342 dc->eci_handled = false;
9343 dc->insn_eci_rewind = NULL;
9344 if (condexec & 0xf) {
9345 dc->condexec_mask = (condexec & 0xf) << 1;
9346 dc->condexec_cond = condexec >> 4;
9347 } else {
9348 if (arm_feature(env, ARM_FEATURE_M)) {
9349 dc->eci = condexec >> 4;
9353 core_mmu_idx = EX_TBFLAG_ANY(tb_flags, MMUIDX);
9354 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
9355 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
9356 #if !defined(CONFIG_USER_ONLY)
9357 dc->user = (dc->current_el == 0);
9358 #endif
9359 dc->fp_excp_el = EX_TBFLAG_ANY(tb_flags, FPEXC_EL);
9360 dc->align_mem = EX_TBFLAG_ANY(tb_flags, ALIGN_MEM);
9362 if (arm_feature(env, ARM_FEATURE_M)) {
9363 dc->vfp_enabled = 1;
9364 dc->be_data = MO_TE;
9365 dc->v7m_handler_mode = EX_TBFLAG_M32(tb_flags, HANDLER);
9366 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
9367 regime_is_secure(env, dc->mmu_idx);
9368 dc->v8m_stackcheck = EX_TBFLAG_M32(tb_flags, STACKCHECK);
9369 dc->v8m_fpccr_s_wrong = EX_TBFLAG_M32(tb_flags, FPCCR_S_WRONG);
9370 dc->v7m_new_fp_ctxt_needed =
9371 EX_TBFLAG_M32(tb_flags, NEW_FP_CTXT_NEEDED);
9372 dc->v7m_lspact = EX_TBFLAG_M32(tb_flags, LSPACT);
9373 } else {
9374 dc->debug_target_el = EX_TBFLAG_ANY(tb_flags, DEBUG_TARGET_EL);
9375 dc->sctlr_b = EX_TBFLAG_A32(tb_flags, SCTLR__B);
9376 dc->hstr_active = EX_TBFLAG_A32(tb_flags, HSTR_ACTIVE);
9377 dc->ns = EX_TBFLAG_A32(tb_flags, NS);
9378 dc->vfp_enabled = EX_TBFLAG_A32(tb_flags, VFPEN);
9379 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
9380 dc->c15_cpar = EX_TBFLAG_A32(tb_flags, XSCALE_CPAR);
9381 } else {
9382 dc->vec_len = EX_TBFLAG_A32(tb_flags, VECLEN);
9383 dc->vec_stride = EX_TBFLAG_A32(tb_flags, VECSTRIDE);
9386 dc->cp_regs = cpu->cp_regs;
9387 dc->features = env->features;
9389 /* Single step state. The code-generation logic here is:
9390 * SS_ACTIVE == 0:
9391 * generate code with no special handling for single-stepping (except
9392 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
9393 * this happens anyway because those changes are all system register or
9394 * PSTATE writes).
9395 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
9396 * emit code for one insn
9397 * emit code to clear PSTATE.SS
9398 * emit code to generate software step exception for completed step
9399 * end TB (as usual for having generated an exception)
9400 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
9401 * emit code to generate a software step exception
9402 * end the TB
9404 dc->ss_active = EX_TBFLAG_ANY(tb_flags, SS_ACTIVE);
9405 dc->pstate_ss = EX_TBFLAG_ANY(tb_flags, PSTATE__SS);
9406 dc->is_ldex = false;
9408 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
9410 /* If architectural single step active, limit to 1. */
9411 if (is_singlestepping(dc)) {
9412 dc->base.max_insns = 1;
9415 /* ARM is a fixed-length ISA. Bound the number of insns to execute
9416 to those left on the page. */
9417 if (!dc->thumb) {
9418 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
9419 dc->base.max_insns = MIN(dc->base.max_insns, bound);
9422 cpu_V0 = tcg_temp_new_i64();
9423 cpu_V1 = tcg_temp_new_i64();
9424 cpu_M0 = tcg_temp_new_i64();
9427 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
9429 DisasContext *dc = container_of(dcbase, DisasContext, base);
9431 /* A note on handling of the condexec (IT) bits:
9433 * We want to avoid the overhead of having to write the updated condexec
9434 * bits back to the CPUARMState for every instruction in an IT block. So:
9435 * (1) if the condexec bits are not already zero then we write
9436 * zero back into the CPUARMState now. This avoids complications trying
9437 * to do it at the end of the block. (For example if we don't do this
9438 * it's hard to identify whether we can safely skip writing condexec
9439 * at the end of the TB, which we definitely want to do for the case
9440 * where a TB doesn't do anything with the IT state at all.)
9441 * (2) if we are going to leave the TB then we call gen_set_condexec()
9442 * which will write the correct value into CPUARMState if zero is wrong.
9443 * This is done both for leaving the TB at the end, and for leaving
9444 * it because of an exception we know will happen, which is done in
9445 * gen_exception_insn(). The latter is necessary because we need to
9446 * leave the TB with the PC/IT state just prior to execution of the
9447 * instruction which caused the exception.
9448 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9449 * then the CPUARMState will be wrong and we need to reset it.
9450 * This is handled in the same way as restoration of the
9451 * PC in these situations; we save the value of the condexec bits
9452 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
9453 * then uses this to restore them after an exception.
9455 * Note that there are no instructions which can read the condexec
9456 * bits, and none which can write non-static values to them, so
9457 * we don't need to care about whether CPUARMState is correct in the
9458 * middle of a TB.
9461 /* Reset the conditional execution bits immediately. This avoids
9462 complications trying to do it at the end of the block. */
9463 if (dc->condexec_mask || dc->condexec_cond) {
9464 TCGv_i32 tmp = tcg_temp_new_i32();
9465 tcg_gen_movi_i32(tmp, 0);
9466 store_cpu_field(tmp, condexec_bits);
9470 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
9472 DisasContext *dc = container_of(dcbase, DisasContext, base);
9474 * The ECI/ICI bits share PSR bits with the IT bits, so we
9475 * need to reconstitute the bits from the split-out DisasContext
9476 * fields here.
9478 uint32_t condexec_bits;
9480 if (dc->eci) {
9481 condexec_bits = dc->eci << 4;
9482 } else {
9483 condexec_bits = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9485 tcg_gen_insn_start(dc->base.pc_next, condexec_bits, 0);
9486 dc->insn_start = tcg_last_op();
9489 static bool arm_pre_translate_insn(DisasContext *dc)
9491 #ifdef CONFIG_USER_ONLY
9492 /* Intercept jump to the magic kernel page. */
9493 if (dc->base.pc_next >= 0xffff0000) {
9494 /* We always get here via a jump, so know we are not in a
9495 conditional execution block. */
9496 gen_exception_internal(EXCP_KERNEL_TRAP);
9497 dc->base.is_jmp = DISAS_NORETURN;
9498 return true;
9500 #endif
9502 if (dc->ss_active && !dc->pstate_ss) {
9503 /* Singlestep state is Active-pending.
9504 * If we're in this state at the start of a TB then either
9505 * a) we just took an exception to an EL which is being debugged
9506 * and this is the first insn in the exception handler
9507 * b) debug exceptions were masked and we just unmasked them
9508 * without changing EL (eg by clearing PSTATE.D)
9509 * In either case we're going to take a swstep exception in the
9510 * "did not step an insn" case, and so the syndrome ISV and EX
9511 * bits should be zero.
9513 assert(dc->base.num_insns == 1);
9514 gen_swstep_exception(dc, 0, 0);
9515 dc->base.is_jmp = DISAS_NORETURN;
9516 return true;
9519 return false;
9522 static void arm_post_translate_insn(DisasContext *dc)
9524 if (dc->condjmp && !dc->base.is_jmp) {
9525 gen_set_label(dc->condlabel);
9526 dc->condjmp = 0;
9528 translator_loop_temp_check(&dc->base);
9531 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
9533 DisasContext *dc = container_of(dcbase, DisasContext, base);
9534 CPUARMState *env = cpu->env_ptr;
9535 unsigned int insn;
9537 if (arm_pre_translate_insn(dc)) {
9538 dc->base.pc_next += 4;
9539 return;
9542 dc->pc_curr = dc->base.pc_next;
9543 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
9544 dc->insn = insn;
9545 dc->base.pc_next += 4;
9546 disas_arm_insn(dc, insn);
9548 arm_post_translate_insn(dc);
9550 /* ARM is a fixed-length ISA. We performed the cross-page check
9551 in init_disas_context by adjusting max_insns. */
9554 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
9556 /* Return true if this Thumb insn is always unconditional,
9557 * even inside an IT block. This is true of only a very few
9558 * instructions: BKPT, HLT, and SG.
9560 * A larger class of instructions are UNPREDICTABLE if used
9561 * inside an IT block; we do not need to detect those here, because
9562 * what we do by default (perform the cc check and update the IT
9563 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
9564 * choice for those situations.
9566 * insn is either a 16-bit or a 32-bit instruction; the two are
9567 * distinguishable because for the 16-bit case the top 16 bits
9568 * are zeroes, and that isn't a valid 32-bit encoding.
9570 if ((insn & 0xffffff00) == 0xbe00) {
9571 /* BKPT */
9572 return true;
9575 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
9576 !arm_dc_feature(s, ARM_FEATURE_M)) {
9577 /* HLT: v8A only. This is unconditional even when it is going to
9578 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
9579 * For v7 cores this was a plain old undefined encoding and so
9580 * honours its cc check. (We might be using the encoding as
9581 * a semihosting trap, but we don't change the cc check behaviour
9582 * on that account, because a debugger connected to a real v7A
9583 * core and emulating semihosting traps by catching the UNDEF
9584 * exception would also only see cases where the cc check passed.
9585 * No guest code should be trying to do a HLT semihosting trap
9586 * in an IT block anyway.
9588 return true;
9591 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
9592 arm_dc_feature(s, ARM_FEATURE_M)) {
9593 /* SG: v8M only */
9594 return true;
9597 return false;
9600 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
9602 DisasContext *dc = container_of(dcbase, DisasContext, base);
9603 CPUARMState *env = cpu->env_ptr;
9604 uint32_t insn;
9605 bool is_16bit;
9607 if (arm_pre_translate_insn(dc)) {
9608 dc->base.pc_next += 2;
9609 return;
9612 dc->pc_curr = dc->base.pc_next;
9613 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
9614 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
9615 dc->base.pc_next += 2;
9616 if (!is_16bit) {
9617 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
9619 insn = insn << 16 | insn2;
9620 dc->base.pc_next += 2;
9622 dc->insn = insn;
9624 if (dc->eci) {
9626 * For M-profile continuable instructions, ECI/ICI handling
9627 * falls into these cases:
9628 * - interrupt-continuable instructions
9629 * These are the various load/store multiple insns (both
9630 * integer and fp). The ICI bits indicate the register
9631 * where the load/store can resume. We make the IMPDEF
9632 * choice to always do "instruction restart", ie ignore
9633 * the ICI value and always execute the ldm/stm from the
9634 * start. So all we need to do is zero PSR.ICI if the
9635 * insn executes.
9636 * - MVE instructions subject to beat-wise execution
9637 * Here the ECI bits indicate which beats have already been
9638 * executed, and we must honour this. Each insn of this
9639 * type will handle it correctly. We will update PSR.ECI
9640 * in the helper function for the insn (some ECI values
9641 * mean that the following insn also has been partially
9642 * executed).
9643 * - Special cases which don't advance ECI
9644 * The insns LE, LETP and BKPT leave the ECI/ICI state
9645 * bits untouched.
9646 * - all other insns (the common case)
9647 * Non-zero ECI/ICI means an INVSTATE UsageFault.
9648 * We place a rewind-marker here. Insns in the previous
9649 * three categories will set a flag in the DisasContext.
9650 * If the flag isn't set after we call disas_thumb_insn()
9651 * or disas_thumb2_insn() then we know we have a "some other
9652 * insn" case. We will rewind to the marker (ie throwing away
9653 * all the generated code) and instead emit "take exception".
9655 dc->insn_eci_rewind = tcg_last_op();
9658 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
9659 uint32_t cond = dc->condexec_cond;
9662 * Conditionally skip the insn. Note that both 0xe and 0xf mean
9663 * "always"; 0xf is not "never".
9665 if (cond < 0x0e) {
9666 arm_skip_unless(dc, cond);
9670 if (is_16bit) {
9671 disas_thumb_insn(dc, insn);
9672 } else {
9673 disas_thumb2_insn(dc, insn);
9676 /* Advance the Thumb condexec condition. */
9677 if (dc->condexec_mask) {
9678 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
9679 ((dc->condexec_mask >> 4) & 1));
9680 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9681 if (dc->condexec_mask == 0) {
9682 dc->condexec_cond = 0;
9686 if (dc->eci && !dc->eci_handled) {
9688 * Insn wasn't valid for ECI/ICI at all: undo what we
9689 * just generated and instead emit an exception
9691 tcg_remove_ops_after(dc->insn_eci_rewind);
9692 dc->condjmp = 0;
9693 gen_exception_insn(dc, dc->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
9694 default_exception_el(dc));
9697 arm_post_translate_insn(dc);
9699 /* Thumb is a variable-length ISA. Stop translation when the next insn
9700 * will touch a new page. This ensures that prefetch aborts occur at
9701 * the right place.
9703 * We want to stop the TB if the next insn starts in a new page,
9704 * or if it spans between this page and the next. This means that
9705 * if we're looking at the last halfword in the page we need to
9706 * see if it's a 16-bit Thumb insn (which will fit in this TB)
9707 * or a 32-bit Thumb insn (which won't).
9708 * This is to avoid generating a silly TB with a single 16-bit insn
9709 * in it at the end of this page (which would execute correctly
9710 * but isn't very efficient).
9712 if (dc->base.is_jmp == DISAS_NEXT
9713 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
9714 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
9715 && insn_crosses_page(env, dc)))) {
9716 dc->base.is_jmp = DISAS_TOO_MANY;
9720 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
9722 DisasContext *dc = container_of(dcbase, DisasContext, base);
9724 /* At this stage dc->condjmp will only be set when the skipped
9725 instruction was a conditional branch or trap, and the PC has
9726 already been written. */
9727 gen_set_condexec(dc);
9728 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
9729 /* Exception return branches need some special case code at the
9730 * end of the TB, which is complex enough that it has to
9731 * handle the single-step vs not and the condition-failed
9732 * insn codepath itself.
9734 gen_bx_excret_final_code(dc);
9735 } else if (unlikely(is_singlestepping(dc))) {
9736 /* Unconditional and "condition passed" instruction codepath. */
9737 switch (dc->base.is_jmp) {
9738 case DISAS_SWI:
9739 gen_ss_advance(dc);
9740 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
9741 default_exception_el(dc));
9742 break;
9743 case DISAS_HVC:
9744 gen_ss_advance(dc);
9745 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
9746 break;
9747 case DISAS_SMC:
9748 gen_ss_advance(dc);
9749 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
9750 break;
9751 case DISAS_NEXT:
9752 case DISAS_TOO_MANY:
9753 case DISAS_UPDATE_EXIT:
9754 case DISAS_UPDATE_NOCHAIN:
9755 gen_set_pc_im(dc, dc->base.pc_next);
9756 /* fall through */
9757 default:
9758 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
9759 gen_singlestep_exception(dc);
9760 break;
9761 case DISAS_NORETURN:
9762 break;
9764 } else {
9765 /* While branches must always occur at the end of an IT block,
9766 there are a few other things that can cause us to terminate
9767 the TB in the middle of an IT block:
9768 - Exception generating instructions (bkpt, swi, undefined).
9769 - Page boundaries.
9770 - Hardware watchpoints.
9771 Hardware breakpoints have already been handled and skip this code.
9773 switch (dc->base.is_jmp) {
9774 case DISAS_NEXT:
9775 case DISAS_TOO_MANY:
9776 gen_goto_tb(dc, 1, dc->base.pc_next);
9777 break;
9778 case DISAS_UPDATE_NOCHAIN:
9779 gen_set_pc_im(dc, dc->base.pc_next);
9780 /* fall through */
9781 case DISAS_JUMP:
9782 gen_goto_ptr();
9783 break;
9784 case DISAS_UPDATE_EXIT:
9785 gen_set_pc_im(dc, dc->base.pc_next);
9786 /* fall through */
9787 default:
9788 /* indicate that the hash table must be used to find the next TB */
9789 tcg_gen_exit_tb(NULL, 0);
9790 break;
9791 case DISAS_NORETURN:
9792 /* nothing more to generate */
9793 break;
9794 case DISAS_WFI:
9796 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
9797 !(dc->insn & (1U << 31))) ? 2 : 4);
9799 gen_helper_wfi(cpu_env, tmp);
9800 tcg_temp_free_i32(tmp);
9801 /* The helper doesn't necessarily throw an exception, but we
9802 * must go back to the main loop to check for interrupts anyway.
9804 tcg_gen_exit_tb(NULL, 0);
9805 break;
9807 case DISAS_WFE:
9808 gen_helper_wfe(cpu_env);
9809 break;
9810 case DISAS_YIELD:
9811 gen_helper_yield(cpu_env);
9812 break;
9813 case DISAS_SWI:
9814 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
9815 default_exception_el(dc));
9816 break;
9817 case DISAS_HVC:
9818 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
9819 break;
9820 case DISAS_SMC:
9821 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
9822 break;
9826 if (dc->condjmp) {
9827 /* "Condition failed" instruction codepath for the branch/trap insn */
9828 gen_set_label(dc->condlabel);
9829 gen_set_condexec(dc);
9830 if (unlikely(is_singlestepping(dc))) {
9831 gen_set_pc_im(dc, dc->base.pc_next);
9832 gen_singlestep_exception(dc);
9833 } else {
9834 gen_goto_tb(dc, 1, dc->base.pc_next);
9839 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
9841 DisasContext *dc = container_of(dcbase, DisasContext, base);
9843 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
9844 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
9847 static const TranslatorOps arm_translator_ops = {
9848 .init_disas_context = arm_tr_init_disas_context,
9849 .tb_start = arm_tr_tb_start,
9850 .insn_start = arm_tr_insn_start,
9851 .translate_insn = arm_tr_translate_insn,
9852 .tb_stop = arm_tr_tb_stop,
9853 .disas_log = arm_tr_disas_log,
9856 static const TranslatorOps thumb_translator_ops = {
9857 .init_disas_context = arm_tr_init_disas_context,
9858 .tb_start = arm_tr_tb_start,
9859 .insn_start = arm_tr_insn_start,
9860 .translate_insn = thumb_tr_translate_insn,
9861 .tb_stop = arm_tr_tb_stop,
9862 .disas_log = arm_tr_disas_log,
9865 /* generate intermediate code for basic block 'tb'. */
9866 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
9868 DisasContext dc = { };
9869 const TranslatorOps *ops = &arm_translator_ops;
9870 CPUARMTBFlags tb_flags = arm_tbflags_from_tb(tb);
9872 if (EX_TBFLAG_AM32(tb_flags, THUMB)) {
9873 ops = &thumb_translator_ops;
9875 #ifdef TARGET_AARCH64
9876 if (EX_TBFLAG_ANY(tb_flags, AARCH64_STATE)) {
9877 ops = &aarch64_translator_ops;
9879 #endif
9881 translator_loop(ops, &dc.base, cpu, tb, max_insns);
9884 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
9885 target_ulong *data)
9887 if (is_a64(env)) {
9888 env->pc = data[0];
9889 env->condexec_bits = 0;
9890 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
9891 } else {
9892 env->regs[15] = data[0];
9893 env->condexec_bits = data[1];
9894 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;