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