Registers.hpp revision 1.33 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_CTR = 66,
152 DWARF_PPC32_CR = 70,
153 DWARF_PPC32_XER = 76,
154 DWARF_PPC32_V0 = 77,
155 DWARF_PPC32_SIGRETURN = 99,
156 DWARF_PPC32_V31 = 108,
157
158 REGNO_PPC32_R0 = 0,
159 REGNO_PPC32_R1 = 1,
160 REGNO_PPC32_R31 = 31,
161 REGNO_PPC32_LR = 32,
162 REGNO_PPC32_CR = 33,
163 REGNO_PPC32_SRR0 = 34,
164
165 REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
166 REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
167 REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
168 REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
169
170 REGNO_PPC32_CTR = REGNO_PPC32_V31 + 1,
171 REGNO_PPC32_XER = REGNO_PPC32_CTR + 1,
172 REGNO_PPC32_SIGRETURN = REGNO_PPC32_XER + 1
173 };
174
175 class Registers_ppc32 {
176 public:
177 enum {
178 LAST_REGISTER = REGNO_PPC32_SIGRETURN,
179 LAST_RESTORE_REG = REGNO_PPC32_SIGRETURN,
180 RETURN_OFFSET = 0,
181 RETURN_MASK = 0,
182 };
183
184 __dso_hidden Registers_ppc32();
185
186 static int dwarf2regno(int num) {
187 if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
188 return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
189 if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
190 return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
191 if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
192 return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
193 switch (num) {
194 case DWARF_PPC32_LR:
195 return REGNO_PPC32_LR;
196 case DWARF_PPC32_CR:
197 return REGNO_PPC32_CR;
198 case DWARF_PPC32_CTR:
199 return REGNO_PPC32_CTR;
200 case DWARF_PPC32_XER:
201 return REGNO_PPC32_XER;
202 case DWARF_PPC32_SIGRETURN:
203 return REGNO_PPC32_SIGRETURN;
204 default:
205 return LAST_REGISTER + 1;
206 }
207 }
208
209 bool validRegister(int num) const {
210 return (num >= 0 && num <= REGNO_PPC32_SRR0) ||
211 (num >= REGNO_PPC32_CTR && num <= REGNO_PPC32_SIGRETURN);
212 }
213
214 uint64_t getRegister(int num) const {
215 assert(validRegister(num));
216 switch (num) {
217 case REGNO_PPC32_CTR:
218 return ctr_reg;
219 case REGNO_PPC32_XER:
220 return xer_reg;
221 case REGNO_PPC32_SIGRETURN:
222 return sigreturn_reg;
223 default:
224 return reg[num];
225 }
226 }
227
228 void setRegister(int num, uint64_t value) {
229 assert(validRegister(num));
230 switch (num) {
231 case REGNO_PPC32_CTR:
232 ctr_reg = value;
233 break;
234 case REGNO_PPC32_XER:
235 xer_reg = value;
236 break;
237 case REGNO_PPC32_SIGRETURN:
238 sigreturn_reg = value;
239 break;
240 default:
241 reg[num] = value;
242 }
243 }
244
245 uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
246
247 void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
248
249 uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
250
251 void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
252
253 bool validFloatVectorRegister(int num) const {
254 return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
255 (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
256 }
257
258 void copyFloatVectorRegister(int num, uint64_t addr_) {
259 const void *addr = reinterpret_cast<const void *>(addr_);
260 if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
261 memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
262 else
263 memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
264 }
265
266 __dso_hidden void jumpto() const __dead;
267
268 private:
269 struct vecreg_t {
270 uint64_t low, high;
271 };
272 uint32_t reg[REGNO_PPC32_SRR0 + 1];
273 uint32_t dummy;
274 uint64_t fpreg[32];
275 vecreg_t vecreg[64];
276 uint32_t ctr_reg;
277 uint32_t xer_reg;
278 uint32_t sigreturn_reg;
279 };
280
281 enum {
282 DWARF_AARCH64_X0 = 0,
283 DWARF_AARCH64_X30 = 30,
284 DWARF_AARCH64_SP = 31,
285 DWARF_AARCH64_V0 = 64,
286 DWARF_AARCH64_V31 = 95,
287
288 REGNO_AARCH64_X0 = 0,
289 REGNO_AARCH64_X30 = 30,
290 REGNO_AARCH64_SP = 31,
291 REGNO_AARCH64_V0 = 32,
292 REGNO_AARCH64_V31 = 63,
293 };
294
295 class Registers_aarch64 {
296 public:
297 enum {
298 LAST_RESTORE_REG = REGNO_AARCH64_V31,
299 LAST_REGISTER = REGNO_AARCH64_V31,
300 RETURN_OFFSET = 0,
301 RETURN_MASK = 0,
302 };
303
304 __dso_hidden Registers_aarch64();
305
306 static int dwarf2regno(int num) {
307 if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
308 return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
309 if (num == DWARF_AARCH64_SP)
310 return REGNO_AARCH64_SP;
311 if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
312 return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
313 return LAST_REGISTER + 1;
314 }
315
316 bool validRegister(int num) const {
317 return num >= 0 && num <= LAST_RESTORE_REG;
318 }
319
320 uint64_t getRegister(int num) const {
321 assert(validRegister(num));
322 return reg[num];
323 }
324
325 void setRegister(int num, uint64_t value) {
326 assert(validRegister(num));
327 reg[num] = value;
328 }
329
330 uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
331
332 void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
333
334 uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
335
336 void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
337
338 bool validFloatVectorRegister(int num) const {
339 return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
340 }
341
342 void copyFloatVectorRegister(int num, uint64_t addr_) {
343 const void *addr = reinterpret_cast<const void *>(addr_);
344 memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16);
345 }
346
347 __dso_hidden void jumpto() const __dead;
348
349 private:
350 uint64_t reg[REGNO_AARCH64_SP + 1];
351 uint64_t vecreg[64];
352 };
353
354 enum {
355 DWARF_ARM32_R0 = 0,
356 DWARF_ARM32_R15 = 15,
357 DWARF_ARM32_SPSR = 128,
358 DWARF_ARM32_S0 = 64,
359 DWARF_ARM32_S31 = 95,
360 DWARF_ARM32_D0 = 256,
361 DWARF_ARM32_D31 = 287,
362 REGNO_ARM32_R0 = 0,
363 REGNO_ARM32_SP = 13,
364 REGNO_ARM32_R15 = 15,
365 REGNO_ARM32_SPSR = 16,
366 REGNO_ARM32_D0 = 17,
367 REGNO_ARM32_D15 = 32,
368 REGNO_ARM32_D31 = 48,
369 REGNO_ARM32_S0 = 49,
370 REGNO_ARM32_S31 = 80,
371 };
372
373 #define FLAGS_VFPV2_USED 0x1
374 #define FLAGS_VFPV3_USED 0x2
375 #define FLAGS_LEGACY_VFPV2_REGNO 0x4
376 #define FLAGS_EXTENDED_VFPV2_REGNO 0x8
377
378 class Registers_arm32 {
379 public:
380 enum {
381 LAST_REGISTER = REGNO_ARM32_S31,
382 LAST_RESTORE_REG = REGNO_ARM32_S31,
383 RETURN_OFFSET = 0,
384 RETURN_MASK = 0,
385 };
386
387 __dso_hidden Registers_arm32();
388
389 static int dwarf2regno(int num) {
390 if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
391 return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
392 if (num == DWARF_ARM32_SPSR)
393 return REGNO_ARM32_SPSR;
394 if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
395 return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
396 if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31)
397 return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
398 return LAST_REGISTER + 1;
399 }
400
401 bool validRegister(int num) const {
402 return num >= 0 && num <= REGNO_ARM32_SPSR;
403 }
404
405 uint64_t getRegister(int num) const {
406 assert(validRegister(num));
407 return reg[num];
408 }
409
410 void setRegister(int num, uint64_t value) {
411 assert(validRegister(num));
412 reg[num] = value;
413 }
414
415 uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
416
417 void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
418
419 uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
420
421 void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
422
423 bool validFloatVectorRegister(int num) const {
424 return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
425 }
426
427 void copyFloatVectorRegister(int num, uint64_t addr_) {
428 assert(validFloatVectorRegister(num));
429 const void *addr = reinterpret_cast<const void *>(addr_);
430 if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
431 /*
432 * XXX
433 * There are two numbering schemes for VFPv2 registers: s0-s31
434 * (used by GCC) and d0-d15 (used by LLVM). We won't support both
435 * schemes simultaneously in a same frame.
436 */
437 assert((flags & FLAGS_EXTENDED_VFPV2_REGNO) == 0);
438 flags |= FLAGS_LEGACY_VFPV2_REGNO;
439 if ((flags & FLAGS_VFPV2_USED) == 0) {
440 lazyVFPv2();
441 flags |= FLAGS_VFPV2_USED;
442 }
443 /*
444 * Emulate single precision register as half of the
445 * corresponding double register.
446 */
447 int dnum = (num - REGNO_ARM32_S0) / 2;
448 int part = (num - REGNO_ARM32_S0) % 2;
449 #if _BYTE_ORDER == _BIG_ENDIAN
450 part = 1 - part;
451 #endif
452 memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2,
453 addr, sizeof(fpreg[0]) / 2);
454 } else {
455 if (num <= REGNO_ARM32_D15) {
456 /*
457 * XXX
458 * See XXX comment above.
459 */
460 assert((flags & FLAGS_LEGACY_VFPV2_REGNO) == 0);
461 flags |= FLAGS_EXTENDED_VFPV2_REGNO;
462 if ((flags & FLAGS_VFPV2_USED) == 0) {
463 lazyVFPv2();
464 flags |= FLAGS_VFPV2_USED;
465 }
466 } else {
467 if ((flags & FLAGS_VFPV3_USED) == 0) {
468 lazyVFPv3();
469 flags |= FLAGS_VFPV3_USED;
470 }
471 }
472 memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
473 }
474 }
475
476 __dso_hidden void lazyVFPv2();
477 __dso_hidden void lazyVFPv3();
478 __dso_hidden void jumpto() const __dead;
479
480 private:
481 uint32_t reg[REGNO_ARM32_SPSR + 1];
482 uint32_t flags;
483 uint64_t fpreg[32];
484 };
485
486 #undef FLAGS_VFPV2_USED
487 #undef FLAGS_VFPV3_USED
488 #undef FLAGS_LEGACY_VFPV2_REGNO
489 #undef FLAGS_EXTENDED_VFPV2_REGNO
490
491 enum {
492 DWARF_VAX_R0 = 0,
493 DWARF_VAX_R15 = 15,
494 DWARF_VAX_PSW = 16,
495
496 REGNO_VAX_R0 = 0,
497 REGNO_VAX_R14 = 14,
498 REGNO_VAX_R15 = 15,
499 REGNO_VAX_PSW = 16,
500 };
501
502 class Registers_vax {
503 public:
504 enum {
505 LAST_REGISTER = REGNO_VAX_PSW,
506 LAST_RESTORE_REG = REGNO_VAX_PSW,
507 RETURN_OFFSET = 0,
508 RETURN_MASK = 0,
509 };
510
511 __dso_hidden Registers_vax();
512
513 static int dwarf2regno(int num) {
514 if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
515 return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
516 if (num == DWARF_VAX_PSW)
517 return REGNO_VAX_PSW;
518 return LAST_REGISTER + 1;
519 }
520
521 bool validRegister(int num) const {
522 return num >= 0 && num <= LAST_RESTORE_REG;
523 }
524
525 uint64_t getRegister(int num) const {
526 assert(validRegister(num));
527 return reg[num];
528 }
529
530 void setRegister(int num, uint64_t value) {
531 assert(validRegister(num));
532 reg[num] = value;
533 }
534
535 uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
536
537 void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
538
539 uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
540
541 void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
542
543 bool validFloatVectorRegister(int num) const {
544 return false;
545 }
546
547 void copyFloatVectorRegister(int num, uint64_t addr_) {
548 }
549
550 __dso_hidden void jumpto() const __dead;
551
552 private:
553 uint32_t reg[REGNO_VAX_PSW + 1];
554 };
555
556 enum {
557 DWARF_M68K_A0 = 0,
558 DWARF_M68K_A7 = 7,
559 DWARF_M68K_D0 = 8,
560 DWARF_M68K_D7 = 15,
561 DWARF_M68K_FP0 = 16,
562 DWARF_M68K_FP7 = 23,
563 DWARF_M68K_PC = 24,
564
565 REGNO_M68K_A0 = 0,
566 REGNO_M68K_A7 = 7,
567 REGNO_M68K_D0 = 8,
568 REGNO_M68K_D7 = 15,
569 REGNO_M68K_PC = 16,
570 REGNO_M68K_FP0 = 17,
571 REGNO_M68K_FP7 = 24,
572 };
573
574 class Registers_M68K {
575 public:
576 enum {
577 LAST_REGISTER = REGNO_M68K_FP7,
578 LAST_RESTORE_REG = REGNO_M68K_FP7,
579 RETURN_OFFSET = 0,
580 RETURN_MASK = 0,
581 };
582
583 __dso_hidden Registers_M68K();
584
585 static int dwarf2regno(int num) {
586 if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
587 return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
588 if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
589 return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
590 if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
591 return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
592 if (num == DWARF_M68K_PC)
593 return REGNO_M68K_PC;
594 return LAST_REGISTER + 1;
595 }
596
597 bool validRegister(int num) const {
598 return num >= 0 && num <= REGNO_M68K_PC;
599 }
600
601 uint64_t getRegister(int num) const {
602 assert(validRegister(num));
603 return reg[num];
604 }
605
606 void setRegister(int num, uint64_t value) {
607 assert(validRegister(num));
608 reg[num] = value;
609 }
610
611 uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
612
613 void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
614
615 uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
616
617 void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
618
619 bool validFloatVectorRegister(int num) const {
620 return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
621 }
622
623 void copyFloatVectorRegister(int num, uint64_t addr_) {
624 assert(validFloatVectorRegister(num));
625 const void *addr = reinterpret_cast<const void *>(addr_);
626 memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
627 }
628
629 __dso_hidden void jumpto() const __dead;
630
631 private:
632 typedef uint32_t fpreg_t[3];
633
634 uint32_t reg[REGNO_M68K_PC + 1];
635 uint32_t dummy;
636 fpreg_t fpreg[8];
637 };
638
639 enum {
640 DWARF_SH3_R0 = 0,
641 DWARF_SH3_R15 = 15,
642 DWARF_SH3_PC = 16,
643 DWARF_SH3_PR = 17,
644
645 REGNO_SH3_R0 = 0,
646 REGNO_SH3_R15 = 15,
647 REGNO_SH3_PC = 16,
648 REGNO_SH3_PR = 17,
649 };
650
651 class Registers_SH3 {
652 public:
653 enum {
654 LAST_REGISTER = REGNO_SH3_PR,
655 LAST_RESTORE_REG = REGNO_SH3_PR,
656 RETURN_OFFSET = 0,
657 RETURN_MASK = 0,
658 };
659
660 __dso_hidden Registers_SH3();
661
662 static int dwarf2regno(int num) {
663 if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
664 return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
665 if (num == DWARF_SH3_PC)
666 return REGNO_SH3_PC;
667 if (num == DWARF_SH3_PR)
668 return REGNO_SH3_PR;
669 return LAST_REGISTER + 1;
670 }
671
672 bool validRegister(int num) const {
673 return num >= 0 && num <= REGNO_SH3_PR;
674 }
675
676 uint64_t getRegister(int num) const {
677 assert(validRegister(num));
678 return reg[num];
679 }
680
681 void setRegister(int num, uint64_t value) {
682 assert(validRegister(num));
683 reg[num] = value;
684 }
685
686 uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
687
688 void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
689
690 uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
691
692 void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
693
694 bool validFloatVectorRegister(int num) const { return false; }
695
696 void copyFloatVectorRegister(int num, uint64_t addr_) {}
697
698 __dso_hidden void jumpto() const __dead;
699
700 private:
701 uint32_t reg[REGNO_SH3_PR + 1];
702 };
703
704 enum {
705 DWARF_SPARC64_R0 = 0,
706 DWARF_SPARC64_R31 = 31,
707 DWARF_SPARC64_PC = 32,
708
709 REGNO_SPARC64_R0 = 0,
710 REGNO_SPARC64_R14 = 14,
711 REGNO_SPARC64_R15 = 15,
712 REGNO_SPARC64_R31 = 31,
713 REGNO_SPARC64_PC = 32,
714 };
715
716 class Registers_SPARC64 {
717 public:
718 enum {
719 LAST_REGISTER = REGNO_SPARC64_PC,
720 LAST_RESTORE_REG = REGNO_SPARC64_PC,
721 RETURN_OFFSET = 8,
722 RETURN_MASK = 0,
723 };
724 typedef uint64_t reg_t;
725
726 __dso_hidden Registers_SPARC64();
727
728 static int dwarf2regno(int num) {
729 if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
730 return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
731 if (num == DWARF_SPARC64_PC)
732 return REGNO_SPARC64_PC;
733 return LAST_REGISTER + 1;
734 }
735
736 bool validRegister(int num) const {
737 return num >= 0 && num <= REGNO_SPARC64_PC;
738 }
739
740 uint64_t getRegister(int num) const {
741 assert(validRegister(num));
742 return reg[num];
743 }
744
745 void setRegister(int num, uint64_t value) {
746 assert(validRegister(num));
747 reg[num] = value;
748 }
749
750 uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
751
752 void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
753
754 uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
755
756 void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
757
758 bool validFloatVectorRegister(int num) const { return false; }
759
760 void copyFloatVectorRegister(int num, uint64_t addr_) {}
761
762 __dso_hidden void jumpto() const __dead;
763
764 private:
765 uint64_t reg[REGNO_SPARC64_PC + 1];
766 };
767
768 enum {
769 DWARF_SPARC_R0 = 0,
770 DWARF_SPARC_R31 = 31,
771 DWARF_SPARC_PC = 32,
772
773 REGNO_SPARC_R0 = 0,
774 REGNO_SPARC_R14 = 14,
775 REGNO_SPARC_R15 = 15,
776 REGNO_SPARC_R31 = 31,
777 REGNO_SPARC_PC = 32,
778 };
779
780 class Registers_SPARC {
781 public:
782 enum {
783 LAST_REGISTER = REGNO_SPARC_PC,
784 LAST_RESTORE_REG = REGNO_SPARC_PC,
785 RETURN_OFFSET = 8,
786 RETURN_MASK = 0,
787 };
788 typedef uint32_t reg_t;
789
790 __dso_hidden Registers_SPARC();
791
792 static int dwarf2regno(int num) {
793 if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
794 return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
795 if (num == DWARF_SPARC_PC)
796 return REGNO_SPARC_PC;
797 return LAST_REGISTER + 1;
798 }
799
800 bool validRegister(int num) const {
801 return num >= 0 && num <= REGNO_SPARC_PC;
802 }
803
804 uint64_t getRegister(int num) const {
805 assert(validRegister(num));
806 return reg[num];
807 }
808
809 void setRegister(int num, uint64_t value) {
810 assert(validRegister(num));
811 reg[num] = value;
812 }
813
814 uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
815
816 void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
817
818 uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
819
820 void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
821
822 bool validFloatVectorRegister(int num) const { return false; }
823
824 void copyFloatVectorRegister(int num, uint64_t addr_) {}
825
826 __dso_hidden void jumpto() const __dead;
827
828 private:
829 uint32_t reg[REGNO_SPARC_PC + 1];
830 };
831
832 enum {
833 DWARF_ALPHA_R0 = 0,
834 DWARF_ALPHA_R30 = 30,
835 DWARF_ALPHA_F0 = 32,
836 DWARF_ALPHA_F30 = 62,
837 DWARF_ALPHA_SIGRETURN = 64,
838
839 REGNO_ALPHA_R0 = 0,
840 REGNO_ALPHA_R26 = 26,
841 REGNO_ALPHA_R30 = 30,
842 REGNO_ALPHA_PC = 31,
843 REGNO_ALPHA_F0 = 32,
844 REGNO_ALPHA_F30 = 62,
845 REGNO_ALPHA_SIGRETURN = 64,
846 };
847
848 class Registers_Alpha {
849 public:
850 enum {
851 LAST_REGISTER = REGNO_ALPHA_SIGRETURN,
852 LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN,
853 RETURN_OFFSET = 0,
854 RETURN_MASK = 0,
855 };
856 typedef uint32_t reg_t;
857
858 __dso_hidden Registers_Alpha();
859
860 static int dwarf2regno(int num) { return num; }
861
862 bool validRegister(int num) const {
863 return (num >= 0 && num <= REGNO_ALPHA_PC) ||
864 num == REGNO_ALPHA_SIGRETURN;
865 }
866
867 uint64_t getRegister(int num) const {
868 assert(validRegister(num));
869 if (num == REGNO_ALPHA_SIGRETURN)
870 return sigreturn_reg;
871 else
872 return reg[num];
873 }
874
875 void setRegister(int num, uint64_t value) {
876 assert(validRegister(num));
877 if (num == REGNO_ALPHA_SIGRETURN)
878 sigreturn_reg = value;
879 else
880 reg[num] = value;
881 }
882
883 uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
884
885 void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
886
887 uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
888
889 void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
890
891 bool validFloatVectorRegister(int num) const {
892 return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
893 }
894
895 void copyFloatVectorRegister(int num, uint64_t addr_) {
896 assert(validFloatVectorRegister(num));
897 const void *addr = reinterpret_cast<const void *>(addr_);
898 memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
899 }
900
901 __dso_hidden void jumpto() const __dead;
902
903 private:
904 uint64_t reg[REGNO_ALPHA_PC + 1];
905 uint64_t fpreg[31];
906 uint64_t sigreturn_reg;
907 };
908
909 enum {
910 DWARF_HPPA_R1 = 1,
911 DWARF_HPPA_R31 = 31,
912 DWARF_HPPA_FR4L = 32,
913 DWARF_HPPA_FR31H = 87,
914
915 REGNO_HPPA_PC = 0,
916 REGNO_HPPA_R1 = 1,
917 REGNO_HPPA_R2 = 2,
918 REGNO_HPPA_R30 = 30,
919 REGNO_HPPA_R31 = 31,
920 REGNO_HPPA_FR4L = 32,
921 REGNO_HPPA_FR31H = 87,
922 };
923
924 class Registers_HPPA {
925 public:
926 enum {
927 LAST_REGISTER = REGNO_HPPA_FR31H,
928 LAST_RESTORE_REG = REGNO_HPPA_FR31H,
929 RETURN_OFFSET = 0,
930 RETURN_MASK = 3,
931 };
932
933 __dso_hidden Registers_HPPA();
934
935 static int dwarf2regno(int num) {
936 if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
937 return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
938 if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
939 return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
940 return LAST_REGISTER + 1;
941 }
942
943 bool validRegister(int num) const {
944 return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
945 }
946
947 uint64_t getRegister(int num) const {
948 assert(validRegister(num));
949 return reg[num];
950 }
951
952 void setRegister(int num, uint64_t value) {
953 assert(validRegister(num));
954 reg[num] = value;
955 }
956
957 uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
958
959 void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
960
961 uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
962
963 void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
964
965 bool validFloatVectorRegister(int num) const {
966 return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
967 }
968
969 void copyFloatVectorRegister(int num, uint64_t addr_) {
970 assert(validFloatVectorRegister(num));
971 const void *addr = reinterpret_cast<const void *>(addr_);
972 memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
973 }
974
975 __dso_hidden void jumpto() const __dead;
976
977 private:
978 uint32_t reg[REGNO_HPPA_R31 + 1];
979 uint32_t fpreg[56];
980 };
981
982 enum {
983 DWARF_MIPS_R1 = 0,
984 DWARF_MIPS_R31 = 31,
985 DWARF_MIPS_F0 = 32,
986 DWARF_MIPS_F31 = 63,
987 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
988 // signal handler return address.
989 DWARF_MIPS_MDHI = 64,
990 DWARF_MIPS_MDLO = 65,
991 DWARF_MIPS_SIGRETURN = 66,
992
993 REGNO_MIPS_PC = 0,
994 REGNO_MIPS_R1 = 0,
995 REGNO_MIPS_R29 = 29,
996 REGNO_MIPS_R31 = 31,
997 REGNO_MIPS_F0 = 33,
998 REGNO_MIPS_F31 = 64,
999 // these live in other_reg[]
1000 REGNO_MIPS_MDHI = 65,
1001 REGNO_MIPS_MDLO = 66,
1002 REGNO_MIPS_SIGRETURN = 67
1003 };
1004
1005 class Registers_MIPS {
1006 public:
1007 enum {
1008 LAST_REGISTER = REGNO_MIPS_SIGRETURN,
1009 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
1010 RETURN_OFFSET = 0,
1011 RETURN_MASK = 0,
1012 };
1013
1014 __dso_hidden Registers_MIPS();
1015
1016 static int dwarf2regno(int num) {
1017 if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
1018 return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
1019 if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
1020 return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
1021 if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN)
1022 return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI);
1023 return LAST_REGISTER + 1;
1024 }
1025
1026 bool validRegister(int num) const {
1027 return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) ||
1028 (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN);
1029 }
1030
1031 uint64_t getRegister(int num) const {
1032 assert(validRegister(num));
1033 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
1034 return other_reg[num - REGNO_MIPS_MDHI];
1035 return reg[num];
1036 }
1037
1038 void setRegister(int num, uint64_t value) {
1039 assert(validRegister(num));
1040 if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
1041 other_reg[num - REGNO_MIPS_MDHI] = value;
1042 else
1043 reg[num] = value;
1044 }
1045
1046 uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
1047
1048 void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
1049
1050 uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
1051
1052 void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
1053
1054 bool validFloatVectorRegister(int num) const {
1055 return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
1056 }
1057
1058 void copyFloatVectorRegister(int num, uint64_t addr_) {
1059 assert(validFloatVectorRegister(num));
1060 const void *addr = reinterpret_cast<const void *>(addr_);
1061 memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
1062 }
1063
1064 __dso_hidden void jumpto() const __dead;
1065
1066 private:
1067 uint32_t reg[REGNO_MIPS_R31 + 1];
1068 uint64_t fpreg[32];
1069 uint32_t other_reg[3];
1070 };
1071
1072 enum {
1073 DWARF_MIPS64_R1 = 0,
1074 DWARF_MIPS64_R31 = 31,
1075 DWARF_MIPS64_F0 = 32,
1076 DWARF_MIPS64_F31 = 63,
1077 // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
1078 // signal handler return address.
1079 DWARF_MIPS64_MDHI = 64,
1080 DWARF_MIPS64_MDLO = 65,
1081 DWARF_MIPS64_SIGRETURN = 66,
1082
1083 REGNO_MIPS64_PC = 0,
1084 REGNO_MIPS64_R1 = 0,
1085 REGNO_MIPS64_R29 = 29,
1086 REGNO_MIPS64_R31 = 31,
1087 REGNO_MIPS64_F0 = 33,
1088 REGNO_MIPS64_F31 = 64,
1089 // these live in other_reg[]
1090 REGNO_MIPS64_MDHI = 65,
1091 REGNO_MIPS64_MDLO = 66,
1092 REGNO_MIPS64_SIGRETURN = 67
1093 };
1094
1095 class Registers_MIPS64 {
1096 public:
1097 enum {
1098 LAST_REGISTER = REGNO_MIPS_SIGRETURN,
1099 LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
1100 RETURN_OFFSET = 0,
1101 RETURN_MASK = 0,
1102 };
1103
1104 __dso_hidden Registers_MIPS64();
1105
1106 static int dwarf2regno(int num) {
1107 if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
1108 return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
1109 if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
1110 return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
1111 if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN)
1112 return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI);
1113 return LAST_REGISTER + 1;
1114 }
1115
1116 bool validRegister(int num) const {
1117 return (num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31) ||
1118 (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN);
1119 }
1120
1121 uint64_t getRegister(int num) const {
1122 assert(validRegister(num));
1123 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1124 return other_reg[num - REGNO_MIPS64_MDHI];
1125 return reg[num];
1126 }
1127
1128 void setRegister(int num, uint64_t value) {
1129 assert(validRegister(num));
1130 if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1131 other_reg[num - REGNO_MIPS64_MDHI] = value;
1132 else
1133 reg[num] = value;
1134 }
1135
1136 uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1137
1138 void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1139
1140 uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1141
1142 void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1143
1144 bool validFloatVectorRegister(int num) const {
1145 return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
1146 }
1147
1148 void copyFloatVectorRegister(int num, uint64_t addr_) {
1149 assert(validFloatVectorRegister(num));
1150 const void *addr = reinterpret_cast<const void *>(addr_);
1151 memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
1152 }
1153
1154 __dso_hidden void jumpto() const __dead;
1155
1156 private:
1157 uint64_t reg[REGNO_MIPS64_R31 + 1];
1158 uint64_t fpreg[32];
1159 uint64_t other_reg[3];
1160 };
1161
1162 enum {
1163 DWARF_OR1K_R0 = 0,
1164 DWARF_OR1K_SP = 1,
1165 DWARF_OR1K_LR = 9,
1166 DWARF_OR1K_R31 = 31,
1167 DWARF_OR1K_FPCSR = 32,
1168
1169 REGNO_OR1K_R0 = 0,
1170 REGNO_OR1K_SP = 1,
1171 REGNO_OR1K_LR = 9,
1172 REGNO_OR1K_R31 = 31,
1173 REGNO_OR1K_FPCSR = 32,
1174 };
1175
1176 class Registers_or1k {
1177 public:
1178 enum {
1179 LAST_REGISTER = REGNO_OR1K_FPCSR,
1180 LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1181 RETURN_OFFSET = 0,
1182 RETURN_MASK = 0,
1183 };
1184
1185 __dso_hidden Registers_or1k();
1186
1187 static int dwarf2regno(int num) {
1188 if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1189 return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1190 if (num == DWARF_OR1K_FPCSR)
1191 return REGNO_OR1K_FPCSR;
1192 return LAST_REGISTER + 1;
1193 }
1194
1195 bool validRegister(int num) const {
1196 return num >= 0 && num <= LAST_RESTORE_REG;
1197 }
1198
1199 uint64_t getRegister(int num) const {
1200 assert(validRegister(num));
1201 return reg[num];
1202 }
1203
1204 void setRegister(int num, uint64_t value) {
1205 assert(validRegister(num));
1206 reg[num] = value;
1207 }
1208
1209 uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1210
1211 void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1212
1213 uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1214
1215 void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1216
1217 bool validFloatVectorRegister(int num) const {
1218 return false;
1219 }
1220
1221 void copyFloatVectorRegister(int num, uint64_t addr_) {
1222 }
1223
1224 __dso_hidden void jumpto() const __dead;
1225
1226 private:
1227 uint32_t reg[REGNO_OR1K_FPCSR + 1];
1228 };
1229
1230 #if __i386__
1231 typedef Registers_x86 NativeUnwindRegisters;
1232 #elif __x86_64__
1233 typedef Registers_x86_64 NativeUnwindRegisters;
1234 #elif __powerpc__
1235 typedef Registers_ppc32 NativeUnwindRegisters;
1236 #elif __aarch64__
1237 typedef Registers_aarch64 NativeUnwindRegisters;
1238 #elif __arm__
1239 typedef Registers_arm32 NativeUnwindRegisters;
1240 #elif __vax__
1241 typedef Registers_vax NativeUnwindRegisters;
1242 #elif __m68k__
1243 typedef Registers_M68K NativeUnwindRegisters;
1244 #elif __mips_n64 || __mips_n32
1245 typedef Registers_MIPS64 NativeUnwindRegisters;
1246 #elif __mips__
1247 typedef Registers_MIPS NativeUnwindRegisters;
1248 #elif __sh3__
1249 typedef Registers_SH3 NativeUnwindRegisters;
1250 #elif __sparc64__
1251 typedef Registers_SPARC64 NativeUnwindRegisters;
1252 #elif __sparc__
1253 typedef Registers_SPARC NativeUnwindRegisters;
1254 #elif __alpha__
1255 typedef Registers_Alpha NativeUnwindRegisters;
1256 #elif __hppa__
1257 typedef Registers_HPPA NativeUnwindRegisters;
1258 #elif __or1k__
1259 typedef Registers_or1k NativeUnwindRegisters;
1260 #endif
1261 } // namespace _Unwind
1262
1263 #endif // __REGISTERS_HPP__
1264