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
19namespace _Unwind {
20
21enum {
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
33class Registers_x86 {
34public:
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
44  static int dwarf2regno(int num) { return num; }
45
46  bool validRegister(int num) const {
47    return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
48  }
49
50  uint32_t getRegister(int num) const {
51    assert(validRegister(num));
52    return reg[num];
53  }
54
55  void setRegister(int num, uint32_t value) {
56    assert(validRegister(num));
57    reg[num] = value;
58  }
59
60  uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
61
62  void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
63
64  uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
65
66  void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
67
68  bool validFloatVectorRegister(int num) const { return false; }
69
70  void copyFloatVectorRegister(int num, uint32_t addr) {
71  }
72
73  __dso_hidden void jumpto() const __dead;
74
75private:
76  uint32_t reg[REGNO_X86_EIP + 1];
77};
78
79enum {
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
99class Registers_x86_64 {
100public:
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
110  static int dwarf2regno(int num) { return num; }
111
112  bool validRegister(int num) const {
113    return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
114  }
115
116  uint64_t getRegister(int num) const {
117    assert(validRegister(num));
118    return reg[num];
119  }
120
121  void setRegister(int num, uint64_t value) {
122    assert(validRegister(num));
123    reg[num] = value;
124  }
125
126  uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
127
128  void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
129
130  uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
131
132  void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
133
134  bool validFloatVectorRegister(int num) const { return false; }
135
136  void copyFloatVectorRegister(int num, uint64_t addr) {
137  }
138
139  __dso_hidden void jumpto() const __dead;
140
141private:
142  uint64_t reg[REGNO_X86_64_RIP + 1];
143};
144
145enum {
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
175class Registers_ppc32 {
176public:
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
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
209  bool validRegister(int num) const {
210    return (num >= 0 && num <= REGNO_PPC32_SRR0) ||
211	(num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN);
212  }
213
214  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
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
245  uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
246
247  void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
248
249  uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
250
251  void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
252
253  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
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
268private:
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
281enum {
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
297class Registers_aarch64 {
298public:
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
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
320  bool validRegister(int num) const {
321    return (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_SP) ||
322	num == DWARF_AARCH64_SIGRETURN;
323  }
324
325  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
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
340  uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
341
342  void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
343
344  uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
345
346  void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
347
348  bool validFloatVectorRegister(int num) const {
349    return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
350  }
351
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
359private:
360  uint64_t reg[REGNO_AARCH64_SP + 1];
361  uint64_t vecreg[64];
362  uint64_t sigreturn_reg;
363};
364
365enum {
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
389class Registers_arm32 {
390public:
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
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
412  bool validRegister(int num) const {
413    return num >= 0 && num <= REGNO_ARM32_SPSR;
414  }
415
416  uint64_t getRegister(int num) const {
417    assert(validRegister(num));
418    return reg[num];
419  }
420
421  void setRegister(int num, uint64_t value) {
422    assert(validRegister(num));
423    reg[num] = value;
424  }
425
426  uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
427
428  void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
429
430  uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
431
432  void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
433
434  bool validFloatVectorRegister(int num) const {
435    return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
436  }
437
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
491private:
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
502enum {
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
513class Registers_vax {
514public:
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
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
532  bool validRegister(int num) const {
533    return num >= 0 && num <= LAST_RESTORE_REG;
534  }
535
536  uint64_t getRegister(int num) const {
537    assert(validRegister(num));
538    return reg[num];
539  }
540
541  void setRegister(int num, uint64_t value) {
542    assert(validRegister(num));
543    reg[num] = value;
544  }
545
546  uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
547
548  void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
549
550  uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
551
552  void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
553
554  bool validFloatVectorRegister(int num) const {
555    return false;
556  }
557
558  void copyFloatVectorRegister(int num, uint64_t addr_) {
559  }
560
561  __dso_hidden void jumpto() const __dead;
562
563private:
564  uint32_t reg[REGNO_VAX_PSW + 1];
565};
566
567enum {
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
588class Registers_M68K {
589public:
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
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
611  bool validRegister(int num) const {
612    return num >= 0 && num <= REGNO_M68K_PC;
613  }
614
615  uint64_t getRegister(int num) const {
616    assert(validRegister(num));
617    return reg[num];
618  }
619
620  void setRegister(int num, uint64_t value) {
621    assert(validRegister(num));
622    reg[num] = value;
623  }
624
625  uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
626
627  void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
628
629  uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
630
631  void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
632
633  bool validFloatVectorRegister(int num) const {
634    return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
635  }
636
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
645private:
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
653enum {
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
673class Registers_SH3 {
674public:
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
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
705  bool validRegister(int num) const {
706    return (num >= 0 && num <= REGNO_SH3_GBR) ||
707	(num >= REGNO_SH3_MACH && num <= REGNO_SH3_SR);
708  }
709
710  uint64_t getRegister(int num) const {
711    assert(validRegister(num));
712    return reg[num];
713  }
714
715  void setRegister(int num, uint64_t value) {
716    assert(validRegister(num));
717    reg[num] = value;
718  }
719
720  uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
721
722  void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
723
724  uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
725
726  void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
727
728  bool validFloatVectorRegister(int num) const { return false; }
729
730  void copyFloatVectorRegister(int num, uint64_t addr_) {}
731
732  __dso_hidden void jumpto() const __dead;
733
734private:
735  uint32_t reg[REGNO_SH3_SR + 1];
736};
737
738enum {
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
750class Registers_SPARC64 {
751public:
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
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
770  bool validRegister(int num) const {
771    return num >= 0 && num <= REGNO_SPARC64_PC;
772  }
773
774  uint64_t getRegister(int num) const {
775    assert(validRegister(num));
776    return reg[num];
777  }
778
779  void setRegister(int num, uint64_t value) {
780    assert(validRegister(num));
781    reg[num] = value;
782  }
783
784  uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
785
786  void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
787
788  uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
789
790  void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
791
792  bool validFloatVectorRegister(int num) const { return false; }
793
794  void copyFloatVectorRegister(int num, uint64_t addr_) {}
795
796  __dso_hidden void jumpto() const __dead;
797
798private:
799  uint64_t reg[REGNO_SPARC64_PC + 1];
800};
801
802enum {
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
814class Registers_SPARC {
815public:
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
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
834  bool validRegister(int num) const {
835    return num >= 0 && num <= REGNO_SPARC_PC;
836  }
837
838  uint64_t getRegister(int num) const {
839    assert(validRegister(num));
840    return reg[num];
841  }
842
843  void setRegister(int num, uint64_t value) {
844    assert(validRegister(num));
845    reg[num] = value;
846  }
847
848  uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
849
850  void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
851
852  uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
853
854  void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
855
856  bool validFloatVectorRegister(int num) const { return false; }
857
858  void copyFloatVectorRegister(int num, uint64_t addr_) {}
859
860  __dso_hidden void jumpto() const __dead;
861
862private:
863  uint32_t reg[REGNO_SPARC_PC + 1];
864};
865
866enum {
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
882class Registers_Alpha {
883public:
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
893  static int dwarf2regno(int num) { return num; }
894
895  bool validRegister(int num) const {
896    return (num >= 0 && num <= REGNO_ALPHA_PC) ||
897	num == REGNO_ALPHA_SIGRETURN;
898  }
899
900  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
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
916  uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
917
918  void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
919
920  uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
921
922  void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
923
924  bool validFloatVectorRegister(int num) const {
925    return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
926  }
927
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
936private:
937  uint64_t reg[REGNO_ALPHA_PC + 1];
938  uint64_t fpreg[31];
939  uint64_t sigreturn_reg;
940};
941
942enum {
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
959class Registers_HPPA {
960public:
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
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
980  bool validRegister(int num) const {
981    return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) ||
982       num == REGNO_HPPA_SIGRETURN;
983  }
984
985  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
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
1001  uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
1002
1003  void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
1004
1005  uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
1006
1007  void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
1008
1009  bool validFloatVectorRegister(int num) const {
1010    return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
1011  }
1012
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
1021private:
1022  uint32_t reg[REGNO_HPPA_R31 + 1];
1023  uint32_t fpreg[56];
1024  uint32_t sigreturn_reg;
1025};
1026
1027enum {
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
1050class Registers_MIPS {
1051public:
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
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
1071  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
1076  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
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
1091  uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
1092
1093  void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
1094
1095  uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
1096
1097  void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
1098
1099  bool validFloatVectorRegister(int num) const {
1100    return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
1101  }
1102
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
1111private:
1112  uint32_t reg[REGNO_MIPS_R31 + 1];
1113  uint64_t fpreg[32];
1114  uint32_t other_reg[3];
1115};
1116
1117enum {
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
1140class Registers_MIPS64 {
1141public:
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
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
1161  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
1166  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
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
1181  uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1182
1183  void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1184
1185  uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1186
1187  void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1188
1189  bool validFloatVectorRegister(int num) const {
1190    return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
1191  }
1192
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
1201private:
1202  uint64_t reg[REGNO_MIPS64_R31 + 1];
1203  uint64_t fpreg[32];
1204  uint64_t other_reg[3];
1205};
1206
1207enum {
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
1221class Registers_or1k {
1222public:
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
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
1240  bool validRegister(int num) const {
1241    return num >= 0 && num <= LAST_RESTORE_REG;
1242  }
1243
1244  uint64_t getRegister(int num) const {
1245    assert(validRegister(num));
1246    return reg[num];
1247  }
1248
1249  void setRegister(int num, uint64_t value) {
1250    assert(validRegister(num));
1251    reg[num] = value;
1252  }
1253
1254  uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1255
1256  void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1257
1258  uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1259
1260  void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1261
1262  bool validFloatVectorRegister(int num) const {
1263    return false;
1264  }
1265
1266  void copyFloatVectorRegister(int num, uint64_t addr_) {
1267  }
1268
1269  __dso_hidden void jumpto() const __dead;
1270
1271private:
1272  uint32_t reg[REGNO_OR1K_FPCSR + 1];
1273};
1274
1275#if __i386__
1276typedef Registers_x86 NativeUnwindRegisters;
1277#elif __x86_64__
1278typedef Registers_x86_64 NativeUnwindRegisters;
1279#elif __powerpc__
1280typedef Registers_ppc32 NativeUnwindRegisters;
1281#elif __aarch64__
1282typedef Registers_aarch64 NativeUnwindRegisters;
1283#elif __arm__
1284typedef Registers_arm32 NativeUnwindRegisters;
1285#elif __vax__
1286typedef Registers_vax NativeUnwindRegisters;
1287#elif __m68k__
1288typedef Registers_M68K NativeUnwindRegisters;
1289#elif __mips_n64 || __mips_n32
1290typedef Registers_MIPS64 NativeUnwindRegisters;
1291#elif __mips__
1292typedef Registers_MIPS NativeUnwindRegisters;
1293#elif __sh3__
1294typedef Registers_SH3 NativeUnwindRegisters;
1295#elif __sparc64__
1296typedef Registers_SPARC64 NativeUnwindRegisters;
1297#elif __sparc__
1298typedef Registers_SPARC NativeUnwindRegisters;
1299#elif __alpha__
1300typedef Registers_Alpha NativeUnwindRegisters;
1301#elif __hppa__
1302typedef Registers_HPPA NativeUnwindRegisters;
1303#elif __or1k__
1304typedef Registers_or1k NativeUnwindRegisters;
1305#endif
1306} // namespace _Unwind
1307
1308#endif // __REGISTERS_HPP__
1309