1f0984d40SFabiano Rosas #ifndef TARGET_ARM_TRANSLATE_H
2f0984d40SFabiano Rosas #define TARGET_ARM_TRANSLATE_H
3f0984d40SFabiano Rosas
45d05e5a1SRichard Henderson #include "cpu.h"
55d05e5a1SRichard Henderson #include "tcg/tcg-op.h"
65d05e5a1SRichard Henderson #include "tcg/tcg-op-gvec.h"
71f17f91dSRichard Henderson #include "exec/exec-all.h"
8f0984d40SFabiano Rosas #include "exec/translator.h"
9a46f42d9SRichard Henderson #include "exec/helper-gen.h"
10f0984d40SFabiano Rosas #include "internals.h"
115a534314SPeter Maydell #include "cpu-features.h"
12f0984d40SFabiano Rosas
13f0984d40SFabiano Rosas /* internal defines */
14f0984d40SFabiano Rosas
15f0984d40SFabiano Rosas /*
16f0984d40SFabiano Rosas * Save pc_save across a branch, so that we may restore the value from
17f0984d40SFabiano Rosas * before the branch at the point the label is emitted.
18f0984d40SFabiano Rosas */
19f0984d40SFabiano Rosas typedef struct DisasLabel {
20f0984d40SFabiano Rosas TCGLabel *label;
21f0984d40SFabiano Rosas target_ulong pc_save;
22f0984d40SFabiano Rosas } DisasLabel;
23f0984d40SFabiano Rosas
24f0984d40SFabiano Rosas typedef struct DisasContext {
25f0984d40SFabiano Rosas DisasContextBase base;
26f0984d40SFabiano Rosas const ARMISARegisters *isar;
27f0984d40SFabiano Rosas
28f0984d40SFabiano Rosas /* The address of the current instruction being translated. */
29f0984d40SFabiano Rosas target_ulong pc_curr;
30f0984d40SFabiano Rosas /*
3103a648c4SAnton Johansson * For CF_PCREL, the full value of cpu_pc is not known
32f0984d40SFabiano Rosas * (although the page offset is known). For convenience, the
33f0984d40SFabiano Rosas * translation loop uses the full virtual address that triggered
34f0984d40SFabiano Rosas * the translation, from base.pc_start through pc_curr.
35f0984d40SFabiano Rosas * For efficiency, we do not update cpu_pc for every instruction.
36f0984d40SFabiano Rosas * Instead, pc_save has the value of pc_curr at the time of the
37f0984d40SFabiano Rosas * last update to cpu_pc, which allows us to compute the addend
38f0984d40SFabiano Rosas * needed to bring cpu_pc current: pc_curr - pc_save.
39f0984d40SFabiano Rosas * If cpu_pc now contains the destination of an indirect branch,
40f0984d40SFabiano Rosas * pc_save contains -1 to indicate that relative updates are no
41f0984d40SFabiano Rosas * longer possible.
42f0984d40SFabiano Rosas */
43f0984d40SFabiano Rosas target_ulong pc_save;
44f0984d40SFabiano Rosas target_ulong page_start;
45f0984d40SFabiano Rosas uint32_t insn;
46f0984d40SFabiano Rosas /* Nonzero if this instruction has been conditionally skipped. */
47f0984d40SFabiano Rosas int condjmp;
48f0984d40SFabiano Rosas /* The label that will be jumped to when the instruction is skipped. */
49f0984d40SFabiano Rosas DisasLabel condlabel;
50f0984d40SFabiano Rosas /* Thumb-2 conditional execution bits. */
51f0984d40SFabiano Rosas int condexec_mask;
52f0984d40SFabiano Rosas int condexec_cond;
53f0984d40SFabiano Rosas /* M-profile ECI/ICI exception-continuable instruction state */
54f0984d40SFabiano Rosas int eci;
55f0984d40SFabiano Rosas /*
56f0984d40SFabiano Rosas * trans_ functions for insns which are continuable should set this true
57f0984d40SFabiano Rosas * after decode (ie after any UNDEF checks)
58f0984d40SFabiano Rosas */
59f0984d40SFabiano Rosas bool eci_handled;
60f0984d40SFabiano Rosas int sctlr_b;
61f0984d40SFabiano Rosas MemOp be_data;
62f0984d40SFabiano Rosas #if !defined(CONFIG_USER_ONLY)
63f0984d40SFabiano Rosas int user;
64f0984d40SFabiano Rosas #endif
65f0984d40SFabiano Rosas ARMMMUIdx mmu_idx; /* MMU index to use for normal loads/stores */
66f0984d40SFabiano Rosas uint8_t tbii; /* TBI1|TBI0 for insns */
67f0984d40SFabiano Rosas uint8_t tbid; /* TBI1|TBI0 for data */
68f0984d40SFabiano Rosas uint8_t tcma; /* TCMA1|TCMA0 for MTE */
69f0984d40SFabiano Rosas bool ns; /* Use non-secure CPREG bank on access */
70f0984d40SFabiano Rosas int fp_excp_el; /* FP exception EL or 0 if enabled */
71f0984d40SFabiano Rosas int sve_excp_el; /* SVE exception EL or 0 if enabled */
72f0984d40SFabiano Rosas int sme_excp_el; /* SME exception EL or 0 if enabled */
73f0984d40SFabiano Rosas int vl; /* current vector length in bytes */
74f0984d40SFabiano Rosas int svl; /* current streaming vector length in bytes */
75f0984d40SFabiano Rosas bool vfp_enabled; /* FP enabled via FPSCR.EN */
76f0984d40SFabiano Rosas int vec_len;
77f0984d40SFabiano Rosas int vec_stride;
78f0984d40SFabiano Rosas bool v7m_handler_mode;
79f0984d40SFabiano Rosas bool v8m_secure; /* true if v8M and we're in Secure mode */
80f0984d40SFabiano Rosas bool v8m_stackcheck; /* true if we need to perform v8M stack limit checks */
81f0984d40SFabiano Rosas bool v8m_fpccr_s_wrong; /* true if v8M FPCCR.S != v8m_secure */
82f0984d40SFabiano Rosas bool v7m_new_fp_ctxt_needed; /* ASPEN set but no active FP context */
83f0984d40SFabiano Rosas bool v7m_lspact; /* FPCCR.LSPACT set */
84f0984d40SFabiano Rosas /* Immediate value in AArch32 SVC insn; must be set if is_jmp == DISAS_SWI
85f0984d40SFabiano Rosas * so that top level loop can generate correct syndrome information.
86f0984d40SFabiano Rosas */
87f0984d40SFabiano Rosas uint32_t svc_imm;
88f0984d40SFabiano Rosas int current_el;
89f0984d40SFabiano Rosas GHashTable *cp_regs;
90f0984d40SFabiano Rosas uint64_t features; /* CPU features bits */
91f0984d40SFabiano Rosas bool aarch64;
92f0984d40SFabiano Rosas bool thumb;
93e452ca5aSRichard Henderson bool lse2;
94*a75e415cSRichard Henderson /*
95*a75e415cSRichard Henderson * Because unallocated encodings generate different exception syndrome
96f0984d40SFabiano Rosas * information from traps due to FP being disabled, we can't do a single
97f0984d40SFabiano Rosas * "is fp access disabled" check at a high level in the decode tree.
98f0984d40SFabiano Rosas * To help in catching bugs where the access check was forgotten in some
99f0984d40SFabiano Rosas * code path, we set this flag when the access check is done, and assert
100f0984d40SFabiano Rosas * that it is set at the point where we actually touch the FP regs.
101*a75e415cSRichard Henderson * 0: not checked,
102*a75e415cSRichard Henderson * 1: checked, access ok
103*a75e415cSRichard Henderson * -1: checked, access denied
104f0984d40SFabiano Rosas */
105*a75e415cSRichard Henderson int8_t fp_access_checked;
106*a75e415cSRichard Henderson int8_t sve_access_checked;
107f0984d40SFabiano Rosas /* ARMv8 single-step state (this is distinct from the QEMU gdbstub
108f0984d40SFabiano Rosas * single-step support).
109f0984d40SFabiano Rosas */
110f0984d40SFabiano Rosas bool ss_active;
111f0984d40SFabiano Rosas bool pstate_ss;
112f0984d40SFabiano Rosas /* True if the insn just emitted was a load-exclusive instruction
113f0984d40SFabiano Rosas * (necessary for syndrome information for single step exceptions),
114f0984d40SFabiano Rosas * ie A64 LDX*, LDAX*, A32/T32 LDREX*, LDAEX*.
115f0984d40SFabiano Rosas */
116f0984d40SFabiano Rosas bool is_ldex;
117f0984d40SFabiano Rosas /* True if AccType_UNPRIV should be used for LDTR et al */
118f0984d40SFabiano Rosas bool unpriv;
119f0984d40SFabiano Rosas /* True if v8.3-PAuth is active. */
120f0984d40SFabiano Rosas bool pauth_active;
121179e9a3bSPeter Maydell /* True if v8.5-MTE access to tags is enabled; index with is_unpriv. */
122179e9a3bSPeter Maydell bool ata[2];
123f0984d40SFabiano Rosas /* True if v8.5-MTE tag checks affect the PE; index with is_unpriv. */
124f0984d40SFabiano Rosas bool mte_active[2];
125f0984d40SFabiano Rosas /* True with v8.5-BTI and SCTLR_ELx.BT* set. */
126f0984d40SFabiano Rosas bool bt;
127f0984d40SFabiano Rosas /* True if any CP15 access is trapped by HSTR_EL2 */
128f0984d40SFabiano Rosas bool hstr_active;
129f0984d40SFabiano Rosas /* True if memory operations require alignment */
130f0984d40SFabiano Rosas bool align_mem;
131f0984d40SFabiano Rosas /* True if PSTATE.IL is set */
132f0984d40SFabiano Rosas bool pstate_il;
133f0984d40SFabiano Rosas /* True if PSTATE.SM is set. */
134f0984d40SFabiano Rosas bool pstate_sm;
135f0984d40SFabiano Rosas /* True if PSTATE.ZA is set. */
136f0984d40SFabiano Rosas bool pstate_za;
137f0984d40SFabiano Rosas /* True if non-streaming insns should raise an SME Streaming exception. */
138f0984d40SFabiano Rosas bool sme_trap_nonstreaming;
139f0984d40SFabiano Rosas /* True if the current instruction is non-streaming. */
140f0984d40SFabiano Rosas bool is_nonstreaming;
141f0984d40SFabiano Rosas /* True if MVE insns are definitely not predicated by VPR or LTPSIZE */
142f0984d40SFabiano Rosas bool mve_no_pred;
143f0984d40SFabiano Rosas /* True if fine-grained traps are active */
144f0984d40SFabiano Rosas bool fgt_active;
145f0984d40SFabiano Rosas /* True if fine-grained trap on SVC is enabled */
146f0984d40SFabiano Rosas bool fgt_svc;
147e37e98b7SPeter Maydell /* True if a trap on ERET is enabled (FGT or NV) */
148e37e98b7SPeter Maydell bool trap_eret;
14983f624d9SRichard Henderson /* True if FEAT_LSE2 SCTLR_ELx.nAA is set */
15083f624d9SRichard Henderson bool naa;
15167d10fc4SPeter Maydell /* True if FEAT_NV HCR_EL2.NV is enabled */
15267d10fc4SPeter Maydell bool nv;
153c35da11dSPeter Maydell /* True if NV enabled and HCR_EL2.NV1 is set */
154c35da11dSPeter Maydell bool nv1;
155c35da11dSPeter Maydell /* True if NV enabled and HCR_EL2.NV2 is set */
156c35da11dSPeter Maydell bool nv2;
157daf9b4a0SPeter Maydell /* True if NV2 enabled and NV2 RAM accesses use EL2&0 translation regime */
158daf9b4a0SPeter Maydell bool nv2_mem_e20;
159daf9b4a0SPeter Maydell /* True if NV2 enabled and NV2 RAM accesses are big-endian */
160daf9b4a0SPeter Maydell bool nv2_mem_be;
161f0984d40SFabiano Rosas /*
162f0984d40SFabiano Rosas * >= 0, a copy of PSTATE.BTYPE, which will be 0 without v8.5-BTI.
163f0984d40SFabiano Rosas * < 0, set by the current instruction.
164f0984d40SFabiano Rosas */
165f0984d40SFabiano Rosas int8_t btype;
166f0984d40SFabiano Rosas /* A copy of cpu->dcz_blocksize. */
167f0984d40SFabiano Rosas uint8_t dcz_blocksize;
168851ec6ebSRichard Henderson /* A copy of cpu->gm_blocksize. */
169851ec6ebSRichard Henderson uint8_t gm_blocksize;
1704642250eSRichard Henderson /* True if the current insn_start has been updated. */
1714642250eSRichard Henderson bool insn_start_updated;
172f0984d40SFabiano Rosas /* Bottom two bits of XScale c15_cpar coprocessor access control reg */
173f0984d40SFabiano Rosas int c15_cpar;
174daf9b4a0SPeter Maydell /* Offset from VNCR_EL2 when FEAT_NV2 redirects this reg to memory */
175daf9b4a0SPeter Maydell uint32_t nv2_redirect_offset;
176f0984d40SFabiano Rosas } DisasContext;
177f0984d40SFabiano Rosas
178f0984d40SFabiano Rosas typedef struct DisasCompare {
179f0984d40SFabiano Rosas TCGCond cond;
180f0984d40SFabiano Rosas TCGv_i32 value;
181f0984d40SFabiano Rosas } DisasCompare;
182f0984d40SFabiano Rosas
183f0984d40SFabiano Rosas /* Share the TCG temporaries common between 32 and 64 bit modes. */
184f0984d40SFabiano Rosas extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
185f0984d40SFabiano Rosas extern TCGv_i64 cpu_exclusive_addr;
186f0984d40SFabiano Rosas extern TCGv_i64 cpu_exclusive_val;
187f0984d40SFabiano Rosas
negate(DisasContext * s,int x)188f0984d40SFabiano Rosas /*
189f0984d40SFabiano Rosas * Constant expanders for the decoders.
190f0984d40SFabiano Rosas */
191f0984d40SFabiano Rosas
192f0984d40SFabiano Rosas static inline int negate(DisasContext *s, int x)
193f0984d40SFabiano Rosas {
194f0984d40SFabiano Rosas return -x;
195f0984d40SFabiano Rosas }
196f0984d40SFabiano Rosas
197f0984d40SFabiano Rosas static inline int plus_1(DisasContext *s, int x)
plus_2(DisasContext * s,int x)198f0984d40SFabiano Rosas {
199f0984d40SFabiano Rosas return x + 1;
200f0984d40SFabiano Rosas }
201f0984d40SFabiano Rosas
202f0984d40SFabiano Rosas static inline int plus_2(DisasContext *s, int x)
plus_12(DisasContext * s,int x)203f0984d40SFabiano Rosas {
204f0984d40SFabiano Rosas return x + 2;
205f0984d40SFabiano Rosas }
206f0984d40SFabiano Rosas
207f0984d40SFabiano Rosas static inline int plus_12(DisasContext *s, int x)
times_2(DisasContext * s,int x)208f0984d40SFabiano Rosas {
209f0984d40SFabiano Rosas return x + 12;
210f0984d40SFabiano Rosas }
211f0984d40SFabiano Rosas
212f0984d40SFabiano Rosas static inline int times_2(DisasContext *s, int x)
times_4(DisasContext * s,int x)213f0984d40SFabiano Rosas {
214f0984d40SFabiano Rosas return x * 2;
215f0984d40SFabiano Rosas }
216f0984d40SFabiano Rosas
217f0984d40SFabiano Rosas static inline int times_4(DisasContext *s, int x)
times_8(DisasContext * s,int x)218f0984d40SFabiano Rosas {
219f0984d40SFabiano Rosas return x * 4;
220f0984d40SFabiano Rosas }
221f0984d40SFabiano Rosas
2225722fc47SPeter Maydell static inline int times_8(DisasContext *s, int x)
times_2_plus_1(DisasContext * s,int x)2235722fc47SPeter Maydell {
2245722fc47SPeter Maydell return x * 8;
2255722fc47SPeter Maydell }
2265722fc47SPeter Maydell
227f0984d40SFabiano Rosas static inline int times_2_plus_1(DisasContext *s, int x)
rsub_64(DisasContext * s,int x)228f0984d40SFabiano Rosas {
229f0984d40SFabiano Rosas return x * 2 + 1;
230f0984d40SFabiano Rosas }
231f0984d40SFabiano Rosas
232f0984d40SFabiano Rosas static inline int rsub_64(DisasContext *s, int x)
rsub_32(DisasContext * s,int x)233f0984d40SFabiano Rosas {
234f0984d40SFabiano Rosas return 64 - x;
235f0984d40SFabiano Rosas }
236f0984d40SFabiano Rosas
237f0984d40SFabiano Rosas static inline int rsub_32(DisasContext *s, int x)
rsub_16(DisasContext * s,int x)238f0984d40SFabiano Rosas {
239f0984d40SFabiano Rosas return 32 - x;
240f0984d40SFabiano Rosas }
241f0984d40SFabiano Rosas
242f0984d40SFabiano Rosas static inline int rsub_16(DisasContext *s, int x)
rsub_8(DisasContext * s,int x)243f0984d40SFabiano Rosas {
244f0984d40SFabiano Rosas return 16 - x;
245f0984d40SFabiano Rosas }
246f0984d40SFabiano Rosas
247f0984d40SFabiano Rosas static inline int rsub_8(DisasContext *s, int x)
shl_12(DisasContext * s,int x)248f0984d40SFabiano Rosas {
249f0984d40SFabiano Rosas return 8 - x;
250f0984d40SFabiano Rosas }
251f0984d40SFabiano Rosas
2523ce7b5eaSRichard Henderson static inline int shl_12(DisasContext *s, int x)
xor_2(DisasContext * s,int x)2533ce7b5eaSRichard Henderson {
2543ce7b5eaSRichard Henderson return x << 12;
2553ce7b5eaSRichard Henderson }
2563ce7b5eaSRichard Henderson
257e0300a9aSRichard Henderson static inline int xor_2(DisasContext *s, int x)
neon_3same_fp_size(DisasContext * s,int x)258e0300a9aSRichard Henderson {
259e0300a9aSRichard Henderson return x ^ 2;
260e0300a9aSRichard Henderson }
261e0300a9aSRichard Henderson
262f0984d40SFabiano Rosas static inline int neon_3same_fp_size(DisasContext *s, int x)
263f0984d40SFabiano Rosas {
arm_dc_feature(DisasContext * dc,int feature)264f0984d40SFabiano Rosas /* Convert 0==fp32, 1==fp16 into a MO_* value */
265f0984d40SFabiano Rosas return MO_32 - x;
266f0984d40SFabiano Rosas }
267f0984d40SFabiano Rosas
268f0984d40SFabiano Rosas static inline int arm_dc_feature(DisasContext *dc, int feature)
get_mem_index(DisasContext * s)269f0984d40SFabiano Rosas {
270f0984d40SFabiano Rosas return (dc->features & (1ULL << feature)) != 0;
271f0984d40SFabiano Rosas }
272f0984d40SFabiano Rosas
273f0984d40SFabiano Rosas static inline int get_mem_index(DisasContext *s)
disas_set_insn_syndrome(DisasContext * s,uint32_t syn)274f0984d40SFabiano Rosas {
275f0984d40SFabiano Rosas return arm_to_core_mmu_idx(s->mmu_idx);
276f0984d40SFabiano Rosas }
277f0984d40SFabiano Rosas
278f0984d40SFabiano Rosas static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
279f0984d40SFabiano Rosas {
280f0984d40SFabiano Rosas /* We don't need to save all of the syndrome so we mask and shift
281f0984d40SFabiano Rosas * out unneeded bits to help the sleb128 encoder do a better job.
282f0984d40SFabiano Rosas */
283f0984d40SFabiano Rosas syn &= ARM_INSN_START_WORD2_MASK;
284f0984d40SFabiano Rosas syn >>= ARM_INSN_START_WORD2_SHIFT;
285f0984d40SFabiano Rosas
2864642250eSRichard Henderson /* Check for multiple updates. */
2874642250eSRichard Henderson assert(!s->insn_start_updated);
curr_insn_len(DisasContext * s)2884642250eSRichard Henderson s->insn_start_updated = true;
2894642250eSRichard Henderson tcg_set_insn_start_param(s->base.insn_start, 2, syn);
290f0984d40SFabiano Rosas }
291f0984d40SFabiano Rosas
292f0984d40SFabiano Rosas static inline int curr_insn_len(DisasContext *s)
293f0984d40SFabiano Rosas {
294f0984d40SFabiano Rosas return s->base.pc_next - s->pc_curr;
295f0984d40SFabiano Rosas }
296f0984d40SFabiano Rosas
297f0984d40SFabiano Rosas /* is_jmp field values */
298f0984d40SFabiano Rosas #define DISAS_JUMP DISAS_TARGET_0 /* only pc was modified dynamically */
299f0984d40SFabiano Rosas /* CPU state was modified dynamically; exit to main loop for interrupts. */
300f0984d40SFabiano Rosas #define DISAS_UPDATE_EXIT DISAS_TARGET_1
301f0984d40SFabiano Rosas /* These instructions trap after executing, so the A32/T32 decoder must
302f0984d40SFabiano Rosas * defer them until after the conditional execution state has been updated.
303f0984d40SFabiano Rosas * WFI also needs special handling when single-stepping.
304f0984d40SFabiano Rosas */
305f0984d40SFabiano Rosas #define DISAS_WFI DISAS_TARGET_2
306f0984d40SFabiano Rosas #define DISAS_SWI DISAS_TARGET_3
307f0984d40SFabiano Rosas /* WFE */
308f0984d40SFabiano Rosas #define DISAS_WFE DISAS_TARGET_4
309f0984d40SFabiano Rosas #define DISAS_HVC DISAS_TARGET_5
310f0984d40SFabiano Rosas #define DISAS_SMC DISAS_TARGET_6
311f0984d40SFabiano Rosas #define DISAS_YIELD DISAS_TARGET_7
312f0984d40SFabiano Rosas /* M profile branch which might be an exception return (and so needs
313f0984d40SFabiano Rosas * custom end-of-TB code)
314f0984d40SFabiano Rosas */
315f0984d40SFabiano Rosas #define DISAS_BX_EXCRET DISAS_TARGET_8
316f0984d40SFabiano Rosas /*
317f0984d40SFabiano Rosas * For instructions which want an immediate exit to the main loop, as opposed
318f0984d40SFabiano Rosas * to attempting to use lookup_and_goto_ptr. Unlike DISAS_UPDATE_EXIT, this
319f0984d40SFabiano Rosas * doesn't write the PC on exiting the translation loop so you need to ensure
320f0984d40SFabiano Rosas * something (gen_a64_update_pc or runtime helper) has done so before we reach
321f0984d40SFabiano Rosas * return from cpu_tb_exec.
322f0984d40SFabiano Rosas */
323f0984d40SFabiano Rosas #define DISAS_EXIT DISAS_TARGET_9
324f0984d40SFabiano Rosas /* CPU state was modified dynamically; no need to exit, but do not chain. */
325f0984d40SFabiano Rosas #define DISAS_UPDATE_NOCHAIN DISAS_TARGET_10
326f0984d40SFabiano Rosas
327f0984d40SFabiano Rosas #ifdef TARGET_AARCH64
a64_translate_init(void)328f0984d40SFabiano Rosas void a64_translate_init(void);
329f0984d40SFabiano Rosas void gen_a64_update_pc(DisasContext *s, target_long diff);
330f0984d40SFabiano Rosas extern const TranslatorOps aarch64_translator_ops;
331f0984d40SFabiano Rosas #else
gen_a64_update_pc(DisasContext * s,target_long diff)332f0984d40SFabiano Rosas static inline void a64_translate_init(void)
333f0984d40SFabiano Rosas {
334f0984d40SFabiano Rosas }
335f0984d40SFabiano Rosas
336f0984d40SFabiano Rosas static inline void gen_a64_update_pc(DisasContext *s, target_long diff)
337f0984d40SFabiano Rosas {
338f0984d40SFabiano Rosas }
339f0984d40SFabiano Rosas #endif
340f0984d40SFabiano Rosas
341f0984d40SFabiano Rosas void arm_test_cc(DisasCompare *cmp, int cc);
342f0984d40SFabiano Rosas void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
343f0984d40SFabiano Rosas void arm_gen_test_cc(int cc, TCGLabel *label);
344f0984d40SFabiano Rosas MemOp pow2_align(unsigned i);
345f0984d40SFabiano Rosas void unallocated_encoding(DisasContext *s);
346f0984d40SFabiano Rosas void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp,
347f0984d40SFabiano Rosas uint32_t syn, uint32_t target_el);
get_ahp_flag(void)348f0984d40SFabiano Rosas void gen_exception_insn(DisasContext *s, target_long pc_diff,
349f0984d40SFabiano Rosas int excp, uint32_t syn);
350f0984d40SFabiano Rosas
351f0984d40SFabiano Rosas /* Return state of Alternate Half-precision flag, caller frees result */
352f0984d40SFabiano Rosas static inline TCGv_i32 get_ahp_flag(void)
353f0984d40SFabiano Rosas {
354f0984d40SFabiano Rosas TCGv_i32 ret = tcg_temp_new_i32();
355f0984d40SFabiano Rosas
356ce07ea61SPeter Maydell tcg_gen_ld_i32(ret, tcg_env, offsetoflow32(CPUARMState, vfp.fpcr));
357f0984d40SFabiano Rosas tcg_gen_extract_i32(ret, ret, 26, 1);
358f0984d40SFabiano Rosas
set_pstate_bits(uint32_t bits)359f0984d40SFabiano Rosas return ret;
360f0984d40SFabiano Rosas }
361f0984d40SFabiano Rosas
362f0984d40SFabiano Rosas /* Set bits within PSTATE. */
363f0984d40SFabiano Rosas static inline void set_pstate_bits(uint32_t bits)
364f0984d40SFabiano Rosas {
365f0984d40SFabiano Rosas TCGv_i32 p = tcg_temp_new_i32();
366f0984d40SFabiano Rosas
367f0984d40SFabiano Rosas tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
368f0984d40SFabiano Rosas
369ad75a51eSRichard Henderson tcg_gen_ld_i32(p, tcg_env, offsetof(CPUARMState, pstate));
370f0984d40SFabiano Rosas tcg_gen_ori_i32(p, p, bits);
clear_pstate_bits(uint32_t bits)371ad75a51eSRichard Henderson tcg_gen_st_i32(p, tcg_env, offsetof(CPUARMState, pstate));
372f0984d40SFabiano Rosas }
373f0984d40SFabiano Rosas
374f0984d40SFabiano Rosas /* Clear bits within PSTATE. */
375f0984d40SFabiano Rosas static inline void clear_pstate_bits(uint32_t bits)
376f0984d40SFabiano Rosas {
377f0984d40SFabiano Rosas TCGv_i32 p = tcg_temp_new_i32();
378f0984d40SFabiano Rosas
379f0984d40SFabiano Rosas tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
380f0984d40SFabiano Rosas
381ad75a51eSRichard Henderson tcg_gen_ld_i32(p, tcg_env, offsetof(CPUARMState, pstate));
382f0984d40SFabiano Rosas tcg_gen_andi_i32(p, p, ~bits);
gen_ss_advance(DisasContext * s)383ad75a51eSRichard Henderson tcg_gen_st_i32(p, tcg_env, offsetof(CPUARMState, pstate));
384f0984d40SFabiano Rosas }
385f0984d40SFabiano Rosas
386f0984d40SFabiano Rosas /* If the singlestep state is Active-not-pending, advance to Active-pending. */
387f0984d40SFabiano Rosas static inline void gen_ss_advance(DisasContext *s)
388f0984d40SFabiano Rosas {
389f0984d40SFabiano Rosas if (s->ss_active) {
390f0984d40SFabiano Rosas s->pstate_ss = 0;
391f0984d40SFabiano Rosas clear_pstate_bits(PSTATE_SS);
gen_swstep_exception(DisasContext * s,int isv,int ex)392f0984d40SFabiano Rosas }
393f0984d40SFabiano Rosas }
394f0984d40SFabiano Rosas
395f0984d40SFabiano Rosas /* Generate an architectural singlestep exception */
396f0984d40SFabiano Rosas static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
397f0984d40SFabiano Rosas {
398f0984d40SFabiano Rosas /* Fill in the same_el field of the syndrome in the helper. */
399f0984d40SFabiano Rosas uint32_t syn = syn_swstep(false, isv, ex);
400ad75a51eSRichard Henderson gen_helper_exception_swstep(tcg_env, tcg_constant_i32(syn));
401f0984d40SFabiano Rosas }
402f0984d40SFabiano Rosas
403f0984d40SFabiano Rosas /*
404f0984d40SFabiano Rosas * Given a VFP floating point constant encoded into an 8 bit immediate in an
405f0984d40SFabiano Rosas * instruction, expand it to the actual constant value of the specified
gen_vfp_absh(TCGv_i32 d,TCGv_i32 s)406f0984d40SFabiano Rosas * size, as per the VFPExpandImm() pseudocode in the Arm ARM.
407f0984d40SFabiano Rosas */
408f0984d40SFabiano Rosas uint64_t vfp_expand_imm(int size, uint8_t imm8);
409f0984d40SFabiano Rosas
41021e885afSRichard Henderson static inline void gen_vfp_absh(TCGv_i32 d, TCGv_i32 s)
gen_vfp_abss(TCGv_i32 d,TCGv_i32 s)41121e885afSRichard Henderson {
41221e885afSRichard Henderson tcg_gen_andi_i32(d, s, INT16_MAX);
41321e885afSRichard Henderson }
41421e885afSRichard Henderson
41521e885afSRichard Henderson static inline void gen_vfp_abss(TCGv_i32 d, TCGv_i32 s)
gen_vfp_absd(TCGv_i64 d,TCGv_i64 s)41621e885afSRichard Henderson {
41721e885afSRichard Henderson tcg_gen_andi_i32(d, s, INT32_MAX);
41821e885afSRichard Henderson }
41921e885afSRichard Henderson
42021e885afSRichard Henderson static inline void gen_vfp_absd(TCGv_i64 d, TCGv_i64 s)
gen_vfp_negh(TCGv_i32 d,TCGv_i32 s)42121e885afSRichard Henderson {
42221e885afSRichard Henderson tcg_gen_andi_i64(d, s, INT64_MAX);
42321e885afSRichard Henderson }
42421e885afSRichard Henderson
42521e885afSRichard Henderson static inline void gen_vfp_negh(TCGv_i32 d, TCGv_i32 s)
gen_vfp_negs(TCGv_i32 d,TCGv_i32 s)42621e885afSRichard Henderson {
42721e885afSRichard Henderson tcg_gen_xori_i32(d, s, 1u << 15);
42821e885afSRichard Henderson }
42921e885afSRichard Henderson
43021e885afSRichard Henderson static inline void gen_vfp_negs(TCGv_i32 d, TCGv_i32 s)
gen_vfp_negd(TCGv_i64 d,TCGv_i64 s)43121e885afSRichard Henderson {
43221e885afSRichard Henderson tcg_gen_xori_i32(d, s, 1u << 31);
43321e885afSRichard Henderson }
43421e885afSRichard Henderson
43521e885afSRichard Henderson static inline void gen_vfp_negd(TCGv_i64 d, TCGv_i64 s)
43621e885afSRichard Henderson {
43721e885afSRichard Henderson tcg_gen_xori_i64(d, s, 1ull << 63);
43821e885afSRichard Henderson }
43921e885afSRichard Henderson
440f0984d40SFabiano Rosas /* Vector operations shared between ARM and AArch64. */
441f0984d40SFabiano Rosas void gen_gvec_ceq0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
442f0984d40SFabiano Rosas uint32_t opr_sz, uint32_t max_sz);
443f0984d40SFabiano Rosas void gen_gvec_clt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
444f0984d40SFabiano Rosas uint32_t opr_sz, uint32_t max_sz);
445f0984d40SFabiano Rosas void gen_gvec_cgt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
446f0984d40SFabiano Rosas uint32_t opr_sz, uint32_t max_sz);
447f0984d40SFabiano Rosas void gen_gvec_cle0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
448f0984d40SFabiano Rosas uint32_t opr_sz, uint32_t max_sz);
449f0984d40SFabiano Rosas void gen_gvec_cge0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
450f0984d40SFabiano Rosas uint32_t opr_sz, uint32_t max_sz);
451f0984d40SFabiano Rosas
452f0984d40SFabiano Rosas void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
453f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
454f0984d40SFabiano Rosas void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
455f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
456f0984d40SFabiano Rosas
457f0984d40SFabiano Rosas void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
458f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
459f0984d40SFabiano Rosas void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
460f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
461f0984d40SFabiano Rosas void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
462f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
463940392c8SRichard Henderson void gen_gvec_srshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
464940392c8SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
465940392c8SRichard Henderson void gen_gvec_urshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
466940392c8SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
467e72a6878SRichard Henderson void gen_neon_sqshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
468e72a6878SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
469e72a6878SRichard Henderson void gen_neon_uqshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
470e72a6878SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
471cef9d54fSRichard Henderson void gen_neon_sqrshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
472cef9d54fSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
473cef9d54fSRichard Henderson void gen_neon_uqrshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
474cef9d54fSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
475f0984d40SFabiano Rosas
476ef2b80ebSRichard Henderson void gen_neon_sqshli(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
477ef2b80ebSRichard Henderson int64_t c, uint32_t opr_sz, uint32_t max_sz);
478ef2b80ebSRichard Henderson void gen_neon_uqshli(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
479ef2b80ebSRichard Henderson int64_t c, uint32_t opr_sz, uint32_t max_sz);
480ef2b80ebSRichard Henderson void gen_neon_sqshlui(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
481ef2b80ebSRichard Henderson int64_t c, uint32_t opr_sz, uint32_t max_sz);
482ef2b80ebSRichard Henderson
483203aca91SRichard Henderson void gen_gvec_shadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
484203aca91SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
485203aca91SRichard Henderson void gen_gvec_uhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
486203aca91SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
48734c0d865SRichard Henderson void gen_gvec_shsub(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
48834c0d865SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
48934c0d865SRichard Henderson void gen_gvec_uhsub(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
49034c0d865SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
4918989b95eSRichard Henderson void gen_gvec_srhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4928989b95eSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
4938989b95eSRichard Henderson void gen_gvec_urhadd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4948989b95eSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
495203aca91SRichard Henderson
496f0984d40SFabiano Rosas void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
497f0984d40SFabiano Rosas void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
498f0984d40SFabiano Rosas void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
499f0984d40SFabiano Rosas void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
500f0984d40SFabiano Rosas void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
501f0984d40SFabiano Rosas
502f4fa83d6SRichard Henderson void gen_uqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
503f4fa83d6SRichard Henderson TCGv_i64 a, TCGv_i64 b, MemOp esz);
504f4fa83d6SRichard Henderson void gen_uqadd_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
505f0984d40SFabiano Rosas void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
506f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
507f4fa83d6SRichard Henderson
508f4fa83d6SRichard Henderson void gen_sqadd_bhs(TCGv_i64 res, TCGv_i64 qc,
509f4fa83d6SRichard Henderson TCGv_i64 a, TCGv_i64 b, MemOp esz);
510f4fa83d6SRichard Henderson void gen_sqadd_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
511f0984d40SFabiano Rosas void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
512f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
513f4fa83d6SRichard Henderson
514f4fa83d6SRichard Henderson void gen_uqsub_bhs(TCGv_i64 res, TCGv_i64 qc,
515f4fa83d6SRichard Henderson TCGv_i64 a, TCGv_i64 b, MemOp esz);
516f4fa83d6SRichard Henderson void gen_uqsub_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
517f0984d40SFabiano Rosas void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
518f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
519f4fa83d6SRichard Henderson
520f4fa83d6SRichard Henderson void gen_sqsub_bhs(TCGv_i64 res, TCGv_i64 qc,
521f4fa83d6SRichard Henderson TCGv_i64 a, TCGv_i64 b, MemOp esz);
522f4fa83d6SRichard Henderson void gen_sqsub_d(TCGv_i64 d, TCGv_i64 q, TCGv_i64 a, TCGv_i64 b);
523f0984d40SFabiano Rosas void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
524f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
525f0984d40SFabiano Rosas
52600bcab5bSRichard Henderson void gen_gvec_sshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
52700bcab5bSRichard Henderson int64_t shift, uint32_t opr_sz, uint32_t max_sz);
52800bcab5bSRichard Henderson void gen_gvec_ushr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
52900bcab5bSRichard Henderson int64_t shift, uint32_t opr_sz, uint32_t max_sz);
53000bcab5bSRichard Henderson
531f0984d40SFabiano Rosas void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
532f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
533f0984d40SFabiano Rosas void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
534f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
535f0984d40SFabiano Rosas
53609a52d85SRichard Henderson void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh);
53709a52d85SRichard Henderson void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh);
53809a52d85SRichard Henderson void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh);
53909a52d85SRichard Henderson void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh);
54009a52d85SRichard Henderson
541f0984d40SFabiano Rosas void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
542f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
543f0984d40SFabiano Rosas void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
544f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
545f0984d40SFabiano Rosas void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
546f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
547f0984d40SFabiano Rosas void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
548f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
549f0984d40SFabiano Rosas
550f0984d40SFabiano Rosas void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
551f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
552f0984d40SFabiano Rosas void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
553f0984d40SFabiano Rosas int64_t shift, uint32_t opr_sz, uint32_t max_sz);
554f0984d40SFabiano Rosas
5558f81dcedSRichard Henderson void gen_gvec_sqdmulh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
5568f81dcedSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
5578f81dcedSRichard Henderson void gen_gvec_sqrdmulh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
5588f81dcedSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
559f0984d40SFabiano Rosas void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
560f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
561f0984d40SFabiano Rosas void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
562f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
563f0984d40SFabiano Rosas
564f0984d40SFabiano Rosas void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
565f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
566f0984d40SFabiano Rosas void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
567f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
568f0984d40SFabiano Rosas
569f0984d40SFabiano Rosas void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
570f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
571f0984d40SFabiano Rosas void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
572f0984d40SFabiano Rosas uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
573f0984d40SFabiano Rosas
574a7e4eec6SRichard Henderson void gen_gvec_addp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
575a7e4eec6SRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
57628b5451bSRichard Henderson void gen_gvec_smaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
57728b5451bSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
57828b5451bSRichard Henderson void gen_gvec_sminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
57928b5451bSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
58028b5451bSRichard Henderson void gen_gvec_umaxp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
58128b5451bSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
58228b5451bSRichard Henderson void gen_gvec_uminp(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
58328b5451bSRichard Henderson uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
584a7e4eec6SRichard Henderson
585f0984d40SFabiano Rosas /*
586f0984d40SFabiano Rosas * Forward to the isar_feature_* tests given a DisasContext pointer.
587f0984d40SFabiano Rosas */
588f0984d40SFabiano Rosas #define dc_isar_feature(name, ctx) \
589f0984d40SFabiano Rosas ({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
590f0984d40SFabiano Rosas
591f0984d40SFabiano Rosas /* Note that the gvec expanders operate on offsets + sizes. */
592f0984d40SFabiano Rosas typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
593f0984d40SFabiano Rosas typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
594f0984d40SFabiano Rosas uint32_t, uint32_t);
595f0984d40SFabiano Rosas typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
596f0984d40SFabiano Rosas uint32_t, uint32_t, uint32_t);
597f0984d40SFabiano Rosas typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
598f0984d40SFabiano Rosas uint32_t, uint32_t, uint32_t);
599f0984d40SFabiano Rosas
600f0984d40SFabiano Rosas /* Function prototype for gen_ functions for calling Neon helpers */
601f0984d40SFabiano Rosas typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
602f0984d40SFabiano Rosas typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
603f0984d40SFabiano Rosas typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
604f0984d40SFabiano Rosas typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
605f0984d40SFabiano Rosas typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
606f0984d40SFabiano Rosas TCGv_i32, TCGv_i32);
607f0984d40SFabiano Rosas typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
608f0984d40SFabiano Rosas typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
609f0984d40SFabiano Rosas typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
610f0984d40SFabiano Rosas typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
611f0984d40SFabiano Rosas typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
612f0984d40SFabiano Rosas typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
613f0984d40SFabiano Rosas typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
614f0984d40SFabiano Rosas typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
615f0984d40SFabiano Rosas typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
6163e683f0aSRichard Henderson typedef void NeonGenOne64OpEnvFn(TCGv_i64, TCGv_env, TCGv_i64);
617f0984d40SFabiano Rosas typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
618f0984d40SFabiano Rosas typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
619f0984d40SFabiano Rosas typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
620f0984d40SFabiano Rosas typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
621f0984d40SFabiano Rosas typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
622f0984d40SFabiano Rosas typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
623f0984d40SFabiano Rosas typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
624f0984d40SFabiano Rosas typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
625f0984d40SFabiano Rosas
626f0984d40SFabiano Rosas /**
627f0984d40SFabiano Rosas * arm_tbflags_from_tb:
arm_tbflags_from_tb(const TranslationBlock * tb)628f0984d40SFabiano Rosas * @tb: the TranslationBlock
629f0984d40SFabiano Rosas *
630f0984d40SFabiano Rosas * Extract the flag values from @tb.
631f0984d40SFabiano Rosas */
632f0984d40SFabiano Rosas static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
633f0984d40SFabiano Rosas {
634f0984d40SFabiano Rosas return (CPUARMTBFlags){ tb->flags, tb->cs_base };
635f0984d40SFabiano Rosas }
636f0984d40SFabiano Rosas
637f0984d40SFabiano Rosas /*
638f0984d40SFabiano Rosas * Enum for argument to fpstatus_ptr().
639f0984d40SFabiano Rosas */
640f0984d40SFabiano Rosas typedef enum ARMFPStatusFlavour {
641f0984d40SFabiano Rosas FPST_FPCR,
642f0984d40SFabiano Rosas FPST_FPCR_F16,
643f0984d40SFabiano Rosas FPST_STD,
644f0984d40SFabiano Rosas FPST_STD_F16,
645f0984d40SFabiano Rosas } ARMFPStatusFlavour;
646f0984d40SFabiano Rosas
647f0984d40SFabiano Rosas /**
648f0984d40SFabiano Rosas * fpstatus_ptr: return TCGv_ptr to the specified fp_status field
649f0984d40SFabiano Rosas *
650f0984d40SFabiano Rosas * We have multiple softfloat float_status fields in the Arm CPU state struct
651f0984d40SFabiano Rosas * (see the comment in cpu.h for details). Return a TCGv_ptr which has
652f0984d40SFabiano Rosas * been set up to point to the requested field in the CPU state struct.
653f0984d40SFabiano Rosas * The options are:
654f0984d40SFabiano Rosas *
655f0984d40SFabiano Rosas * FPST_FPCR
656f0984d40SFabiano Rosas * for non-FP16 operations controlled by the FPCR
657f0984d40SFabiano Rosas * FPST_FPCR_F16
658f0984d40SFabiano Rosas * for operations controlled by the FPCR where FPCR.FZ16 is to be used
659f0984d40SFabiano Rosas * FPST_STD
fpstatus_ptr(ARMFPStatusFlavour flavour)660f0984d40SFabiano Rosas * for A32/T32 Neon operations using the "standard FPSCR value"
661f0984d40SFabiano Rosas * FPST_STD_F16
662f0984d40SFabiano Rosas * as FPST_STD, but where FPCR.FZ16 is to be used
663f0984d40SFabiano Rosas */
664f0984d40SFabiano Rosas static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour)
665f0984d40SFabiano Rosas {
666f0984d40SFabiano Rosas TCGv_ptr statusptr = tcg_temp_new_ptr();
667f0984d40SFabiano Rosas int offset;
668f0984d40SFabiano Rosas
669f0984d40SFabiano Rosas switch (flavour) {
670f0984d40SFabiano Rosas case FPST_FPCR:
671f0984d40SFabiano Rosas offset = offsetof(CPUARMState, vfp.fp_status);
672f0984d40SFabiano Rosas break;
673f0984d40SFabiano Rosas case FPST_FPCR_F16:
674f0984d40SFabiano Rosas offset = offsetof(CPUARMState, vfp.fp_status_f16);
675f0984d40SFabiano Rosas break;
676f0984d40SFabiano Rosas case FPST_STD:
677f0984d40SFabiano Rosas offset = offsetof(CPUARMState, vfp.standard_fp_status);
678f0984d40SFabiano Rosas break;
679f0984d40SFabiano Rosas case FPST_STD_F16:
680f0984d40SFabiano Rosas offset = offsetof(CPUARMState, vfp.standard_fp_status_f16);
681f0984d40SFabiano Rosas break;
682f0984d40SFabiano Rosas default:
683f0984d40SFabiano Rosas g_assert_not_reached();
684f0984d40SFabiano Rosas }
685ad75a51eSRichard Henderson tcg_gen_addi_ptr(statusptr, tcg_env, offset);
686f0984d40SFabiano Rosas return statusptr;
687f0984d40SFabiano Rosas }
688f0984d40SFabiano Rosas
689f0984d40SFabiano Rosas /**
690e452ca5aSRichard Henderson * finalize_memop_atom:
691f0984d40SFabiano Rosas * @s: DisasContext
692f0984d40SFabiano Rosas * @opc: size+sign+align of the memory operation
693e452ca5aSRichard Henderson * @atom: atomicity of the memory operation
694f0984d40SFabiano Rosas *
695e452ca5aSRichard Henderson * Build the complete MemOp for a memory operation, including alignment,
696e452ca5aSRichard Henderson * endianness, and atomicity.
697f0984d40SFabiano Rosas *
698f0984d40SFabiano Rosas * If (op & MO_AMASK) then the operation already contains the required
699f0984d40SFabiano Rosas * alignment, e.g. for AccType_ATOMIC. Otherwise, this an optionally
700f0984d40SFabiano Rosas * unaligned operation, e.g. for AccType_NORMAL.
701f0984d40SFabiano Rosas *
finalize_memop_atom(DisasContext * s,MemOp opc,MemOp atom)702f0984d40SFabiano Rosas * In the latter case, there are configuration bits that require alignment,
703f0984d40SFabiano Rosas * and this is applied here. Note that there is no way to indicate that
704f0984d40SFabiano Rosas * no alignment should ever be enforced; this must be handled manually.
705f0984d40SFabiano Rosas */
706e452ca5aSRichard Henderson static inline MemOp finalize_memop_atom(DisasContext *s, MemOp opc, MemOp atom)
707f0984d40SFabiano Rosas {
708f0984d40SFabiano Rosas if (s->align_mem && !(opc & MO_AMASK)) {
709f0984d40SFabiano Rosas opc |= MO_ALIGN;
710f0984d40SFabiano Rosas }
711e452ca5aSRichard Henderson return opc | atom | s->be_data;
712e452ca5aSRichard Henderson }
713e452ca5aSRichard Henderson
714e452ca5aSRichard Henderson /**
715e452ca5aSRichard Henderson * finalize_memop:
716e452ca5aSRichard Henderson * @s: DisasContext
finalize_memop(DisasContext * s,MemOp opc)717e452ca5aSRichard Henderson * @opc: size+sign+align of the memory operation
718e452ca5aSRichard Henderson *
719e452ca5aSRichard Henderson * Like finalize_memop_atom, but with default atomicity.
720e452ca5aSRichard Henderson */
721e452ca5aSRichard Henderson static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
722e452ca5aSRichard Henderson {
723e452ca5aSRichard Henderson MemOp atom = s->lse2 ? MO_ATOM_WITHIN16 : MO_ATOM_IFALIGN;
724e452ca5aSRichard Henderson return finalize_memop_atom(s, opc, atom);
725e452ca5aSRichard Henderson }
726e452ca5aSRichard Henderson
727e452ca5aSRichard Henderson /**
728e452ca5aSRichard Henderson * finalize_memop_pair:
729e452ca5aSRichard Henderson * @s: DisasContext
730e452ca5aSRichard Henderson * @opc: size+sign+align of the memory operation
finalize_memop_pair(DisasContext * s,MemOp opc)731e452ca5aSRichard Henderson *
732e452ca5aSRichard Henderson * Like finalize_memop_atom, but with atomicity for a pair.
733e452ca5aSRichard Henderson * C.f. Pseudocode for Mem[], operand ispair.
734e452ca5aSRichard Henderson */
735e452ca5aSRichard Henderson static inline MemOp finalize_memop_pair(DisasContext *s, MemOp opc)
736e452ca5aSRichard Henderson {
737e452ca5aSRichard Henderson MemOp atom = s->lse2 ? MO_ATOM_WITHIN16_PAIR : MO_ATOM_IFALIGN_PAIR;
738e452ca5aSRichard Henderson return finalize_memop_atom(s, opc, atom);
739f0984d40SFabiano Rosas }
740f0984d40SFabiano Rosas
741f0984d40SFabiano Rosas /**
742d450bd01SRichard Henderson * finalize_memop_asimd:
743d450bd01SRichard Henderson * @s: DisasContext
finalize_memop_asimd(DisasContext * s,MemOp opc)744d450bd01SRichard Henderson * @opc: size+sign+align of the memory operation
745d450bd01SRichard Henderson *
746d450bd01SRichard Henderson * Like finalize_memop_atom, but with atomicity of AccessType_ASIMD.
747d450bd01SRichard Henderson */
748d450bd01SRichard Henderson static inline MemOp finalize_memop_asimd(DisasContext *s, MemOp opc)
749d450bd01SRichard Henderson {
750d450bd01SRichard Henderson /*
751d450bd01SRichard Henderson * In the pseudocode for Mem[], with AccessType_ASIMD, size == 16,
752d450bd01SRichard Henderson * if IsAligned(8), the first case provides separate atomicity for
753d450bd01SRichard Henderson * the pair of 64-bit accesses. If !IsAligned(8), the middle cases
754d450bd01SRichard Henderson * do not apply, and we're left with the final case of no atomicity.
755d450bd01SRichard Henderson * Thus MO_ATOM_IFALIGN_PAIR.
756d450bd01SRichard Henderson *
757d450bd01SRichard Henderson * For other sizes, normal LSE2 rules apply.
758d450bd01SRichard Henderson */
759d450bd01SRichard Henderson if ((opc & MO_SIZE) == MO_128) {
760d450bd01SRichard Henderson return finalize_memop_atom(s, opc, MO_ATOM_IFALIGN_PAIR);
761d450bd01SRichard Henderson }
762d450bd01SRichard Henderson return finalize_memop(s, opc);
763d450bd01SRichard Henderson }
764d450bd01SRichard Henderson
765d450bd01SRichard Henderson /**
766f0984d40SFabiano Rosas * asimd_imm_const: Expand an encoded SIMD constant value
767f0984d40SFabiano Rosas *
768f0984d40SFabiano Rosas * Expand a SIMD constant value. This is essentially the pseudocode
769f0984d40SFabiano Rosas * AdvSIMDExpandImm, except that we also perform the boolean NOT needed for
770f0984d40SFabiano Rosas * VMVN and VBIC (when cmode < 14 && op == 1).
771f0984d40SFabiano Rosas *
772f0984d40SFabiano Rosas * The combination cmode == 15 op == 1 is a reserved encoding for AArch32;
773f0984d40SFabiano Rosas * callers must catch this; we return the 64-bit constant value defined
774f0984d40SFabiano Rosas * for AArch64.
775f0984d40SFabiano Rosas *
776f0984d40SFabiano Rosas * cmode = 2,3,4,5,6,7,10,11,12,13 imm=0 was UNPREDICTABLE in v7A but
777f0984d40SFabiano Rosas * is either not unpredictable or merely CONSTRAINED UNPREDICTABLE in v8A;
778f0984d40SFabiano Rosas * we produce an immediate constant value of 0 in these cases.
779f0984d40SFabiano Rosas */
780f0984d40SFabiano Rosas uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
781f0984d40SFabiano Rosas
gen_disas_label(DisasContext * s)782f0984d40SFabiano Rosas /*
783f0984d40SFabiano Rosas * gen_disas_label:
784f0984d40SFabiano Rosas * Create a label and cache a copy of pc_save.
785f0984d40SFabiano Rosas */
786f0984d40SFabiano Rosas static inline DisasLabel gen_disas_label(DisasContext *s)
787f0984d40SFabiano Rosas {
788f0984d40SFabiano Rosas return (DisasLabel){
789f0984d40SFabiano Rosas .label = gen_new_label(),
790f0984d40SFabiano Rosas .pc_save = s->pc_save,
791f0984d40SFabiano Rosas };
792f0984d40SFabiano Rosas }
793f0984d40SFabiano Rosas
set_disas_label(DisasContext * s,DisasLabel l)794f0984d40SFabiano Rosas /*
795f0984d40SFabiano Rosas * set_disas_label:
796f0984d40SFabiano Rosas * Emit a label and restore the cached copy of pc_save.
797f0984d40SFabiano Rosas */
798f0984d40SFabiano Rosas static inline void set_disas_label(DisasContext *s, DisasLabel l)
799f0984d40SFabiano Rosas {
800f0984d40SFabiano Rosas gen_set_label(l.label);
801f0984d40SFabiano Rosas s->pc_save = l.pc_save;
802f0984d40SFabiano Rosas }
803f0984d40SFabiano Rosas
804f0984d40SFabiano Rosas static inline TCGv_ptr gen_lookup_cp_reg(uint32_t key)
805f0984d40SFabiano Rosas {
806f0984d40SFabiano Rosas TCGv_ptr ret = tcg_temp_new_ptr();
807ad75a51eSRichard Henderson gen_helper_lookup_cp_reg(ret, tcg_env, tcg_constant_i32(key));
808f0984d40SFabiano Rosas return ret;
809f0984d40SFabiano Rosas }
gen_set_rmode(ARMFPRounding rmode,TCGv_ptr fpst)810f0984d40SFabiano Rosas
811f0984d40SFabiano Rosas /*
8128d1b02a6SRichard Henderson * Set and reset rounding mode around another operation.
8138d1b02a6SRichard Henderson */
8148d1b02a6SRichard Henderson static inline TCGv_i32 gen_set_rmode(ARMFPRounding rmode, TCGv_ptr fpst)
8158d1b02a6SRichard Henderson {
8168d1b02a6SRichard Henderson TCGv_i32 new = tcg_constant_i32(arm_rmode_to_sf(rmode));
8178d1b02a6SRichard Henderson TCGv_i32 old = tcg_temp_new_i32();
8188d1b02a6SRichard Henderson
8198d1b02a6SRichard Henderson gen_helper_set_rmode(old, new, fpst);
8208d1b02a6SRichard Henderson return old;
8218d1b02a6SRichard Henderson }
8228d1b02a6SRichard Henderson
8238d1b02a6SRichard Henderson static inline void gen_restore_rmode(TCGv_i32 old, TCGv_ptr fpst)
8248d1b02a6SRichard Henderson {
8258d1b02a6SRichard Henderson gen_helper_set_rmode(old, old, fpst);
8268d1b02a6SRichard Henderson }
8278d1b02a6SRichard Henderson
8288d1b02a6SRichard Henderson /*
829f0984d40SFabiano Rosas * Helpers for implementing sets of trans_* functions.
830f0984d40SFabiano Rosas * Defer the implementation of NAME to FUNC, with optional extra arguments.
831f0984d40SFabiano Rosas */
832f0984d40SFabiano Rosas #define TRANS(NAME, FUNC, ...) \
833f0984d40SFabiano Rosas static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
834f0984d40SFabiano Rosas { return FUNC(s, __VA_ARGS__); }
835f0984d40SFabiano Rosas #define TRANS_FEAT(NAME, FEAT, FUNC, ...) \
836f0984d40SFabiano Rosas static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
837f0984d40SFabiano Rosas { return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); }
838f0984d40SFabiano Rosas
839f0984d40SFabiano Rosas #define TRANS_FEAT_NONSTREAMING(NAME, FEAT, FUNC, ...) \
840f0984d40SFabiano Rosas static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
841f0984d40SFabiano Rosas { \
842f0984d40SFabiano Rosas s->is_nonstreaming = true; \
843f0984d40SFabiano Rosas return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); \
844f0984d40SFabiano Rosas }
845f0984d40SFabiano Rosas
846f0984d40SFabiano Rosas #endif /* TARGET_ARM_TRANSLATE_H */
847