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