1 //===----------------------------- Registers.hpp --------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
9 // Models register sets for supported processors.
11 //===----------------------------------------------------------------------===//
13 #ifndef __REGISTERS_HPP__
14 #define __REGISTERS_HPP__
19 #include "libunwind.h"
24 // For emulating 128-bit registers
25 struct v128 { uint32_t vec[4]; };
37 REGISTERS_MIPS_NEWABI,
41 #if defined(_LIBUNWIND_TARGET_I386)
42 /// Registers_x86 holds the register state of a thread in a 32-bit intel
44 class _LIBUNWIND_HIDDEN Registers_x86 {
47 Registers_x86(const void *registers);
49 bool validRegister(int num) const;
50 uint32_t getRegister(int num) const;
51 void setRegister(int num, uint32_t value);
52 bool validFloatRegister(int) const { return false; }
53 double getFloatRegister(int num) const;
54 void setFloatRegister(int num, double value);
55 bool validVectorRegister(int) const { return false; }
56 v128 getVectorRegister(int num) const;
57 void setVectorRegister(int num, v128 value);
58 static const char *getRegisterName(int num);
60 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86; }
61 static int getArch() { return REGISTERS_X86; }
63 uint32_t getSP() const { return _registers.__esp; }
64 void setSP(uint32_t value) { _registers.__esp = value; }
65 uint32_t getIP() const { return _registers.__eip; }
66 void setIP(uint32_t value) { _registers.__eip = value; }
67 uint32_t getEBP() const { return _registers.__ebp; }
68 void setEBP(uint32_t value) { _registers.__ebp = value; }
69 uint32_t getEBX() const { return _registers.__ebx; }
70 void setEBX(uint32_t value) { _registers.__ebx = value; }
71 uint32_t getECX() const { return _registers.__ecx; }
72 void setECX(uint32_t value) { _registers.__ecx = value; }
73 uint32_t getEDX() const { return _registers.__edx; }
74 void setEDX(uint32_t value) { _registers.__edx = value; }
75 uint32_t getESI() const { return _registers.__esi; }
76 void setESI(uint32_t value) { _registers.__esi = value; }
77 uint32_t getEDI() const { return _registers.__edi; }
78 void setEDI(uint32_t value) { _registers.__edi = value; }
91 unsigned int __eflags;
103 inline Registers_x86::Registers_x86(const void *registers) {
104 static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
105 "x86 registers do not fit into unw_context_t");
106 memcpy(&_registers, registers, sizeof(_registers));
109 inline Registers_x86::Registers_x86() {
110 memset(&_registers, 0, sizeof(_registers));
113 inline bool Registers_x86::validRegister(int regNum) const {
114 if (regNum == UNW_REG_IP)
116 if (regNum == UNW_REG_SP)
125 inline uint32_t Registers_x86::getRegister(int regNum) const {
128 return _registers.__eip;
130 return _registers.__esp;
132 return _registers.__eax;
134 return _registers.__ecx;
136 return _registers.__edx;
138 return _registers.__ebx;
139 #if !defined(__APPLE__)
144 return _registers.__ebp;
145 #if !defined(__APPLE__)
150 return _registers.__esp;
152 return _registers.__esi;
154 return _registers.__edi;
156 _LIBUNWIND_ABORT("unsupported x86 register");
159 inline void Registers_x86::setRegister(int regNum, uint32_t value) {
162 _registers.__eip = value;
165 _registers.__esp = value;
168 _registers.__eax = value;
171 _registers.__ecx = value;
174 _registers.__edx = value;
177 _registers.__ebx = value;
179 #if !defined(__APPLE__)
184 _registers.__ebp = value;
186 #if !defined(__APPLE__)
191 _registers.__esp = value;
194 _registers.__esi = value;
197 _registers.__edi = value;
200 _LIBUNWIND_ABORT("unsupported x86 register");
203 inline const char *Registers_x86::getRegisterName(int regNum) {
226 return "unknown register";
230 inline double Registers_x86::getFloatRegister(int) const {
231 _LIBUNWIND_ABORT("no x86 float registers");
234 inline void Registers_x86::setFloatRegister(int, double) {
235 _LIBUNWIND_ABORT("no x86 float registers");
238 inline v128 Registers_x86::getVectorRegister(int) const {
239 _LIBUNWIND_ABORT("no x86 vector registers");
242 inline void Registers_x86::setVectorRegister(int, v128) {
243 _LIBUNWIND_ABORT("no x86 vector registers");
245 #endif // _LIBUNWIND_TARGET_I386
248 #if defined(_LIBUNWIND_TARGET_X86_64)
249 /// Registers_x86_64 holds the register state of a thread in a 64-bit intel
251 class _LIBUNWIND_HIDDEN Registers_x86_64 {
254 Registers_x86_64(const void *registers);
256 bool validRegister(int num) const;
257 uint64_t getRegister(int num) const;
258 void setRegister(int num, uint64_t value);
259 bool validFloatRegister(int) const { return false; }
260 double getFloatRegister(int num) const;
261 void setFloatRegister(int num, double value);
262 bool validVectorRegister(int) const;
263 v128 getVectorRegister(int num) const;
264 void setVectorRegister(int num, v128 value);
265 static const char *getRegisterName(int num);
267 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86_64; }
268 static int getArch() { return REGISTERS_X86_64; }
270 uint64_t getSP() const { return _registers.__rsp; }
271 void setSP(uint64_t value) { _registers.__rsp = value; }
272 uint64_t getIP() const { return _registers.__rip; }
273 void setIP(uint64_t value) { _registers.__rip = value; }
274 uint64_t getRBP() const { return _registers.__rbp; }
275 void setRBP(uint64_t value) { _registers.__rbp = value; }
276 uint64_t getRBX() const { return _registers.__rbx; }
277 void setRBX(uint64_t value) { _registers.__rbx = value; }
278 uint64_t getR12() const { return _registers.__r12; }
279 void setR12(uint64_t value) { _registers.__r12 = value; }
280 uint64_t getR13() const { return _registers.__r13; }
281 void setR13(uint64_t value) { _registers.__r13 = value; }
282 uint64_t getR14() const { return _registers.__r14; }
283 void setR14(uint64_t value) { _registers.__r14 = value; }
284 uint64_t getR15() const { return _registers.__r15; }
285 void setR15(uint64_t value) { _registers.__r15 = value; }
311 uint64_t __padding; // 16-byte align
320 inline Registers_x86_64::Registers_x86_64(const void *registers) {
321 static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
322 "x86_64 registers do not fit into unw_context_t");
323 memcpy(&_registers, registers, sizeof(_registers));
326 inline Registers_x86_64::Registers_x86_64() {
327 memset(&_registers, 0, sizeof(_registers));
330 inline bool Registers_x86_64::validRegister(int regNum) const {
331 if (regNum == UNW_REG_IP)
333 if (regNum == UNW_REG_SP)
342 inline uint64_t Registers_x86_64::getRegister(int regNum) const {
345 return _registers.__rip;
347 return _registers.__rsp;
349 return _registers.__rax;
351 return _registers.__rdx;
353 return _registers.__rcx;
355 return _registers.__rbx;
357 return _registers.__rsi;
359 return _registers.__rdi;
361 return _registers.__rbp;
363 return _registers.__rsp;
365 return _registers.__r8;
367 return _registers.__r9;
369 return _registers.__r10;
371 return _registers.__r11;
373 return _registers.__r12;
375 return _registers.__r13;
377 return _registers.__r14;
379 return _registers.__r15;
381 _LIBUNWIND_ABORT("unsupported x86_64 register");
384 inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
387 _registers.__rip = value;
390 _registers.__rsp = value;
393 _registers.__rax = value;
396 _registers.__rdx = value;
399 _registers.__rcx = value;
402 _registers.__rbx = value;
405 _registers.__rsi = value;
408 _registers.__rdi = value;
411 _registers.__rbp = value;
414 _registers.__rsp = value;
417 _registers.__r8 = value;
420 _registers.__r9 = value;
423 _registers.__r10 = value;
426 _registers.__r11 = value;
429 _registers.__r12 = value;
432 _registers.__r13 = value;
435 _registers.__r14 = value;
438 _registers.__r15 = value;
441 _LIBUNWIND_ABORT("unsupported x86_64 register");
444 inline const char *Registers_x86_64::getRegisterName(int regNum) {
482 case UNW_X86_64_XMM0:
484 case UNW_X86_64_XMM1:
486 case UNW_X86_64_XMM2:
488 case UNW_X86_64_XMM3:
490 case UNW_X86_64_XMM4:
492 case UNW_X86_64_XMM5:
494 case UNW_X86_64_XMM6:
496 case UNW_X86_64_XMM7:
498 case UNW_X86_64_XMM8:
500 case UNW_X86_64_XMM9:
502 case UNW_X86_64_XMM10:
504 case UNW_X86_64_XMM11:
506 case UNW_X86_64_XMM12:
508 case UNW_X86_64_XMM13:
510 case UNW_X86_64_XMM14:
512 case UNW_X86_64_XMM15:
515 return "unknown register";
519 inline double Registers_x86_64::getFloatRegister(int) const {
520 _LIBUNWIND_ABORT("no x86_64 float registers");
523 inline void Registers_x86_64::setFloatRegister(int, double) {
524 _LIBUNWIND_ABORT("no x86_64 float registers");
527 inline bool Registers_x86_64::validVectorRegister(int regNum) const {
529 if (regNum < UNW_X86_64_XMM0)
531 if (regNum > UNW_X86_64_XMM15)
535 (void)regNum; // suppress unused parameter warning
540 inline v128 Registers_x86_64::getVectorRegister(int regNum) const {
542 assert(validVectorRegister(regNum));
543 return _xmm[regNum - UNW_X86_64_XMM0];
545 (void)regNum; // suppress unused parameter warning
546 _LIBUNWIND_ABORT("no x86_64 vector registers");
550 inline void Registers_x86_64::setVectorRegister(int regNum, v128 value) {
552 assert(validVectorRegister(regNum));
553 _xmm[regNum - UNW_X86_64_XMM0] = value;
555 (void)regNum; (void)value; // suppress unused parameter warnings
556 _LIBUNWIND_ABORT("no x86_64 vector registers");
559 #endif // _LIBUNWIND_TARGET_X86_64
562 #if defined(_LIBUNWIND_TARGET_PPC)
563 /// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
565 class _LIBUNWIND_HIDDEN Registers_ppc {
568 Registers_ppc(const void *registers);
570 bool validRegister(int num) const;
571 uint32_t getRegister(int num) const;
572 void setRegister(int num, uint32_t value);
573 bool validFloatRegister(int num) const;
574 double getFloatRegister(int num) const;
575 void setFloatRegister(int num, double value);
576 bool validVectorRegister(int num) const;
577 v128 getVectorRegister(int num) const;
578 void setVectorRegister(int num, v128 value);
579 static const char *getRegisterName(int num);
581 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC; }
582 static int getArch() { return REGISTERS_PPC; }
584 uint64_t getSP() const { return _registers.__r1; }
585 void setSP(uint32_t value) { _registers.__r1 = value; }
586 uint64_t getIP() const { return _registers.__srr0; }
587 void setIP(uint32_t value) { _registers.__srr0 = value; }
590 struct ppc_thread_state_t {
591 unsigned int __srr0; /* Instruction address register (PC) */
592 unsigned int __srr1; /* Machine state register (supervisor) */
625 unsigned int __cr; /* Condition register */
626 unsigned int __xer; /* User's integer exception register */
627 unsigned int __lr; /* Link register */
628 unsigned int __ctr; /* Count register */
629 unsigned int __mq; /* MQ register (601 only) */
630 unsigned int __vrsave; /* Vector Save Register */
633 struct ppc_float_state_t {
636 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
637 unsigned int __fpscr; /* floating point status register */
640 ppc_thread_state_t _registers;
641 ppc_float_state_t _floatRegisters;
642 v128 _vectorRegisters[32]; // offset 424
645 inline Registers_ppc::Registers_ppc(const void *registers) {
646 static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
647 "ppc registers do not fit into unw_context_t");
648 memcpy(&_registers, static_cast<const uint8_t *>(registers),
650 static_assert(sizeof(ppc_thread_state_t) == 160,
651 "expected float register offset to be 160");
652 memcpy(&_floatRegisters,
653 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
654 sizeof(_floatRegisters));
655 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
656 "expected vector register offset to be 424 bytes");
657 memcpy(_vectorRegisters,
658 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
659 sizeof(ppc_float_state_t),
660 sizeof(_vectorRegisters));
663 inline Registers_ppc::Registers_ppc() {
664 memset(&_registers, 0, sizeof(_registers));
665 memset(&_floatRegisters, 0, sizeof(_floatRegisters));
666 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
669 inline bool Registers_ppc::validRegister(int regNum) const {
670 if (regNum == UNW_REG_IP)
672 if (regNum == UNW_REG_SP)
674 if (regNum == UNW_PPC_VRSAVE)
678 if (regNum <= UNW_PPC_R31)
680 if (regNum == UNW_PPC_MQ)
682 if (regNum == UNW_PPC_LR)
684 if (regNum == UNW_PPC_CTR)
686 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
691 inline uint32_t Registers_ppc::getRegister(int regNum) const {
694 return _registers.__srr0;
696 return _registers.__r1;
698 return _registers.__r0;
700 return _registers.__r1;
702 return _registers.__r2;
704 return _registers.__r3;
706 return _registers.__r4;
708 return _registers.__r5;
710 return _registers.__r6;
712 return _registers.__r7;
714 return _registers.__r8;
716 return _registers.__r9;
718 return _registers.__r10;
720 return _registers.__r11;
722 return _registers.__r12;
724 return _registers.__r13;
726 return _registers.__r14;
728 return _registers.__r15;
730 return _registers.__r16;
732 return _registers.__r17;
734 return _registers.__r18;
736 return _registers.__r19;
738 return _registers.__r20;
740 return _registers.__r21;
742 return _registers.__r22;
744 return _registers.__r23;
746 return _registers.__r24;
748 return _registers.__r25;
750 return _registers.__r26;
752 return _registers.__r27;
754 return _registers.__r28;
756 return _registers.__r29;
758 return _registers.__r30;
760 return _registers.__r31;
762 return _registers.__lr;
764 return (_registers.__cr & 0xF0000000);
766 return (_registers.__cr & 0x0F000000);
768 return (_registers.__cr & 0x00F00000);
770 return (_registers.__cr & 0x000F0000);
772 return (_registers.__cr & 0x0000F000);
774 return (_registers.__cr & 0x00000F00);
776 return (_registers.__cr & 0x000000F0);
778 return (_registers.__cr & 0x0000000F);
780 return _registers.__vrsave;
782 _LIBUNWIND_ABORT("unsupported ppc register");
785 inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
786 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
789 _registers.__srr0 = value;
792 _registers.__r1 = value;
795 _registers.__r0 = value;
798 _registers.__r1 = value;
801 _registers.__r2 = value;
804 _registers.__r3 = value;
807 _registers.__r4 = value;
810 _registers.__r5 = value;
813 _registers.__r6 = value;
816 _registers.__r7 = value;
819 _registers.__r8 = value;
822 _registers.__r9 = value;
825 _registers.__r10 = value;
828 _registers.__r11 = value;
831 _registers.__r12 = value;
834 _registers.__r13 = value;
837 _registers.__r14 = value;
840 _registers.__r15 = value;
843 _registers.__r16 = value;
846 _registers.__r17 = value;
849 _registers.__r18 = value;
852 _registers.__r19 = value;
855 _registers.__r20 = value;
858 _registers.__r21 = value;
861 _registers.__r22 = value;
864 _registers.__r23 = value;
867 _registers.__r24 = value;
870 _registers.__r25 = value;
873 _registers.__r26 = value;
876 _registers.__r27 = value;
879 _registers.__r28 = value;
882 _registers.__r29 = value;
885 _registers.__r30 = value;
888 _registers.__r31 = value;
891 _registers.__mq = value;
894 _registers.__lr = value;
897 _registers.__ctr = value;
900 _registers.__cr &= 0x0FFFFFFF;
901 _registers.__cr |= (value & 0xF0000000);
904 _registers.__cr &= 0xF0FFFFFF;
905 _registers.__cr |= (value & 0x0F000000);
908 _registers.__cr &= 0xFF0FFFFF;
909 _registers.__cr |= (value & 0x00F00000);
912 _registers.__cr &= 0xFFF0FFFF;
913 _registers.__cr |= (value & 0x000F0000);
916 _registers.__cr &= 0xFFFF0FFF;
917 _registers.__cr |= (value & 0x0000F000);
920 _registers.__cr &= 0xFFFFF0FF;
921 _registers.__cr |= (value & 0x00000F00);
924 _registers.__cr &= 0xFFFFFF0F;
925 _registers.__cr |= (value & 0x000000F0);
928 _registers.__cr &= 0xFFFFFFF0;
929 _registers.__cr |= (value & 0x0000000F);
932 _registers.__vrsave = value;
937 _registers.__xer = value;
941 case UNW_PPC_SPEFSCR:
945 _LIBUNWIND_ABORT("unsupported ppc register");
948 inline bool Registers_ppc::validFloatRegister(int regNum) const {
949 if (regNum < UNW_PPC_F0)
951 if (regNum > UNW_PPC_F31)
956 inline double Registers_ppc::getFloatRegister(int regNum) const {
957 assert(validFloatRegister(regNum));
958 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
961 inline void Registers_ppc::setFloatRegister(int regNum, double value) {
962 assert(validFloatRegister(regNum));
963 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
966 inline bool Registers_ppc::validVectorRegister(int regNum) const {
967 if (regNum < UNW_PPC_V0)
969 if (regNum > UNW_PPC_V31)
974 inline v128 Registers_ppc::getVectorRegister(int regNum) const {
975 assert(validVectorRegister(regNum));
976 v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
980 inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
981 assert(validVectorRegister(regNum));
982 _vectorRegisters[regNum - UNW_PPC_V0] = value;
985 inline const char *Registers_ppc::getRegisterName(int regNum) {
1122 return "unknown register";
1126 #endif // _LIBUNWIND_TARGET_PPC
1128 #if defined(_LIBUNWIND_TARGET_PPC64)
1129 /// Registers_ppc64 holds the register state of a thread in a 64-bit PowerPC
1131 class _LIBUNWIND_HIDDEN Registers_ppc64 {
1134 Registers_ppc64(const void *registers);
1136 bool validRegister(int num) const;
1137 uint64_t getRegister(int num) const;
1138 void setRegister(int num, uint64_t value);
1139 bool validFloatRegister(int num) const;
1140 double getFloatRegister(int num) const;
1141 void setFloatRegister(int num, double value);
1142 bool validVectorRegister(int num) const;
1143 v128 getVectorRegister(int num) const;
1144 void setVectorRegister(int num, v128 value);
1145 static const char *getRegisterName(int num);
1147 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_PPC64; }
1148 static int getArch() { return REGISTERS_PPC64; }
1150 uint64_t getSP() const { return _registers.__r1; }
1151 void setSP(uint64_t value) { _registers.__r1 = value; }
1152 uint64_t getIP() const { return _registers.__srr0; }
1153 void setIP(uint64_t value) { _registers.__srr0 = value; }
1156 struct ppc64_thread_state_t {
1157 uint64_t __srr0; // Instruction address register (PC)
1158 uint64_t __srr1; // Machine state register (supervisor)
1191 uint64_t __cr; // Condition register
1192 uint64_t __xer; // User's integer exception register
1193 uint64_t __lr; // Link register
1194 uint64_t __ctr; // Count register
1195 uint64_t __vrsave; // Vector Save Register
1206 ppc64_thread_state_t _registers;
1207 ppc64_vsr_t _vectorScalarRegisters[64];
1209 static int getVectorRegNum(int num);
1212 inline Registers_ppc64::Registers_ppc64(const void *registers) {
1213 static_assert((check_fit<Registers_ppc64, unw_context_t>::does_fit),
1214 "ppc64 registers do not fit into unw_context_t");
1215 memcpy(&_registers, static_cast<const uint8_t *>(registers),
1216 sizeof(_registers));
1217 static_assert(sizeof(_registers) == 312,
1218 "expected vector scalar register offset to be 312");
1219 memcpy(&_vectorScalarRegisters,
1220 static_cast<const uint8_t *>(registers) + sizeof(_registers),
1221 sizeof(_vectorScalarRegisters));
1222 static_assert(sizeof(_registers) +
1223 sizeof(_vectorScalarRegisters) == 1336,
1224 "expected vector register offset to be 1336 bytes");
1227 inline Registers_ppc64::Registers_ppc64() {
1228 memset(&_registers, 0, sizeof(_registers));
1229 memset(&_vectorScalarRegisters, 0, sizeof(_vectorScalarRegisters));
1232 inline bool Registers_ppc64::validRegister(int regNum) const {
1239 case UNW_PPC64_VRSAVE:
1243 if (regNum >= UNW_PPC64_R0 && regNum <= UNW_PPC64_R31)
1245 if (regNum >= UNW_PPC64_CR0 && regNum <= UNW_PPC64_CR7)
1251 inline uint64_t Registers_ppc64::getRegister(int regNum) const {
1254 return _registers.__srr0;
1256 return _registers.__r0;
1259 return _registers.__r1;
1261 return _registers.__r2;
1263 return _registers.__r3;
1265 return _registers.__r4;
1267 return _registers.__r5;
1269 return _registers.__r6;
1271 return _registers.__r7;
1273 return _registers.__r8;
1275 return _registers.__r9;
1277 return _registers.__r10;
1279 return _registers.__r11;
1281 return _registers.__r12;
1283 return _registers.__r13;
1285 return _registers.__r14;
1287 return _registers.__r15;
1289 return _registers.__r16;
1291 return _registers.__r17;
1293 return _registers.__r18;
1295 return _registers.__r19;
1297 return _registers.__r20;
1299 return _registers.__r21;
1301 return _registers.__r22;
1303 return _registers.__r23;
1305 return _registers.__r24;
1307 return _registers.__r25;
1309 return _registers.__r26;
1311 return _registers.__r27;
1313 return _registers.__r28;
1315 return _registers.__r29;
1317 return _registers.__r30;
1319 return _registers.__r31;
1321 return (_registers.__cr & 0xF0000000);
1323 return (_registers.__cr & 0x0F000000);
1325 return (_registers.__cr & 0x00F00000);
1327 return (_registers.__cr & 0x000F0000);
1329 return (_registers.__cr & 0x0000F000);
1331 return (_registers.__cr & 0x00000F00);
1333 return (_registers.__cr & 0x000000F0);
1335 return (_registers.__cr & 0x0000000F);
1337 return _registers.__xer;
1339 return _registers.__lr;
1341 return _registers.__ctr;
1342 case UNW_PPC64_VRSAVE:
1343 return _registers.__vrsave;
1345 _LIBUNWIND_ABORT("unsupported ppc64 register");
1348 inline void Registers_ppc64::setRegister(int regNum, uint64_t value) {
1351 _registers.__srr0 = value;
1354 _registers.__r0 = value;
1358 _registers.__r1 = value;
1361 _registers.__r2 = value;
1364 _registers.__r3 = value;
1367 _registers.__r4 = value;
1370 _registers.__r5 = value;
1373 _registers.__r6 = value;
1376 _registers.__r7 = value;
1379 _registers.__r8 = value;
1382 _registers.__r9 = value;
1385 _registers.__r10 = value;
1388 _registers.__r11 = value;
1391 _registers.__r12 = value;
1394 _registers.__r13 = value;
1397 _registers.__r14 = value;
1400 _registers.__r15 = value;
1403 _registers.__r16 = value;
1406 _registers.__r17 = value;
1409 _registers.__r18 = value;
1412 _registers.__r19 = value;
1415 _registers.__r20 = value;
1418 _registers.__r21 = value;
1421 _registers.__r22 = value;
1424 _registers.__r23 = value;
1427 _registers.__r24 = value;
1430 _registers.__r25 = value;
1433 _registers.__r26 = value;
1436 _registers.__r27 = value;
1439 _registers.__r28 = value;
1442 _registers.__r29 = value;
1445 _registers.__r30 = value;
1448 _registers.__r31 = value;
1451 _registers.__cr &= 0x0FFFFFFF;
1452 _registers.__cr |= (value & 0xF0000000);
1455 _registers.__cr &= 0xF0FFFFFF;
1456 _registers.__cr |= (value & 0x0F000000);
1459 _registers.__cr &= 0xFF0FFFFF;
1460 _registers.__cr |= (value & 0x00F00000);
1463 _registers.__cr &= 0xFFF0FFFF;
1464 _registers.__cr |= (value & 0x000F0000);
1467 _registers.__cr &= 0xFFFF0FFF;
1468 _registers.__cr |= (value & 0x0000F000);
1471 _registers.__cr &= 0xFFFFF0FF;
1472 _registers.__cr |= (value & 0x00000F00);
1475 _registers.__cr &= 0xFFFFFF0F;
1476 _registers.__cr |= (value & 0x000000F0);
1479 _registers.__cr &= 0xFFFFFFF0;
1480 _registers.__cr |= (value & 0x0000000F);
1483 _registers.__xer = value;
1486 _registers.__lr = value;
1489 _registers.__ctr = value;
1491 case UNW_PPC64_VRSAVE:
1492 _registers.__vrsave = value;
1495 _LIBUNWIND_ABORT("unsupported ppc64 register");
1498 inline bool Registers_ppc64::validFloatRegister(int regNum) const {
1499 return regNum >= UNW_PPC64_F0 && regNum <= UNW_PPC64_F31;
1502 inline double Registers_ppc64::getFloatRegister(int regNum) const {
1503 assert(validFloatRegister(regNum));
1504 return _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f;
1507 inline void Registers_ppc64::setFloatRegister(int regNum, double value) {
1508 assert(validFloatRegister(regNum));
1509 _vectorScalarRegisters[regNum - UNW_PPC64_F0].asfloat.f = value;
1512 inline bool Registers_ppc64::validVectorRegister(int regNum) const {
1513 #ifdef PPC64_HAS_VMX
1514 if (regNum >= UNW_PPC64_VS0 && regNum <= UNW_PPC64_VS31)
1516 if (regNum >= UNW_PPC64_VS32 && regNum <= UNW_PPC64_VS63)
1519 if (regNum >= UNW_PPC64_V0 && regNum <= UNW_PPC64_V31)
1525 inline int Registers_ppc64::getVectorRegNum(int num)
1527 if (num >= UNW_PPC64_VS0 && num <= UNW_PPC64_VS31)
1528 return num - UNW_PPC64_VS0;
1530 return num - UNW_PPC64_VS32 + 32;
1533 inline v128 Registers_ppc64::getVectorRegister(int regNum) const {
1534 assert(validVectorRegister(regNum));
1535 return _vectorScalarRegisters[getVectorRegNum(regNum)].v;
1538 inline void Registers_ppc64::setVectorRegister(int regNum, v128 value) {
1539 assert(validVectorRegister(regNum));
1540 _vectorScalarRegisters[getVectorRegNum(regNum)].v = value;
1543 inline const char *Registers_ppc64::getRegisterName(int regNum) {
1635 case UNW_PPC64_VRSAVE:
1766 return "unknown register";
1768 #endif // _LIBUNWIND_TARGET_PPC64
1771 #if defined(_LIBUNWIND_TARGET_AARCH64)
1772 /// Registers_arm64 holds the register state of a thread in a 64-bit arm
1774 class _LIBUNWIND_HIDDEN Registers_arm64 {
1777 Registers_arm64(const void *registers);
1779 bool validRegister(int num) const;
1780 uint64_t getRegister(int num) const;
1781 void setRegister(int num, uint64_t value);
1782 bool validFloatRegister(int num) const;
1783 double getFloatRegister(int num) const;
1784 void setFloatRegister(int num, double value);
1785 bool validVectorRegister(int num) const;
1786 v128 getVectorRegister(int num) const;
1787 void setVectorRegister(int num, v128 value);
1788 static const char *getRegisterName(int num);
1790 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM64; }
1791 static int getArch() { return REGISTERS_ARM64; }
1793 uint64_t getSP() const { return _registers.__sp; }
1794 void setSP(uint64_t value) { _registers.__sp = value; }
1795 uint64_t getIP() const { return _registers.__pc; }
1796 void setIP(uint64_t value) { _registers.__pc = value; }
1797 uint64_t getFP() const { return _registers.__fp; }
1798 void setFP(uint64_t value) { _registers.__fp = value; }
1802 uint64_t __x[29]; // x0-x28
1803 uint64_t __fp; // Frame pointer x29
1804 uint64_t __lr; // Link register x30
1805 uint64_t __sp; // Stack pointer x31
1806 uint64_t __pc; // Program counter
1807 uint64_t __ra_sign_state; // RA sign state register
1811 double _vectorHalfRegisters[32];
1812 // Currently only the lower double in 128-bit vectore registers
1813 // is perserved during unwinding. We could define new register
1814 // numbers (> 96) which mean whole vector registers, then this
1815 // struct would need to change to contain whole vector registers.
1818 inline Registers_arm64::Registers_arm64(const void *registers) {
1819 static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
1820 "arm64 registers do not fit into unw_context_t");
1821 memcpy(&_registers, registers, sizeof(_registers));
1822 static_assert(sizeof(GPRs) == 0x110,
1823 "expected VFP registers to be at offset 272");
1824 memcpy(_vectorHalfRegisters,
1825 static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1826 sizeof(_vectorHalfRegisters));
1829 inline Registers_arm64::Registers_arm64() {
1830 memset(&_registers, 0, sizeof(_registers));
1831 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1834 inline bool Registers_arm64::validRegister(int regNum) const {
1835 if (regNum == UNW_REG_IP)
1837 if (regNum == UNW_REG_SP)
1843 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1845 if ((regNum > 31) && (regNum < 64))
1850 inline uint64_t Registers_arm64::getRegister(int regNum) const {
1851 if (regNum == UNW_REG_IP)
1852 return _registers.__pc;
1853 if (regNum == UNW_REG_SP)
1854 return _registers.__sp;
1855 if (regNum == UNW_ARM64_RA_SIGN_STATE)
1856 return _registers.__ra_sign_state;
1857 if ((regNum >= 0) && (regNum < 32))
1858 return _registers.__x[regNum];
1859 _LIBUNWIND_ABORT("unsupported arm64 register");
1862 inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1863 if (regNum == UNW_REG_IP)
1864 _registers.__pc = value;
1865 else if (regNum == UNW_REG_SP)
1866 _registers.__sp = value;
1867 else if (regNum == UNW_ARM64_RA_SIGN_STATE)
1868 _registers.__ra_sign_state = value;
1869 else if ((regNum >= 0) && (regNum < 32))
1870 _registers.__x[regNum] = value;
1872 _LIBUNWIND_ABORT("unsupported arm64 register");
1875 inline const char *Registers_arm64::getRegisterName(int regNum) {
2010 return "unknown register";
2014 inline bool Registers_arm64::validFloatRegister(int regNum) const {
2015 if (regNum < UNW_ARM64_D0)
2017 if (regNum > UNW_ARM64_D31)
2022 inline double Registers_arm64::getFloatRegister(int regNum) const {
2023 assert(validFloatRegister(regNum));
2024 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
2027 inline void Registers_arm64::setFloatRegister(int regNum, double value) {
2028 assert(validFloatRegister(regNum));
2029 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
2032 inline bool Registers_arm64::validVectorRegister(int) const {
2036 inline v128 Registers_arm64::getVectorRegister(int) const {
2037 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2040 inline void Registers_arm64::setVectorRegister(int, v128) {
2041 _LIBUNWIND_ABORT("no arm64 vector register support yet");
2043 #endif // _LIBUNWIND_TARGET_AARCH64
2045 #if defined(_LIBUNWIND_TARGET_ARM)
2046 /// Registers_arm holds the register state of a thread in a 32-bit arm
2049 /// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
2050 /// this uses more memory than required.
2051 class _LIBUNWIND_HIDDEN Registers_arm {
2054 Registers_arm(const void *registers);
2056 bool validRegister(int num) const;
2057 uint32_t getRegister(int num) const;
2058 void setRegister(int num, uint32_t value);
2059 bool validFloatRegister(int num) const;
2060 unw_fpreg_t getFloatRegister(int num);
2061 void setFloatRegister(int num, unw_fpreg_t value);
2062 bool validVectorRegister(int num) const;
2063 v128 getVectorRegister(int num) const;
2064 void setVectorRegister(int num, v128 value);
2065 static const char *getRegisterName(int num);
2067 restoreSavedFloatRegisters();
2068 restoreCoreAndJumpTo();
2070 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_ARM; }
2071 static int getArch() { return REGISTERS_ARM; }
2073 uint32_t getSP() const { return _registers.__sp; }
2074 void setSP(uint32_t value) { _registers.__sp = value; }
2075 uint32_t getIP() const { return _registers.__pc; }
2076 void setIP(uint32_t value) { _registers.__pc = value; }
2079 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
2080 _use_X_for_vfp_save = true;
2083 void restoreSavedFloatRegisters() {
2084 if (_saved_vfp_d0_d15) {
2085 if (_use_X_for_vfp_save)
2086 restoreVFPWithFLDMX(_vfp_d0_d15_pad);
2088 restoreVFPWithFLDMD(_vfp_d0_d15_pad);
2090 if (_saved_vfp_d16_d31)
2091 restoreVFPv3(_vfp_d16_d31);
2092 #if defined(__ARM_WMMX)
2094 restoreiWMMX(_iwmmx);
2095 if (_saved_iwmmx_control)
2096 restoreiWMMXControl(_iwmmx_control);
2102 uint32_t __r[13]; // r0-r12
2103 uint32_t __sp; // Stack pointer r13
2104 uint32_t __lr; // Link register r14
2105 uint32_t __pc; // Program counter r15
2108 static void saveVFPWithFSTMD(unw_fpreg_t*);
2109 static void saveVFPWithFSTMX(unw_fpreg_t*);
2110 static void saveVFPv3(unw_fpreg_t*);
2111 static void restoreVFPWithFLDMD(unw_fpreg_t*);
2112 static void restoreVFPWithFLDMX(unw_fpreg_t*);
2113 static void restoreVFPv3(unw_fpreg_t*);
2114 #if defined(__ARM_WMMX)
2115 static void saveiWMMX(unw_fpreg_t*);
2116 static void saveiWMMXControl(uint32_t*);
2117 static void restoreiWMMX(unw_fpreg_t*);
2118 static void restoreiWMMXControl(uint32_t*);
2120 void restoreCoreAndJumpTo();
2125 // We save floating point registers lazily because we can't know ahead of
2126 // time which ones are used. See EHABI #4.7.
2128 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
2130 // See EHABI #7.5 that explains how matching instruction sequences for load
2131 // and store need to be used to correctly restore the exact register bits.
2132 bool _use_X_for_vfp_save;
2133 // Whether VFP D0-D15 are saved.
2134 bool _saved_vfp_d0_d15;
2135 // Whether VFPv3 D16-D31 are saved.
2136 bool _saved_vfp_d16_d31;
2137 // VFP registers D0-D15, + padding if saved using FSTMX
2138 unw_fpreg_t _vfp_d0_d15_pad[17];
2139 // VFPv3 registers D16-D31, always saved using FSTMD
2140 unw_fpreg_t _vfp_d16_d31[16];
2141 #if defined(__ARM_WMMX)
2142 // Whether iWMMX data registers are saved.
2144 // Whether iWMMX control registers are saved.
2145 mutable bool _saved_iwmmx_control;
2147 unw_fpreg_t _iwmmx[16];
2148 // iWMMX control registers
2149 mutable uint32_t _iwmmx_control[4];
2153 inline Registers_arm::Registers_arm(const void *registers)
2154 : _use_X_for_vfp_save(false),
2155 _saved_vfp_d0_d15(false),
2156 _saved_vfp_d16_d31(false) {
2157 static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
2158 "arm registers do not fit into unw_context_t");
2159 // See unw_getcontext() note about data.
2160 memcpy(&_registers, registers, sizeof(_registers));
2161 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2162 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2163 #if defined(__ARM_WMMX)
2164 _saved_iwmmx = false;
2165 _saved_iwmmx_control = false;
2166 memset(&_iwmmx, 0, sizeof(_iwmmx));
2167 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2171 inline Registers_arm::Registers_arm()
2172 : _use_X_for_vfp_save(false),
2173 _saved_vfp_d0_d15(false),
2174 _saved_vfp_d16_d31(false) {
2175 memset(&_registers, 0, sizeof(_registers));
2176 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
2177 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
2178 #if defined(__ARM_WMMX)
2179 _saved_iwmmx = false;
2180 _saved_iwmmx_control = false;
2181 memset(&_iwmmx, 0, sizeof(_iwmmx));
2182 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
2186 inline bool Registers_arm::validRegister(int regNum) const {
2187 // Returns true for all non-VFP registers supported by the EHABI
2188 // virtual register set (VRS).
2189 if (regNum == UNW_REG_IP)
2192 if (regNum == UNW_REG_SP)
2195 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
2198 #if defined(__ARM_WMMX)
2199 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
2206 inline uint32_t Registers_arm::getRegister(int regNum) const {
2207 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
2208 return _registers.__sp;
2210 if (regNum == UNW_ARM_LR)
2211 return _registers.__lr;
2213 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
2214 return _registers.__pc;
2216 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
2217 return _registers.__r[regNum];
2219 #if defined(__ARM_WMMX)
2220 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2221 if (!_saved_iwmmx_control) {
2222 _saved_iwmmx_control = true;
2223 saveiWMMXControl(_iwmmx_control);
2225 return _iwmmx_control[regNum - UNW_ARM_WC0];
2229 _LIBUNWIND_ABORT("unsupported arm register");
2232 inline void Registers_arm::setRegister(int regNum, uint32_t value) {
2233 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
2234 _registers.__sp = value;
2238 if (regNum == UNW_ARM_LR) {
2239 _registers.__lr = value;
2243 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
2244 _registers.__pc = value;
2248 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
2249 _registers.__r[regNum] = value;
2253 #if defined(__ARM_WMMX)
2254 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
2255 if (!_saved_iwmmx_control) {
2256 _saved_iwmmx_control = true;
2257 saveiWMMXControl(_iwmmx_control);
2259 _iwmmx_control[regNum - UNW_ARM_WC0] = value;
2264 _LIBUNWIND_ABORT("unsupported arm register");
2267 inline const char *Registers_arm::getRegisterName(int regNum) {
2270 case UNW_ARM_IP: // UNW_ARM_R15 is alias
2272 case UNW_ARM_LR: // UNW_ARM_R14 is alias
2275 case UNW_ARM_SP: // UNW_ARM_R13 is alias
2432 return "unknown register";
2436 inline bool Registers_arm::validFloatRegister(int regNum) const {
2437 // NOTE: Consider the intel MMX registers floating points so the
2438 // unw_get_fpreg can be used to transmit the 64-bit data back.
2439 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
2440 #if defined(__ARM_WMMX)
2441 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
2446 inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
2447 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2448 if (!_saved_vfp_d0_d15) {
2449 _saved_vfp_d0_d15 = true;
2450 if (_use_X_for_vfp_save)
2451 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2453 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2455 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
2458 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2459 if (!_saved_vfp_d16_d31) {
2460 _saved_vfp_d16_d31 = true;
2461 saveVFPv3(_vfp_d16_d31);
2463 return _vfp_d16_d31[regNum - UNW_ARM_D16];
2466 #if defined(__ARM_WMMX)
2467 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2468 if (!_saved_iwmmx) {
2469 _saved_iwmmx = true;
2472 return _iwmmx[regNum - UNW_ARM_WR0];
2476 _LIBUNWIND_ABORT("Unknown ARM float register");
2479 inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
2480 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
2481 if (!_saved_vfp_d0_d15) {
2482 _saved_vfp_d0_d15 = true;
2483 if (_use_X_for_vfp_save)
2484 saveVFPWithFSTMX(_vfp_d0_d15_pad);
2486 saveVFPWithFSTMD(_vfp_d0_d15_pad);
2488 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
2492 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
2493 if (!_saved_vfp_d16_d31) {
2494 _saved_vfp_d16_d31 = true;
2495 saveVFPv3(_vfp_d16_d31);
2497 _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
2501 #if defined(__ARM_WMMX)
2502 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
2503 if (!_saved_iwmmx) {
2504 _saved_iwmmx = true;
2507 _iwmmx[regNum - UNW_ARM_WR0] = value;
2512 _LIBUNWIND_ABORT("Unknown ARM float register");
2515 inline bool Registers_arm::validVectorRegister(int) const {
2519 inline v128 Registers_arm::getVectorRegister(int) const {
2520 _LIBUNWIND_ABORT("ARM vector support not implemented");
2523 inline void Registers_arm::setVectorRegister(int, v128) {
2524 _LIBUNWIND_ABORT("ARM vector support not implemented");
2526 #endif // _LIBUNWIND_TARGET_ARM
2529 #if defined(_LIBUNWIND_TARGET_OR1K)
2530 /// Registers_or1k holds the register state of a thread in an OpenRISC1000
2532 class _LIBUNWIND_HIDDEN Registers_or1k {
2535 Registers_or1k(const void *registers);
2537 bool validRegister(int num) const;
2538 uint32_t getRegister(int num) const;
2539 void setRegister(int num, uint32_t value);
2540 bool validFloatRegister(int num) const;
2541 double getFloatRegister(int num) const;
2542 void setFloatRegister(int num, double value);
2543 bool validVectorRegister(int num) const;
2544 v128 getVectorRegister(int num) const;
2545 void setVectorRegister(int num, v128 value);
2546 static const char *getRegisterName(int num);
2548 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K; }
2549 static int getArch() { return REGISTERS_OR1K; }
2551 uint64_t getSP() const { return _registers.__r[1]; }
2552 void setSP(uint32_t value) { _registers.__r[1] = value; }
2553 uint64_t getIP() const { return _registers.__pc; }
2554 void setIP(uint32_t value) { _registers.__pc = value; }
2557 struct or1k_thread_state_t {
2558 unsigned int __r[32]; // r0-r31
2559 unsigned int __pc; // Program counter
2560 unsigned int __epcr; // Program counter at exception
2563 or1k_thread_state_t _registers;
2566 inline Registers_or1k::Registers_or1k(const void *registers) {
2567 static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
2568 "or1k registers do not fit into unw_context_t");
2569 memcpy(&_registers, static_cast<const uint8_t *>(registers),
2570 sizeof(_registers));
2573 inline Registers_or1k::Registers_or1k() {
2574 memset(&_registers, 0, sizeof(_registers));
2577 inline bool Registers_or1k::validRegister(int regNum) const {
2578 if (regNum == UNW_REG_IP)
2580 if (regNum == UNW_REG_SP)
2584 if (regNum <= UNW_OR1K_R31)
2586 if (regNum == UNW_OR1K_EPCR)
2591 inline uint32_t Registers_or1k::getRegister(int regNum) const {
2592 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
2593 return _registers.__r[regNum - UNW_OR1K_R0];
2597 return _registers.__pc;
2599 return _registers.__r[1];
2601 return _registers.__epcr;
2603 _LIBUNWIND_ABORT("unsupported or1k register");
2606 inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
2607 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
2608 _registers.__r[regNum - UNW_OR1K_R0] = value;
2614 _registers.__pc = value;
2617 _registers.__r[1] = value;
2620 _registers.__epcr = value;
2623 _LIBUNWIND_ABORT("unsupported or1k register");
2626 inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
2630 inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
2631 _LIBUNWIND_ABORT("or1k float support not implemented");
2634 inline void Registers_or1k::setFloatRegister(int /* regNum */,
2635 double /* value */) {
2636 _LIBUNWIND_ABORT("or1k float support not implemented");
2639 inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
2643 inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
2644 _LIBUNWIND_ABORT("or1k vector support not implemented");
2647 inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
2648 _LIBUNWIND_ABORT("or1k vector support not implemented");
2651 inline const char *Registers_or1k::getRegisterName(int regNum) {
2720 return "unknown register";
2724 #endif // _LIBUNWIND_TARGET_OR1K
2726 #if defined(_LIBUNWIND_TARGET_RISCV)
2727 /// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
2729 class _LIBUNWIND_HIDDEN Registers_riscv {
2732 Registers_riscv(const void *registers);
2734 bool validRegister(int num) const;
2735 uint64_t getRegister(int num) const;
2736 void setRegister(int num, uint64_t value);
2737 bool validFloatRegister(int num) const;
2738 double getFloatRegister(int num) const;
2739 void setFloatRegister(int num, double value);
2740 bool validVectorRegister(int num) const;
2741 v128 getVectorRegister(int num) const;
2742 void setVectorRegister(int num, v128 value);
2743 static const char *getRegisterName(int num);
2745 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
2746 static int getArch() { return REGISTERS_RISCV; }
2748 uint64_t getSP() const { return _registers.__x[2]; }
2749 void setSP(uint64_t value) { _registers.__x[2] = value; }
2750 uint64_t getIP() const { return _registers.__x[1]; }
2751 void setIP(uint64_t value) { _registers.__x[1] = value; }
2755 uint64_t __x[32]; // x0-x31
2759 double _vectorHalfRegisters[32];
2760 // Currently only the lower double in 128-bit vectore registers
2761 // is perserved during unwinding. We could define new register
2762 // numbers (> 96) which mean whole vector registers, then this
2763 // struct would need to change to contain whole vector registers.
2766 inline Registers_riscv::Registers_riscv(const void *registers) {
2767 static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
2768 "riscv registers do not fit into unw_context_t");
2769 memcpy(&_registers, registers, sizeof(_registers));
2770 static_assert(sizeof(GPRs) == 0x100,
2771 "expected VFP registers to be at offset 256");
2772 memcpy(_vectorHalfRegisters,
2773 static_cast<const uint8_t *>(registers) + sizeof(GPRs),
2774 sizeof(_vectorHalfRegisters));
2777 inline Registers_riscv::Registers_riscv() {
2778 memset(&_registers, 0, sizeof(_registers));
2779 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
2782 inline bool Registers_riscv::validRegister(int regNum) const {
2783 if (regNum == UNW_REG_IP)
2785 if (regNum == UNW_REG_SP)
2791 if ((regNum > 31) && (regNum < 64))
2796 inline uint64_t Registers_riscv::getRegister(int regNum) const {
2797 if (regNum == UNW_REG_IP)
2798 return _registers.__x[1];
2799 if (regNum == UNW_REG_SP)
2800 return _registers.__x[2];
2801 if ((regNum >= 0) && (regNum < 32))
2802 return _registers.__x[regNum];
2803 _LIBUNWIND_ABORT("unsupported riscv register");
2806 inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
2807 if (regNum == UNW_REG_IP)
2808 _registers.__x[1] = value;
2809 else if (regNum == UNW_REG_SP)
2810 _registers.__x[2] = value;
2811 else if ((regNum >= 0) && (regNum < 32))
2812 _registers.__x[regNum] = value;
2814 _LIBUNWIND_ABORT("unsupported riscv register");
2817 inline const char *Registers_riscv::getRegisterName(int regNum) {
2952 return "unknown register";
2956 inline bool Registers_riscv::validFloatRegister(int regNum) const {
2957 if (regNum < UNW_RISCV_D0)
2959 if (regNum > UNW_RISCV_D31)
2964 inline double Registers_riscv::getFloatRegister(int regNum) const {
2965 assert(validFloatRegister(regNum));
2966 return _vectorHalfRegisters[regNum - UNW_RISCV_D0];
2969 inline void Registers_riscv::setFloatRegister(int regNum, double value) {
2970 assert(validFloatRegister(regNum));
2971 _vectorHalfRegisters[regNum - UNW_RISCV_D0] = value;
2974 inline bool Registers_riscv::validVectorRegister(int) const {
2978 inline v128 Registers_riscv::getVectorRegister(int) const {
2979 _LIBUNWIND_ABORT("no riscv vector register support yet");
2982 inline void Registers_riscv::setVectorRegister(int, v128) {
2983 _LIBUNWIND_ABORT("no riscv vector register support yet");
2985 #endif // _LIBUNWIND_TARGET_RISCV
2987 #if defined(_LIBUNWIND_TARGET_MIPS_O32)
2988 /// Registers_mips_o32 holds the register state of a thread in a 32-bit MIPS
2990 class _LIBUNWIND_HIDDEN Registers_mips_o32 {
2992 Registers_mips_o32();
2993 Registers_mips_o32(const void *registers);
2995 bool validRegister(int num) const;
2996 uint32_t getRegister(int num) const;
2997 void setRegister(int num, uint32_t value);
2998 bool validFloatRegister(int num) const;
2999 double getFloatRegister(int num) const;
3000 void setFloatRegister(int num, double value);
3001 bool validVectorRegister(int num) const;
3002 v128 getVectorRegister(int num) const;
3003 void setVectorRegister(int num, v128 value);
3004 static const char *getRegisterName(int num);
3006 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3007 static int getArch() { return REGISTERS_MIPS_O32; }
3009 uint32_t getSP() const { return _registers.__r[29]; }
3010 void setSP(uint32_t value) { _registers.__r[29] = value; }
3011 uint32_t getIP() const { return _registers.__pc; }
3012 void setIP(uint32_t value) { _registers.__pc = value; }
3015 struct mips_o32_thread_state_t {
3022 mips_o32_thread_state_t _registers;
3023 #ifdef __mips_hard_float
3024 /// O32 with 32-bit floating point registers only uses half of this
3025 /// space. However, using the same layout for 32-bit vs 64-bit
3026 /// floating point registers results in a single context size for
3027 /// O32 with hard float.
3033 inline Registers_mips_o32::Registers_mips_o32(const void *registers) {
3034 static_assert((check_fit<Registers_mips_o32, unw_context_t>::does_fit),
3035 "mips_o32 registers do not fit into unw_context_t");
3036 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3037 sizeof(_registers));
3040 inline Registers_mips_o32::Registers_mips_o32() {
3041 memset(&_registers, 0, sizeof(_registers));
3044 inline bool Registers_mips_o32::validRegister(int regNum) const {
3045 if (regNum == UNW_REG_IP)
3047 if (regNum == UNW_REG_SP)
3051 if (regNum <= UNW_MIPS_R31)
3053 #if __mips_isa_rev != 6
3054 if (regNum == UNW_MIPS_HI)
3056 if (regNum == UNW_MIPS_LO)
3059 #if defined(__mips_hard_float) && __mips_fpr == 32
3060 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3063 // FIXME: DSP accumulator registers, MSA registers
3067 inline uint32_t Registers_mips_o32::getRegister(int regNum) const {
3068 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3069 return _registers.__r[regNum - UNW_MIPS_R0];
3070 #if defined(__mips_hard_float) && __mips_fpr == 32
3071 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
3074 if (regNum % 2 == 0)
3075 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
3077 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
3084 return _registers.__pc;
3086 return _registers.__r[29];
3088 return _registers.__hi;
3090 return _registers.__lo;
3092 _LIBUNWIND_ABORT("unsupported mips_o32 register");
3095 inline void Registers_mips_o32::setRegister(int regNum, uint32_t value) {
3096 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3097 _registers.__r[regNum - UNW_MIPS_R0] = value;
3100 #if defined(__mips_hard_float) && __mips_fpr == 32
3101 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31) {
3104 if (regNum % 2 == 0)
3105 p = (uint32_t *)&_floats[regNum - UNW_MIPS_F0];
3107 p = (uint32_t *)&_floats[(regNum - 1) - UNW_MIPS_F0] + 1;
3115 _registers.__pc = value;
3118 _registers.__r[29] = value;
3121 _registers.__hi = value;
3124 _registers.__lo = value;
3127 _LIBUNWIND_ABORT("unsupported mips_o32 register");
3130 inline bool Registers_mips_o32::validFloatRegister(int regNum) const {
3131 #if defined(__mips_hard_float) && __mips_fpr == 64
3132 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3138 inline double Registers_mips_o32::getFloatRegister(int regNum) const {
3139 #if defined(__mips_hard_float) && __mips_fpr == 64
3140 assert(validFloatRegister(regNum));
3141 return _floats[regNum - UNW_MIPS_F0];
3143 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
3147 inline void Registers_mips_o32::setFloatRegister(int regNum,
3149 #if defined(__mips_hard_float) && __mips_fpr == 64
3150 assert(validFloatRegister(regNum));
3151 _floats[regNum - UNW_MIPS_F0] = value;
3153 _LIBUNWIND_ABORT("mips_o32 float support not implemented");
3157 inline bool Registers_mips_o32::validVectorRegister(int /* regNum */) const {
3161 inline v128 Registers_mips_o32::getVectorRegister(int /* regNum */) const {
3162 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3165 inline void Registers_mips_o32::setVectorRegister(int /* regNum */, v128 /* value */) {
3166 _LIBUNWIND_ABORT("mips_o32 vector support not implemented");
3169 inline const char *Registers_mips_o32::getRegisterName(int regNum) {
3304 return "unknown register";
3307 #endif // _LIBUNWIND_TARGET_MIPS_O32
3309 #if defined(_LIBUNWIND_TARGET_MIPS_NEWABI)
3310 /// Registers_mips_newabi holds the register state of a thread in a
3311 /// MIPS process using NEWABI (the N32 or N64 ABIs).
3312 class _LIBUNWIND_HIDDEN Registers_mips_newabi {
3314 Registers_mips_newabi();
3315 Registers_mips_newabi(const void *registers);
3317 bool validRegister(int num) const;
3318 uint64_t getRegister(int num) const;
3319 void setRegister(int num, uint64_t value);
3320 bool validFloatRegister(int num) const;
3321 double getFloatRegister(int num) const;
3322 void setFloatRegister(int num, double value);
3323 bool validVectorRegister(int num) const;
3324 v128 getVectorRegister(int num) const;
3325 void setVectorRegister(int num, v128 value);
3326 static const char *getRegisterName(int num);
3328 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS; }
3329 static int getArch() { return REGISTERS_MIPS_NEWABI; }
3331 uint64_t getSP() const { return _registers.__r[29]; }
3332 void setSP(uint64_t value) { _registers.__r[29] = value; }
3333 uint64_t getIP() const { return _registers.__pc; }
3334 void setIP(uint64_t value) { _registers.__pc = value; }
3337 struct mips_newabi_thread_state_t {
3344 mips_newabi_thread_state_t _registers;
3345 #ifdef __mips_hard_float
3350 inline Registers_mips_newabi::Registers_mips_newabi(const void *registers) {
3351 static_assert((check_fit<Registers_mips_newabi, unw_context_t>::does_fit),
3352 "mips_newabi registers do not fit into unw_context_t");
3353 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3354 sizeof(_registers));
3357 inline Registers_mips_newabi::Registers_mips_newabi() {
3358 memset(&_registers, 0, sizeof(_registers));
3361 inline bool Registers_mips_newabi::validRegister(int regNum) const {
3362 if (regNum == UNW_REG_IP)
3364 if (regNum == UNW_REG_SP)
3368 if (regNum <= UNW_MIPS_R31)
3370 #if __mips_isa_rev != 6
3371 if (regNum == UNW_MIPS_HI)
3373 if (regNum == UNW_MIPS_LO)
3376 // FIXME: Hard float, DSP accumulator registers, MSA registers
3380 inline uint64_t Registers_mips_newabi::getRegister(int regNum) const {
3381 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31)
3382 return _registers.__r[regNum - UNW_MIPS_R0];
3386 return _registers.__pc;
3388 return _registers.__r[29];
3390 return _registers.__hi;
3392 return _registers.__lo;
3394 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3397 inline void Registers_mips_newabi::setRegister(int regNum, uint64_t value) {
3398 if (regNum >= UNW_MIPS_R0 && regNum <= UNW_MIPS_R31) {
3399 _registers.__r[regNum - UNW_MIPS_R0] = value;
3405 _registers.__pc = value;
3408 _registers.__r[29] = value;
3411 _registers.__hi = value;
3414 _registers.__lo = value;
3417 _LIBUNWIND_ABORT("unsupported mips_newabi register");
3420 inline bool Registers_mips_newabi::validFloatRegister(int regNum) const {
3421 #ifdef __mips_hard_float
3422 if (regNum >= UNW_MIPS_F0 && regNum <= UNW_MIPS_F31)
3428 inline double Registers_mips_newabi::getFloatRegister(int regNum) const {
3429 #ifdef __mips_hard_float
3430 assert(validFloatRegister(regNum));
3431 return _floats[regNum - UNW_MIPS_F0];
3433 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3437 inline void Registers_mips_newabi::setFloatRegister(int regNum,
3439 #ifdef __mips_hard_float
3440 assert(validFloatRegister(regNum));
3441 _floats[regNum - UNW_MIPS_F0] = value;
3443 _LIBUNWIND_ABORT("mips_newabi float support not implemented");
3447 inline bool Registers_mips_newabi::validVectorRegister(int /* regNum */) const {
3451 inline v128 Registers_mips_newabi::getVectorRegister(int /* regNum */) const {
3452 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3455 inline void Registers_mips_newabi::setVectorRegister(int /* regNum */, v128 /* value */) {
3456 _LIBUNWIND_ABORT("mips_newabi vector support not implemented");
3459 inline const char *Registers_mips_newabi::getRegisterName(int regNum) {
3594 return "unknown register";
3597 #endif // _LIBUNWIND_TARGET_MIPS_NEWABI
3599 #if defined(_LIBUNWIND_TARGET_SPARC)
3600 /// Registers_sparc holds the register state of a thread in a 32-bit Sparc
3602 class _LIBUNWIND_HIDDEN Registers_sparc {
3605 Registers_sparc(const void *registers);
3607 bool validRegister(int num) const;
3608 uint32_t getRegister(int num) const;
3609 void setRegister(int num, uint32_t value);
3610 bool validFloatRegister(int num) const;
3611 double getFloatRegister(int num) const;
3612 void setFloatRegister(int num, double value);
3613 bool validVectorRegister(int num) const;
3614 v128 getVectorRegister(int num) const;
3615 void setVectorRegister(int num, v128 value);
3616 static const char *getRegisterName(int num);
3618 static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC; }
3619 static int getArch() { return REGISTERS_SPARC; }
3621 uint64_t getSP() const { return _registers.__regs[UNW_SPARC_O6]; }
3622 void setSP(uint32_t value) { _registers.__regs[UNW_SPARC_O6] = value; }
3623 uint64_t getIP() const { return _registers.__regs[UNW_SPARC_O7]; }
3624 void setIP(uint32_t value) { _registers.__regs[UNW_SPARC_O7] = value; }
3627 struct sparc_thread_state_t {
3628 unsigned int __regs[32];
3631 sparc_thread_state_t _registers;
3634 inline Registers_sparc::Registers_sparc(const void *registers) {
3635 static_assert((check_fit<Registers_sparc, unw_context_t>::does_fit),
3636 "sparc registers do not fit into unw_context_t");
3637 memcpy(&_registers, static_cast<const uint8_t *>(registers),
3638 sizeof(_registers));
3641 inline Registers_sparc::Registers_sparc() {
3642 memset(&_registers, 0, sizeof(_registers));
3645 inline bool Registers_sparc::validRegister(int regNum) const {
3646 if (regNum == UNW_REG_IP)
3648 if (regNum == UNW_REG_SP)
3652 if (regNum <= UNW_SPARC_I7)
3657 inline uint32_t Registers_sparc::getRegister(int regNum) const {
3658 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3659 return _registers.__regs[regNum];
3664 return _registers.__regs[UNW_SPARC_O7];
3666 return _registers.__regs[UNW_SPARC_O6];
3668 _LIBUNWIND_ABORT("unsupported sparc register");
3671 inline void Registers_sparc::setRegister(int regNum, uint32_t value) {
3672 if ((UNW_SPARC_G0 <= regNum) && (regNum <= UNW_SPARC_I7)) {
3673 _registers.__regs[regNum] = value;
3679 _registers.__regs[UNW_SPARC_O7] = value;
3682 _registers.__regs[UNW_SPARC_O6] = value;
3685 _LIBUNWIND_ABORT("unsupported sparc register");
3688 inline bool Registers_sparc::validFloatRegister(int) const { return false; }
3690 inline double Registers_sparc::getFloatRegister(int) const {
3691 _LIBUNWIND_ABORT("no Sparc float registers");
3694 inline void Registers_sparc::setFloatRegister(int, double) {
3695 _LIBUNWIND_ABORT("no Sparc float registers");
3698 inline bool Registers_sparc::validVectorRegister(int) const { return false; }
3700 inline v128 Registers_sparc::getVectorRegister(int) const {
3701 _LIBUNWIND_ABORT("no Sparc vector registers");
3704 inline void Registers_sparc::setVectorRegister(int, v128) {
3705 _LIBUNWIND_ABORT("no Sparc vector registers");
3708 inline const char *Registers_sparc::getRegisterName(int regNum) {
3778 return "unknown register";
3781 #endif // _LIBUNWIND_TARGET_SPARC
3783 } // namespace libunwind
3785 #endif // __REGISTERS_HPP__