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