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     RETURN_MASK = 0,
39   };
40 
41   __dso_hidden Registers_x86();
42 
dwarf2regno(int num)43   static int dwarf2regno(int num) { return num; }
44 
validRegister(int num) const45   bool validRegister(int num) const {
46     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
47   }
48 
getRegister(int num) const49   uint32_t getRegister(int num) const {
50     assert(validRegister(num));
51     return reg[num];
52   }
53 
setRegister(int num,uint32_t value)54   void setRegister(int num, uint32_t value) {
55     assert(validRegister(num));
56     reg[num] = value;
57   }
58 
getIP() const59   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
60 
setIP(uint32_t value)61   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
62 
getSP() const63   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
64 
setSP(uint32_t value)65   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
66 
validFloatVectorRegister(int num) const67   bool validFloatVectorRegister(int num) const { return false; }
68 
copyFloatVectorRegister(int num,uint32_t addr)69   void copyFloatVectorRegister(int num, uint32_t addr) {
70   }
71 
72   __dso_hidden void jumpto() const __dead;
73 
74 private:
75   uint32_t reg[REGNO_X86_EIP + 1];
76 };
77 
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,
96 };
97 
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,
105   };
106 
107   __dso_hidden Registers_x86_64();
108 
dwarf2regno(int num)109   static int dwarf2regno(int num) { return num; }
110 
validRegister(int num) const111   bool validRegister(int num) const {
112     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
113   }
114 
getRegister(int num) const115   uint64_t getRegister(int num) const {
116     assert(validRegister(num));
117     return reg[num];
118   }
119 
setRegister(int num,uint64_t value)120   void setRegister(int num, uint64_t value) {
121     assert(validRegister(num));
122     reg[num] = value;
123   }
124 
getIP() const125   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
126 
setIP(uint64_t value)127   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
128 
getSP() const129   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
130 
setSP(uint64_t value)131   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
132 
validFloatVectorRegister(int num) const133   bool validFloatVectorRegister(int num) const { return false; }
134 
copyFloatVectorRegister(int num,uint64_t addr)135   void copyFloatVectorRegister(int num, uint64_t addr) {
136   }
137 
138   __dso_hidden void jumpto() const __dead;
139 
140 private:
141   uint64_t reg[REGNO_X86_64_RIP + 1];
142 };
143 
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,
153 
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,
160 
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,
165 };
166 
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,
174   };
175 
176   __dso_hidden Registers_ppc32();
177 
dwarf2regno(int num)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;
192     }
193   }
194 
validRegister(int num) const195   bool validRegister(int num) const {
196     return num >= 0 && num <= LAST_RESTORE_REG;
197   }
198 
getRegister(int num) const199   uint64_t getRegister(int num) const {
200     assert(validRegister(num));
201     return reg[num];
202   }
203 
setRegister(int num,uint64_t value)204   void setRegister(int num, uint64_t value) {
205     assert(validRegister(num));
206     reg[num] = value;
207   }
208 
getIP() const209   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
210 
setIP(uint64_t value)211   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
212 
getSP() const213   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
214 
setSP(uint64_t value)215   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
216 
validFloatVectorRegister(int num) const217   bool validFloatVectorRegister(int num) const {
218     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
219            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
220   }
221 
copyFloatVectorRegister(int num,uint64_t addr_)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]));
228   }
229 
230   __dso_hidden void jumpto() const __dead;
231 
232 private:
233   struct vecreg_t {
234     uint64_t low, high;
235   };
236   uint32_t reg[REGNO_PPC32_SRR0 + 1];
237   uint32_t dummy;
238   uint64_t fpreg[32];
239   vecreg_t vecreg[64];
240 };
241 
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,
249 
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,
256 };
257 
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,
265   };
266 
267   __dso_hidden Registers_aarch64();
268 
dwarf2regno(int num)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;
279   }
280 
validRegister(int num) const281   bool validRegister(int num) const {
282     return num >= 0 && num <= LAST_RESTORE_REG;
283   }
284 
getRegister(int num) const285   uint64_t getRegister(int num) const {
286     assert(validRegister(num));
287     return reg[num];
288   }
289 
setRegister(int num,uint64_t value)290   void setRegister(int num, uint64_t value) {
291     assert(validRegister(num));
292     reg[num] = value;
293   }
294 
getIP() const295   uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
296 
setIP(uint64_t value)297   void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
298 
getSP() const299   uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
300 
setSP(uint64_t value)301   void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
302 
validFloatVectorRegister(int num) const303   bool validFloatVectorRegister(int num) const {
304     return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
305   }
306 
copyFloatVectorRegister(int num,uint64_t addr_)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]));
310   }
311 
312   __dso_hidden void jumpto() const __dead;
313 
314 private:
315   struct vecreg_t {
316     uint64_t low, high;
317   };
318   uint64_t reg[REGNO_AARCH64_ELR_MODE + 1];
319   vecreg_t vecreg[32];
320 };
321 
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,
337 };
338 
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,
346   };
347 
348   __dso_hidden Registers_arm32();
349 
dwarf2regno(int num)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;
360     }
361     return LAST_REGISTER + 1;
362   }
363 
validRegister(int num) const364   bool validRegister(int num) const {
365     return num >= 0 && num <= REGNO_ARM32_SPSR;
366   }
367 
getRegister(int num) const368   uint64_t getRegister(int num) const {
369     assert(validRegister(num));
370     return reg[num];
371   }
372 
setRegister(int num,uint64_t value)373   void setRegister(int num, uint64_t value) {
374     assert(validRegister(num));
375     reg[num] = value;
376   }
377 
getIP() const378   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
379 
setIP(uint64_t value)380   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
381 
getSP() const382   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
383 
setSP(uint64_t value)384   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
385 
validFloatVectorRegister(int num) const386   bool validFloatVectorRegister(int num) const {
387     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
388   }
389 
copyFloatVectorRegister(int num,uint64_t addr_)390   void copyFloatVectorRegister(int num, uint64_t addr_) {
391     if (num <= REGNO_ARM32_D15) {
392       if ((flags & 1) == 0) {
393         lazyVFP1();
394         flags |= 1;
395       }
396     } else {
397       if ((flags & 2) == 0) {
398         lazyVFP3();
399         flags |= 2;
400       }
401     }
402     const void *addr = reinterpret_cast<const void *>(addr_);
403     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
404   }
405 
406   __dso_hidden void lazyVFP1();
407   __dso_hidden void lazyVFP3();
408   __dso_hidden void jumpto() const __dead;
409 
410 private:
411   uint32_t reg[REGNO_ARM32_SPSR + 1];
412   uint32_t flags;
413   uint64_t fpreg[32];
414 };
415 
416 enum {
417   DWARF_VAX_R0 = 0,
418   DWARF_VAX_R15 = 15,
419   DWARF_VAX_PSW = 16,
420 
421   REGNO_VAX_R0 = 0,
422   REGNO_VAX_R14 = 14,
423   REGNO_VAX_R15 = 15,
424   REGNO_VAX_PSW = 16,
425 };
426 
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,
434   };
435 
436   __dso_hidden Registers_vax();
437 
dwarf2regno(int num)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;
444   }
445 
validRegister(int num) const446   bool validRegister(int num) const {
447     return num >= 0 && num <= LAST_RESTORE_REG;
448   }
449 
getRegister(int num) const450   uint64_t getRegister(int num) const {
451     assert(validRegister(num));
452     return reg[num];
453   }
454 
setRegister(int num,uint64_t value)455   void setRegister(int num, uint64_t value) {
456     assert(validRegister(num));
457     reg[num] = value;
458   }
459 
getIP() const460   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
461 
setIP(uint64_t value)462   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
463 
getSP() const464   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
465 
setSP(uint64_t value)466   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
467 
validFloatVectorRegister(int num) const468   bool validFloatVectorRegister(int num) const {
469     return false;
470   }
471 
copyFloatVectorRegister(int num,uint64_t addr_)472   void copyFloatVectorRegister(int num, uint64_t addr_) {
473   }
474 
475   __dso_hidden void jumpto() const __dead;
476 
477 private:
478   uint32_t reg[REGNO_VAX_PSW + 1];
479 };
480 
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,
489 
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,
497 };
498 
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,
506   };
507 
508   __dso_hidden Registers_M68K();
509 
dwarf2regno(int num)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;
520   }
521 
validRegister(int num) const522   bool validRegister(int num) const {
523     return num >= 0 && num <= REGNO_M68K_PC;
524   }
525 
getRegister(int num) const526   uint64_t getRegister(int num) const {
527     assert(validRegister(num));
528     return reg[num];
529   }
530 
setRegister(int num,uint64_t value)531   void setRegister(int num, uint64_t value) {
532     assert(validRegister(num));
533     reg[num] = value;
534   }
535 
getIP() const536   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
537 
setIP(uint64_t value)538   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
539 
getSP() const540   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
541 
setSP(uint64_t value)542   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
543 
validFloatVectorRegister(int num) const544   bool validFloatVectorRegister(int num) const {
545     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
546   }
547 
copyFloatVectorRegister(int num,uint64_t addr_)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]));
552   }
553 
554   __dso_hidden void jumpto() const __dead;
555 
556 private:
557   typedef uint32_t fpreg_t[3];
558 
559   uint32_t reg[REGNO_M68K_PC + 1];
560   uint32_t dummy;
561   fpreg_t fpreg[8];
562 };
563 
564 enum {
565   DWARF_SH3_R0 = 0,
566   DWARF_SH3_R15 = 15,
567   DWARF_SH3_PC = 16,
568   DWARF_SH3_PR = 17,
569 
570   REGNO_SH3_R0 = 0,
571   REGNO_SH3_R15 = 15,
572   REGNO_SH3_PC = 16,
573   REGNO_SH3_PR = 17,
574 };
575 
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,
583   };
584 
585   __dso_hidden Registers_SH3();
586 
dwarf2regno(int num)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;
595   }
596 
validRegister(int num) const597   bool validRegister(int num) const {
598     return num >= 0 && num <= REGNO_SH3_PR;
599   }
600 
getRegister(int num) const601   uint64_t getRegister(int num) const {
602     assert(validRegister(num));
603     return reg[num];
604   }
605 
setRegister(int num,uint64_t value)606   void setRegister(int num, uint64_t value) {
607     assert(validRegister(num));
608     reg[num] = value;
609   }
610 
getIP() const611   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
612 
setIP(uint64_t value)613   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
614 
getSP() const615   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
616 
setSP(uint64_t value)617   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
618 
validFloatVectorRegister(int num) const619   bool validFloatVectorRegister(int num) const { return false; }
620 
copyFloatVectorRegister(int num,uint64_t addr_)621   void copyFloatVectorRegister(int num, uint64_t addr_) {}
622 
623   __dso_hidden void jumpto() const __dead;
624 
625 private:
626   uint32_t reg[REGNO_SH3_PR + 1];
627 };
628 
629 enum {
630   DWARF_SPARC64_R0 = 0,
631   DWARF_SPARC64_R31 = 31,
632   DWARF_SPARC64_PC = 32,
633 
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,
639 };
640 
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,
648   };
649   typedef uint64_t reg_t;
650 
651   __dso_hidden Registers_SPARC64();
652 
dwarf2regno(int num)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;
659   }
660 
validRegister(int num) const661   bool validRegister(int num) const {
662     return num >= 0 && num <= REGNO_SPARC64_PC;
663   }
664 
getRegister(int num) const665   uint64_t getRegister(int num) const {
666     assert(validRegister(num));
667     return reg[num];
668   }
669 
setRegister(int num,uint64_t value)670   void setRegister(int num, uint64_t value) {
671     assert(validRegister(num));
672     reg[num] = value;
673   }
674 
getIP() const675   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
676 
setIP(uint64_t value)677   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
678 
getSP() const679   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
680 
setSP(uint64_t value)681   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
682 
validFloatVectorRegister(int num) const683   bool validFloatVectorRegister(int num) const { return false; }
684 
copyFloatVectorRegister(int num,uint64_t addr_)685   void copyFloatVectorRegister(int num, uint64_t addr_) {}
686 
687   __dso_hidden void jumpto() const __dead;
688 
689 private:
690   uint64_t reg[REGNO_SPARC64_PC + 1];
691 };
692 
693 enum {
694   DWARF_SPARC_R0 = 0,
695   DWARF_SPARC_R31 = 31,
696   DWARF_SPARC_PC = 32,
697 
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,
703 };
704 
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,
712   };
713   typedef uint32_t reg_t;
714 
715   __dso_hidden Registers_SPARC();
716 
dwarf2regno(int num)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;
723   }
724 
validRegister(int num) const725   bool validRegister(int num) const {
726     return num >= 0 && num <= REGNO_SPARC_PC;
727   }
728 
getRegister(int num) const729   uint64_t getRegister(int num) const {
730     assert(validRegister(num));
731     return reg[num];
732   }
733 
setRegister(int num,uint64_t value)734   void setRegister(int num, uint64_t value) {
735     assert(validRegister(num));
736     reg[num] = value;
737   }
738 
getIP() const739   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
740 
setIP(uint64_t value)741   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
742 
getSP() const743   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
744 
setSP(uint64_t value)745   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
746 
validFloatVectorRegister(int num) const747   bool validFloatVectorRegister(int num) const { return false; }
748 
copyFloatVectorRegister(int num,uint64_t addr_)749   void copyFloatVectorRegister(int num, uint64_t addr_) {}
750 
751   __dso_hidden void jumpto() const __dead;
752 
753 private:
754   uint32_t reg[REGNO_SPARC_PC + 1];
755 };
756 
757 enum {
758   DWARF_ALPHA_R0 = 0,
759   DWARF_ALPHA_R30 = 30,
760   DWARF_ALPHA_F0 = 32,
761   DWARF_ALPHA_F30 = 62,
762 
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,
769 };
770 
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,
778   };
779   typedef uint32_t reg_t;
780 
781   __dso_hidden Registers_Alpha();
782 
dwarf2regno(int num)783   static int dwarf2regno(int num) { return num; }
784 
validRegister(int num) const785   bool validRegister(int num) const {
786     return num >= 0 && num <= REGNO_ALPHA_PC;
787   }
788 
getRegister(int num) const789   uint64_t getRegister(int num) const {
790     assert(validRegister(num));
791     return reg[num];
792   }
793 
setRegister(int num,uint64_t value)794   void setRegister(int num, uint64_t value) {
795     assert(validRegister(num));
796     reg[num] = value;
797   }
798 
getIP() const799   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
800 
setIP(uint64_t value)801   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
802 
getSP() const803   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
804 
setSP(uint64_t value)805   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
806 
validFloatVectorRegister(int num) const807   bool validFloatVectorRegister(int num) const {
808     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
809   }
810 
copyFloatVectorRegister(int num,uint64_t addr_)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]));
815   }
816 
817   __dso_hidden void jumpto() const __dead;
818 
819 private:
820   uint64_t reg[REGNO_ALPHA_PC + 1];
821   uint64_t fpreg[31];
822 };
823 
824 enum {
825   DWARF_HPPA_R1 = 1,
826   DWARF_HPPA_R31 = 31,
827   DWARF_HPPA_FR4L = 32,
828   DWARF_HPPA_FR31H = 87,
829 
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,
837 };
838 
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,
846   };
847 
848   __dso_hidden Registers_HPPA();
849 
dwarf2regno(int num)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;
856   }
857 
validRegister(int num) const858   bool validRegister(int num) const {
859     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
860   }
861 
getRegister(int num) const862   uint64_t getRegister(int num) const {
863     assert(validRegister(num));
864     return reg[num];
865   }
866 
setRegister(int num,uint64_t value)867   void setRegister(int num, uint64_t value) {
868     assert(validRegister(num));
869     reg[num] = value;
870   }
871 
getIP() const872   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
873 
setIP(uint64_t value)874   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
875 
getSP() const876   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
877 
setSP(uint64_t value)878   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
879 
validFloatVectorRegister(int num) const880   bool validFloatVectorRegister(int num) const {
881     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
882   }
883 
copyFloatVectorRegister(int num,uint64_t addr_)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]));
888   }
889 
890   __dso_hidden void jumpto() const __dead;
891 
892 private:
893   uint32_t reg[REGNO_HPPA_R31 + 1];
894   uint32_t fpreg[56];
895 };
896 
897 enum {
898   DWARF_MIPS_R1 = 0,
899   DWARF_MIPS_R31 = 31,
900   DWARF_MIPS_F0 = 32,
901   DWARF_MIPS_F31 = 63,
902 
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
909 };
910 
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,
918   };
919 
920   __dso_hidden Registers_MIPS();
921 
dwarf2regno(int num)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;
928   }
929 
validRegister(int num) const930   bool validRegister(int num) const {
931     return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
932   }
933 
getRegister(int num) const934   uint64_t getRegister(int num) const {
935     assert(validRegister(num));
936     return reg[num];
937   }
938 
setRegister(int num,uint64_t value)939   void setRegister(int num, uint64_t value) {
940     assert(validRegister(num));
941     reg[num] = value;
942   }
943 
getIP() const944   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
945 
setIP(uint64_t value)946   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
947 
getSP() const948   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
949 
setSP(uint64_t value)950   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
951 
validFloatVectorRegister(int num) const952   bool validFloatVectorRegister(int num) const {
953     return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
954   }
955 
copyFloatVectorRegister(int num,uint64_t addr_)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]));
960   }
961 
962   __dso_hidden void jumpto() const __dead;
963 
964 private:
965   uint32_t reg[REGNO_MIPS_R31 + 1];
966   uint64_t fpreg[32];
967 };
968 
969 enum {
970   DWARF_MIPS64_R1 = 0,
971   DWARF_MIPS64_R31 = 31,
972   DWARF_MIPS64_F0 = 32,
973   DWARF_MIPS64_F31 = 63,
974 
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
981 };
982 
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,
990   };
991 
992   __dso_hidden Registers_MIPS64();
993 
dwarf2regno(int num)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;
1000   }
1001 
validRegister(int num) const1002   bool validRegister(int num) const {
1003     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
1004   }
1005 
getRegister(int num) const1006   uint64_t getRegister(int num) const {
1007     assert(validRegister(num));
1008     return reg[num];
1009   }
1010 
setRegister(int num,uint64_t value)1011   void setRegister(int num, uint64_t value) {
1012     assert(validRegister(num));
1013     reg[num] = value;
1014   }
1015 
getIP() const1016   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1017 
setIP(uint64_t value)1018   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1019 
getSP() const1020   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1021 
setSP(uint64_t value)1022   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1023 
validFloatVectorRegister(int num) const1024   bool validFloatVectorRegister(int num) const {
1025     return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
1026   }
1027 
copyFloatVectorRegister(int num,uint64_t addr_)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]));
1032   }
1033 
1034   __dso_hidden void jumpto() const __dead;
1035 
1036 private:
1037   uint64_t reg[REGNO_MIPS64_R31 + 1];
1038   uint64_t fpreg[32];
1039 };
1040 
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,
1047 
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,
1053 };
1054 
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,
1062   };
1063 
1064   __dso_hidden Registers_or1k();
1065 
dwarf2regno(int num)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;
1072   }
1073 
validRegister(int num) const1074   bool validRegister(int num) const {
1075     return num >= 0 && num <= LAST_RESTORE_REG;
1076   }
1077 
getRegister(int num) const1078   uint64_t getRegister(int num) const {
1079     assert(validRegister(num));
1080     return reg[num];
1081   }
1082 
setRegister(int num,uint64_t value)1083   void setRegister(int num, uint64_t value) {
1084     assert(validRegister(num));
1085     reg[num] = value;
1086   }
1087 
getIP() const1088   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1089 
setIP(uint64_t value)1090   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1091 
getSP() const1092   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1093 
setSP(uint64_t value)1094   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1095 
validFloatVectorRegister(int num) const1096   bool validFloatVectorRegister(int num) const {
1097     return false;
1098   }
1099 
copyFloatVectorRegister(int num,uint64_t addr_)1100   void copyFloatVectorRegister(int num, uint64_t addr_) {
1101   }
1102 
1103   __dso_hidden void jumpto() const __dead;
1104 
1105 private:
1106   uint32_t reg[REGNO_OR1K_FPCSR + 1];
1107 };
1108 
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
1141 
1142 #endif // __REGISTERS_HPP__
1143