1 | //===-- RegisterInfoPOSIX_arm64.h -------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H |
10 | #define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_REGISTERINFOPOSIX_ARM64_H |
11 | |
12 | #include "RegisterInfoAndSetInterface.h" |
13 | #include "lldb/Target/RegisterContext.h" |
14 | #include "lldb/Utility/Flags.h" |
15 | #include "lldb/lldb-private.h" |
16 | #include <map> |
17 | |
18 | enum class SVEState : uint8_t { Unknown, Disabled, FPSIMD, Full, Streaming }; |
19 | |
20 | class RegisterInfoPOSIX_arm64 |
21 | : public lldb_private::RegisterInfoAndSetInterface { |
22 | public: |
23 | enum { GPRegSet = 0, FPRegSet }; |
24 | |
25 | // AArch64 register set mask value |
26 | enum { |
27 | eRegsetMaskDefault = 0, |
28 | eRegsetMaskSVE = 1, |
29 | eRegsetMaskSSVE = 2, |
30 | eRegsetMaskPAuth = 4, |
31 | eRegsetMaskMTE = 8, |
32 | eRegsetMaskTLS = 16, |
33 | eRegsetMaskZA = 32, |
34 | eRegsetMaskZT = 64, |
35 | eRegsetMaskFPMR = 128, |
36 | eRegsetMaskGCS = 256, |
37 | eRegsetMaskDynamic = ~1, |
38 | }; |
39 | |
40 | // AArch64 Register set FP/SIMD feature configuration |
41 | enum { |
42 | eVectorQuadwordAArch64, |
43 | eVectorQuadwordAArch64SVE, |
44 | eVectorQuadwordAArch64SVEMax = 256 |
45 | }; |
46 | |
47 | // based on RegisterContextDarwin_arm64.h |
48 | LLVM_PACKED_START |
49 | struct GPR { |
50 | uint64_t x[29]; // x0-x28 |
51 | uint64_t fp; // x29 |
52 | uint64_t lr; // x30 |
53 | uint64_t sp; // x31 |
54 | uint64_t pc; // pc |
55 | uint32_t cpsr; // cpsr |
56 | uint32_t pad; |
57 | }; |
58 | LLVM_PACKED_END |
59 | |
60 | // based on RegisterContextDarwin_arm64.h |
61 | struct VReg { |
62 | uint8_t bytes[16]; |
63 | }; |
64 | |
65 | // based on RegisterContextDarwin_arm64.h |
66 | struct FPU { |
67 | VReg v[32]; |
68 | uint32_t fpsr; |
69 | uint32_t fpcr; |
70 | }; |
71 | |
72 | // based on RegisterContextDarwin_arm64.h |
73 | struct EXC { |
74 | uint64_t far; // Virtual Fault Address |
75 | uint32_t esr; // Exception syndrome |
76 | uint32_t exception; // number of arm exception token |
77 | }; |
78 | |
79 | // based on RegisterContextDarwin_arm64.h |
80 | struct DBG { |
81 | uint64_t bvr[16]; |
82 | uint64_t bcr[16]; |
83 | uint64_t wvr[16]; |
84 | uint64_t wcr[16]; |
85 | uint64_t mdscr_el1; |
86 | }; |
87 | |
88 | RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch, |
89 | lldb_private::Flags opt_regsets); |
90 | |
91 | static size_t GetGPRSizeStatic(); |
92 | size_t GetGPRSize() const override { return GetGPRSizeStatic(); } |
93 | |
94 | size_t GetFPRSize() const override; |
95 | |
96 | const lldb_private::RegisterInfo *GetRegisterInfo() const override; |
97 | |
98 | uint32_t GetRegisterCount() const override; |
99 | |
100 | const lldb_private::RegisterSet * |
101 | GetRegisterSet(size_t reg_set) const override; |
102 | |
103 | size_t GetRegisterSetCount() const override; |
104 | |
105 | size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override; |
106 | |
107 | void AddRegSetPAuth(); |
108 | |
109 | void AddRegSetMTE(); |
110 | |
111 | void AddRegSetTLS(bool has_tpidr2); |
112 | |
113 | void AddRegSetSME(bool has_zt); |
114 | |
115 | void AddRegSetFPMR(); |
116 | |
117 | void AddRegSetGCS(); |
118 | |
119 | uint32_t ConfigureVectorLengthSVE(uint32_t sve_vq); |
120 | |
121 | void ConfigureVectorLengthZA(uint32_t za_vq); |
122 | |
123 | bool VectorSizeIsValid(uint32_t vq) { |
124 | // coverity[unsigned_compare] |
125 | if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax) |
126 | return true; |
127 | return false; |
128 | } |
129 | |
130 | bool IsSVEPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskSVE); } |
131 | bool IsSSVEPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskSSVE); } |
132 | bool IsZAPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskZA); } |
133 | bool IsZTPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskZT); } |
134 | bool IsPAuthPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskPAuth); } |
135 | bool IsMTEPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskMTE); } |
136 | bool IsTLSPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskTLS); } |
137 | bool IsFPMRPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskFPMR); } |
138 | bool IsGCSPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskGCS); } |
139 | |
140 | bool IsSVEReg(unsigned reg) const; |
141 | bool IsSVEZReg(unsigned reg) const; |
142 | bool IsSVEPReg(unsigned reg) const; |
143 | bool IsSVERegVG(unsigned reg) const; |
144 | bool IsPAuthReg(unsigned reg) const; |
145 | bool IsMTEReg(unsigned reg) const; |
146 | bool IsTLSReg(unsigned reg) const; |
147 | bool IsSMEReg(unsigned reg) const; |
148 | bool IsSMERegZA(unsigned reg) const; |
149 | bool IsSMERegZT(unsigned reg) const; |
150 | bool IsFPMRReg(unsigned reg) const; |
151 | bool IsGCSReg(unsigned reg) const; |
152 | |
153 | uint32_t GetRegNumSVEZ0() const; |
154 | uint32_t GetRegNumSVEFFR() const; |
155 | uint32_t GetRegNumFPCR() const; |
156 | uint32_t GetRegNumFPSR() const; |
157 | uint32_t GetRegNumSVEVG() const; |
158 | uint32_t GetRegNumSMESVG() const; |
159 | uint32_t GetPAuthOffset() const; |
160 | uint32_t GetMTEOffset() const; |
161 | uint32_t GetTLSOffset() const; |
162 | uint32_t GetSMEOffset() const; |
163 | uint32_t GetFPMROffset() const; |
164 | uint32_t GetGCSOffset() const; |
165 | |
166 | private: |
167 | typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>> |
168 | per_vq_register_infos; |
169 | |
170 | per_vq_register_infos m_per_vq_reg_infos; |
171 | |
172 | uint32_t m_vector_reg_vq = eVectorQuadwordAArch64; |
173 | uint32_t m_za_reg_vq = eVectorQuadwordAArch64; |
174 | |
175 | // In normal operation this is const. Only when SVE or SME registers change |
176 | // size is it either replaced or the content modified. |
177 | const lldb_private::RegisterInfo *m_register_info_p; |
178 | uint32_t m_register_info_count; |
179 | |
180 | const lldb_private::RegisterSet *m_register_set_p; |
181 | uint32_t m_register_set_count; |
182 | |
183 | // Contains pair of [start, end] register numbers of a register set with start |
184 | // and end included. |
185 | std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range; |
186 | |
187 | lldb_private::Flags m_opt_regsets; |
188 | |
189 | std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos; |
190 | std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets; |
191 | |
192 | std::vector<uint32_t> pauth_regnum_collection; |
193 | std::vector<uint32_t> m_mte_regnum_collection; |
194 | std::vector<uint32_t> m_tls_regnum_collection; |
195 | std::vector<uint32_t> m_sme_regnum_collection; |
196 | std::vector<uint32_t> m_fpmr_regnum_collection; |
197 | std::vector<uint32_t> m_gcs_regnum_collection; |
198 | }; |
199 | |
200 | #endif |
201 | |