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