Registers.hpp revision 1.37 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.20 joerg #include <sys/endian.h>
16 1.1 joerg #include <cassert>
17 1.1 joerg #include <cstdint>
18 1.1 joerg
19 1.1 joerg namespace _Unwind {
20 1.1 joerg
21 1.1 joerg enum {
22 1.1 joerg REGNO_X86_EAX = 0,
23 1.1 joerg REGNO_X86_ECX = 1,
24 1.1 joerg REGNO_X86_EDX = 2,
25 1.1 joerg REGNO_X86_EBX = 3,
26 1.1 joerg REGNO_X86_ESP = 4,
27 1.1 joerg REGNO_X86_EBP = 5,
28 1.1 joerg REGNO_X86_ESI = 6,
29 1.1 joerg REGNO_X86_EDI = 7,
30 1.1 joerg REGNO_X86_EIP = 8,
31 1.1 joerg };
32 1.1 joerg
33 1.1 joerg class Registers_x86 {
34 1.1 joerg public:
35 1.1 joerg enum {
36 1.3 joerg LAST_REGISTER = REGNO_X86_EIP,
37 1.1 joerg LAST_RESTORE_REG = REGNO_X86_EIP,
38 1.10 joerg RETURN_OFFSET = 0,
39 1.19 joerg RETURN_MASK = 0,
40 1.1 joerg };
41 1.1 joerg
42 1.1 joerg __dso_hidden Registers_x86();
43 1.1 joerg
44 1.1 joerg static int dwarf2regno(int num) { return num; }
45 1.1 joerg
46 1.1 joerg bool validRegister(int num) const {
47 1.1 joerg return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
48 1.1 joerg }
49 1.1 joerg
50 1.1 joerg uint32_t getRegister(int num) const {
51 1.1 joerg assert(validRegister(num));
52 1.1 joerg return reg[num];
53 1.1 joerg }
54 1.1 joerg
55 1.1 joerg void setRegister(int num, uint32_t value) {
56 1.1 joerg assert(validRegister(num));
57 1.1 joerg reg[num] = value;
58 1.1 joerg }
59 1.1 joerg
60 1.1 joerg uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
61 1.1 joerg
62 1.1 joerg void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
63 1.1 joerg
64 1.1 joerg uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
65 1.1 joerg
66 1.1 joerg void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
67 1.1 joerg
68 1.1 joerg bool validFloatVectorRegister(int num) const { return false; }
69 1.1 joerg
70 1.1 joerg void copyFloatVectorRegister(int num, uint32_t addr) {
71 1.1 joerg }
72 1.1 joerg
73 1.1 joerg __dso_hidden void jumpto() const __dead;
74 1.1 joerg
75 1.1 joerg private:
76 1.1 joerg uint32_t reg[REGNO_X86_EIP + 1];
77 1.1 joerg };
78 1.1 joerg
79 1.1 joerg enum {
80 1.1 joerg REGNO_X86_64_RAX = 0,
81 1.1 joerg REGNO_X86_64_RDX = 1,
82 1.1 joerg REGNO_X86_64_RCX = 2,
83 1.1 joerg REGNO_X86_64_RBX = 3,
84 1.1 joerg REGNO_X86_64_RSI = 4,
85 1.1 joerg REGNO_X86_64_RDI = 5,
86 1.1 joerg REGNO_X86_64_RBP = 6,
87 1.1 joerg REGNO_X86_64_RSP = 7,
88 1.1 joerg REGNO_X86_64_R8 = 8,
89 1.1 joerg REGNO_X86_64_R9 = 9,
90 1.1 joerg REGNO_X86_64_R10 = 10,
91 1.1 joerg REGNO_X86_64_R11 = 11,
92 1.1 joerg REGNO_X86_64_R12 = 12,
93 1.1 joerg REGNO_X86_64_R13 = 13,
94 1.1 joerg REGNO_X86_64_R14 = 14,
95 1.1 joerg REGNO_X86_64_R15 = 15,
96 1.1 joerg REGNO_X86_64_RIP = 16,
97 1.1 joerg };
98 1.1 joerg
99 1.1 joerg class Registers_x86_64 {
100 1.1 joerg public:
101 1.1 joerg enum {
102 1.3 joerg LAST_REGISTER = REGNO_X86_64_RIP,
103 1.1 joerg LAST_RESTORE_REG = REGNO_X86_64_RIP,
104 1.10 joerg RETURN_OFFSET = 0,
105 1.19 joerg RETURN_MASK = 0,
106 1.1 joerg };
107 1.1 joerg
108 1.1 joerg __dso_hidden Registers_x86_64();
109 1.1 joerg
110 1.1 joerg static int dwarf2regno(int num) { return num; }
111 1.1 joerg
112 1.1 joerg bool validRegister(int num) const {
113 1.1 joerg return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
114 1.1 joerg }
115 1.1 joerg
116 1.1 joerg uint64_t getRegister(int num) const {
117 1.1 joerg assert(validRegister(num));
118 1.1 joerg return reg[num];
119 1.1 joerg }
120 1.1 joerg
121 1.1 joerg void setRegister(int num, uint64_t value) {
122 1.1 joerg assert(validRegister(num));
123 1.1 joerg reg[num] = value;
124 1.1 joerg }
125 1.1 joerg
126 1.1 joerg uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
127 1.1 joerg
128 1.1 joerg void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
129 1.1 joerg
130 1.1 joerg uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
131 1.1 joerg
132 1.1 joerg void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
133 1.1 joerg
134 1.1 joerg bool validFloatVectorRegister(int num) const { return false; }
135 1.1 joerg
136 1.1 joerg void copyFloatVectorRegister(int num, uint64_t addr) {
137 1.1 joerg }
138 1.1 joerg
139 1.1 joerg __dso_hidden void jumpto() const __dead;
140 1.1 joerg
141 1.1 joerg private:
142 1.1 joerg uint64_t reg[REGNO_X86_64_RIP + 1];
143 1.1 joerg };
144 1.1 joerg
145 1.1 joerg enum {
146 1.1 joerg DWARF_PPC32_R0 = 0,
147 1.1 joerg DWARF_PPC32_R31 = 31,
148 1.1 joerg DWARF_PPC32_F0 = 32,
149 1.1 joerg DWARF_PPC32_F31 = 63,
150 1.1 joerg DWARF_PPC32_LR = 65,
151 1.33 thorpej DWARF_PPC32_CTR = 66,
152 1.4 joerg DWARF_PPC32_CR = 70,
153 1.33 thorpej DWARF_PPC32_XER = 76,
154 1.4 joerg DWARF_PPC32_V0 = 77,
155 1.33 thorpej DWARF_PPC32_SIGRETURN = 99,
156 1.4 joerg DWARF_PPC32_V31 = 108,
157 1.4 joerg
158 1.1 joerg REGNO_PPC32_R0 = 0,
159 1.4 joerg REGNO_PPC32_R1 = 1,
160 1.1 joerg REGNO_PPC32_R31 = 31,
161 1.4 joerg REGNO_PPC32_LR = 32,
162 1.4 joerg REGNO_PPC32_CR = 33,
163 1.4 joerg REGNO_PPC32_SRR0 = 34,
164 1.4 joerg
165 1.1 joerg REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
166 1.1 joerg REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
167 1.1 joerg REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
168 1.1 joerg REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
169 1.33 thorpej
170 1.33 thorpej REGNO_PPC32_CTR = REGNO_PPC32_V31 + 1,
171 1.33 thorpej REGNO_PPC32_XER = REGNO_PPC32_CTR + 1,
172 1.33 thorpej REGNO_PPC32_SIGRETURN = REGNO_PPC32_XER + 1
173 1.1 joerg };
174 1.1 joerg
175 1.1 joerg class Registers_ppc32 {
176 1.1 joerg public:
177 1.1 joerg enum {
178 1.33 thorpej LAST_REGISTER = REGNO_PPC32_SIGRETURN,
179 1.33 thorpej LAST_RESTORE_REG = REGNO_PPC32_SIGRETURN,
180 1.10 joerg RETURN_OFFSET = 0,
181 1.19 joerg RETURN_MASK = 0,
182 1.1 joerg };
183 1.1 joerg
184 1.1 joerg __dso_hidden Registers_ppc32();
185 1.1 joerg
186 1.1 joerg static int dwarf2regno(int num) {
187 1.1 joerg if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
188 1.1 joerg return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
189 1.1 joerg if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
190 1.1 joerg return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
191 1.1 joerg if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
192 1.1 joerg return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
193 1.4 joerg switch (num) {
194 1.4 joerg case DWARF_PPC32_LR:
195 1.4 joerg return REGNO_PPC32_LR;
196 1.4 joerg case DWARF_PPC32_CR:
197 1.4 joerg return REGNO_PPC32_CR;
198 1.33 thorpej case DWARF_PPC32_CTR:
199 1.33 thorpej return REGNO_PPC32_CTR;
200 1.33 thorpej case DWARF_PPC32_XER:
201 1.33 thorpej return REGNO_PPC32_XER;
202 1.33 thorpej case DWARF_PPC32_SIGRETURN:
203 1.33 thorpej return REGNO_PPC32_SIGRETURN;
204 1.4 joerg default:
205 1.4 joerg return LAST_REGISTER + 1;
206 1.4 joerg }
207 1.1 joerg }
208 1.1 joerg
209 1.1 joerg bool validRegister(int num) const {
210 1.33 thorpej return (num >= 0 && num <= REGNO_PPC32_SRR0) ||
211 1.33 thorpej (num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN);
212 1.1 joerg }
213 1.1 joerg
214 1.1 joerg uint64_t getRegister(int num) const {
215 1.1 joerg assert(validRegister(num));
216 1.33 thorpej switch (num) {
217 1.33 thorpej case REGNO_PPC32_CTR:
218 1.33 thorpej return ctr_reg;
219 1.33 thorpej case REGNO_PPC32_XER:
220 1.33 thorpej return xer_reg;
221 1.33 thorpej case REGNO_PPC32_SIGRETURN:
222 1.33 thorpej return sigreturn_reg;
223 1.33 thorpej default:
224 1.33 thorpej return reg[num];
225 1.33 thorpej }
226 1.1 joerg }
227 1.1 joerg
228 1.1 joerg void setRegister(int num, uint64_t value) {
229 1.1 joerg assert(validRegister(num));
230 1.33 thorpej switch (num) {
231 1.33 thorpej case REGNO_PPC32_CTR:
232 1.33 thorpej ctr_reg = value;
233 1.33 thorpej break;
234 1.33 thorpej case REGNO_PPC32_XER:
235 1.33 thorpej xer_reg = value;
236 1.33 thorpej break;
237 1.33 thorpej case REGNO_PPC32_SIGRETURN:
238 1.33 thorpej sigreturn_reg = value;
239 1.33 thorpej break;
240 1.33 thorpej default:
241 1.33 thorpej reg[num] = value;
242 1.33 thorpej }
243 1.1 joerg }
244 1.1 joerg
245 1.1 joerg uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
246 1.1 joerg
247 1.1 joerg void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
248 1.1 joerg
249 1.1 joerg uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
250 1.1 joerg
251 1.1 joerg void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
252 1.1 joerg
253 1.1 joerg bool validFloatVectorRegister(int num) const {
254 1.1 joerg return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
255 1.1 joerg (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
256 1.1 joerg }
257 1.1 joerg
258 1.1 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
259 1.1 joerg const void *addr = reinterpret_cast<const void *>(addr_);
260 1.1 joerg if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
261 1.1 joerg memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
262 1.1 joerg else
263 1.1 joerg memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
264 1.1 joerg }
265 1.1 joerg
266 1.1 joerg __dso_hidden void jumpto() const __dead;
267 1.1 joerg
268 1.1 joerg private:
269 1.1 joerg struct vecreg_t {
270 1.1 joerg uint64_t low, high;
271 1.1 joerg };
272 1.1 joerg uint32_t reg[REGNO_PPC32_SRR0 + 1];
273 1.4 joerg uint32_t dummy;
274 1.1 joerg uint64_t fpreg[32];
275 1.1 joerg vecreg_t vecreg[64];
276 1.33 thorpej uint32_t ctr_reg;
277 1.33 thorpej uint32_t xer_reg;
278 1.33 thorpej uint32_t sigreturn_reg;
279 1.1 joerg };
280 1.1 joerg
281 1.2 matt enum {
282 1.17 matt DWARF_AARCH64_X0 = 0,
283 1.17 matt DWARF_AARCH64_X30 = 30,
284 1.17 matt DWARF_AARCH64_SP = 31,
285 1.17 matt DWARF_AARCH64_V0 = 64,
286 1.17 matt DWARF_AARCH64_V31 = 95,
287 1.35 thorpej DWARF_AARCH64_SIGRETURN = 96,
288 1.17 matt
289 1.17 matt REGNO_AARCH64_X0 = 0,
290 1.17 matt REGNO_AARCH64_X30 = 30,
291 1.17 matt REGNO_AARCH64_SP = 31,
292 1.21 joerg REGNO_AARCH64_V0 = 32,
293 1.21 joerg REGNO_AARCH64_V31 = 63,
294 1.35 thorpej REGNO_AARCH64_SIGRETURN = 64,
295 1.17 matt };
296 1.17 matt
297 1.17 matt class Registers_aarch64 {
298 1.17 matt public:
299 1.17 matt enum {
300 1.35 thorpej LAST_RESTORE_REG = REGNO_AARCH64_SIGRETURN,
301 1.35 thorpej LAST_REGISTER = REGNO_AARCH64_SIGRETURN,
302 1.17 matt RETURN_OFFSET = 0,
303 1.19 joerg RETURN_MASK = 0,
304 1.17 matt };
305 1.17 matt
306 1.17 matt __dso_hidden Registers_aarch64();
307 1.17 matt
308 1.17 matt static int dwarf2regno(int num) {
309 1.17 matt if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
310 1.17 matt return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
311 1.17 matt if (num == DWARF_AARCH64_SP)
312 1.17 matt return REGNO_AARCH64_SP;
313 1.17 matt if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
314 1.17 matt return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
315 1.35 thorpej if (num == DWARF_AARCH64_SIGRETURN)
316 1.35 thorpej return REGNO_AARCH64_SIGRETURN;
317 1.17 matt return LAST_REGISTER + 1;
318 1.17 matt }
319 1.17 matt
320 1.17 matt bool validRegister(int num) const {
321 1.35 thorpej return (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_SP) ||
322 1.35 thorpej num == DWARF_AARCH64_SIGRETURN;
323 1.17 matt }
324 1.17 matt
325 1.17 matt uint64_t getRegister(int num) const {
326 1.17 matt assert(validRegister(num));
327 1.36 thorpej if (num == REGNO_AARCH64_SIGRETURN)
328 1.35 thorpej return sigreturn_reg;
329 1.17 matt return reg[num];
330 1.17 matt }
331 1.17 matt
332 1.17 matt void setRegister(int num, uint64_t value) {
333 1.17 matt assert(validRegister(num));
334 1.36 thorpej if (num == REGNO_AARCH64_SIGRETURN)
335 1.35 thorpej sigreturn_reg = value;
336 1.35 thorpej else
337 1.35 thorpej reg[num] = value;
338 1.17 matt }
339 1.17 matt
340 1.17 matt uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
341 1.17 matt
342 1.17 matt void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
343 1.17 matt
344 1.17 matt uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
345 1.17 matt
346 1.17 matt void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
347 1.17 matt
348 1.17 matt bool validFloatVectorRegister(int num) const {
349 1.17 matt return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
350 1.17 matt }
351 1.17 matt
352 1.17 matt void copyFloatVectorRegister(int num, uint64_t addr_) {
353 1.17 matt const void *addr = reinterpret_cast<const void *>(addr_);
354 1.21 joerg memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16);
355 1.17 matt }
356 1.17 matt
357 1.17 matt __dso_hidden void jumpto() const __dead;
358 1.17 matt
359 1.17 matt private:
360 1.21 joerg uint64_t reg[REGNO_AARCH64_SP + 1];
361 1.21 joerg uint64_t vecreg[64];
362 1.35 thorpej uint64_t sigreturn_reg;
363 1.17 matt };
364 1.17 matt
365 1.17 matt enum {
366 1.2 matt DWARF_ARM32_R0 = 0,
367 1.2 matt DWARF_ARM32_R15 = 15,
368 1.2 matt DWARF_ARM32_SPSR = 128,
369 1.20 joerg DWARF_ARM32_S0 = 64,
370 1.24 rin DWARF_ARM32_S31 = 95,
371 1.16 joerg DWARF_ARM32_D0 = 256,
372 1.2 matt DWARF_ARM32_D31 = 287,
373 1.2 matt REGNO_ARM32_R0 = 0,
374 1.2 matt REGNO_ARM32_SP = 13,
375 1.2 matt REGNO_ARM32_R15 = 15,
376 1.2 matt REGNO_ARM32_SPSR = 16,
377 1.16 joerg REGNO_ARM32_D0 = 17,
378 1.16 joerg REGNO_ARM32_D15 = 32,
379 1.16 joerg REGNO_ARM32_D31 = 48,
380 1.20 joerg REGNO_ARM32_S0 = 49,
381 1.24 rin REGNO_ARM32_S31 = 80,
382 1.2 matt };
383 1.2 matt
384 1.28 rin #define FLAGS_VFPV2_USED 0x1
385 1.28 rin #define FLAGS_VFPV3_USED 0x2
386 1.28 rin #define FLAGS_LEGACY_VFPV2_REGNO 0x4
387 1.28 rin #define FLAGS_EXTENDED_VFPV2_REGNO 0x8
388 1.28 rin
389 1.2 matt class Registers_arm32 {
390 1.2 matt public:
391 1.2 matt enum {
392 1.27 rin LAST_REGISTER = REGNO_ARM32_S31,
393 1.27 rin LAST_RESTORE_REG = REGNO_ARM32_S31,
394 1.10 joerg RETURN_OFFSET = 0,
395 1.19 joerg RETURN_MASK = 0,
396 1.2 matt };
397 1.2 matt
398 1.2 matt __dso_hidden Registers_arm32();
399 1.2 matt
400 1.2 matt static int dwarf2regno(int num) {
401 1.2 matt if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
402 1.2 matt return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
403 1.16 joerg if (num == DWARF_ARM32_SPSR)
404 1.16 joerg return REGNO_ARM32_SPSR;
405 1.2 matt if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
406 1.2 matt return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
407 1.22 rin if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31)
408 1.20 joerg return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
409 1.2 matt return LAST_REGISTER + 1;
410 1.2 matt }
411 1.2 matt
412 1.2 matt bool validRegister(int num) const {
413 1.16 joerg return num >= 0 && num <= REGNO_ARM32_SPSR;
414 1.2 matt }
415 1.2 matt
416 1.2 matt uint64_t getRegister(int num) const {
417 1.2 matt assert(validRegister(num));
418 1.2 matt return reg[num];
419 1.2 matt }
420 1.2 matt
421 1.2 matt void setRegister(int num, uint64_t value) {
422 1.2 matt assert(validRegister(num));
423 1.2 matt reg[num] = value;
424 1.2 matt }
425 1.2 matt
426 1.2 matt uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
427 1.2 matt
428 1.2 matt void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
429 1.2 matt
430 1.2 matt uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
431 1.2 matt
432 1.2 matt void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
433 1.2 matt
434 1.2 matt bool validFloatVectorRegister(int num) const {
435 1.20 joerg return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
436 1.2 matt }
437 1.2 matt
438 1.2 matt void copyFloatVectorRegister(int num, uint64_t addr_) {
439 1.23 rin assert(validFloatVectorRegister(num));
440 1.20 joerg const void *addr = reinterpret_cast<const void *>(addr_);
441 1.20 joerg if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
442 1.27 rin /*
443 1.27 rin * XXX
444 1.27 rin * There are two numbering schemes for VFPv2 registers: s0-s31
445 1.27 rin * (used by GCC) and d0-d15 (used by LLVM). We won't support both
446 1.27 rin * schemes simultaneously in a same frame.
447 1.27 rin */
448 1.27 rin assert((flags & FLAGS_EXTENDED_VFPV2_REGNO) == 0);
449 1.27 rin flags |= FLAGS_LEGACY_VFPV2_REGNO;
450 1.22 rin if ((flags & FLAGS_VFPV2_USED) == 0) {
451 1.22 rin lazyVFPv2();
452 1.22 rin flags |= FLAGS_VFPV2_USED;
453 1.20 joerg }
454 1.20 joerg /*
455 1.20 joerg * Emulate single precision register as half of the
456 1.20 joerg * corresponding double register.
457 1.20 joerg */
458 1.20 joerg int dnum = (num - REGNO_ARM32_S0) / 2;
459 1.20 joerg int part = (num - REGNO_ARM32_S0) % 2;
460 1.20 joerg #if _BYTE_ORDER == _BIG_ENDIAN
461 1.20 joerg part = 1 - part;
462 1.20 joerg #endif
463 1.25 rin memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2,
464 1.20 joerg addr, sizeof(fpreg[0]) / 2);
465 1.16 joerg } else {
466 1.26 rin if (num <= REGNO_ARM32_D15) {
467 1.27 rin /*
468 1.27 rin * XXX
469 1.27 rin * See XXX comment above.
470 1.27 rin */
471 1.27 rin assert((flags & FLAGS_LEGACY_VFPV2_REGNO) == 0);
472 1.27 rin flags |= FLAGS_EXTENDED_VFPV2_REGNO;
473 1.26 rin if ((flags & FLAGS_VFPV2_USED) == 0) {
474 1.26 rin lazyVFPv2();
475 1.26 rin flags |= FLAGS_VFPV2_USED;
476 1.26 rin }
477 1.26 rin } else {
478 1.26 rin if ((flags & FLAGS_VFPV3_USED) == 0) {
479 1.26 rin lazyVFPv3();
480 1.26 rin flags |= FLAGS_VFPV3_USED;
481 1.26 rin }
482 1.16 joerg }
483 1.26 rin memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
484 1.16 joerg }
485 1.2 matt }
486 1.2 matt
487 1.22 rin __dso_hidden void lazyVFPv2();
488 1.22 rin __dso_hidden void lazyVFPv3();
489 1.2 matt __dso_hidden void jumpto() const __dead;
490 1.2 matt
491 1.2 matt private:
492 1.2 matt uint32_t reg[REGNO_ARM32_SPSR + 1];
493 1.16 joerg uint32_t flags;
494 1.2 matt uint64_t fpreg[32];
495 1.28 rin };
496 1.22 rin
497 1.28 rin #undef FLAGS_VFPV2_USED
498 1.28 rin #undef FLAGS_VFPV3_USED
499 1.28 rin #undef FLAGS_LEGACY_VFPV2_REGNO
500 1.28 rin #undef FLAGS_EXTENDED_VFPV2_REGNO
501 1.2 matt
502 1.5 joerg enum {
503 1.5 joerg DWARF_VAX_R0 = 0,
504 1.5 joerg DWARF_VAX_R15 = 15,
505 1.5 joerg DWARF_VAX_PSW = 16,
506 1.5 joerg
507 1.5 joerg REGNO_VAX_R0 = 0,
508 1.5 joerg REGNO_VAX_R14 = 14,
509 1.5 joerg REGNO_VAX_R15 = 15,
510 1.5 joerg REGNO_VAX_PSW = 16,
511 1.5 joerg };
512 1.5 joerg
513 1.5 joerg class Registers_vax {
514 1.5 joerg public:
515 1.5 joerg enum {
516 1.5 joerg LAST_REGISTER = REGNO_VAX_PSW,
517 1.5 joerg LAST_RESTORE_REG = REGNO_VAX_PSW,
518 1.10 joerg RETURN_OFFSET = 0,
519 1.19 joerg RETURN_MASK = 0,
520 1.5 joerg };
521 1.5 joerg
522 1.5 joerg __dso_hidden Registers_vax();
523 1.5 joerg
524 1.5 joerg static int dwarf2regno(int num) {
525 1.5 joerg if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
526 1.5 joerg return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
527 1.5 joerg if (num == DWARF_VAX_PSW)
528 1.5 joerg return REGNO_VAX_PSW;
529 1.5 joerg return LAST_REGISTER + 1;
530 1.5 joerg }
531 1.5 joerg
532 1.5 joerg bool validRegister(int num) const {
533 1.5 joerg return num >= 0 && num <= LAST_RESTORE_REG;
534 1.5 joerg }
535 1.5 joerg
536 1.5 joerg uint64_t getRegister(int num) const {
537 1.5 joerg assert(validRegister(num));
538 1.5 joerg return reg[num];
539 1.5 joerg }
540 1.5 joerg
541 1.5 joerg void setRegister(int num, uint64_t value) {
542 1.5 joerg assert(validRegister(num));
543 1.5 joerg reg[num] = value;
544 1.5 joerg }
545 1.5 joerg
546 1.5 joerg uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
547 1.5 joerg
548 1.5 joerg void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
549 1.5 joerg
550 1.5 joerg uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
551 1.5 joerg
552 1.5 joerg void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
553 1.5 joerg
554 1.5 joerg bool validFloatVectorRegister(int num) const {
555 1.5 joerg return false;
556 1.5 joerg }
557 1.5 joerg
558 1.5 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
559 1.5 joerg }
560 1.5 joerg
561 1.5 joerg __dso_hidden void jumpto() const __dead;
562 1.5 joerg
563 1.5 joerg private:
564 1.5 joerg uint32_t reg[REGNO_VAX_PSW + 1];
565 1.5 joerg };
566 1.5 joerg
567 1.6 joerg enum {
568 1.6 joerg DWARF_M68K_A0 = 0,
569 1.6 joerg DWARF_M68K_A7 = 7,
570 1.6 joerg DWARF_M68K_D0 = 8,
571 1.6 joerg DWARF_M68K_D7 = 15,
572 1.7 joerg DWARF_M68K_FP0 = 16,
573 1.7 joerg DWARF_M68K_FP7 = 23,
574 1.6 joerg DWARF_M68K_PC = 24,
575 1.34 thorpej // DWARF pseudo-register that is an alternate that may be used
576 1.34 thorpej // for the return address.
577 1.34 thorpej DWARF_M68K_ALT_PC = 25,
578 1.6 joerg
579 1.6 joerg REGNO_M68K_A0 = 0,
580 1.6 joerg REGNO_M68K_A7 = 7,
581 1.6 joerg REGNO_M68K_D0 = 8,
582 1.6 joerg REGNO_M68K_D7 = 15,
583 1.6 joerg REGNO_M68K_PC = 16,
584 1.7 joerg REGNO_M68K_FP0 = 17,
585 1.7 joerg REGNO_M68K_FP7 = 24,
586 1.6 joerg };
587 1.6 joerg
588 1.6 joerg class Registers_M68K {
589 1.6 joerg public:
590 1.6 joerg enum {
591 1.7 joerg LAST_REGISTER = REGNO_M68K_FP7,
592 1.7 joerg LAST_RESTORE_REG = REGNO_M68K_FP7,
593 1.10 joerg RETURN_OFFSET = 0,
594 1.19 joerg RETURN_MASK = 0,
595 1.6 joerg };
596 1.6 joerg
597 1.6 joerg __dso_hidden Registers_M68K();
598 1.6 joerg
599 1.6 joerg static int dwarf2regno(int num) {
600 1.6 joerg if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
601 1.6 joerg return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
602 1.6 joerg if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
603 1.6 joerg return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
604 1.7 joerg if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
605 1.7 joerg return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
606 1.34 thorpej if (num == DWARF_M68K_PC || num == DWARF_M68K_ALT_PC)
607 1.6 joerg return REGNO_M68K_PC;
608 1.6 joerg return LAST_REGISTER + 1;
609 1.6 joerg }
610 1.6 joerg
611 1.6 joerg bool validRegister(int num) const {
612 1.7 joerg return num >= 0 && num <= REGNO_M68K_PC;
613 1.6 joerg }
614 1.6 joerg
615 1.6 joerg uint64_t getRegister(int num) const {
616 1.6 joerg assert(validRegister(num));
617 1.6 joerg return reg[num];
618 1.6 joerg }
619 1.6 joerg
620 1.6 joerg void setRegister(int num, uint64_t value) {
621 1.6 joerg assert(validRegister(num));
622 1.6 joerg reg[num] = value;
623 1.6 joerg }
624 1.6 joerg
625 1.6 joerg uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
626 1.6 joerg
627 1.6 joerg void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
628 1.6 joerg
629 1.6 joerg uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
630 1.6 joerg
631 1.6 joerg void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
632 1.6 joerg
633 1.6 joerg bool validFloatVectorRegister(int num) const {
634 1.7 joerg return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
635 1.6 joerg }
636 1.6 joerg
637 1.6 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
638 1.7 joerg assert(validFloatVectorRegister(num));
639 1.7 joerg const void *addr = reinterpret_cast<const void *>(addr_);
640 1.7 joerg memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
641 1.6 joerg }
642 1.6 joerg
643 1.6 joerg __dso_hidden void jumpto() const __dead;
644 1.6 joerg
645 1.6 joerg private:
646 1.7 joerg typedef uint32_t fpreg_t[3];
647 1.7 joerg
648 1.6 joerg uint32_t reg[REGNO_M68K_PC + 1];
649 1.7 joerg uint32_t dummy;
650 1.7 joerg fpreg_t fpreg[8];
651 1.6 joerg };
652 1.6 joerg
653 1.8 joerg enum {
654 1.8 joerg DWARF_SH3_R0 = 0,
655 1.8 joerg DWARF_SH3_R15 = 15,
656 1.8 joerg DWARF_SH3_PC = 16,
657 1.8 joerg DWARF_SH3_PR = 17,
658 1.37 thorpej DWARF_SH3_GBR = 18,
659 1.37 thorpej DWARF_SH3_MACH = 20,
660 1.37 thorpej DWARF_SH3_MACL = 21,
661 1.37 thorpej DWARF_SH3_SR = 22,
662 1.8 joerg
663 1.8 joerg REGNO_SH3_R0 = 0,
664 1.8 joerg REGNO_SH3_R15 = 15,
665 1.8 joerg REGNO_SH3_PC = 16,
666 1.8 joerg REGNO_SH3_PR = 17,
667 1.37 thorpej REGNO_SH3_GBR = 18,
668 1.37 thorpej REGNO_SH3_MACH = 20,
669 1.37 thorpej REGNO_SH3_MACL = 21,
670 1.37 thorpej REGNO_SH3_SR = 22,
671 1.8 joerg };
672 1.8 joerg
673 1.8 joerg class Registers_SH3 {
674 1.8 joerg public:
675 1.8 joerg enum {
676 1.37 thorpej LAST_REGISTER = REGNO_SH3_SR,
677 1.37 thorpej LAST_RESTORE_REG = REGNO_SH3_SR,
678 1.10 joerg RETURN_OFFSET = 0,
679 1.19 joerg RETURN_MASK = 0,
680 1.8 joerg };
681 1.8 joerg
682 1.8 joerg __dso_hidden Registers_SH3();
683 1.8 joerg
684 1.8 joerg static int dwarf2regno(int num) {
685 1.8 joerg if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
686 1.8 joerg return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
687 1.37 thorpej switch (num) {
688 1.37 thorpej case DWARF_SH3_PC:
689 1.8 joerg return REGNO_SH3_PC;
690 1.37 thorpej case DWARF_SH3_PR:
691 1.8 joerg return REGNO_SH3_PR;
692 1.37 thorpej case DWARF_SH3_GBR:
693 1.37 thorpej return REGNO_SH3_GBR;
694 1.37 thorpej case DWARF_SH3_MACH:
695 1.37 thorpej return REGNO_SH3_MACH;
696 1.37 thorpej case DWARF_SH3_MACL:
697 1.37 thorpej return REGNO_SH3_MACL;
698 1.37 thorpej case DWARF_SH3_SR:
699 1.37 thorpej return REGNO_SH3_SR;
700 1.37 thorpej default:
701 1.37 thorpej return LAST_REGISTER + 1;
702 1.37 thorpej }
703 1.8 joerg }
704 1.8 joerg
705 1.8 joerg bool validRegister(int num) const {
706 1.37 thorpej return (num >= 0 && num <= REGNO_SH3_GBR) ||
707 1.37 thorpej (num >= REGNO_SH3_MACH && num <= REGNO_SH3_SR);
708 1.8 joerg }
709 1.8 joerg
710 1.8 joerg uint64_t getRegister(int num) const {
711 1.8 joerg assert(validRegister(num));
712 1.8 joerg return reg[num];
713 1.8 joerg }
714 1.8 joerg
715 1.8 joerg void setRegister(int num, uint64_t value) {
716 1.8 joerg assert(validRegister(num));
717 1.8 joerg reg[num] = value;
718 1.8 joerg }
719 1.8 joerg
720 1.8 joerg uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
721 1.8 joerg
722 1.8 joerg void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
723 1.8 joerg
724 1.8 joerg uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
725 1.8 joerg
726 1.8 joerg void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
727 1.8 joerg
728 1.8 joerg bool validFloatVectorRegister(int num) const { return false; }
729 1.8 joerg
730 1.8 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {}
731 1.8 joerg
732 1.8 joerg __dso_hidden void jumpto() const __dead;
733 1.8 joerg
734 1.8 joerg private:
735 1.37 thorpej uint32_t reg[REGNO_SH3_SR + 1];
736 1.8 joerg };
737 1.8 joerg
738 1.11 joerg enum {
739 1.11 joerg DWARF_SPARC64_R0 = 0,
740 1.11 joerg DWARF_SPARC64_R31 = 31,
741 1.11 joerg DWARF_SPARC64_PC = 32,
742 1.11 joerg
743 1.11 joerg REGNO_SPARC64_R0 = 0,
744 1.11 joerg REGNO_SPARC64_R14 = 14,
745 1.11 joerg REGNO_SPARC64_R15 = 15,
746 1.11 joerg REGNO_SPARC64_R31 = 31,
747 1.11 joerg REGNO_SPARC64_PC = 32,
748 1.11 joerg };
749 1.11 joerg
750 1.11 joerg class Registers_SPARC64 {
751 1.11 joerg public:
752 1.11 joerg enum {
753 1.11 joerg LAST_REGISTER = REGNO_SPARC64_PC,
754 1.11 joerg LAST_RESTORE_REG = REGNO_SPARC64_PC,
755 1.11 joerg RETURN_OFFSET = 8,
756 1.19 joerg RETURN_MASK = 0,
757 1.11 joerg };
758 1.11 joerg typedef uint64_t reg_t;
759 1.11 joerg
760 1.11 joerg __dso_hidden Registers_SPARC64();
761 1.11 joerg
762 1.11 joerg static int dwarf2regno(int num) {
763 1.11 joerg if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
764 1.11 joerg return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
765 1.11 joerg if (num == DWARF_SPARC64_PC)
766 1.11 joerg return REGNO_SPARC64_PC;
767 1.11 joerg return LAST_REGISTER + 1;
768 1.11 joerg }
769 1.11 joerg
770 1.11 joerg bool validRegister(int num) const {
771 1.11 joerg return num >= 0 && num <= REGNO_SPARC64_PC;
772 1.11 joerg }
773 1.11 joerg
774 1.11 joerg uint64_t getRegister(int num) const {
775 1.11 joerg assert(validRegister(num));
776 1.11 joerg return reg[num];
777 1.11 joerg }
778 1.11 joerg
779 1.11 joerg void setRegister(int num, uint64_t value) {
780 1.11 joerg assert(validRegister(num));
781 1.11 joerg reg[num] = value;
782 1.11 joerg }
783 1.11 joerg
784 1.11 joerg uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
785 1.11 joerg
786 1.11 joerg void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
787 1.11 joerg
788 1.11 joerg uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
789 1.11 joerg
790 1.11 joerg void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
791 1.11 joerg
792 1.11 joerg bool validFloatVectorRegister(int num) const { return false; }
793 1.11 joerg
794 1.11 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {}
795 1.11 joerg
796 1.11 joerg __dso_hidden void jumpto() const __dead;
797 1.11 joerg
798 1.11 joerg private:
799 1.11 joerg uint64_t reg[REGNO_SPARC64_PC + 1];
800 1.11 joerg };
801 1.11 joerg
802 1.11 joerg enum {
803 1.11 joerg DWARF_SPARC_R0 = 0,
804 1.11 joerg DWARF_SPARC_R31 = 31,
805 1.11 joerg DWARF_SPARC_PC = 32,
806 1.11 joerg
807 1.11 joerg REGNO_SPARC_R0 = 0,
808 1.11 joerg REGNO_SPARC_R14 = 14,
809 1.11 joerg REGNO_SPARC_R15 = 15,
810 1.11 joerg REGNO_SPARC_R31 = 31,
811 1.11 joerg REGNO_SPARC_PC = 32,
812 1.11 joerg };
813 1.11 joerg
814 1.11 joerg class Registers_SPARC {
815 1.11 joerg public:
816 1.11 joerg enum {
817 1.11 joerg LAST_REGISTER = REGNO_SPARC_PC,
818 1.11 joerg LAST_RESTORE_REG = REGNO_SPARC_PC,
819 1.11 joerg RETURN_OFFSET = 8,
820 1.19 joerg RETURN_MASK = 0,
821 1.11 joerg };
822 1.11 joerg typedef uint32_t reg_t;
823 1.11 joerg
824 1.11 joerg __dso_hidden Registers_SPARC();
825 1.11 joerg
826 1.11 joerg static int dwarf2regno(int num) {
827 1.11 joerg if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
828 1.11 joerg return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
829 1.11 joerg if (num == DWARF_SPARC_PC)
830 1.11 joerg return REGNO_SPARC_PC;
831 1.11 joerg return LAST_REGISTER + 1;
832 1.11 joerg }
833 1.11 joerg
834 1.11 joerg bool validRegister(int num) const {
835 1.11 joerg return num >= 0 && num <= REGNO_SPARC_PC;
836 1.11 joerg }
837 1.11 joerg
838 1.11 joerg uint64_t getRegister(int num) const {
839 1.11 joerg assert(validRegister(num));
840 1.11 joerg return reg[num];
841 1.11 joerg }
842 1.11 joerg
843 1.11 joerg void setRegister(int num, uint64_t value) {
844 1.11 joerg assert(validRegister(num));
845 1.11 joerg reg[num] = value;
846 1.11 joerg }
847 1.11 joerg
848 1.11 joerg uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
849 1.11 joerg
850 1.11 joerg void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
851 1.11 joerg
852 1.11 joerg uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
853 1.11 joerg
854 1.11 joerg void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
855 1.11 joerg
856 1.11 joerg bool validFloatVectorRegister(int num) const { return false; }
857 1.11 joerg
858 1.11 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {}
859 1.11 joerg
860 1.11 joerg __dso_hidden void jumpto() const __dead;
861 1.11 joerg
862 1.11 joerg private:
863 1.11 joerg uint32_t reg[REGNO_SPARC_PC + 1];
864 1.11 joerg };
865 1.11 joerg
866 1.12 joerg enum {
867 1.12 joerg DWARF_ALPHA_R0 = 0,
868 1.12 joerg DWARF_ALPHA_R30 = 30,
869 1.12 joerg DWARF_ALPHA_F0 = 32,
870 1.12 joerg DWARF_ALPHA_F30 = 62,
871 1.31 thorpej DWARF_ALPHA_SIGRETURN = 64,
872 1.12 joerg
873 1.12 joerg REGNO_ALPHA_R0 = 0,
874 1.12 joerg REGNO_ALPHA_R26 = 26,
875 1.12 joerg REGNO_ALPHA_R30 = 30,
876 1.12 joerg REGNO_ALPHA_PC = 31,
877 1.12 joerg REGNO_ALPHA_F0 = 32,
878 1.12 joerg REGNO_ALPHA_F30 = 62,
879 1.31 thorpej REGNO_ALPHA_SIGRETURN = 64,
880 1.12 joerg };
881 1.12 joerg
882 1.12 joerg class Registers_Alpha {
883 1.12 joerg public:
884 1.12 joerg enum {
885 1.31 thorpej LAST_REGISTER = REGNO_ALPHA_SIGRETURN,
886 1.31 thorpej LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN,
887 1.12 joerg RETURN_OFFSET = 0,
888 1.19 joerg RETURN_MASK = 0,
889 1.12 joerg };
890 1.12 joerg typedef uint32_t reg_t;
891 1.12 joerg
892 1.12 joerg __dso_hidden Registers_Alpha();
893 1.12 joerg
894 1.12 joerg static int dwarf2regno(int num) { return num; }
895 1.12 joerg
896 1.12 joerg bool validRegister(int num) const {
897 1.31 thorpej return (num >= 0 && num <= REGNO_ALPHA_PC) ||
898 1.31 thorpej num == REGNO_ALPHA_SIGRETURN;
899 1.12 joerg }
900 1.12 joerg
901 1.12 joerg uint64_t getRegister(int num) const {
902 1.12 joerg assert(validRegister(num));
903 1.31 thorpej if (num == REGNO_ALPHA_SIGRETURN)
904 1.31 thorpej return sigreturn_reg;
905 1.31 thorpej else
906 1.31 thorpej return reg[num];
907 1.12 joerg }
908 1.12 joerg
909 1.12 joerg void setRegister(int num, uint64_t value) {
910 1.12 joerg assert(validRegister(num));
911 1.31 thorpej if (num == REGNO_ALPHA_SIGRETURN)
912 1.31 thorpej sigreturn_reg = value;
913 1.31 thorpej else
914 1.31 thorpej reg[num] = value;
915 1.12 joerg }
916 1.12 joerg
917 1.12 joerg uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
918 1.12 joerg
919 1.12 joerg void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
920 1.12 joerg
921 1.12 joerg uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
922 1.12 joerg
923 1.12 joerg void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
924 1.12 joerg
925 1.12 joerg bool validFloatVectorRegister(int num) const {
926 1.12 joerg return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
927 1.12 joerg }
928 1.12 joerg
929 1.12 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
930 1.12 joerg assert(validFloatVectorRegister(num));
931 1.12 joerg const void *addr = reinterpret_cast<const void *>(addr_);
932 1.12 joerg memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
933 1.12 joerg }
934 1.12 joerg
935 1.12 joerg __dso_hidden void jumpto() const __dead;
936 1.12 joerg
937 1.12 joerg private:
938 1.12 joerg uint64_t reg[REGNO_ALPHA_PC + 1];
939 1.12 joerg uint64_t fpreg[31];
940 1.31 thorpej uint64_t sigreturn_reg;
941 1.12 joerg };
942 1.12 joerg
943 1.13 joerg enum {
944 1.13 joerg DWARF_HPPA_R1 = 1,
945 1.13 joerg DWARF_HPPA_R31 = 31,
946 1.13 joerg DWARF_HPPA_FR4L = 32,
947 1.13 joerg DWARF_HPPA_FR31H = 87,
948 1.13 joerg
949 1.13 joerg REGNO_HPPA_PC = 0,
950 1.13 joerg REGNO_HPPA_R1 = 1,
951 1.13 joerg REGNO_HPPA_R2 = 2,
952 1.13 joerg REGNO_HPPA_R30 = 30,
953 1.13 joerg REGNO_HPPA_R31 = 31,
954 1.13 joerg REGNO_HPPA_FR4L = 32,
955 1.13 joerg REGNO_HPPA_FR31H = 87,
956 1.13 joerg };
957 1.13 joerg
958 1.13 joerg class Registers_HPPA {
959 1.13 joerg public:
960 1.13 joerg enum {
961 1.13 joerg LAST_REGISTER = REGNO_HPPA_FR31H,
962 1.13 joerg LAST_RESTORE_REG = REGNO_HPPA_FR31H,
963 1.19 joerg RETURN_OFFSET = 0,
964 1.19 joerg RETURN_MASK = 3,
965 1.13 joerg };
966 1.13 joerg
967 1.13 joerg __dso_hidden Registers_HPPA();
968 1.13 joerg
969 1.13 joerg static int dwarf2regno(int num) {
970 1.13 joerg if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
971 1.13 joerg return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
972 1.13 joerg if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
973 1.13 joerg return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
974 1.13 joerg return LAST_REGISTER + 1;
975 1.13 joerg }
976 1.13 joerg
977 1.13 joerg bool validRegister(int num) const {
978 1.13 joerg return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
979 1.13 joerg }
980 1.13 joerg
981 1.13 joerg uint64_t getRegister(int num) const {
982 1.13 joerg assert(validRegister(num));
983 1.13 joerg return reg[num];
984 1.13 joerg }
985 1.13 joerg
986 1.13 joerg void setRegister(int num, uint64_t value) {
987 1.13 joerg assert(validRegister(num));
988 1.13 joerg reg[num] = value;
989 1.13 joerg }
990 1.13 joerg
991 1.13 joerg uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
992 1.13 joerg
993 1.13 joerg void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
994 1.13 joerg
995 1.13 joerg uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
996 1.13 joerg
997 1.13 joerg void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
998 1.13 joerg
999 1.13 joerg bool validFloatVectorRegister(int num) const {
1000 1.13 joerg return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
1001 1.13 joerg }
1002 1.13 joerg
1003 1.13 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
1004 1.13 joerg assert(validFloatVectorRegister(num));
1005 1.13 joerg const void *addr = reinterpret_cast<const void *>(addr_);
1006 1.13 joerg memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
1007 1.13 joerg }
1008 1.13 joerg
1009 1.13 joerg __dso_hidden void jumpto() const __dead;
1010 1.13 joerg
1011 1.13 joerg private:
1012 1.13 joerg uint32_t reg[REGNO_HPPA_R31 + 1];
1013 1.13 joerg uint32_t fpreg[56];
1014 1.13 joerg };
1015 1.13 joerg
1016 1.14 joerg enum {
1017 1.14 joerg DWARF_MIPS_R1 = 0,
1018 1.14 joerg DWARF_MIPS_R31 = 31,
1019 1.14 joerg DWARF_MIPS_F0 = 32,
1020 1.14 joerg DWARF_MIPS_F31 = 63,
1021 1.29 thorpej // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
1022 1.29 thorpej // signal handler return address.
1023 1.29 thorpej DWARF_MIPS_MDHI = 64,
1024 1.29 thorpej DWARF_MIPS_MDLO = 65,
1025 1.29 thorpej DWARF_MIPS_SIGRETURN = 66,
1026 1.14 joerg
1027 1.14 joerg REGNO_MIPS_PC = 0,
1028 1.14 joerg REGNO_MIPS_R1 = 0,
1029 1.14 joerg REGNO_MIPS_R29 = 29,
1030 1.14 joerg REGNO_MIPS_R31 = 31,
1031 1.14 joerg REGNO_MIPS_F0 = 33,
1032 1.29 thorpej REGNO_MIPS_F31 = 64,
1033 1.29 thorpej // these live in other_reg[]
1034 1.29 thorpej REGNO_MIPS_MDHI = 65,
1035 1.29 thorpej REGNO_MIPS_MDLO = 66,
1036 1.29 thorpej REGNO_MIPS_SIGRETURN = 67
1037 1.14 joerg };
1038 1.14 joerg
1039 1.14 joerg class Registers_MIPS {
1040 1.14 joerg public:
1041 1.14 joerg enum {
1042 1.29 thorpej LAST_REGISTER = REGNO_MIPS_SIGRETURN,
1043 1.29 thorpej LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
1044 1.14 joerg RETURN_OFFSET = 0,
1045 1.19 joerg RETURN_MASK = 0,
1046 1.14 joerg };
1047 1.14 joerg
1048 1.14 joerg __dso_hidden Registers_MIPS();
1049 1.14 joerg
1050 1.14 joerg static int dwarf2regno(int num) {
1051 1.14 joerg if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
1052 1.14 joerg return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
1053 1.14 joerg if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
1054 1.14 joerg return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
1055 1.29 thorpej if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN)
1056 1.29 thorpej return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI);
1057 1.14 joerg return LAST_REGISTER + 1;
1058 1.14 joerg }
1059 1.14 joerg
1060 1.14 joerg bool validRegister(int num) const {
1061 1.29 thorpej return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) ||
1062 1.29 thorpej (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN);
1063 1.14 joerg }
1064 1.14 joerg
1065 1.14 joerg uint64_t getRegister(int num) const {
1066 1.14 joerg assert(validRegister(num));
1067 1.29 thorpej if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
1068 1.29 thorpej return other_reg[num - REGNO_MIPS_MDHI];
1069 1.14 joerg return reg[num];
1070 1.14 joerg }
1071 1.14 joerg
1072 1.14 joerg void setRegister(int num, uint64_t value) {
1073 1.14 joerg assert(validRegister(num));
1074 1.29 thorpej if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
1075 1.29 thorpej other_reg[num - REGNO_MIPS_MDHI] = value;
1076 1.29 thorpej else
1077 1.29 thorpej reg[num] = value;
1078 1.14 joerg }
1079 1.14 joerg
1080 1.14 joerg uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
1081 1.14 joerg
1082 1.14 joerg void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
1083 1.14 joerg
1084 1.14 joerg uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
1085 1.14 joerg
1086 1.14 joerg void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
1087 1.14 joerg
1088 1.14 joerg bool validFloatVectorRegister(int num) const {
1089 1.29 thorpej return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
1090 1.14 joerg }
1091 1.14 joerg
1092 1.14 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
1093 1.14 joerg assert(validFloatVectorRegister(num));
1094 1.14 joerg const void *addr = reinterpret_cast<const void *>(addr_);
1095 1.14 joerg memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
1096 1.14 joerg }
1097 1.14 joerg
1098 1.14 joerg __dso_hidden void jumpto() const __dead;
1099 1.14 joerg
1100 1.14 joerg private:
1101 1.14 joerg uint32_t reg[REGNO_MIPS_R31 + 1];
1102 1.14 joerg uint64_t fpreg[32];
1103 1.29 thorpej uint32_t other_reg[3];
1104 1.14 joerg };
1105 1.14 joerg
1106 1.14 joerg enum {
1107 1.14 joerg DWARF_MIPS64_R1 = 0,
1108 1.14 joerg DWARF_MIPS64_R31 = 31,
1109 1.14 joerg DWARF_MIPS64_F0 = 32,
1110 1.14 joerg DWARF_MIPS64_F31 = 63,
1111 1.30 thorpej // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
1112 1.30 thorpej // signal handler return address.
1113 1.30 thorpej DWARF_MIPS64_MDHI = 64,
1114 1.30 thorpej DWARF_MIPS64_MDLO = 65,
1115 1.30 thorpej DWARF_MIPS64_SIGRETURN = 66,
1116 1.14 joerg
1117 1.14 joerg REGNO_MIPS64_PC = 0,
1118 1.14 joerg REGNO_MIPS64_R1 = 0,
1119 1.14 joerg REGNO_MIPS64_R29 = 29,
1120 1.14 joerg REGNO_MIPS64_R31 = 31,
1121 1.14 joerg REGNO_MIPS64_F0 = 33,
1122 1.30 thorpej REGNO_MIPS64_F31 = 64,
1123 1.30 thorpej // these live in other_reg[]
1124 1.30 thorpej REGNO_MIPS64_MDHI = 65,
1125 1.30 thorpej REGNO_MIPS64_MDLO = 66,
1126 1.30 thorpej REGNO_MIPS64_SIGRETURN = 67
1127 1.14 joerg };
1128 1.14 joerg
1129 1.14 joerg class Registers_MIPS64 {
1130 1.14 joerg public:
1131 1.14 joerg enum {
1132 1.30 thorpej LAST_REGISTER = REGNO_MIPS_SIGRETURN,
1133 1.30 thorpej LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
1134 1.14 joerg RETURN_OFFSET = 0,
1135 1.19 joerg RETURN_MASK = 0,
1136 1.14 joerg };
1137 1.14 joerg
1138 1.14 joerg __dso_hidden Registers_MIPS64();
1139 1.14 joerg
1140 1.14 joerg static int dwarf2regno(int num) {
1141 1.14 joerg if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
1142 1.14 joerg return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
1143 1.14 joerg if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
1144 1.14 joerg return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
1145 1.30 thorpej if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN)
1146 1.30 thorpej return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI);
1147 1.14 joerg return LAST_REGISTER + 1;
1148 1.14 joerg }
1149 1.14 joerg
1150 1.14 joerg bool validRegister(int num) const {
1151 1.32 skrll return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) ||
1152 1.30 thorpej (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN);
1153 1.14 joerg }
1154 1.14 joerg
1155 1.14 joerg uint64_t getRegister(int num) const {
1156 1.14 joerg assert(validRegister(num));
1157 1.30 thorpej if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1158 1.30 thorpej return other_reg[num - REGNO_MIPS64_MDHI];
1159 1.14 joerg return reg[num];
1160 1.14 joerg }
1161 1.14 joerg
1162 1.14 joerg void setRegister(int num, uint64_t value) {
1163 1.14 joerg assert(validRegister(num));
1164 1.30 thorpej if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1165 1.30 thorpej other_reg[num - REGNO_MIPS64_MDHI] = value;
1166 1.30 thorpej else
1167 1.30 thorpej reg[num] = value;
1168 1.14 joerg }
1169 1.14 joerg
1170 1.14 joerg uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1171 1.14 joerg
1172 1.14 joerg void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1173 1.14 joerg
1174 1.14 joerg uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1175 1.14 joerg
1176 1.14 joerg void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1177 1.14 joerg
1178 1.14 joerg bool validFloatVectorRegister(int num) const {
1179 1.30 thorpej return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
1180 1.14 joerg }
1181 1.14 joerg
1182 1.14 joerg void copyFloatVectorRegister(int num, uint64_t addr_) {
1183 1.14 joerg assert(validFloatVectorRegister(num));
1184 1.14 joerg const void *addr = reinterpret_cast<const void *>(addr_);
1185 1.14 joerg memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
1186 1.14 joerg }
1187 1.14 joerg
1188 1.14 joerg __dso_hidden void jumpto() const __dead;
1189 1.14 joerg
1190 1.14 joerg private:
1191 1.14 joerg uint64_t reg[REGNO_MIPS64_R31 + 1];
1192 1.14 joerg uint64_t fpreg[32];
1193 1.30 thorpej uint64_t other_reg[3];
1194 1.14 joerg };
1195 1.14 joerg
1196 1.18 matt enum {
1197 1.18 matt DWARF_OR1K_R0 = 0,
1198 1.18 matt DWARF_OR1K_SP = 1,
1199 1.18 matt DWARF_OR1K_LR = 9,
1200 1.18 matt DWARF_OR1K_R31 = 31,
1201 1.18 matt DWARF_OR1K_FPCSR = 32,
1202 1.18 matt
1203 1.18 matt REGNO_OR1K_R0 = 0,
1204 1.18 matt REGNO_OR1K_SP = 1,
1205 1.18 matt REGNO_OR1K_LR = 9,
1206 1.18 matt REGNO_OR1K_R31 = 31,
1207 1.18 matt REGNO_OR1K_FPCSR = 32,
1208 1.18 matt };
1209 1.18 matt
1210 1.18 matt class Registers_or1k {
1211 1.18 matt public:
1212 1.18 matt enum {
1213 1.18 matt LAST_REGISTER = REGNO_OR1K_FPCSR,
1214 1.18 matt LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1215 1.18 matt RETURN_OFFSET = 0,
1216 1.19 joerg RETURN_MASK = 0,
1217 1.18 matt };
1218 1.18 matt
1219 1.18 matt __dso_hidden Registers_or1k();
1220 1.18 matt
1221 1.18 matt static int dwarf2regno(int num) {
1222 1.18 matt if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1223 1.18 matt return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1224 1.18 matt if (num == DWARF_OR1K_FPCSR)
1225 1.18 matt return REGNO_OR1K_FPCSR;
1226 1.18 matt return LAST_REGISTER + 1;
1227 1.18 matt }
1228 1.18 matt
1229 1.18 matt bool validRegister(int num) const {
1230 1.18 matt return num >= 0 && num <= LAST_RESTORE_REG;
1231 1.18 matt }
1232 1.18 matt
1233 1.18 matt uint64_t getRegister(int num) const {
1234 1.18 matt assert(validRegister(num));
1235 1.18 matt return reg[num];
1236 1.18 matt }
1237 1.18 matt
1238 1.18 matt void setRegister(int num, uint64_t value) {
1239 1.18 matt assert(validRegister(num));
1240 1.18 matt reg[num] = value;
1241 1.18 matt }
1242 1.18 matt
1243 1.18 matt uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1244 1.18 matt
1245 1.18 matt void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1246 1.18 matt
1247 1.18 matt uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1248 1.18 matt
1249 1.18 matt void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1250 1.18 matt
1251 1.18 matt bool validFloatVectorRegister(int num) const {
1252 1.18 matt return false;
1253 1.18 matt }
1254 1.18 matt
1255 1.18 matt void copyFloatVectorRegister(int num, uint64_t addr_) {
1256 1.18 matt }
1257 1.18 matt
1258 1.18 matt __dso_hidden void jumpto() const __dead;
1259 1.18 matt
1260 1.18 matt private:
1261 1.18 matt uint32_t reg[REGNO_OR1K_FPCSR + 1];
1262 1.18 matt };
1263 1.18 matt
1264 1.9 joerg #if __i386__
1265 1.9 joerg typedef Registers_x86 NativeUnwindRegisters;
1266 1.9 joerg #elif __x86_64__
1267 1.9 joerg typedef Registers_x86_64 NativeUnwindRegisters;
1268 1.9 joerg #elif __powerpc__
1269 1.9 joerg typedef Registers_ppc32 NativeUnwindRegisters;
1270 1.17 matt #elif __aarch64__
1271 1.17 matt typedef Registers_aarch64 NativeUnwindRegisters;
1272 1.16 joerg #elif __arm__
1273 1.9 joerg typedef Registers_arm32 NativeUnwindRegisters;
1274 1.9 joerg #elif __vax__
1275 1.9 joerg typedef Registers_vax NativeUnwindRegisters;
1276 1.9 joerg #elif __m68k__
1277 1.9 joerg typedef Registers_M68K NativeUnwindRegisters;
1278 1.14 joerg #elif __mips_n64 || __mips_n32
1279 1.14 joerg typedef Registers_MIPS64 NativeUnwindRegisters;
1280 1.14 joerg #elif __mips__
1281 1.14 joerg typedef Registers_MIPS NativeUnwindRegisters;
1282 1.9 joerg #elif __sh3__
1283 1.9 joerg typedef Registers_SH3 NativeUnwindRegisters;
1284 1.11 joerg #elif __sparc64__
1285 1.11 joerg typedef Registers_SPARC64 NativeUnwindRegisters;
1286 1.11 joerg #elif __sparc__
1287 1.11 joerg typedef Registers_SPARC NativeUnwindRegisters;
1288 1.12 joerg #elif __alpha__
1289 1.12 joerg typedef Registers_Alpha NativeUnwindRegisters;
1290 1.13 joerg #elif __hppa__
1291 1.13 joerg typedef Registers_HPPA NativeUnwindRegisters;
1292 1.18 matt #elif __or1k__
1293 1.18 matt typedef Registers_or1k NativeUnwindRegisters;
1294 1.9 joerg #endif
1295 1.1 joerg } // namespace _Unwind
1296 1.1 joerg
1297 1.1 joerg #endif // __REGISTERS_HPP__
1298