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