xref: /netbsd/sys/lib/libunwind/Registers.hpp (revision aa2e0e12)
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 
15155a9ee6Sjoerg #include <sys/endian.h>
16aa0b96d0Sjoerg #include <cassert>
17aa0b96d0Sjoerg #include <cstdint>
18aa0b96d0Sjoerg 
19aa0b96d0Sjoerg namespace _Unwind {
20aa0b96d0Sjoerg 
21aa0b96d0Sjoerg enum {
22aa0b96d0Sjoerg   REGNO_X86_EAX = 0,
23aa0b96d0Sjoerg   REGNO_X86_ECX = 1,
24aa0b96d0Sjoerg   REGNO_X86_EDX = 2,
25aa0b96d0Sjoerg   REGNO_X86_EBX = 3,
26aa0b96d0Sjoerg   REGNO_X86_ESP = 4,
27aa0b96d0Sjoerg   REGNO_X86_EBP = 5,
28aa0b96d0Sjoerg   REGNO_X86_ESI = 6,
29aa0b96d0Sjoerg   REGNO_X86_EDI = 7,
30aa0b96d0Sjoerg   REGNO_X86_EIP = 8,
31aa0b96d0Sjoerg };
32aa0b96d0Sjoerg 
33aa0b96d0Sjoerg class Registers_x86 {
34aa0b96d0Sjoerg public:
35aa0b96d0Sjoerg   enum {
36aa0b96d0Sjoerg     LAST_REGISTER = REGNO_X86_EIP,
37916de6d0Sjoerg     LAST_RESTORE_REG = REGNO_X86_EIP,
389788222aSjoerg     RETURN_OFFSET = 0,
390282220bSjoerg     RETURN_MASK = 0,
40aa0b96d0Sjoerg   };
41aa0b96d0Sjoerg 
42aa0b96d0Sjoerg   __dso_hidden Registers_x86();
43aa0b96d0Sjoerg 
44aa0b96d0Sjoerg   static int dwarf2regno(int num) { return num; }
45aa0b96d0Sjoerg 
46aa0b96d0Sjoerg   bool validRegister(int num) const {
47aa0b96d0Sjoerg     return num >= REGNO_X86_EAX && num <= REGNO_X86_EDI;
48aa0b96d0Sjoerg   }
49aa0b96d0Sjoerg 
50aa0b96d0Sjoerg   uint32_t getRegister(int num) const {
51aa0b96d0Sjoerg     assert(validRegister(num));
52aa0b96d0Sjoerg     return reg[num];
53aa0b96d0Sjoerg   }
54aa0b96d0Sjoerg 
55aa0b96d0Sjoerg   void setRegister(int num, uint32_t value) {
56aa0b96d0Sjoerg     assert(validRegister(num));
57aa0b96d0Sjoerg     reg[num] = value;
58aa0b96d0Sjoerg   }
59aa0b96d0Sjoerg 
60aa0b96d0Sjoerg   uint32_t getIP() const { return reg[REGNO_X86_EIP]; }
61aa0b96d0Sjoerg 
62aa0b96d0Sjoerg   void setIP(uint32_t value) { reg[REGNO_X86_EIP] = value; }
63aa0b96d0Sjoerg 
64aa0b96d0Sjoerg   uint32_t getSP() const { return reg[REGNO_X86_ESP]; }
65aa0b96d0Sjoerg 
66aa0b96d0Sjoerg   void setSP(uint32_t value) { reg[REGNO_X86_ESP] = value; }
67aa0b96d0Sjoerg 
68aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
69aa0b96d0Sjoerg 
70aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint32_t addr) {
71aa0b96d0Sjoerg   }
72aa0b96d0Sjoerg 
73aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
74aa0b96d0Sjoerg 
75aa0b96d0Sjoerg private:
76aa0b96d0Sjoerg   uint32_t reg[REGNO_X86_EIP + 1];
77aa0b96d0Sjoerg };
78aa0b96d0Sjoerg 
79aa0b96d0Sjoerg enum {
80aa0b96d0Sjoerg   REGNO_X86_64_RAX = 0,
81aa0b96d0Sjoerg   REGNO_X86_64_RDX = 1,
82aa0b96d0Sjoerg   REGNO_X86_64_RCX = 2,
83aa0b96d0Sjoerg   REGNO_X86_64_RBX = 3,
84aa0b96d0Sjoerg   REGNO_X86_64_RSI = 4,
85aa0b96d0Sjoerg   REGNO_X86_64_RDI = 5,
86aa0b96d0Sjoerg   REGNO_X86_64_RBP = 6,
87aa0b96d0Sjoerg   REGNO_X86_64_RSP = 7,
88aa0b96d0Sjoerg   REGNO_X86_64_R8 = 8,
89aa0b96d0Sjoerg   REGNO_X86_64_R9 = 9,
90aa0b96d0Sjoerg   REGNO_X86_64_R10 = 10,
91aa0b96d0Sjoerg   REGNO_X86_64_R11 = 11,
92aa0b96d0Sjoerg   REGNO_X86_64_R12 = 12,
93aa0b96d0Sjoerg   REGNO_X86_64_R13 = 13,
94aa0b96d0Sjoerg   REGNO_X86_64_R14 = 14,
95aa0b96d0Sjoerg   REGNO_X86_64_R15 = 15,
96aa0b96d0Sjoerg   REGNO_X86_64_RIP = 16,
97aa0b96d0Sjoerg };
98aa0b96d0Sjoerg 
99aa0b96d0Sjoerg class Registers_x86_64 {
100aa0b96d0Sjoerg public:
101aa0b96d0Sjoerg   enum {
102aa0b96d0Sjoerg     LAST_REGISTER = REGNO_X86_64_RIP,
103916de6d0Sjoerg     LAST_RESTORE_REG = REGNO_X86_64_RIP,
1049788222aSjoerg     RETURN_OFFSET = 0,
1050282220bSjoerg     RETURN_MASK = 0,
106aa0b96d0Sjoerg   };
107aa0b96d0Sjoerg 
108aa0b96d0Sjoerg   __dso_hidden Registers_x86_64();
109aa0b96d0Sjoerg 
110aa0b96d0Sjoerg   static int dwarf2regno(int num) { return num; }
111aa0b96d0Sjoerg 
112aa0b96d0Sjoerg   bool validRegister(int num) const {
113aa0b96d0Sjoerg     return num >= REGNO_X86_64_RAX && num <= REGNO_X86_64_R15;
114aa0b96d0Sjoerg   }
115aa0b96d0Sjoerg 
116aa0b96d0Sjoerg   uint64_t getRegister(int num) const {
117aa0b96d0Sjoerg     assert(validRegister(num));
118aa0b96d0Sjoerg     return reg[num];
119aa0b96d0Sjoerg   }
120aa0b96d0Sjoerg 
121aa0b96d0Sjoerg   void setRegister(int num, uint64_t value) {
122aa0b96d0Sjoerg     assert(validRegister(num));
123aa0b96d0Sjoerg     reg[num] = value;
124aa0b96d0Sjoerg   }
125aa0b96d0Sjoerg 
126aa0b96d0Sjoerg   uint64_t getIP() const { return reg[REGNO_X86_64_RIP]; }
127aa0b96d0Sjoerg 
128aa0b96d0Sjoerg   void setIP(uint64_t value) { reg[REGNO_X86_64_RIP] = value; }
129aa0b96d0Sjoerg 
130aa0b96d0Sjoerg   uint64_t getSP() const { return reg[REGNO_X86_64_RSP]; }
131aa0b96d0Sjoerg 
132aa0b96d0Sjoerg   void setSP(uint64_t value) { reg[REGNO_X86_64_RSP] = value; }
133aa0b96d0Sjoerg 
134aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
135aa0b96d0Sjoerg 
136aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr) {
137aa0b96d0Sjoerg   }
138aa0b96d0Sjoerg 
139aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
140aa0b96d0Sjoerg 
141aa0b96d0Sjoerg private:
142aa0b96d0Sjoerg   uint64_t reg[REGNO_X86_64_RIP + 1];
143aa0b96d0Sjoerg };
144aa0b96d0Sjoerg 
145aa0b96d0Sjoerg enum {
146aa0b96d0Sjoerg   DWARF_PPC32_R0 = 0,
147aa0b96d0Sjoerg   DWARF_PPC32_R31 = 31,
148aa0b96d0Sjoerg   DWARF_PPC32_F0 = 32,
149aa0b96d0Sjoerg   DWARF_PPC32_F31 = 63,
150aa0b96d0Sjoerg   DWARF_PPC32_LR = 65,
151b238bfcaSjoerg   DWARF_PPC32_CR = 70,
152b238bfcaSjoerg   DWARF_PPC32_V0 = 77,
153b238bfcaSjoerg   DWARF_PPC32_V31 = 108,
154b238bfcaSjoerg 
155aa0b96d0Sjoerg   REGNO_PPC32_R0 = 0,
156b238bfcaSjoerg   REGNO_PPC32_R1 = 1,
157aa0b96d0Sjoerg   REGNO_PPC32_R31 = 31,
158b238bfcaSjoerg   REGNO_PPC32_LR = 32,
159b238bfcaSjoerg   REGNO_PPC32_CR = 33,
160b238bfcaSjoerg   REGNO_PPC32_SRR0 = 34,
161b238bfcaSjoerg 
162aa0b96d0Sjoerg   REGNO_PPC32_F0 = REGNO_PPC32_SRR0 + 1,
163aa0b96d0Sjoerg   REGNO_PPC32_F31 = REGNO_PPC32_F0 + 31,
164aa0b96d0Sjoerg   REGNO_PPC32_V0 = REGNO_PPC32_F31 + 1,
165aa0b96d0Sjoerg   REGNO_PPC32_V31 = REGNO_PPC32_V0 + 31,
166aa0b96d0Sjoerg };
167aa0b96d0Sjoerg 
168aa0b96d0Sjoerg class Registers_ppc32 {
169aa0b96d0Sjoerg public:
170aa0b96d0Sjoerg   enum {
171aa0b96d0Sjoerg     LAST_REGISTER = REGNO_PPC32_V31,
172916de6d0Sjoerg     LAST_RESTORE_REG = REGNO_PPC32_V31,
1739788222aSjoerg     RETURN_OFFSET = 0,
1740282220bSjoerg     RETURN_MASK = 0,
175aa0b96d0Sjoerg   };
176aa0b96d0Sjoerg 
177aa0b96d0Sjoerg   __dso_hidden Registers_ppc32();
178aa0b96d0Sjoerg 
179aa0b96d0Sjoerg   static int dwarf2regno(int num) {
180aa0b96d0Sjoerg     if (num >= DWARF_PPC32_R0 && num <= DWARF_PPC32_R31)
181aa0b96d0Sjoerg       return REGNO_PPC32_R0 + (num - DWARF_PPC32_R0);
182aa0b96d0Sjoerg     if (num >= DWARF_PPC32_F0 && num <= DWARF_PPC32_F31)
183aa0b96d0Sjoerg       return REGNO_PPC32_F0 + (num - DWARF_PPC32_F0);
184aa0b96d0Sjoerg     if (num >= DWARF_PPC32_V0 && num <= DWARF_PPC32_V31)
185aa0b96d0Sjoerg       return REGNO_PPC32_V0 + (num - DWARF_PPC32_V0);
186b238bfcaSjoerg     switch (num) {
187b238bfcaSjoerg     case DWARF_PPC32_LR:
188b238bfcaSjoerg       return REGNO_PPC32_LR;
189b238bfcaSjoerg     case DWARF_PPC32_CR:
190b238bfcaSjoerg       return REGNO_PPC32_CR;
191b238bfcaSjoerg     default:
192aa0b96d0Sjoerg       return LAST_REGISTER + 1;
193aa0b96d0Sjoerg     }
194b238bfcaSjoerg   }
195aa0b96d0Sjoerg 
196aa0b96d0Sjoerg   bool validRegister(int num) const {
197aa0b96d0Sjoerg     return num >= 0 && num <= LAST_RESTORE_REG;
198aa0b96d0Sjoerg   }
199aa0b96d0Sjoerg 
200aa0b96d0Sjoerg   uint64_t getRegister(int num) const {
201aa0b96d0Sjoerg     assert(validRegister(num));
202aa0b96d0Sjoerg     return reg[num];
203aa0b96d0Sjoerg   }
204aa0b96d0Sjoerg 
205aa0b96d0Sjoerg   void setRegister(int num, uint64_t value) {
206aa0b96d0Sjoerg     assert(validRegister(num));
207aa0b96d0Sjoerg     reg[num] = value;
208aa0b96d0Sjoerg   }
209aa0b96d0Sjoerg 
210aa0b96d0Sjoerg   uint64_t getIP() const { return reg[REGNO_PPC32_SRR0]; }
211aa0b96d0Sjoerg 
212aa0b96d0Sjoerg   void setIP(uint64_t value) { reg[REGNO_PPC32_SRR0] = value; }
213aa0b96d0Sjoerg 
214aa0b96d0Sjoerg   uint64_t getSP() const { return reg[REGNO_PPC32_R1]; }
215aa0b96d0Sjoerg 
216aa0b96d0Sjoerg   void setSP(uint64_t value) { reg[REGNO_PPC32_R1] = value; }
217aa0b96d0Sjoerg 
218aa0b96d0Sjoerg   bool validFloatVectorRegister(int num) const {
219aa0b96d0Sjoerg     return (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31) ||
220aa0b96d0Sjoerg            (num >= REGNO_PPC32_V0 && num <= REGNO_PPC32_V31);
221aa0b96d0Sjoerg   }
222aa0b96d0Sjoerg 
223aa0b96d0Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
224aa0b96d0Sjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
225aa0b96d0Sjoerg     if (num >= REGNO_PPC32_F0 && num <= REGNO_PPC32_F31)
226aa0b96d0Sjoerg       memcpy(fpreg + (num - REGNO_PPC32_F0), addr, sizeof(fpreg[0]));
227aa0b96d0Sjoerg     else
228aa0b96d0Sjoerg       memcpy(vecreg + (num - REGNO_PPC32_V0), addr, sizeof(vecreg[0]));
229aa0b96d0Sjoerg   }
230aa0b96d0Sjoerg 
231aa0b96d0Sjoerg   __dso_hidden void jumpto() const __dead;
232aa0b96d0Sjoerg 
233aa0b96d0Sjoerg private:
234aa0b96d0Sjoerg   struct vecreg_t {
235aa0b96d0Sjoerg     uint64_t low, high;
236aa0b96d0Sjoerg   };
237aa0b96d0Sjoerg   uint32_t reg[REGNO_PPC32_SRR0 + 1];
238b238bfcaSjoerg   uint32_t dummy;
239aa0b96d0Sjoerg   uint64_t fpreg[32];
240aa0b96d0Sjoerg   vecreg_t vecreg[64];
241aa0b96d0Sjoerg };
242aa0b96d0Sjoerg 
243eb98b3ccSmatt enum {
244aa37019dSmatt   DWARF_AARCH64_X0 = 0,
245aa37019dSmatt   DWARF_AARCH64_X30 = 30,
246aa37019dSmatt   DWARF_AARCH64_SP = 31,
247aa37019dSmatt   DWARF_AARCH64_V0 = 64,
248aa37019dSmatt   DWARF_AARCH64_V31 = 95,
249aa37019dSmatt 
250aa37019dSmatt   REGNO_AARCH64_X0 = 0,
251aa37019dSmatt   REGNO_AARCH64_X30 = 30,
252aa37019dSmatt   REGNO_AARCH64_SP = 31,
25328f5faf2Sjoerg   REGNO_AARCH64_V0 = 32,
25428f5faf2Sjoerg   REGNO_AARCH64_V31 = 63,
255aa37019dSmatt };
256aa37019dSmatt 
257aa37019dSmatt class Registers_aarch64 {
258aa37019dSmatt public:
259aa37019dSmatt   enum {
260aa37019dSmatt     LAST_RESTORE_REG = REGNO_AARCH64_V31,
261aa37019dSmatt     LAST_REGISTER = REGNO_AARCH64_V31,
262aa37019dSmatt     RETURN_OFFSET = 0,
2630282220bSjoerg     RETURN_MASK = 0,
264aa37019dSmatt   };
265aa37019dSmatt 
266aa37019dSmatt   __dso_hidden Registers_aarch64();
267aa37019dSmatt 
268aa37019dSmatt   static int dwarf2regno(int num) {
269aa37019dSmatt     if (num >= DWARF_AARCH64_X0 && num <= DWARF_AARCH64_X30)
270aa37019dSmatt       return REGNO_AARCH64_X0 + (num - DWARF_AARCH64_X0);
271aa37019dSmatt     if (num == DWARF_AARCH64_SP)
272aa37019dSmatt       return REGNO_AARCH64_SP;
273aa37019dSmatt     if (num >= DWARF_AARCH64_V0 && num <= DWARF_AARCH64_V31)
274aa37019dSmatt       return REGNO_AARCH64_V0 + (num - DWARF_AARCH64_V0);
275aa37019dSmatt     return LAST_REGISTER + 1;
276aa37019dSmatt   }
277aa37019dSmatt 
278aa37019dSmatt   bool validRegister(int num) const {
279aa37019dSmatt     return num >= 0 && num <= LAST_RESTORE_REG;
280aa37019dSmatt   }
281aa37019dSmatt 
282aa37019dSmatt   uint64_t getRegister(int num) const {
283aa37019dSmatt     assert(validRegister(num));
284aa37019dSmatt     return reg[num];
285aa37019dSmatt   }
286aa37019dSmatt 
287aa37019dSmatt   void setRegister(int num, uint64_t value) {
288aa37019dSmatt     assert(validRegister(num));
289aa37019dSmatt     reg[num] = value;
290aa37019dSmatt   }
291aa37019dSmatt 
292aa37019dSmatt   uint64_t getIP() const { return reg[REGNO_AARCH64_X30]; }
293aa37019dSmatt 
294aa37019dSmatt   void setIP(uint64_t value) { reg[REGNO_AARCH64_X30] = value; }
295aa37019dSmatt 
296aa37019dSmatt   uint64_t getSP() const { return reg[REGNO_AARCH64_SP]; }
297aa37019dSmatt 
298aa37019dSmatt   void setSP(uint64_t value) { reg[REGNO_AARCH64_SP] = value; }
299aa37019dSmatt 
300aa37019dSmatt   bool validFloatVectorRegister(int num) const {
301aa37019dSmatt     return (num >= REGNO_AARCH64_V0 && num <= REGNO_AARCH64_V31);
302aa37019dSmatt   }
303aa37019dSmatt 
304aa37019dSmatt   void copyFloatVectorRegister(int num, uint64_t addr_) {
305aa37019dSmatt     const void *addr = reinterpret_cast<const void *>(addr_);
30628f5faf2Sjoerg     memcpy(vecreg + (num - REGNO_AARCH64_V0), addr, 16);
307aa37019dSmatt   }
308aa37019dSmatt 
309aa37019dSmatt   __dso_hidden void jumpto() const __dead;
310aa37019dSmatt 
311aa37019dSmatt private:
31228f5faf2Sjoerg   uint64_t reg[REGNO_AARCH64_SP + 1];
31328f5faf2Sjoerg   uint64_t vecreg[64];
314aa37019dSmatt };
315aa37019dSmatt 
316aa37019dSmatt enum {
317eb98b3ccSmatt   DWARF_ARM32_R0 = 0,
318eb98b3ccSmatt   DWARF_ARM32_R15 = 15,
319eb98b3ccSmatt   DWARF_ARM32_SPSR = 128,
320155a9ee6Sjoerg   DWARF_ARM32_S0 = 64,
3218026a450Srin   DWARF_ARM32_S31 = 95,
322bdd3372bSjoerg   DWARF_ARM32_D0 = 256,
323eb98b3ccSmatt   DWARF_ARM32_D31 = 287,
324eb98b3ccSmatt   REGNO_ARM32_R0 = 0,
325eb98b3ccSmatt   REGNO_ARM32_SP = 13,
326eb98b3ccSmatt   REGNO_ARM32_R15 = 15,
327eb98b3ccSmatt   REGNO_ARM32_SPSR = 16,
328bdd3372bSjoerg   REGNO_ARM32_D0 = 17,
329bdd3372bSjoerg   REGNO_ARM32_D15 = 32,
330bdd3372bSjoerg   REGNO_ARM32_D31 = 48,
331155a9ee6Sjoerg   REGNO_ARM32_S0 = 49,
3328026a450Srin   REGNO_ARM32_S31 = 80,
333eb98b3ccSmatt };
334eb98b3ccSmatt 
3351a44aed1Srin #define	FLAGS_VFPV2_USED		0x1
3361a44aed1Srin #define	FLAGS_VFPV3_USED		0x2
3371a44aed1Srin #define	FLAGS_LEGACY_VFPV2_REGNO	0x4
3381a44aed1Srin #define	FLAGS_EXTENDED_VFPV2_REGNO	0x8
3391a44aed1Srin 
340eb98b3ccSmatt class Registers_arm32 {
341eb98b3ccSmatt public:
342eb98b3ccSmatt   enum {
3431b5786f9Srin     LAST_REGISTER = REGNO_ARM32_S31,
3441b5786f9Srin     LAST_RESTORE_REG = REGNO_ARM32_S31,
3459788222aSjoerg     RETURN_OFFSET = 0,
3460282220bSjoerg     RETURN_MASK = 0,
347eb98b3ccSmatt   };
348eb98b3ccSmatt 
349eb98b3ccSmatt   __dso_hidden Registers_arm32();
350eb98b3ccSmatt 
351eb98b3ccSmatt   static int dwarf2regno(int num) {
352eb98b3ccSmatt     if (num >= DWARF_ARM32_R0 && num <= DWARF_ARM32_R15)
353eb98b3ccSmatt       return REGNO_ARM32_R0 + (num - DWARF_ARM32_R0);
354eb98b3ccSmatt     if (num == DWARF_ARM32_SPSR)
355eb98b3ccSmatt       return REGNO_ARM32_SPSR;
356bdd3372bSjoerg     if (num >= DWARF_ARM32_D0 && num <= DWARF_ARM32_D31)
357bdd3372bSjoerg       return REGNO_ARM32_D0 + (num - DWARF_ARM32_D0);
35885f18f75Srin     if (num >= DWARF_ARM32_S0 && num <= DWARF_ARM32_S31)
359155a9ee6Sjoerg       return REGNO_ARM32_S0 + (num - DWARF_ARM32_S0);
360eb98b3ccSmatt     return LAST_REGISTER + 1;
361eb98b3ccSmatt   }
362eb98b3ccSmatt 
363eb98b3ccSmatt   bool validRegister(int num) const {
364bdd3372bSjoerg     return num >= 0 && num <= REGNO_ARM32_SPSR;
365eb98b3ccSmatt   }
366eb98b3ccSmatt 
367eb98b3ccSmatt   uint64_t getRegister(int num) const {
368eb98b3ccSmatt     assert(validRegister(num));
369eb98b3ccSmatt     return reg[num];
370eb98b3ccSmatt   }
371eb98b3ccSmatt 
372eb98b3ccSmatt   void setRegister(int num, uint64_t value) {
373eb98b3ccSmatt     assert(validRegister(num));
374eb98b3ccSmatt     reg[num] = value;
375eb98b3ccSmatt   }
376eb98b3ccSmatt 
377eb98b3ccSmatt   uint64_t getIP() const { return reg[REGNO_ARM32_R15]; }
378eb98b3ccSmatt 
379eb98b3ccSmatt   void setIP(uint64_t value) { reg[REGNO_ARM32_R15] = value; }
380eb98b3ccSmatt 
381eb98b3ccSmatt   uint64_t getSP() const { return reg[REGNO_ARM32_SP]; }
382eb98b3ccSmatt 
383eb98b3ccSmatt   void setSP(uint64_t value) { reg[REGNO_ARM32_SP] = value; }
384eb98b3ccSmatt 
385eb98b3ccSmatt   bool validFloatVectorRegister(int num) const {
386155a9ee6Sjoerg     return (num >= REGNO_ARM32_D0 && num <= REGNO_ARM32_S31);
387eb98b3ccSmatt   }
388eb98b3ccSmatt 
389eb98b3ccSmatt   void copyFloatVectorRegister(int num, uint64_t addr_) {
390d03fef5bSrin     assert(validFloatVectorRegister(num));
391155a9ee6Sjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
392155a9ee6Sjoerg     if (num >= REGNO_ARM32_S0 && num <= REGNO_ARM32_S31) {
3931b5786f9Srin       /*
3941b5786f9Srin        * XXX
3951b5786f9Srin        * There are two numbering schemes for VFPv2 registers: s0-s31
3961b5786f9Srin        * (used by GCC) and d0-d15 (used by LLVM). We won't support both
3971b5786f9Srin        * schemes simultaneously in a same frame.
3981b5786f9Srin        */
3991b5786f9Srin       assert((flags & FLAGS_EXTENDED_VFPV2_REGNO) == 0);
4001b5786f9Srin       flags |= FLAGS_LEGACY_VFPV2_REGNO;
40185f18f75Srin       if ((flags & FLAGS_VFPV2_USED) == 0) {
40285f18f75Srin         lazyVFPv2();
40385f18f75Srin         flags |= FLAGS_VFPV2_USED;
404155a9ee6Sjoerg       }
405155a9ee6Sjoerg       /*
406155a9ee6Sjoerg        * Emulate single precision register as half of the
407155a9ee6Sjoerg        * corresponding double register.
408155a9ee6Sjoerg        */
409155a9ee6Sjoerg       int dnum = (num - REGNO_ARM32_S0) / 2;
410155a9ee6Sjoerg       int part = (num - REGNO_ARM32_S0) % 2;
411155a9ee6Sjoerg #if _BYTE_ORDER == _BIG_ENDIAN
412155a9ee6Sjoerg       part = 1 - part;
413155a9ee6Sjoerg #endif
414c2f619e8Srin       memcpy((uint8_t *)(fpreg + dnum) + part * sizeof(fpreg[0]) / 2,
415155a9ee6Sjoerg         addr, sizeof(fpreg[0]) / 2);
416994a5fb3Srin     } else {
417bdd3372bSjoerg       if (num <= REGNO_ARM32_D15) {
4181b5786f9Srin 	/*
4191b5786f9Srin 	 * XXX
4201b5786f9Srin 	 * See XXX comment above.
4211b5786f9Srin 	 */
4221b5786f9Srin         assert((flags & FLAGS_LEGACY_VFPV2_REGNO) == 0);
4231b5786f9Srin         flags |= FLAGS_EXTENDED_VFPV2_REGNO;
42485f18f75Srin         if ((flags & FLAGS_VFPV2_USED) == 0) {
42585f18f75Srin           lazyVFPv2();
42685f18f75Srin           flags |= FLAGS_VFPV2_USED;
427bdd3372bSjoerg         }
428bdd3372bSjoerg       } else {
42985f18f75Srin         if ((flags & FLAGS_VFPV3_USED) == 0) {
43085f18f75Srin           lazyVFPv3();
43185f18f75Srin           flags |= FLAGS_VFPV3_USED;
432bdd3372bSjoerg         }
433bdd3372bSjoerg       }
434eb98b3ccSmatt       memcpy(fpreg + (num - REGNO_ARM32_D0), addr, sizeof(fpreg[0]));
435eb98b3ccSmatt     }
436994a5fb3Srin   }
437eb98b3ccSmatt 
43885f18f75Srin   __dso_hidden void lazyVFPv2();
43985f18f75Srin   __dso_hidden void lazyVFPv3();
440eb98b3ccSmatt   __dso_hidden void jumpto() const __dead;
441eb98b3ccSmatt 
442eb98b3ccSmatt private:
443eb98b3ccSmatt   uint32_t reg[REGNO_ARM32_SPSR + 1];
444bdd3372bSjoerg   uint32_t flags;
445eb98b3ccSmatt   uint64_t fpreg[32];
4461a44aed1Srin };
44785f18f75Srin 
4481a44aed1Srin #undef	FLAGS_VFPV2_USED
4491a44aed1Srin #undef	FLAGS_VFPV3_USED
4501a44aed1Srin #undef	FLAGS_LEGACY_VFPV2_REGNO
4511a44aed1Srin #undef	FLAGS_EXTENDED_VFPV2_REGNO
452eb98b3ccSmatt 
453396ee378Sjoerg enum {
454396ee378Sjoerg   DWARF_VAX_R0 = 0,
455396ee378Sjoerg   DWARF_VAX_R15 = 15,
456396ee378Sjoerg   DWARF_VAX_PSW = 16,
457396ee378Sjoerg 
458396ee378Sjoerg   REGNO_VAX_R0 = 0,
459396ee378Sjoerg   REGNO_VAX_R14 = 14,
460396ee378Sjoerg   REGNO_VAX_R15 = 15,
461396ee378Sjoerg   REGNO_VAX_PSW = 16,
462396ee378Sjoerg };
463396ee378Sjoerg 
464396ee378Sjoerg class Registers_vax {
465396ee378Sjoerg public:
466396ee378Sjoerg   enum {
467396ee378Sjoerg     LAST_REGISTER = REGNO_VAX_PSW,
468396ee378Sjoerg     LAST_RESTORE_REG = REGNO_VAX_PSW,
4699788222aSjoerg     RETURN_OFFSET = 0,
4700282220bSjoerg     RETURN_MASK = 0,
471396ee378Sjoerg   };
472396ee378Sjoerg 
473396ee378Sjoerg   __dso_hidden Registers_vax();
474396ee378Sjoerg 
475396ee378Sjoerg   static int dwarf2regno(int num) {
476396ee378Sjoerg     if (num >= DWARF_VAX_R0 && num <= DWARF_VAX_R15)
477396ee378Sjoerg       return REGNO_VAX_R0 + (num - DWARF_VAX_R0);
478396ee378Sjoerg     if (num == DWARF_VAX_PSW)
479396ee378Sjoerg       return REGNO_VAX_PSW;
480396ee378Sjoerg     return LAST_REGISTER + 1;
481396ee378Sjoerg   }
482396ee378Sjoerg 
483396ee378Sjoerg   bool validRegister(int num) const {
484396ee378Sjoerg     return num >= 0 && num <= LAST_RESTORE_REG;
485396ee378Sjoerg   }
486396ee378Sjoerg 
487396ee378Sjoerg   uint64_t getRegister(int num) const {
488396ee378Sjoerg     assert(validRegister(num));
489396ee378Sjoerg     return reg[num];
490396ee378Sjoerg   }
491396ee378Sjoerg 
492396ee378Sjoerg   void setRegister(int num, uint64_t value) {
493396ee378Sjoerg     assert(validRegister(num));
494396ee378Sjoerg     reg[num] = value;
495396ee378Sjoerg   }
496396ee378Sjoerg 
497396ee378Sjoerg   uint64_t getIP() const { return reg[REGNO_VAX_R15]; }
498396ee378Sjoerg 
499396ee378Sjoerg   void setIP(uint64_t value) { reg[REGNO_VAX_R15] = value; }
500396ee378Sjoerg 
501396ee378Sjoerg   uint64_t getSP() const { return reg[REGNO_VAX_R14]; }
502396ee378Sjoerg 
503396ee378Sjoerg   void setSP(uint64_t value) { reg[REGNO_VAX_R14] = value; }
504396ee378Sjoerg 
505396ee378Sjoerg   bool validFloatVectorRegister(int num) const {
506396ee378Sjoerg     return false;
507396ee378Sjoerg   }
508396ee378Sjoerg 
509396ee378Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
510396ee378Sjoerg   }
511396ee378Sjoerg 
512396ee378Sjoerg   __dso_hidden void jumpto() const __dead;
513396ee378Sjoerg 
514396ee378Sjoerg private:
515396ee378Sjoerg   uint32_t reg[REGNO_VAX_PSW + 1];
516396ee378Sjoerg };
517396ee378Sjoerg 
518a55c6bd8Sjoerg enum {
519a55c6bd8Sjoerg   DWARF_M68K_A0 = 0,
520a55c6bd8Sjoerg   DWARF_M68K_A7 = 7,
521a55c6bd8Sjoerg   DWARF_M68K_D0 = 8,
522a55c6bd8Sjoerg   DWARF_M68K_D7 = 15,
523c05d688cSjoerg   DWARF_M68K_FP0 = 16,
524c05d688cSjoerg   DWARF_M68K_FP7 = 23,
525a55c6bd8Sjoerg   DWARF_M68K_PC = 24,
526a55c6bd8Sjoerg 
527a55c6bd8Sjoerg   REGNO_M68K_A0 = 0,
528a55c6bd8Sjoerg   REGNO_M68K_A7 = 7,
529a55c6bd8Sjoerg   REGNO_M68K_D0 = 8,
530a55c6bd8Sjoerg   REGNO_M68K_D7 = 15,
531a55c6bd8Sjoerg   REGNO_M68K_PC = 16,
532c05d688cSjoerg   REGNO_M68K_FP0 = 17,
533c05d688cSjoerg   REGNO_M68K_FP7 = 24,
534a55c6bd8Sjoerg };
535a55c6bd8Sjoerg 
536a55c6bd8Sjoerg class Registers_M68K {
537a55c6bd8Sjoerg public:
538a55c6bd8Sjoerg   enum {
539c05d688cSjoerg     LAST_REGISTER = REGNO_M68K_FP7,
540c05d688cSjoerg     LAST_RESTORE_REG = REGNO_M68K_FP7,
5419788222aSjoerg     RETURN_OFFSET = 0,
5420282220bSjoerg     RETURN_MASK = 0,
543a55c6bd8Sjoerg   };
544a55c6bd8Sjoerg 
545a55c6bd8Sjoerg   __dso_hidden Registers_M68K();
546a55c6bd8Sjoerg 
547a55c6bd8Sjoerg   static int dwarf2regno(int num) {
548a55c6bd8Sjoerg     if (num >= DWARF_M68K_A0 && num <= DWARF_M68K_A7)
549a55c6bd8Sjoerg       return REGNO_M68K_A0 + (num - DWARF_M68K_A0);
550a55c6bd8Sjoerg     if (num >= DWARF_M68K_D0 && num <= DWARF_M68K_D7)
551a55c6bd8Sjoerg       return REGNO_M68K_D0 + (num - DWARF_M68K_D0);
552c05d688cSjoerg     if (num >= DWARF_M68K_FP0 && num <= DWARF_M68K_FP7)
553c05d688cSjoerg       return REGNO_M68K_FP0 + (num - DWARF_M68K_FP0);
554a55c6bd8Sjoerg     if (num == DWARF_M68K_PC)
555a55c6bd8Sjoerg       return REGNO_M68K_PC;
556a55c6bd8Sjoerg     return LAST_REGISTER + 1;
557a55c6bd8Sjoerg   }
558a55c6bd8Sjoerg 
559a55c6bd8Sjoerg   bool validRegister(int num) const {
560c05d688cSjoerg     return num >= 0 && num <= REGNO_M68K_PC;
561a55c6bd8Sjoerg   }
562a55c6bd8Sjoerg 
563a55c6bd8Sjoerg   uint64_t getRegister(int num) const {
564a55c6bd8Sjoerg     assert(validRegister(num));
565a55c6bd8Sjoerg     return reg[num];
566a55c6bd8Sjoerg   }
567a55c6bd8Sjoerg 
568a55c6bd8Sjoerg   void setRegister(int num, uint64_t value) {
569a55c6bd8Sjoerg     assert(validRegister(num));
570a55c6bd8Sjoerg     reg[num] = value;
571a55c6bd8Sjoerg   }
572a55c6bd8Sjoerg 
573a55c6bd8Sjoerg   uint64_t getIP() const { return reg[REGNO_M68K_PC]; }
574a55c6bd8Sjoerg 
575a55c6bd8Sjoerg   void setIP(uint64_t value) { reg[REGNO_M68K_PC] = value; }
576a55c6bd8Sjoerg 
577a55c6bd8Sjoerg   uint64_t getSP() const { return reg[REGNO_M68K_A7]; }
578a55c6bd8Sjoerg 
579a55c6bd8Sjoerg   void setSP(uint64_t value) { reg[REGNO_M68K_A7] = value; }
580a55c6bd8Sjoerg 
581a55c6bd8Sjoerg   bool validFloatVectorRegister(int num) const {
582c05d688cSjoerg     return num >= REGNO_M68K_FP0 && num <= REGNO_M68K_FP7;
583a55c6bd8Sjoerg   }
584a55c6bd8Sjoerg 
585a55c6bd8Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
586c05d688cSjoerg     assert(validFloatVectorRegister(num));
587c05d688cSjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
588c05d688cSjoerg     memcpy(fpreg + (num - REGNO_M68K_FP0), addr, sizeof(fpreg[0]));
589a55c6bd8Sjoerg   }
590a55c6bd8Sjoerg 
591a55c6bd8Sjoerg   __dso_hidden void jumpto() const __dead;
592a55c6bd8Sjoerg 
593a55c6bd8Sjoerg private:
594c05d688cSjoerg   typedef uint32_t fpreg_t[3];
595c05d688cSjoerg 
596a55c6bd8Sjoerg   uint32_t reg[REGNO_M68K_PC + 1];
597c05d688cSjoerg   uint32_t dummy;
598c05d688cSjoerg   fpreg_t fpreg[8];
599a55c6bd8Sjoerg };
600a55c6bd8Sjoerg 
601a280fb92Sjoerg enum {
602a280fb92Sjoerg   DWARF_SH3_R0 = 0,
603a280fb92Sjoerg   DWARF_SH3_R15 = 15,
604a280fb92Sjoerg   DWARF_SH3_PC = 16,
605a280fb92Sjoerg   DWARF_SH3_PR = 17,
606a280fb92Sjoerg 
607a280fb92Sjoerg   REGNO_SH3_R0 = 0,
608a280fb92Sjoerg   REGNO_SH3_R15 = 15,
609a280fb92Sjoerg   REGNO_SH3_PC = 16,
610a280fb92Sjoerg   REGNO_SH3_PR = 17,
611a280fb92Sjoerg };
612a280fb92Sjoerg 
613a280fb92Sjoerg class Registers_SH3 {
614a280fb92Sjoerg public:
615a280fb92Sjoerg   enum {
616a280fb92Sjoerg     LAST_REGISTER = REGNO_SH3_PR,
617a280fb92Sjoerg     LAST_RESTORE_REG = REGNO_SH3_PR,
6189788222aSjoerg     RETURN_OFFSET = 0,
6190282220bSjoerg     RETURN_MASK = 0,
620a280fb92Sjoerg   };
621a280fb92Sjoerg 
622a280fb92Sjoerg   __dso_hidden Registers_SH3();
623a280fb92Sjoerg 
624a280fb92Sjoerg   static int dwarf2regno(int num) {
625a280fb92Sjoerg     if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15)
626a280fb92Sjoerg       return REGNO_SH3_R0 + (num - DWARF_SH3_R0);
627a280fb92Sjoerg     if (num == DWARF_SH3_PC)
628a280fb92Sjoerg       return REGNO_SH3_PC;
629a280fb92Sjoerg     if (num == DWARF_SH3_PR)
630a280fb92Sjoerg       return REGNO_SH3_PR;
631a280fb92Sjoerg     return LAST_REGISTER + 1;
632a280fb92Sjoerg   }
633a280fb92Sjoerg 
634a280fb92Sjoerg   bool validRegister(int num) const {
635a280fb92Sjoerg     return num >= 0 && num <= REGNO_SH3_PR;
636a280fb92Sjoerg   }
637a280fb92Sjoerg 
638a280fb92Sjoerg   uint64_t getRegister(int num) const {
639a280fb92Sjoerg     assert(validRegister(num));
640a280fb92Sjoerg     return reg[num];
641a280fb92Sjoerg   }
642a280fb92Sjoerg 
643a280fb92Sjoerg   void setRegister(int num, uint64_t value) {
644a280fb92Sjoerg     assert(validRegister(num));
645a280fb92Sjoerg     reg[num] = value;
646a280fb92Sjoerg   }
647a280fb92Sjoerg 
648a280fb92Sjoerg   uint64_t getIP() const { return reg[REGNO_SH3_PC]; }
649a280fb92Sjoerg 
650a280fb92Sjoerg   void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; }
651a280fb92Sjoerg 
652a280fb92Sjoerg   uint64_t getSP() const { return reg[REGNO_SH3_R15]; }
653a280fb92Sjoerg 
654a280fb92Sjoerg   void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; }
655a280fb92Sjoerg 
656a280fb92Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
657a280fb92Sjoerg 
658a280fb92Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {}
659a280fb92Sjoerg 
660a280fb92Sjoerg   __dso_hidden void jumpto() const __dead;
661a280fb92Sjoerg 
662a280fb92Sjoerg private:
663a280fb92Sjoerg   uint32_t reg[REGNO_SH3_PR + 1];
664a280fb92Sjoerg };
665a280fb92Sjoerg 
666f5cf7457Sjoerg enum {
667f5cf7457Sjoerg   DWARF_SPARC64_R0 = 0,
668f5cf7457Sjoerg   DWARF_SPARC64_R31 = 31,
669f5cf7457Sjoerg   DWARF_SPARC64_PC = 32,
670f5cf7457Sjoerg 
671f5cf7457Sjoerg   REGNO_SPARC64_R0 = 0,
672f5cf7457Sjoerg   REGNO_SPARC64_R14 = 14,
673f5cf7457Sjoerg   REGNO_SPARC64_R15 = 15,
674f5cf7457Sjoerg   REGNO_SPARC64_R31 = 31,
675f5cf7457Sjoerg   REGNO_SPARC64_PC = 32,
676f5cf7457Sjoerg };
677f5cf7457Sjoerg 
678f5cf7457Sjoerg class Registers_SPARC64 {
679f5cf7457Sjoerg public:
680f5cf7457Sjoerg   enum {
681f5cf7457Sjoerg     LAST_REGISTER = REGNO_SPARC64_PC,
682f5cf7457Sjoerg     LAST_RESTORE_REG = REGNO_SPARC64_PC,
683f5cf7457Sjoerg     RETURN_OFFSET = 8,
6840282220bSjoerg     RETURN_MASK = 0,
685f5cf7457Sjoerg   };
686f5cf7457Sjoerg   typedef uint64_t reg_t;
687f5cf7457Sjoerg 
688f5cf7457Sjoerg   __dso_hidden Registers_SPARC64();
689f5cf7457Sjoerg 
690f5cf7457Sjoerg   static int dwarf2regno(int num) {
691f5cf7457Sjoerg     if (num >= DWARF_SPARC64_R0 && num <= DWARF_SPARC64_R31)
692f5cf7457Sjoerg       return REGNO_SPARC64_R0 + (num - DWARF_SPARC64_R0);
693f5cf7457Sjoerg     if (num == DWARF_SPARC64_PC)
694f5cf7457Sjoerg       return REGNO_SPARC64_PC;
695f5cf7457Sjoerg     return LAST_REGISTER + 1;
696f5cf7457Sjoerg   }
697f5cf7457Sjoerg 
698f5cf7457Sjoerg   bool validRegister(int num) const {
699f5cf7457Sjoerg     return num >= 0 && num <= REGNO_SPARC64_PC;
700f5cf7457Sjoerg   }
701f5cf7457Sjoerg 
702f5cf7457Sjoerg   uint64_t getRegister(int num) const {
703f5cf7457Sjoerg     assert(validRegister(num));
704f5cf7457Sjoerg     return reg[num];
705f5cf7457Sjoerg   }
706f5cf7457Sjoerg 
707f5cf7457Sjoerg   void setRegister(int num, uint64_t value) {
708f5cf7457Sjoerg     assert(validRegister(num));
709f5cf7457Sjoerg     reg[num] = value;
710f5cf7457Sjoerg   }
711f5cf7457Sjoerg 
712f5cf7457Sjoerg   uint64_t getIP() const { return reg[REGNO_SPARC64_PC]; }
713f5cf7457Sjoerg 
714f5cf7457Sjoerg   void setIP(uint64_t value) { reg[REGNO_SPARC64_PC] = value; }
715f5cf7457Sjoerg 
716f5cf7457Sjoerg   uint64_t getSP() const { return reg[REGNO_SPARC64_R14]; }
717f5cf7457Sjoerg 
718f5cf7457Sjoerg   void setSP(uint64_t value) { reg[REGNO_SPARC64_R14] = value; }
719f5cf7457Sjoerg 
720f5cf7457Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
721f5cf7457Sjoerg 
722f5cf7457Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {}
723f5cf7457Sjoerg 
724f5cf7457Sjoerg   __dso_hidden void jumpto() const __dead;
725f5cf7457Sjoerg 
726f5cf7457Sjoerg private:
727f5cf7457Sjoerg   uint64_t reg[REGNO_SPARC64_PC + 1];
728f5cf7457Sjoerg };
729f5cf7457Sjoerg 
730f5cf7457Sjoerg enum {
731f5cf7457Sjoerg   DWARF_SPARC_R0 = 0,
732f5cf7457Sjoerg   DWARF_SPARC_R31 = 31,
733f5cf7457Sjoerg   DWARF_SPARC_PC = 32,
734f5cf7457Sjoerg 
735f5cf7457Sjoerg   REGNO_SPARC_R0 = 0,
736f5cf7457Sjoerg   REGNO_SPARC_R14 = 14,
737f5cf7457Sjoerg   REGNO_SPARC_R15 = 15,
738f5cf7457Sjoerg   REGNO_SPARC_R31 = 31,
739f5cf7457Sjoerg   REGNO_SPARC_PC = 32,
740f5cf7457Sjoerg };
741f5cf7457Sjoerg 
742f5cf7457Sjoerg class Registers_SPARC {
743f5cf7457Sjoerg public:
744f5cf7457Sjoerg   enum {
745f5cf7457Sjoerg     LAST_REGISTER = REGNO_SPARC_PC,
746f5cf7457Sjoerg     LAST_RESTORE_REG = REGNO_SPARC_PC,
747f5cf7457Sjoerg     RETURN_OFFSET = 8,
7480282220bSjoerg     RETURN_MASK = 0,
749f5cf7457Sjoerg   };
750f5cf7457Sjoerg   typedef uint32_t reg_t;
751f5cf7457Sjoerg 
752f5cf7457Sjoerg   __dso_hidden Registers_SPARC();
753f5cf7457Sjoerg 
754f5cf7457Sjoerg   static int dwarf2regno(int num) {
755f5cf7457Sjoerg     if (num >= DWARF_SPARC_R0 && num <= DWARF_SPARC_R31)
756f5cf7457Sjoerg       return REGNO_SPARC_R0 + (num - DWARF_SPARC_R0);
757f5cf7457Sjoerg     if (num == DWARF_SPARC_PC)
758f5cf7457Sjoerg       return REGNO_SPARC_PC;
759f5cf7457Sjoerg     return LAST_REGISTER + 1;
760f5cf7457Sjoerg   }
761f5cf7457Sjoerg 
762f5cf7457Sjoerg   bool validRegister(int num) const {
763f5cf7457Sjoerg     return num >= 0 && num <= REGNO_SPARC_PC;
764f5cf7457Sjoerg   }
765f5cf7457Sjoerg 
766f5cf7457Sjoerg   uint64_t getRegister(int num) const {
767f5cf7457Sjoerg     assert(validRegister(num));
768f5cf7457Sjoerg     return reg[num];
769f5cf7457Sjoerg   }
770f5cf7457Sjoerg 
771f5cf7457Sjoerg   void setRegister(int num, uint64_t value) {
772f5cf7457Sjoerg     assert(validRegister(num));
773f5cf7457Sjoerg     reg[num] = value;
774f5cf7457Sjoerg   }
775f5cf7457Sjoerg 
776f5cf7457Sjoerg   uint64_t getIP() const { return reg[REGNO_SPARC_PC]; }
777f5cf7457Sjoerg 
778f5cf7457Sjoerg   void setIP(uint64_t value) { reg[REGNO_SPARC_PC] = value; }
779f5cf7457Sjoerg 
780f5cf7457Sjoerg   uint64_t getSP() const { return reg[REGNO_SPARC_R14]; }
781f5cf7457Sjoerg 
782f5cf7457Sjoerg   void setSP(uint64_t value) { reg[REGNO_SPARC_R14] = value; }
783f5cf7457Sjoerg 
784f5cf7457Sjoerg   bool validFloatVectorRegister(int num) const { return false; }
785f5cf7457Sjoerg 
786f5cf7457Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {}
787f5cf7457Sjoerg 
788f5cf7457Sjoerg   __dso_hidden void jumpto() const __dead;
789f5cf7457Sjoerg 
790f5cf7457Sjoerg private:
791f5cf7457Sjoerg   uint32_t reg[REGNO_SPARC_PC + 1];
792f5cf7457Sjoerg };
793f5cf7457Sjoerg 
794e3d4269aSjoerg enum {
795e3d4269aSjoerg   DWARF_ALPHA_R0 = 0,
796e3d4269aSjoerg   DWARF_ALPHA_R30 = 30,
797e3d4269aSjoerg   DWARF_ALPHA_F0 = 32,
798e3d4269aSjoerg   DWARF_ALPHA_F30 = 62,
799*aa2e0e12Sthorpej   DWARF_ALPHA_SIGRETURN = 64,
800e3d4269aSjoerg 
801e3d4269aSjoerg   REGNO_ALPHA_R0 = 0,
802e3d4269aSjoerg   REGNO_ALPHA_R26 = 26,
803e3d4269aSjoerg   REGNO_ALPHA_R30 = 30,
804e3d4269aSjoerg   REGNO_ALPHA_PC = 31,
805e3d4269aSjoerg   REGNO_ALPHA_F0 = 32,
806e3d4269aSjoerg   REGNO_ALPHA_F30 = 62,
807*aa2e0e12Sthorpej   REGNO_ALPHA_SIGRETURN = 64,
808e3d4269aSjoerg };
809e3d4269aSjoerg 
810e3d4269aSjoerg class Registers_Alpha {
811e3d4269aSjoerg public:
812e3d4269aSjoerg   enum {
813*aa2e0e12Sthorpej     LAST_REGISTER = REGNO_ALPHA_SIGRETURN,
814*aa2e0e12Sthorpej     LAST_RESTORE_REG = REGNO_ALPHA_SIGRETURN,
815e3d4269aSjoerg     RETURN_OFFSET = 0,
8160282220bSjoerg     RETURN_MASK = 0,
817e3d4269aSjoerg   };
818e3d4269aSjoerg   typedef uint32_t reg_t;
819e3d4269aSjoerg 
820e3d4269aSjoerg   __dso_hidden Registers_Alpha();
821e3d4269aSjoerg 
822e3d4269aSjoerg   static int dwarf2regno(int num) { return num; }
823e3d4269aSjoerg 
824e3d4269aSjoerg   bool validRegister(int num) const {
825*aa2e0e12Sthorpej     return (num >= 0 && num <= REGNO_ALPHA_PC) ||
826*aa2e0e12Sthorpej 	num == REGNO_ALPHA_SIGRETURN;
827e3d4269aSjoerg   }
828e3d4269aSjoerg 
829e3d4269aSjoerg   uint64_t getRegister(int num) const {
830e3d4269aSjoerg     assert(validRegister(num));
831*aa2e0e12Sthorpej     if (num == REGNO_ALPHA_SIGRETURN)
832*aa2e0e12Sthorpej       return sigreturn_reg;
833*aa2e0e12Sthorpej     else
834e3d4269aSjoerg       return reg[num];
835e3d4269aSjoerg   }
836e3d4269aSjoerg 
837e3d4269aSjoerg   void setRegister(int num, uint64_t value) {
838e3d4269aSjoerg     assert(validRegister(num));
839*aa2e0e12Sthorpej     if (num == REGNO_ALPHA_SIGRETURN)
840*aa2e0e12Sthorpej       sigreturn_reg = value;
841*aa2e0e12Sthorpej     else
842e3d4269aSjoerg       reg[num] = value;
843e3d4269aSjoerg   }
844e3d4269aSjoerg 
845e3d4269aSjoerg   uint64_t getIP() const { return reg[REGNO_ALPHA_PC]; }
846e3d4269aSjoerg 
847e3d4269aSjoerg   void setIP(uint64_t value) { reg[REGNO_ALPHA_PC] = value; }
848e3d4269aSjoerg 
849e3d4269aSjoerg   uint64_t getSP() const { return reg[REGNO_ALPHA_R30]; }
850e3d4269aSjoerg 
851e3d4269aSjoerg   void setSP(uint64_t value) { reg[REGNO_ALPHA_R30] = value; }
852e3d4269aSjoerg 
853e3d4269aSjoerg   bool validFloatVectorRegister(int num) const {
854e3d4269aSjoerg     return num >= REGNO_ALPHA_F0 && num <= REGNO_ALPHA_F30;
855e3d4269aSjoerg   }
856e3d4269aSjoerg 
857e3d4269aSjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
858e3d4269aSjoerg     assert(validFloatVectorRegister(num));
859e3d4269aSjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
860e3d4269aSjoerg     memcpy(fpreg + (num - REGNO_ALPHA_F0), addr, sizeof(fpreg[0]));
861e3d4269aSjoerg   }
862e3d4269aSjoerg 
863e3d4269aSjoerg   __dso_hidden void jumpto() const __dead;
864e3d4269aSjoerg 
865e3d4269aSjoerg private:
866e3d4269aSjoerg   uint64_t reg[REGNO_ALPHA_PC + 1];
867e3d4269aSjoerg   uint64_t fpreg[31];
868*aa2e0e12Sthorpej   uint64_t sigreturn_reg;
869e3d4269aSjoerg };
870e3d4269aSjoerg 
871a78e9b23Sjoerg enum {
872a78e9b23Sjoerg   DWARF_HPPA_R1 = 1,
873a78e9b23Sjoerg   DWARF_HPPA_R31 = 31,
874a78e9b23Sjoerg   DWARF_HPPA_FR4L = 32,
875a78e9b23Sjoerg   DWARF_HPPA_FR31H = 87,
876a78e9b23Sjoerg 
877a78e9b23Sjoerg   REGNO_HPPA_PC = 0,
878a78e9b23Sjoerg   REGNO_HPPA_R1 = 1,
879a78e9b23Sjoerg   REGNO_HPPA_R2 = 2,
880a78e9b23Sjoerg   REGNO_HPPA_R30 = 30,
881a78e9b23Sjoerg   REGNO_HPPA_R31 = 31,
882a78e9b23Sjoerg   REGNO_HPPA_FR4L = 32,
883a78e9b23Sjoerg   REGNO_HPPA_FR31H = 87,
884a78e9b23Sjoerg };
885a78e9b23Sjoerg 
886a78e9b23Sjoerg class Registers_HPPA {
887a78e9b23Sjoerg public:
888a78e9b23Sjoerg   enum {
889a78e9b23Sjoerg     LAST_REGISTER = REGNO_HPPA_FR31H,
890a78e9b23Sjoerg     LAST_RESTORE_REG = REGNO_HPPA_FR31H,
8910282220bSjoerg     RETURN_OFFSET = 0,
8920282220bSjoerg     RETURN_MASK = 3,
893a78e9b23Sjoerg   };
894a78e9b23Sjoerg 
895a78e9b23Sjoerg   __dso_hidden Registers_HPPA();
896a78e9b23Sjoerg 
897a78e9b23Sjoerg   static int dwarf2regno(int num) {
898a78e9b23Sjoerg     if (num >= DWARF_HPPA_R1 && num <= DWARF_HPPA_R31)
899a78e9b23Sjoerg       return REGNO_HPPA_R1 + (num - DWARF_HPPA_R1);
900a78e9b23Sjoerg     if (num >= DWARF_HPPA_FR4L && num <= DWARF_HPPA_FR31H)
901a78e9b23Sjoerg       return REGNO_HPPA_FR4L + (num - DWARF_HPPA_FR31H);
902a78e9b23Sjoerg     return LAST_REGISTER + 1;
903a78e9b23Sjoerg   }
904a78e9b23Sjoerg 
905a78e9b23Sjoerg   bool validRegister(int num) const {
906a78e9b23Sjoerg     return num >= REGNO_HPPA_PC && num <= REGNO_HPPA_R31;
907a78e9b23Sjoerg   }
908a78e9b23Sjoerg 
909a78e9b23Sjoerg   uint64_t getRegister(int num) const {
910a78e9b23Sjoerg     assert(validRegister(num));
911a78e9b23Sjoerg     return reg[num];
912a78e9b23Sjoerg   }
913a78e9b23Sjoerg 
914a78e9b23Sjoerg   void setRegister(int num, uint64_t value) {
915a78e9b23Sjoerg     assert(validRegister(num));
916a78e9b23Sjoerg     reg[num] = value;
917a78e9b23Sjoerg   }
918a78e9b23Sjoerg 
919a78e9b23Sjoerg   uint64_t getIP() const { return reg[REGNO_HPPA_PC]; }
920a78e9b23Sjoerg 
921a78e9b23Sjoerg   void setIP(uint64_t value) { reg[REGNO_HPPA_PC] = value; }
922a78e9b23Sjoerg 
923a78e9b23Sjoerg   uint64_t getSP() const { return reg[REGNO_HPPA_R30]; }
924a78e9b23Sjoerg 
925a78e9b23Sjoerg   void setSP(uint64_t value) { reg[REGNO_HPPA_R30] = value; }
926a78e9b23Sjoerg 
927a78e9b23Sjoerg   bool validFloatVectorRegister(int num) const {
928a78e9b23Sjoerg     return num >= REGNO_HPPA_FR4L && num <= REGNO_HPPA_FR31H;
929a78e9b23Sjoerg   }
930a78e9b23Sjoerg 
931a78e9b23Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
932a78e9b23Sjoerg     assert(validFloatVectorRegister(num));
933a78e9b23Sjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
934a78e9b23Sjoerg     memcpy(fpreg + (num - REGNO_HPPA_FR4L), addr, sizeof(fpreg[0]));
935a78e9b23Sjoerg   }
936a78e9b23Sjoerg 
937a78e9b23Sjoerg   __dso_hidden void jumpto() const __dead;
938a78e9b23Sjoerg 
939a78e9b23Sjoerg private:
940a78e9b23Sjoerg   uint32_t reg[REGNO_HPPA_R31 + 1];
941a78e9b23Sjoerg   uint32_t fpreg[56];
942a78e9b23Sjoerg };
943a78e9b23Sjoerg 
944ed444622Sjoerg enum {
945ed444622Sjoerg   DWARF_MIPS_R1 = 0,
946ed444622Sjoerg   DWARF_MIPS_R31 = 31,
947ed444622Sjoerg   DWARF_MIPS_F0 = 32,
948ed444622Sjoerg   DWARF_MIPS_F31 = 63,
94992db81e4Sthorpej   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
95092db81e4Sthorpej   // signal handler return address.
95192db81e4Sthorpej   DWARF_MIPS_MDHI = 64,
95292db81e4Sthorpej   DWARF_MIPS_MDLO = 65,
95392db81e4Sthorpej   DWARF_MIPS_SIGRETURN = 66,
954ed444622Sjoerg 
955ed444622Sjoerg   REGNO_MIPS_PC = 0,
956ed444622Sjoerg   REGNO_MIPS_R1 = 0,
957ed444622Sjoerg   REGNO_MIPS_R29 = 29,
958ed444622Sjoerg   REGNO_MIPS_R31 = 31,
959ed444622Sjoerg   REGNO_MIPS_F0 = 33,
96092db81e4Sthorpej   REGNO_MIPS_F31 = 64,
96192db81e4Sthorpej   // these live in other_reg[]
96292db81e4Sthorpej   REGNO_MIPS_MDHI = 65,
96392db81e4Sthorpej   REGNO_MIPS_MDLO = 66,
96492db81e4Sthorpej   REGNO_MIPS_SIGRETURN = 67
965ed444622Sjoerg };
966ed444622Sjoerg 
967ed444622Sjoerg class Registers_MIPS {
968ed444622Sjoerg public:
969ed444622Sjoerg   enum {
97092db81e4Sthorpej     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
97192db81e4Sthorpej     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
972ed444622Sjoerg     RETURN_OFFSET = 0,
9730282220bSjoerg     RETURN_MASK = 0,
974ed444622Sjoerg   };
975ed444622Sjoerg 
976ed444622Sjoerg   __dso_hidden Registers_MIPS();
977ed444622Sjoerg 
978ed444622Sjoerg   static int dwarf2regno(int num) {
979ed444622Sjoerg     if (num >= DWARF_MIPS_R1 && num <= DWARF_MIPS_R31)
980ed444622Sjoerg       return REGNO_MIPS_R1 + (num - DWARF_MIPS_R1);
981ed444622Sjoerg     if (num >= DWARF_MIPS_F0 && num <= DWARF_MIPS_F31)
982ed444622Sjoerg       return REGNO_MIPS_F0 + (num - DWARF_MIPS_F0);
98392db81e4Sthorpej     if (num >= DWARF_MIPS_MDHI && num <= DWARF_MIPS_SIGRETURN)
98492db81e4Sthorpej       return REGNO_MIPS_MDHI + (num - DWARF_MIPS_MDHI);
985ed444622Sjoerg     return LAST_REGISTER + 1;
986ed444622Sjoerg   }
987ed444622Sjoerg 
988ed444622Sjoerg   bool validRegister(int num) const {
98992db81e4Sthorpej     return (num >= REGNO_MIPS_PC && num <= REGNO_MIPS_R31) ||
99092db81e4Sthorpej       (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN);
991ed444622Sjoerg   }
992ed444622Sjoerg 
993ed444622Sjoerg   uint64_t getRegister(int num) const {
994ed444622Sjoerg     assert(validRegister(num));
99592db81e4Sthorpej     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
99692db81e4Sthorpej       return other_reg[num - REGNO_MIPS_MDHI];
997ed444622Sjoerg     return reg[num];
998ed444622Sjoerg   }
999ed444622Sjoerg 
1000ed444622Sjoerg   void setRegister(int num, uint64_t value) {
1001ed444622Sjoerg     assert(validRegister(num));
100292db81e4Sthorpej     if (num >= REGNO_MIPS_MDHI && num <= REGNO_MIPS_SIGRETURN)
100392db81e4Sthorpej       other_reg[num - REGNO_MIPS_MDHI] = value;
100492db81e4Sthorpej     else
1005ed444622Sjoerg       reg[num] = value;
1006ed444622Sjoerg   }
1007ed444622Sjoerg 
1008ed444622Sjoerg   uint64_t getIP() const { return reg[REGNO_MIPS_PC]; }
1009ed444622Sjoerg 
1010ed444622Sjoerg   void setIP(uint64_t value) { reg[REGNO_MIPS_PC] = value; }
1011ed444622Sjoerg 
1012ed444622Sjoerg   uint64_t getSP() const { return reg[REGNO_MIPS_R29]; }
1013ed444622Sjoerg 
1014ed444622Sjoerg   void setSP(uint64_t value) { reg[REGNO_MIPS_R29] = value; }
1015ed444622Sjoerg 
1016ed444622Sjoerg   bool validFloatVectorRegister(int num) const {
101792db81e4Sthorpej     return num >= REGNO_MIPS_F0 && num <= REGNO_MIPS_F31;
1018ed444622Sjoerg   }
1019ed444622Sjoerg 
1020ed444622Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
1021ed444622Sjoerg     assert(validFloatVectorRegister(num));
1022ed444622Sjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
1023ed444622Sjoerg     memcpy(fpreg + (num - REGNO_MIPS_F0), addr, sizeof(fpreg[0]));
1024ed444622Sjoerg   }
1025ed444622Sjoerg 
1026ed444622Sjoerg   __dso_hidden void jumpto() const __dead;
1027ed444622Sjoerg 
1028ed444622Sjoerg private:
1029ed444622Sjoerg   uint32_t reg[REGNO_MIPS_R31 + 1];
1030ed444622Sjoerg   uint64_t fpreg[32];
103192db81e4Sthorpej   uint32_t other_reg[3];
1032ed444622Sjoerg };
1033ed444622Sjoerg 
1034ed444622Sjoerg enum {
1035ed444622Sjoerg   DWARF_MIPS64_R1 = 0,
1036ed444622Sjoerg   DWARF_MIPS64_R31 = 31,
1037ed444622Sjoerg   DWARF_MIPS64_F0 = 32,
1038ed444622Sjoerg   DWARF_MIPS64_F31 = 63,
1039b751d63aSthorpej   // DWARF Pseudo-registers used by GCC on MIPS for MD{HI,LO} and
1040b751d63aSthorpej   // signal handler return address.
1041b751d63aSthorpej   DWARF_MIPS64_MDHI = 64,
1042b751d63aSthorpej   DWARF_MIPS64_MDLO = 65,
1043b751d63aSthorpej   DWARF_MIPS64_SIGRETURN = 66,
1044ed444622Sjoerg 
1045ed444622Sjoerg   REGNO_MIPS64_PC = 0,
1046ed444622Sjoerg   REGNO_MIPS64_R1 = 0,
1047ed444622Sjoerg   REGNO_MIPS64_R29 = 29,
1048ed444622Sjoerg   REGNO_MIPS64_R31 = 31,
1049ed444622Sjoerg   REGNO_MIPS64_F0 = 33,
1050b751d63aSthorpej   REGNO_MIPS64_F31 = 64,
1051b751d63aSthorpej   // these live in other_reg[]
1052b751d63aSthorpej   REGNO_MIPS64_MDHI = 65,
1053b751d63aSthorpej   REGNO_MIPS64_MDLO = 66,
1054b751d63aSthorpej   REGNO_MIPS64_SIGRETURN = 67
1055ed444622Sjoerg };
1056ed444622Sjoerg 
1057ed444622Sjoerg class Registers_MIPS64 {
1058ed444622Sjoerg public:
1059ed444622Sjoerg   enum {
1060b751d63aSthorpej     LAST_REGISTER = REGNO_MIPS_SIGRETURN,
1061b751d63aSthorpej     LAST_RESTORE_REG = REGNO_MIPS_SIGRETURN,
1062ed444622Sjoerg     RETURN_OFFSET = 0,
10630282220bSjoerg     RETURN_MASK = 0,
1064ed444622Sjoerg   };
1065ed444622Sjoerg 
1066ed444622Sjoerg   __dso_hidden Registers_MIPS64();
1067ed444622Sjoerg 
1068ed444622Sjoerg   static int dwarf2regno(int num) {
1069ed444622Sjoerg     if (num >= DWARF_MIPS64_R1 && num <= DWARF_MIPS64_R31)
1070ed444622Sjoerg       return REGNO_MIPS64_R1 + (num - DWARF_MIPS64_R1);
1071ed444622Sjoerg     if (num >= DWARF_MIPS64_F0 && num <= DWARF_MIPS64_F31)
1072ed444622Sjoerg       return REGNO_MIPS64_F0 + (num - DWARF_MIPS64_F0);
1073b751d63aSthorpej     if (num >= DWARF_MIPS64_MDHI && num <= DWARF_MIPS64_SIGRETURN)
1074b751d63aSthorpej       return REGNO_MIPS64_MDHI + (num - DWARF_MIPS64_MDHI);
1075ed444622Sjoerg     return LAST_REGISTER + 1;
1076ed444622Sjoerg   }
1077ed444622Sjoerg 
1078ed444622Sjoerg   bool validRegister(int num) const {
1079b751d63aSthorpej     return num >= REGNO_MIPS64_PC && num <= REGNO_MIPS64_R31 ||
1080b751d63aSthorpej         (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN);
1081ed444622Sjoerg   }
1082ed444622Sjoerg 
1083ed444622Sjoerg   uint64_t getRegister(int num) const {
1084ed444622Sjoerg     assert(validRegister(num));
1085b751d63aSthorpej     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1086b751d63aSthorpej       return other_reg[num - REGNO_MIPS64_MDHI];
1087ed444622Sjoerg     return reg[num];
1088ed444622Sjoerg   }
1089ed444622Sjoerg 
1090ed444622Sjoerg   void setRegister(int num, uint64_t value) {
1091ed444622Sjoerg     assert(validRegister(num));
1092b751d63aSthorpej     if (num >= REGNO_MIPS64_MDHI && num <= REGNO_MIPS64_SIGRETURN)
1093b751d63aSthorpej       other_reg[num - REGNO_MIPS64_MDHI] = value;
1094b751d63aSthorpej     else
1095ed444622Sjoerg       reg[num] = value;
1096ed444622Sjoerg   }
1097ed444622Sjoerg 
1098ed444622Sjoerg   uint64_t getIP() const { return reg[REGNO_MIPS64_PC]; }
1099ed444622Sjoerg 
1100ed444622Sjoerg   void setIP(uint64_t value) { reg[REGNO_MIPS64_PC] = value; }
1101ed444622Sjoerg 
1102ed444622Sjoerg   uint64_t getSP() const { return reg[REGNO_MIPS64_R29]; }
1103ed444622Sjoerg 
1104ed444622Sjoerg   void setSP(uint64_t value) { reg[REGNO_MIPS64_R29] = value; }
1105ed444622Sjoerg 
1106ed444622Sjoerg   bool validFloatVectorRegister(int num) const {
1107b751d63aSthorpej     return num >= REGNO_MIPS64_F0 && num <= REGNO_MIPS64_F31;
1108ed444622Sjoerg   }
1109ed444622Sjoerg 
1110ed444622Sjoerg   void copyFloatVectorRegister(int num, uint64_t addr_) {
1111ed444622Sjoerg     assert(validFloatVectorRegister(num));
1112ed444622Sjoerg     const void *addr = reinterpret_cast<const void *>(addr_);
1113ed444622Sjoerg     memcpy(fpreg + (num - REGNO_MIPS64_F0), addr, sizeof(fpreg[0]));
1114ed444622Sjoerg   }
1115ed444622Sjoerg 
1116ed444622Sjoerg   __dso_hidden void jumpto() const __dead;
1117ed444622Sjoerg 
1118ed444622Sjoerg private:
1119ed444622Sjoerg   uint64_t reg[REGNO_MIPS64_R31 + 1];
1120ed444622Sjoerg   uint64_t fpreg[32];
1121b751d63aSthorpej   uint64_t other_reg[3];
1122ed444622Sjoerg };
1123ed444622Sjoerg 
1124938bf86eSmatt enum {
1125938bf86eSmatt   DWARF_OR1K_R0 = 0,
1126938bf86eSmatt   DWARF_OR1K_SP = 1,
1127938bf86eSmatt   DWARF_OR1K_LR = 9,
1128938bf86eSmatt   DWARF_OR1K_R31 = 31,
1129938bf86eSmatt   DWARF_OR1K_FPCSR = 32,
1130938bf86eSmatt 
1131938bf86eSmatt   REGNO_OR1K_R0 = 0,
1132938bf86eSmatt   REGNO_OR1K_SP = 1,
1133938bf86eSmatt   REGNO_OR1K_LR = 9,
1134938bf86eSmatt   REGNO_OR1K_R31 = 31,
1135938bf86eSmatt   REGNO_OR1K_FPCSR = 32,
1136938bf86eSmatt };
1137938bf86eSmatt 
1138938bf86eSmatt class Registers_or1k {
1139938bf86eSmatt public:
1140938bf86eSmatt   enum {
1141938bf86eSmatt     LAST_REGISTER = REGNO_OR1K_FPCSR,
1142938bf86eSmatt     LAST_RESTORE_REG = REGNO_OR1K_FPCSR,
1143938bf86eSmatt     RETURN_OFFSET = 0,
11440282220bSjoerg     RETURN_MASK = 0,
1145938bf86eSmatt   };
1146938bf86eSmatt 
1147938bf86eSmatt   __dso_hidden Registers_or1k();
1148938bf86eSmatt 
1149938bf86eSmatt   static int dwarf2regno(int num) {
1150938bf86eSmatt     if (num >= DWARF_OR1K_R0 && num <= DWARF_OR1K_R31)
1151938bf86eSmatt       return REGNO_OR1K_R0 + (num - DWARF_OR1K_R0);
1152938bf86eSmatt     if (num == DWARF_OR1K_FPCSR)
1153938bf86eSmatt       return REGNO_OR1K_FPCSR;
1154938bf86eSmatt     return LAST_REGISTER + 1;
1155938bf86eSmatt   }
1156938bf86eSmatt 
1157938bf86eSmatt   bool validRegister(int num) const {
1158938bf86eSmatt     return num >= 0 && num <= LAST_RESTORE_REG;
1159938bf86eSmatt   }
1160938bf86eSmatt 
1161938bf86eSmatt   uint64_t getRegister(int num) const {
1162938bf86eSmatt     assert(validRegister(num));
1163938bf86eSmatt     return reg[num];
1164938bf86eSmatt   }
1165938bf86eSmatt 
1166938bf86eSmatt   void setRegister(int num, uint64_t value) {
1167938bf86eSmatt     assert(validRegister(num));
1168938bf86eSmatt     reg[num] = value;
1169938bf86eSmatt   }
1170938bf86eSmatt 
1171938bf86eSmatt   uint64_t getIP() const { return reg[REGNO_OR1K_LR]; }
1172938bf86eSmatt 
1173938bf86eSmatt   void setIP(uint64_t value) { reg[REGNO_OR1K_LR] = value; }
1174938bf86eSmatt 
1175938bf86eSmatt   uint64_t getSP() const { return reg[REGNO_OR1K_SP]; }
1176938bf86eSmatt 
1177938bf86eSmatt   void setSP(uint64_t value) { reg[REGNO_OR1K_SP] = value; }
1178938bf86eSmatt 
1179938bf86eSmatt   bool validFloatVectorRegister(int num) const {
1180938bf86eSmatt     return false;
1181938bf86eSmatt   }
1182938bf86eSmatt 
1183938bf86eSmatt   void copyFloatVectorRegister(int num, uint64_t addr_) {
1184938bf86eSmatt   }
1185938bf86eSmatt 
1186938bf86eSmatt   __dso_hidden void jumpto() const __dead;
1187938bf86eSmatt 
1188938bf86eSmatt private:
1189938bf86eSmatt   uint32_t reg[REGNO_OR1K_FPCSR + 1];
1190938bf86eSmatt };
1191938bf86eSmatt 
1192a6ecde39Sjoerg #if __i386__
1193a6ecde39Sjoerg typedef Registers_x86 NativeUnwindRegisters;
1194a6ecde39Sjoerg #elif __x86_64__
1195a6ecde39Sjoerg typedef Registers_x86_64 NativeUnwindRegisters;
1196a6ecde39Sjoerg #elif __powerpc__
1197a6ecde39Sjoerg typedef Registers_ppc32 NativeUnwindRegisters;
1198aa37019dSmatt #elif __aarch64__
1199aa37019dSmatt typedef Registers_aarch64 NativeUnwindRegisters;
1200bdd3372bSjoerg #elif __arm__
1201a6ecde39Sjoerg typedef Registers_arm32 NativeUnwindRegisters;
1202a6ecde39Sjoerg #elif __vax__
1203a6ecde39Sjoerg typedef Registers_vax NativeUnwindRegisters;
1204a6ecde39Sjoerg #elif __m68k__
1205a6ecde39Sjoerg typedef Registers_M68K NativeUnwindRegisters;
1206ed444622Sjoerg #elif __mips_n64 || __mips_n32
1207ed444622Sjoerg typedef Registers_MIPS64 NativeUnwindRegisters;
1208ed444622Sjoerg #elif __mips__
1209ed444622Sjoerg typedef Registers_MIPS NativeUnwindRegisters;
1210a6ecde39Sjoerg #elif __sh3__
1211a6ecde39Sjoerg typedef Registers_SH3 NativeUnwindRegisters;
1212f5cf7457Sjoerg #elif __sparc64__
1213f5cf7457Sjoerg typedef Registers_SPARC64 NativeUnwindRegisters;
1214f5cf7457Sjoerg #elif __sparc__
1215f5cf7457Sjoerg typedef Registers_SPARC NativeUnwindRegisters;
1216e3d4269aSjoerg #elif __alpha__
1217e3d4269aSjoerg typedef Registers_Alpha NativeUnwindRegisters;
1218a78e9b23Sjoerg #elif __hppa__
1219a78e9b23Sjoerg typedef Registers_HPPA NativeUnwindRegisters;
1220938bf86eSmatt #elif __or1k__
1221938bf86eSmatt typedef Registers_or1k NativeUnwindRegisters;
1222a6ecde39Sjoerg #endif
1223aa0b96d0Sjoerg } // namespace _Unwind
1224aa0b96d0Sjoerg 
1225aa0b96d0Sjoerg #endif // __REGISTERS_HPP__
1226