Registers.hpp revision 1.3 1 1.1 joerg //===----------------------------- Registers.hpp --------------------------===//
2 1.1 joerg //
3 1.1 joerg // The LLVM Compiler Infrastructure
4 1.1 joerg //
5 1.1 joerg // This file is dual licensed under the MIT and the University of Illinois Open
6 1.1 joerg // Source Licenses. See LICENSE.TXT for details.
7 1.1 joerg //
8 1.1 joerg //
9 1.1 joerg // Models register sets for supported processors.
10 1.1 joerg //
11 1.1 joerg //===----------------------------------------------------------------------===//
12 1.1 joerg #ifndef __REGISTERS_HPP__
13 1.1 joerg #define __REGISTERS_HPP__
14 1.1 joerg
15 1.1 joerg #include <cassert>
16 1.1 joerg #include <cstdint>
17 1.1 joerg
18 1.1 joerg namespace _Unwind {
19 1.1 joerg
20 1.1 joerg enum {
21 1.1 joerg REGNO_X86_EAX = 0,
22 1.1 joerg REGNO_X86_ECX = 1,
23 1.1 joerg REGNO_X86_EDX = 2,
24 1.1 joerg REGNO_X86_EBX = 3,
25 1.1 joerg REGNO_X86_ESP = 4,
26 1.1 joerg REGNO_X86_EBP = 5,
27 1.1 joerg REGNO_X86_ESI = 6,
28 1.1 joerg REGNO_X86_EDI = 7,
29 1.1 joerg REGNO_X86_EIP = 8,
30 1.1 joerg };
31 1.1 joerg
32 1.1 joerg class Registers_x86 {
33 1.1 joerg public:
34 1.1 joerg enum {
35 1.3 joerg LAST_REGISTER = REGNO_X86_EIP,
36 1.1 joerg LAST_RESTORE_REG = REGNO_X86_EIP,
37 1.3 joerg RETURN_REG = REGNO_X86_EIP,
38 1.1 joerg };
39 1.1 joerg
40 1.1 joerg __dso_hidden Registers_x86();
41 1.1 joerg
42 1.1 joerg static int dwarf2regno(int num) { return num; }
43 1.1 joerg
44 1.1 joerg bool validRegister(int num) const {
45 1.1 joerg return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
46 1.1 joerg }
47 1.1 joerg
48 1.1 joerg uint32_t getRegister(int num) const {
49 1.1 joerg assert(validRegister(num));
50 1.1 joerg return reg[num];
51 1.1 joerg }
52 1.1 joerg
53 1.1 joerg void setRegister(int num, uint32_t value) {
54 1.1 joerg assert(validRegister(num));
55 1.1 joerg reg[num] = value;
56 1.1 joerg }
57 1.1 joerg
58 1.1 joerg uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
59 1.1 joerg
60 1.1 joerg void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
61 1.1 joerg
62 1.1 joerg uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
63 1.1 joerg
64 1.1 joerg void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
65 1.1 joerg
66 1.1 joerg bool validFloatVectorRegister(int num) const { return false; }
67 1.1 joerg
68 1.1 joerg void copyFloatVectorRegister(int num, uint32_t addr) {
69 1.1 joerg }
70 1.1 joerg
71 1.1 joerg __dso_hidden void jumpto() const __dead;
72 1.1 joerg
73 1.1 joerg private:
74 1.1 joerg uint32_t reg[REGNO_X86_EIP + 1];
75 1.1 joerg };
76 1.1 joerg
77 1.1 joerg enum {
78 1.1 joerg REGNO_X86_64_RAX = 0,
79 1.1 joerg REGNO_X86_64_RDX = 1,
80 1.1 joerg REGNO_X86_64_RCX = 2,
81 1.1 joerg REGNO_X86_64_RBX = 3,
82 1.1 joerg REGNO_X86_64_RSI = 4,
83 1.1 joerg REGNO_X86_64_RDI = 5,
84 1.1 joerg REGNO_X86_64_RBP = 6,
85 1.1 joerg REGNO_X86_64_RSP = 7,
86 1.1 joerg REGNO_X86_64_R8 = 8,
87 1.1 joerg REGNO_X86_64_R9 = 9,
88 1.1 joerg REGNO_X86_64_R10 = 10,
89 1.1 joerg REGNO_X86_64_R11 = 11,
90 1.1 joerg REGNO_X86_64_R12 = 12,
91 1.1 joerg REGNO_X86_64_R13 = 13,
92 1.1 joerg REGNO_X86_64_R14 = 14,
93 1.1 joerg REGNO_X86_64_R15 = 15,
94 1.1 joerg REGNO_X86_64_RIP = 16,
95 1.1 joerg };
96 1.1 joerg
97 1.1 joerg class Registers_x86_64 {
98 1.1 joerg public:
99 1.1 joerg enum {
100 1.3 joerg LAST_REGISTER = REGNO_X86_64_RIP,
101 1.1 joerg LAST_RESTORE_REG = REGNO_X86_64_RIP,
102 1.3 joerg RETURN_REG = REGNO_X86_64_RIP,
103 1.1 joerg };
104 1.1 joerg
105 1.1 joerg __dso_hidden Registers_x86_64();
106 1.1 joerg
107 1.1 joerg static int dwarf2regno(int num) { return num; }
108 1.1 joerg
109 1.1 joerg bool validRegister(int num) const {
110 1.1 joerg return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
111 1.1 joerg }
112 1.1 joerg
113 1.1 joerg uint64_t getRegister(int num) const {
114 1.1 joerg assert(validRegister(num));
115 1.1 joerg return reg[num];
116 1.1 joerg }
117 1.1 joerg
118 1.1 joerg void setRegister(int num, uint64_t value) {
119 1.1 joerg assert(validRegister(num));
120 1.1 joerg reg[num] = value;
121 1.1 joerg }
122 1.1 joerg
123 1.1 joerg uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
124 1.1 joerg
125 1.1 joerg void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
126 1.1 joerg
127 1.1 joerg uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
128 1.1 joerg
129 1.1 joerg void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
130 1.1 joerg
131 1.1 joerg bool validFloatVectorRegister(int num) const { return false; }
132 1.1 joerg
133 1.1 joerg void copyFloatVectorRegister(int num, uint64_t addr) {
134 1.1 joerg }
135 1.1 joerg
136 1.1 joerg __dso_hidden void jumpto() const __dead;
137 1.1 joerg
138 1.1 joerg private:
139 1.1 joerg uint64_t reg[REGNO_X86_64_RIP + 1];
140 1.1 joerg };
141 1.1 joerg
142 1.1 joerg enum {
143 1.1 joerg DWARF_PPC32_R0 = 0,
144 1.1 joerg DWARF_PPC32_R31 = 31,
145 1.1 joerg DWARF_PPC32_F0 = 32,
146 1.1 joerg DWARF_PPC32_F31 = 63,
147 1.1 joerg DWARF_PPC32_V0 = 1124,
148 1.1 joerg DWARF_PPC32_V31 = 1155,
149 1.1 joerg DWARF_PPC32_LR = 65,
150 1.1 joerg DWARF_PPC32_CTR = 66,
151 1.1 joerg DWARF_PPC32_XER = 76,
152 1.1 joerg REGNO_PPC32_R0 = 0,
153 1.1 joerg REGNO_PPC32_R1 = 0,
154 1.1 joerg REGNO_PPC32_R31 = 31,
155 1.1 joerg REGNO_PPC32_CR = 32,
156 1.1 joerg REGNO_PPC32_LR = 33,
157 1.1 joerg REGNO_PPC32_CTR = 34,
158 1.1 joerg REGNO_PPC32_XER = 35,
159 1.1 joerg REGNO_PPC32_SRR0 = 36,
160 1.1 joerg REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
161 1.1 joerg REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
162 1.1 joerg REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
163 1.1 joerg REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
164 1.1 joerg };
165 1.1 joerg
166 1.1 joerg class Registers_ppc32 {
167 1.1 joerg public:
168 1.1 joerg enum {
169 1.3 joerg LAST_REGISTER = REGNO_PPC32_V31,
170 1.1 joerg LAST_RESTORE_REG = REGNO_PPC32_V31,
171 1.3 joerg RETURN_REG = REGNO_PPC32_LR,
172 1.1 joerg };
173 1.1 joerg
174 1.1 joerg __dso_hidden Registers_ppc32();
175 1.1 joerg
176 1.1 joerg static int dwarf2regno(int num) {
177 1.1 joerg if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
178 1.1 joerg return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
179 1.1 joerg if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
180 1.1 joerg return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
181 1.1 joerg if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
182 1.1 joerg return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
183 1.1 joerg return LAST_REGISTER + 1;
184 1.1 joerg }
185 1.1 joerg
186 1.1 joerg bool validRegister(int num) const {
187 1.1 joerg return num >= 0 && num <= LAST_RESTORE_REG;
188 1.1 joerg }
189 1.1 joerg
190 1.1 joerg uint64_t getRegister(int num) const {
191 1.1 joerg assert(validRegister(num));
192 1.1 joerg return reg[num];
193 1.1 joerg }
194 1.1 joerg
195 1.1 joerg void setRegister(int num, uint64_t value) {
196 1.1 joerg assert(validRegister(num));
197 1.1 joerg reg[num] = value;
198 1.1 joerg }
199 1.1 joerg
200 1.1 joerg uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
201 1.1 joerg
202 1.1 joerg void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
203 1.1 joerg
204 1.1 joerg uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
205 1.1 joerg
206 1.1 joerg void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
207 1.1 joerg
208 1.1 joerg bool validFloatVectorRegister(int num) const {
209 1.1 joerg return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
210 1.1 joerg (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
211 1.1 joerg }
212 1.1 joerg
213 1.1 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
214 1.1 joerg const void *addr = reinterpret_cast<const void *>(addr_);
215 1.1 joerg if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
216 1.1 joerg memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
217 1.1 joerg else
218 1.1 joerg memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
219 1.1 joerg }
220 1.1 joerg
221 1.1 joerg __dso_hidden void jumpto() const __dead;
222 1.1 joerg
223 1.1 joerg private:
224 1.1 joerg struct vecreg_t {
225 1.1 joerg uint64_t low, high;
226 1.1 joerg };
227 1.1 joerg uint32_t reg[REGNO_PPC32_SRR0 + 1];
228 1.1 joerg uint64_t fpreg[32];
229 1.1 joerg vecreg_t vecreg[64];
230 1.1 joerg };
231 1.1 joerg
232 1.2 matt enum {
233 1.2 matt DWARF_ARM32_R0 = 0,
234 1.2 matt DWARF_ARM32_R15 = 15,
235 1.2 matt DWARF_ARM32_SPSR = 128,
236 1.2 matt DWARF_ARM32_D0 = 256, // VFP-v3/Neon
237 1.2 matt DWARF_ARM32_D31 = 287,
238 1.2 matt REGNO_ARM32_R0 = 0,
239 1.2 matt REGNO_ARM32_SP = 13,
240 1.2 matt REGNO_ARM32_R15 = 15,
241 1.2 matt REGNO_ARM32_SPSR = 16,
242 1.2 matt REGNO_ARM32_D0 = 0,
243 1.2 matt REGNO_ARM32_D31 = 31,
244 1.2 matt };
245 1.2 matt
246 1.2 matt class Registers_arm32 {
247 1.2 matt public:
248 1.2 matt enum {
249 1.3 joerg LAST_REGISTER = REGNO_ARM32_D31,
250 1.2 matt LAST_RESTORE_REG = REGNO_ARM32_SPSR,
251 1.3 joerg RETURN_REG = REGNO_ARM32_SPSR,
252 1.2 matt };
253 1.2 matt
254 1.2 matt __dso_hidden Registers_arm32();
255 1.2 matt
256 1.2 matt static int dwarf2regno(int num) {
257 1.2 matt if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
258 1.2 matt return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
259 1.2 matt if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
260 1.2 matt return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
261 1.2 matt if (num == DWARF_ARM32_SPSR)
262 1.2 matt return REGNO_ARM32_SPSR;
263 1.2 matt return LAST_REGISTER + 1;
264 1.2 matt }
265 1.2 matt
266 1.2 matt bool validRegister(int num) const {
267 1.2 matt return num >= 0 && num <= LAST_RESTORE_REG;
268 1.2 matt }
269 1.2 matt
270 1.2 matt uint64_t getRegister(int num) const {
271 1.2 matt assert(validRegister(num));
272 1.2 matt return reg[num];
273 1.2 matt }
274 1.2 matt
275 1.2 matt void setRegister(int num, uint64_t value) {
276 1.2 matt assert(validRegister(num));
277 1.2 matt reg[num] = value;
278 1.2 matt }
279 1.2 matt
280 1.2 matt uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
281 1.2 matt
282 1.2 matt void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
283 1.2 matt
284 1.2 matt uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
285 1.2 matt
286 1.2 matt void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
287 1.2 matt
288 1.2 matt bool validFloatVectorRegister(int num) const {
289 1.2 matt return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
290 1.2 matt }
291 1.2 matt
292 1.2 matt void copyFloatVectorRegister(int num, uint64_t addr_) {
293 1.2 matt const void *addr = reinterpret_cast<const void *>(addr_);
294 1.2 matt memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
295 1.2 matt }
296 1.2 matt
297 1.2 matt __dso_hidden void jumpto() const __dead;
298 1.2 matt
299 1.2 matt private:
300 1.2 matt uint32_t reg[REGNO_ARM32_SPSR + 1];
301 1.2 matt uint64_t fpreg[32];
302 1.2 matt };
303 1.2 matt
304 1.1 joerg } // namespace _Unwind
305 1.1 joerg
306 1.1 joerg #endif // __REGISTERS_HPP__
307