Registers.hpp revision 1.16 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_ARM32_R0 = 0,
241 DWARF_ARM32_R15 = 15,
242 DWARF_ARM32_SPSR = 128,
243 DWARF_ARM32_OLD_S0 = 64,
244 DWARF_ARM32_OLD_S31 = 91,
245 DWARF_ARM32_D0 = 256,
246 DWARF_ARM32_D31 = 287,
247 REGNO_ARM32_R0 = 0,
248 REGNO_ARM32_SP = 13,
249 REGNO_ARM32_R15 = 15,
250 REGNO_ARM32_SPSR = 16,
251 REGNO_ARM32_D0 = 17,
252 REGNO_ARM32_D15 = 32,
253 REGNO_ARM32_D31 = 48,
254 };
255
256 class Registers_arm32 {
257 public:
258 enum {
259 LAST_REGISTER = REGNO_ARM32_D31,
260 LAST_RESTORE_REG = REGNO_ARM32_D31,
261 RETURN_OFFSET = 0,
262 };
263
264 __dso_hidden Registers_arm32();
265
266 static int dwarf2regno(int num) {
267 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
268 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
269 if (num == DWARF_ARM32_SPSR)
270 return REGNO_ARM32_SPSR;
271 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
272 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
273 if (num >= DWARF_ARM32_OLD_S0 && num <= DWARF_ARM32_OLD_S31) {
274 assert(num % 2 == 0);
275 return REGNO_ARM32_D0 + (num - DWARF_ARM32_OLD_S0) / 2;
276 }
277 return LAST_REGISTER + 1;
278 }
279
280 bool validRegister(int num) const {
281 return num >= 0 && num <= REGNO_ARM32_SPSR;
282 }
283
284 uint64_t getRegister(int num) const {
285 assert(validRegister(num));
286 return reg[num];
287 }
288
289 void setRegister(int num, uint64_t value) {
290 assert(validRegister(num));
291 reg[num] = value;
292 }
293
294 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
295
296 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
297
298 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
299
300 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
301
302 bool validFloatVectorRegister(int num) const {
303 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
304 }
305
306 void copyFloatVectorRegister(int num, uint64_t addr_) {
307 if (num <= REGNO_ARM32_D15) {
308 if ((flags & 1) == 0) {
309 lazyVFP1();
310 flags |= 1;
311 }
312 } else {
313 if ((flags & 2) == 0) {
314 lazyVFP3();
315 flags |= 2;
316 }
317 }
318 const void *addr = reinterpret_cast<const void *>(addr_);
319 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
320 }
321
322 __dso_hidden void lazyVFP1();
323 __dso_hidden void lazyVFP3();
324 __dso_hidden void jumpto() const __dead;
325
326 private:
327 uint32_t reg[REGNO_ARM32_SPSR + 1];
328 uint32_t flags;
329 uint64_t fpreg[32];
330 };
331
332 enum {
333 DWARF_VAX_R0 = 0,
334 DWARF_VAX_R15 = 15,
335 DWARF_VAX_PSW = 16,
336
337 REGNO_VAX_R0 = 0,
338 REGNO_VAX_R14 = 14,
339 REGNO_VAX_R15 = 15,
340 REGNO_VAX_PSW = 16,
341 };
342
343 class Registers_vax {
344 public:
345 enum {
346 LAST_REGISTER = REGNO_VAX_PSW,
347 LAST_RESTORE_REG = REGNO_VAX_PSW,
348 RETURN_OFFSET = 0,
349 };
350
351 __dso_hidden Registers_vax();
352
353 static int dwarf2regno(int num) {
354 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
355 return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
356 if (num == DWARF_VAX_PSW)
357 return REGNO_VAX_PSW;
358 return LAST_REGISTER + 1;
359 }
360
361 bool validRegister(int num) const {
362 return num >= 0 && num <= LAST_RESTORE_REG;
363 }
364
365 uint64_t getRegister(int num) const {
366 assert(validRegister(num));
367 return reg[num];
368 }
369
370 void setRegister(int num, uint64_t value) {
371 assert(validRegister(num));
372 reg[num] = value;
373 }
374
375 uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
376
377 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
378
379 uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
380
381 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
382
383 bool validFloatVectorRegister(int num) const {
384 return false;
385 }
386
387 void copyFloatVectorRegister(int num, uint64_t addr_) {
388 }
389
390 __dso_hidden void jumpto() const __dead;
391
392 private:
393 uint32_t reg[REGNO_VAX_PSW + 1];
394 };
395
396 enum {
397 DWARF_M68K_A0 = 0,
398 DWARF_M68K_A7 = 7,
399 DWARF_M68K_D0 = 8,
400 DWARF_M68K_D7 = 15,
401 DWARF_M68K_FP0 = 16,
402 DWARF_M68K_FP7 = 23,
403 DWARF_M68K_PC = 24,
404
405 REGNO_M68K_A0 = 0,
406 REGNO_M68K_A7 = 7,
407 REGNO_M68K_D0 = 8,
408 REGNO_M68K_D7 = 15,
409 REGNO_M68K_PC = 16,
410 REGNO_M68K_FP0 = 17,
411 REGNO_M68K_FP7 = 24,
412 };
413
414 class Registers_M68K {
415 public:
416 enum {
417 LAST_REGISTER = REGNO_M68K_FP7,
418 LAST_RESTORE_REG = REGNO_M68K_FP7,
419 RETURN_OFFSET = 0,
420 };
421
422 __dso_hidden Registers_M68K();
423
424 static int dwarf2regno(int num) {
425 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
426 return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
427 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
428 return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
429 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
430 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
431 if (num == DWARF_M68K_PC)
432 return REGNO_M68K_PC;
433 return LAST_REGISTER + 1;
434 }
435
436 bool validRegister(int num) const {
437 return num >= 0 && num <= REGNO_M68K_PC;
438 }
439
440 uint64_t getRegister(int num) const {
441 assert(validRegister(num));
442 return reg[num];
443 }
444
445 void setRegister(int num, uint64_t value) {
446 assert(validRegister(num));
447 reg[num] = value;
448 }
449
450 uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
451
452 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
453
454 uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
455
456 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
457
458 bool validFloatVectorRegister(int num) const {
459 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
460 }
461
462 void copyFloatVectorRegister(int num, uint64_t addr_) {
463 assert(validFloatVectorRegister(num));
464 const void *addr = reinterpret_cast<const void *>(addr_);
465 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
466 }
467
468 __dso_hidden void jumpto() const __dead;
469
470 private:
471 typedef uint32_t fpreg_t[3];
472
473 uint32_t reg[REGNO_M68K_PC + 1];
474 uint32_t dummy;
475 fpreg_t fpreg[8];
476 };
477
478 enum {
479 DWARF_SH3_R0 = 0,
480 DWARF_SH3_R15 = 15,
481 DWARF_SH3_PC = 16,
482 DWARF_SH3_PR = 17,
483
484 REGNO_SH3_R0 = 0,
485 REGNO_SH3_R15 = 15,
486 REGNO_SH3_PC = 16,
487 REGNO_SH3_PR = 17,
488 };
489
490 class Registers_SH3 {
491 public:
492 enum {
493 LAST_REGISTER = REGNO_SH3_PR,
494 LAST_RESTORE_REG = REGNO_SH3_PR,
495 RETURN_OFFSET = 0,
496 };
497
498 __dso_hidden Registers_SH3();
499
500 static int dwarf2regno(int num) {
501 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
502 return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
503 if (num == DWARF_SH3_PC)
504 return REGNO_SH3_PC;
505 if (num == DWARF_SH3_PR)
506 return REGNO_SH3_PR;
507 return LAST_REGISTER + 1;
508 }
509
510 bool validRegister(int num) const {
511 return num >= 0 && num <= REGNO_SH3_PR;
512 }
513
514 uint64_t getRegister(int num) const {
515 assert(validRegister(num));
516 return reg[num];
517 }
518
519 void setRegister(int num, uint64_t value) {
520 assert(validRegister(num));
521 reg[num] = value;
522 }
523
524 uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
525
526 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
527
528 uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
529
530 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
531
532 bool validFloatVectorRegister(int num) const { return false; }
533
534 void copyFloatVectorRegister(int num, uint64_t addr_) {}
535
536 __dso_hidden void jumpto() const __dead;
537
538 private:
539 uint32_t reg[REGNO_SH3_PR + 1];
540 };
541
542 enum {
543 DWARF_SPARC64_R0 = 0,
544 DWARF_SPARC64_R31 = 31,
545 DWARF_SPARC64_PC = 32,
546
547 REGNO_SPARC64_R0 = 0,
548 REGNO_SPARC64_R14 = 14,
549 REGNO_SPARC64_R15 = 15,
550 REGNO_SPARC64_R31 = 31,
551 REGNO_SPARC64_PC = 32,
552 };
553
554 class Registers_SPARC64 {
555 public:
556 enum {
557 LAST_REGISTER = REGNO_SPARC64_PC,
558 LAST_RESTORE_REG = REGNO_SPARC64_PC,
559 RETURN_OFFSET = 8,
560 };
561 typedef uint64_t reg_t;
562
563 __dso_hidden Registers_SPARC64();
564
565 static int dwarf2regno(int num) {
566 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
567 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
568 if (num == DWARF_SPARC64_PC)
569 return REGNO_SPARC64_PC;
570 return LAST_REGISTER + 1;
571 }
572
573 bool validRegister(int num) const {
574 return num >= 0 && num <= REGNO_SPARC64_PC;
575 }
576
577 uint64_t getRegister(int num) const {
578 assert(validRegister(num));
579 return reg[num];
580 }
581
582 void setRegister(int num, uint64_t value) {
583 assert(validRegister(num));
584 reg[num] = value;
585 }
586
587 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
588
589 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
590
591 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
592
593 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
594
595 bool validFloatVectorRegister(int num) const { return false; }
596
597 void copyFloatVectorRegister(int num, uint64_t addr_) {}
598
599 __dso_hidden void jumpto() const __dead;
600
601 private:
602 uint64_t reg[REGNO_SPARC64_PC + 1];
603 };
604
605 enum {
606 DWARF_SPARC_R0 = 0,
607 DWARF_SPARC_R31 = 31,
608 DWARF_SPARC_PC = 32,
609
610 REGNO_SPARC_R0 = 0,
611 REGNO_SPARC_R14 = 14,
612 REGNO_SPARC_R15 = 15,
613 REGNO_SPARC_R31 = 31,
614 REGNO_SPARC_PC = 32,
615 };
616
617 class Registers_SPARC {
618 public:
619 enum {
620 LAST_REGISTER = REGNO_SPARC_PC,
621 LAST_RESTORE_REG = REGNO_SPARC_PC,
622 RETURN_OFFSET = 8,
623 };
624 typedef uint32_t reg_t;
625
626 __dso_hidden Registers_SPARC();
627
628 static int dwarf2regno(int num) {
629 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
630 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
631 if (num == DWARF_SPARC_PC)
632 return REGNO_SPARC_PC;
633 return LAST_REGISTER + 1;
634 }
635
636 bool validRegister(int num) const {
637 return num >= 0 && num <= REGNO_SPARC_PC;
638 }
639
640 uint64_t getRegister(int num) const {
641 assert(validRegister(num));
642 return reg[num];
643 }
644
645 void setRegister(int num, uint64_t value) {
646 assert(validRegister(num));
647 reg[num] = value;
648 }
649
650 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
651
652 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
653
654 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
655
656 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
657
658 bool validFloatVectorRegister(int num) const { return false; }
659
660 void copyFloatVectorRegister(int num, uint64_t addr_) {}
661
662 __dso_hidden void jumpto() const __dead;
663
664 private:
665 uint32_t reg[REGNO_SPARC_PC + 1];
666 };
667
668 enum {
669 DWARF_ALPHA_R0 = 0,
670 DWARF_ALPHA_R30 = 30,
671 DWARF_ALPHA_F0 = 32,
672 DWARF_ALPHA_F30 = 62,
673
674 REGNO_ALPHA_R0 = 0,
675 REGNO_ALPHA_R26 = 26,
676 REGNO_ALPHA_R30 = 30,
677 REGNO_ALPHA_PC = 31,
678 REGNO_ALPHA_F0 = 32,
679 REGNO_ALPHA_F30 = 62,
680 };
681
682 class Registers_Alpha {
683 public:
684 enum {
685 LAST_REGISTER = REGNO_ALPHA_F30,
686 LAST_RESTORE_REG = REGNO_ALPHA_F30,
687 RETURN_OFFSET = 0,
688 };
689 typedef uint32_t reg_t;
690
691 __dso_hidden Registers_Alpha();
692
693 static int dwarf2regno(int num) { return num; }
694
695 bool validRegister(int num) const {
696 return num >= 0 && num <= REGNO_ALPHA_PC;
697 }
698
699 uint64_t getRegister(int num) const {
700 assert(validRegister(num));
701 return reg[num];
702 }
703
704 void setRegister(int num, uint64_t value) {
705 assert(validRegister(num));
706 reg[num] = value;
707 }
708
709 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
710
711 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
712
713 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
714
715 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
716
717 bool validFloatVectorRegister(int num) const {
718 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
719 }
720
721 void copyFloatVectorRegister(int num, uint64_t addr_) {
722 assert(validFloatVectorRegister(num));
723 const void *addr = reinterpret_cast<const void *>(addr_);
724 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
725 }
726
727 __dso_hidden void jumpto() const __dead;
728
729 private:
730 uint64_t reg[REGNO_ALPHA_PC + 1];
731 uint64_t fpreg[31];
732 };
733
734 enum {
735 DWARF_HPPA_R1 = 1,
736 DWARF_HPPA_R31 = 31,
737 DWARF_HPPA_FR4L = 32,
738 DWARF_HPPA_FR31H = 87,
739
740 REGNO_HPPA_PC = 0,
741 REGNO_HPPA_R1 = 1,
742 REGNO_HPPA_R2 = 2,
743 REGNO_HPPA_R30 = 30,
744 REGNO_HPPA_R31 = 31,
745 REGNO_HPPA_FR4L = 32,
746 REGNO_HPPA_FR31H = 87,
747 };
748
749 class Registers_HPPA {
750 public:
751 enum {
752 LAST_REGISTER = REGNO_HPPA_FR31H,
753 LAST_RESTORE_REG = REGNO_HPPA_FR31H,
754 RETURN_OFFSET = -3, // strictly speaking, this is a mask
755 };
756
757 __dso_hidden Registers_HPPA();
758
759 static int dwarf2regno(int num) {
760 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
761 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
762 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
763 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
764 return LAST_REGISTER + 1;
765 }
766
767 bool validRegister(int num) const {
768 return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
769 }
770
771 uint64_t getRegister(int num) const {
772 assert(validRegister(num));
773 return reg[num];
774 }
775
776 void setRegister(int num, uint64_t value) {
777 assert(validRegister(num));
778 reg[num] = value;
779 }
780
781 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
782
783 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
784
785 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
786
787 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
788
789 bool validFloatVectorRegister(int num) const {
790 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
791 }
792
793 void copyFloatVectorRegister(int num, uint64_t addr_) {
794 assert(validFloatVectorRegister(num));
795 const void *addr = reinterpret_cast<const void *>(addr_);
796 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
797 }
798
799 __dso_hidden void jumpto() const __dead;
800
801 private:
802 uint32_t reg[REGNO_HPPA_R31 + 1];
803 uint32_t fpreg[56];
804 };
805
806 enum {
807 DWARF_MIPS_R1 = 0,
808 DWARF_MIPS_R31 = 31,
809 DWARF_MIPS_F0 = 32,
810 DWARF_MIPS_F31 = 63,
811
812 REGNO_MIPS_PC = 0,
813 REGNO_MIPS_R1 = 0,
814 REGNO_MIPS_R29 = 29,
815 REGNO_MIPS_R31 = 31,
816 REGNO_MIPS_F0 = 33,
817 REGNO_MIPS_F31 = 64
818 };
819
820 class Registers_MIPS {
821 public:
822 enum {
823 LAST_REGISTER = REGNO_MIPS_F31,
824 LAST_RESTORE_REG = REGNO_MIPS_F31,
825 RETURN_OFFSET = 0,
826 };
827
828 __dso_hidden Registers_MIPS();
829
830 static int dwarf2regno(int num) {
831 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
832 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
833 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
834 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
835 return LAST_REGISTER + 1;
836 }
837
838 bool validRegister(int num) const {
839 return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
840 }
841
842 uint64_t getRegister(int num) const {
843 assert(validRegister(num));
844 return reg[num];
845 }
846
847 void setRegister(int num, uint64_t value) {
848 assert(validRegister(num));
849 reg[num] = value;
850 }
851
852 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
853
854 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
855
856 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
857
858 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
859
860 bool validFloatVectorRegister(int num) const {
861 return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
862 }
863
864 void copyFloatVectorRegister(int num, uint64_t addr_) {
865 assert(validFloatVectorRegister(num));
866 const void *addr = reinterpret_cast<const void *>(addr_);
867 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
868 }
869
870 __dso_hidden void jumpto() const __dead;
871
872 private:
873 uint32_t reg[REGNO_MIPS_R31 + 1];
874 uint64_t fpreg[32];
875 };
876
877 enum {
878 DWARF_MIPS64_R1 = 0,
879 DWARF_MIPS64_R31 = 31,
880 DWARF_MIPS64_F0 = 32,
881 DWARF_MIPS64_F31 = 63,
882
883 REGNO_MIPS64_PC = 0,
884 REGNO_MIPS64_R1 = 0,
885 REGNO_MIPS64_R29 = 29,
886 REGNO_MIPS64_R31 = 31,
887 REGNO_MIPS64_F0 = 33,
888 REGNO_MIPS64_F31 = 64
889 };
890
891 class Registers_MIPS64 {
892 public:
893 enum {
894 LAST_REGISTER = REGNO_MIPS64_F31,
895 LAST_RESTORE_REG = REGNO_MIPS64_F31,
896 RETURN_OFFSET = 0,
897 };
898
899 __dso_hidden Registers_MIPS64();
900
901 static int dwarf2regno(int num) {
902 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
903 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
904 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
905 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
906 return LAST_REGISTER + 1;
907 }
908
909 bool validRegister(int num) const {
910 return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
911 }
912
913 uint64_t getRegister(int num) const {
914 assert(validRegister(num));
915 return reg[num];
916 }
917
918 void setRegister(int num, uint64_t value) {
919 assert(validRegister(num));
920 reg[num] = value;
921 }
922
923 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
924
925 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
926
927 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
928
929 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
930
931 bool validFloatVectorRegister(int num) const {
932 return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
933 }
934
935 void copyFloatVectorRegister(int num, uint64_t addr_) {
936 assert(validFloatVectorRegister(num));
937 const void *addr = reinterpret_cast<const void *>(addr_);
938 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
939 }
940
941 __dso_hidden void jumpto() const __dead;
942
943 private:
944 uint64_t reg[REGNO_MIPS64_R31 + 1];
945 uint64_t fpreg[32];
946 };
947
948 #if __i386__
949 typedef Registers_x86 NativeUnwindRegisters;
950 #elif __x86_64__
951 typedef Registers_x86_64 NativeUnwindRegisters;
952 #elif __powerpc__
953 typedef Registers_ppc32 NativeUnwindRegisters;
954 #elif __arm__
955 typedef Registers_arm32 NativeUnwindRegisters;
956 #elif __vax__
957 typedef Registers_vax NativeUnwindRegisters;
958 #elif __m68k__
959 typedef Registers_M68K NativeUnwindRegisters;
960 #elif __mips_n64 || __mips_n32
961 typedef Registers_MIPS64 NativeUnwindRegisters;
962 #elif __mips__
963 typedef Registers_MIPS NativeUnwindRegisters;
964 #elif __sh3__
965 typedef Registers_SH3 NativeUnwindRegisters;
966 #elif __sparc64__
967 typedef Registers_SPARC64 NativeUnwindRegisters;
968 #elif __sparc__
969 typedef Registers_SPARC NativeUnwindRegisters;
970 #elif __alpha__
971 typedef Registers_Alpha NativeUnwindRegisters;
972 #elif __hppa__
973 typedef Registers_HPPA NativeUnwindRegisters;
974 #endif
975 } // namespace _Unwind
976
977 #endif // __REGISTERS_HPP__
978