xref: /netbsd-src/sys/lib/libunwind/Registers.hpp (revision 1dbc3f1d7906aa4b42c345b1bd13899bdd7e2a76)
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 
891   __dso_hidden Registers_Alpha();
892 
dwarf2regno(int num)893   static int dwarf2regno(int num) { return num; }
894 
validRegister(int num) const895   bool validRegister(int num) const {
896     return (num >= 0 && num <= REGNO_ALPHA_PC) ||
897 	num == REGNO_ALPHA_SIGRETURN;
898   }
899 
getRegister(int num) const900   uint64_t getRegister(int num) const {
901     assert(validRegister(num));
902     if (num == REGNO_ALPHA_SIGRETURN)
903       return sigreturn_reg;
904     else
905       return reg[num];
906   }
907 
setRegister(int num,uint64_t value)908   void setRegister(int num, uint64_t value) {
909     assert(validRegister(num));
910     if (num == REGNO_ALPHA_SIGRETURN)
911       sigreturn_reg = value;
912     else
913       reg[num] = value;
914   }
915 
getIP() const916   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
917 
setIP(uint64_t value)918   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
919 
getSP() const920   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
921 
setSP(uint64_t value)922   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
923 
validFloatVectorRegister(int num) const924   bool validFloatVectorRegister(int num) const {
925     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
926   }
927 
copyFloatVectorRegister(int num,uint64_t addr_)928   void copyFloatVectorRegister(int num, uint64_t addr_) {
929     assert(validFloatVectorRegister(num));
930     const void *addr = reinterpret_cast<const void *>(addr_);
931     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
932   }
933 
934   __dso_hidden void jumpto() const __dead;
935 
936 private:
937   uint64_t reg[REGNO_ALPHA_PC + 1];
938   uint64_t fpreg[31];
939   uint64_t sigreturn_reg;
940 };
941 
942 enum {
943   DWARF_HPPA_R1 = 1,
944   DWARF_HPPA_R31 = 31,
945   DWARF_HPPA_FR4L = 32,
946   DWARF_HPPA_FR31H = 87,
947   DWARF_HPPA_SIGRETURN = 89,
948 
949   REGNO_HPPA_PC = 0,
950   REGNO_HPPA_R1 = 1,
951   REGNO_HPPA_R2 = 2,
952   REGNO_HPPA_R30 = 30,
953   REGNO_HPPA_R31 = 31,
954   REGNO_HPPA_FR4L = 32,
955   REGNO_HPPA_FR31H = 87,
956   REGNO_HPPA_SIGRETURN = 89,
957 };
958 
959 class Registers_HPPA {
960 public:
961   enum {
962     LAST_REGISTER = REGNO_HPPA_FR31H,
963     LAST_RESTORE_REG = REGNO_HPPA_SIGRETURN,
964     RETURN_OFFSET = 0,
965     RETURN_MASK = 3,
966   };
967 
968   __dso_hidden Registers_HPPA();
969 
dwarf2regno(int num)970   static int dwarf2regno(int num) {
971     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
972       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
973     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
974       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
975     if (num == DWARF_HPPA_SIGRETURN)
976       return REGNO_HPPA_SIGRETURN;
977     return LAST_REGISTER + 1;
978   }
979 
validRegister(int num) const980   bool validRegister(int num) const {
981     return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) ||
982        num == REGNO_HPPA_SIGRETURN;
983   }
984 
getRegister(int num) const985   uint64_t getRegister(int num) const {
986     assert(validRegister(num));
987     if (num == REGNO_HPPA_SIGRETURN)
988       return sigreturn_reg;
989     else
990       return reg[num];
991   }
992 
setRegister(int num,uint64_t value)993   void setRegister(int num, uint64_t value) {
994     assert(validRegister(num));
995     if (num == REGNO_HPPA_SIGRETURN)
996       sigreturn_reg = value;
997     else
998       reg[num] = value;
999   }
1000 
getIP() const1001   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
1002 
setIP(uint64_t value)1003   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
1004 
getSP() const1005   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
1006 
setSP(uint64_t value)1007   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
1008 
validFloatVectorRegister(int num) const1009   bool validFloatVectorRegister(int num) const {
1010     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
1011   }
1012 
copyFloatVectorRegister(int num,uint64_t addr_)1013   void copyFloatVectorRegister(int num, uint64_t addr_) {
1014     assert(validFloatVectorRegister(num));
1015     const void *addr = reinterpret_cast<const void *>(addr_);
1016     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
1017   }
1018 
1019   __dso_hidden void jumpto() const __dead;
1020 
1021 private:
1022   uint32_t reg[REGNO_HPPA_R31 + 1];
1023   uint32_t fpreg[56];
1024   uint32_t sigreturn_reg;
1025 };
1026 
1027 enum {
1028   DWARF_MIPS_R1 = 0,
1029   DWARF_MIPS_R31 = 31,
1030   DWARF_MIPS_F0 = 32,
1031   DWARF_MIPS_F31 = 63,
1032   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
1033   // signal handler return address.
1034   DWARF_MIPS_MDHI = 64,
1035   DWARF_MIPS_MDLO = 65,
1036   DWARF_MIPS_SIGRETURN = 66,
1037 
1038   REGNO_MIPS_PC = 0,
1039   REGNO_MIPS_R1 = 0,
1040   REGNO_MIPS_R29 = 29,
1041   REGNO_MIPS_R31 = 31,
1042   REGNO_MIPS_F0 = 33,
1043   REGNO_MIPS_F31 = 64,
1044   // these live in other_reg[]
1045   REGNO_MIPS_MDHI = 65,
1046   REGNO_MIPS_MDLO = 66,
1047   REGNO_MIPS_SIGRETURN = 67
1048 };
1049 
1050 class Registers_MIPS {
1051 public:
1052   enum {
1053     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
1054     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
1055     RETURN_OFFSET = 0,
1056     RETURN_MASK = 0,
1057   };
1058 
1059   __dso_hidden Registers_MIPS();
1060 
dwarf2regno(int num)1061   static int dwarf2regno(int num) {
1062     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
1063       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
1064     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
1065       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
1066     if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN)
1067       return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI);
1068     return LAST_REGISTER + 1;
1069   }
1070 
validRegister(int num) const1071   bool validRegister(int num) const {
1072     return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) ||
1073       (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN);
1074   }
1075 
getRegister(int num) const1076   uint64_t getRegister(int num) const {
1077     assert(validRegister(num));
1078     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
1079       return other_reg[num - REGNO_MIPS_MDHI];
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     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
1086       other_reg[num - REGNO_MIPS_MDHI] = value;
1087     else
1088       reg[num] = value;
1089   }
1090 
getIP() const1091   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
1092 
setIP(uint64_t value)1093   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
1094 
getSP() const1095   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
1096 
setSP(uint64_t value)1097   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
1098 
validFloatVectorRegister(int num) const1099   bool validFloatVectorRegister(int num) const {
1100     return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
1101   }
1102 
copyFloatVectorRegister(int num,uint64_t addr_)1103   void copyFloatVectorRegister(int num, uint64_t addr_) {
1104     assert(validFloatVectorRegister(num));
1105     const void *addr = reinterpret_cast<const void *>(addr_);
1106     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
1107   }
1108 
1109   __dso_hidden void jumpto() const __dead;
1110 
1111 private:
1112   uint32_t reg[REGNO_MIPS_R31 + 1];
1113   uint64_t fpreg[32];
1114   uint32_t other_reg[3];
1115 };
1116 
1117 enum {
1118   DWARF_MIPS64_R1 = 0,
1119   DWARF_MIPS64_R31 = 31,
1120   DWARF_MIPS64_F0 = 32,
1121   DWARF_MIPS64_F31 = 63,
1122   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
1123   // signal handler return address.
1124   DWARF_MIPS64_MDHI = 64,
1125   DWARF_MIPS64_MDLO = 65,
1126   DWARF_MIPS64_SIGRETURN = 66,
1127 
1128   REGNO_MIPS64_PC = 0,
1129   REGNO_MIPS64_R1 = 0,
1130   REGNO_MIPS64_R29 = 29,
1131   REGNO_MIPS64_R31 = 31,
1132   REGNO_MIPS64_F0 = 33,
1133   REGNO_MIPS64_F31 = 64,
1134   // these live in other_reg[]
1135   REGNO_MIPS64_MDHI = 65,
1136   REGNO_MIPS64_MDLO = 66,
1137   REGNO_MIPS64_SIGRETURN = 67
1138 };
1139 
1140 class Registers_MIPS64 {
1141 public:
1142   enum {
1143     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
1144     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
1145     RETURN_OFFSET = 0,
1146     RETURN_MASK = 0,
1147   };
1148 
1149   __dso_hidden Registers_MIPS64();
1150 
dwarf2regno(int num)1151   static int dwarf2regno(int num) {
1152     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
1153       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
1154     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
1155       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
1156     if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN)
1157       return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI);
1158     return LAST_REGISTER + 1;
1159   }
1160 
validRegister(int num) const1161   bool validRegister(int num) const {
1162     return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) ||
1163         (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN);
1164   }
1165 
getRegister(int num) const1166   uint64_t getRegister(int num) const {
1167     assert(validRegister(num));
1168     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1169       return other_reg[num - REGNO_MIPS64_MDHI];
1170     return reg[num];
1171   }
1172 
setRegister(int num,uint64_t value)1173   void setRegister(int num, uint64_t value) {
1174     assert(validRegister(num));
1175     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1176       other_reg[num - REGNO_MIPS64_MDHI] = value;
1177     else
1178       reg[num] = value;
1179   }
1180 
getIP() const1181   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1182 
setIP(uint64_t value)1183   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1184 
getSP() const1185   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1186 
setSP(uint64_t value)1187   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1188 
validFloatVectorRegister(int num) const1189   bool validFloatVectorRegister(int num) const {
1190     return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
1191   }
1192 
copyFloatVectorRegister(int num,uint64_t addr_)1193   void copyFloatVectorRegister(int num, uint64_t addr_) {
1194     assert(validFloatVectorRegister(num));
1195     const void *addr = reinterpret_cast<const void *>(addr_);
1196     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
1197   }
1198 
1199   __dso_hidden void jumpto() const __dead;
1200 
1201 private:
1202   uint64_t reg[REGNO_MIPS64_R31 + 1];
1203   uint64_t fpreg[32];
1204   uint64_t other_reg[3];
1205 };
1206 
1207 enum {
1208   DWARF_OR1K_R0 = 0,
1209   DWARF_OR1K_SP = 1,
1210   DWARF_OR1K_LR = 9,
1211   DWARF_OR1K_R31 = 31,
1212   DWARF_OR1K_FPCSR = 32,
1213 
1214   REGNO_OR1K_R0 = 0,
1215   REGNO_OR1K_SP = 1,
1216   REGNO_OR1K_LR = 9,
1217   REGNO_OR1K_R31 = 31,
1218   REGNO_OR1K_FPCSR = 32,
1219 };
1220 
1221 class Registers_or1k {
1222 public:
1223   enum {
1224     LAST_REGISTER = REGNO_OR1K_FPCSR,
1225     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1226     RETURN_OFFSET = 0,
1227     RETURN_MASK = 0,
1228   };
1229 
1230   __dso_hidden Registers_or1k();
1231 
dwarf2regno(int num)1232   static int dwarf2regno(int num) {
1233     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1234       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1235     if (num == DWARF_OR1K_FPCSR)
1236       return REGNO_OR1K_FPCSR;
1237     return LAST_REGISTER + 1;
1238   }
1239 
validRegister(int num) const1240   bool validRegister(int num) const {
1241     return num >= 0 && num <= LAST_RESTORE_REG;
1242   }
1243 
getRegister(int num) const1244   uint64_t getRegister(int num) const {
1245     assert(validRegister(num));
1246     return reg[num];
1247   }
1248 
setRegister(int num,uint64_t value)1249   void setRegister(int num, uint64_t value) {
1250     assert(validRegister(num));
1251     reg[num] = value;
1252   }
1253 
getIP() const1254   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1255 
setIP(uint64_t value)1256   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1257 
getSP() const1258   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1259 
setSP(uint64_t value)1260   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1261 
validFloatVectorRegister(int num) const1262   bool validFloatVectorRegister(int num) const {
1263     return false;
1264   }
1265 
copyFloatVectorRegister(int num,uint64_t addr_)1266   void copyFloatVectorRegister(int num, uint64_t addr_) {
1267   }
1268 
1269   __dso_hidden void jumpto() const __dead;
1270 
1271 private:
1272   uint32_t reg[REGNO_OR1K_FPCSR + 1];
1273 };
1274 
1275 #if __i386__
1276 typedef Registers_x86 NativeUnwindRegisters;
1277 #elif __x86_64__
1278 typedef Registers_x86_64 NativeUnwindRegisters;
1279 #elif __powerpc__
1280 typedef Registers_ppc32 NativeUnwindRegisters;
1281 #elif __aarch64__
1282 typedef Registers_aarch64 NativeUnwindRegisters;
1283 #elif __arm__
1284 typedef Registers_arm32 NativeUnwindRegisters;
1285 #elif __vax__
1286 typedef Registers_vax NativeUnwindRegisters;
1287 #elif __m68k__
1288 typedef Registers_M68K NativeUnwindRegisters;
1289 #elif __mips_n64 || __mips_n32
1290 typedef Registers_MIPS64 NativeUnwindRegisters;
1291 #elif __mips__
1292 typedef Registers_MIPS NativeUnwindRegisters;
1293 #elif __sh3__
1294 typedef Registers_SH3 NativeUnwindRegisters;
1295 #elif __sparc64__
1296 typedef Registers_SPARC64 NativeUnwindRegisters;
1297 #elif __sparc__
1298 typedef Registers_SPARC NativeUnwindRegisters;
1299 #elif __alpha__
1300 typedef Registers_Alpha NativeUnwindRegisters;
1301 #elif __hppa__
1302 typedef Registers_HPPA NativeUnwindRegisters;
1303 #elif __or1k__
1304 typedef Registers_or1k NativeUnwindRegisters;
1305 #endif
1306 } // namespace _Unwind
1307 
1308 #endif // __REGISTERS_HPP__
1309