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