xref: /minix/sys/lib/libunwind/Registers.hpp (revision 83133719)
1 //===----------------------------- Registers.hpp --------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 //  Models register sets for supported processors.
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef __REGISTERS_HPP__
13 #define __REGISTERS_HPP__
14 
15 #include <cassert>
16 #include <cstdint>
17 
18 namespace _Unwind {
19 
20 enum {
21   REGNO_X86_EAX = 0,
22   REGNO_X86_ECX = 1,
23   REGNO_X86_EDX = 2,
24   REGNO_X86_EBX = 3,
25   REGNO_X86_ESP = 4,
26   REGNO_X86_EBP = 5,
27   REGNO_X86_ESI = 6,
28   REGNO_X86_EDI = 7,
29   REGNO_X86_EIP = 8,
30 };
31 
32 class Registers_x86 {
33 public:
34   enum {
35     LAST_REGISTER = REGNO_X86_EIP,
36     LAST_RESTORE_REG = REGNO_X86_EIP,
37     RETURN_OFFSET = 0,
38   };
39 
40   __dso_hidden Registers_x86();
41 
42   static int dwarf2regno(int num) { return num; }
43 
44   bool validRegister(int num) const {
45     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
46   }
47 
48   uint32_t getRegister(int num) const {
49     assert(validRegister(num));
50     return reg[num];
51   }
52 
53   void setRegister(int num, uint32_t value) {
54     assert(validRegister(num));
55     reg[num] = value;
56   }
57 
58   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
59 
60   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
61 
62   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
63 
64   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
65 
66   bool validFloatVectorRegister(int num) const { return false; }
67 
68   void copyFloatVectorRegister(int num, uint32_t addr) {
69   }
70 
71   __dso_hidden void jumpto() const __dead;
72 
73 private:
74   uint32_t reg[REGNO_X86_EIP + 1];
75 };
76 
77 enum {
78   REGNO_X86_64_RAX = 0,
79   REGNO_X86_64_RDX = 1,
80   REGNO_X86_64_RCX = 2,
81   REGNO_X86_64_RBX = 3,
82   REGNO_X86_64_RSI = 4,
83   REGNO_X86_64_RDI = 5,
84   REGNO_X86_64_RBP = 6,
85   REGNO_X86_64_RSP = 7,
86   REGNO_X86_64_R8 = 8,
87   REGNO_X86_64_R9 = 9,
88   REGNO_X86_64_R10 = 10,
89   REGNO_X86_64_R11 = 11,
90   REGNO_X86_64_R12 = 12,
91   REGNO_X86_64_R13 = 13,
92   REGNO_X86_64_R14 = 14,
93   REGNO_X86_64_R15 = 15,
94   REGNO_X86_64_RIP = 16,
95 };
96 
97 class Registers_x86_64 {
98 public:
99   enum {
100     LAST_REGISTER = REGNO_X86_64_RIP,
101     LAST_RESTORE_REG = REGNO_X86_64_RIP,
102     RETURN_OFFSET = 0,
103   };
104 
105   __dso_hidden Registers_x86_64();
106 
107   static int dwarf2regno(int num) { return num; }
108 
109   bool validRegister(int num) const {
110     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
111   }
112 
113   uint64_t getRegister(int num) const {
114     assert(validRegister(num));
115     return reg[num];
116   }
117 
118   void setRegister(int num, uint64_t value) {
119     assert(validRegister(num));
120     reg[num] = value;
121   }
122 
123   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
124 
125   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
126 
127   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
128 
129   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
130 
131   bool validFloatVectorRegister(int num) const { return false; }
132 
133   void copyFloatVectorRegister(int num, uint64_t addr) {
134   }
135 
136   __dso_hidden void jumpto() const __dead;
137 
138 private:
139   uint64_t reg[REGNO_X86_64_RIP + 1];
140 };
141 
142 enum {
143   DWARF_PPC32_R0 = 0,
144   DWARF_PPC32_R31 = 31,
145   DWARF_PPC32_F0 = 32,
146   DWARF_PPC32_F31 = 63,
147   DWARF_PPC32_LR = 65,
148   DWARF_PPC32_CR = 70,
149   DWARF_PPC32_V0 = 77,
150   DWARF_PPC32_V31 = 108,
151 
152   REGNO_PPC32_R0 = 0,
153   REGNO_PPC32_R1 = 1,
154   REGNO_PPC32_R31 = 31,
155   REGNO_PPC32_LR = 32,
156   REGNO_PPC32_CR = 33,
157   REGNO_PPC32_SRR0 = 34,
158 
159   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
160   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
161   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
162   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
163 };
164 
165 class Registers_ppc32 {
166 public:
167   enum {
168     LAST_REGISTER = REGNO_PPC32_V31,
169     LAST_RESTORE_REG = REGNO_PPC32_V31,
170     RETURN_OFFSET = 0,
171   };
172 
173   __dso_hidden Registers_ppc32();
174 
175   static int dwarf2regno(int num) {
176     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
177       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
178     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
179       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
180     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
181       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
182     switch (num) {
183     case DWARF_PPC32_LR:
184       return REGNO_PPC32_LR;
185     case DWARF_PPC32_CR:
186       return REGNO_PPC32_CR;
187     default:
188       return LAST_REGISTER + 1;
189     }
190   }
191 
192   bool validRegister(int num) const {
193     return num >= 0 && num <= LAST_RESTORE_REG;
194   }
195 
196   uint64_t getRegister(int num) const {
197     assert(validRegister(num));
198     return reg[num];
199   }
200 
201   void setRegister(int num, uint64_t value) {
202     assert(validRegister(num));
203     reg[num] = value;
204   }
205 
206   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
207 
208   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
209 
210   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
211 
212   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
213 
214   bool validFloatVectorRegister(int num) const {
215     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
216            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
217   }
218 
219   void copyFloatVectorRegister(int num, uint64_t addr_) {
220     const void *addr = reinterpret_cast<const void *>(addr_);
221     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
222       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
223     else
224       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
225   }
226 
227   __dso_hidden void jumpto() const __dead;
228 
229 private:
230   struct vecreg_t {
231     uint64_t low, high;
232   };
233   uint32_t reg[REGNO_PPC32_SRR0 + 1];
234   uint32_t dummy;
235   uint64_t fpreg[32];
236   vecreg_t vecreg[64];
237 };
238 
239 enum {
240   DWARF_ARM32_R0 = 0,
241   DWARF_ARM32_R15 = 15,
242   DWARF_ARM32_SPSR = 128,
243   DWARF_ARM32_OLD_S0 = 64,
244   DWARF_ARM32_OLD_S31 = 91,
245   DWARF_ARM32_D0 = 256,
246   DWARF_ARM32_D31 = 287,
247   REGNO_ARM32_R0 = 0,
248   REGNO_ARM32_SP = 13,
249   REGNO_ARM32_R15 = 15,
250   REGNO_ARM32_SPSR = 16,
251   REGNO_ARM32_D0 = 17,
252   REGNO_ARM32_D15 = 32,
253   REGNO_ARM32_D31 = 48,
254 };
255 
256 class Registers_arm32 {
257 public:
258   enum {
259     LAST_REGISTER = REGNO_ARM32_D31,
260     LAST_RESTORE_REG = REGNO_ARM32_D31,
261     RETURN_OFFSET = 0,
262   };
263 
264   __dso_hidden Registers_arm32();
265 
266   static int dwarf2regno(int num) {
267     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
268       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
269     if (num == DWARF_ARM32_SPSR)
270       return REGNO_ARM32_SPSR;
271     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
272       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
273     if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) {
274       assert(num % 2 == 0);
275       return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2;
276     }
277     return LAST_REGISTER + 1;
278   }
279 
280   bool validRegister(int num) const {
281     return num >= 0 && num <= REGNO_ARM32_SPSR;
282   }
283 
284   uint64_t getRegister(int num) const {
285     assert(validRegister(num));
286     return reg[num];
287   }
288 
289   void setRegister(int num, uint64_t value) {
290     assert(validRegister(num));
291     reg[num] = value;
292   }
293 
294   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
295 
296   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
297 
298   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
299 
300   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
301 
302   bool validFloatVectorRegister(int num) const {
303     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
304   }
305 
306   void copyFloatVectorRegister(int num, uint64_t addr_) {
307     if (num <= REGNO_ARM32_D15) {
308       if ((flags & 1) == 0) {
309         lazyVFP1();
310         flags |= 1;
311       }
312     } else {
313       if ((flags & 2) == 0) {
314         lazyVFP3();
315         flags |= 2;
316       }
317     }
318     const void *addr = reinterpret_cast<const void *>(addr_);
319     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
320   }
321 
322   __dso_hidden void lazyVFP1();
323   __dso_hidden void lazyVFP3();
324   __dso_hidden void jumpto() const __dead;
325 
326 private:
327   uint32_t reg[REGNO_ARM32_SPSR + 1];
328   uint32_t flags;
329   uint64_t fpreg[32];
330 };
331 
332 enum {
333   DWARF_VAX_R0 = 0,
334   DWARF_VAX_R15 = 15,
335   DWARF_VAX_PSW = 16,
336 
337   REGNO_VAX_R0 = 0,
338   REGNO_VAX_R14 = 14,
339   REGNO_VAX_R15 = 15,
340   REGNO_VAX_PSW = 16,
341 };
342 
343 class Registers_vax {
344 public:
345   enum {
346     LAST_REGISTER = REGNO_VAX_PSW,
347     LAST_RESTORE_REG = REGNO_VAX_PSW,
348     RETURN_OFFSET = 0,
349   };
350 
351   __dso_hidden Registers_vax();
352 
353   static int dwarf2regno(int num) {
354     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
355       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
356     if (num == DWARF_VAX_PSW)
357       return REGNO_VAX_PSW;
358     return LAST_REGISTER + 1;
359   }
360 
361   bool validRegister(int num) const {
362     return num >= 0 && num <= LAST_RESTORE_REG;
363   }
364 
365   uint64_t getRegister(int num) const {
366     assert(validRegister(num));
367     return reg[num];
368   }
369 
370   void setRegister(int num, uint64_t value) {
371     assert(validRegister(num));
372     reg[num] = value;
373   }
374 
375   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
376 
377   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
378 
379   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
380 
381   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
382 
383   bool validFloatVectorRegister(int num) const {
384     return false;
385   }
386 
387   void copyFloatVectorRegister(int num, uint64_t addr_) {
388   }
389 
390   __dso_hidden void jumpto() const __dead;
391 
392 private:
393   uint32_t reg[REGNO_VAX_PSW + 1];
394 };
395 
396 enum {
397   DWARF_M68K_A0 = 0,
398   DWARF_M68K_A7 = 7,
399   DWARF_M68K_D0 = 8,
400   DWARF_M68K_D7 = 15,
401   DWARF_M68K_FP0 = 16,
402   DWARF_M68K_FP7 = 23,
403   DWARF_M68K_PC = 24,
404 
405   REGNO_M68K_A0 = 0,
406   REGNO_M68K_A7 = 7,
407   REGNO_M68K_D0 = 8,
408   REGNO_M68K_D7 = 15,
409   REGNO_M68K_PC = 16,
410   REGNO_M68K_FP0 = 17,
411   REGNO_M68K_FP7 = 24,
412 };
413 
414 class Registers_M68K {
415 public:
416   enum {
417     LAST_REGISTER = REGNO_M68K_FP7,
418     LAST_RESTORE_REG = REGNO_M68K_FP7,
419     RETURN_OFFSET = 0,
420   };
421 
422   __dso_hidden Registers_M68K();
423 
424   static int dwarf2regno(int num) {
425     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
426       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
427     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
428       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
429     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
430       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
431     if (num == DWARF_M68K_PC)
432       return REGNO_M68K_PC;
433     return LAST_REGISTER + 1;
434   }
435 
436   bool validRegister(int num) const {
437     return num >= 0 && num <= REGNO_M68K_PC;
438   }
439 
440   uint64_t getRegister(int num) const {
441     assert(validRegister(num));
442     return reg[num];
443   }
444 
445   void setRegister(int num, uint64_t value) {
446     assert(validRegister(num));
447     reg[num] = value;
448   }
449 
450   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
451 
452   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
453 
454   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
455 
456   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
457 
458   bool validFloatVectorRegister(int num) const {
459     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
460   }
461 
462   void copyFloatVectorRegister(int num, uint64_t addr_) {
463     assert(validFloatVectorRegister(num));
464     const void *addr = reinterpret_cast<const void *>(addr_);
465     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
466   }
467 
468   __dso_hidden void jumpto() const __dead;
469 
470 private:
471   typedef uint32_t fpreg_t[3];
472 
473   uint32_t reg[REGNO_M68K_PC + 1];
474   uint32_t dummy;
475   fpreg_t fpreg[8];
476 };
477 
478 enum {
479   DWARF_SH3_R0 = 0,
480   DWARF_SH3_R15 = 15,
481   DWARF_SH3_PC = 16,
482   DWARF_SH3_PR = 17,
483 
484   REGNO_SH3_R0 = 0,
485   REGNO_SH3_R15 = 15,
486   REGNO_SH3_PC = 16,
487   REGNO_SH3_PR = 17,
488 };
489 
490 class Registers_SH3 {
491 public:
492   enum {
493     LAST_REGISTER = REGNO_SH3_PR,
494     LAST_RESTORE_REG = REGNO_SH3_PR,
495     RETURN_OFFSET = 0,
496   };
497 
498   __dso_hidden Registers_SH3();
499 
500   static int dwarf2regno(int num) {
501     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
502       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
503     if (num == DWARF_SH3_PC)
504       return REGNO_SH3_PC;
505     if (num == DWARF_SH3_PR)
506       return REGNO_SH3_PR;
507     return LAST_REGISTER + 1;
508   }
509 
510   bool validRegister(int num) const {
511     return num >= 0 && num <= REGNO_SH3_PR;
512   }
513 
514   uint64_t getRegister(int num) const {
515     assert(validRegister(num));
516     return reg[num];
517   }
518 
519   void setRegister(int num, uint64_t value) {
520     assert(validRegister(num));
521     reg[num] = value;
522   }
523 
524   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
525 
526   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
527 
528   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
529 
530   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
531 
532   bool validFloatVectorRegister(int num) const { return false; }
533 
534   void copyFloatVectorRegister(int num, uint64_t addr_) {}
535 
536   __dso_hidden void jumpto() const __dead;
537 
538 private:
539   uint32_t reg[REGNO_SH3_PR + 1];
540 };
541 
542 enum {
543   DWARF_SPARC64_R0 = 0,
544   DWARF_SPARC64_R31 = 31,
545   DWARF_SPARC64_PC = 32,
546 
547   REGNO_SPARC64_R0 = 0,
548   REGNO_SPARC64_R14 = 14,
549   REGNO_SPARC64_R15 = 15,
550   REGNO_SPARC64_R31 = 31,
551   REGNO_SPARC64_PC = 32,
552 };
553 
554 class Registers_SPARC64 {
555 public:
556   enum {
557     LAST_REGISTER = REGNO_SPARC64_PC,
558     LAST_RESTORE_REG = REGNO_SPARC64_PC,
559     RETURN_OFFSET = 8,
560   };
561   typedef uint64_t reg_t;
562 
563   __dso_hidden Registers_SPARC64();
564 
565   static int dwarf2regno(int num) {
566     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
567       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
568     if (num == DWARF_SPARC64_PC)
569       return REGNO_SPARC64_PC;
570     return LAST_REGISTER + 1;
571   }
572 
573   bool validRegister(int num) const {
574     return num >= 0 && num <= REGNO_SPARC64_PC;
575   }
576 
577   uint64_t getRegister(int num) const {
578     assert(validRegister(num));
579     return reg[num];
580   }
581 
582   void setRegister(int num, uint64_t value) {
583     assert(validRegister(num));
584     reg[num] = value;
585   }
586 
587   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
588 
589   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
590 
591   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
592 
593   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
594 
595   bool validFloatVectorRegister(int num) const { return false; }
596 
597   void copyFloatVectorRegister(int num, uint64_t addr_) {}
598 
599   __dso_hidden void jumpto() const __dead;
600 
601 private:
602   uint64_t reg[REGNO_SPARC64_PC + 1];
603 };
604 
605 enum {
606   DWARF_SPARC_R0 = 0,
607   DWARF_SPARC_R31 = 31,
608   DWARF_SPARC_PC = 32,
609 
610   REGNO_SPARC_R0 = 0,
611   REGNO_SPARC_R14 = 14,
612   REGNO_SPARC_R15 = 15,
613   REGNO_SPARC_R31 = 31,
614   REGNO_SPARC_PC = 32,
615 };
616 
617 class Registers_SPARC {
618 public:
619   enum {
620     LAST_REGISTER = REGNO_SPARC_PC,
621     LAST_RESTORE_REG = REGNO_SPARC_PC,
622     RETURN_OFFSET = 8,
623   };
624   typedef uint32_t reg_t;
625 
626   __dso_hidden Registers_SPARC();
627 
628   static int dwarf2regno(int num) {
629     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
630       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
631     if (num == DWARF_SPARC_PC)
632       return REGNO_SPARC_PC;
633     return LAST_REGISTER + 1;
634   }
635 
636   bool validRegister(int num) const {
637     return num >= 0 && num <= REGNO_SPARC_PC;
638   }
639 
640   uint64_t getRegister(int num) const {
641     assert(validRegister(num));
642     return reg[num];
643   }
644 
645   void setRegister(int num, uint64_t value) {
646     assert(validRegister(num));
647     reg[num] = value;
648   }
649 
650   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
651 
652   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
653 
654   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
655 
656   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
657 
658   bool validFloatVectorRegister(int num) const { return false; }
659 
660   void copyFloatVectorRegister(int num, uint64_t addr_) {}
661 
662   __dso_hidden void jumpto() const __dead;
663 
664 private:
665   uint32_t reg[REGNO_SPARC_PC + 1];
666 };
667 
668 enum {
669   DWARF_ALPHA_R0 = 0,
670   DWARF_ALPHA_R30 = 30,
671   DWARF_ALPHA_F0 = 32,
672   DWARF_ALPHA_F30 = 62,
673 
674   REGNO_ALPHA_R0 = 0,
675   REGNO_ALPHA_R26 = 26,
676   REGNO_ALPHA_R30 = 30,
677   REGNO_ALPHA_PC = 31,
678   REGNO_ALPHA_F0 = 32,
679   REGNO_ALPHA_F30 = 62,
680 };
681 
682 class Registers_Alpha {
683 public:
684   enum {
685     LAST_REGISTER = REGNO_ALPHA_F30,
686     LAST_RESTORE_REG = REGNO_ALPHA_F30,
687     RETURN_OFFSET = 0,
688   };
689   typedef uint32_t reg_t;
690 
691   __dso_hidden Registers_Alpha();
692 
693   static int dwarf2regno(int num) { return num; }
694 
695   bool validRegister(int num) const {
696     return num >= 0 && num <= REGNO_ALPHA_PC;
697   }
698 
699   uint64_t getRegister(int num) const {
700     assert(validRegister(num));
701     return reg[num];
702   }
703 
704   void setRegister(int num, uint64_t value) {
705     assert(validRegister(num));
706     reg[num] = value;
707   }
708 
709   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
710 
711   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
712 
713   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
714 
715   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
716 
717   bool validFloatVectorRegister(int num) const {
718     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
719   }
720 
721   void copyFloatVectorRegister(int num, uint64_t addr_) {
722     assert(validFloatVectorRegister(num));
723     const void *addr = reinterpret_cast<const void *>(addr_);
724     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
725   }
726 
727   __dso_hidden void jumpto() const __dead;
728 
729 private:
730   uint64_t reg[REGNO_ALPHA_PC + 1];
731   uint64_t fpreg[31];
732 };
733 
734 enum {
735   DWARF_HPPA_R1 = 1,
736   DWARF_HPPA_R31 = 31,
737   DWARF_HPPA_FR4L = 32,
738   DWARF_HPPA_FR31H = 87,
739 
740   REGNO_HPPA_PC = 0,
741   REGNO_HPPA_R1 = 1,
742   REGNO_HPPA_R2 = 2,
743   REGNO_HPPA_R30 = 30,
744   REGNO_HPPA_R31 = 31,
745   REGNO_HPPA_FR4L = 32,
746   REGNO_HPPA_FR31H = 87,
747 };
748 
749 class Registers_HPPA {
750 public:
751   enum {
752     LAST_REGISTER = REGNO_HPPA_FR31H,
753     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
754     RETURN_OFFSET = -3, // strictly speaking, this is a mask
755   };
756 
757   __dso_hidden Registers_HPPA();
758 
759   static int dwarf2regno(int num) {
760     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
761       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
762     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
763       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
764     return LAST_REGISTER + 1;
765   }
766 
767   bool validRegister(int num) const {
768     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
769   }
770 
771   uint64_t getRegister(int num) const {
772     assert(validRegister(num));
773     return reg[num];
774   }
775 
776   void setRegister(int num, uint64_t value) {
777     assert(validRegister(num));
778     reg[num] = value;
779   }
780 
781   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
782 
783   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
784 
785   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
786 
787   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
788 
789   bool validFloatVectorRegister(int num) const {
790     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
791   }
792 
793   void copyFloatVectorRegister(int num, uint64_t addr_) {
794     assert(validFloatVectorRegister(num));
795     const void *addr = reinterpret_cast<const void *>(addr_);
796     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
797   }
798 
799   __dso_hidden void jumpto() const __dead;
800 
801 private:
802   uint32_t reg[REGNO_HPPA_R31 + 1];
803   uint32_t fpreg[56];
804 };
805 
806 enum {
807   DWARF_MIPS_R1 = 0,
808   DWARF_MIPS_R31 = 31,
809   DWARF_MIPS_F0 = 32,
810   DWARF_MIPS_F31 = 63,
811 
812   REGNO_MIPS_PC = 0,
813   REGNO_MIPS_R1 = 0,
814   REGNO_MIPS_R29 = 29,
815   REGNO_MIPS_R31 = 31,
816   REGNO_MIPS_F0 = 33,
817   REGNO_MIPS_F31 = 64
818 };
819 
820 class Registers_MIPS {
821 public:
822   enum {
823     LAST_REGISTER = REGNO_MIPS_F31,
824     LAST_RESTORE_REG = REGNO_MIPS_F31,
825     RETURN_OFFSET = 0,
826   };
827 
828   __dso_hidden Registers_MIPS();
829 
830   static int dwarf2regno(int num) {
831     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
832       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
833     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
834       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
835     return LAST_REGISTER + 1;
836   }
837 
838   bool validRegister(int num) const {
839     return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
840   }
841 
842   uint64_t getRegister(int num) const {
843     assert(validRegister(num));
844     return reg[num];
845   }
846 
847   void setRegister(int num, uint64_t value) {
848     assert(validRegister(num));
849     reg[num] = value;
850   }
851 
852   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
853 
854   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
855 
856   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
857 
858   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
859 
860   bool validFloatVectorRegister(int num) const {
861     return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
862   }
863 
864   void copyFloatVectorRegister(int num, uint64_t addr_) {
865     assert(validFloatVectorRegister(num));
866     const void *addr = reinterpret_cast<const void *>(addr_);
867     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
868   }
869 
870   __dso_hidden void jumpto() const __dead;
871 
872 private:
873   uint32_t reg[REGNO_MIPS_R31 + 1];
874   uint64_t fpreg[32];
875 };
876 
877 enum {
878   DWARF_MIPS64_R1 = 0,
879   DWARF_MIPS64_R31 = 31,
880   DWARF_MIPS64_F0 = 32,
881   DWARF_MIPS64_F31 = 63,
882 
883   REGNO_MIPS64_PC = 0,
884   REGNO_MIPS64_R1 = 0,
885   REGNO_MIPS64_R29 = 29,
886   REGNO_MIPS64_R31 = 31,
887   REGNO_MIPS64_F0 = 33,
888   REGNO_MIPS64_F31 = 64
889 };
890 
891 class Registers_MIPS64 {
892 public:
893   enum {
894     LAST_REGISTER = REGNO_MIPS64_F31,
895     LAST_RESTORE_REG = REGNO_MIPS64_F31,
896     RETURN_OFFSET = 0,
897   };
898 
899   __dso_hidden Registers_MIPS64();
900 
901   static int dwarf2regno(int num) {
902     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
903       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
904     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
905       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
906     return LAST_REGISTER + 1;
907   }
908 
909   bool validRegister(int num) const {
910     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
911   }
912 
913   uint64_t getRegister(int num) const {
914     assert(validRegister(num));
915     return reg[num];
916   }
917 
918   void setRegister(int num, uint64_t value) {
919     assert(validRegister(num));
920     reg[num] = value;
921   }
922 
923   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
924 
925   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
926 
927   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
928 
929   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
930 
931   bool validFloatVectorRegister(int num) const {
932     return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
933   }
934 
935   void copyFloatVectorRegister(int num, uint64_t addr_) {
936     assert(validFloatVectorRegister(num));
937     const void *addr = reinterpret_cast<const void *>(addr_);
938     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
939   }
940 
941   __dso_hidden void jumpto() const __dead;
942 
943 private:
944   uint64_t reg[REGNO_MIPS64_R31 + 1];
945   uint64_t fpreg[32];
946 };
947 
948 #if __i386__
949 typedef Registers_x86 NativeUnwindRegisters;
950 #elif __x86_64__
951 typedef Registers_x86_64 NativeUnwindRegisters;
952 #elif __powerpc__
953 typedef Registers_ppc32 NativeUnwindRegisters;
954 #elif __arm__
955 typedef Registers_arm32 NativeUnwindRegisters;
956 #elif __vax__
957 typedef Registers_vax NativeUnwindRegisters;
958 #elif __m68k__
959 typedef Registers_M68K NativeUnwindRegisters;
960 #elif __mips_n64 || __mips_n32
961 typedef Registers_MIPS64 NativeUnwindRegisters;
962 #elif __mips__
963 typedef Registers_MIPS NativeUnwindRegisters;
964 #elif __sh3__
965 typedef Registers_SH3 NativeUnwindRegisters;
966 #elif __sparc64__
967 typedef Registers_SPARC64 NativeUnwindRegisters;
968 #elif __sparc__
969 typedef Registers_SPARC NativeUnwindRegisters;
970 #elif __alpha__
971 typedef Registers_Alpha NativeUnwindRegisters;
972 #elif __hppa__
973 typedef Registers_HPPA NativeUnwindRegisters;
974 #endif
975 } // namespace _Unwind
976 
977 #endif // __REGISTERS_HPP__
978