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 | eRegsetMaskDynamic = ~1, |
36 | }; |
37 | |
38 | // AArch64 Register set FP/SIMD feature configuration |
39 | enum { |
40 | eVectorQuadwordAArch64, |
41 | eVectorQuadwordAArch64SVE, |
42 | eVectorQuadwordAArch64SVEMax = 256 |
43 | }; |
44 | |
45 | // based on RegisterContextDarwin_arm64.h |
46 | LLVM_PACKED_START |
47 | struct GPR { |
48 | uint64_t x[29]; // x0-x28 |
49 | uint64_t fp; // x29 |
50 | uint64_t lr; // x30 |
51 | uint64_t sp; // x31 |
52 | uint64_t pc; // pc |
53 | uint32_t cpsr; // cpsr |
54 | uint32_t pad; |
55 | }; |
56 | LLVM_PACKED_END |
57 | |
58 | // based on RegisterContextDarwin_arm64.h |
59 | struct VReg { |
60 | uint8_t bytes[16]; |
61 | }; |
62 | |
63 | // based on RegisterContextDarwin_arm64.h |
64 | struct FPU { |
65 | VReg v[32]; |
66 | uint32_t fpsr; |
67 | uint32_t fpcr; |
68 | }; |
69 | |
70 | // based on RegisterContextDarwin_arm64.h |
71 | struct EXC { |
72 | uint64_t far; // Virtual Fault Address |
73 | uint32_t esr; // Exception syndrome |
74 | uint32_t exception; // number of arm exception token |
75 | }; |
76 | |
77 | // based on RegisterContextDarwin_arm64.h |
78 | struct DBG { |
79 | uint64_t bvr[16]; |
80 | uint64_t bcr[16]; |
81 | uint64_t wvr[16]; |
82 | uint64_t wcr[16]; |
83 | uint64_t mdscr_el1; |
84 | }; |
85 | |
86 | RegisterInfoPOSIX_arm64(const lldb_private::ArchSpec &target_arch, |
87 | lldb_private::Flags opt_regsets); |
88 | |
89 | static size_t GetGPRSizeStatic(); |
90 | size_t GetGPRSize() const override { return GetGPRSizeStatic(); } |
91 | |
92 | size_t GetFPRSize() const override; |
93 | |
94 | const lldb_private::RegisterInfo *GetRegisterInfo() const override; |
95 | |
96 | uint32_t GetRegisterCount() const override; |
97 | |
98 | const lldb_private::RegisterSet * |
99 | GetRegisterSet(size_t reg_set) const override; |
100 | |
101 | size_t GetRegisterSetCount() const override; |
102 | |
103 | size_t GetRegisterSetFromRegisterIndex(uint32_t reg_index) const override; |
104 | |
105 | void AddRegSetPAuth(); |
106 | |
107 | void AddRegSetMTE(); |
108 | |
109 | void AddRegSetTLS(bool has_tpidr2); |
110 | |
111 | void AddRegSetSME(bool has_zt); |
112 | |
113 | uint32_t ConfigureVectorLengthSVE(uint32_t sve_vq); |
114 | |
115 | void ConfigureVectorLengthZA(uint32_t za_vq); |
116 | |
117 | bool VectorSizeIsValid(uint32_t vq) { |
118 | // coverity[unsigned_compare] |
119 | if (vq >= eVectorQuadwordAArch64 && vq <= eVectorQuadwordAArch64SVEMax) |
120 | return true; |
121 | return false; |
122 | } |
123 | |
124 | bool IsSVEPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskSVE); } |
125 | bool IsSSVEPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskSSVE); } |
126 | bool IsZAPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskZA); } |
127 | bool IsZTPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskZT); } |
128 | bool IsPAuthPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskPAuth); } |
129 | bool IsMTEPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskMTE); } |
130 | bool IsTLSPresent() const { return m_opt_regsets.AnySet(mask: eRegsetMaskTLS); } |
131 | |
132 | bool IsSVEReg(unsigned reg) const; |
133 | bool IsSVEZReg(unsigned reg) const; |
134 | bool IsSVEPReg(unsigned reg) const; |
135 | bool IsSVERegVG(unsigned reg) const; |
136 | bool IsPAuthReg(unsigned reg) const; |
137 | bool IsMTEReg(unsigned reg) const; |
138 | bool IsTLSReg(unsigned reg) const; |
139 | bool IsSMEReg(unsigned reg) const; |
140 | bool IsSMERegZA(unsigned reg) const; |
141 | bool IsSMERegZT(unsigned reg) const; |
142 | |
143 | uint32_t GetRegNumSVEZ0() const; |
144 | uint32_t GetRegNumSVEFFR() const; |
145 | uint32_t GetRegNumFPCR() const; |
146 | uint32_t GetRegNumFPSR() const; |
147 | uint32_t GetRegNumSVEVG() const; |
148 | uint32_t GetRegNumSMESVG() const; |
149 | uint32_t GetPAuthOffset() const; |
150 | uint32_t GetMTEOffset() const; |
151 | uint32_t GetTLSOffset() const; |
152 | uint32_t GetSMEOffset() const; |
153 | |
154 | private: |
155 | typedef std::map<uint32_t, std::vector<lldb_private::RegisterInfo>> |
156 | per_vq_register_infos; |
157 | |
158 | per_vq_register_infos m_per_vq_reg_infos; |
159 | |
160 | uint32_t m_vector_reg_vq = eVectorQuadwordAArch64; |
161 | uint32_t m_za_reg_vq = eVectorQuadwordAArch64; |
162 | |
163 | // In normal operation this is const. Only when SVE or SME registers change |
164 | // size is it either replaced or the content modified. |
165 | const lldb_private::RegisterInfo *m_register_info_p; |
166 | uint32_t m_register_info_count; |
167 | |
168 | const lldb_private::RegisterSet *m_register_set_p; |
169 | uint32_t m_register_set_count; |
170 | |
171 | // Contains pair of [start, end] register numbers of a register set with start |
172 | // and end included. |
173 | std::map<uint32_t, std::pair<uint32_t, uint32_t>> m_per_regset_regnum_range; |
174 | |
175 | lldb_private::Flags m_opt_regsets; |
176 | |
177 | std::vector<lldb_private::RegisterInfo> m_dynamic_reg_infos; |
178 | std::vector<lldb_private::RegisterSet> m_dynamic_reg_sets; |
179 | |
180 | std::vector<uint32_t> pauth_regnum_collection; |
181 | std::vector<uint32_t> m_mte_regnum_collection; |
182 | std::vector<uint32_t> m_tls_regnum_collection; |
183 | std::vector<uint32_t> m_sme_regnum_collection; |
184 | }; |
185 | |
186 | #endif |
187 | |