xref: /netbsd/sys/lib/libunwind/Registers.hpp (revision aa0b96d0)
1*aa0b96d0Sjoerg //===----------------------------- Registers.hpp --------------------------===//
2*aa0b96d0Sjoerg //
3*aa0b96d0Sjoerg //                     The LLVM Compiler Infrastructure
4*aa0b96d0Sjoerg //
5*aa0b96d0Sjoerg // This file is dual licensed under the MIT and the University of Illinois Open
6*aa0b96d0Sjoerg // Source Licenses. See LICENSE.TXT for details.
7*aa0b96d0Sjoerg //
8*aa0b96d0Sjoerg //
9*aa0b96d0Sjoerg //  Models register sets for supported processors.
10*aa0b96d0Sjoerg //
11*aa0b96d0Sjoerg //===----------------------------------------------------------------------===//
12*aa0b96d0Sjoerg #ifndef __REGISTERS_HPP__
13*aa0b96d0Sjoerg #define __REGISTERS_HPP__
14*aa0b96d0Sjoerg 
15*aa0b96d0Sjoerg #include <cassert>
16*aa0b96d0Sjoerg #include <cstdint>
17*aa0b96d0Sjoerg 
18*aa0b96d0Sjoerg namespace _Unwind {
19*aa0b96d0Sjoerg 
20*aa0b96d0Sjoerg enum {
21*aa0b96d0Sjoerg   REGNO_X86_EAX = 0,
22*aa0b96d0Sjoerg   REGNO_X86_ECX = 1,
23*aa0b96d0Sjoerg   REGNO_X86_EDX = 2,
24*aa0b96d0Sjoerg   REGNO_X86_EBX = 3,
25*aa0b96d0Sjoerg   REGNO_X86_ESP = 4,
26*aa0b96d0Sjoerg   REGNO_X86_EBP = 5,
27*aa0b96d0Sjoerg   REGNO_X86_ESI = 6,
28*aa0b96d0Sjoerg   REGNO_X86_EDI = 7,
29*aa0b96d0Sjoerg   REGNO_X86_EIP = 8,
30*aa0b96d0Sjoerg };
31*aa0b96d0Sjoerg 
32*aa0b96d0Sjoerg class Registers_x86 {
33*aa0b96d0Sjoerg public:
34*aa0b96d0Sjoerg   enum {
35*aa0b96d0Sjoerg     LAST_RESTORE_REG = REGNO_X86_EIP,
36*aa0b96d0Sjoerg     IP_PSEUDO_REG = REGNO_X86_EIP,
37*aa0b96d0Sjoerg     LAST_REGISTER = REGNO_X86_EIP,
38*aa0b96d0Sjoerg   };
39*aa0b96d0Sjoerg 
40*aa0b96d0Sjoerg   __dso_hidden Registers_x86();
41*aa0b96d0Sjoerg 
42*aa0b96d0Sjoerg   static int dwarf2regno(int num) { return num; }
43*aa0b96d0Sjoerg 
44*aa0b96d0Sjoerg   bool validRegister(int num) const {
45*aa0b96d0Sjoerg     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
46*aa0b96d0Sjoerg   }
47*aa0b96d0Sjoerg 
48*aa0b96d0Sjoerg   uint32_t getRegister(int num) const {
49*aa0b96d0Sjoerg     assert(validRegister(num));
50*aa0b96d0Sjoerg     return reg[num];
51*aa0b96d0Sjoerg   }
52*aa0b96d0Sjoerg 
53*aa0b96d0Sjoerg   void setRegister(int num, uint32_t value) {
54*aa0b96d0Sjoerg     assert(validRegister(num));
55*aa0b96d0Sjoerg     reg[num] = value;
56*aa0b96d0Sjoerg   }
57*aa0b96d0Sjoerg 
58*aa0b96d0Sjoerg   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
59*aa0b96d0Sjoerg 
60*aa0b96d0Sjoerg   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
61*aa0b96d0Sjoerg 
62*aa0b96d0Sjoerg   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
63*aa0b96d0Sjoerg 
64*aa0b96d0Sjoerg   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
65*aa0b96d0Sjoerg 
66*aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
67*aa0b96d0Sjoerg 
68*aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint32_t addr) {
69*aa0b96d0Sjoerg   }
70*aa0b96d0Sjoerg 
71*aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
72*aa0b96d0Sjoerg 
73*aa0b96d0Sjoerg private:
74*aa0b96d0Sjoerg   uint32_t reg[REGNO_X86_EIP + 1];
75*aa0b96d0Sjoerg };
76*aa0b96d0Sjoerg 
77*aa0b96d0Sjoerg enum {
78*aa0b96d0Sjoerg   REGNO_X86_64_RAX = 0,
79*aa0b96d0Sjoerg   REGNO_X86_64_RDX = 1,
80*aa0b96d0Sjoerg   REGNO_X86_64_RCX = 2,
81*aa0b96d0Sjoerg   REGNO_X86_64_RBX = 3,
82*aa0b96d0Sjoerg   REGNO_X86_64_RSI = 4,
83*aa0b96d0Sjoerg   REGNO_X86_64_RDI = 5,
84*aa0b96d0Sjoerg   REGNO_X86_64_RBP = 6,
85*aa0b96d0Sjoerg   REGNO_X86_64_RSP = 7,
86*aa0b96d0Sjoerg   REGNO_X86_64_R8 = 8,
87*aa0b96d0Sjoerg   REGNO_X86_64_R9 = 9,
88*aa0b96d0Sjoerg   REGNO_X86_64_R10 = 10,
89*aa0b96d0Sjoerg   REGNO_X86_64_R11 = 11,
90*aa0b96d0Sjoerg   REGNO_X86_64_R12 = 12,
91*aa0b96d0Sjoerg   REGNO_X86_64_R13 = 13,
92*aa0b96d0Sjoerg   REGNO_X86_64_R14 = 14,
93*aa0b96d0Sjoerg   REGNO_X86_64_R15 = 15,
94*aa0b96d0Sjoerg   REGNO_X86_64_RIP = 16,
95*aa0b96d0Sjoerg };
96*aa0b96d0Sjoerg 
97*aa0b96d0Sjoerg class Registers_x86_64 {
98*aa0b96d0Sjoerg public:
99*aa0b96d0Sjoerg   enum {
100*aa0b96d0Sjoerg     LAST_RESTORE_REG = REGNO_X86_64_RIP,
101*aa0b96d0Sjoerg     IP_PSEUDO_REG = REGNO_X86_64_RIP,
102*aa0b96d0Sjoerg     LAST_REGISTER = REGNO_X86_64_RIP,
103*aa0b96d0Sjoerg   };
104*aa0b96d0Sjoerg 
105*aa0b96d0Sjoerg   __dso_hidden Registers_x86_64();
106*aa0b96d0Sjoerg 
107*aa0b96d0Sjoerg   static int dwarf2regno(int num) { return num; }
108*aa0b96d0Sjoerg 
109*aa0b96d0Sjoerg   bool validRegister(int num) const {
110*aa0b96d0Sjoerg     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
111*aa0b96d0Sjoerg   }
112*aa0b96d0Sjoerg 
113*aa0b96d0Sjoerg   uint64_t getRegister(int num) const {
114*aa0b96d0Sjoerg     assert(validRegister(num));
115*aa0b96d0Sjoerg     return reg[num];
116*aa0b96d0Sjoerg   }
117*aa0b96d0Sjoerg 
118*aa0b96d0Sjoerg   void setRegister(int num, uint64_t value) {
119*aa0b96d0Sjoerg     assert(validRegister(num));
120*aa0b96d0Sjoerg     reg[num] = value;
121*aa0b96d0Sjoerg   }
122*aa0b96d0Sjoerg 
123*aa0b96d0Sjoerg   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
124*aa0b96d0Sjoerg 
125*aa0b96d0Sjoerg   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
126*aa0b96d0Sjoerg 
127*aa0b96d0Sjoerg   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
128*aa0b96d0Sjoerg 
129*aa0b96d0Sjoerg   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
130*aa0b96d0Sjoerg 
131*aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
132*aa0b96d0Sjoerg 
133*aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr) {
134*aa0b96d0Sjoerg   }
135*aa0b96d0Sjoerg 
136*aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
137*aa0b96d0Sjoerg 
138*aa0b96d0Sjoerg private:
139*aa0b96d0Sjoerg   uint64_t reg[REGNO_X86_64_RIP + 1];
140*aa0b96d0Sjoerg };
141*aa0b96d0Sjoerg 
142*aa0b96d0Sjoerg enum {
143*aa0b96d0Sjoerg   DWARF_PPC32_R0 = 0,
144*aa0b96d0Sjoerg   DWARF_PPC32_R31 = 31,
145*aa0b96d0Sjoerg   DWARF_PPC32_F0 = 32,
146*aa0b96d0Sjoerg   DWARF_PPC32_F31 = 63,
147*aa0b96d0Sjoerg   DWARF_PPC32_V0 = 1124,
148*aa0b96d0Sjoerg   DWARF_PPC32_V31 = 1155,
149*aa0b96d0Sjoerg   DWARF_PPC32_LR = 65,
150*aa0b96d0Sjoerg   DWARF_PPC32_CTR = 66,
151*aa0b96d0Sjoerg   DWARF_PPC32_XER = 76,
152*aa0b96d0Sjoerg   REGNO_PPC32_R0 = 0,
153*aa0b96d0Sjoerg   REGNO_PPC32_R1 = 0,
154*aa0b96d0Sjoerg   REGNO_PPC32_R31 = 31,
155*aa0b96d0Sjoerg   REGNO_PPC32_CR = 32,
156*aa0b96d0Sjoerg   REGNO_PPC32_LR = 33,
157*aa0b96d0Sjoerg   REGNO_PPC32_CTR = 34,
158*aa0b96d0Sjoerg   REGNO_PPC32_XER = 35,
159*aa0b96d0Sjoerg   REGNO_PPC32_SRR0 = 36,
160*aa0b96d0Sjoerg   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
161*aa0b96d0Sjoerg   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
162*aa0b96d0Sjoerg   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
163*aa0b96d0Sjoerg   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
164*aa0b96d0Sjoerg };
165*aa0b96d0Sjoerg 
166*aa0b96d0Sjoerg class Registers_ppc32 {
167*aa0b96d0Sjoerg public:
168*aa0b96d0Sjoerg   enum {
169*aa0b96d0Sjoerg     LAST_RESTORE_REG = REGNO_PPC32_V31,
170*aa0b96d0Sjoerg     IP_PSEUDO_REG = REGNO_PPC32_SRR0,
171*aa0b96d0Sjoerg     LAST_REGISTER = REGNO_PPC32_V31,
172*aa0b96d0Sjoerg   };
173*aa0b96d0Sjoerg 
174*aa0b96d0Sjoerg   __dso_hidden Registers_ppc32();
175*aa0b96d0Sjoerg 
176*aa0b96d0Sjoerg   static int dwarf2regno(int num) {
177*aa0b96d0Sjoerg     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
178*aa0b96d0Sjoerg       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
179*aa0b96d0Sjoerg     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
180*aa0b96d0Sjoerg       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
181*aa0b96d0Sjoerg     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
182*aa0b96d0Sjoerg       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
183*aa0b96d0Sjoerg     return LAST_REGISTER + 1;
184*aa0b96d0Sjoerg   }
185*aa0b96d0Sjoerg 
186*aa0b96d0Sjoerg   bool validRegister(int num) const {
187*aa0b96d0Sjoerg     return num >= 0 && num <= LAST_RESTORE_REG;
188*aa0b96d0Sjoerg   }
189*aa0b96d0Sjoerg 
190*aa0b96d0Sjoerg   uint64_t getRegister(int num) const {
191*aa0b96d0Sjoerg     assert(validRegister(num));
192*aa0b96d0Sjoerg     return reg[num];
193*aa0b96d0Sjoerg   }
194*aa0b96d0Sjoerg 
195*aa0b96d0Sjoerg   void setRegister(int num, uint64_t value) {
196*aa0b96d0Sjoerg     assert(validRegister(num));
197*aa0b96d0Sjoerg     reg[num] = value;
198*aa0b96d0Sjoerg   }
199*aa0b96d0Sjoerg 
200*aa0b96d0Sjoerg   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
201*aa0b96d0Sjoerg 
202*aa0b96d0Sjoerg   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
203*aa0b96d0Sjoerg 
204*aa0b96d0Sjoerg   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
205*aa0b96d0Sjoerg 
206*aa0b96d0Sjoerg   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
207*aa0b96d0Sjoerg 
208*aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const {
209*aa0b96d0Sjoerg     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
210*aa0b96d0Sjoerg            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
211*aa0b96d0Sjoerg   }
212*aa0b96d0Sjoerg 
213*aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
214*aa0b96d0Sjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
215*aa0b96d0Sjoerg     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
216*aa0b96d0Sjoerg       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
217*aa0b96d0Sjoerg     else
218*aa0b96d0Sjoerg       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
219*aa0b96d0Sjoerg   }
220*aa0b96d0Sjoerg 
221*aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
222*aa0b96d0Sjoerg 
223*aa0b96d0Sjoerg private:
224*aa0b96d0Sjoerg   struct vecreg_t {
225*aa0b96d0Sjoerg     uint64_t low, high;
226*aa0b96d0Sjoerg   };
227*aa0b96d0Sjoerg   uint32_t reg[REGNO_PPC32_SRR0 + 1];
228*aa0b96d0Sjoerg   uint64_t fpreg[32];
229*aa0b96d0Sjoerg   vecreg_t vecreg[64];
230*aa0b96d0Sjoerg };
231*aa0b96d0Sjoerg 
232*aa0b96d0Sjoerg } // namespace _Unwind
233*aa0b96d0Sjoerg 
234*aa0b96d0Sjoerg #endif // __REGISTERS_HPP__
235