Registers.hpp revision 1.17.4.3 1 1.17.4.2 tls //===----------------------------- Registers.hpp --------------------------===//
2 1.17.4.2 tls //
3 1.17.4.2 tls // The LLVM Compiler Infrastructure
4 1.17.4.2 tls //
5 1.17.4.2 tls // This file is dual licensed under the MIT and the University of Illinois Open
6 1.17.4.2 tls // Source Licenses. See LICENSE.TXT for details.
7 1.17.4.2 tls //
8 1.17.4.2 tls //
9 1.17.4.2 tls // Models register sets for supported processors.
10 1.17.4.2 tls //
11 1.17.4.2 tls //===----------------------------------------------------------------------===//
12 1.17.4.2 tls #ifndef __REGISTERS_HPP__
13 1.17.4.2 tls #define __REGISTERS_HPP__
14 1.17.4.2 tls
15 1.17.4.3 jdolecek #include <sys/endian.h>
16 1.17.4.2 tls #include <cassert>
17 1.17.4.2 tls #include <cstdint>
18 1.17.4.2 tls
19 1.17.4.2 tls namespace _Unwind {
20 1.17.4.2 tls
21 1.17.4.2 tls enum {
22 1.17.4.2 tls REGNO_X86_EAX = 0,
23 1.17.4.2 tls REGNO_X86_ECX = 1,
24 1.17.4.2 tls REGNO_X86_EDX = 2,
25 1.17.4.2 tls REGNO_X86_EBX = 3,
26 1.17.4.2 tls REGNO_X86_ESP = 4,
27 1.17.4.2 tls REGNO_X86_EBP = 5,
28 1.17.4.2 tls REGNO_X86_ESI = 6,
29 1.17.4.2 tls REGNO_X86_EDI = 7,
30 1.17.4.2 tls REGNO_X86_EIP = 8,
31 1.17.4.2 tls };
32 1.17.4.2 tls
33 1.17.4.2 tls class Registers_x86 {
34 1.17.4.2 tls public:
35 1.17.4.2 tls enum {
36 1.17.4.2 tls LAST_REGISTER = REGNO_X86_EIP,
37 1.17.4.2 tls LAST_RESTORE_REG = REGNO_X86_EIP,
38 1.17.4.2 tls RETURN_OFFSET = 0,
39 1.17.4.3 jdolecek RETURN_MASK = 0,
40 1.17.4.2 tls };
41 1.17.4.2 tls
42 1.17.4.2 tls __dso_hidden Registers_x86();
43 1.17.4.2 tls
44 1.17.4.2 tls static int dwarf2regno(int num) { return num; }
45 1.17.4.2 tls
46 1.17.4.2 tls bool validRegister(int num) const {
47 1.17.4.2 tls return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
48 1.17.4.2 tls }
49 1.17.4.2 tls
50 1.17.4.2 tls uint32_t getRegister(int num) const {
51 1.17.4.2 tls assert(validRegister(num));
52 1.17.4.2 tls return reg[num];
53 1.17.4.2 tls }
54 1.17.4.2 tls
55 1.17.4.2 tls void setRegister(int num, uint32_t value) {
56 1.17.4.2 tls assert(validRegister(num));
57 1.17.4.2 tls reg[num] = value;
58 1.17.4.2 tls }
59 1.17.4.2 tls
60 1.17.4.2 tls uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
61 1.17.4.2 tls
62 1.17.4.2 tls void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
63 1.17.4.2 tls
64 1.17.4.2 tls uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
65 1.17.4.2 tls
66 1.17.4.2 tls void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
67 1.17.4.2 tls
68 1.17.4.2 tls bool validFloatVectorRegister(int num) const { return false; }
69 1.17.4.2 tls
70 1.17.4.2 tls void copyFloatVectorRegister(int num, uint32_t addr) {
71 1.17.4.2 tls }
72 1.17.4.2 tls
73 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
74 1.17.4.2 tls
75 1.17.4.2 tls private:
76 1.17.4.2 tls uint32_t reg[REGNO_X86_EIP + 1];
77 1.17.4.2 tls };
78 1.17.4.2 tls
79 1.17.4.2 tls enum {
80 1.17.4.2 tls REGNO_X86_64_RAX = 0,
81 1.17.4.2 tls REGNO_X86_64_RDX = 1,
82 1.17.4.2 tls REGNO_X86_64_RCX = 2,
83 1.17.4.2 tls REGNO_X86_64_RBX = 3,
84 1.17.4.2 tls REGNO_X86_64_RSI = 4,
85 1.17.4.2 tls REGNO_X86_64_RDI = 5,
86 1.17.4.2 tls REGNO_X86_64_RBP = 6,
87 1.17.4.2 tls REGNO_X86_64_RSP = 7,
88 1.17.4.2 tls REGNO_X86_64_R8 = 8,
89 1.17.4.2 tls REGNO_X86_64_R9 = 9,
90 1.17.4.2 tls REGNO_X86_64_R10 = 10,
91 1.17.4.2 tls REGNO_X86_64_R11 = 11,
92 1.17.4.2 tls REGNO_X86_64_R12 = 12,
93 1.17.4.2 tls REGNO_X86_64_R13 = 13,
94 1.17.4.2 tls REGNO_X86_64_R14 = 14,
95 1.17.4.2 tls REGNO_X86_64_R15 = 15,
96 1.17.4.2 tls REGNO_X86_64_RIP = 16,
97 1.17.4.2 tls };
98 1.17.4.2 tls
99 1.17.4.2 tls class Registers_x86_64 {
100 1.17.4.2 tls public:
101 1.17.4.2 tls enum {
102 1.17.4.2 tls LAST_REGISTER = REGNO_X86_64_RIP,
103 1.17.4.2 tls LAST_RESTORE_REG = REGNO_X86_64_RIP,
104 1.17.4.2 tls RETURN_OFFSET = 0,
105 1.17.4.3 jdolecek RETURN_MASK = 0,
106 1.17.4.2 tls };
107 1.17.4.2 tls
108 1.17.4.2 tls __dso_hidden Registers_x86_64();
109 1.17.4.2 tls
110 1.17.4.2 tls static int dwarf2regno(int num) { return num; }
111 1.17.4.2 tls
112 1.17.4.2 tls bool validRegister(int num) const {
113 1.17.4.2 tls return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
114 1.17.4.2 tls }
115 1.17.4.2 tls
116 1.17.4.2 tls uint64_t getRegister(int num) const {
117 1.17.4.2 tls assert(validRegister(num));
118 1.17.4.2 tls return reg[num];
119 1.17.4.2 tls }
120 1.17.4.2 tls
121 1.17.4.2 tls void setRegister(int num, uint64_t value) {
122 1.17.4.2 tls assert(validRegister(num));
123 1.17.4.2 tls reg[num] = value;
124 1.17.4.2 tls }
125 1.17.4.2 tls
126 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
127 1.17.4.2 tls
128 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
129 1.17.4.2 tls
130 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
131 1.17.4.2 tls
132 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
133 1.17.4.2 tls
134 1.17.4.2 tls bool validFloatVectorRegister(int num) const { return false; }
135 1.17.4.2 tls
136 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr) {
137 1.17.4.2 tls }
138 1.17.4.2 tls
139 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
140 1.17.4.2 tls
141 1.17.4.2 tls private:
142 1.17.4.2 tls uint64_t reg[REGNO_X86_64_RIP + 1];
143 1.17.4.2 tls };
144 1.17.4.2 tls
145 1.17.4.2 tls enum {
146 1.17.4.2 tls DWARF_PPC32_R0 = 0,
147 1.17.4.2 tls DWARF_PPC32_R31 = 31,
148 1.17.4.2 tls DWARF_PPC32_F0 = 32,
149 1.17.4.2 tls DWARF_PPC32_F31 = 63,
150 1.17.4.2 tls DWARF_PPC32_LR = 65,
151 1.17.4.2 tls DWARF_PPC32_CR = 70,
152 1.17.4.2 tls DWARF_PPC32_V0 = 77,
153 1.17.4.2 tls DWARF_PPC32_V31 = 108,
154 1.17.4.2 tls
155 1.17.4.2 tls REGNO_PPC32_R0 = 0,
156 1.17.4.2 tls REGNO_PPC32_R1 = 1,
157 1.17.4.2 tls REGNO_PPC32_R31 = 31,
158 1.17.4.2 tls REGNO_PPC32_LR = 32,
159 1.17.4.2 tls REGNO_PPC32_CR = 33,
160 1.17.4.2 tls REGNO_PPC32_SRR0 = 34,
161 1.17.4.2 tls
162 1.17.4.2 tls REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
163 1.17.4.2 tls REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
164 1.17.4.2 tls REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
165 1.17.4.2 tls REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
166 1.17.4.2 tls };
167 1.17.4.2 tls
168 1.17.4.2 tls class Registers_ppc32 {
169 1.17.4.2 tls public:
170 1.17.4.2 tls enum {
171 1.17.4.2 tls LAST_REGISTER = REGNO_PPC32_V31,
172 1.17.4.2 tls LAST_RESTORE_REG = REGNO_PPC32_V31,
173 1.17.4.2 tls RETURN_OFFSET = 0,
174 1.17.4.3 jdolecek RETURN_MASK = 0,
175 1.17.4.2 tls };
176 1.17.4.2 tls
177 1.17.4.2 tls __dso_hidden Registers_ppc32();
178 1.17.4.2 tls
179 1.17.4.2 tls static int dwarf2regno(int num) {
180 1.17.4.2 tls if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
181 1.17.4.2 tls return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
182 1.17.4.2 tls if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
183 1.17.4.2 tls return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
184 1.17.4.2 tls if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
185 1.17.4.2 tls return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
186 1.17.4.2 tls switch (num) {
187 1.17.4.2 tls case DWARF_PPC32_LR:
188 1.17.4.2 tls return REGNO_PPC32_LR;
189 1.17.4.2 tls case DWARF_PPC32_CR:
190 1.17.4.2 tls return REGNO_PPC32_CR;
191 1.17.4.2 tls default:
192 1.17.4.2 tls return LAST_REGISTER + 1;
193 1.17.4.2 tls }
194 1.17.4.2 tls }
195 1.17.4.2 tls
196 1.17.4.2 tls bool validRegister(int num) const {
197 1.17.4.2 tls return num >= 0 && num <= LAST_RESTORE_REG;
198 1.17.4.2 tls }
199 1.17.4.2 tls
200 1.17.4.2 tls uint64_t getRegister(int num) const {
201 1.17.4.2 tls assert(validRegister(num));
202 1.17.4.2 tls return reg[num];
203 1.17.4.2 tls }
204 1.17.4.2 tls
205 1.17.4.2 tls void setRegister(int num, uint64_t value) {
206 1.17.4.2 tls assert(validRegister(num));
207 1.17.4.2 tls reg[num] = value;
208 1.17.4.2 tls }
209 1.17.4.2 tls
210 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
211 1.17.4.2 tls
212 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
213 1.17.4.2 tls
214 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
215 1.17.4.2 tls
216 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
217 1.17.4.2 tls
218 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
219 1.17.4.2 tls return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
220 1.17.4.2 tls (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
221 1.17.4.2 tls }
222 1.17.4.2 tls
223 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
224 1.17.4.2 tls const void *addr = reinterpret_cast<const void *>(addr_);
225 1.17.4.2 tls if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
226 1.17.4.2 tls memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
227 1.17.4.2 tls else
228 1.17.4.2 tls memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
229 1.17.4.2 tls }
230 1.17.4.2 tls
231 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
232 1.17.4.2 tls
233 1.17.4.2 tls private:
234 1.17.4.2 tls struct vecreg_t {
235 1.17.4.2 tls uint64_t low, high;
236 1.17.4.2 tls };
237 1.17.4.2 tls uint32_t reg[REGNO_PPC32_SRR0 + 1];
238 1.17.4.2 tls uint32_t dummy;
239 1.17.4.2 tls uint64_t fpreg[32];
240 1.17.4.2 tls vecreg_t vecreg[64];
241 1.17.4.2 tls };
242 1.17.4.2 tls
243 1.17.4.2 tls enum {
244 1.17.4.2 tls DWARF_AARCH64_X0 = 0,
245 1.17.4.2 tls DWARF_AARCH64_X30 = 30,
246 1.17.4.2 tls DWARF_AARCH64_SP = 31,
247 1.17.4.2 tls DWARF_AARCH64_ELR_MODE = 33,
248 1.17.4.2 tls DWARF_AARCH64_V0 = 64,
249 1.17.4.2 tls DWARF_AARCH64_V31 = 95,
250 1.17.4.2 tls
251 1.17.4.2 tls REGNO_AARCH64_X0 = 0,
252 1.17.4.2 tls REGNO_AARCH64_X30 = 30,
253 1.17.4.2 tls REGNO_AARCH64_SP = 31,
254 1.17.4.2 tls REGNO_AARCH64_ELR_MODE = 32,
255 1.17.4.2 tls REGNO_AARCH64_V0 = 33,
256 1.17.4.2 tls REGNO_AARCH64_V31 = 64,
257 1.17.4.2 tls };
258 1.17.4.2 tls
259 1.17.4.2 tls class Registers_aarch64 {
260 1.17.4.2 tls public:
261 1.17.4.2 tls enum {
262 1.17.4.2 tls LAST_RESTORE_REG = REGNO_AARCH64_V31,
263 1.17.4.2 tls LAST_REGISTER = REGNO_AARCH64_V31,
264 1.17.4.2 tls RETURN_OFFSET = 0,
265 1.17.4.3 jdolecek RETURN_MASK = 0,
266 1.17.4.2 tls };
267 1.17.4.2 tls
268 1.17.4.2 tls __dso_hidden Registers_aarch64();
269 1.17.4.2 tls
270 1.17.4.2 tls static int dwarf2regno(int num) {
271 1.17.4.2 tls if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
272 1.17.4.2 tls return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
273 1.17.4.2 tls if (num == DWARF_AARCH64_SP)
274 1.17.4.2 tls return REGNO_AARCH64_SP;
275 1.17.4.2 tls if (num == DWARF_AARCH64_ELR_MODE)
276 1.17.4.2 tls return REGNO_AARCH64_ELR_MODE;
277 1.17.4.2 tls if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
278 1.17.4.2 tls return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
279 1.17.4.2 tls return LAST_REGISTER + 1;
280 1.17.4.2 tls }
281 1.17.4.2 tls
282 1.17.4.2 tls bool validRegister(int num) const {
283 1.17.4.2 tls return num >= 0 && num <= LAST_RESTORE_REG;
284 1.17.4.2 tls }
285 1.17.4.2 tls
286 1.17.4.2 tls uint64_t getRegister(int num) const {
287 1.17.4.2 tls assert(validRegister(num));
288 1.17.4.2 tls return reg[num];
289 1.17.4.2 tls }
290 1.17.4.2 tls
291 1.17.4.2 tls void setRegister(int num, uint64_t value) {
292 1.17.4.2 tls assert(validRegister(num));
293 1.17.4.2 tls reg[num] = value;
294 1.17.4.2 tls }
295 1.17.4.2 tls
296 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
297 1.17.4.2 tls
298 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
299 1.17.4.2 tls
300 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
301 1.17.4.2 tls
302 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
303 1.17.4.2 tls
304 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
305 1.17.4.2 tls return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
306 1.17.4.2 tls }
307 1.17.4.2 tls
308 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
309 1.17.4.2 tls const void *addr = reinterpret_cast<const void *>(addr_);
310 1.17.4.2 tls memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, sizeof(vecreg[0]));
311 1.17.4.2 tls }
312 1.17.4.2 tls
313 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
314 1.17.4.2 tls
315 1.17.4.2 tls private:
316 1.17.4.2 tls struct vecreg_t {
317 1.17.4.2 tls uint64_t low, high;
318 1.17.4.2 tls };
319 1.17.4.2 tls uint64_t reg[REGNO_AARCH64_ELR_MODE + 1];
320 1.17.4.2 tls vecreg_t vecreg[32];
321 1.17.4.2 tls };
322 1.17.4.2 tls
323 1.17.4.2 tls enum {
324 1.17.4.2 tls DWARF_ARM32_R0 = 0,
325 1.17.4.2 tls DWARF_ARM32_R15 = 15,
326 1.17.4.2 tls DWARF_ARM32_SPSR = 128,
327 1.17.4.3 jdolecek DWARF_ARM32_S0 = 64,
328 1.17.4.3 jdolecek DWARF_ARM32_S31 = 91,
329 1.17.4.2 tls DWARF_ARM32_D0 = 256,
330 1.17.4.2 tls DWARF_ARM32_D31 = 287,
331 1.17.4.2 tls REGNO_ARM32_R0 = 0,
332 1.17.4.2 tls REGNO_ARM32_SP = 13,
333 1.17.4.2 tls REGNO_ARM32_R15 = 15,
334 1.17.4.2 tls REGNO_ARM32_SPSR = 16,
335 1.17.4.2 tls REGNO_ARM32_D0 = 17,
336 1.17.4.2 tls REGNO_ARM32_D15 = 32,
337 1.17.4.2 tls REGNO_ARM32_D31 = 48,
338 1.17.4.3 jdolecek REGNO_ARM32_S0 = 49,
339 1.17.4.3 jdolecek REGNO_ARM32_S31 = 70,
340 1.17.4.2 tls };
341 1.17.4.2 tls
342 1.17.4.2 tls class Registers_arm32 {
343 1.17.4.2 tls public:
344 1.17.4.2 tls enum {
345 1.17.4.2 tls LAST_REGISTER = REGNO_ARM32_D31,
346 1.17.4.2 tls LAST_RESTORE_REG = REGNO_ARM32_D31,
347 1.17.4.2 tls RETURN_OFFSET = 0,
348 1.17.4.3 jdolecek RETURN_MASK = 0,
349 1.17.4.2 tls };
350 1.17.4.2 tls
351 1.17.4.2 tls __dso_hidden Registers_arm32();
352 1.17.4.2 tls
353 1.17.4.2 tls static int dwarf2regno(int num) {
354 1.17.4.2 tls if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
355 1.17.4.2 tls return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
356 1.17.4.2 tls if (num == DWARF_ARM32_SPSR)
357 1.17.4.2 tls return REGNO_ARM32_SPSR;
358 1.17.4.2 tls if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
359 1.17.4.2 tls return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
360 1.17.4.3 jdolecek if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31) {
361 1.17.4.3 jdolecek return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
362 1.17.4.2 tls }
363 1.17.4.2 tls return LAST_REGISTER + 1;
364 1.17.4.2 tls }
365 1.17.4.2 tls
366 1.17.4.2 tls bool validRegister(int num) const {
367 1.17.4.2 tls return num >= 0 && num <= REGNO_ARM32_SPSR;
368 1.17.4.2 tls }
369 1.17.4.2 tls
370 1.17.4.2 tls uint64_t getRegister(int num) const {
371 1.17.4.2 tls assert(validRegister(num));
372 1.17.4.2 tls return reg[num];
373 1.17.4.2 tls }
374 1.17.4.2 tls
375 1.17.4.2 tls void setRegister(int num, uint64_t value) {
376 1.17.4.2 tls assert(validRegister(num));
377 1.17.4.2 tls reg[num] = value;
378 1.17.4.2 tls }
379 1.17.4.2 tls
380 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
381 1.17.4.2 tls
382 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
383 1.17.4.2 tls
384 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
385 1.17.4.2 tls
386 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
387 1.17.4.2 tls
388 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
389 1.17.4.3 jdolecek return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
390 1.17.4.2 tls }
391 1.17.4.2 tls
392 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
393 1.17.4.3 jdolecek const void *addr = reinterpret_cast<const void *>(addr_);
394 1.17.4.3 jdolecek if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
395 1.17.4.3 jdolecek if ((flags & 1) == 0) {
396 1.17.4.3 jdolecek lazyVFP1();
397 1.17.4.3 jdolecek flags |= 1;
398 1.17.4.3 jdolecek }
399 1.17.4.3 jdolecek /*
400 1.17.4.3 jdolecek * Emulate single precision register as half of the
401 1.17.4.3 jdolecek * corresponding double register.
402 1.17.4.3 jdolecek */
403 1.17.4.3 jdolecek int dnum = (num - REGNO_ARM32_S0) / 2;
404 1.17.4.3 jdolecek int part = (num - REGNO_ARM32_S0) % 2;
405 1.17.4.3 jdolecek #if _BYTE_ORDER == _BIG_ENDIAN
406 1.17.4.3 jdolecek part = 1 - part;
407 1.17.4.3 jdolecek #endif
408 1.17.4.3 jdolecek memcpy(fpreg + dnum + part * sizeof(fpreg[0]) / 2,
409 1.17.4.3 jdolecek addr, sizeof(fpreg[0]) / 2);
410 1.17.4.3 jdolecek }
411 1.17.4.2 tls if (num <= REGNO_ARM32_D15) {
412 1.17.4.2 tls if ((flags & 1) == 0) {
413 1.17.4.2 tls lazyVFP1();
414 1.17.4.2 tls flags |= 1;
415 1.17.4.2 tls }
416 1.17.4.2 tls } else {
417 1.17.4.2 tls if ((flags & 2) == 0) {
418 1.17.4.2 tls lazyVFP3();
419 1.17.4.2 tls flags |= 2;
420 1.17.4.2 tls }
421 1.17.4.2 tls }
422 1.17.4.2 tls memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
423 1.17.4.2 tls }
424 1.17.4.2 tls
425 1.17.4.2 tls __dso_hidden void lazyVFP1();
426 1.17.4.2 tls __dso_hidden void lazyVFP3();
427 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
428 1.17.4.2 tls
429 1.17.4.2 tls private:
430 1.17.4.2 tls uint32_t reg[REGNO_ARM32_SPSR + 1];
431 1.17.4.2 tls uint32_t flags;
432 1.17.4.2 tls uint64_t fpreg[32];
433 1.17.4.2 tls };
434 1.17.4.2 tls
435 1.17.4.2 tls enum {
436 1.17.4.2 tls DWARF_VAX_R0 = 0,
437 1.17.4.2 tls DWARF_VAX_R15 = 15,
438 1.17.4.2 tls DWARF_VAX_PSW = 16,
439 1.17.4.2 tls
440 1.17.4.2 tls REGNO_VAX_R0 = 0,
441 1.17.4.2 tls REGNO_VAX_R14 = 14,
442 1.17.4.2 tls REGNO_VAX_R15 = 15,
443 1.17.4.2 tls REGNO_VAX_PSW = 16,
444 1.17.4.2 tls };
445 1.17.4.2 tls
446 1.17.4.2 tls class Registers_vax {
447 1.17.4.2 tls public:
448 1.17.4.2 tls enum {
449 1.17.4.2 tls LAST_REGISTER = REGNO_VAX_PSW,
450 1.17.4.2 tls LAST_RESTORE_REG = REGNO_VAX_PSW,
451 1.17.4.2 tls RETURN_OFFSET = 0,
452 1.17.4.3 jdolecek RETURN_MASK = 0,
453 1.17.4.2 tls };
454 1.17.4.2 tls
455 1.17.4.2 tls __dso_hidden Registers_vax();
456 1.17.4.2 tls
457 1.17.4.2 tls static int dwarf2regno(int num) {
458 1.17.4.2 tls if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
459 1.17.4.2 tls return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
460 1.17.4.2 tls if (num == DWARF_VAX_PSW)
461 1.17.4.2 tls return REGNO_VAX_PSW;
462 1.17.4.2 tls return LAST_REGISTER + 1;
463 1.17.4.2 tls }
464 1.17.4.2 tls
465 1.17.4.2 tls bool validRegister(int num) const {
466 1.17.4.2 tls return num >= 0 && num <= LAST_RESTORE_REG;
467 1.17.4.2 tls }
468 1.17.4.2 tls
469 1.17.4.2 tls uint64_t getRegister(int num) const {
470 1.17.4.2 tls assert(validRegister(num));
471 1.17.4.2 tls return reg[num];
472 1.17.4.2 tls }
473 1.17.4.2 tls
474 1.17.4.2 tls void setRegister(int num, uint64_t value) {
475 1.17.4.2 tls assert(validRegister(num));
476 1.17.4.2 tls reg[num] = value;
477 1.17.4.2 tls }
478 1.17.4.2 tls
479 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
480 1.17.4.2 tls
481 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
482 1.17.4.2 tls
483 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
484 1.17.4.2 tls
485 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
486 1.17.4.2 tls
487 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
488 1.17.4.2 tls return false;
489 1.17.4.2 tls }
490 1.17.4.2 tls
491 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
492 1.17.4.2 tls }
493 1.17.4.2 tls
494 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
495 1.17.4.2 tls
496 1.17.4.2 tls private:
497 1.17.4.2 tls uint32_t reg[REGNO_VAX_PSW + 1];
498 1.17.4.2 tls };
499 1.17.4.2 tls
500 1.17.4.2 tls enum {
501 1.17.4.2 tls DWARF_M68K_A0 = 0,
502 1.17.4.2 tls DWARF_M68K_A7 = 7,
503 1.17.4.2 tls DWARF_M68K_D0 = 8,
504 1.17.4.2 tls DWARF_M68K_D7 = 15,
505 1.17.4.2 tls DWARF_M68K_FP0 = 16,
506 1.17.4.2 tls DWARF_M68K_FP7 = 23,
507 1.17.4.2 tls DWARF_M68K_PC = 24,
508 1.17.4.2 tls
509 1.17.4.2 tls REGNO_M68K_A0 = 0,
510 1.17.4.2 tls REGNO_M68K_A7 = 7,
511 1.17.4.2 tls REGNO_M68K_D0 = 8,
512 1.17.4.2 tls REGNO_M68K_D7 = 15,
513 1.17.4.2 tls REGNO_M68K_PC = 16,
514 1.17.4.2 tls REGNO_M68K_FP0 = 17,
515 1.17.4.2 tls REGNO_M68K_FP7 = 24,
516 1.17.4.2 tls };
517 1.17.4.2 tls
518 1.17.4.2 tls class Registers_M68K {
519 1.17.4.2 tls public:
520 1.17.4.2 tls enum {
521 1.17.4.2 tls LAST_REGISTER = REGNO_M68K_FP7,
522 1.17.4.2 tls LAST_RESTORE_REG = REGNO_M68K_FP7,
523 1.17.4.2 tls RETURN_OFFSET = 0,
524 1.17.4.3 jdolecek RETURN_MASK = 0,
525 1.17.4.2 tls };
526 1.17.4.2 tls
527 1.17.4.2 tls __dso_hidden Registers_M68K();
528 1.17.4.2 tls
529 1.17.4.2 tls static int dwarf2regno(int num) {
530 1.17.4.2 tls if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
531 1.17.4.2 tls return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
532 1.17.4.2 tls if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
533 1.17.4.2 tls return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
534 1.17.4.2 tls if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
535 1.17.4.2 tls return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
536 1.17.4.2 tls if (num == DWARF_M68K_PC)
537 1.17.4.2 tls return REGNO_M68K_PC;
538 1.17.4.2 tls return LAST_REGISTER + 1;
539 1.17.4.2 tls }
540 1.17.4.2 tls
541 1.17.4.2 tls bool validRegister(int num) const {
542 1.17.4.2 tls return num >= 0 && num <= REGNO_M68K_PC;
543 1.17.4.2 tls }
544 1.17.4.2 tls
545 1.17.4.2 tls uint64_t getRegister(int num) const {
546 1.17.4.2 tls assert(validRegister(num));
547 1.17.4.2 tls return reg[num];
548 1.17.4.2 tls }
549 1.17.4.2 tls
550 1.17.4.2 tls void setRegister(int num, uint64_t value) {
551 1.17.4.2 tls assert(validRegister(num));
552 1.17.4.2 tls reg[num] = value;
553 1.17.4.2 tls }
554 1.17.4.2 tls
555 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
556 1.17.4.2 tls
557 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
558 1.17.4.2 tls
559 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
560 1.17.4.2 tls
561 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
562 1.17.4.2 tls
563 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
564 1.17.4.2 tls return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
565 1.17.4.2 tls }
566 1.17.4.2 tls
567 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
568 1.17.4.2 tls assert(validFloatVectorRegister(num));
569 1.17.4.2 tls const void *addr = reinterpret_cast<const void *>(addr_);
570 1.17.4.2 tls memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
571 1.17.4.2 tls }
572 1.17.4.2 tls
573 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
574 1.17.4.2 tls
575 1.17.4.2 tls private:
576 1.17.4.2 tls typedef uint32_t fpreg_t[3];
577 1.17.4.2 tls
578 1.17.4.2 tls uint32_t reg[REGNO_M68K_PC + 1];
579 1.17.4.2 tls uint32_t dummy;
580 1.17.4.2 tls fpreg_t fpreg[8];
581 1.17.4.2 tls };
582 1.17.4.2 tls
583 1.17.4.2 tls enum {
584 1.17.4.2 tls DWARF_SH3_R0 = 0,
585 1.17.4.2 tls DWARF_SH3_R15 = 15,
586 1.17.4.2 tls DWARF_SH3_PC = 16,
587 1.17.4.2 tls DWARF_SH3_PR = 17,
588 1.17.4.2 tls
589 1.17.4.2 tls REGNO_SH3_R0 = 0,
590 1.17.4.2 tls REGNO_SH3_R15 = 15,
591 1.17.4.2 tls REGNO_SH3_PC = 16,
592 1.17.4.2 tls REGNO_SH3_PR = 17,
593 1.17.4.2 tls };
594 1.17.4.2 tls
595 1.17.4.2 tls class Registers_SH3 {
596 1.17.4.2 tls public:
597 1.17.4.2 tls enum {
598 1.17.4.2 tls LAST_REGISTER = REGNO_SH3_PR,
599 1.17.4.2 tls LAST_RESTORE_REG = REGNO_SH3_PR,
600 1.17.4.2 tls RETURN_OFFSET = 0,
601 1.17.4.3 jdolecek RETURN_MASK = 0,
602 1.17.4.2 tls };
603 1.17.4.2 tls
604 1.17.4.2 tls __dso_hidden Registers_SH3();
605 1.17.4.2 tls
606 1.17.4.2 tls static int dwarf2regno(int num) {
607 1.17.4.2 tls if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
608 1.17.4.2 tls return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
609 1.17.4.2 tls if (num == DWARF_SH3_PC)
610 1.17.4.2 tls return REGNO_SH3_PC;
611 1.17.4.2 tls if (num == DWARF_SH3_PR)
612 1.17.4.2 tls return REGNO_SH3_PR;
613 1.17.4.2 tls return LAST_REGISTER + 1;
614 1.17.4.2 tls }
615 1.17.4.2 tls
616 1.17.4.2 tls bool validRegister(int num) const {
617 1.17.4.2 tls return num >= 0 && num <= REGNO_SH3_PR;
618 1.17.4.2 tls }
619 1.17.4.2 tls
620 1.17.4.2 tls uint64_t getRegister(int num) const {
621 1.17.4.2 tls assert(validRegister(num));
622 1.17.4.2 tls return reg[num];
623 1.17.4.2 tls }
624 1.17.4.2 tls
625 1.17.4.2 tls void setRegister(int num, uint64_t value) {
626 1.17.4.2 tls assert(validRegister(num));
627 1.17.4.2 tls reg[num] = value;
628 1.17.4.2 tls }
629 1.17.4.2 tls
630 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
631 1.17.4.2 tls
632 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
633 1.17.4.2 tls
634 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
635 1.17.4.2 tls
636 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
637 1.17.4.2 tls
638 1.17.4.2 tls bool validFloatVectorRegister(int num) const { return false; }
639 1.17.4.2 tls
640 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {}
641 1.17.4.2 tls
642 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
643 1.17.4.2 tls
644 1.17.4.2 tls private:
645 1.17.4.2 tls uint32_t reg[REGNO_SH3_PR + 1];
646 1.17.4.2 tls };
647 1.17.4.2 tls
648 1.17.4.2 tls enum {
649 1.17.4.2 tls DWARF_SPARC64_R0 = 0,
650 1.17.4.2 tls DWARF_SPARC64_R31 = 31,
651 1.17.4.2 tls DWARF_SPARC64_PC = 32,
652 1.17.4.2 tls
653 1.17.4.2 tls REGNO_SPARC64_R0 = 0,
654 1.17.4.2 tls REGNO_SPARC64_R14 = 14,
655 1.17.4.2 tls REGNO_SPARC64_R15 = 15,
656 1.17.4.2 tls REGNO_SPARC64_R31 = 31,
657 1.17.4.2 tls REGNO_SPARC64_PC = 32,
658 1.17.4.2 tls };
659 1.17.4.2 tls
660 1.17.4.2 tls class Registers_SPARC64 {
661 1.17.4.2 tls public:
662 1.17.4.2 tls enum {
663 1.17.4.2 tls LAST_REGISTER = REGNO_SPARC64_PC,
664 1.17.4.2 tls LAST_RESTORE_REG = REGNO_SPARC64_PC,
665 1.17.4.2 tls RETURN_OFFSET = 8,
666 1.17.4.3 jdolecek RETURN_MASK = 0,
667 1.17.4.2 tls };
668 1.17.4.2 tls typedef uint64_t reg_t;
669 1.17.4.2 tls
670 1.17.4.2 tls __dso_hidden Registers_SPARC64();
671 1.17.4.2 tls
672 1.17.4.2 tls static int dwarf2regno(int num) {
673 1.17.4.2 tls if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
674 1.17.4.2 tls return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
675 1.17.4.2 tls if (num == DWARF_SPARC64_PC)
676 1.17.4.2 tls return REGNO_SPARC64_PC;
677 1.17.4.2 tls return LAST_REGISTER + 1;
678 1.17.4.2 tls }
679 1.17.4.2 tls
680 1.17.4.2 tls bool validRegister(int num) const {
681 1.17.4.2 tls return num >= 0 && num <= REGNO_SPARC64_PC;
682 1.17.4.2 tls }
683 1.17.4.2 tls
684 1.17.4.2 tls uint64_t getRegister(int num) const {
685 1.17.4.2 tls assert(validRegister(num));
686 1.17.4.2 tls return reg[num];
687 1.17.4.2 tls }
688 1.17.4.2 tls
689 1.17.4.2 tls void setRegister(int num, uint64_t value) {
690 1.17.4.2 tls assert(validRegister(num));
691 1.17.4.2 tls reg[num] = value;
692 1.17.4.2 tls }
693 1.17.4.2 tls
694 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
695 1.17.4.2 tls
696 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
697 1.17.4.2 tls
698 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
699 1.17.4.2 tls
700 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
701 1.17.4.2 tls
702 1.17.4.2 tls bool validFloatVectorRegister(int num) const { return false; }
703 1.17.4.2 tls
704 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {}
705 1.17.4.2 tls
706 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
707 1.17.4.2 tls
708 1.17.4.2 tls private:
709 1.17.4.2 tls uint64_t reg[REGNO_SPARC64_PC + 1];
710 1.17.4.2 tls };
711 1.17.4.2 tls
712 1.17.4.2 tls enum {
713 1.17.4.2 tls DWARF_SPARC_R0 = 0,
714 1.17.4.2 tls DWARF_SPARC_R31 = 31,
715 1.17.4.2 tls DWARF_SPARC_PC = 32,
716 1.17.4.2 tls
717 1.17.4.2 tls REGNO_SPARC_R0 = 0,
718 1.17.4.2 tls REGNO_SPARC_R14 = 14,
719 1.17.4.2 tls REGNO_SPARC_R15 = 15,
720 1.17.4.2 tls REGNO_SPARC_R31 = 31,
721 1.17.4.2 tls REGNO_SPARC_PC = 32,
722 1.17.4.2 tls };
723 1.17.4.2 tls
724 1.17.4.2 tls class Registers_SPARC {
725 1.17.4.2 tls public:
726 1.17.4.2 tls enum {
727 1.17.4.2 tls LAST_REGISTER = REGNO_SPARC_PC,
728 1.17.4.2 tls LAST_RESTORE_REG = REGNO_SPARC_PC,
729 1.17.4.2 tls RETURN_OFFSET = 8,
730 1.17.4.3 jdolecek RETURN_MASK = 0,
731 1.17.4.2 tls };
732 1.17.4.2 tls typedef uint32_t reg_t;
733 1.17.4.2 tls
734 1.17.4.2 tls __dso_hidden Registers_SPARC();
735 1.17.4.2 tls
736 1.17.4.2 tls static int dwarf2regno(int num) {
737 1.17.4.2 tls if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
738 1.17.4.2 tls return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
739 1.17.4.2 tls if (num == DWARF_SPARC_PC)
740 1.17.4.2 tls return REGNO_SPARC_PC;
741 1.17.4.2 tls return LAST_REGISTER + 1;
742 1.17.4.2 tls }
743 1.17.4.2 tls
744 1.17.4.2 tls bool validRegister(int num) const {
745 1.17.4.2 tls return num >= 0 && num <= REGNO_SPARC_PC;
746 1.17.4.2 tls }
747 1.17.4.2 tls
748 1.17.4.2 tls uint64_t getRegister(int num) const {
749 1.17.4.2 tls assert(validRegister(num));
750 1.17.4.2 tls return reg[num];
751 1.17.4.2 tls }
752 1.17.4.2 tls
753 1.17.4.2 tls void setRegister(int num, uint64_t value) {
754 1.17.4.2 tls assert(validRegister(num));
755 1.17.4.2 tls reg[num] = value;
756 1.17.4.2 tls }
757 1.17.4.2 tls
758 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
759 1.17.4.2 tls
760 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
761 1.17.4.2 tls
762 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
763 1.17.4.2 tls
764 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
765 1.17.4.2 tls
766 1.17.4.2 tls bool validFloatVectorRegister(int num) const { return false; }
767 1.17.4.2 tls
768 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {}
769 1.17.4.2 tls
770 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
771 1.17.4.2 tls
772 1.17.4.2 tls private:
773 1.17.4.2 tls uint32_t reg[REGNO_SPARC_PC + 1];
774 1.17.4.2 tls };
775 1.17.4.2 tls
776 1.17.4.2 tls enum {
777 1.17.4.2 tls DWARF_ALPHA_R0 = 0,
778 1.17.4.2 tls DWARF_ALPHA_R30 = 30,
779 1.17.4.2 tls DWARF_ALPHA_F0 = 32,
780 1.17.4.2 tls DWARF_ALPHA_F30 = 62,
781 1.17.4.2 tls
782 1.17.4.2 tls REGNO_ALPHA_R0 = 0,
783 1.17.4.2 tls REGNO_ALPHA_R26 = 26,
784 1.17.4.2 tls REGNO_ALPHA_R30 = 30,
785 1.17.4.2 tls REGNO_ALPHA_PC = 31,
786 1.17.4.2 tls REGNO_ALPHA_F0 = 32,
787 1.17.4.2 tls REGNO_ALPHA_F30 = 62,
788 1.17.4.2 tls };
789 1.17.4.2 tls
790 1.17.4.2 tls class Registers_Alpha {
791 1.17.4.2 tls public:
792 1.17.4.2 tls enum {
793 1.17.4.2 tls LAST_REGISTER = REGNO_ALPHA_F30,
794 1.17.4.2 tls LAST_RESTORE_REG = REGNO_ALPHA_F30,
795 1.17.4.2 tls RETURN_OFFSET = 0,
796 1.17.4.3 jdolecek RETURN_MASK = 0,
797 1.17.4.2 tls };
798 1.17.4.2 tls typedef uint32_t reg_t;
799 1.17.4.2 tls
800 1.17.4.2 tls __dso_hidden Registers_Alpha();
801 1.17.4.2 tls
802 1.17.4.2 tls static int dwarf2regno(int num) { return num; }
803 1.17.4.2 tls
804 1.17.4.2 tls bool validRegister(int num) const {
805 1.17.4.2 tls return num >= 0 && num <= REGNO_ALPHA_PC;
806 1.17.4.2 tls }
807 1.17.4.2 tls
808 1.17.4.2 tls uint64_t getRegister(int num) const {
809 1.17.4.2 tls assert(validRegister(num));
810 1.17.4.2 tls return reg[num];
811 1.17.4.2 tls }
812 1.17.4.2 tls
813 1.17.4.2 tls void setRegister(int num, uint64_t value) {
814 1.17.4.2 tls assert(validRegister(num));
815 1.17.4.2 tls reg[num] = value;
816 1.17.4.2 tls }
817 1.17.4.2 tls
818 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
819 1.17.4.2 tls
820 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
821 1.17.4.2 tls
822 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
823 1.17.4.2 tls
824 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
825 1.17.4.2 tls
826 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
827 1.17.4.2 tls return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
828 1.17.4.2 tls }
829 1.17.4.2 tls
830 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
831 1.17.4.2 tls assert(validFloatVectorRegister(num));
832 1.17.4.2 tls const void *addr = reinterpret_cast<const void *>(addr_);
833 1.17.4.2 tls memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
834 1.17.4.2 tls }
835 1.17.4.2 tls
836 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
837 1.17.4.2 tls
838 1.17.4.2 tls private:
839 1.17.4.2 tls uint64_t reg[REGNO_ALPHA_PC + 1];
840 1.17.4.2 tls uint64_t fpreg[31];
841 1.17.4.2 tls };
842 1.17.4.2 tls
843 1.17.4.2 tls enum {
844 1.17.4.2 tls DWARF_HPPA_R1 = 1,
845 1.17.4.2 tls DWARF_HPPA_R31 = 31,
846 1.17.4.2 tls DWARF_HPPA_FR4L = 32,
847 1.17.4.2 tls DWARF_HPPA_FR31H = 87,
848 1.17.4.2 tls
849 1.17.4.2 tls REGNO_HPPA_PC = 0,
850 1.17.4.2 tls REGNO_HPPA_R1 = 1,
851 1.17.4.2 tls REGNO_HPPA_R2 = 2,
852 1.17.4.2 tls REGNO_HPPA_R30 = 30,
853 1.17.4.2 tls REGNO_HPPA_R31 = 31,
854 1.17.4.2 tls REGNO_HPPA_FR4L = 32,
855 1.17.4.2 tls REGNO_HPPA_FR31H = 87,
856 1.17.4.2 tls };
857 1.17.4.2 tls
858 1.17.4.2 tls class Registers_HPPA {
859 1.17.4.2 tls public:
860 1.17.4.2 tls enum {
861 1.17.4.2 tls LAST_REGISTER = REGNO_HPPA_FR31H,
862 1.17.4.2 tls LAST_RESTORE_REG = REGNO_HPPA_FR31H,
863 1.17.4.3 jdolecek RETURN_OFFSET = 0,
864 1.17.4.3 jdolecek RETURN_MASK = 3,
865 1.17.4.2 tls };
866 1.17.4.2 tls
867 1.17.4.2 tls __dso_hidden Registers_HPPA();
868 1.17.4.2 tls
869 1.17.4.2 tls static int dwarf2regno(int num) {
870 1.17.4.2 tls if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
871 1.17.4.2 tls return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
872 1.17.4.2 tls if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
873 1.17.4.2 tls return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
874 1.17.4.2 tls return LAST_REGISTER + 1;
875 1.17.4.2 tls }
876 1.17.4.2 tls
877 1.17.4.2 tls bool validRegister(int num) const {
878 1.17.4.2 tls return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
879 1.17.4.2 tls }
880 1.17.4.2 tls
881 1.17.4.2 tls uint64_t getRegister(int num) const {
882 1.17.4.2 tls assert(validRegister(num));
883 1.17.4.2 tls return reg[num];
884 1.17.4.2 tls }
885 1.17.4.2 tls
886 1.17.4.2 tls void setRegister(int num, uint64_t value) {
887 1.17.4.2 tls assert(validRegister(num));
888 1.17.4.2 tls reg[num] = value;
889 1.17.4.2 tls }
890 1.17.4.2 tls
891 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
892 1.17.4.2 tls
893 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
894 1.17.4.2 tls
895 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
896 1.17.4.2 tls
897 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
898 1.17.4.2 tls
899 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
900 1.17.4.2 tls return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
901 1.17.4.2 tls }
902 1.17.4.2 tls
903 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
904 1.17.4.2 tls assert(validFloatVectorRegister(num));
905 1.17.4.2 tls const void *addr = reinterpret_cast<const void *>(addr_);
906 1.17.4.2 tls memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
907 1.17.4.2 tls }
908 1.17.4.2 tls
909 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
910 1.17.4.2 tls
911 1.17.4.2 tls private:
912 1.17.4.2 tls uint32_t reg[REGNO_HPPA_R31 + 1];
913 1.17.4.2 tls uint32_t fpreg[56];
914 1.17.4.2 tls };
915 1.17.4.2 tls
916 1.17.4.2 tls enum {
917 1.17.4.2 tls DWARF_MIPS_R1 = 0,
918 1.17.4.2 tls DWARF_MIPS_R31 = 31,
919 1.17.4.2 tls DWARF_MIPS_F0 = 32,
920 1.17.4.2 tls DWARF_MIPS_F31 = 63,
921 1.17.4.2 tls
922 1.17.4.2 tls REGNO_MIPS_PC = 0,
923 1.17.4.2 tls REGNO_MIPS_R1 = 0,
924 1.17.4.2 tls REGNO_MIPS_R29 = 29,
925 1.17.4.2 tls REGNO_MIPS_R31 = 31,
926 1.17.4.2 tls REGNO_MIPS_F0 = 33,
927 1.17.4.2 tls REGNO_MIPS_F31 = 64
928 1.17.4.2 tls };
929 1.17.4.2 tls
930 1.17.4.2 tls class Registers_MIPS {
931 1.17.4.2 tls public:
932 1.17.4.2 tls enum {
933 1.17.4.2 tls LAST_REGISTER = REGNO_MIPS_F31,
934 1.17.4.2 tls LAST_RESTORE_REG = REGNO_MIPS_F31,
935 1.17.4.2 tls RETURN_OFFSET = 0,
936 1.17.4.3 jdolecek RETURN_MASK = 0,
937 1.17.4.2 tls };
938 1.17.4.2 tls
939 1.17.4.2 tls __dso_hidden Registers_MIPS();
940 1.17.4.2 tls
941 1.17.4.2 tls static int dwarf2regno(int num) {
942 1.17.4.2 tls if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
943 1.17.4.2 tls return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
944 1.17.4.2 tls if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
945 1.17.4.2 tls return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
946 1.17.4.2 tls return LAST_REGISTER + 1;
947 1.17.4.2 tls }
948 1.17.4.2 tls
949 1.17.4.2 tls bool validRegister(int num) const {
950 1.17.4.2 tls return num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31;
951 1.17.4.2 tls }
952 1.17.4.2 tls
953 1.17.4.2 tls uint64_t getRegister(int num) const {
954 1.17.4.2 tls assert(validRegister(num));
955 1.17.4.2 tls return reg[num];
956 1.17.4.2 tls }
957 1.17.4.2 tls
958 1.17.4.2 tls void setRegister(int num, uint64_t value) {
959 1.17.4.2 tls assert(validRegister(num));
960 1.17.4.2 tls reg[num] = value;
961 1.17.4.2 tls }
962 1.17.4.2 tls
963 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
964 1.17.4.2 tls
965 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
966 1.17.4.2 tls
967 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
968 1.17.4.2 tls
969 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
970 1.17.4.2 tls
971 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
972 1.17.4.2 tls return num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31;
973 1.17.4.2 tls }
974 1.17.4.2 tls
975 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
976 1.17.4.2 tls assert(validFloatVectorRegister(num));
977 1.17.4.2 tls const void *addr = reinterpret_cast<const void *>(addr_);
978 1.17.4.2 tls memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
979 1.17.4.2 tls }
980 1.17.4.2 tls
981 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
982 1.17.4.2 tls
983 1.17.4.2 tls private:
984 1.17.4.2 tls uint32_t reg[REGNO_MIPS_R31 + 1];
985 1.17.4.2 tls uint64_t fpreg[32];
986 1.17.4.2 tls };
987 1.17.4.2 tls
988 1.17.4.2 tls enum {
989 1.17.4.2 tls DWARF_MIPS64_R1 = 0,
990 1.17.4.2 tls DWARF_MIPS64_R31 = 31,
991 1.17.4.2 tls DWARF_MIPS64_F0 = 32,
992 1.17.4.2 tls DWARF_MIPS64_F31 = 63,
993 1.17.4.2 tls
994 1.17.4.2 tls REGNO_MIPS64_PC = 0,
995 1.17.4.2 tls REGNO_MIPS64_R1 = 0,
996 1.17.4.2 tls REGNO_MIPS64_R29 = 29,
997 1.17.4.2 tls REGNO_MIPS64_R31 = 31,
998 1.17.4.2 tls REGNO_MIPS64_F0 = 33,
999 1.17.4.2 tls REGNO_MIPS64_F31 = 64
1000 1.17.4.2 tls };
1001 1.17.4.2 tls
1002 1.17.4.2 tls class Registers_MIPS64 {
1003 1.17.4.2 tls public:
1004 1.17.4.2 tls enum {
1005 1.17.4.2 tls LAST_REGISTER = REGNO_MIPS64_F31,
1006 1.17.4.2 tls LAST_RESTORE_REG = REGNO_MIPS64_F31,
1007 1.17.4.2 tls RETURN_OFFSET = 0,
1008 1.17.4.3 jdolecek RETURN_MASK = 0,
1009 1.17.4.2 tls };
1010 1.17.4.2 tls
1011 1.17.4.2 tls __dso_hidden Registers_MIPS64();
1012 1.17.4.2 tls
1013 1.17.4.2 tls static int dwarf2regno(int num) {
1014 1.17.4.2 tls if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
1015 1.17.4.2 tls return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
1016 1.17.4.2 tls if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
1017 1.17.4.2 tls return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
1018 1.17.4.2 tls return LAST_REGISTER + 1;
1019 1.17.4.2 tls }
1020 1.17.4.2 tls
1021 1.17.4.2 tls bool validRegister(int num) const {
1022 1.17.4.2 tls return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31;
1023 1.17.4.2 tls }
1024 1.17.4.2 tls
1025 1.17.4.2 tls uint64_t getRegister(int num) const {
1026 1.17.4.2 tls assert(validRegister(num));
1027 1.17.4.2 tls return reg[num];
1028 1.17.4.2 tls }
1029 1.17.4.2 tls
1030 1.17.4.2 tls void setRegister(int num, uint64_t value) {
1031 1.17.4.2 tls assert(validRegister(num));
1032 1.17.4.2 tls reg[num] = value;
1033 1.17.4.2 tls }
1034 1.17.4.2 tls
1035 1.17.4.2 tls uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1036 1.17.4.2 tls
1037 1.17.4.2 tls void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1038 1.17.4.2 tls
1039 1.17.4.2 tls uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1040 1.17.4.2 tls
1041 1.17.4.2 tls void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1042 1.17.4.2 tls
1043 1.17.4.2 tls bool validFloatVectorRegister(int num) const {
1044 1.17.4.2 tls return num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31;
1045 1.17.4.2 tls }
1046 1.17.4.2 tls
1047 1.17.4.2 tls void copyFloatVectorRegister(int num, uint64_t addr_) {
1048 1.17.4.2 tls assert(validFloatVectorRegister(num));
1049 1.17.4.2 tls const void *addr = reinterpret_cast<const void *>(addr_);
1050 1.17.4.2 tls memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
1051 1.17.4.2 tls }
1052 1.17.4.2 tls
1053 1.17.4.2 tls __dso_hidden void jumpto() const __dead;
1054 1.17.4.2 tls
1055 1.17.4.2 tls private:
1056 1.17.4.2 tls uint64_t reg[REGNO_MIPS64_R31 + 1];
1057 1.17.4.2 tls uint64_t fpreg[32];
1058 1.17.4.2 tls };
1059 1.17.4.2 tls
1060 1.17.4.3 jdolecek enum {
1061 1.17.4.3 jdolecek DWARF_OR1K_R0 = 0,
1062 1.17.4.3 jdolecek DWARF_OR1K_SP = 1,
1063 1.17.4.3 jdolecek DWARF_OR1K_LR = 9,
1064 1.17.4.3 jdolecek DWARF_OR1K_R31 = 31,
1065 1.17.4.3 jdolecek DWARF_OR1K_FPCSR = 32,
1066 1.17.4.3 jdolecek
1067 1.17.4.3 jdolecek REGNO_OR1K_R0 = 0,
1068 1.17.4.3 jdolecek REGNO_OR1K_SP = 1,
1069 1.17.4.3 jdolecek REGNO_OR1K_LR = 9,
1070 1.17.4.3 jdolecek REGNO_OR1K_R31 = 31,
1071 1.17.4.3 jdolecek REGNO_OR1K_FPCSR = 32,
1072 1.17.4.3 jdolecek };
1073 1.17.4.3 jdolecek
1074 1.17.4.3 jdolecek class Registers_or1k {
1075 1.17.4.3 jdolecek public:
1076 1.17.4.3 jdolecek enum {
1077 1.17.4.3 jdolecek LAST_REGISTER = REGNO_OR1K_FPCSR,
1078 1.17.4.3 jdolecek LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1079 1.17.4.3 jdolecek RETURN_OFFSET = 0,
1080 1.17.4.3 jdolecek RETURN_MASK = 0,
1081 1.17.4.3 jdolecek };
1082 1.17.4.3 jdolecek
1083 1.17.4.3 jdolecek __dso_hidden Registers_or1k();
1084 1.17.4.3 jdolecek
1085 1.17.4.3 jdolecek static int dwarf2regno(int num) {
1086 1.17.4.3 jdolecek if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1087 1.17.4.3 jdolecek return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1088 1.17.4.3 jdolecek if (num == DWARF_OR1K_FPCSR)
1089 1.17.4.3 jdolecek return REGNO_OR1K_FPCSR;
1090 1.17.4.3 jdolecek return LAST_REGISTER + 1;
1091 1.17.4.3 jdolecek }
1092 1.17.4.3 jdolecek
1093 1.17.4.3 jdolecek bool validRegister(int num) const {
1094 1.17.4.3 jdolecek return num >= 0 && num <= LAST_RESTORE_REG;
1095 1.17.4.3 jdolecek }
1096 1.17.4.3 jdolecek
1097 1.17.4.3 jdolecek uint64_t getRegister(int num) const {
1098 1.17.4.3 jdolecek assert(validRegister(num));
1099 1.17.4.3 jdolecek return reg[num];
1100 1.17.4.3 jdolecek }
1101 1.17.4.3 jdolecek
1102 1.17.4.3 jdolecek void setRegister(int num, uint64_t value) {
1103 1.17.4.3 jdolecek assert(validRegister(num));
1104 1.17.4.3 jdolecek reg[num] = value;
1105 1.17.4.3 jdolecek }
1106 1.17.4.3 jdolecek
1107 1.17.4.3 jdolecek uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1108 1.17.4.3 jdolecek
1109 1.17.4.3 jdolecek void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1110 1.17.4.3 jdolecek
1111 1.17.4.3 jdolecek uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1112 1.17.4.3 jdolecek
1113 1.17.4.3 jdolecek void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1114 1.17.4.3 jdolecek
1115 1.17.4.3 jdolecek bool validFloatVectorRegister(int num) const {
1116 1.17.4.3 jdolecek return false;
1117 1.17.4.3 jdolecek }
1118 1.17.4.3 jdolecek
1119 1.17.4.3 jdolecek void copyFloatVectorRegister(int num, uint64_t addr_) {
1120 1.17.4.3 jdolecek }
1121 1.17.4.3 jdolecek
1122 1.17.4.3 jdolecek __dso_hidden void jumpto() const __dead;
1123 1.17.4.3 jdolecek
1124 1.17.4.3 jdolecek private:
1125 1.17.4.3 jdolecek uint32_t reg[REGNO_OR1K_FPCSR + 1];
1126 1.17.4.3 jdolecek };
1127 1.17.4.3 jdolecek
1128 1.17.4.2 tls #if __i386__
1129 1.17.4.2 tls typedef Registers_x86 NativeUnwindRegisters;
1130 1.17.4.2 tls #elif __x86_64__
1131 1.17.4.2 tls typedef Registers_x86_64 NativeUnwindRegisters;
1132 1.17.4.2 tls #elif __powerpc__
1133 1.17.4.2 tls typedef Registers_ppc32 NativeUnwindRegisters;
1134 1.17.4.2 tls #elif __aarch64__
1135 1.17.4.2 tls typedef Registers_aarch64 NativeUnwindRegisters;
1136 1.17.4.2 tls #elif __arm__
1137 1.17.4.2 tls typedef Registers_arm32 NativeUnwindRegisters;
1138 1.17.4.2 tls #elif __vax__
1139 1.17.4.2 tls typedef Registers_vax NativeUnwindRegisters;
1140 1.17.4.2 tls #elif __m68k__
1141 1.17.4.2 tls typedef Registers_M68K NativeUnwindRegisters;
1142 1.17.4.2 tls #elif __mips_n64 || __mips_n32
1143 1.17.4.2 tls typedef Registers_MIPS64 NativeUnwindRegisters;
1144 1.17.4.2 tls #elif __mips__
1145 1.17.4.2 tls typedef Registers_MIPS NativeUnwindRegisters;
1146 1.17.4.2 tls #elif __sh3__
1147 1.17.4.2 tls typedef Registers_SH3 NativeUnwindRegisters;
1148 1.17.4.2 tls #elif __sparc64__
1149 1.17.4.2 tls typedef Registers_SPARC64 NativeUnwindRegisters;
1150 1.17.4.2 tls #elif __sparc__
1151 1.17.4.2 tls typedef Registers_SPARC NativeUnwindRegisters;
1152 1.17.4.2 tls #elif __alpha__
1153 1.17.4.2 tls typedef Registers_Alpha NativeUnwindRegisters;
1154 1.17.4.2 tls #elif __hppa__
1155 1.17.4.2 tls typedef Registers_HPPA NativeUnwindRegisters;
1156 1.17.4.3 jdolecek #elif __or1k__
1157 1.17.4.3 jdolecek typedef Registers_or1k NativeUnwindRegisters;
1158 1.17.4.2 tls #endif
1159 1.17.4.2 tls } // namespace _Unwind
1160 1.17.4.2 tls
1161 1.17.4.2 tls #endif // __REGISTERS_HPP__
1162