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