1 //===----------------------------- Registers.hpp --------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 // Models register sets for supported processors.
10 //===----------------------------------------------------------------------===//
12 #ifndef __REGISTERS_HPP__
13 #define __REGISTERS_HPP__
18 #include "libunwind.h"
23 // For emulating 128-bit registers
24 struct v128 { uint32_t vec[4]; };
35 REGISTERS_MIPS_NEWABI,
40 #if defined(_LIBUNWIND_TARGET_I386)
41 /// Registers_x86 holds the register state of a thread in a 32-bit intel
43 class _LIBUNWIND_HIDDEN Registers_x86 {
46 Registers_x86(const void *registers);
48 bool validRegister(int num) const;
49 uint32_t getRegister(int num) const;
50 void setRegister(int num, uint32_t value);
51 bool validFloatRegister(int) const { return false; }
52 double getFloatRegister(int num) const;
53 void setFloatRegister(int num, double value);
54 bool validVectorRegister(int) const { return false; }
55 v128 getVectorRegister(int num) const;
56 void setVectorRegister(int num, v128 value);
57 static const char *getRegisterName(int num);
59 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
60 static int getArch() { return REGISTERS_X86; }
62 uint32_t getSP() const { return _registers.__esp; }
63 void setSP(uint32_t value) { _registers.__esp = value; }
64 uint32_t getIP() const { return _registers.__eip; }
65 void setIP(uint32_t value) { _registers.__eip = value; }
66 uint32_t getEBP() const { return _registers.__ebp; }
67 void setEBP(uint32_t value) { _registers.__ebp = value; }
68 uint32_t getEBX() const { return _registers.__ebx; }
69 void setEBX(uint32_t value) { _registers.__ebx = value; }
70 uint32_t getECX() const { return _registers.__ecx; }
71 void setECX(uint32_t value) { _registers.__ecx = value; }
72 uint32_t getEDX() const { return _registers.__edx; }
73 void setEDX(uint32_t value) { _registers.__edx = value; }
74 uint32_t getESI() const { return _registers.__esi; }
75 void setESI(uint32_t value) { _registers.__esi = value; }
76 uint32_t getEDI() const { return _registers.__edi; }
77 void setEDI(uint32_t value) { _registers.__edi = value; }
90 unsigned int __eflags;
102 inline Registers_x86::Registers_x86(const void *registers) {
103 static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
104 "x86 registers do not fit into unw_context_t");
105 memcpy(&_registers, registers, sizeof(_registers));
108 inline Registers_x86::Registers_x86() {
109 memset(&_registers, 0, sizeof(_registers));
112 inline bool Registers_x86::validRegister(int regNum) const {
113 if (regNum == UNW_REG_IP)
115 if (regNum == UNW_REG_SP)
124 inline uint32_t Registers_x86::getRegister(int regNum) const {
127 return _registers.__eip;
129 return _registers.__esp;
131 return _registers.__eax;
133 return _registers.__ecx;
135 return _registers.__edx;
137 return _registers.__ebx;
138 #if !defined(__APPLE__)
143 return _registers.__ebp;
144 #if !defined(__APPLE__)
149 return _registers.__esp;
151 return _registers.__esi;
153 return _registers.__edi;
155 _LIBUNWIND_ABORT("unsupported x86 register");
158 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
161 _registers.__eip = value;
164 _registers.__esp = value;
167 _registers.__eax = value;
170 _registers.__ecx = value;
173 _registers.__edx = value;
176 _registers.__ebx = value;
178 #if !defined(__APPLE__)
183 _registers.__ebp = value;
185 #if !defined(__APPLE__)
190 _registers.__esp = value;
193 _registers.__esi = value;
196 _registers.__edi = value;
199 _LIBUNWIND_ABORT("unsupported x86 register");
202 inline const char *Registers_x86::getRegisterName(int regNum) {
225 return "unknown register";
229 inline double Registers_x86::getFloatRegister(int) const {
230 _LIBUNWIND_ABORT("no x86 float registers");
233 inline void Registers_x86::setFloatRegister(int, double) {
234 _LIBUNWIND_ABORT("no x86 float registers");
237 inline v128 Registers_x86::getVectorRegister(int) const {
238 _LIBUNWIND_ABORT("no x86 vector registers");
241 inline void Registers_x86::setVectorRegister(int, v128) {
242 _LIBUNWIND_ABORT("no x86 vector registers");
244 #endif // _LIBUNWIND_TARGET_I386
247 #if defined(_LIBUNWIND_TARGET_X86_64)
248 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel
250 class _LIBUNWIND_HIDDEN Registers_x86_64 {
253 Registers_x86_64(const void *registers);
255 bool validRegister(int num) const;
256 uint64_t getRegister(int num) const;
257 void setRegister(int num, uint64_t value);
258 bool validFloatRegister(int) const { return false; }
259 double getFloatRegister(int num) const;
260 void setFloatRegister(int num, double value);
261 bool validVectorRegister(int) const;
262 v128 getVectorRegister(int num) const;
263 void setVectorRegister(int num, v128 value);
264 static const char *getRegisterName(int num);
266 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
267 static int getArch() { return REGISTERS_X86_64; }
269 uint64_t getSP() const { return _registers.__rsp; }
270 void setSP(uint64_t value) { _registers.__rsp = value; }
271 uint64_t getIP() const { return _registers.__rip; }
272 void setIP(uint64_t value) { _registers.__rip = value; }
273 uint64_t getRBP() const { return _registers.__rbp; }
274 void setRBP(uint64_t value) { _registers.__rbp = value; }
275 uint64_t getRBX() const { return _registers.__rbx; }
276 void setRBX(uint64_t value) { _registers.__rbx = value; }
277 uint64_t getR12() const { return _registers.__r12; }
278 void setR12(uint64_t value) { _registers.__r12 = value; }
279 uint64_t getR13() const { return _registers.__r13; }
280 void setR13(uint64_t value) { _registers.__r13 = value; }
281 uint64_t getR14() const { return _registers.__r14; }
282 void setR14(uint64_t value) { _registers.__r14 = value; }
283 uint64_t getR15() const { return _registers.__r15; }
284 void setR15(uint64_t value) { _registers.__r15 = value; }
310 uint64_t __padding; // 16-byte align
319 inline Registers_x86_64::Registers_x86_64(const void *registers) {
320 static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
321 "x86_64 registers do not fit into unw_context_t");
322 memcpy(&_registers, registers, sizeof(_registers));
325 inline Registers_x86_64::Registers_x86_64() {
326 memset(&_registers, 0, sizeof(_registers));
329 inline bool Registers_x86_64::validRegister(int regNum) const {
330 if (regNum == UNW_REG_IP)
332 if (regNum == UNW_REG_SP)
341 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
344 return _registers.__rip;
346 return _registers.__rsp;
348 return _registers.__rax;
350 return _registers.__rdx;
352 return _registers.__rcx;
354 return _registers.__rbx;
356 return _registers.__rsi;
358 return _registers.__rdi;
360 return _registers.__rbp;
362 return _registers.__rsp;
364 return _registers.__r8;
366 return _registers.__r9;
368 return _registers.__r10;
370 return _registers.__r11;
372 return _registers.__r12;
374 return _registers.__r13;
376 return _registers.__r14;
378 return _registers.__r15;
380 _LIBUNWIND_ABORT("unsupported x86_64 register");
383 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
386 _registers.__rip = value;
389 _registers.__rsp = value;
392 _registers.__rax = value;
395 _registers.__rdx = value;
398 _registers.__rcx = value;
401 _registers.__rbx = value;
404 _registers.__rsi = value;
407 _registers.__rdi = value;
410 _registers.__rbp = value;
413 _registers.__rsp = value;
416 _registers.__r8 = value;
419 _registers.__r9 = value;
422 _registers.__r10 = value;
425 _registers.__r11 = value;
428 _registers.__r12 = value;
431 _registers.__r13 = value;
434 _registers.__r14 = value;
437 _registers.__r15 = value;
440 _LIBUNWIND_ABORT("unsupported x86_64 register");
443 inline const char *Registers_x86_64::getRegisterName(int regNum) {
481 case UNW_X86_64_XMM0:
483 case UNW_X86_64_XMM1:
485 case UNW_X86_64_XMM2:
487 case UNW_X86_64_XMM3:
489 case UNW_X86_64_XMM4:
491 case UNW_X86_64_XMM5:
493 case UNW_X86_64_XMM6:
495 case UNW_X86_64_XMM7:
497 case UNW_X86_64_XMM8:
499 case UNW_X86_64_XMM9:
501 case UNW_X86_64_XMM10:
503 case UNW_X86_64_XMM11:
505 case UNW_X86_64_XMM12:
507 case UNW_X86_64_XMM13:
509 case UNW_X86_64_XMM14:
511 case UNW_X86_64_XMM15:
514 return "unknown register";
518 inline double Registers_x86_64::getFloatRegister(int) const {
519 _LIBUNWIND_ABORT("no x86_64 float registers");
522 inline void Registers_x86_64::setFloatRegister(int, double) {
523 _LIBUNWIND_ABORT("no x86_64 float registers");
526 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
528 if (regNum < UNW_X86_64_XMM0)
530 if (regNum > UNW_X86_64_XMM15)
534 (void)regNum; // suppress unused parameter warning
539 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
541 assert(validVectorRegister(regNum));
542 return _xmm[regNum - UNW_X86_64_XMM0];
544 (void)regNum; // suppress unused parameter warning
545 _LIBUNWIND_ABORT("no x86_64 vector registers");
549 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
551 assert(validVectorRegister(regNum));
552 _xmm[regNum - UNW_X86_64_XMM0] = value;
554 (void)regNum; (void)value; // suppress unused parameter warnings
555 _LIBUNWIND_ABORT("no x86_64 vector registers");
558 #endif // _LIBUNWIND_TARGET_X86_64
561 #if defined(_LIBUNWIND_TARGET_PPC)
562 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
564 class _LIBUNWIND_HIDDEN Registers_ppc {
567 Registers_ppc(const void *registers);
569 bool validRegister(int num) const;
570 uint32_t getRegister(int num) const;
571 void setRegister(int num, uint32_t value);
572 bool validFloatRegister(int num) const;
573 double getFloatRegister(int num) const;
574 void setFloatRegister(int num, double value);
575 bool validVectorRegister(int num) const;
576 v128 getVectorRegister(int num) const;
577 void setVectorRegister(int num, v128 value);
578 static const char *getRegisterName(int num);
580 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
581 static int getArch() { return REGISTERS_PPC; }
583 uint64_t getSP() const { return _registers.__r1; }
584 void setSP(uint32_t value) { _registers.__r1 = value; }
585 uint64_t getIP() const { return _registers.__srr0; }
586 void setIP(uint32_t value) { _registers.__srr0 = value; }
589 struct ppc_thread_state_t {
590 unsigned int __srr0; /* Instruction address register (PC) */
591 unsigned int __srr1; /* Machine state register (supervisor) */
624 unsigned int __cr; /* Condition register */
625 unsigned int __xer; /* User's integer exception register */
626 unsigned int __lr; /* Link register */
627 unsigned int __ctr; /* Count register */
628 unsigned int __mq; /* MQ register (601 only) */
629 unsigned int __vrsave; /* Vector Save Register */
632 struct ppc_float_state_t {
635 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
636 unsigned int __fpscr; /* floating point status register */
639 ppc_thread_state_t _registers;
640 ppc_float_state_t _floatRegisters;
641 v128 _vectorRegisters[32]; // offset 424
644 inline Registers_ppc::Registers_ppc(const void *registers) {
645 static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
646 "ppc registers do not fit into unw_context_t");
647 memcpy(&_registers, static_cast<const uint8_t *>(registers),
649 static_assert(sizeof(ppc_thread_state_t) == 160,
650 "expected float register offset to be 160");
651 memcpy(&_floatRegisters,
652 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
653 sizeof(_floatRegisters));
654 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
655 "expected vector register offset to be 424 bytes");
656 memcpy(_vectorRegisters,
657 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
658 sizeof(ppc_float_state_t),
659 sizeof(_vectorRegisters));
662 inline Registers_ppc::Registers_ppc() {
663 memset(&_registers, 0, sizeof(_registers));
664 memset(&_floatRegisters, 0, sizeof(_floatRegisters));
665 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
668 inline bool Registers_ppc::validRegister(int regNum) const {
669 if (regNum == UNW_REG_IP)
671 if (regNum == UNW_REG_SP)
673 if (regNum == UNW_PPC_VRSAVE)
677 if (regNum <= UNW_PPC_R31)
679 if (regNum == UNW_PPC_MQ)
681 if (regNum == UNW_PPC_LR)
683 if (regNum == UNW_PPC_CTR)
685 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
690 inline uint32_t Registers_ppc::getRegister(int regNum) const {
693 return _registers.__srr0;
695 return _registers.__r1;
697 return _registers.__r0;
699 return _registers.__r1;
701 return _registers.__r2;
703 return _registers.__r3;
705 return _registers.__r4;
707 return _registers.__r5;
709 return _registers.__r6;
711 return _registers.__r7;
713 return _registers.__r8;
715 return _registers.__r9;
717 return _registers.__r10;
719 return _registers.__r11;
721 return _registers.__r12;
723 return _registers.__r13;
725 return _registers.__r14;
727 return _registers.__r15;
729 return _registers.__r16;
731 return _registers.__r17;
733 return _registers.__r18;
735 return _registers.__r19;
737 return _registers.__r20;
739 return _registers.__r21;
741 return _registers.__r22;
743 return _registers.__r23;
745 return _registers.__r24;
747 return _registers.__r25;
749 return _registers.__r26;
751 return _registers.__r27;
753 return _registers.__r28;
755 return _registers.__r29;
757 return _registers.__r30;
759 return _registers.__r31;
761 return _registers.__lr;
763 return (_registers.__cr & 0xF0000000);
765 return (_registers.__cr & 0x0F000000);
767 return (_registers.__cr & 0x00F00000);
769 return (_registers.__cr & 0x000F0000);
771 return (_registers.__cr & 0x0000F000);
773 return (_registers.__cr & 0x00000F00);
775 return (_registers.__cr & 0x000000F0);
777 return (_registers.__cr & 0x0000000F);
779 return _registers.__vrsave;
781 _LIBUNWIND_ABORT("unsupported ppc register");
784 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
785 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
788 _registers.__srr0 = value;
791 _registers.__r1 = value;
794 _registers.__r0 = value;
797 _registers.__r1 = value;
800 _registers.__r2 = value;
803 _registers.__r3 = value;
806 _registers.__r4 = value;
809 _registers.__r5 = value;
812 _registers.__r6 = value;
815 _registers.__r7 = value;
818 _registers.__r8 = value;
821 _registers.__r9 = value;
824 _registers.__r10 = value;
827 _registers.__r11 = value;
830 _registers.__r12 = value;
833 _registers.__r13 = value;
836 _registers.__r14 = value;
839 _registers.__r15 = value;
842 _registers.__r16 = value;
845 _registers.__r17 = value;
848 _registers.__r18 = value;
851 _registers.__r19 = value;
854 _registers.__r20 = value;
857 _registers.__r21 = value;
860 _registers.__r22 = value;
863 _registers.__r23 = value;
866 _registers.__r24 = value;
869 _registers.__r25 = value;
872 _registers.__r26 = value;
875 _registers.__r27 = value;
878 _registers.__r28 = value;
881 _registers.__r29 = value;
884 _registers.__r30 = value;
887 _registers.__r31 = value;
890 _registers.__mq = value;
893 _registers.__lr = value;
896 _registers.__ctr = value;
899 _registers.__cr &= 0x0FFFFFFF;
900 _registers.__cr |= (value & 0xF0000000);
903 _registers.__cr &= 0xF0FFFFFF;
904 _registers.__cr |= (value & 0x0F000000);
907 _registers.__cr &= 0xFF0FFFFF;
908 _registers.__cr |= (value & 0x00F00000);
911 _registers.__cr &= 0xFFF0FFFF;
912 _registers.__cr |= (value & 0x000F0000);
915 _registers.__cr &= 0xFFFF0FFF;
916 _registers.__cr |= (value & 0x0000F000);
919 _registers.__cr &= 0xFFFFF0FF;
920 _registers.__cr |= (value & 0x00000F00);
923 _registers.__cr &= 0xFFFFFF0F;
924 _registers.__cr |= (value & 0x000000F0);
927 _registers.__cr &= 0xFFFFFFF0;
928 _registers.__cr |= (value & 0x0000000F);
931 _registers.__vrsave = value;
936 _registers.__xer = value;
940 case UNW_PPC_SPEFSCR:
944 _LIBUNWIND_ABORT("unsupported ppc register");
947 inline bool Registers_ppc::validFloatRegister(int regNum) const {
948 if (regNum < UNW_PPC_F0)
950 if (regNum > UNW_PPC_F31)
955 inline double Registers_ppc::getFloatRegister(int regNum) const {
956 assert(validFloatRegister(regNum));
957 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
960 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
961 assert(validFloatRegister(regNum));
962 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
965 inline bool Registers_ppc::validVectorRegister(int regNum) const {
966 if (regNum < UNW_PPC_V0)
968 if (regNum > UNW_PPC_V31)
973 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
974 assert(validVectorRegister(regNum));
975 v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
979 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
980 assert(validVectorRegister(regNum));
981 _vectorRegisters[regNum - UNW_PPC_V0] = value;
984 inline const char *Registers_ppc::getRegisterName(int regNum) {
1121 return "unknown register";
1125 #endif // _LIBUNWIND_TARGET_PPC
1127 #if defined(_LIBUNWIND_TARGET_PPC64)
1128 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1130 class _LIBUNWIND_HIDDEN Registers_ppc64 {
1133 Registers_ppc64(const void *registers);
1135 bool validRegister(int num) const;
1136 uint64_t getRegister(int num) const;
1137 void setRegister(int num, uint64_t value);
1138 bool validFloatRegister(int num) const;
1139 double getFloatRegister(int num) const;
1140 void setFloatRegister(int num, double value);
1141 bool validVectorRegister(int num) const;
1142 v128 getVectorRegister(int num) const;
1143 void setVectorRegister(int num, v128 value);
1144 static const char *getRegisterName(int num);
1146 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
1147 static int getArch() { return REGISTERS_PPC64; }
1149 uint64_t getSP() const { return _registers.__r1; }
1150 void setSP(uint64_t value) { _registers.__r1 = value; }
1151 uint64_t getIP() const { return _registers.__srr0; }
1152 void setIP(uint64_t value) { _registers.__srr0 = value; }
1155 struct ppc64_thread_state_t {
1156 uint64_t __srr0; // Instruction address register (PC)
1157 uint64_t __srr1; // Machine state register (supervisor)
1190 uint64_t __cr; // Condition register
1191 uint64_t __xer; // User's integer exception register
1192 uint64_t __lr; // Link register
1193 uint64_t __ctr; // Count register
1194 uint64_t __vrsave; // Vector Save Register
1205 ppc64_thread_state_t _registers;
1206 ppc64_vsr_t _vectorScalarRegisters[64];
1208 static int getVectorRegNum(int num);
1211 inline Registers_ppc64::Registers_ppc64(const void *registers) {
1212 static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1213 "ppc64 registers do not fit into unw_context_t");
1214 memcpy(&_registers, static_cast<const uint8_t *>(registers),
1215 sizeof(_registers));
1216 static_assert(sizeof(_registers) == 312,
1217 "expected vector scalar register offset to be 312");
1218 memcpy(&_vectorScalarRegisters,
1219 static_cast<const uint8_t *>(registers) + sizeof(_registers),
1220 sizeof(_vectorScalarRegisters));
1221 static_assert(sizeof(_registers) +
1222 sizeof(_vectorScalarRegisters) == 1336,
1223 "expected vector register offset to be 1336 bytes");
1226 inline Registers_ppc64::Registers_ppc64() {
1227 memset(&_registers, 0, sizeof(_registers));
1228 memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1231 inline bool Registers_ppc64::validRegister(int regNum) const {
1238 case UNW_PPC64_VRSAVE:
1242 if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1244 if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1250 inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1253 return _registers.__srr0;
1255 return _registers.__r0;
1258 return _registers.__r1;
1260 return _registers.__r2;
1262 return _registers.__r3;
1264 return _registers.__r4;
1266 return _registers.__r5;
1268 return _registers.__r6;
1270 return _registers.__r7;
1272 return _registers.__r8;
1274 return _registers.__r9;
1276 return _registers.__r10;
1278 return _registers.__r11;
1280 return _registers.__r12;
1282 return _registers.__r13;
1284 return _registers.__r14;
1286 return _registers.__r15;
1288 return _registers.__r16;
1290 return _registers.__r17;
1292 return _registers.__r18;
1294 return _registers.__r19;
1296 return _registers.__r20;
1298 return _registers.__r21;
1300 return _registers.__r22;
1302 return _registers.__r23;
1304 return _registers.__r24;
1306 return _registers.__r25;
1308 return _registers.__r26;
1310 return _registers.__r27;
1312 return _registers.__r28;
1314 return _registers.__r29;
1316 return _registers.__r30;
1318 return _registers.__r31;
1320 return (_registers.__cr & 0xF0000000);
1322 return (_registers.__cr & 0x0F000000);
1324 return (_registers.__cr & 0x00F00000);
1326 return (_registers.__cr & 0x000F0000);
1328 return (_registers.__cr & 0x0000F000);
1330 return (_registers.__cr & 0x00000F00);
1332 return (_registers.__cr & 0x000000F0);
1334 return (_registers.__cr & 0x0000000F);
1336 return _registers.__xer;
1338 return _registers.__lr;
1340 return _registers.__ctr;
1341 case UNW_PPC64_VRSAVE:
1342 return _registers.__vrsave;
1344 _LIBUNWIND_ABORT("unsupported ppc64 register");
1347 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1350 _registers.__srr0 = value;
1353 _registers.__r0 = value;
1357 _registers.__r1 = value;
1360 _registers.__r2 = value;
1363 _registers.__r3 = value;
1366 _registers.__r4 = value;
1369 _registers.__r5 = value;
1372 _registers.__r6 = value;
1375 _registers.__r7 = value;
1378 _registers.__r8 = value;
1381 _registers.__r9 = value;
1384 _registers.__r10 = value;
1387 _registers.__r11 = value;
1390 _registers.__r12 = value;
1393 _registers.__r13 = value;
1396 _registers.__r14 = value;
1399 _registers.__r15 = value;
1402 _registers.__r16 = value;
1405 _registers.__r17 = value;
1408 _registers.__r18 = value;
1411 _registers.__r19 = value;
1414 _registers.__r20 = value;
1417 _registers.__r21 = value;
1420 _registers.__r22 = value;
1423 _registers.__r23 = value;
1426 _registers.__r24 = value;
1429 _registers.__r25 = value;
1432 _registers.__r26 = value;
1435 _registers.__r27 = value;
1438 _registers.__r28 = value;
1441 _registers.__r29 = value;
1444 _registers.__r30 = value;
1447 _registers.__r31 = value;
1450 _registers.__cr &= 0x0FFFFFFF;
1451 _registers.__cr |= (value & 0xF0000000);
1454 _registers.__cr &= 0xF0FFFFFF;
1455 _registers.__cr |= (value & 0x0F000000);
1458 _registers.__cr &= 0xFF0FFFFF;
1459 _registers.__cr |= (value & 0x00F00000);
1462 _registers.__cr &= 0xFFF0FFFF;
1463 _registers.__cr |= (value & 0x000F0000);
1466 _registers.__cr &= 0xFFFF0FFF;
1467 _registers.__cr |= (value & 0x0000F000);
1470 _registers.__cr &= 0xFFFFF0FF;
1471 _registers.__cr |= (value & 0x00000F00);
1474 _registers.__cr &= 0xFFFFFF0F;
1475 _registers.__cr |= (value & 0x000000F0);
1478 _registers.__cr &= 0xFFFFFFF0;
1479 _registers.__cr |= (value & 0x0000000F);
1482 _registers.__xer = value;
1485 _registers.__lr = value;
1488 _registers.__ctr = value;
1490 case UNW_PPC64_VRSAVE:
1491 _registers.__vrsave = value;
1494 _LIBUNWIND_ABORT("unsupported ppc64 register");
1497 inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1498 return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1501 inline double Registers_ppc64::getFloatRegister(int regNum) const {
1502 assert(validFloatRegister(regNum));
1503 return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1506 inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1507 assert(validFloatRegister(regNum));
1508 _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1511 inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1512 #ifdef PPC64_HAS_VMX
1513 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1515 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1518 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1524 inline int Registers_ppc64::getVectorRegNum(int num)
1526 if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1527 return num - UNW_PPC64_VS0;
1529 return num - UNW_PPC64_VS32 + 32;
1532 inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1533 assert(validVectorRegister(regNum));
1534 return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1537 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1538 assert(validVectorRegister(regNum));
1539 _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1542 inline const char *Registers_ppc64::getRegisterName(int regNum) {
1634 case UNW_PPC64_VRSAVE:
1765 return "unknown register";
1767 #endif // _LIBUNWIND_TARGET_PPC64
1770 #if defined(_LIBUNWIND_TARGET_AARCH64)
1771 /// Registers_arm64 holds the register state of a thread in a 64-bit arm
1773 class _LIBUNWIND_HIDDEN Registers_arm64 {
1776 Registers_arm64(const void *registers);
1778 bool validRegister(int num) const;
1779 uint64_t getRegister(int num) const;
1780 void setRegister(int num, uint64_t value);
1781 bool validFloatRegister(int num) const;
1782 double getFloatRegister(int num) const;
1783 void setFloatRegister(int num, double value);
1784 bool validVectorRegister(int num) const;
1785 v128 getVectorRegister(int num) const;
1786 void setVectorRegister(int num, v128 value);
1787 static const char *getRegisterName(int num);
1789 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
1790 static int getArch() { return REGISTERS_ARM64; }
1792 uint64_t getSP() const { return _registers.__sp; }
1793 void setSP(uint64_t value) { _registers.__sp = value; }
1794 uint64_t getIP() const { return _registers.__pc; }
1795 void setIP(uint64_t value) { _registers.__pc = value; }
1796 uint64_t getFP() const { return _registers.__fp; }
1797 void setFP(uint64_t value) { _registers.__fp = value; }
1801 uint64_t __x[29]; // x0-x28
1802 uint64_t __fp; // Frame pointer x29
1803 uint64_t __lr; // Link register x30
1804 uint64_t __sp; // Stack pointer x31
1805 uint64_t __pc; // Program counter
1806 uint64_t __ra_sign_state; // RA sign state register
1810 double _vectorHalfRegisters[32];
1811 // Currently only the lower double in 128-bit vectore registers
1812 // is perserved during unwinding. We could define new register
1813 // numbers (> 96) which mean whole vector registers, then this
1814 // struct would need to change to contain whole vector registers.
1817 inline Registers_arm64::Registers_arm64(const void *registers) {
1818 static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1819 "arm64 registers do not fit into unw_context_t");
1820 memcpy(&_registers, registers, sizeof(_registers));
1821 static_assert(sizeof(GPRs) == 0x110,
1822 "expected VFP registers to be at offset 272");
1823 memcpy(_vectorHalfRegisters,
1824 static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1825 sizeof(_vectorHalfRegisters));
1828 inline Registers_arm64::Registers_arm64() {
1829 memset(&_registers, 0, sizeof(_registers));
1830 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1833 inline bool Registers_arm64::validRegister(int regNum) const {
1834 if (regNum == UNW_REG_IP)
1836 if (regNum == UNW_REG_SP)
1842 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1844 if ((regNum > 31) && (regNum < 64))
1849 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1850 if (regNum == UNW_REG_IP)
1851 return _registers.__pc;
1852 if (regNum == UNW_REG_SP)
1853 return _registers.__sp;
1854 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1855 return _registers.__ra_sign_state;
1856 if ((regNum >= 0) && (regNum < 32))
1857 return _registers.__x[regNum];
1858 _LIBUNWIND_ABORT("unsupported arm64 register");
1861 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1862 if (regNum == UNW_REG_IP)
1863 _registers.__pc = value;
1864 else if (regNum == UNW_REG_SP)
1865 _registers.__sp = value;
1866 else if (regNum == UNW_ARM64_RA_SIGN_STATE)
1867 _registers.__ra_sign_state = value;
1868 else if ((regNum >= 0) && (regNum < 32))
1869 _registers.__x[regNum] = value;
1871 _LIBUNWIND_ABORT("unsupported arm64 register");
1874 inline const char *Registers_arm64::getRegisterName(int regNum) {
2009 return "unknown register";
2013 inline bool Registers_arm64::validFloatRegister(int regNum) const {
2014 if (regNum < UNW_ARM64_D0)
2016 if (regNum > UNW_ARM64_D31)
2021 inline double Registers_arm64::getFloatRegister(int regNum) const {
2022 assert(validFloatRegister(regNum));
2023 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2026 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2027 assert(validFloatRegister(regNum));
2028 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2031 inline bool Registers_arm64::validVectorRegister(int) const {
2035 inline v128 Registers_arm64::getVectorRegister(int) const {
2036 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2039 inline void Registers_arm64::setVectorRegister(int, v128) {
2040 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2042 #endif // _LIBUNWIND_TARGET_AARCH64
2044 #if defined(_LIBUNWIND_TARGET_ARM)
2045 /// Registers_arm holds the register state of a thread in a 32-bit arm
2048 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2049 /// this uses more memory than required.
2050 class _LIBUNWIND_HIDDEN Registers_arm {
2053 Registers_arm(const void *registers);
2055 bool validRegister(int num) const;
2056 uint32_t getRegister(int num) const;
2057 void setRegister(int num, uint32_t value);
2058 bool validFloatRegister(int num) const;
2059 unw_fpreg_t getFloatRegister(int num);
2060 void setFloatRegister(int num, unw_fpreg_t value);
2061 bool validVectorRegister(int num) const;
2062 v128 getVectorRegister(int num) const;
2063 void setVectorRegister(int num, v128 value);
2064 static const char *getRegisterName(int num);
2066 restoreSavedFloatRegisters();
2067 restoreCoreAndJumpTo();
2069 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
2070 static int getArch() { return REGISTERS_ARM; }
2072 uint32_t getSP() const { return _registers.__sp; }
2073 void setSP(uint32_t value) { _registers.__sp = value; }
2074 uint32_t getIP() const { return _registers.__pc; }
2075 void setIP(uint32_t value) { _registers.__pc = value; }
2078 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2079 _use_X_for_vfp_save = true;
2082 void restoreSavedFloatRegisters() {
2083 if (_saved_vfp_d0_d15) {
2084 if (_use_X_for_vfp_save)
2085 restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2087 restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2089 if (_saved_vfp_d16_d31)
2090 restoreVFPv3(_vfp_d16_d31);
2091 #if defined(__ARM_WMMX)
2093 restoreiWMMX(_iwmmx);
2094 if (_saved_iwmmx_control)
2095 restoreiWMMXControl(_iwmmx_control);
2101 uint32_t __r[13]; // r0-r12
2102 uint32_t __sp; // Stack pointer r13
2103 uint32_t __lr; // Link register r14
2104 uint32_t __pc; // Program counter r15
2107 static void saveVFPWithFSTMD(void*);
2108 static void saveVFPWithFSTMX(void*);
2109 static void saveVFPv3(void*);
2110 static void restoreVFPWithFLDMD(void*);
2111 static void restoreVFPWithFLDMX(void*);
2112 static void restoreVFPv3(void*);
2113 #if defined(__ARM_WMMX)
2114 static void saveiWMMX(void*);
2115 static void saveiWMMXControl(uint32_t*);
2116 static void restoreiWMMX(void*);
2117 static void restoreiWMMXControl(uint32_t*);
2119 void restoreCoreAndJumpTo();
2124 // We save floating point registers lazily because we can't know ahead of
2125 // time which ones are used. See EHABI #4.7.
2127 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2129 // See EHABI #7.5 that explains how matching instruction sequences for load
2130 // and store need to be used to correctly restore the exact register bits.
2131 bool _use_X_for_vfp_save;
2132 // Whether VFP D0-D15 are saved.
2133 bool _saved_vfp_d0_d15;
2134 // Whether VFPv3 D16-D31 are saved.
2135 bool _saved_vfp_d16_d31;
2136 // VFP registers D0-D15, + padding if saved using FSTMX
2137 unw_fpreg_t _vfp_d0_d15_pad[17];
2138 // VFPv3 registers D16-D31, always saved using FSTMD
2139 unw_fpreg_t _vfp_d16_d31[16];
2140 #if defined(__ARM_WMMX)
2141 // Whether iWMMX data registers are saved.
2143 // Whether iWMMX control registers are saved.
2144 mutable bool _saved_iwmmx_control;
2146 unw_fpreg_t _iwmmx[16];
2147 // iWMMX control registers
2148 mutable uint32_t _iwmmx_control[4];
2152 inline Registers_arm::Registers_arm(const void *registers)
2153 : _use_X_for_vfp_save(false),
2154 _saved_vfp_d0_d15(false),
2155 _saved_vfp_d16_d31(false) {
2156 static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2157 "arm registers do not fit into unw_context_t");
2158 // See __unw_getcontext() note about data.
2159 memcpy(&_registers, registers, sizeof(_registers));
2160 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2161 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2162 #if defined(__ARM_WMMX)
2163 _saved_iwmmx = false;
2164 _saved_iwmmx_control = false;
2165 memset(&_iwmmx, 0, sizeof(_iwmmx));
2166 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2170 inline Registers_arm::Registers_arm()
2171 : _use_X_for_vfp_save(false),
2172 _saved_vfp_d0_d15(false),
2173 _saved_vfp_d16_d31(false) {
2174 memset(&_registers, 0, sizeof(_registers));
2175 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2176 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2177 #if defined(__ARM_WMMX)
2178 _saved_iwmmx = false;
2179 _saved_iwmmx_control = false;
2180 memset(&_iwmmx, 0, sizeof(_iwmmx));
2181 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2185 inline bool Registers_arm::validRegister(int regNum) const {
2186 // Returns true for all non-VFP registers supported by the EHABI
2187 // virtual register set (VRS).
2188 if (regNum == UNW_REG_IP)
2191 if (regNum == UNW_REG_SP)
2194 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2197 #if defined(__ARM_WMMX)
2198 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2205 inline uint32_t Registers_arm::getRegister(int regNum) const {
2206 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2207 return _registers.__sp;
2209 if (regNum == UNW_ARM_LR)
2210 return _registers.__lr;
2212 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2213 return _registers.__pc;
2215 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2216 return _registers.__r[regNum];
2218 #if defined(__ARM_WMMX)
2219 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2220 if (!_saved_iwmmx_control) {
2221 _saved_iwmmx_control = true;
2222 saveiWMMXControl(_iwmmx_control);
2224 return _iwmmx_control[regNum - UNW_ARM_WC0];
2228 _LIBUNWIND_ABORT("unsupported arm register");
2231 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2232 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2233 _registers.__sp = value;
2237 if (regNum == UNW_ARM_LR) {
2238 _registers.__lr = value;
2242 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2243 _registers.__pc = value;
2247 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2248 _registers.__r[regNum] = value;
2252 #if defined(__ARM_WMMX)
2253 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2254 if (!_saved_iwmmx_control) {
2255 _saved_iwmmx_control = true;
2256 saveiWMMXControl(_iwmmx_control);
2258 _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2263 _LIBUNWIND_ABORT("unsupported arm register");
2266 inline const char *Registers_arm::getRegisterName(int regNum) {
2269 case UNW_ARM_IP: // UNW_ARM_R15 is alias
2271 case UNW_ARM_LR: // UNW_ARM_R14 is alias
2274 case UNW_ARM_SP: // UNW_ARM_R13 is alias
2431 return "unknown register";
2435 inline bool Registers_arm::validFloatRegister(int regNum) const {
2436 // NOTE: Consider the intel MMX registers floating points so the
2437 // __unw_get_fpreg can be used to transmit the 64-bit data back.
2438 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2439 #if defined(__ARM_WMMX)
2440 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2445 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2446 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2447 if (!_saved_vfp_d0_d15) {
2448 _saved_vfp_d0_d15 = true;
2449 if (_use_X_for_vfp_save)
2450 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2452 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2454 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2457 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2458 if (!_saved_vfp_d16_d31) {
2459 _saved_vfp_d16_d31 = true;
2460 saveVFPv3(_vfp_d16_d31);
2462 return _vfp_d16_d31[regNum - UNW_ARM_D16];
2465 #if defined(__ARM_WMMX)
2466 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2467 if (!_saved_iwmmx) {
2468 _saved_iwmmx = true;
2471 return _iwmmx[regNum - UNW_ARM_WR0];
2475 _LIBUNWIND_ABORT("Unknown ARM float register");
2478 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2479 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2480 if (!_saved_vfp_d0_d15) {
2481 _saved_vfp_d0_d15 = true;
2482 if (_use_X_for_vfp_save)
2483 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2485 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2487 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2491 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2492 if (!_saved_vfp_d16_d31) {
2493 _saved_vfp_d16_d31 = true;
2494 saveVFPv3(_vfp_d16_d31);
2496 _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2500 #if defined(__ARM_WMMX)
2501 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2502 if (!_saved_iwmmx) {
2503 _saved_iwmmx = true;
2506 _iwmmx[regNum - UNW_ARM_WR0] = value;
2511 _LIBUNWIND_ABORT("Unknown ARM float register");
2514 inline bool Registers_arm::validVectorRegister(int) const {
2518 inline v128 Registers_arm::getVectorRegister(int) const {
2519 _LIBUNWIND_ABORT("ARM vector support not implemented");
2522 inline void Registers_arm::setVectorRegister(int, v128) {
2523 _LIBUNWIND_ABORT("ARM vector support not implemented");
2525 #endif // _LIBUNWIND_TARGET_ARM
2528 #if defined(_LIBUNWIND_TARGET_OR1K)
2529 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2531 class _LIBUNWIND_HIDDEN Registers_or1k {
2534 Registers_or1k(const void *registers);
2536 bool validRegister(int num) const;
2537 uint32_t getRegister(int num) const;
2538 void setRegister(int num, uint32_t value);
2539 bool validFloatRegister(int num) const;
2540 double getFloatRegister(int num) const;
2541 void setFloatRegister(int num, double value);
2542 bool validVectorRegister(int num) const;
2543 v128 getVectorRegister(int num) const;
2544 void setVectorRegister(int num, v128 value);
2545 static const char *getRegisterName(int num);
2547 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
2548 static int getArch() { return REGISTERS_OR1K; }
2550 uint64_t getSP() const { return _registers.__r[1]; }
2551 void setSP(uint32_t value) { _registers.__r[1] = value; }
2552 uint64_t getIP() const { return _registers.__pc; }
2553 void setIP(uint32_t value) { _registers.__pc = value; }
2556 struct or1k_thread_state_t {
2557 unsigned int __r[32]; // r0-r31
2558 unsigned int __pc; // Program counter
2559 unsigned int __epcr; // Program counter at exception
2562 or1k_thread_state_t _registers;
2565 inline Registers_or1k::Registers_or1k(const void *registers) {
2566 static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2567 "or1k registers do not fit into unw_context_t");
2568 memcpy(&_registers, static_cast<const uint8_t *>(registers),
2569 sizeof(_registers));
2572 inline Registers_or1k::Registers_or1k() {
2573 memset(&_registers, 0, sizeof(_registers));
2576 inline bool Registers_or1k::validRegister(int regNum) const {
2577 if (regNum == UNW_REG_IP)
2579 if (regNum == UNW_REG_SP)
2583 if (regNum <= UNW_OR1K_R31)
2585 if (regNum == UNW_OR1K_EPCR)
2590 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2591 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2592 return _registers.__r[regNum - UNW_OR1K_R0];
2596 return _registers.__pc;
2598 return _registers.__r[1];
2600 return _registers.__epcr;
2602 _LIBUNWIND_ABORT("unsupported or1k register");
2605 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2606 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2607 _registers.__r[regNum - UNW_OR1K_R0] = value;
2613 _registers.__pc = value;
2616 _registers.__r[1] = value;
2619 _registers.__epcr = value;
2622 _LIBUNWIND_ABORT("unsupported or1k register");
2625 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2629 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2630 _LIBUNWIND_ABORT("or1k float support not implemented");
2633 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2634 double /* value */) {
2635 _LIBUNWIND_ABORT("or1k float support not implemented");
2638 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2642 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2643 _LIBUNWIND_ABORT("or1k vector support not implemented");
2646 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2647 _LIBUNWIND_ABORT("or1k vector support not implemented");
2650 inline const char *Registers_or1k::getRegisterName(int regNum) {
2719 return "unknown register";
2723 #endif // _LIBUNWIND_TARGET_OR1K
2725 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2726 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2728 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2730 Registers_mips_o32();
2731 Registers_mips_o32(const void *registers);
2733 bool validRegister(int num) const;
2734 uint32_t getRegister(int num) const;
2735 void setRegister(int num, uint32_t value);
2736 bool validFloatRegister(int num) const;
2737 double getFloatRegister(int num) const;
2738 void setFloatRegister(int num, double value);
2739 bool validVectorRegister(int num) const;
2740 v128 getVectorRegister(int num) const;
2741 void setVectorRegister(int num, v128 value);
2742 static const char *getRegisterName(int num);
2744 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
2745 static int getArch() { return REGISTERS_MIPS_O32; }
2747 uint32_t getSP() const { return _registers.__r[29]; }
2748 void setSP(uint32_t value) { _registers.__r[29] = value; }
2749 uint32_t getIP() const { return _registers.__pc; }
2750 void setIP(uint32_t value) { _registers.__pc = value; }
2753 struct mips_o32_thread_state_t {
2760 mips_o32_thread_state_t _registers;
2761 #ifdef __mips_hard_float
2762 /// O32 with 32-bit floating point registers only uses half of this
2763 /// space. However, using the same layout for 32-bit vs 64-bit
2764 /// floating point registers results in a single context size for
2765 /// O32 with hard float.
2771 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
2772 static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
2773 "mips_o32 registers do not fit into unw_context_t");
2774 memcpy(&_registers, static_cast<const uint8_t *>(registers),
2775 sizeof(_registers));
2778 inline Registers_mips_o32::Registers_mips_o32() {
2779 memset(&_registers, 0, sizeof(_registers));
2782 inline bool Registers_mips_o32::validRegister(int regNum) const {
2783 if (regNum == UNW_REG_IP)
2785 if (regNum == UNW_REG_SP)
2789 if (regNum <= UNW_MIPS_R31)
2791 #if __mips_isa_rev != 6
2792 if (regNum == UNW_MIPS_HI)
2794 if (regNum == UNW_MIPS_LO)
2797 #if defined(__mips_hard_float) && __mips_fpr == 32
2798 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2801 // FIXME: DSP accumulator registers, MSA registers
2805 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
2806 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
2807 return _registers.__r[regNum - UNW_MIPS_R0];
2808 #if defined(__mips_hard_float) && __mips_fpr == 32
2809 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2812 if (regNum % 2 == 0)
2813 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2815 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2822 return _registers.__pc;
2824 return _registers.__r[29];
2826 return _registers.__hi;
2828 return _registers.__lo;
2830 _LIBUNWIND_ABORT("unsupported mips_o32 register");
2833 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
2834 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
2835 _registers.__r[regNum - UNW_MIPS_R0] = value;
2838 #if defined(__mips_hard_float) && __mips_fpr == 32
2839 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
2842 if (regNum % 2 == 0)
2843 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
2845 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
2853 _registers.__pc = value;
2856 _registers.__r[29] = value;
2859 _registers.__hi = value;
2862 _registers.__lo = value;
2865 _LIBUNWIND_ABORT("unsupported mips_o32 register");
2868 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
2869 #if defined(__mips_hard_float) && __mips_fpr == 64
2870 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
2876 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
2877 #if defined(__mips_hard_float) && __mips_fpr == 64
2878 assert(validFloatRegister(regNum));
2879 return _floats[regNum - UNW_MIPS_F0];
2881 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2885 inline void Registers_mips_o32::setFloatRegister(int regNum,
2887 #if defined(__mips_hard_float) && __mips_fpr == 64
2888 assert(validFloatRegister(regNum));
2889 _floats[regNum - UNW_MIPS_F0] = value;
2891 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
2895 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
2899 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
2900 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2903 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
2904 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
2907 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
3042 return "unknown register";
3045 #endif // _LIBUNWIND_TARGET_MIPS_O32
3047 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3048 /// Registers_mips_newabi holds the register state of a thread in a
3049 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3050 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3052 Registers_mips_newabi();
3053 Registers_mips_newabi(const void *registers);
3055 bool validRegister(int num) const;
3056 uint64_t getRegister(int num) const;
3057 void setRegister(int num, uint64_t value);
3058 bool validFloatRegister(int num) const;
3059 double getFloatRegister(int num) const;
3060 void setFloatRegister(int num, double value);
3061 bool validVectorRegister(int num) const;
3062 v128 getVectorRegister(int num) const;
3063 void setVectorRegister(int num, v128 value);
3064 static const char *getRegisterName(int num);
3066 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3067 static int getArch() { return REGISTERS_MIPS_NEWABI; }
3069 uint64_t getSP() const { return _registers.__r[29]; }
3070 void setSP(uint64_t value) { _registers.__r[29] = value; }
3071 uint64_t getIP() const { return _registers.__pc; }
3072 void setIP(uint64_t value) { _registers.__pc = value; }
3075 struct mips_newabi_thread_state_t {
3082 mips_newabi_thread_state_t _registers;
3083 #ifdef __mips_hard_float
3088 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3089 static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3090 "mips_newabi registers do not fit into unw_context_t");
3091 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3092 sizeof(_registers));
3095 inline Registers_mips_newabi::Registers_mips_newabi() {
3096 memset(&_registers, 0, sizeof(_registers));
3099 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3100 if (regNum == UNW_REG_IP)
3102 if (regNum == UNW_REG_SP)
3106 if (regNum <= UNW_MIPS_R31)
3108 #if __mips_isa_rev != 6
3109 if (regNum == UNW_MIPS_HI)
3111 if (regNum == UNW_MIPS_LO)
3114 // FIXME: Hard float, DSP accumulator registers, MSA registers
3118 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3119 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3120 return _registers.__r[regNum - UNW_MIPS_R0];
3124 return _registers.__pc;
3126 return _registers.__r[29];
3128 return _registers.__hi;
3130 return _registers.__lo;
3132 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3135 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3136 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3137 _registers.__r[regNum - UNW_MIPS_R0] = value;
3143 _registers.__pc = value;
3146 _registers.__r[29] = value;
3149 _registers.__hi = value;
3152 _registers.__lo = value;
3155 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3158 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3159 #ifdef __mips_hard_float
3160 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3166 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3167 #ifdef __mips_hard_float
3168 assert(validFloatRegister(regNum));
3169 return _floats[regNum - UNW_MIPS_F0];
3171 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3175 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3177 #ifdef __mips_hard_float
3178 assert(validFloatRegister(regNum));
3179 _floats[regNum - UNW_MIPS_F0] = value;
3181 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3185 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3189 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3190 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3193 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3194 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3197 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3332 return "unknown register";
3335 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3337 #if defined(_LIBUNWIND_TARGET_SPARC)
3338 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3340 class _LIBUNWIND_HIDDEN Registers_sparc {
3343 Registers_sparc(const void *registers);
3345 bool validRegister(int num) const;
3346 uint32_t getRegister(int num) const;
3347 void setRegister(int num, uint32_t value);
3348 bool validFloatRegister(int num) const;
3349 double getFloatRegister(int num) const;
3350 void setFloatRegister(int num, double value);
3351 bool validVectorRegister(int num) const;
3352 v128 getVectorRegister(int num) const;
3353 void setVectorRegister(int num, v128 value);
3354 static const char *getRegisterName(int num);
3356 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
3357 static int getArch() { return REGISTERS_SPARC; }
3359 uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; }
3360 void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
3361 uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
3362 void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3365 struct sparc_thread_state_t {
3366 unsigned int __regs[32];
3369 sparc_thread_state_t _registers;
3372 inline Registers_sparc::Registers_sparc(const void *registers) {
3373 static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3374 "sparc registers do not fit into unw_context_t");
3375 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3376 sizeof(_registers));
3379 inline Registers_sparc::Registers_sparc() {
3380 memset(&_registers, 0, sizeof(_registers));
3383 inline bool Registers_sparc::validRegister(int regNum) const {
3384 if (regNum == UNW_REG_IP)
3386 if (regNum == UNW_REG_SP)
3390 if (regNum <= UNW_SPARC_I7)
3395 inline uint32_t Registers_sparc::getRegister(int regNum) const {
3396 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3397 return _registers.__regs[regNum];
3402 return _registers.__regs[UNW_SPARC_O7];
3404 return _registers.__regs[UNW_SPARC_O6];
3406 _LIBUNWIND_ABORT("unsupported sparc register");
3409 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3410 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3411 _registers.__regs[regNum] = value;
3417 _registers.__regs[UNW_SPARC_O7] = value;
3420 _registers.__regs[UNW_SPARC_O6] = value;
3423 _LIBUNWIND_ABORT("unsupported sparc register");
3426 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3428 inline double Registers_sparc::getFloatRegister(int) const {
3429 _LIBUNWIND_ABORT("no Sparc float registers");
3432 inline void Registers_sparc::setFloatRegister(int, double) {
3433 _LIBUNWIND_ABORT("no Sparc float registers");
3436 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3438 inline v128 Registers_sparc::getVectorRegister(int) const {
3439 _LIBUNWIND_ABORT("no Sparc vector registers");
3442 inline void Registers_sparc::setVectorRegister(int, v128) {
3443 _LIBUNWIND_ABORT("no Sparc vector registers");
3446 inline const char *Registers_sparc::getRegisterName(int regNum) {
3516 return "unknown register";
3519 #endif // _LIBUNWIND_TARGET_SPARC
3521 #if defined(_LIBUNWIND_TARGET_RISCV)
3522 /// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
3524 class _LIBUNWIND_HIDDEN Registers_riscv {
3527 Registers_riscv(const void *registers);
3529 bool validRegister(int num) const;
3530 uint64_t getRegister(int num) const;
3531 void setRegister(int num, uint64_t value);
3532 bool validFloatRegister(int num) const;
3533 double getFloatRegister(int num) const;
3534 void setFloatRegister(int num, double value);
3535 bool validVectorRegister(int num) const;
3536 v128 getVectorRegister(int num) const;
3537 void setVectorRegister(int num, v128 value);
3538 static const char *getRegisterName(int num);
3540 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
3541 static int getArch() { return REGISTERS_RISCV; }
3543 uint64_t getSP() const { return _registers[2]; }
3544 void setSP(uint64_t value) { _registers[2] = value; }
3545 uint64_t getIP() const { return _registers[1]; }
3546 void setIP(uint64_t value) { _registers[1] = value; }
3550 uint64_t _registers[32];
3554 inline Registers_riscv::Registers_riscv(const void *registers) {
3555 static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
3556 "riscv registers do not fit into unw_context_t");
3557 memcpy(&_registers, registers, sizeof(_registers));
3558 static_assert(sizeof(_registers) == 0x100,
3559 "expected float registers to be at offset 256");
3561 static_cast<const uint8_t *>(registers) + sizeof(_registers),
3565 inline Registers_riscv::Registers_riscv() {
3566 memset(&_registers, 0, sizeof(_registers));
3567 memset(&_floats, 0, sizeof(_floats));
3570 inline bool Registers_riscv::validRegister(int regNum) const {
3571 if (regNum == UNW_REG_IP)
3573 if (regNum == UNW_REG_SP)
3577 if (regNum > UNW_RISCV_F31)
3582 inline uint64_t Registers_riscv::getRegister(int regNum) const {
3583 if (regNum == UNW_REG_IP)
3584 return _registers[1];
3585 if (regNum == UNW_REG_SP)
3586 return _registers[2];
3587 if (regNum == UNW_RISCV_X0)
3589 if ((regNum > 0) && (regNum < 32))
3590 return _registers[regNum];
3591 _LIBUNWIND_ABORT("unsupported riscv register");
3594 inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
3595 if (regNum == UNW_REG_IP)
3596 _registers[1] = value;
3597 else if (regNum == UNW_REG_SP)
3598 _registers[2] = value;
3599 else if (regNum == UNW_RISCV_X0)
3600 /* x0 is hardwired to zero */
3602 else if ((regNum > 0) && (regNum < 32))
3603 _registers[regNum] = value;
3605 _LIBUNWIND_ABORT("unsupported riscv register");
3608 inline const char *Registers_riscv::getRegisterName(int regNum) {
3743 return "unknown register";
3747 inline bool Registers_riscv::validFloatRegister(int regNum) const {
3748 if (regNum < UNW_RISCV_F0)
3750 if (regNum > UNW_RISCV_F31)
3755 inline double Registers_riscv::getFloatRegister(int regNum) const {
3756 #if defined(__riscv_flen) && __riscv_flen == 64
3757 assert(validFloatRegister(regNum));
3758 return _floats[regNum - UNW_RISCV_F0];
3760 _LIBUNWIND_ABORT("libunwind not built with float support");
3764 inline void Registers_riscv::setFloatRegister(int regNum, double value) {
3765 #if defined(__riscv_flen) && __riscv_flen == 64
3766 assert(validFloatRegister(regNum));
3767 _floats[regNum - UNW_RISCV_F0] = value;
3769 _LIBUNWIND_ABORT("libunwind not built with float support");
3773 inline bool Registers_riscv::validVectorRegister(int) const {
3777 inline v128 Registers_riscv::getVectorRegister(int) const {
3778 _LIBUNWIND_ABORT("no riscv vector register support yet");
3781 inline void Registers_riscv::setVectorRegister(int, v128) {
3782 _LIBUNWIND_ABORT("no riscv vector register support yet");
3784 #endif // _LIBUNWIND_TARGET_RISCV
3785 } // namespace libunwind
3787 #endif // __REGISTERS_HPP__