1#ifndef TARGET_ARM_TRANSLATE_H
2#define TARGET_ARM_TRANSLATE_H
3
4#include "exec/translator.h"
5
6
7
8typedef struct DisasContext {
9 DisasContextBase base;
10 const ARMISARegisters *isar;
11
12 target_ulong pc;
13 target_ulong page_start;
14 uint32_t insn;
15
16 int condjmp;
17
18 TCGLabel *condlabel;
19
20 int condexec_mask;
21 int condexec_cond;
22 int thumb;
23 int sctlr_b;
24 TCGMemOp be_data;
25#if !defined(CONFIG_USER_ONLY)
26 int user;
27#endif
28 ARMMMUIdx mmu_idx;
29 uint8_t tbii;
30 uint8_t tbid;
31 bool ns;
32 int fp_excp_el;
33 int sve_excp_el;
34 int sve_len;
35
36 bool secure_routed_to_el3;
37 bool vfp_enabled;
38 int vec_len;
39 int vec_stride;
40 bool v7m_handler_mode;
41 bool v8m_secure;
42 bool v8m_stackcheck;
43
44
45
46 uint32_t svc_imm;
47 int aarch64;
48 int current_el;
49 GHashTable *cp_regs;
50 uint64_t features;
51
52
53
54
55
56
57
58 bool fp_access_checked;
59
60
61
62 bool ss_active;
63 bool pstate_ss;
64
65
66
67
68 bool is_ldex;
69
70 bool ss_same_el;
71
72 bool pauth_active;
73
74 bool bt;
75
76
77
78
79 int8_t btype;
80
81 bool guarded_page;
82
83 int c15_cpar;
84
85 TCGOp *insn_start;
86#define TMP_A64_MAX 16
87 int tmp_a64_count;
88 TCGv_i64 tmp_a64[TMP_A64_MAX];
89} DisasContext;
90
91typedef struct DisasCompare {
92 TCGCond cond;
93 TCGv_i32 value;
94 bool value_global;
95} DisasCompare;
96
97
98extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
99extern TCGv_i64 cpu_exclusive_addr;
100extern TCGv_i64 cpu_exclusive_val;
101
102static inline int arm_dc_feature(DisasContext *dc, int feature)
103{
104 return (dc->features & (1ULL << feature)) != 0;
105}
106
107static inline int get_mem_index(DisasContext *s)
108{
109 return arm_to_core_mmu_idx(s->mmu_idx);
110}
111
112
113
114
115static inline int default_exception_el(DisasContext *s)
116{
117
118
119
120
121
122 return (s->mmu_idx == ARMMMUIdx_S1SE0 && s->secure_routed_to_el3)
123 ? 3 : MAX(1, s->current_el);
124}
125
126static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
127{
128
129
130
131 syn &= ARM_INSN_START_WORD2_MASK;
132 syn >>= ARM_INSN_START_WORD2_SHIFT;
133
134
135 assert(s->insn_start != NULL);
136 tcg_set_insn_start_param(s->insn_start, 2, syn);
137 s->insn_start = NULL;
138}
139
140
141#define DISAS_JUMP DISAS_TARGET_0
142#define DISAS_UPDATE DISAS_TARGET_1
143
144
145
146
147#define DISAS_WFI DISAS_TARGET_2
148#define DISAS_SWI DISAS_TARGET_3
149
150#define DISAS_WFE DISAS_TARGET_4
151#define DISAS_HVC DISAS_TARGET_5
152#define DISAS_SMC DISAS_TARGET_6
153#define DISAS_YIELD DISAS_TARGET_7
154
155
156
157#define DISAS_BX_EXCRET DISAS_TARGET_8
158
159
160
161
162
163
164#define DISAS_EXIT DISAS_TARGET_9
165
166#ifdef TARGET_AARCH64
167void a64_translate_init(void);
168void gen_a64_set_pc_im(uint64_t val);
169void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
170 fprintf_function cpu_fprintf, int flags);
171extern const TranslatorOps aarch64_translator_ops;
172#else
173static inline void a64_translate_init(void)
174{
175}
176
177static inline void gen_a64_set_pc_im(uint64_t val)
178{
179}
180
181static inline void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
182 fprintf_function cpu_fprintf,
183 int flags)
184{
185}
186#endif
187
188void arm_test_cc(DisasCompare *cmp, int cc);
189void arm_free_cc(DisasCompare *cmp);
190void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
191void arm_gen_test_cc(int cc, TCGLabel *label);
192
193
194static inline TCGv_i32 get_ahp_flag(void)
195{
196 TCGv_i32 ret = tcg_temp_new_i32();
197
198 tcg_gen_ld_i32(ret, cpu_env,
199 offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPSCR]));
200 tcg_gen_extract_i32(ret, ret, 26, 1);
201
202 return ret;
203}
204
205
206static inline void set_pstate_bits(uint32_t bits)
207{
208 TCGv_i32 p = tcg_temp_new_i32();
209
210 tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
211
212 tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
213 tcg_gen_ori_i32(p, p, bits);
214 tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
215 tcg_temp_free_i32(p);
216}
217
218
219static inline void clear_pstate_bits(uint32_t bits)
220{
221 TCGv_i32 p = tcg_temp_new_i32();
222
223 tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
224
225 tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
226 tcg_gen_andi_i32(p, p, ~bits);
227 tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
228 tcg_temp_free_i32(p);
229}
230
231
232static inline void gen_ss_advance(DisasContext *s)
233{
234 if (s->ss_active) {
235 s->pstate_ss = 0;
236 clear_pstate_bits(PSTATE_SS);
237 }
238}
239
240
241extern const GVecGen3 bsl_op;
242extern const GVecGen3 bit_op;
243extern const GVecGen3 bif_op;
244extern const GVecGen3 mla_op[4];
245extern const GVecGen3 mls_op[4];
246extern const GVecGen3 cmtst_op[4];
247extern const GVecGen2i ssra_op[4];
248extern const GVecGen2i usra_op[4];
249extern const GVecGen2i sri_op[4];
250extern const GVecGen2i sli_op[4];
251extern const GVecGen4 uqadd_op[4];
252extern const GVecGen4 sqadd_op[4];
253extern const GVecGen4 uqsub_op[4];
254extern const GVecGen4 sqsub_op[4];
255void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
256
257
258
259
260#define dc_isar_feature(name, ctx) \
261 ({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
262
263#endif
264