Drop main() prototype. Syncs with NetBSD-8
[minix.git] / sys / lib / libunwind / Registers.hpp
blob596d35b4c127bc57184d1ca550a38f6a974cff1a
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.
11 //===----------------------------------------------------------------------===//
12 #ifndef __REGISTERS_HPP__
13 #define __REGISTERS_HPP__
15 #include <cassert>
16 #include <cstdint>
18 namespace _Unwind {
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,
32 class Registers_x86 {
33 public:
34 enum {
35 LAST_REGISTER = REGNO_X86_EIP,
36 LAST_RESTORE_REG = REGNO_X86_EIP,
37 RETURN_OFFSET = 0,
38 RETURN_MASK = 0,
41 __dso_hidden Registers_x86();
43 static int dwarf2regno(int num) { return num; }
45 bool validRegister(int num) const {
46 return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
49 uint32_t getRegister(int num) const {
50 assert(validRegister(num));
51 return reg[num];
54 void setRegister(int num, uint32_t value) {
55 assert(validRegister(num));
56 reg[num] = value;
59 uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
61 void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
63 uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
65 void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
67 bool validFloatVectorRegister(int num) const { return false; }
69 void copyFloatVectorRegister(int num, uint32_t addr) {
72 __dso_hidden void jumpto() const __dead;
74 private:
75 uint32_t reg[REGNO_X86_EIP + 1];
78 enum {
79 REGNO_X86_64_RAX = 0,
80 REGNO_X86_64_RDX = 1,
81 REGNO_X86_64_RCX = 2,
82 REGNO_X86_64_RBX = 3,
83 REGNO_X86_64_RSI = 4,
84 REGNO_X86_64_RDI = 5,
85 REGNO_X86_64_RBP = 6,
86 REGNO_X86_64_RSP = 7,
87 REGNO_X86_64_R8 = 8,
88 REGNO_X86_64_R9 = 9,
89 REGNO_X86_64_R10 = 10,
90 REGNO_X86_64_R11 = 11,
91 REGNO_X86_64_R12 = 12,
92 REGNO_X86_64_R13 = 13,
93 REGNO_X86_64_R14 = 14,
94 REGNO_X86_64_R15 = 15,
95 REGNO_X86_64_RIP = 16,
98 class Registers_x86_64 {
99 public:
100 enum {
101 LAST_REGISTER = REGNO_X86_64_RIP,
102 LAST_RESTORE_REG = REGNO_X86_64_RIP,
103 RETURN_OFFSET = 0,
104 RETURN_MASK = 0,
107 __dso_hidden Registers_x86_64();
109 static int dwarf2regno(int num) { return num; }
111 bool validRegister(int num) const {
112 return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
115 uint64_t getRegister(int num) const {
116 assert(validRegister(num));
117 return reg[num];
120 void setRegister(int num, uint64_t value) {
121 assert(validRegister(num));
122 reg[num] = value;
125 uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
127 void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
129 uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
131 void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
133 bool validFloatVectorRegister(int num) const { return false; }
135 void copyFloatVectorRegister(int num, uint64_t addr) {
138 __dso_hidden void jumpto() const __dead;
140 private:
141 uint64_t reg[REGNO_X86_64_RIP + 1];
144 enum {
145 DWARF_PPC32_R0 = 0,
146 DWARF_PPC32_R31 = 31,
147 DWARF_PPC32_F0 = 32,
148 DWARF_PPC32_F31 = 63,
149 DWARF_PPC32_LR = 65,
150 DWARF_PPC32_CR = 70,
151 DWARF_PPC32_V0 = 77,
152 DWARF_PPC32_V31 = 108,
154 REGNO_PPC32_R0 = 0,
155 REGNO_PPC32_R1 = 1,
156 REGNO_PPC32_R31 = 31,
157 REGNO_PPC32_LR = 32,
158 REGNO_PPC32_CR = 33,
159 REGNO_PPC32_SRR0 = 34,
161 REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
162 REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
163 REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
164 REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
167 class Registers_ppc32 {
168 public:
169 enum {
170 LAST_REGISTER = REGNO_PPC32_V31,
171 LAST_RESTORE_REG = REGNO_PPC32_V31,
172 RETURN_OFFSET = 0,
173 RETURN_MASK = 0,
176 __dso_hidden Registers_ppc32();
178 static int dwarf2regno(int num) {
179 if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
180 return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
181 if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
182 return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
183 if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
184 return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
185 switch (num) {
186 case DWARF_PPC32_LR:
187 return REGNO_PPC32_LR;
188 case DWARF_PPC32_CR:
189 return REGNO_PPC32_CR;
190 default:
191 return LAST_REGISTER + 1;
195 bool validRegister(int num) const {
196 return num >= 0 && num <= LAST_RESTORE_REG;
199 uint64_t getRegister(int num) const {
200 assert(validRegister(num));
201 return reg[num];
204 void setRegister(int num, uint64_t value) {
205 assert(validRegister(num));
206 reg[num] = value;
209 uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
211 void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
213 uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
215 void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
217 bool validFloatVectorRegister(int num) const {
218 return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
219 (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
222 void copyFloatVectorRegister(int num, uint64_t addr_) {
223 const void *addr = reinterpret_cast<const void *>(addr_);
224 if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
225 memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
226 else
227 memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
230 __dso_hidden void jumpto() const __dead;
232 private:
233 struct vecreg_t {
234 uint64_t low, high;
236 uint32_t reg[REGNO_PPC32_SRR0 + 1];
237 uint32_t dummy;
238 uint64_t fpreg[32];
239 vecreg_t vecreg[64];
242 enum {
243 DWARF_AARCH64_X0 = 0,
244 DWARF_AARCH64_X30 = 30,
245 DWARF_AARCH64_SP = 31,
246 DWARF_AARCH64_ELR_MODE = 33,
247 DWARF_AARCH64_V0 = 64,
248 DWARF_AARCH64_V31 = 95,
250 REGNO_AARCH64_X0 = 0,
251 REGNO_AARCH64_X30 = 30,
252 REGNO_AARCH64_SP = 31,
253 REGNO_AARCH64_ELR_MODE = 32,
254 REGNO_AARCH64_V0 = 33,
255 REGNO_AARCH64_V31 = 64,
258 class Registers_aarch64 {
259 public:
260 enum {
261 LAST_RESTORE_REG = REGNO_AARCH64_V31,
262 LAST_REGISTER = REGNO_AARCH64_V31,
263 RETURN_OFFSET = 0,
264 RETURN_MASK = 0,
267 __dso_hidden Registers_aarch64();
269 static int dwarf2regno(int num) {
270 if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
271 return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
272 if (num == DWARF_AARCH64_SP)
273 return REGNO_AARCH64_SP;
274 if (num == DWARF_AARCH64_ELR_MODE)
275 return REGNO_AARCH64_ELR_MODE;
276 if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
277 return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
278 return LAST_REGISTER + 1;
281 bool validRegister(int num) const {
282 return num >= 0 && num <= LAST_RESTORE_REG;
285 uint64_t getRegister(int num) const {
286 assert(validRegister(num));
287 return reg[num];
290 void setRegister(int num, uint64_t value) {
291 assert(validRegister(num));
292 reg[num] = value;
295 uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
297 void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
299 uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
301 void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
303 bool validFloatVectorRegister(int num) const {
304 return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
307 void copyFloatVectorRegister(int num, uint64_t addr_) {
308 const void *addr = reinterpret_cast<const void *>(addr_);
309 memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, sizeof(vecreg[0]));
312 __dso_hidden void jumpto() const __dead;
314 private:
315 struct vecreg_t {
316 uint64_t low, high;
318 uint64_t reg[REGNO_AARCH64_ELR_MODE + 1];
319 vecreg_t vecreg[32];
322 enum {
323 DWARF_ARM32_R0 = 0,
324 DWARF_ARM32_R15 = 15,
325 DWARF_ARM32_SPSR = 128,
326 DWARF_ARM32_OLD_S0 = 64,
327 DWARF_ARM32_OLD_S31 = 91,
328 DWARF_ARM32_D0 = 256,
329 DWARF_ARM32_D31 = 287,
330 REGNO_ARM32_R0 = 0,
331 REGNO_ARM32_SP = 13,
332 REGNO_ARM32_R15 = 15,
333 REGNO_ARM32_SPSR = 16,
334 REGNO_ARM32_D0 = 17,
335 REGNO_ARM32_D15 = 32,
336 REGNO_ARM32_D31 = 48,
339 class Registers_arm32 {
340 public:
341 enum {
342 LAST_REGISTER = REGNO_ARM32_D31,
343 LAST_RESTORE_REG = REGNO_ARM32_D31,
344 RETURN_OFFSET = 0,
345 RETURN_MASK = 0,
348 __dso_hidden Registers_arm32();
350 static int dwarf2regno(int num) {
351 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
352 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
353 if (num == DWARF_ARM32_SPSR)
354 return REGNO_ARM32_SPSR;
355 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
356 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
357 if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) {
358 assert(num % 2 == 0);
359 return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2;
361 return LAST_REGISTER + 1;
364 bool validRegister(int num) const {
365 return num >= 0 && num <= REGNO_ARM32_SPSR;
368 uint64_t getRegister(int num) const {
369 assert(validRegister(num));
370 return reg[num];
373 void setRegister(int num, uint64_t value) {
374 assert(validRegister(num));
375 reg[num] = value;
378 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
380 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
382 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
384 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
386 bool validFloatVectorRegister(int num) const {
387 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
390 void copyFloatVectorRegister(int num, uint64_t addr_) {
391 if (num <= REGNO_ARM32_D15) {
392 if ((flags & 1) == 0) {
393 lazyVFP1();
394 flags |= 1;
396 } else {
397 if ((flags & 2) == 0) {
398 lazyVFP3();
399 flags |= 2;
402 const void *addr = reinterpret_cast<const void *>(addr_);
403 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
406 __dso_hidden void lazyVFP1();
407 __dso_hidden void lazyVFP3();
408 __dso_hidden void jumpto() const __dead;
410 private:
411 uint32_t reg[REGNO_ARM32_SPSR + 1];
412 uint32_t flags;
413 uint64_t fpreg[32];
416 enum {
417 DWARF_VAX_R0 = 0,
418 DWARF_VAX_R15 = 15,
419 DWARF_VAX_PSW = 16,
421 REGNO_VAX_R0 = 0,
422 REGNO_VAX_R14 = 14,
423 REGNO_VAX_R15 = 15,
424 REGNO_VAX_PSW = 16,
427 class Registers_vax {
428 public:
429 enum {
430 LAST_REGISTER = REGNO_VAX_PSW,
431 LAST_RESTORE_REG = REGNO_VAX_PSW,
432 RETURN_OFFSET = 0,
433 RETURN_MASK = 0,
436 __dso_hidden Registers_vax();
438 static int dwarf2regno(int num) {
439 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
440 return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
441 if (num == DWARF_VAX_PSW)
442 return REGNO_VAX_PSW;
443 return LAST_REGISTER + 1;
446 bool validRegister(int num) const {
447 return num >= 0 && num <= LAST_RESTORE_REG;
450 uint64_t getRegister(int num) const {
451 assert(validRegister(num));
452 return reg[num];
455 void setRegister(int num, uint64_t value) {
456 assert(validRegister(num));
457 reg[num] = value;
460 uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
462 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
464 uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
466 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
468 bool validFloatVectorRegister(int num) const {
469 return false;
472 void copyFloatVectorRegister(int num, uint64_t addr_) {
475 __dso_hidden void jumpto() const __dead;
477 private:
478 uint32_t reg[REGNO_VAX_PSW + 1];
481 enum {
482 DWARF_M68K_A0 = 0,
483 DWARF_M68K_A7 = 7,
484 DWARF_M68K_D0 = 8,
485 DWARF_M68K_D7 = 15,
486 DWARF_M68K_FP0 = 16,
487 DWARF_M68K_FP7 = 23,
488 DWARF_M68K_PC = 24,
490 REGNO_M68K_A0 = 0,
491 REGNO_M68K_A7 = 7,
492 REGNO_M68K_D0 = 8,
493 REGNO_M68K_D7 = 15,
494 REGNO_M68K_PC = 16,
495 REGNO_M68K_FP0 = 17,
496 REGNO_M68K_FP7 = 24,
499 class Registers_M68K {
500 public:
501 enum {
502 LAST_REGISTER = REGNO_M68K_FP7,
503 LAST_RESTORE_REG = REGNO_M68K_FP7,
504 RETURN_OFFSET = 0,
505 RETURN_MASK = 0,
508 __dso_hidden Registers_M68K();
510 static int dwarf2regno(int num) {
511 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
512 return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
513 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
514 return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
515 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
516 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
517 if (num == DWARF_M68K_PC)
518 return REGNO_M68K_PC;
519 return LAST_REGISTER + 1;
522 bool validRegister(int num) const {
523 return num >= 0 && num <= REGNO_M68K_PC;
526 uint64_t getRegister(int num) const {
527 assert(validRegister(num));
528 return reg[num];
531 void setRegister(int num, uint64_t value) {
532 assert(validRegister(num));
533 reg[num] = value;
536 uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
538 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
540 uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
542 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
544 bool validFloatVectorRegister(int num) const {
545 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
548 void copyFloatVectorRegister(int num, uint64_t addr_) {
549 assert(validFloatVectorRegister(num));
550 const void *addr = reinterpret_cast<const void *>(addr_);
551 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
554 __dso_hidden void jumpto() const __dead;
556 private:
557 typedef uint32_t fpreg_t[3];
559 uint32_t reg[REGNO_M68K_PC + 1];
560 uint32_t dummy;
561 fpreg_t fpreg[8];
564 enum {
565 DWARF_SH3_R0 = 0,
566 DWARF_SH3_R15 = 15,
567 DWARF_SH3_PC = 16,
568 DWARF_SH3_PR = 17,
570 REGNO_SH3_R0 = 0,
571 REGNO_SH3_R15 = 15,
572 REGNO_SH3_PC = 16,
573 REGNO_SH3_PR = 17,
576 class Registers_SH3 {
577 public:
578 enum {
579 LAST_REGISTER = REGNO_SH3_PR,
580 LAST_RESTORE_REG = REGNO_SH3_PR,
581 RETURN_OFFSET = 0,
582 RETURN_MASK = 0,
585 __dso_hidden Registers_SH3();
587 static int dwarf2regno(int num) {
588 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
589 return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
590 if (num == DWARF_SH3_PC)
591 return REGNO_SH3_PC;
592 if (num == DWARF_SH3_PR)
593 return REGNO_SH3_PR;
594 return LAST_REGISTER + 1;
597 bool validRegister(int num) const {
598 return num >= 0 && num <= REGNO_SH3_PR;
601 uint64_t getRegister(int num) const {
602 assert(validRegister(num));
603 return reg[num];
606 void setRegister(int num, uint64_t value) {
607 assert(validRegister(num));
608 reg[num] = value;
611 uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
613 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
615 uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
617 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
619 bool validFloatVectorRegister(int num) const { return false; }
621 void copyFloatVectorRegister(int num, uint64_t addr_) {}
623 __dso_hidden void jumpto() const __dead;
625 private:
626 uint32_t reg[REGNO_SH3_PR + 1];
629 enum {
630 DWARF_SPARC64_R0 = 0,
631 DWARF_SPARC64_R31 = 31,
632 DWARF_SPARC64_PC = 32,
634 REGNO_SPARC64_R0 = 0,
635 REGNO_SPARC64_R14 = 14,
636 REGNO_SPARC64_R15 = 15,
637 REGNO_SPARC64_R31 = 31,
638 REGNO_SPARC64_PC = 32,
641 class Registers_SPARC64 {
642 public:
643 enum {
644 LAST_REGISTER = REGNO_SPARC64_PC,
645 LAST_RESTORE_REG = REGNO_SPARC64_PC,
646 RETURN_OFFSET = 8,
647 RETURN_MASK = 0,
649 typedef uint64_t reg_t;
651 __dso_hidden Registers_SPARC64();
653 static int dwarf2regno(int num) {
654 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
655 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
656 if (num == DWARF_SPARC64_PC)
657 return REGNO_SPARC64_PC;
658 return LAST_REGISTER + 1;
661 bool validRegister(int num) const {
662 return num >= 0 && num <= REGNO_SPARC64_PC;
665 uint64_t getRegister(int num) const {
666 assert(validRegister(num));
667 return reg[num];
670 void setRegister(int num, uint64_t value) {
671 assert(validRegister(num));
672 reg[num] = value;
675 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
677 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
679 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
681 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
683 bool validFloatVectorRegister(int num) const { return false; }
685 void copyFloatVectorRegister(int num, uint64_t addr_) {}
687 __dso_hidden void jumpto() const __dead;
689 private:
690 uint64_t reg[REGNO_SPARC64_PC + 1];
693 enum {
694 DWARF_SPARC_R0 = 0,
695 DWARF_SPARC_R31 = 31,
696 DWARF_SPARC_PC = 32,
698 REGNO_SPARC_R0 = 0,
699 REGNO_SPARC_R14 = 14,
700 REGNO_SPARC_R15 = 15,
701 REGNO_SPARC_R31 = 31,
702 REGNO_SPARC_PC = 32,
705 class Registers_SPARC {
706 public:
707 enum {
708 LAST_REGISTER = REGNO_SPARC_PC,
709 LAST_RESTORE_REG = REGNO_SPARC_PC,
710 RETURN_OFFSET = 8,
711 RETURN_MASK = 0,
713 typedef uint32_t reg_t;
715 __dso_hidden Registers_SPARC();
717 static int dwarf2regno(int num) {
718 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
719 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
720 if (num == DWARF_SPARC_PC)
721 return REGNO_SPARC_PC;
722 return LAST_REGISTER + 1;
725 bool validRegister(int num) const {
726 return num >= 0 && num <= REGNO_SPARC_PC;
729 uint64_t getRegister(int num) const {
730 assert(validRegister(num));
731 return reg[num];
734 void setRegister(int num, uint64_t value) {
735 assert(validRegister(num));
736 reg[num] = value;
739 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
741 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
743 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
745 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
747 bool validFloatVectorRegister(int num) const { return false; }
749 void copyFloatVectorRegister(int num, uint64_t addr_) {}
751 __dso_hidden void jumpto() const __dead;
753 private:
754 uint32_t reg[REGNO_SPARC_PC + 1];
757 enum {
758 DWARF_ALPHA_R0 = 0,
759 DWARF_ALPHA_R30 = 30,
760 DWARF_ALPHA_F0 = 32,
761 DWARF_ALPHA_F30 = 62,
763 REGNO_ALPHA_R0 = 0,
764 REGNO_ALPHA_R26 = 26,
765 REGNO_ALPHA_R30 = 30,
766 REGNO_ALPHA_PC = 31,
767 REGNO_ALPHA_F0 = 32,
768 REGNO_ALPHA_F30 = 62,
771 class Registers_Alpha {
772 public:
773 enum {
774 LAST_REGISTER = REGNO_ALPHA_F30,
775 LAST_RESTORE_REG = REGNO_ALPHA_F30,
776 RETURN_OFFSET = 0,
777 RETURN_MASK = 0,
779 typedef uint32_t reg_t;
781 __dso_hidden Registers_Alpha();
783 static int dwarf2regno(int num) { return num; }
785 bool validRegister(int num) const {
786 return num >= 0 && num <= REGNO_ALPHA_PC;
789 uint64_t getRegister(int num) const {
790 assert(validRegister(num));
791 return reg[num];
794 void setRegister(int num, uint64_t value) {
795 assert(validRegister(num));
796 reg[num] = value;
799 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
801 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
803 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
805 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
807 bool validFloatVectorRegister(int num) const {
808 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
811 void copyFloatVectorRegister(int num, uint64_t addr_) {
812 assert(validFloatVectorRegister(num));
813 const void *addr = reinterpret_cast<const void *>(addr_);
814 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
817 __dso_hidden void jumpto() const __dead;
819 private:
820 uint64_t reg[REGNO_ALPHA_PC + 1];
821 uint64_t fpreg[31];
824 enum {
825 DWARF_HPPA_R1 = 1,
826 DWARF_HPPA_R31 = 31,
827 DWARF_HPPA_FR4L = 32,
828 DWARF_HPPA_FR31H = 87,
830 REGNO_HPPA_PC = 0,
831 REGNO_HPPA_R1 = 1,
832 REGNO_HPPA_R2 = 2,
833 REGNO_HPPA_R30 = 30,
834 REGNO_HPPA_R31 = 31,
835 REGNO_HPPA_FR4L = 32,
836 REGNO_HPPA_FR31H = 87,
839 class Registers_HPPA {
840 public:
841 enum {
842 LAST_REGISTER = REGNO_HPPA_FR31H,
843 LAST_RESTORE_REG = REGNO_HPPA_FR31H,
844 RETURN_OFFSET = 0,
845 RETURN_MASK = 3,
848 __dso_hidden Registers_HPPA();
850 static int dwarf2regno(int num) {
851 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
852 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
853 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
854 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
855 return LAST_REGISTER + 1;
858 bool validRegister(int num) const {
859 return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
862 uint64_t getRegister(int num) const {
863 assert(validRegister(num));
864 return reg[num];
867 void setRegister(int num, uint64_t value) {
868 assert(validRegister(num));
869 reg[num] = value;
872 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
874 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
876 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
878 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
880 bool validFloatVectorRegister(int num) const {
881 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
884 void copyFloatVectorRegister(int num, uint64_t addr_) {
885 assert(validFloatVectorRegister(num));
886 const void *addr = reinterpret_cast<const void *>(addr_);
887 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
890 __dso_hidden void jumpto() const __dead;
892 private:
893 uint32_t reg[REGNO_HPPA_R31 + 1];
894 uint32_t fpreg[56];
897 enum {
898 DWARF_MIPS_R1 = 0,
899 DWARF_MIPS_R31 = 31,
900 DWARF_MIPS_F0 = 32,
901 DWARF_MIPS_F31 = 63,
903 REGNO_MIPS_PC = 0,
904 REGNO_MIPS_R1 = 0,
905 REGNO_MIPS_R29 = 29,
906 REGNO_MIPS_R31 = 31,
907 REGNO_MIPS_F0 = 33,
908 REGNO_MIPS_F31 = 64
911 class Registers_MIPS {
912 public:
913 enum {
914 LAST_REGISTER = REGNO_MIPS_F31,
915 LAST_RESTORE_REG = REGNO_MIPS_F31,
916 RETURN_OFFSET = 0,
917 RETURN_MASK = 0,
920 __dso_hidden Registers_MIPS();
922 static int dwarf2regno(int num) {
923 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
924 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
925 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
926 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
927 return LAST_REGISTER + 1;
930 bool validRegister(int num) const {
931 return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
934 uint64_t getRegister(int num) const {
935 assert(validRegister(num));
936 return reg[num];
939 void setRegister(int num, uint64_t value) {
940 assert(validRegister(num));
941 reg[num] = value;
944 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
946 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
948 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
950 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
952 bool validFloatVectorRegister(int num) const {
953 return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
956 void copyFloatVectorRegister(int num, uint64_t addr_) {
957 assert(validFloatVectorRegister(num));
958 const void *addr = reinterpret_cast<const void *>(addr_);
959 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
962 __dso_hidden void jumpto() const __dead;
964 private:
965 uint32_t reg[REGNO_MIPS_R31 + 1];
966 uint64_t fpreg[32];
969 enum {
970 DWARF_MIPS64_R1 = 0,
971 DWARF_MIPS64_R31 = 31,
972 DWARF_MIPS64_F0 = 32,
973 DWARF_MIPS64_F31 = 63,
975 REGNO_MIPS64_PC = 0,
976 REGNO_MIPS64_R1 = 0,
977 REGNO_MIPS64_R29 = 29,
978 REGNO_MIPS64_R31 = 31,
979 REGNO_MIPS64_F0 = 33,
980 REGNO_MIPS64_F31 = 64
983 class Registers_MIPS64 {
984 public:
985 enum {
986 LAST_REGISTER = REGNO_MIPS64_F31,
987 LAST_RESTORE_REG = REGNO_MIPS64_F31,
988 RETURN_OFFSET = 0,
989 RETURN_MASK = 0,
992 __dso_hidden Registers_MIPS64();
994 static int dwarf2regno(int num) {
995 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
996 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
997 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
998 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
999 return LAST_REGISTER + 1;
1002 bool validRegister(int num) const {
1003 return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
1006 uint64_t getRegister(int num) const {
1007 assert(validRegister(num));
1008 return reg[num];
1011 void setRegister(int num, uint64_t value) {
1012 assert(validRegister(num));
1013 reg[num] = value;
1016 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1018 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1020 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1022 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1024 bool validFloatVectorRegister(int num) const {
1025 return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
1028 void copyFloatVectorRegister(int num, uint64_t addr_) {
1029 assert(validFloatVectorRegister(num));
1030 const void *addr = reinterpret_cast<const void *>(addr_);
1031 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
1034 __dso_hidden void jumpto() const __dead;
1036 private:
1037 uint64_t reg[REGNO_MIPS64_R31 + 1];
1038 uint64_t fpreg[32];
1041 enum {
1042 DWARF_OR1K_R0 = 0,
1043 DWARF_OR1K_SP = 1,
1044 DWARF_OR1K_LR = 9,
1045 DWARF_OR1K_R31 = 31,
1046 DWARF_OR1K_FPCSR = 32,
1048 REGNO_OR1K_R0 = 0,
1049 REGNO_OR1K_SP = 1,
1050 REGNO_OR1K_LR = 9,
1051 REGNO_OR1K_R31 = 31,
1052 REGNO_OR1K_FPCSR = 32,
1055 class Registers_or1k {
1056 public:
1057 enum {
1058 LAST_REGISTER = REGNO_OR1K_FPCSR,
1059 LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1060 RETURN_OFFSET = 0,
1061 RETURN_MASK = 0,
1064 __dso_hidden Registers_or1k();
1066 static int dwarf2regno(int num) {
1067 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1068 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1069 if (num == DWARF_OR1K_FPCSR)
1070 return REGNO_OR1K_FPCSR;
1071 return LAST_REGISTER + 1;
1074 bool validRegister(int num) const {
1075 return num >= 0 && num <= LAST_RESTORE_REG;
1078 uint64_t getRegister(int num) const {
1079 assert(validRegister(num));
1080 return reg[num];
1083 void setRegister(int num, uint64_t value) {
1084 assert(validRegister(num));
1085 reg[num] = value;
1088 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1090 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1092 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1094 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1096 bool validFloatVectorRegister(int num) const {
1097 return false;
1100 void copyFloatVectorRegister(int num, uint64_t addr_) {
1103 __dso_hidden void jumpto() const __dead;
1105 private:
1106 uint32_t reg[REGNO_OR1K_FPCSR + 1];
1109 #if __i386__
1110 typedef Registers_x86 NativeUnwindRegisters;
1111 #elif __x86_64__
1112 typedef Registers_x86_64 NativeUnwindRegisters;
1113 #elif __powerpc__
1114 typedef Registers_ppc32 NativeUnwindRegisters;
1115 #elif __aarch64__
1116 typedef Registers_aarch64 NativeUnwindRegisters;
1117 #elif __arm__
1118 typedef Registers_arm32 NativeUnwindRegisters;
1119 #elif __vax__
1120 typedef Registers_vax NativeUnwindRegisters;
1121 #elif __m68k__
1122 typedef Registers_M68K NativeUnwindRegisters;
1123 #elif __mips_n64 || __mips_n32
1124 typedef Registers_MIPS64 NativeUnwindRegisters;
1125 #elif __mips__
1126 typedef Registers_MIPS NativeUnwindRegisters;
1127 #elif __sh3__
1128 typedef Registers_SH3 NativeUnwindRegisters;
1129 #elif __sparc64__
1130 typedef Registers_SPARC64 NativeUnwindRegisters;
1131 #elif __sparc__
1132 typedef Registers_SPARC NativeUnwindRegisters;
1133 #elif __alpha__
1134 typedef Registers_Alpha NativeUnwindRegisters;
1135 #elif __hppa__
1136 typedef Registers_HPPA NativeUnwindRegisters;
1137 #elif __or1k__
1138 typedef Registers_or1k NativeUnwindRegisters;
1139 #endif
1140 } // namespace _Unwind
1142 #endif // __REGISTERS_HPP__