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