Registers.hpp revision 1.39 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
894 static int dwarf2regno(int num) { return num; }
895
896 bool validRegister(int num) const {
897 return (num >= 0 && num <= REGNO_ALPHA_PC) ||
898 num == REGNO_ALPHA_SIGRETURN;
899 }
900
901 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
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
917 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
918
919 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
920
921 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
922
923 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
924
925 bool validFloatVectorRegister(int num) const {
926 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
927 }
928
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
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
981 bool validRegister(int num) const {
982 return (num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31) ||
983 num == REGNO_HPPA_SIGRETURN;
984 }
985
986 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
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
1002 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
1003
1004 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
1005
1006 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
1007
1008 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
1009
1010 bool validFloatVectorRegister(int num) const {
1011 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
1012 }
1013
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
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
1072 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
1077 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
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
1092 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
1093
1094 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
1095
1096 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
1097
1098 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
1099
1100 bool validFloatVectorRegister(int num) const {
1101 return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
1102 }
1103
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
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
1162 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
1167 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
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
1182 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1183
1184 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1185
1186 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1187
1188 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1189
1190 bool validFloatVectorRegister(int num) const {
1191 return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
1192 }
1193
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
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
1241 bool validRegister(int num) const {
1242 return num >= 0 && num <= LAST_RESTORE_REG;
1243 }
1244
1245 uint64_t getRegister(int num) const {
1246 assert(validRegister(num));
1247 return reg[num];
1248 }
1249
1250 void setRegister(int num, uint64_t value) {
1251 assert(validRegister(num));
1252 reg[num] = value;
1253 }
1254
1255 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1256
1257 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1258
1259 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1260
1261 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1262
1263 bool validFloatVectorRegister(int num) const {
1264 return false;
1265 }
1266
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