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