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