xref: /netbsd/sys/lib/libunwind/Registers.hpp (revision 9788222a)
1aa0b96d0Sjoerg //===----------------------------- Registers.hpp --------------------------===//
2aa0b96d0Sjoerg //
3aa0b96d0Sjoerg //                     The LLVM Compiler Infrastructure
4aa0b96d0Sjoerg //
5aa0b96d0Sjoerg // This file is dual licensed under the MIT and the University of Illinois Open
6aa0b96d0Sjoerg // Source Licenses. See LICENSE.TXT for details.
7aa0b96d0Sjoerg //
8aa0b96d0Sjoerg //
9aa0b96d0Sjoerg //  Models register sets for supported processors.
10aa0b96d0Sjoerg //
11aa0b96d0Sjoerg //===----------------------------------------------------------------------===//
12aa0b96d0Sjoerg #ifndef __REGISTERS_HPP__
13aa0b96d0Sjoerg #define __REGISTERS_HPP__
14aa0b96d0Sjoerg 
15aa0b96d0Sjoerg #include <cassert>
16aa0b96d0Sjoerg #include <cstdint>
17aa0b96d0Sjoerg 
18aa0b96d0Sjoerg namespace _Unwind {
19aa0b96d0Sjoerg 
20aa0b96d0Sjoerg enum {
21aa0b96d0Sjoerg   REGNO_X86_EAX = 0,
22aa0b96d0Sjoerg   REGNO_X86_ECX = 1,
23aa0b96d0Sjoerg   REGNO_X86_EDX = 2,
24aa0b96d0Sjoerg   REGNO_X86_EBX = 3,
25aa0b96d0Sjoerg   REGNO_X86_ESP = 4,
26aa0b96d0Sjoerg   REGNO_X86_EBP = 5,
27aa0b96d0Sjoerg   REGNO_X86_ESI = 6,
28aa0b96d0Sjoerg   REGNO_X86_EDI = 7,
29aa0b96d0Sjoerg   REGNO_X86_EIP = 8,
30aa0b96d0Sjoerg };
31aa0b96d0Sjoerg 
32aa0b96d0Sjoerg class Registers_x86 {
33aa0b96d0Sjoerg public:
34aa0b96d0Sjoerg   enum {
35aa0b96d0Sjoerg     LAST_REGISTER = REGNO_X86_EIP,
36916de6d0Sjoerg     LAST_RESTORE_REG = REGNO_X86_EIP,
37916de6d0Sjoerg     RETURN_REG = REGNO_X86_EIP,
38*9788222aSjoerg     RETURN_OFFSET = 0,
39aa0b96d0Sjoerg   };
40aa0b96d0Sjoerg 
41aa0b96d0Sjoerg   __dso_hidden Registers_x86();
42aa0b96d0Sjoerg 
43aa0b96d0Sjoerg   static int dwarf2regno(int num) { return num; }
44aa0b96d0Sjoerg 
45aa0b96d0Sjoerg   bool validRegister(int num) const {
46aa0b96d0Sjoerg     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
47aa0b96d0Sjoerg   }
48aa0b96d0Sjoerg 
49aa0b96d0Sjoerg   uint32_t getRegister(int num) const {
50aa0b96d0Sjoerg     assert(validRegister(num));
51aa0b96d0Sjoerg     return reg[num];
52aa0b96d0Sjoerg   }
53aa0b96d0Sjoerg 
54aa0b96d0Sjoerg   void setRegister(int num, uint32_t value) {
55aa0b96d0Sjoerg     assert(validRegister(num));
56aa0b96d0Sjoerg     reg[num] = value;
57aa0b96d0Sjoerg   }
58aa0b96d0Sjoerg 
59aa0b96d0Sjoerg   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
60aa0b96d0Sjoerg 
61aa0b96d0Sjoerg   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
62aa0b96d0Sjoerg 
63aa0b96d0Sjoerg   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
64aa0b96d0Sjoerg 
65aa0b96d0Sjoerg   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
66aa0b96d0Sjoerg 
67aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
68aa0b96d0Sjoerg 
69aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint32_t addr) {
70aa0b96d0Sjoerg   }
71aa0b96d0Sjoerg 
72aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
73aa0b96d0Sjoerg 
74aa0b96d0Sjoerg private:
75aa0b96d0Sjoerg   uint32_t reg[REGNO_X86_EIP + 1];
76aa0b96d0Sjoerg };
77aa0b96d0Sjoerg 
78aa0b96d0Sjoerg enum {
79aa0b96d0Sjoerg   REGNO_X86_64_RAX = 0,
80aa0b96d0Sjoerg   REGNO_X86_64_RDX = 1,
81aa0b96d0Sjoerg   REGNO_X86_64_RCX = 2,
82aa0b96d0Sjoerg   REGNO_X86_64_RBX = 3,
83aa0b96d0Sjoerg   REGNO_X86_64_RSI = 4,
84aa0b96d0Sjoerg   REGNO_X86_64_RDI = 5,
85aa0b96d0Sjoerg   REGNO_X86_64_RBP = 6,
86aa0b96d0Sjoerg   REGNO_X86_64_RSP = 7,
87aa0b96d0Sjoerg   REGNO_X86_64_R8 = 8,
88aa0b96d0Sjoerg   REGNO_X86_64_R9 = 9,
89aa0b96d0Sjoerg   REGNO_X86_64_R10 = 10,
90aa0b96d0Sjoerg   REGNO_X86_64_R11 = 11,
91aa0b96d0Sjoerg   REGNO_X86_64_R12 = 12,
92aa0b96d0Sjoerg   REGNO_X86_64_R13 = 13,
93aa0b96d0Sjoerg   REGNO_X86_64_R14 = 14,
94aa0b96d0Sjoerg   REGNO_X86_64_R15 = 15,
95aa0b96d0Sjoerg   REGNO_X86_64_RIP = 16,
96aa0b96d0Sjoerg };
97aa0b96d0Sjoerg 
98aa0b96d0Sjoerg class Registers_x86_64 {
99aa0b96d0Sjoerg public:
100aa0b96d0Sjoerg   enum {
101aa0b96d0Sjoerg     LAST_REGISTER = REGNO_X86_64_RIP,
102916de6d0Sjoerg     LAST_RESTORE_REG = REGNO_X86_64_RIP,
103916de6d0Sjoerg     RETURN_REG = REGNO_X86_64_RIP,
104*9788222aSjoerg     RETURN_OFFSET = 0,
105aa0b96d0Sjoerg   };
106aa0b96d0Sjoerg 
107aa0b96d0Sjoerg   __dso_hidden Registers_x86_64();
108aa0b96d0Sjoerg 
109aa0b96d0Sjoerg   static int dwarf2regno(int num) { return num; }
110aa0b96d0Sjoerg 
111aa0b96d0Sjoerg   bool validRegister(int num) const {
112aa0b96d0Sjoerg     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
113aa0b96d0Sjoerg   }
114aa0b96d0Sjoerg 
115aa0b96d0Sjoerg   uint64_t getRegister(int num) const {
116aa0b96d0Sjoerg     assert(validRegister(num));
117aa0b96d0Sjoerg     return reg[num];
118aa0b96d0Sjoerg   }
119aa0b96d0Sjoerg 
120aa0b96d0Sjoerg   void setRegister(int num, uint64_t value) {
121aa0b96d0Sjoerg     assert(validRegister(num));
122aa0b96d0Sjoerg     reg[num] = value;
123aa0b96d0Sjoerg   }
124aa0b96d0Sjoerg 
125aa0b96d0Sjoerg   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
126aa0b96d0Sjoerg 
127aa0b96d0Sjoerg   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
128aa0b96d0Sjoerg 
129aa0b96d0Sjoerg   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
130aa0b96d0Sjoerg 
131aa0b96d0Sjoerg   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
132aa0b96d0Sjoerg 
133aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
134aa0b96d0Sjoerg 
135aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr) {
136aa0b96d0Sjoerg   }
137aa0b96d0Sjoerg 
138aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
139aa0b96d0Sjoerg 
140aa0b96d0Sjoerg private:
141aa0b96d0Sjoerg   uint64_t reg[REGNO_X86_64_RIP + 1];
142aa0b96d0Sjoerg };
143aa0b96d0Sjoerg 
144aa0b96d0Sjoerg enum {
145aa0b96d0Sjoerg   DWARF_PPC32_R0 = 0,
146aa0b96d0Sjoerg   DWARF_PPC32_R31 = 31,
147aa0b96d0Sjoerg   DWARF_PPC32_F0 = 32,
148aa0b96d0Sjoerg   DWARF_PPC32_F31 = 63,
149aa0b96d0Sjoerg   DWARF_PPC32_LR = 65,
150b238bfcaSjoerg   DWARF_PPC32_CR = 70,
151b238bfcaSjoerg   DWARF_PPC32_V0 = 77,
152b238bfcaSjoerg   DWARF_PPC32_V31 = 108,
153b238bfcaSjoerg 
154aa0b96d0Sjoerg   REGNO_PPC32_R0 = 0,
155b238bfcaSjoerg   REGNO_PPC32_R1 = 1,
156aa0b96d0Sjoerg   REGNO_PPC32_R31 = 31,
157b238bfcaSjoerg   REGNO_PPC32_LR = 32,
158b238bfcaSjoerg   REGNO_PPC32_CR = 33,
159b238bfcaSjoerg   REGNO_PPC32_SRR0 = 34,
160b238bfcaSjoerg 
161aa0b96d0Sjoerg   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
162aa0b96d0Sjoerg   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
163aa0b96d0Sjoerg   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
164aa0b96d0Sjoerg   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
165aa0b96d0Sjoerg };
166aa0b96d0Sjoerg 
167aa0b96d0Sjoerg class Registers_ppc32 {
168aa0b96d0Sjoerg public:
169aa0b96d0Sjoerg   enum {
170aa0b96d0Sjoerg     LAST_REGISTER = REGNO_PPC32_V31,
171916de6d0Sjoerg     LAST_RESTORE_REG = REGNO_PPC32_V31,
172916de6d0Sjoerg     RETURN_REG = REGNO_PPC32_LR,
173*9788222aSjoerg     RETURN_OFFSET = 0,
174aa0b96d0Sjoerg   };
175aa0b96d0Sjoerg 
176aa0b96d0Sjoerg   __dso_hidden Registers_ppc32();
177aa0b96d0Sjoerg 
178aa0b96d0Sjoerg   static int dwarf2regno(int num) {
179aa0b96d0Sjoerg     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
180aa0b96d0Sjoerg       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
181aa0b96d0Sjoerg     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
182aa0b96d0Sjoerg       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
183aa0b96d0Sjoerg     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
184aa0b96d0Sjoerg       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
185b238bfcaSjoerg     switch (num) {
186b238bfcaSjoerg     case DWARF_PPC32_LR:
187b238bfcaSjoerg       return REGNO_PPC32_LR;
188b238bfcaSjoerg     case DWARF_PPC32_CR:
189b238bfcaSjoerg       return REGNO_PPC32_CR;
190b238bfcaSjoerg     default:
191aa0b96d0Sjoerg       return LAST_REGISTER + 1;
192aa0b96d0Sjoerg     }
193b238bfcaSjoerg   }
194aa0b96d0Sjoerg 
195aa0b96d0Sjoerg   bool validRegister(int num) const {
196aa0b96d0Sjoerg     return num >= 0 && num <= LAST_RESTORE_REG;
197aa0b96d0Sjoerg   }
198aa0b96d0Sjoerg 
199aa0b96d0Sjoerg   uint64_t getRegister(int num) const {
200aa0b96d0Sjoerg     assert(validRegister(num));
201aa0b96d0Sjoerg     return reg[num];
202aa0b96d0Sjoerg   }
203aa0b96d0Sjoerg 
204aa0b96d0Sjoerg   void setRegister(int num, uint64_t value) {
205aa0b96d0Sjoerg     assert(validRegister(num));
206aa0b96d0Sjoerg     reg[num] = value;
207aa0b96d0Sjoerg   }
208aa0b96d0Sjoerg 
209aa0b96d0Sjoerg   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
210aa0b96d0Sjoerg 
211aa0b96d0Sjoerg   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
212aa0b96d0Sjoerg 
213aa0b96d0Sjoerg   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
214aa0b96d0Sjoerg 
215aa0b96d0Sjoerg   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
216aa0b96d0Sjoerg 
217aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const {
218aa0b96d0Sjoerg     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
219aa0b96d0Sjoerg            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
220aa0b96d0Sjoerg   }
221aa0b96d0Sjoerg 
222aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
223aa0b96d0Sjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
224aa0b96d0Sjoerg     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
225aa0b96d0Sjoerg       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
226aa0b96d0Sjoerg     else
227aa0b96d0Sjoerg       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
228aa0b96d0Sjoerg   }
229aa0b96d0Sjoerg 
230aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
231aa0b96d0Sjoerg 
232aa0b96d0Sjoerg private:
233aa0b96d0Sjoerg   struct vecreg_t {
234aa0b96d0Sjoerg     uint64_t low, high;
235aa0b96d0Sjoerg   };
236aa0b96d0Sjoerg   uint32_t reg[REGNO_PPC32_SRR0 + 1];
237b238bfcaSjoerg   uint32_t dummy;
238aa0b96d0Sjoerg   uint64_t fpreg[32];
239aa0b96d0Sjoerg   vecreg_t vecreg[64];
240aa0b96d0Sjoerg };
241aa0b96d0Sjoerg 
242eb98b3ccSmatt enum {
243eb98b3ccSmatt   DWARF_ARM32_R0 = 0,
244eb98b3ccSmatt   DWARF_ARM32_R15 = 15,
245eb98b3ccSmatt   DWARF_ARM32_SPSR = 128,
246eb98b3ccSmatt   DWARF_ARM32_D0 = 256,		// VFP-v3/Neon
247eb98b3ccSmatt   DWARF_ARM32_D31 = 287,
248eb98b3ccSmatt   REGNO_ARM32_R0 = 0,
249eb98b3ccSmatt   REGNO_ARM32_SP = 13,
250eb98b3ccSmatt   REGNO_ARM32_R15 = 15,
251eb98b3ccSmatt   REGNO_ARM32_SPSR = 16,
252eb98b3ccSmatt   REGNO_ARM32_D0 = 0,
253eb98b3ccSmatt   REGNO_ARM32_D31 = 31,
254eb98b3ccSmatt };
255eb98b3ccSmatt 
256eb98b3ccSmatt class Registers_arm32 {
257eb98b3ccSmatt public:
258eb98b3ccSmatt   enum {
259eb98b3ccSmatt     LAST_REGISTER = REGNO_ARM32_D31,
260916de6d0Sjoerg     LAST_RESTORE_REG = REGNO_ARM32_SPSR,
261916de6d0Sjoerg     RETURN_REG = REGNO_ARM32_SPSR,
262*9788222aSjoerg     RETURN_OFFSET = 0,
263eb98b3ccSmatt   };
264eb98b3ccSmatt 
265eb98b3ccSmatt   __dso_hidden Registers_arm32();
266eb98b3ccSmatt 
267eb98b3ccSmatt   static int dwarf2regno(int num) {
268eb98b3ccSmatt     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
269eb98b3ccSmatt       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
270eb98b3ccSmatt     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
271eb98b3ccSmatt       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
272eb98b3ccSmatt     if (num == DWARF_ARM32_SPSR)
273eb98b3ccSmatt       return REGNO_ARM32_SPSR;
274eb98b3ccSmatt     return LAST_REGISTER + 1;
275eb98b3ccSmatt   }
276eb98b3ccSmatt 
277eb98b3ccSmatt   bool validRegister(int num) const {
278eb98b3ccSmatt     return num >= 0 && num <= LAST_RESTORE_REG;
279eb98b3ccSmatt   }
280eb98b3ccSmatt 
281eb98b3ccSmatt   uint64_t getRegister(int num) const {
282eb98b3ccSmatt     assert(validRegister(num));
283eb98b3ccSmatt     return reg[num];
284eb98b3ccSmatt   }
285eb98b3ccSmatt 
286eb98b3ccSmatt   void setRegister(int num, uint64_t value) {
287eb98b3ccSmatt     assert(validRegister(num));
288eb98b3ccSmatt     reg[num] = value;
289eb98b3ccSmatt   }
290eb98b3ccSmatt 
291eb98b3ccSmatt   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
292eb98b3ccSmatt 
293eb98b3ccSmatt   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
294eb98b3ccSmatt 
295eb98b3ccSmatt   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
296eb98b3ccSmatt 
297eb98b3ccSmatt   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
298eb98b3ccSmatt 
299eb98b3ccSmatt   bool validFloatVectorRegister(int num) const {
300eb98b3ccSmatt     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_D31);
301eb98b3ccSmatt   }
302eb98b3ccSmatt 
303eb98b3ccSmatt   void copyFloatVectorRegister(int num, uint64_t addr_) {
304eb98b3ccSmatt     const void *addr = reinterpret_cast<const void *>(addr_);
305eb98b3ccSmatt     memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
306eb98b3ccSmatt   }
307eb98b3ccSmatt 
308eb98b3ccSmatt   __dso_hidden void jumpto() const __dead;
309eb98b3ccSmatt 
310eb98b3ccSmatt private:
311eb98b3ccSmatt   uint32_t reg[REGNO_ARM32_SPSR + 1];
312eb98b3ccSmatt   uint64_t fpreg[32];
313eb98b3ccSmatt };
314eb98b3ccSmatt 
315396ee378Sjoerg enum {
316396ee378Sjoerg   DWARF_VAX_R0 = 0,
317396ee378Sjoerg   DWARF_VAX_R15 = 15,
318396ee378Sjoerg   DWARF_VAX_PSW = 16,
319396ee378Sjoerg 
320396ee378Sjoerg   REGNO_VAX_R0 = 0,
321396ee378Sjoerg   REGNO_VAX_R14 = 14,
322396ee378Sjoerg   REGNO_VAX_R15 = 15,
323396ee378Sjoerg   REGNO_VAX_PSW = 16,
324396ee378Sjoerg };
325396ee378Sjoerg 
326396ee378Sjoerg class Registers_vax {
327396ee378Sjoerg public:
328396ee378Sjoerg   enum {
329396ee378Sjoerg     LAST_REGISTER = REGNO_VAX_PSW,
330396ee378Sjoerg     LAST_RESTORE_REG = REGNO_VAX_PSW,
331396ee378Sjoerg     RETURN_REG = REGNO_VAX_R15,
332*9788222aSjoerg     RETURN_OFFSET = 0,
333396ee378Sjoerg   };
334396ee378Sjoerg 
335396ee378Sjoerg   __dso_hidden Registers_vax();
336396ee378Sjoerg 
337396ee378Sjoerg   static int dwarf2regno(int num) {
338396ee378Sjoerg     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
339396ee378Sjoerg       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
340396ee378Sjoerg     if (num == DWARF_VAX_PSW)
341396ee378Sjoerg       return REGNO_VAX_PSW;
342396ee378Sjoerg     return LAST_REGISTER + 1;
343396ee378Sjoerg   }
344396ee378Sjoerg 
345396ee378Sjoerg   bool validRegister(int num) const {
346396ee378Sjoerg     return num >= 0 && num <= LAST_RESTORE_REG;
347396ee378Sjoerg   }
348396ee378Sjoerg 
349396ee378Sjoerg   uint64_t getRegister(int num) const {
350396ee378Sjoerg     assert(validRegister(num));
351396ee378Sjoerg     return reg[num];
352396ee378Sjoerg   }
353396ee378Sjoerg 
354396ee378Sjoerg   void setRegister(int num, uint64_t value) {
355396ee378Sjoerg     assert(validRegister(num));
356396ee378Sjoerg     reg[num] = value;
357396ee378Sjoerg   }
358396ee378Sjoerg 
359396ee378Sjoerg   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
360396ee378Sjoerg 
361396ee378Sjoerg   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
362396ee378Sjoerg 
363396ee378Sjoerg   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
364396ee378Sjoerg 
365396ee378Sjoerg   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
366396ee378Sjoerg 
367396ee378Sjoerg   bool validFloatVectorRegister(int num) const {
368396ee378Sjoerg     return false;
369396ee378Sjoerg   }
370396ee378Sjoerg 
371396ee378Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
372396ee378Sjoerg   }
373396ee378Sjoerg 
374396ee378Sjoerg   __dso_hidden void jumpto() const __dead;
375396ee378Sjoerg 
376396ee378Sjoerg private:
377396ee378Sjoerg   uint32_t reg[REGNO_VAX_PSW + 1];
378396ee378Sjoerg };
379396ee378Sjoerg 
380a55c6bd8Sjoerg enum {
381a55c6bd8Sjoerg   DWARF_M68K_A0 = 0,
382a55c6bd8Sjoerg   DWARF_M68K_A7 = 7,
383a55c6bd8Sjoerg   DWARF_M68K_D0 = 8,
384a55c6bd8Sjoerg   DWARF_M68K_D7 = 15,
385c05d688cSjoerg   DWARF_M68K_FP0 = 16,
386c05d688cSjoerg   DWARF_M68K_FP7 = 23,
387a55c6bd8Sjoerg   DWARF_M68K_PC = 24,
388a55c6bd8Sjoerg 
389a55c6bd8Sjoerg   REGNO_M68K_A0 = 0,
390a55c6bd8Sjoerg   REGNO_M68K_A7 = 7,
391a55c6bd8Sjoerg   REGNO_M68K_D0 = 8,
392a55c6bd8Sjoerg   REGNO_M68K_D7 = 15,
393a55c6bd8Sjoerg   REGNO_M68K_PC = 16,
394c05d688cSjoerg   REGNO_M68K_FP0 = 17,
395c05d688cSjoerg   REGNO_M68K_FP7 = 24,
396a55c6bd8Sjoerg };
397a55c6bd8Sjoerg 
398a55c6bd8Sjoerg class Registers_M68K {
399a55c6bd8Sjoerg public:
400a55c6bd8Sjoerg   enum {
401c05d688cSjoerg     LAST_REGISTER = REGNO_M68K_FP7,
402c05d688cSjoerg     LAST_RESTORE_REG = REGNO_M68K_FP7,
403a55c6bd8Sjoerg     RETURN_REG = REGNO_M68K_PC,
404*9788222aSjoerg     RETURN_OFFSET = 0,
405a55c6bd8Sjoerg   };
406a55c6bd8Sjoerg 
407a55c6bd8Sjoerg   __dso_hidden Registers_M68K();
408a55c6bd8Sjoerg 
409a55c6bd8Sjoerg   static int dwarf2regno(int num) {
410a55c6bd8Sjoerg     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
411a55c6bd8Sjoerg       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
412a55c6bd8Sjoerg     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
413a55c6bd8Sjoerg       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
414c05d688cSjoerg     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
415c05d688cSjoerg       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
416a55c6bd8Sjoerg     if (num == DWARF_M68K_PC)
417a55c6bd8Sjoerg       return REGNO_M68K_PC;
418a55c6bd8Sjoerg     return LAST_REGISTER + 1;
419a55c6bd8Sjoerg   }
420a55c6bd8Sjoerg 
421a55c6bd8Sjoerg   bool validRegister(int num) const {
422c05d688cSjoerg     return num >= 0 && num <= REGNO_M68K_PC;
423a55c6bd8Sjoerg   }
424a55c6bd8Sjoerg 
425a55c6bd8Sjoerg   uint64_t getRegister(int num) const {
426a55c6bd8Sjoerg     assert(validRegister(num));
427a55c6bd8Sjoerg     return reg[num];
428a55c6bd8Sjoerg   }
429a55c6bd8Sjoerg 
430a55c6bd8Sjoerg   void setRegister(int num, uint64_t value) {
431a55c6bd8Sjoerg     assert(validRegister(num));
432a55c6bd8Sjoerg     reg[num] = value;
433a55c6bd8Sjoerg   }
434a55c6bd8Sjoerg 
435a55c6bd8Sjoerg   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
436a55c6bd8Sjoerg 
437a55c6bd8Sjoerg   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
438a55c6bd8Sjoerg 
439a55c6bd8Sjoerg   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
440a55c6bd8Sjoerg 
441a55c6bd8Sjoerg   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
442a55c6bd8Sjoerg 
443a55c6bd8Sjoerg   bool validFloatVectorRegister(int num) const {
444c05d688cSjoerg     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
445a55c6bd8Sjoerg   }
446a55c6bd8Sjoerg 
447a55c6bd8Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
448c05d688cSjoerg     assert(validFloatVectorRegister(num));
449c05d688cSjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
450c05d688cSjoerg     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
451a55c6bd8Sjoerg   }
452a55c6bd8Sjoerg 
453a55c6bd8Sjoerg   __dso_hidden void jumpto() const __dead;
454a55c6bd8Sjoerg 
455a55c6bd8Sjoerg private:
456c05d688cSjoerg   typedef uint32_t fpreg_t[3];
457c05d688cSjoerg 
458a55c6bd8Sjoerg   uint32_t reg[REGNO_M68K_PC + 1];
459c05d688cSjoerg   uint32_t dummy;
460c05d688cSjoerg   fpreg_t fpreg[8];
461a55c6bd8Sjoerg };
462a55c6bd8Sjoerg 
463a280fb92Sjoerg enum {
464a280fb92Sjoerg   DWARF_SH3_R0 = 0,
465a280fb92Sjoerg   DWARF_SH3_R15 = 15,
466a280fb92Sjoerg   DWARF_SH3_PC = 16,
467a280fb92Sjoerg   DWARF_SH3_PR = 17,
468a280fb92Sjoerg 
469a280fb92Sjoerg   REGNO_SH3_R0 = 0,
470a280fb92Sjoerg   REGNO_SH3_R15 = 15,
471a280fb92Sjoerg   REGNO_SH3_PC = 16,
472a280fb92Sjoerg   REGNO_SH3_PR = 17,
473a280fb92Sjoerg };
474a280fb92Sjoerg 
475a280fb92Sjoerg class Registers_SH3 {
476a280fb92Sjoerg public:
477a280fb92Sjoerg   enum {
478a280fb92Sjoerg     LAST_REGISTER = REGNO_SH3_PR,
479a280fb92Sjoerg     LAST_RESTORE_REG = REGNO_SH3_PR,
480a280fb92Sjoerg     RETURN_REG = REGNO_SH3_PR,
481*9788222aSjoerg     RETURN_OFFSET = 0,
482a280fb92Sjoerg   };
483a280fb92Sjoerg 
484a280fb92Sjoerg   __dso_hidden Registers_SH3();
485a280fb92Sjoerg 
486a280fb92Sjoerg   static int dwarf2regno(int num) {
487a280fb92Sjoerg     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
488a280fb92Sjoerg       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
489a280fb92Sjoerg     if (num == DWARF_SH3_PC)
490a280fb92Sjoerg       return REGNO_SH3_PC;
491a280fb92Sjoerg     if (num == DWARF_SH3_PR)
492a280fb92Sjoerg       return REGNO_SH3_PR;
493a280fb92Sjoerg     return LAST_REGISTER + 1;
494a280fb92Sjoerg   }
495a280fb92Sjoerg 
496a280fb92Sjoerg   bool validRegister(int num) const {
497a280fb92Sjoerg     return num >= 0 && num <= REGNO_SH3_PR;
498a280fb92Sjoerg   }
499a280fb92Sjoerg 
500a280fb92Sjoerg   uint64_t getRegister(int num) const {
501a280fb92Sjoerg     assert(validRegister(num));
502a280fb92Sjoerg     return reg[num];
503a280fb92Sjoerg   }
504a280fb92Sjoerg 
505a280fb92Sjoerg   void setRegister(int num, uint64_t value) {
506a280fb92Sjoerg     assert(validRegister(num));
507a280fb92Sjoerg     reg[num] = value;
508a280fb92Sjoerg   }
509a280fb92Sjoerg 
510a280fb92Sjoerg   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
511a280fb92Sjoerg 
512a280fb92Sjoerg   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
513a280fb92Sjoerg 
514a280fb92Sjoerg   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
515a280fb92Sjoerg 
516a280fb92Sjoerg   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
517a280fb92Sjoerg 
518a280fb92Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
519a280fb92Sjoerg 
520a280fb92Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {}
521a280fb92Sjoerg 
522a280fb92Sjoerg   __dso_hidden void jumpto() const __dead;
523a280fb92Sjoerg 
524a280fb92Sjoerg private:
525a280fb92Sjoerg   uint32_t reg[REGNO_SH3_PR + 1];
526a280fb92Sjoerg };
527a280fb92Sjoerg 
528a6ecde39Sjoerg #if __i386__
529a6ecde39Sjoerg typedef Registers_x86 NativeUnwindRegisters;
530a6ecde39Sjoerg #elif __x86_64__
531a6ecde39Sjoerg typedef Registers_x86_64 NativeUnwindRegisters;
532a6ecde39Sjoerg #elif __powerpc__
533a6ecde39Sjoerg typedef Registers_ppc32 NativeUnwindRegisters;
534a6ecde39Sjoerg #elif __arm__ && !defined(__ARM_EABI__)
535a6ecde39Sjoerg typedef Registers_arm32 NativeUnwindRegisters;
536a6ecde39Sjoerg #elif __vax__
537a6ecde39Sjoerg typedef Registers_vax NativeUnwindRegisters;
538a6ecde39Sjoerg #elif __m68k__
539a6ecde39Sjoerg typedef Registers_M68K NativeUnwindRegisters;
540a6ecde39Sjoerg #elif __sh3__
541a6ecde39Sjoerg typedef Registers_SH3 NativeUnwindRegisters;
542a6ecde39Sjoerg #endif
543aa0b96d0Sjoerg } // namespace _Unwind
544aa0b96d0Sjoerg 
545aa0b96d0Sjoerg #endif // __REGISTERS_HPP__
546