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