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
9
10
11
12
13
14typedef struct DisasLabel {
15 TCGLabel *label;
16 target_ulong pc_save;
17} DisasLabel;
18
19typedef struct DisasContext {
20 DisasContextBase base;
21 const ARMISARegisters *isar;
22
23
24 target_ulong pc_curr;
25
26
27
28
29
30
31
32
33
34
35
36
37
38 target_ulong pc_save;
39 target_ulong page_start;
40 uint32_t insn;
41
42 int condjmp;
43
44 DisasLabel condlabel;
45
46 int condexec_mask;
47 int condexec_cond;
48
49 int eci;
50
51
52
53
54 bool eci_handled;
55 int sctlr_b;
56 MemOp be_data;
57#if !defined(CONFIG_USER_ONLY)
58 int user;
59#endif
60 ARMMMUIdx mmu_idx;
61 uint8_t tbii;
62 uint8_t tbid;
63 uint8_t tcma;
64 bool ns;
65 int fp_excp_el;
66 int sve_excp_el;
67 int sme_excp_el;
68 int vl;
69 int svl;
70 bool vfp_enabled;
71 int vec_len;
72 int vec_stride;
73 bool v7m_handler_mode;
74 bool v8m_secure;
75 bool v8m_stackcheck;
76 bool v8m_fpccr_s_wrong;
77 bool v7m_new_fp_ctxt_needed;
78 bool v7m_lspact;
79
80
81
82 uint32_t svc_imm;
83 int current_el;
84 GHashTable *cp_regs;
85 uint64_t features;
86 bool aarch64;
87 bool thumb;
88
89
90
91
92
93
94
95 bool fp_access_checked;
96 bool sve_access_checked;
97
98
99
100 bool ss_active;
101 bool pstate_ss;
102
103
104
105
106 bool is_ldex;
107
108 bool unpriv;
109
110 bool pauth_active;
111
112 bool ata;
113
114 bool mte_active[2];
115
116 bool bt;
117
118 bool hstr_active;
119
120 bool align_mem;
121
122 bool pstate_il;
123
124 bool pstate_sm;
125
126 bool pstate_za;
127
128 bool sme_trap_nonstreaming;
129
130 bool is_nonstreaming;
131
132 bool mve_no_pred;
133
134
135
136
137 int8_t btype;
138
139 uint8_t dcz_blocksize;
140
141 bool guarded_page;
142
143 int c15_cpar;
144
145 TCGOp *insn_start;
146#define TMP_A64_MAX 16
147 int tmp_a64_count;
148 TCGv_i64 tmp_a64[TMP_A64_MAX];
149} DisasContext;
150
151typedef struct DisasCompare {
152 TCGCond cond;
153 TCGv_i32 value;
154 bool value_global;
155} DisasCompare;
156
157
158extern TCGv_i32 cpu_NF, cpu_ZF, cpu_CF, cpu_VF;
159extern TCGv_i64 cpu_exclusive_addr;
160extern TCGv_i64 cpu_exclusive_val;
161
162
163
164
165
166static inline int negate(DisasContext *s, int x)
167{
168 return -x;
169}
170
171static inline int plus_1(DisasContext *s, int x)
172{
173 return x + 1;
174}
175
176static inline int plus_2(DisasContext *s, int x)
177{
178 return x + 2;
179}
180
181static inline int plus_12(DisasContext *s, int x)
182{
183 return x + 12;
184}
185
186static inline int times_2(DisasContext *s, int x)
187{
188 return x * 2;
189}
190
191static inline int times_4(DisasContext *s, int x)
192{
193 return x * 4;
194}
195
196static inline int times_2_plus_1(DisasContext *s, int x)
197{
198 return x * 2 + 1;
199}
200
201static inline int rsub_64(DisasContext *s, int x)
202{
203 return 64 - x;
204}
205
206static inline int rsub_32(DisasContext *s, int x)
207{
208 return 32 - x;
209}
210
211static inline int rsub_16(DisasContext *s, int x)
212{
213 return 16 - x;
214}
215
216static inline int rsub_8(DisasContext *s, int x)
217{
218 return 8 - x;
219}
220
221static inline int neon_3same_fp_size(DisasContext *s, int x)
222{
223
224 return MO_32 - x;
225}
226
227static inline int arm_dc_feature(DisasContext *dc, int feature)
228{
229 return (dc->features & (1ULL << feature)) != 0;
230}
231
232static inline int get_mem_index(DisasContext *s)
233{
234 return arm_to_core_mmu_idx(s->mmu_idx);
235}
236
237static inline void disas_set_insn_syndrome(DisasContext *s, uint32_t syn)
238{
239
240
241
242 syn &= ARM_INSN_START_WORD2_MASK;
243 syn >>= ARM_INSN_START_WORD2_SHIFT;
244
245
246 assert(s->insn_start != NULL);
247 tcg_set_insn_start_param(s->insn_start, 2, syn);
248 s->insn_start = NULL;
249}
250
251static inline int curr_insn_len(DisasContext *s)
252{
253 return s->base.pc_next - s->pc_curr;
254}
255
256
257#define DISAS_JUMP DISAS_TARGET_0
258
259#define DISAS_UPDATE_EXIT DISAS_TARGET_1
260
261
262
263
264#define DISAS_WFI DISAS_TARGET_2
265#define DISAS_SWI DISAS_TARGET_3
266
267#define DISAS_WFE DISAS_TARGET_4
268#define DISAS_HVC DISAS_TARGET_5
269#define DISAS_SMC DISAS_TARGET_6
270#define DISAS_YIELD DISAS_TARGET_7
271
272
273
274#define DISAS_BX_EXCRET DISAS_TARGET_8
275
276
277
278
279
280
281
282#define DISAS_EXIT DISAS_TARGET_9
283
284#define DISAS_UPDATE_NOCHAIN DISAS_TARGET_10
285
286#ifdef TARGET_AARCH64
287void a64_translate_init(void);
288void gen_a64_update_pc(DisasContext *s, target_long diff);
289extern const TranslatorOps aarch64_translator_ops;
290#else
291static inline void a64_translate_init(void)
292{
293}
294
295static inline void gen_a64_update_pc(DisasContext *s, target_long diff)
296{
297}
298#endif
299
300void arm_test_cc(DisasCompare *cmp, int cc);
301void arm_free_cc(DisasCompare *cmp);
302void arm_jump_cc(DisasCompare *cmp, TCGLabel *label);
303void arm_gen_test_cc(int cc, TCGLabel *label);
304MemOp pow2_align(unsigned i);
305void unallocated_encoding(DisasContext *s);
306void gen_exception_insn_el(DisasContext *s, target_long pc_diff, int excp,
307 uint32_t syn, uint32_t target_el);
308void gen_exception_insn(DisasContext *s, target_long pc_diff,
309 int excp, uint32_t syn);
310
311
312static inline TCGv_i32 get_ahp_flag(void)
313{
314 TCGv_i32 ret = tcg_temp_new_i32();
315
316 tcg_gen_ld_i32(ret, cpu_env,
317 offsetof(CPUARMState, vfp.xregs[ARM_VFP_FPSCR]));
318 tcg_gen_extract_i32(ret, ret, 26, 1);
319
320 return ret;
321}
322
323
324static inline void set_pstate_bits(uint32_t bits)
325{
326 TCGv_i32 p = tcg_temp_new_i32();
327
328 tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
329
330 tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
331 tcg_gen_ori_i32(p, p, bits);
332 tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
333 tcg_temp_free_i32(p);
334}
335
336
337static inline void clear_pstate_bits(uint32_t bits)
338{
339 TCGv_i32 p = tcg_temp_new_i32();
340
341 tcg_debug_assert(!(bits & CACHED_PSTATE_BITS));
342
343 tcg_gen_ld_i32(p, cpu_env, offsetof(CPUARMState, pstate));
344 tcg_gen_andi_i32(p, p, ~bits);
345 tcg_gen_st_i32(p, cpu_env, offsetof(CPUARMState, pstate));
346 tcg_temp_free_i32(p);
347}
348
349
350static inline void gen_ss_advance(DisasContext *s)
351{
352 if (s->ss_active) {
353 s->pstate_ss = 0;
354 clear_pstate_bits(PSTATE_SS);
355 }
356}
357
358
359static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
360{
361
362 uint32_t syn = syn_swstep(false, isv, ex);
363 gen_helper_exception_swstep(cpu_env, tcg_constant_i32(syn));
364}
365
366
367
368
369
370
371uint64_t vfp_expand_imm(int size, uint8_t imm8);
372
373
374void gen_gvec_ceq0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
375 uint32_t opr_sz, uint32_t max_sz);
376void gen_gvec_clt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
377 uint32_t opr_sz, uint32_t max_sz);
378void gen_gvec_cgt0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
379 uint32_t opr_sz, uint32_t max_sz);
380void gen_gvec_cle0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
381 uint32_t opr_sz, uint32_t max_sz);
382void gen_gvec_cge0(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
383 uint32_t opr_sz, uint32_t max_sz);
384
385void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
386 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
387void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
388 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
389
390void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
391 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
392void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
393 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
394void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
395 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
396
397void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
398void gen_ushl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
399void gen_sshl_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b);
400void gen_ushl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
401void gen_sshl_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b);
402
403void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
404 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
405void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
406 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
407void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
408 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
409void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
410 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
411
412void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
413 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
414void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
415 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
416
417void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
418 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
419void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
420 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
421void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
422 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
423void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
424 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
425
426void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
427 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
428void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
429 int64_t shift, uint32_t opr_sz, uint32_t max_sz);
430
431void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
432 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
433void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
434 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
435
436void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
437 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
438void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
439 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
440
441void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
442 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
443void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
444 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz);
445
446
447
448
449#define dc_isar_feature(name, ctx) \
450 ({ DisasContext *ctx_ = (ctx); isar_feature_##name(ctx_->isar); })
451
452
453typedef void GVecGen2Fn(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
454typedef void GVecGen2iFn(unsigned, uint32_t, uint32_t, int64_t,
455 uint32_t, uint32_t);
456typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
457 uint32_t, uint32_t, uint32_t);
458typedef void GVecGen4Fn(unsigned, uint32_t, uint32_t, uint32_t,
459 uint32_t, uint32_t, uint32_t);
460
461
462typedef void NeonGenOneOpFn(TCGv_i32, TCGv_i32);
463typedef void NeonGenOneOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32);
464typedef void NeonGenTwoOpFn(TCGv_i32, TCGv_i32, TCGv_i32);
465typedef void NeonGenTwoOpEnvFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
466typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
467 TCGv_i32, TCGv_i32);
468typedef void NeonGenTwo64OpFn(TCGv_i64, TCGv_i64, TCGv_i64);
469typedef void NeonGenTwo64OpEnvFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i64);
470typedef void NeonGenNarrowFn(TCGv_i32, TCGv_i64);
471typedef void NeonGenNarrowEnvFn(TCGv_i32, TCGv_ptr, TCGv_i64);
472typedef void NeonGenWidenFn(TCGv_i64, TCGv_i32);
473typedef void NeonGenTwoOpWidenFn(TCGv_i64, TCGv_i32, TCGv_i32);
474typedef void NeonGenOneSingleOpFn(TCGv_i32, TCGv_i32, TCGv_ptr);
475typedef void NeonGenTwoSingleOpFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
476typedef void NeonGenTwoDoubleOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGv_ptr);
477typedef void NeonGenOne64OpFn(TCGv_i64, TCGv_i64);
478typedef void CryptoTwoOpFn(TCGv_ptr, TCGv_ptr);
479typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
480typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr);
481typedef void AtomicThreeOpFn(TCGv_i64, TCGv_i64, TCGv_i64, TCGArg, MemOp);
482typedef void WideShiftImmFn(TCGv_i64, TCGv_i64, int64_t shift);
483typedef void WideShiftFn(TCGv_i64, TCGv_ptr, TCGv_i64, TCGv_i32);
484typedef void ShiftImmFn(TCGv_i32, TCGv_i32, int32_t shift);
485typedef void ShiftFn(TCGv_i32, TCGv_ptr, TCGv_i32, TCGv_i32);
486
487
488
489
490
491
492
493static inline CPUARMTBFlags arm_tbflags_from_tb(const TranslationBlock *tb)
494{
495 return (CPUARMTBFlags){ tb->flags, tb->cs_base };
496}
497
498
499
500
501typedef enum ARMFPStatusFlavour {
502 FPST_FPCR,
503 FPST_FPCR_F16,
504 FPST_STD,
505 FPST_STD_F16,
506} ARMFPStatusFlavour;
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525static inline TCGv_ptr fpstatus_ptr(ARMFPStatusFlavour flavour)
526{
527 TCGv_ptr statusptr = tcg_temp_new_ptr();
528 int offset;
529
530 switch (flavour) {
531 case FPST_FPCR:
532 offset = offsetof(CPUARMState, vfp.fp_status);
533 break;
534 case FPST_FPCR_F16:
535 offset = offsetof(CPUARMState, vfp.fp_status_f16);
536 break;
537 case FPST_STD:
538 offset = offsetof(CPUARMState, vfp.standard_fp_status);
539 break;
540 case FPST_STD_F16:
541 offset = offsetof(CPUARMState, vfp.standard_fp_status_f16);
542 break;
543 default:
544 g_assert_not_reached();
545 }
546 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
547 return statusptr;
548}
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566static inline MemOp finalize_memop(DisasContext *s, MemOp opc)
567{
568 if (s->align_mem && !(opc & MO_AMASK)) {
569 opc |= MO_ALIGN;
570 }
571 return opc | s->be_data;
572}
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589uint64_t asimd_imm_const(uint32_t imm, int cmode, int op);
590
591
592
593
594
595static inline DisasLabel gen_disas_label(DisasContext *s)
596{
597 return (DisasLabel){
598 .label = gen_new_label(),
599 .pc_save = s->pc_save,
600 };
601}
602
603
604
605
606
607static inline void set_disas_label(DisasContext *s, DisasLabel l)
608{
609 gen_set_label(l.label);
610 s->pc_save = l.pc_save;
611}
612
613
614
615
616
617#define TRANS(NAME, FUNC, ...) \
618 static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
619 { return FUNC(s, __VA_ARGS__); }
620#define TRANS_FEAT(NAME, FEAT, FUNC, ...) \
621 static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
622 { return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); }
623
624#define TRANS_FEAT_NONSTREAMING(NAME, FEAT, FUNC, ...) \
625 static bool trans_##NAME(DisasContext *s, arg_##NAME *a) \
626 { \
627 s->is_nonstreaming = true; \
628 return dc_isar_feature(FEAT, s) && FUNC(s, __VA_ARGS__); \
629 }
630
631#endif
632