Registers.hpp revision 1.18 1 //===----------------------------- Registers.hpp --------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //
9 // Models register sets for supported processors.
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef __REGISTERS_HPP__
13 #define __REGISTERS_HPP__
14
15 #include <cassert>
16 #include <cstdint>
17
18 namespace _Unwind {
19
20 enum {
21 REGNO_X86_EAX = 0,
22 REGNO_X86_ECX = 1,
23 REGNO_X86_EDX = 2,
24 REGNO_X86_EBX = 3,
25 REGNO_X86_ESP = 4,
26 REGNO_X86_EBP = 5,
27 REGNO_X86_ESI = 6,
28 REGNO_X86_EDI = 7,
29 REGNO_X86_EIP = 8,
30 };
31
32 class Registers_x86 {
33 public:
34 enum {
35 LAST_REGISTER = REGNO_X86_EIP,
36 LAST_RESTORE_REG = REGNO_X86_EIP,
37 RETURN_OFFSET = 0,
38 };
39
40 __dso_hidden Registers_x86();
41
42 static int dwarf2regno(int num) { return num; }
43
44 bool validRegister(int num) const {
45 return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
46 }
47
48 uint32_t getRegister(int num) const {
49 assert(validRegister(num));
50 return reg[num];
51 }
52
53 void setRegister(int num, uint32_t value) {
54 assert(validRegister(num));
55 reg[num] = value;
56 }
57
58 uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
59
60 void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
61
62 uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
63
64 void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
65
66 bool validFloatVectorRegister(int num) const { return false; }
67
68 void copyFloatVectorRegister(int num, uint32_t addr) {
69 }
70
71 __dso_hidden void jumpto() const __dead;
72
73 private:
74 uint32_t reg[REGNO_X86_EIP + 1];
75 };
76
77 enum {
78 REGNO_X86_64_RAX = 0,
79 REGNO_X86_64_RDX = 1,
80 REGNO_X86_64_RCX = 2,
81 REGNO_X86_64_RBX = 3,
82 REGNO_X86_64_RSI = 4,
83 REGNO_X86_64_RDI = 5,
84 REGNO_X86_64_RBP = 6,
85 REGNO_X86_64_RSP = 7,
86 REGNO_X86_64_R8 = 8,
87 REGNO_X86_64_R9 = 9,
88 REGNO_X86_64_R10 = 10,
89 REGNO_X86_64_R11 = 11,
90 REGNO_X86_64_R12 = 12,
91 REGNO_X86_64_R13 = 13,
92 REGNO_X86_64_R14 = 14,
93 REGNO_X86_64_R15 = 15,
94 REGNO_X86_64_RIP = 16,
95 };
96
97 class Registers_x86_64 {
98 public:
99 enum {
100 LAST_REGISTER = REGNO_X86_64_RIP,
101 LAST_RESTORE_REG = REGNO_X86_64_RIP,
102 RETURN_OFFSET = 0,
103 };
104
105 __dso_hidden Registers_x86_64();
106
107 static int dwarf2regno(int num) { return num; }
108
109 bool validRegister(int num) const {
110 return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
111 }
112
113 uint64_t getRegister(int num) const {
114 assert(validRegister(num));
115 return reg[num];
116 }
117
118 void setRegister(int num, uint64_t value) {
119 assert(validRegister(num));
120 reg[num] = value;
121 }
122
123 uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
124
125 void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
126
127 uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
128
129 void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
130
131 bool validFloatVectorRegister(int num) const { return false; }
132
133 void copyFloatVectorRegister(int num, uint64_t addr) {
134 }
135
136 __dso_hidden void jumpto() const __dead;
137
138 private:
139 uint64_t reg[REGNO_X86_64_RIP + 1];
140 };
141
142 enum {
143 DWARF_PPC32_R0 = 0,
144 DWARF_PPC32_R31 = 31,
145 DWARF_PPC32_F0 = 32,
146 DWARF_PPC32_F31 = 63,
147 DWARF_PPC32_LR = 65,
148 DWARF_PPC32_CR = 70,
149 DWARF_PPC32_V0 = 77,
150 DWARF_PPC32_V31 = 108,
151
152 REGNO_PPC32_R0 = 0,
153 REGNO_PPC32_R1 = 1,
154 REGNO_PPC32_R31 = 31,
155 REGNO_PPC32_LR = 32,
156 REGNO_PPC32_CR = 33,
157 REGNO_PPC32_SRR0 = 34,
158
159 REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
160 REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
161 REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
162 REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
163 };
164
165 class Registers_ppc32 {
166 public:
167 enum {
168 LAST_REGISTER = REGNO_PPC32_V31,
169 LAST_RESTORE_REG = REGNO_PPC32_V31,
170 RETURN_OFFSET = 0,
171 };
172
173 __dso_hidden Registers_ppc32();
174
175 static int dwarf2regno(int num) {
176 if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
177 return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
178 if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
179 return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
180 if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
181 return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
182 switch (num) {
183 case DWARF_PPC32_LR:
184 return REGNO_PPC32_LR;
185 case DWARF_PPC32_CR:
186 return REGNO_PPC32_CR;
187 default:
188 return LAST_REGISTER + 1;
189 }
190 }
191
192 bool validRegister(int num) const {
193 return num >= 0 && num <= LAST_RESTORE_REG;
194 }
195
196 uint64_t getRegister(int num) const {
197 assert(validRegister(num));
198 return reg[num];
199 }
200
201 void setRegister(int num, uint64_t value) {
202 assert(validRegister(num));
203 reg[num] = value;
204 }
205
206 uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
207
208 void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
209
210 uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
211
212 void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
213
214 bool validFloatVectorRegister(int num) const {
215 return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
216 (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
217 }
218
219 void copyFloatVectorRegister(int num, uint64_t addr_) {
220 const void *addr = reinterpret_cast<const void *>(addr_);
221 if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
222 memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
223 else
224 memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
225 }
226
227 __dso_hidden void jumpto() const __dead;
228
229 private:
230 struct vecreg_t {
231 uint64_t low, high;
232 };
233 uint32_t reg[REGNO_PPC32_SRR0 + 1];
234 uint32_t dummy;
235 uint64_t fpreg[32];
236 vecreg_t vecreg[64];
237 };
238
239 enum {
240 DWARF_AARCH64_X0 = 0,
241 DWARF_AARCH64_X30 = 30,
242 DWARF_AARCH64_SP = 31,
243 DWARF_AARCH64_ELR_MODE = 33,
244 DWARF_AARCH64_V0 = 64,
245 DWARF_AARCH64_V31 = 95,
246
247 REGNO_AARCH64_X0 = 0,
248 REGNO_AARCH64_X30 = 30,
249 REGNO_AARCH64_SP = 31,
250 REGNO_AARCH64_ELR_MODE = 32,
251 REGNO_AARCH64_V0 = 33,
252 REGNO_AARCH64_V31 = 64,
253 };
254
255 class Registers_aarch64 {
256 public:
257 enum {
258 LAST_RESTORE_REG = REGNO_AARCH64_V31,
259 LAST_REGISTER = REGNO_AARCH64_V31,
260 RETURN_OFFSET = 0,
261 };
262
263 __dso_hidden Registers_aarch64();
264
265 static int dwarf2regno(int num) {
266 if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
267 return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
268 if (num == DWARF_AARCH64_SP)
269 return REGNO_AARCH64_SP;
270 if (num == DWARF_AARCH64_ELR_MODE)
271 return REGNO_AARCH64_ELR_MODE;
272 if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
273 return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
274 return LAST_REGISTER + 1;
275 }
276
277 bool validRegister(int num) const {
278 return num >= 0 && num <= LAST_RESTORE_REG;
279 }
280
281 uint64_t getRegister(int num) const {
282 assert(validRegister(num));
283 return reg[num];
284 }
285
286 void setRegister(int num, uint64_t value) {
287 assert(validRegister(num));
288 reg[num] = value;
289 }
290
291 uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
292
293 void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
294
295 uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
296
297 void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
298
299 bool validFloatVectorRegister(int num) const {
300 return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
301 }
302
303 void copyFloatVectorRegister(int num, uint64_t addr_) {
304 const void *addr = reinterpret_cast<const void *>(addr_);
305 memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, sizeof(vecreg[0]));
306 }
307
308 __dso_hidden void jumpto() const __dead;
309
310 private:
311 struct vecreg_t {
312 uint64_t low, high;
313 };
314 uint64_t reg[REGNO_AARCH64_ELR_MODE + 1];
315 vecreg_t vecreg[32];
316 };
317
318 enum {
319 DWARF_ARM32_R0 = 0,
320 DWARF_ARM32_R15 = 15,
321 DWARF_ARM32_SPSR = 128,
322 DWARF_ARM32_OLD_S0 = 64,
323 DWARF_ARM32_OLD_S31 = 91,
324 DWARF_ARM32_D0 = 256,
325 DWARF_ARM32_D31 = 287,
326 REGNO_ARM32_R0 = 0,
327 REGNO_ARM32_SP = 13,
328 REGNO_ARM32_R15 = 15,
329 REGNO_ARM32_SPSR = 16,
330 REGNO_ARM32_D0 = 17,
331 REGNO_ARM32_D15 = 32,
332 REGNO_ARM32_D31 = 48,
333 };
334
335 class Registers_arm32 {
336 public:
337 enum {
338 LAST_REGISTER = REGNO_ARM32_D31,
339 LAST_RESTORE_REG = REGNO_ARM32_D31,
340 RETURN_OFFSET = 0,
341 };
342
343 __dso_hidden Registers_arm32();
344
345 static int dwarf2regno(int num) {
346 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
347 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
348 if (num == DWARF_ARM32_SPSR)
349 return REGNO_ARM32_SPSR;
350 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
351 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
352 if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) {
353 assert(num % 2 == 0);
354 return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2;
355 }
356 return LAST_REGISTER + 1;
357 }
358
359 bool validRegister(int num) const {
360 return num >= 0 && num <= REGNO_ARM32_SPSR;
361 }
362
363 uint64_t getRegister(int num) const {
364 assert(validRegister(num));
365 return reg[num];
366 }
367
368 void setRegister(int num, uint64_t value) {
369 assert(validRegister(num));
370 reg[num] = value;
371 }
372
373 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
374
375 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
376
377 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
378
379 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
380
381 bool validFloatVectorRegister(int num) const {
382 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
383 }
384
385 void copyFloatVectorRegister(int num, uint64_t addr_) {
386 if (num <= REGNO_ARM32_D15) {
387 if ((flags & 1) == 0) {
388 lazyVFP1();
389 flags |= 1;
390 }
391 } else {
392 if ((flags & 2) == 0) {
393 lazyVFP3();
394 flags |= 2;
395 }
396 }
397 const void *addr = reinterpret_cast<const void *>(addr_);
398 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
399 }
400
401 __dso_hidden void lazyVFP1();
402 __dso_hidden void lazyVFP3();
403 __dso_hidden void jumpto() const __dead;
404
405 private:
406 uint32_t reg[REGNO_ARM32_SPSR + 1];
407 uint32_t flags;
408 uint64_t fpreg[32];
409 };
410
411 enum {
412 DWARF_VAX_R0 = 0,
413 DWARF_VAX_R15 = 15,
414 DWARF_VAX_PSW = 16,
415
416 REGNO_VAX_R0 = 0,
417 REGNO_VAX_R14 = 14,
418 REGNO_VAX_R15 = 15,
419 REGNO_VAX_PSW = 16,
420 };
421
422 class Registers_vax {
423 public:
424 enum {
425 LAST_REGISTER = REGNO_VAX_PSW,
426 LAST_RESTORE_REG = REGNO_VAX_PSW,
427 RETURN_OFFSET = 0,
428 };
429
430 __dso_hidden Registers_vax();
431
432 static int dwarf2regno(int num) {
433 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
434 return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
435 if (num == DWARF_VAX_PSW)
436 return REGNO_VAX_PSW;
437 return LAST_REGISTER + 1;
438 }
439
440 bool validRegister(int num) const {
441 return num >= 0 && num <= LAST_RESTORE_REG;
442 }
443
444 uint64_t getRegister(int num) const {
445 assert(validRegister(num));
446 return reg[num];
447 }
448
449 void setRegister(int num, uint64_t value) {
450 assert(validRegister(num));
451 reg[num] = value;
452 }
453
454 uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
455
456 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
457
458 uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
459
460 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
461
462 bool validFloatVectorRegister(int num) const {
463 return false;
464 }
465
466 void copyFloatVectorRegister(int num, uint64_t addr_) {
467 }
468
469 __dso_hidden void jumpto() const __dead;
470
471 private:
472 uint32_t reg[REGNO_VAX_PSW + 1];
473 };
474
475 enum {
476 DWARF_M68K_A0 = 0,
477 DWARF_M68K_A7 = 7,
478 DWARF_M68K_D0 = 8,
479 DWARF_M68K_D7 = 15,
480 DWARF_M68K_FP0 = 16,
481 DWARF_M68K_FP7 = 23,
482 DWARF_M68K_PC = 24,
483
484 REGNO_M68K_A0 = 0,
485 REGNO_M68K_A7 = 7,
486 REGNO_M68K_D0 = 8,
487 REGNO_M68K_D7 = 15,
488 REGNO_M68K_PC = 16,
489 REGNO_M68K_FP0 = 17,
490 REGNO_M68K_FP7 = 24,
491 };
492
493 class Registers_M68K {
494 public:
495 enum {
496 LAST_REGISTER = REGNO_M68K_FP7,
497 LAST_RESTORE_REG = REGNO_M68K_FP7,
498 RETURN_OFFSET = 0,
499 };
500
501 __dso_hidden Registers_M68K();
502
503 static int dwarf2regno(int num) {
504 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
505 return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
506 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
507 return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
508 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
509 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
510 if (num == DWARF_M68K_PC)
511 return REGNO_M68K_PC;
512 return LAST_REGISTER + 1;
513 }
514
515 bool validRegister(int num) const {
516 return num >= 0 && num <= REGNO_M68K_PC;
517 }
518
519 uint64_t getRegister(int num) const {
520 assert(validRegister(num));
521 return reg[num];
522 }
523
524 void setRegister(int num, uint64_t value) {
525 assert(validRegister(num));
526 reg[num] = value;
527 }
528
529 uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
530
531 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
532
533 uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
534
535 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
536
537 bool validFloatVectorRegister(int num) const {
538 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
539 }
540
541 void copyFloatVectorRegister(int num, uint64_t addr_) {
542 assert(validFloatVectorRegister(num));
543 const void *addr = reinterpret_cast<const void *>(addr_);
544 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
545 }
546
547 __dso_hidden void jumpto() const __dead;
548
549 private:
550 typedef uint32_t fpreg_t[3];
551
552 uint32_t reg[REGNO_M68K_PC + 1];
553 uint32_t dummy;
554 fpreg_t fpreg[8];
555 };
556
557 enum {
558 DWARF_SH3_R0 = 0,
559 DWARF_SH3_R15 = 15,
560 DWARF_SH3_PC = 16,
561 DWARF_SH3_PR = 17,
562
563 REGNO_SH3_R0 = 0,
564 REGNO_SH3_R15 = 15,
565 REGNO_SH3_PC = 16,
566 REGNO_SH3_PR = 17,
567 };
568
569 class Registers_SH3 {
570 public:
571 enum {
572 LAST_REGISTER = REGNO_SH3_PR,
573 LAST_RESTORE_REG = REGNO_SH3_PR,
574 RETURN_OFFSET = 0,
575 };
576
577 __dso_hidden Registers_SH3();
578
579 static int dwarf2regno(int num) {
580 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
581 return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
582 if (num == DWARF_SH3_PC)
583 return REGNO_SH3_PC;
584 if (num == DWARF_SH3_PR)
585 return REGNO_SH3_PR;
586 return LAST_REGISTER + 1;
587 }
588
589 bool validRegister(int num) const {
590 return num >= 0 && num <= REGNO_SH3_PR;
591 }
592
593 uint64_t getRegister(int num) const {
594 assert(validRegister(num));
595 return reg[num];
596 }
597
598 void setRegister(int num, uint64_t value) {
599 assert(validRegister(num));
600 reg[num] = value;
601 }
602
603 uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
604
605 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
606
607 uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
608
609 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
610
611 bool validFloatVectorRegister(int num) const { return false; }
612
613 void copyFloatVectorRegister(int num, uint64_t addr_) {}
614
615 __dso_hidden void jumpto() const __dead;
616
617 private:
618 uint32_t reg[REGNO_SH3_PR + 1];
619 };
620
621 enum {
622 DWARF_SPARC64_R0 = 0,
623 DWARF_SPARC64_R31 = 31,
624 DWARF_SPARC64_PC = 32,
625
626 REGNO_SPARC64_R0 = 0,
627 REGNO_SPARC64_R14 = 14,
628 REGNO_SPARC64_R15 = 15,
629 REGNO_SPARC64_R31 = 31,
630 REGNO_SPARC64_PC = 32,
631 };
632
633 class Registers_SPARC64 {
634 public:
635 enum {
636 LAST_REGISTER = REGNO_SPARC64_PC,
637 LAST_RESTORE_REG = REGNO_SPARC64_PC,
638 RETURN_OFFSET = 8,
639 };
640 typedef uint64_t reg_t;
641
642 __dso_hidden Registers_SPARC64();
643
644 static int dwarf2regno(int num) {
645 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
646 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
647 if (num == DWARF_SPARC64_PC)
648 return REGNO_SPARC64_PC;
649 return LAST_REGISTER + 1;
650 }
651
652 bool validRegister(int num) const {
653 return num >= 0 && num <= REGNO_SPARC64_PC;
654 }
655
656 uint64_t getRegister(int num) const {
657 assert(validRegister(num));
658 return reg[num];
659 }
660
661 void setRegister(int num, uint64_t value) {
662 assert(validRegister(num));
663 reg[num] = value;
664 }
665
666 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
667
668 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
669
670 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
671
672 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
673
674 bool validFloatVectorRegister(int num) const { return false; }
675
676 void copyFloatVectorRegister(int num, uint64_t addr_) {}
677
678 __dso_hidden void jumpto() const __dead;
679
680 private:
681 uint64_t reg[REGNO_SPARC64_PC + 1];
682 };
683
684 enum {
685 DWARF_SPARC_R0 = 0,
686 DWARF_SPARC_R31 = 31,
687 DWARF_SPARC_PC = 32,
688
689 REGNO_SPARC_R0 = 0,
690 REGNO_SPARC_R14 = 14,
691 REGNO_SPARC_R15 = 15,
692 REGNO_SPARC_R31 = 31,
693 REGNO_SPARC_PC = 32,
694 };
695
696 class Registers_SPARC {
697 public:
698 enum {
699 LAST_REGISTER = REGNO_SPARC_PC,
700 LAST_RESTORE_REG = REGNO_SPARC_PC,
701 RETURN_OFFSET = 8,
702 };
703 typedef uint32_t reg_t;
704
705 __dso_hidden Registers_SPARC();
706
707 static int dwarf2regno(int num) {
708 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
709 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
710 if (num == DWARF_SPARC_PC)
711 return REGNO_SPARC_PC;
712 return LAST_REGISTER + 1;
713 }
714
715 bool validRegister(int num) const {
716 return num >= 0 && num <= REGNO_SPARC_PC;
717 }
718
719 uint64_t getRegister(int num) const {
720 assert(validRegister(num));
721 return reg[num];
722 }
723
724 void setRegister(int num, uint64_t value) {
725 assert(validRegister(num));
726 reg[num] = value;
727 }
728
729 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
730
731 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
732
733 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
734
735 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
736
737 bool validFloatVectorRegister(int num) const { return false; }
738
739 void copyFloatVectorRegister(int num, uint64_t addr_) {}
740
741 __dso_hidden void jumpto() const __dead;
742
743 private:
744 uint32_t reg[REGNO_SPARC_PC + 1];
745 };
746
747 enum {
748 DWARF_ALPHA_R0 = 0,
749 DWARF_ALPHA_R30 = 30,
750 DWARF_ALPHA_F0 = 32,
751 DWARF_ALPHA_F30 = 62,
752
753 REGNO_ALPHA_R0 = 0,
754 REGNO_ALPHA_R26 = 26,
755 REGNO_ALPHA_R30 = 30,
756 REGNO_ALPHA_PC = 31,
757 REGNO_ALPHA_F0 = 32,
758 REGNO_ALPHA_F30 = 62,
759 };
760
761 class Registers_Alpha {
762 public:
763 enum {
764 LAST_REGISTER = REGNO_ALPHA_F30,
765 LAST_RESTORE_REG = REGNO_ALPHA_F30,
766 RETURN_OFFSET = 0,
767 };
768 typedef uint32_t reg_t;
769
770 __dso_hidden Registers_Alpha();
771
772 static int dwarf2regno(int num) { return num; }
773
774 bool validRegister(int num) const {
775 return num >= 0 && num <= REGNO_ALPHA_PC;
776 }
777
778 uint64_t getRegister(int num) const {
779 assert(validRegister(num));
780 return reg[num];
781 }
782
783 void setRegister(int num, uint64_t value) {
784 assert(validRegister(num));
785 reg[num] = value;
786 }
787
788 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
789
790 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
791
792 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
793
794 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
795
796 bool validFloatVectorRegister(int num) const {
797 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
798 }
799
800 void copyFloatVectorRegister(int num, uint64_t addr_) {
801 assert(validFloatVectorRegister(num));
802 const void *addr = reinterpret_cast<const void *>(addr_);
803 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
804 }
805
806 __dso_hidden void jumpto() const __dead;
807
808 private:
809 uint64_t reg[REGNO_ALPHA_PC + 1];
810 uint64_t fpreg[31];
811 };
812
813 enum {
814 DWARF_HPPA_R1 = 1,
815 DWARF_HPPA_R31 = 31,
816 DWARF_HPPA_FR4L = 32,
817 DWARF_HPPA_FR31H = 87,
818
819 REGNO_HPPA_PC = 0,
820 REGNO_HPPA_R1 = 1,
821 REGNO_HPPA_R2 = 2,
822 REGNO_HPPA_R30 = 30,
823 REGNO_HPPA_R31 = 31,
824 REGNO_HPPA_FR4L = 32,
825 REGNO_HPPA_FR31H = 87,
826 };
827
828 class Registers_HPPA {
829 public:
830 enum {
831 LAST_REGISTER = REGNO_HPPA_FR31H,
832 LAST_RESTORE_REG = REGNO_HPPA_FR31H,
833 RETURN_OFFSET = -3, // strictly speaking, this is a mask
834 };
835
836 __dso_hidden Registers_HPPA();
837
838 static int dwarf2regno(int num) {
839 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
840 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
841 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
842 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
843 return LAST_REGISTER + 1;
844 }
845
846 bool validRegister(int num) const {
847 return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
848 }
849
850 uint64_t getRegister(int num) const {
851 assert(validRegister(num));
852 return reg[num];
853 }
854
855 void setRegister(int num, uint64_t value) {
856 assert(validRegister(num));
857 reg[num] = value;
858 }
859
860 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
861
862 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
863
864 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
865
866 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
867
868 bool validFloatVectorRegister(int num) const {
869 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
870 }
871
872 void copyFloatVectorRegister(int num, uint64_t addr_) {
873 assert(validFloatVectorRegister(num));
874 const void *addr = reinterpret_cast<const void *>(addr_);
875 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
876 }
877
878 __dso_hidden void jumpto() const __dead;
879
880 private:
881 uint32_t reg[REGNO_HPPA_R31 + 1];
882 uint32_t fpreg[56];
883 };
884
885 enum {
886 DWARF_MIPS_R1 = 0,
887 DWARF_MIPS_R31 = 31,
888 DWARF_MIPS_F0 = 32,
889 DWARF_MIPS_F31 = 63,
890
891 REGNO_MIPS_PC = 0,
892 REGNO_MIPS_R1 = 0,
893 REGNO_MIPS_R29 = 29,
894 REGNO_MIPS_R31 = 31,
895 REGNO_MIPS_F0 = 33,
896 REGNO_MIPS_F31 = 64
897 };
898
899 class Registers_MIPS {
900 public:
901 enum {
902 LAST_REGISTER = REGNO_MIPS_F31,
903 LAST_RESTORE_REG = REGNO_MIPS_F31,
904 RETURN_OFFSET = 0,
905 };
906
907 __dso_hidden Registers_MIPS();
908
909 static int dwarf2regno(int num) {
910 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
911 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
912 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
913 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
914 return LAST_REGISTER + 1;
915 }
916
917 bool validRegister(int num) const {
918 return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
919 }
920
921 uint64_t getRegister(int num) const {
922 assert(validRegister(num));
923 return reg[num];
924 }
925
926 void setRegister(int num, uint64_t value) {
927 assert(validRegister(num));
928 reg[num] = value;
929 }
930
931 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
932
933 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
934
935 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
936
937 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
938
939 bool validFloatVectorRegister(int num) const {
940 return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
941 }
942
943 void copyFloatVectorRegister(int num, uint64_t addr_) {
944 assert(validFloatVectorRegister(num));
945 const void *addr = reinterpret_cast<const void *>(addr_);
946 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
947 }
948
949 __dso_hidden void jumpto() const __dead;
950
951 private:
952 uint32_t reg[REGNO_MIPS_R31 + 1];
953 uint64_t fpreg[32];
954 };
955
956 enum {
957 DWARF_MIPS64_R1 = 0,
958 DWARF_MIPS64_R31 = 31,
959 DWARF_MIPS64_F0 = 32,
960 DWARF_MIPS64_F31 = 63,
961
962 REGNO_MIPS64_PC = 0,
963 REGNO_MIPS64_R1 = 0,
964 REGNO_MIPS64_R29 = 29,
965 REGNO_MIPS64_R31 = 31,
966 REGNO_MIPS64_F0 = 33,
967 REGNO_MIPS64_F31 = 64
968 };
969
970 class Registers_MIPS64 {
971 public:
972 enum {
973 LAST_REGISTER = REGNO_MIPS64_F31,
974 LAST_RESTORE_REG = REGNO_MIPS64_F31,
975 RETURN_OFFSET = 0,
976 };
977
978 __dso_hidden Registers_MIPS64();
979
980 static int dwarf2regno(int num) {
981 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
982 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
983 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
984 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
985 return LAST_REGISTER + 1;
986 }
987
988 bool validRegister(int num) const {
989 return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
990 }
991
992 uint64_t getRegister(int num) const {
993 assert(validRegister(num));
994 return reg[num];
995 }
996
997 void setRegister(int num, uint64_t value) {
998 assert(validRegister(num));
999 reg[num] = value;
1000 }
1001
1002 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1003
1004 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1005
1006 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1007
1008 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1009
1010 bool validFloatVectorRegister(int num) const {
1011 return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
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_MIPS64_F0), addr, sizeof(fpreg[0]));
1018 }
1019
1020 __dso_hidden void jumpto() const __dead;
1021
1022 private:
1023 uint64_t reg[REGNO_MIPS64_R31 + 1];
1024 uint64_t fpreg[32];
1025 };
1026
1027 enum {
1028 DWARF_OR1K_R0 = 0,
1029 DWARF_OR1K_SP = 1,
1030 DWARF_OR1K_LR = 9,
1031 DWARF_OR1K_R31 = 31,
1032 DWARF_OR1K_FPCSR = 32,
1033
1034 REGNO_OR1K_R0 = 0,
1035 REGNO_OR1K_SP = 1,
1036 REGNO_OR1K_LR = 9,
1037 REGNO_OR1K_R31 = 31,
1038 REGNO_OR1K_FPCSR = 32,
1039 };
1040
1041 class Registers_or1k {
1042 public:
1043 enum {
1044 LAST_REGISTER = REGNO_OR1K_FPCSR,
1045 LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1046 RETURN_OFFSET = 0,
1047 };
1048
1049 __dso_hidden Registers_or1k();
1050
1051 static int dwarf2regno(int num) {
1052 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1053 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1054 if (num == DWARF_OR1K_FPCSR)
1055 return REGNO_OR1K_FPCSR;
1056 return LAST_REGISTER + 1;
1057 }
1058
1059 bool validRegister(int num) const {
1060 return num >= 0 && num <= LAST_RESTORE_REG;
1061 }
1062
1063 uint64_t getRegister(int num) const {
1064 assert(validRegister(num));
1065 return reg[num];
1066 }
1067
1068 void setRegister(int num, uint64_t value) {
1069 assert(validRegister(num));
1070 reg[num] = value;
1071 }
1072
1073 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1074
1075 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1076
1077 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1078
1079 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1080
1081 bool validFloatVectorRegister(int num) const {
1082 return false;
1083 }
1084
1085 void copyFloatVectorRegister(int num, uint64_t addr_) {
1086 }
1087
1088 __dso_hidden void jumpto() const __dead;
1089
1090 private:
1091 uint32_t reg[REGNO_OR1K_FPCSR + 1];
1092 };
1093
1094 #if __i386__
1095 typedef Registers_x86 NativeUnwindRegisters;
1096 #elif __x86_64__
1097 typedef Registers_x86_64 NativeUnwindRegisters;
1098 #elif __powerpc__
1099 typedef Registers_ppc32 NativeUnwindRegisters;
1100 #elif __aarch64__
1101 typedef Registers_aarch64 NativeUnwindRegisters;
1102 #elif __arm__
1103 typedef Registers_arm32 NativeUnwindRegisters;
1104 #elif __vax__
1105 typedef Registers_vax NativeUnwindRegisters;
1106 #elif __m68k__
1107 typedef Registers_M68K NativeUnwindRegisters;
1108 #elif __mips_n64 || __mips_n32
1109 typedef Registers_MIPS64 NativeUnwindRegisters;
1110 #elif __mips__
1111 typedef Registers_MIPS NativeUnwindRegisters;
1112 #elif __sh3__
1113 typedef Registers_SH3 NativeUnwindRegisters;
1114 #elif __sparc64__
1115 typedef Registers_SPARC64 NativeUnwindRegisters;
1116 #elif __sparc__
1117 typedef Registers_SPARC NativeUnwindRegisters;
1118 #elif __alpha__
1119 typedef Registers_Alpha NativeUnwindRegisters;
1120 #elif __hppa__
1121 typedef Registers_HPPA NativeUnwindRegisters;
1122 #elif __or1k__
1123 typedef Registers_or1k NativeUnwindRegisters;
1124 #endif
1125 } // namespace _Unwind
1126
1127 #endif // __REGISTERS_HPP__
1128