Registers.hpp revision 1.26 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_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_V0 = 32,
254 REGNO_AARCH64_V31 = 63,
255 };
256
257 class Registers_aarch64 {
258 public:
259 enum {
260 LAST_RESTORE_REG = REGNO_AARCH64_V31,
261 LAST_REGISTER = REGNO_AARCH64_V31,
262 RETURN_OFFSET = 0,
263 RETURN_MASK = 0,
264 };
265
266 __dso_hidden Registers_aarch64();
267
268 static int dwarf2regno(int num) {
269 if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
270 return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
271 if (num == DWARF_AARCH64_SP)
272 return REGNO_AARCH64_SP;
273 if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
274 return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
275 return LAST_REGISTER + 1;
276 }
277
278 bool validRegister(int num) const {
279 return num >= 0 && num <= LAST_RESTORE_REG;
280 }
281
282 uint64_t getRegister(int num) const {
283 assert(validRegister(num));
284 return reg[num];
285 }
286
287 void setRegister(int num, uint64_t value) {
288 assert(validRegister(num));
289 reg[num] = value;
290 }
291
292 uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
293
294 void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
295
296 uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
297
298 void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
299
300 bool validFloatVectorRegister(int num) const {
301 return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
302 }
303
304 void copyFloatVectorRegister(int num, uint64_t addr_) {
305 const void *addr = reinterpret_cast<const void *>(addr_);
306 memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16);
307 }
308
309 __dso_hidden void jumpto() const __dead;
310
311 private:
312 uint64_t reg[REGNO_AARCH64_SP + 1];
313 uint64_t vecreg[64];
314 };
315
316 enum {
317 DWARF_ARM32_R0 = 0,
318 DWARF_ARM32_R15 = 15,
319 DWARF_ARM32_SPSR = 128,
320 DWARF_ARM32_S0 = 64,
321 DWARF_ARM32_S31 = 95,
322 DWARF_ARM32_D0 = 256,
323 DWARF_ARM32_D31 = 287,
324 REGNO_ARM32_R0 = 0,
325 REGNO_ARM32_SP = 13,
326 REGNO_ARM32_R15 = 15,
327 REGNO_ARM32_SPSR = 16,
328 REGNO_ARM32_D0 = 17,
329 REGNO_ARM32_D15 = 32,
330 REGNO_ARM32_D31 = 48,
331 REGNO_ARM32_S0 = 49,
332 REGNO_ARM32_S31 = 80,
333 };
334
335 class Registers_arm32 {
336 public:
337 enum {
338 LAST_REGISTER = REGNO_ARM32_D31,
339 LAST_RESTORE_REG = REGNO_ARM32_D31,
340 RETURN_OFFSET = 0,
341 RETURN_MASK = 0,
342 };
343
344 __dso_hidden Registers_arm32();
345
346 static int dwarf2regno(int num) {
347 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
348 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
349 if (num == DWARF_ARM32_SPSR)
350 return REGNO_ARM32_SPSR;
351 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
352 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
353 if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31)
354 return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
355 return LAST_REGISTER + 1;
356 }
357
358 bool validRegister(int num) const {
359 return num >= 0 && num <= REGNO_ARM32_SPSR;
360 }
361
362 uint64_t getRegister(int num) const {
363 assert(validRegister(num));
364 return reg[num];
365 }
366
367 void setRegister(int num, uint64_t value) {
368 assert(validRegister(num));
369 reg[num] = value;
370 }
371
372 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
373
374 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
375
376 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
377
378 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
379
380 bool validFloatVectorRegister(int num) const {
381 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
382 }
383
384 void copyFloatVectorRegister(int num, uint64_t addr_) {
385 assert(validFloatVectorRegister(num));
386 const void *addr = reinterpret_cast<const void *>(addr_);
387 if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
388 if ((flags & FLAGS_VFPV2_USED) == 0) {
389 lazyVFPv2();
390 flags |= FLAGS_VFPV2_USED;
391 }
392 /*
393 * Emulate single precision register as half of the
394 * corresponding double register.
395 */
396 int dnum = (num - REGNO_ARM32_S0) / 2;
397 int part = (num - REGNO_ARM32_S0) % 2;
398 #if _BYTE_ORDER == _BIG_ENDIAN
399 part = 1 - part;
400 #endif
401 memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2,
402 addr, sizeof(fpreg[0]) / 2);
403 } else {
404 if (num <= REGNO_ARM32_D15) {
405 if ((flags & FLAGS_VFPV2_USED) == 0) {
406 lazyVFPv2();
407 flags |= FLAGS_VFPV2_USED;
408 }
409 } else {
410 if ((flags & FLAGS_VFPV3_USED) == 0) {
411 lazyVFPv3();
412 flags |= FLAGS_VFPV3_USED;
413 }
414 }
415 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
416 }
417 }
418
419 __dso_hidden void lazyVFPv2();
420 __dso_hidden void lazyVFPv3();
421 __dso_hidden void jumpto() const __dead;
422
423 private:
424 uint32_t reg[REGNO_ARM32_SPSR + 1];
425 uint32_t flags;
426 uint64_t fpreg[32];
427
428 enum {
429 FLAGS_VFPV2_USED = 0x1,
430 FLAGS_VFPV3_USED = 0x2,
431 };
432 };
433
434 enum {
435 DWARF_VAX_R0 = 0,
436 DWARF_VAX_R15 = 15,
437 DWARF_VAX_PSW = 16,
438
439 REGNO_VAX_R0 = 0,
440 REGNO_VAX_R14 = 14,
441 REGNO_VAX_R15 = 15,
442 REGNO_VAX_PSW = 16,
443 };
444
445 class Registers_vax {
446 public:
447 enum {
448 LAST_REGISTER = REGNO_VAX_PSW,
449 LAST_RESTORE_REG = REGNO_VAX_PSW,
450 RETURN_OFFSET = 0,
451 RETURN_MASK = 0,
452 };
453
454 __dso_hidden Registers_vax();
455
456 static int dwarf2regno(int num) {
457 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
458 return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
459 if (num == DWARF_VAX_PSW)
460 return REGNO_VAX_PSW;
461 return LAST_REGISTER + 1;
462 }
463
464 bool validRegister(int num) const {
465 return num >= 0 && num <= LAST_RESTORE_REG;
466 }
467
468 uint64_t getRegister(int num) const {
469 assert(validRegister(num));
470 return reg[num];
471 }
472
473 void setRegister(int num, uint64_t value) {
474 assert(validRegister(num));
475 reg[num] = value;
476 }
477
478 uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
479
480 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
481
482 uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
483
484 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
485
486 bool validFloatVectorRegister(int num) const {
487 return false;
488 }
489
490 void copyFloatVectorRegister(int num, uint64_t addr_) {
491 }
492
493 __dso_hidden void jumpto() const __dead;
494
495 private:
496 uint32_t reg[REGNO_VAX_PSW + 1];
497 };
498
499 enum {
500 DWARF_M68K_A0 = 0,
501 DWARF_M68K_A7 = 7,
502 DWARF_M68K_D0 = 8,
503 DWARF_M68K_D7 = 15,
504 DWARF_M68K_FP0 = 16,
505 DWARF_M68K_FP7 = 23,
506 DWARF_M68K_PC = 24,
507
508 REGNO_M68K_A0 = 0,
509 REGNO_M68K_A7 = 7,
510 REGNO_M68K_D0 = 8,
511 REGNO_M68K_D7 = 15,
512 REGNO_M68K_PC = 16,
513 REGNO_M68K_FP0 = 17,
514 REGNO_M68K_FP7 = 24,
515 };
516
517 class Registers_M68K {
518 public:
519 enum {
520 LAST_REGISTER = REGNO_M68K_FP7,
521 LAST_RESTORE_REG = REGNO_M68K_FP7,
522 RETURN_OFFSET = 0,
523 RETURN_MASK = 0,
524 };
525
526 __dso_hidden Registers_M68K();
527
528 static int dwarf2regno(int num) {
529 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
530 return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
531 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
532 return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
533 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
534 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
535 if (num == DWARF_M68K_PC)
536 return REGNO_M68K_PC;
537 return LAST_REGISTER + 1;
538 }
539
540 bool validRegister(int num) const {
541 return num >= 0 && num <= REGNO_M68K_PC;
542 }
543
544 uint64_t getRegister(int num) const {
545 assert(validRegister(num));
546 return reg[num];
547 }
548
549 void setRegister(int num, uint64_t value) {
550 assert(validRegister(num));
551 reg[num] = value;
552 }
553
554 uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
555
556 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
557
558 uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
559
560 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
561
562 bool validFloatVectorRegister(int num) const {
563 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
564 }
565
566 void copyFloatVectorRegister(int num, uint64_t addr_) {
567 assert(validFloatVectorRegister(num));
568 const void *addr = reinterpret_cast<const void *>(addr_);
569 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
570 }
571
572 __dso_hidden void jumpto() const __dead;
573
574 private:
575 typedef uint32_t fpreg_t[3];
576
577 uint32_t reg[REGNO_M68K_PC + 1];
578 uint32_t dummy;
579 fpreg_t fpreg[8];
580 };
581
582 enum {
583 DWARF_SH3_R0 = 0,
584 DWARF_SH3_R15 = 15,
585 DWARF_SH3_PC = 16,
586 DWARF_SH3_PR = 17,
587
588 REGNO_SH3_R0 = 0,
589 REGNO_SH3_R15 = 15,
590 REGNO_SH3_PC = 16,
591 REGNO_SH3_PR = 17,
592 };
593
594 class Registers_SH3 {
595 public:
596 enum {
597 LAST_REGISTER = REGNO_SH3_PR,
598 LAST_RESTORE_REG = REGNO_SH3_PR,
599 RETURN_OFFSET = 0,
600 RETURN_MASK = 0,
601 };
602
603 __dso_hidden Registers_SH3();
604
605 static int dwarf2regno(int num) {
606 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
607 return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
608 if (num == DWARF_SH3_PC)
609 return REGNO_SH3_PC;
610 if (num == DWARF_SH3_PR)
611 return REGNO_SH3_PR;
612 return LAST_REGISTER + 1;
613 }
614
615 bool validRegister(int num) const {
616 return num >= 0 && num <= REGNO_SH3_PR;
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_SH3_PC]; }
630
631 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
632
633 uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
634
635 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = 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_SH3_PR + 1];
645 };
646
647 enum {
648 DWARF_SPARC64_R0 = 0,
649 DWARF_SPARC64_R31 = 31,
650 DWARF_SPARC64_PC = 32,
651
652 REGNO_SPARC64_R0 = 0,
653 REGNO_SPARC64_R14 = 14,
654 REGNO_SPARC64_R15 = 15,
655 REGNO_SPARC64_R31 = 31,
656 REGNO_SPARC64_PC = 32,
657 };
658
659 class Registers_SPARC64 {
660 public:
661 enum {
662 LAST_REGISTER = REGNO_SPARC64_PC,
663 LAST_RESTORE_REG = REGNO_SPARC64_PC,
664 RETURN_OFFSET = 8,
665 RETURN_MASK = 0,
666 };
667 typedef uint64_t reg_t;
668
669 __dso_hidden Registers_SPARC64();
670
671 static int dwarf2regno(int num) {
672 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
673 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
674 if (num == DWARF_SPARC64_PC)
675 return REGNO_SPARC64_PC;
676 return LAST_REGISTER + 1;
677 }
678
679 bool validRegister(int num) const {
680 return num >= 0 && num <= REGNO_SPARC64_PC;
681 }
682
683 uint64_t getRegister(int num) const {
684 assert(validRegister(num));
685 return reg[num];
686 }
687
688 void setRegister(int num, uint64_t value) {
689 assert(validRegister(num));
690 reg[num] = value;
691 }
692
693 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
694
695 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
696
697 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
698
699 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
700
701 bool validFloatVectorRegister(int num) const { return false; }
702
703 void copyFloatVectorRegister(int num, uint64_t addr_) {}
704
705 __dso_hidden void jumpto() const __dead;
706
707 private:
708 uint64_t reg[REGNO_SPARC64_PC + 1];
709 };
710
711 enum {
712 DWARF_SPARC_R0 = 0,
713 DWARF_SPARC_R31 = 31,
714 DWARF_SPARC_PC = 32,
715
716 REGNO_SPARC_R0 = 0,
717 REGNO_SPARC_R14 = 14,
718 REGNO_SPARC_R15 = 15,
719 REGNO_SPARC_R31 = 31,
720 REGNO_SPARC_PC = 32,
721 };
722
723 class Registers_SPARC {
724 public:
725 enum {
726 LAST_REGISTER = REGNO_SPARC_PC,
727 LAST_RESTORE_REG = REGNO_SPARC_PC,
728 RETURN_OFFSET = 8,
729 RETURN_MASK = 0,
730 };
731 typedef uint32_t reg_t;
732
733 __dso_hidden Registers_SPARC();
734
735 static int dwarf2regno(int num) {
736 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
737 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
738 if (num == DWARF_SPARC_PC)
739 return REGNO_SPARC_PC;
740 return LAST_REGISTER + 1;
741 }
742
743 bool validRegister(int num) const {
744 return num >= 0 && num <= REGNO_SPARC_PC;
745 }
746
747 uint64_t getRegister(int num) const {
748 assert(validRegister(num));
749 return reg[num];
750 }
751
752 void setRegister(int num, uint64_t value) {
753 assert(validRegister(num));
754 reg[num] = value;
755 }
756
757 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
758
759 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
760
761 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
762
763 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
764
765 bool validFloatVectorRegister(int num) const { return false; }
766
767 void copyFloatVectorRegister(int num, uint64_t addr_) {}
768
769 __dso_hidden void jumpto() const __dead;
770
771 private:
772 uint32_t reg[REGNO_SPARC_PC + 1];
773 };
774
775 enum {
776 DWARF_ALPHA_R0 = 0,
777 DWARF_ALPHA_R30 = 30,
778 DWARF_ALPHA_F0 = 32,
779 DWARF_ALPHA_F30 = 62,
780
781 REGNO_ALPHA_R0 = 0,
782 REGNO_ALPHA_R26 = 26,
783 REGNO_ALPHA_R30 = 30,
784 REGNO_ALPHA_PC = 31,
785 REGNO_ALPHA_F0 = 32,
786 REGNO_ALPHA_F30 = 62,
787 };
788
789 class Registers_Alpha {
790 public:
791 enum {
792 LAST_REGISTER = REGNO_ALPHA_F30,
793 LAST_RESTORE_REG = REGNO_ALPHA_F30,
794 RETURN_OFFSET = 0,
795 RETURN_MASK = 0,
796 };
797 typedef uint32_t reg_t;
798
799 __dso_hidden Registers_Alpha();
800
801 static int dwarf2regno(int num) { return num; }
802
803 bool validRegister(int num) const {
804 return num >= 0 && num <= REGNO_ALPHA_PC;
805 }
806
807 uint64_t getRegister(int num) const {
808 assert(validRegister(num));
809 return reg[num];
810 }
811
812 void setRegister(int num, uint64_t value) {
813 assert(validRegister(num));
814 reg[num] = value;
815 }
816
817 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
818
819 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
820
821 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
822
823 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
824
825 bool validFloatVectorRegister(int num) const {
826 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
827 }
828
829 void copyFloatVectorRegister(int num, uint64_t addr_) {
830 assert(validFloatVectorRegister(num));
831 const void *addr = reinterpret_cast<const void *>(addr_);
832 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
833 }
834
835 __dso_hidden void jumpto() const __dead;
836
837 private:
838 uint64_t reg[REGNO_ALPHA_PC + 1];
839 uint64_t fpreg[31];
840 };
841
842 enum {
843 DWARF_HPPA_R1 = 1,
844 DWARF_HPPA_R31 = 31,
845 DWARF_HPPA_FR4L = 32,
846 DWARF_HPPA_FR31H = 87,
847
848 REGNO_HPPA_PC = 0,
849 REGNO_HPPA_R1 = 1,
850 REGNO_HPPA_R2 = 2,
851 REGNO_HPPA_R30 = 30,
852 REGNO_HPPA_R31 = 31,
853 REGNO_HPPA_FR4L = 32,
854 REGNO_HPPA_FR31H = 87,
855 };
856
857 class Registers_HPPA {
858 public:
859 enum {
860 LAST_REGISTER = REGNO_HPPA_FR31H,
861 LAST_RESTORE_REG = REGNO_HPPA_FR31H,
862 RETURN_OFFSET = 0,
863 RETURN_MASK = 3,
864 };
865
866 __dso_hidden Registers_HPPA();
867
868 static int dwarf2regno(int num) {
869 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
870 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
871 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
872 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
873 return LAST_REGISTER + 1;
874 }
875
876 bool validRegister(int num) const {
877 return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
878 }
879
880 uint64_t getRegister(int num) const {
881 assert(validRegister(num));
882 return reg[num];
883 }
884
885 void setRegister(int num, uint64_t value) {
886 assert(validRegister(num));
887 reg[num] = value;
888 }
889
890 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
891
892 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
893
894 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
895
896 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
897
898 bool validFloatVectorRegister(int num) const {
899 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
900 }
901
902 void copyFloatVectorRegister(int num, uint64_t addr_) {
903 assert(validFloatVectorRegister(num));
904 const void *addr = reinterpret_cast<const void *>(addr_);
905 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
906 }
907
908 __dso_hidden void jumpto() const __dead;
909
910 private:
911 uint32_t reg[REGNO_HPPA_R31 + 1];
912 uint32_t fpreg[56];
913 };
914
915 enum {
916 DWARF_MIPS_R1 = 0,
917 DWARF_MIPS_R31 = 31,
918 DWARF_MIPS_F0 = 32,
919 DWARF_MIPS_F31 = 63,
920
921 REGNO_MIPS_PC = 0,
922 REGNO_MIPS_R1 = 0,
923 REGNO_MIPS_R29 = 29,
924 REGNO_MIPS_R31 = 31,
925 REGNO_MIPS_F0 = 33,
926 REGNO_MIPS_F31 = 64
927 };
928
929 class Registers_MIPS {
930 public:
931 enum {
932 LAST_REGISTER = REGNO_MIPS_F31,
933 LAST_RESTORE_REG = REGNO_MIPS_F31,
934 RETURN_OFFSET = 0,
935 RETURN_MASK = 0,
936 };
937
938 __dso_hidden Registers_MIPS();
939
940 static int dwarf2regno(int num) {
941 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
942 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
943 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
944 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
945 return LAST_REGISTER + 1;
946 }
947
948 bool validRegister(int num) const {
949 return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
950 }
951
952 uint64_t getRegister(int num) const {
953 assert(validRegister(num));
954 return reg[num];
955 }
956
957 void setRegister(int num, uint64_t value) {
958 assert(validRegister(num));
959 reg[num] = value;
960 }
961
962 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
963
964 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
965
966 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
967
968 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
969
970 bool validFloatVectorRegister(int num) const {
971 return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
972 }
973
974 void copyFloatVectorRegister(int num, uint64_t addr_) {
975 assert(validFloatVectorRegister(num));
976 const void *addr = reinterpret_cast<const void *>(addr_);
977 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
978 }
979
980 __dso_hidden void jumpto() const __dead;
981
982 private:
983 uint32_t reg[REGNO_MIPS_R31 + 1];
984 uint64_t fpreg[32];
985 };
986
987 enum {
988 DWARF_MIPS64_R1 = 0,
989 DWARF_MIPS64_R31 = 31,
990 DWARF_MIPS64_F0 = 32,
991 DWARF_MIPS64_F31 = 63,
992
993 REGNO_MIPS64_PC = 0,
994 REGNO_MIPS64_R1 = 0,
995 REGNO_MIPS64_R29 = 29,
996 REGNO_MIPS64_R31 = 31,
997 REGNO_MIPS64_F0 = 33,
998 REGNO_MIPS64_F31 = 64
999 };
1000
1001 class Registers_MIPS64 {
1002 public:
1003 enum {
1004 LAST_REGISTER = REGNO_MIPS64_F31,
1005 LAST_RESTORE_REG = REGNO_MIPS64_F31,
1006 RETURN_OFFSET = 0,
1007 RETURN_MASK = 0,
1008 };
1009
1010 __dso_hidden Registers_MIPS64();
1011
1012 static int dwarf2regno(int num) {
1013 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
1014 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
1015 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
1016 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
1017 return LAST_REGISTER + 1;
1018 }
1019
1020 bool validRegister(int num) const {
1021 return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
1022 }
1023
1024 uint64_t getRegister(int num) const {
1025 assert(validRegister(num));
1026 return reg[num];
1027 }
1028
1029 void setRegister(int num, uint64_t value) {
1030 assert(validRegister(num));
1031 reg[num] = value;
1032 }
1033
1034 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1035
1036 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1037
1038 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1039
1040 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1041
1042 bool validFloatVectorRegister(int num) const {
1043 return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
1044 }
1045
1046 void copyFloatVectorRegister(int num, uint64_t addr_) {
1047 assert(validFloatVectorRegister(num));
1048 const void *addr = reinterpret_cast<const void *>(addr_);
1049 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
1050 }
1051
1052 __dso_hidden void jumpto() const __dead;
1053
1054 private:
1055 uint64_t reg[REGNO_MIPS64_R31 + 1];
1056 uint64_t fpreg[32];
1057 };
1058
1059 enum {
1060 DWARF_OR1K_R0 = 0,
1061 DWARF_OR1K_SP = 1,
1062 DWARF_OR1K_LR = 9,
1063 DWARF_OR1K_R31 = 31,
1064 DWARF_OR1K_FPCSR = 32,
1065
1066 REGNO_OR1K_R0 = 0,
1067 REGNO_OR1K_SP = 1,
1068 REGNO_OR1K_LR = 9,
1069 REGNO_OR1K_R31 = 31,
1070 REGNO_OR1K_FPCSR = 32,
1071 };
1072
1073 class Registers_or1k {
1074 public:
1075 enum {
1076 LAST_REGISTER = REGNO_OR1K_FPCSR,
1077 LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1078 RETURN_OFFSET = 0,
1079 RETURN_MASK = 0,
1080 };
1081
1082 __dso_hidden Registers_or1k();
1083
1084 static int dwarf2regno(int num) {
1085 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1086 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1087 if (num == DWARF_OR1K_FPCSR)
1088 return REGNO_OR1K_FPCSR;
1089 return LAST_REGISTER + 1;
1090 }
1091
1092 bool validRegister(int num) const {
1093 return num >= 0 && num <= LAST_RESTORE_REG;
1094 }
1095
1096 uint64_t getRegister(int num) const {
1097 assert(validRegister(num));
1098 return reg[num];
1099 }
1100
1101 void setRegister(int num, uint64_t value) {
1102 assert(validRegister(num));
1103 reg[num] = value;
1104 }
1105
1106 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1107
1108 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1109
1110 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1111
1112 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1113
1114 bool validFloatVectorRegister(int num) const {
1115 return false;
1116 }
1117
1118 void copyFloatVectorRegister(int num, uint64_t addr_) {
1119 }
1120
1121 __dso_hidden void jumpto() const __dead;
1122
1123 private:
1124 uint32_t reg[REGNO_OR1K_FPCSR + 1];
1125 };
1126
1127 #if __i386__
1128 typedef Registers_x86 NativeUnwindRegisters;
1129 #elif __x86_64__
1130 typedef Registers_x86_64 NativeUnwindRegisters;
1131 #elif __powerpc__
1132 typedef Registers_ppc32 NativeUnwindRegisters;
1133 #elif __aarch64__
1134 typedef Registers_aarch64 NativeUnwindRegisters;
1135 #elif __arm__
1136 typedef Registers_arm32 NativeUnwindRegisters;
1137 #elif __vax__
1138 typedef Registers_vax NativeUnwindRegisters;
1139 #elif __m68k__
1140 typedef Registers_M68K NativeUnwindRegisters;
1141 #elif __mips_n64 || __mips_n32
1142 typedef Registers_MIPS64 NativeUnwindRegisters;
1143 #elif __mips__
1144 typedef Registers_MIPS NativeUnwindRegisters;
1145 #elif __sh3__
1146 typedef Registers_SH3 NativeUnwindRegisters;
1147 #elif __sparc64__
1148 typedef Registers_SPARC64 NativeUnwindRegisters;
1149 #elif __sparc__
1150 typedef Registers_SPARC NativeUnwindRegisters;
1151 #elif __alpha__
1152 typedef Registers_Alpha NativeUnwindRegisters;
1153 #elif __hppa__
1154 typedef Registers_HPPA NativeUnwindRegisters;
1155 #elif __or1k__
1156 typedef Registers_or1k NativeUnwindRegisters;
1157 #endif
1158 } // namespace _Unwind
1159
1160 #endif // __REGISTERS_HPP__
1161