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