blob: ff57c6076fe0000bb4cea6d8c14afbc4e9da4987 [file] [log] [blame]
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001//===----------------------------- Registers.hpp --------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//
9// Models register sets for supported processors.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef __REGISTERS_HPP__
14#define __REGISTERS_HPP__
15
16#include <stdint.h>
Saleem Abdulrasool675df582015-04-24 19:39:17 +000017#include <string.h>
18
19#include "libunwind.h"
20#include "config.h"
21
22namespace libunwind {
23
24// For emulating 128-bit registers
25struct v128 { uint32_t vec[4]; };
26
27
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +000028#if defined(_LIBUNWIND_TARGET_I386)
Saleem Abdulrasool675df582015-04-24 19:39:17 +000029/// Registers_x86 holds the register state of a thread in a 32-bit intel
30/// process.
31class _LIBUNWIND_HIDDEN Registers_x86 {
32public:
33 Registers_x86();
34 Registers_x86(const void *registers);
35
36 bool validRegister(int num) const;
37 uint32_t getRegister(int num) const;
38 void setRegister(int num, uint32_t value);
39 bool validFloatRegister(int) const { return false; }
40 double getFloatRegister(int num) const;
41 void setFloatRegister(int num, double value);
42 bool validVectorRegister(int) const { return false; }
43 v128 getVectorRegister(int num) const;
44 void setVectorRegister(int num, v128 value);
45 const char *getRegisterName(int num);
46 void jumpto();
47 static int lastDwarfRegNum() { return 8; }
48
49 uint32_t getSP() const { return _registers.__esp; }
50 void setSP(uint32_t value) { _registers.__esp = value; }
51 uint32_t getIP() const { return _registers.__eip; }
52 void setIP(uint32_t value) { _registers.__eip = value; }
53 uint32_t getEBP() const { return _registers.__ebp; }
54 void setEBP(uint32_t value) { _registers.__ebp = value; }
55 uint32_t getEBX() const { return _registers.__ebx; }
56 void setEBX(uint32_t value) { _registers.__ebx = value; }
57 uint32_t getECX() const { return _registers.__ecx; }
58 void setECX(uint32_t value) { _registers.__ecx = value; }
59 uint32_t getEDX() const { return _registers.__edx; }
60 void setEDX(uint32_t value) { _registers.__edx = value; }
61 uint32_t getESI() const { return _registers.__esi; }
62 void setESI(uint32_t value) { _registers.__esi = value; }
63 uint32_t getEDI() const { return _registers.__edi; }
64 void setEDI(uint32_t value) { _registers.__edi = value; }
65
66private:
67 struct GPRs {
68 unsigned int __eax;
69 unsigned int __ebx;
70 unsigned int __ecx;
71 unsigned int __edx;
72 unsigned int __edi;
73 unsigned int __esi;
74 unsigned int __ebp;
75 unsigned int __esp;
76 unsigned int __ss;
77 unsigned int __eflags;
78 unsigned int __eip;
79 unsigned int __cs;
80 unsigned int __ds;
81 unsigned int __es;
82 unsigned int __fs;
83 unsigned int __gs;
84 };
85
86 GPRs _registers;
87};
88
89inline Registers_x86::Registers_x86(const void *registers) {
Asiri Rathnayake98bc6762016-05-26 21:45:54 +000090 static_assert((check_fit<Registers_x86, unw_context_t>::does_fit),
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +000091 "x86 registers do not fit into unw_context_t");
Saleem Abdulrasool675df582015-04-24 19:39:17 +000092 memcpy(&_registers, registers, sizeof(_registers));
93}
94
95inline Registers_x86::Registers_x86() {
96 memset(&_registers, 0, sizeof(_registers));
97}
98
99inline bool Registers_x86::validRegister(int regNum) const {
100 if (regNum == UNW_REG_IP)
101 return true;
102 if (regNum == UNW_REG_SP)
103 return true;
104 if (regNum < 0)
105 return false;
106 if (regNum > 7)
107 return false;
108 return true;
109}
110
111inline uint32_t Registers_x86::getRegister(int regNum) const {
112 switch (regNum) {
113 case UNW_REG_IP:
114 return _registers.__eip;
115 case UNW_REG_SP:
116 return _registers.__esp;
117 case UNW_X86_EAX:
118 return _registers.__eax;
119 case UNW_X86_ECX:
120 return _registers.__ecx;
121 case UNW_X86_EDX:
122 return _registers.__edx;
123 case UNW_X86_EBX:
124 return _registers.__ebx;
Saleem Abdulrasoolaa805e42017-01-21 16:22:59 +0000125#if !defined(__APPLE__)
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000126 case UNW_X86_ESP:
Saleem Abdulrasoolaa805e42017-01-21 16:22:59 +0000127#else
128 case UNW_X86_EBP:
129#endif
130 return _registers.__ebp;
131#if !defined(__APPLE__)
132 case UNW_X86_EBP:
133#else
134 case UNW_X86_ESP:
135#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000136 return _registers.__esp;
137 case UNW_X86_ESI:
138 return _registers.__esi;
139 case UNW_X86_EDI:
140 return _registers.__edi;
141 }
142 _LIBUNWIND_ABORT("unsupported x86 register");
143}
144
145inline void Registers_x86::setRegister(int regNum, uint32_t value) {
146 switch (regNum) {
147 case UNW_REG_IP:
148 _registers.__eip = value;
149 return;
150 case UNW_REG_SP:
151 _registers.__esp = value;
152 return;
153 case UNW_X86_EAX:
154 _registers.__eax = value;
155 return;
156 case UNW_X86_ECX:
157 _registers.__ecx = value;
158 return;
159 case UNW_X86_EDX:
160 _registers.__edx = value;
161 return;
162 case UNW_X86_EBX:
163 _registers.__ebx = value;
164 return;
Saleem Abdulrasoolaa805e42017-01-21 16:22:59 +0000165#if !defined(__APPLE__)
166 case UNW_X86_ESP:
167#else
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000168 case UNW_X86_EBP:
Saleem Abdulrasoolaa805e42017-01-21 16:22:59 +0000169#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000170 _registers.__ebp = value;
171 return;
Saleem Abdulrasoolaa805e42017-01-21 16:22:59 +0000172#if !defined(__APPLE__)
173 case UNW_X86_EBP:
174#else
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000175 case UNW_X86_ESP:
Saleem Abdulrasoolaa805e42017-01-21 16:22:59 +0000176#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000177 _registers.__esp = value;
178 return;
179 case UNW_X86_ESI:
180 _registers.__esi = value;
181 return;
182 case UNW_X86_EDI:
183 _registers.__edi = value;
184 return;
185 }
186 _LIBUNWIND_ABORT("unsupported x86 register");
187}
188
189inline const char *Registers_x86::getRegisterName(int regNum) {
190 switch (regNum) {
191 case UNW_REG_IP:
192 return "ip";
193 case UNW_REG_SP:
194 return "esp";
195 case UNW_X86_EAX:
196 return "eax";
197 case UNW_X86_ECX:
198 return "ecx";
199 case UNW_X86_EDX:
200 return "edx";
201 case UNW_X86_EBX:
202 return "ebx";
203 case UNW_X86_EBP:
204 return "ebp";
205 case UNW_X86_ESP:
206 return "esp";
207 case UNW_X86_ESI:
208 return "esi";
209 case UNW_X86_EDI:
210 return "edi";
211 default:
212 return "unknown register";
213 }
214}
215
216inline double Registers_x86::getFloatRegister(int) const {
217 _LIBUNWIND_ABORT("no x86 float registers");
218}
219
220inline void Registers_x86::setFloatRegister(int, double) {
221 _LIBUNWIND_ABORT("no x86 float registers");
222}
223
224inline v128 Registers_x86::getVectorRegister(int) const {
225 _LIBUNWIND_ABORT("no x86 vector registers");
226}
227
228inline void Registers_x86::setVectorRegister(int, v128) {
229 _LIBUNWIND_ABORT("no x86 vector registers");
230}
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +0000231#endif // _LIBUNWIND_TARGET_I386
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000232
233
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +0000234#if defined(_LIBUNWIND_TARGET_X86_64)
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000235/// Registers_x86_64 holds the register state of a thread in a 64-bit intel
236/// process.
237class _LIBUNWIND_HIDDEN Registers_x86_64 {
238public:
239 Registers_x86_64();
240 Registers_x86_64(const void *registers);
241
242 bool validRegister(int num) const;
243 uint64_t getRegister(int num) const;
244 void setRegister(int num, uint64_t value);
245 bool validFloatRegister(int) const { return false; }
246 double getFloatRegister(int num) const;
247 void setFloatRegister(int num, double value);
248 bool validVectorRegister(int) const { return false; }
249 v128 getVectorRegister(int num) const;
250 void setVectorRegister(int num, v128 value);
251 const char *getRegisterName(int num);
252 void jumpto();
253 static int lastDwarfRegNum() { return 16; }
254
255 uint64_t getSP() const { return _registers.__rsp; }
256 void setSP(uint64_t value) { _registers.__rsp = value; }
257 uint64_t getIP() const { return _registers.__rip; }
258 void setIP(uint64_t value) { _registers.__rip = value; }
259 uint64_t getRBP() const { return _registers.__rbp; }
260 void setRBP(uint64_t value) { _registers.__rbp = value; }
261 uint64_t getRBX() const { return _registers.__rbx; }
262 void setRBX(uint64_t value) { _registers.__rbx = value; }
263 uint64_t getR12() const { return _registers.__r12; }
264 void setR12(uint64_t value) { _registers.__r12 = value; }
265 uint64_t getR13() const { return _registers.__r13; }
266 void setR13(uint64_t value) { _registers.__r13 = value; }
267 uint64_t getR14() const { return _registers.__r14; }
268 void setR14(uint64_t value) { _registers.__r14 = value; }
269 uint64_t getR15() const { return _registers.__r15; }
270 void setR15(uint64_t value) { _registers.__r15 = value; }
271
272private:
273 struct GPRs {
274 uint64_t __rax;
275 uint64_t __rbx;
276 uint64_t __rcx;
277 uint64_t __rdx;
278 uint64_t __rdi;
279 uint64_t __rsi;
280 uint64_t __rbp;
281 uint64_t __rsp;
282 uint64_t __r8;
283 uint64_t __r9;
284 uint64_t __r10;
285 uint64_t __r11;
286 uint64_t __r12;
287 uint64_t __r13;
288 uint64_t __r14;
289 uint64_t __r15;
290 uint64_t __rip;
291 uint64_t __rflags;
292 uint64_t __cs;
293 uint64_t __fs;
294 uint64_t __gs;
295 };
296 GPRs _registers;
297};
298
299inline Registers_x86_64::Registers_x86_64(const void *registers) {
Asiri Rathnayake98bc6762016-05-26 21:45:54 +0000300 static_assert((check_fit<Registers_x86_64, unw_context_t>::does_fit),
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +0000301 "x86_64 registers do not fit into unw_context_t");
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000302 memcpy(&_registers, registers, sizeof(_registers));
303}
304
305inline Registers_x86_64::Registers_x86_64() {
306 memset(&_registers, 0, sizeof(_registers));
307}
308
309inline bool Registers_x86_64::validRegister(int regNum) const {
310 if (regNum == UNW_REG_IP)
311 return true;
312 if (regNum == UNW_REG_SP)
313 return true;
314 if (regNum < 0)
315 return false;
316 if (regNum > 15)
317 return false;
318 return true;
319}
320
321inline uint64_t Registers_x86_64::getRegister(int regNum) const {
322 switch (regNum) {
323 case UNW_REG_IP:
324 return _registers.__rip;
325 case UNW_REG_SP:
326 return _registers.__rsp;
327 case UNW_X86_64_RAX:
328 return _registers.__rax;
329 case UNW_X86_64_RDX:
330 return _registers.__rdx;
331 case UNW_X86_64_RCX:
332 return _registers.__rcx;
333 case UNW_X86_64_RBX:
334 return _registers.__rbx;
335 case UNW_X86_64_RSI:
336 return _registers.__rsi;
337 case UNW_X86_64_RDI:
338 return _registers.__rdi;
339 case UNW_X86_64_RBP:
340 return _registers.__rbp;
341 case UNW_X86_64_RSP:
342 return _registers.__rsp;
343 case UNW_X86_64_R8:
344 return _registers.__r8;
345 case UNW_X86_64_R9:
346 return _registers.__r9;
347 case UNW_X86_64_R10:
348 return _registers.__r10;
349 case UNW_X86_64_R11:
350 return _registers.__r11;
351 case UNW_X86_64_R12:
352 return _registers.__r12;
353 case UNW_X86_64_R13:
354 return _registers.__r13;
355 case UNW_X86_64_R14:
356 return _registers.__r14;
357 case UNW_X86_64_R15:
358 return _registers.__r15;
359 }
360 _LIBUNWIND_ABORT("unsupported x86_64 register");
361}
362
363inline void Registers_x86_64::setRegister(int regNum, uint64_t value) {
364 switch (regNum) {
365 case UNW_REG_IP:
366 _registers.__rip = value;
367 return;
368 case UNW_REG_SP:
369 _registers.__rsp = value;
370 return;
371 case UNW_X86_64_RAX:
372 _registers.__rax = value;
373 return;
374 case UNW_X86_64_RDX:
375 _registers.__rdx = value;
376 return;
377 case UNW_X86_64_RCX:
378 _registers.__rcx = value;
379 return;
380 case UNW_X86_64_RBX:
381 _registers.__rbx = value;
382 return;
383 case UNW_X86_64_RSI:
384 _registers.__rsi = value;
385 return;
386 case UNW_X86_64_RDI:
387 _registers.__rdi = value;
388 return;
389 case UNW_X86_64_RBP:
390 _registers.__rbp = value;
391 return;
392 case UNW_X86_64_RSP:
393 _registers.__rsp = value;
394 return;
395 case UNW_X86_64_R8:
396 _registers.__r8 = value;
397 return;
398 case UNW_X86_64_R9:
399 _registers.__r9 = value;
400 return;
401 case UNW_X86_64_R10:
402 _registers.__r10 = value;
403 return;
404 case UNW_X86_64_R11:
405 _registers.__r11 = value;
406 return;
407 case UNW_X86_64_R12:
408 _registers.__r12 = value;
409 return;
410 case UNW_X86_64_R13:
411 _registers.__r13 = value;
412 return;
413 case UNW_X86_64_R14:
414 _registers.__r14 = value;
415 return;
416 case UNW_X86_64_R15:
417 _registers.__r15 = value;
418 return;
419 }
420 _LIBUNWIND_ABORT("unsupported x86_64 register");
421}
422
423inline const char *Registers_x86_64::getRegisterName(int regNum) {
424 switch (regNum) {
425 case UNW_REG_IP:
426 return "rip";
427 case UNW_REG_SP:
428 return "rsp";
429 case UNW_X86_64_RAX:
430 return "rax";
431 case UNW_X86_64_RDX:
432 return "rdx";
433 case UNW_X86_64_RCX:
434 return "rcx";
435 case UNW_X86_64_RBX:
436 return "rbx";
437 case UNW_X86_64_RSI:
438 return "rsi";
439 case UNW_X86_64_RDI:
440 return "rdi";
441 case UNW_X86_64_RBP:
442 return "rbp";
443 case UNW_X86_64_RSP:
444 return "rsp";
445 case UNW_X86_64_R8:
446 return "r8";
447 case UNW_X86_64_R9:
448 return "r9";
449 case UNW_X86_64_R10:
450 return "r10";
451 case UNW_X86_64_R11:
452 return "r11";
453 case UNW_X86_64_R12:
454 return "r12";
455 case UNW_X86_64_R13:
456 return "r13";
457 case UNW_X86_64_R14:
458 return "r14";
459 case UNW_X86_64_R15:
460 return "r15";
461 default:
462 return "unknown register";
463 }
464}
465
466inline double Registers_x86_64::getFloatRegister(int) const {
467 _LIBUNWIND_ABORT("no x86_64 float registers");
468}
469
470inline void Registers_x86_64::setFloatRegister(int, double) {
471 _LIBUNWIND_ABORT("no x86_64 float registers");
472}
473
474inline v128 Registers_x86_64::getVectorRegister(int) const {
475 _LIBUNWIND_ABORT("no x86_64 vector registers");
476}
477
478inline void Registers_x86_64::setVectorRegister(int, v128) {
479 _LIBUNWIND_ABORT("no x86_64 vector registers");
480}
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +0000481#endif // _LIBUNWIND_TARGET_X86_64
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000482
483
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +0000484#if defined(_LIBUNWIND_TARGET_PPC)
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000485/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC
486/// process.
487class _LIBUNWIND_HIDDEN Registers_ppc {
488public:
489 Registers_ppc();
490 Registers_ppc(const void *registers);
491
492 bool validRegister(int num) const;
493 uint32_t getRegister(int num) const;
494 void setRegister(int num, uint32_t value);
495 bool validFloatRegister(int num) const;
496 double getFloatRegister(int num) const;
497 void setFloatRegister(int num, double value);
498 bool validVectorRegister(int num) const;
499 v128 getVectorRegister(int num) const;
500 void setVectorRegister(int num, v128 value);
501 const char *getRegisterName(int num);
502 void jumpto();
503 static int lastDwarfRegNum() { return 112; }
504
505 uint64_t getSP() const { return _registers.__r1; }
506 void setSP(uint32_t value) { _registers.__r1 = value; }
507 uint64_t getIP() const { return _registers.__srr0; }
508 void setIP(uint32_t value) { _registers.__srr0 = value; }
509
510private:
511 struct ppc_thread_state_t {
512 unsigned int __srr0; /* Instruction address register (PC) */
513 unsigned int __srr1; /* Machine state register (supervisor) */
514 unsigned int __r0;
515 unsigned int __r1;
516 unsigned int __r2;
517 unsigned int __r3;
518 unsigned int __r4;
519 unsigned int __r5;
520 unsigned int __r6;
521 unsigned int __r7;
522 unsigned int __r8;
523 unsigned int __r9;
524 unsigned int __r10;
525 unsigned int __r11;
526 unsigned int __r12;
527 unsigned int __r13;
528 unsigned int __r14;
529 unsigned int __r15;
530 unsigned int __r16;
531 unsigned int __r17;
532 unsigned int __r18;
533 unsigned int __r19;
534 unsigned int __r20;
535 unsigned int __r21;
536 unsigned int __r22;
537 unsigned int __r23;
538 unsigned int __r24;
539 unsigned int __r25;
540 unsigned int __r26;
541 unsigned int __r27;
542 unsigned int __r28;
543 unsigned int __r29;
544 unsigned int __r30;
545 unsigned int __r31;
546 unsigned int __cr; /* Condition register */
547 unsigned int __xer; /* User's integer exception register */
548 unsigned int __lr; /* Link register */
549 unsigned int __ctr; /* Count register */
550 unsigned int __mq; /* MQ register (601 only) */
551 unsigned int __vrsave; /* Vector Save Register */
552 };
553
554 struct ppc_float_state_t {
555 double __fpregs[32];
556
557 unsigned int __fpscr_pad; /* fpscr is 64 bits, 32 bits of rubbish */
558 unsigned int __fpscr; /* floating point status register */
559 };
560
561 ppc_thread_state_t _registers;
562 ppc_float_state_t _floatRegisters;
563 v128 _vectorRegisters[32]; // offset 424
564};
565
566inline Registers_ppc::Registers_ppc(const void *registers) {
Asiri Rathnayake98bc6762016-05-26 21:45:54 +0000567 static_assert((check_fit<Registers_ppc, unw_context_t>::does_fit),
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +0000568 "ppc registers do not fit into unw_context_t");
Saleem Abdulrasool675df582015-04-24 19:39:17 +0000569 memcpy(&_registers, static_cast<const uint8_t *>(registers),
570 sizeof(_registers));
571 static_assert(sizeof(ppc_thread_state_t) == 160,
572 "expected float register offset to be 160");
573 memcpy(&_floatRegisters,
574 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t),
575 sizeof(_floatRegisters));
576 static_assert(sizeof(ppc_thread_state_t) + sizeof(ppc_float_state_t) == 424,
577 "expected vector register offset to be 424 bytes");
578 memcpy(_vectorRegisters,
579 static_cast<const uint8_t *>(registers) + sizeof(ppc_thread_state_t) +
580 sizeof(ppc_float_state_t),
581 sizeof(_vectorRegisters));
582}
583
584inline Registers_ppc::Registers_ppc() {
585 memset(&_registers, 0, sizeof(_registers));
586 memset(&_floatRegisters, 0, sizeof(_floatRegisters));
587 memset(&_vectorRegisters, 0, sizeof(_vectorRegisters));
588}
589
590inline bool Registers_ppc::validRegister(int regNum) const {
591 if (regNum == UNW_REG_IP)
592 return true;
593 if (regNum == UNW_REG_SP)
594 return true;
595 if (regNum == UNW_PPC_VRSAVE)
596 return true;
597 if (regNum < 0)
598 return false;
599 if (regNum <= UNW_PPC_R31)
600 return true;
601 if (regNum == UNW_PPC_MQ)
602 return true;
603 if (regNum == UNW_PPC_LR)
604 return true;
605 if (regNum == UNW_PPC_CTR)
606 return true;
607 if ((UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7))
608 return true;
609 return false;
610}
611
612inline uint32_t Registers_ppc::getRegister(int regNum) const {
613 switch (regNum) {
614 case UNW_REG_IP:
615 return _registers.__srr0;
616 case UNW_REG_SP:
617 return _registers.__r1;
618 case UNW_PPC_R0:
619 return _registers.__r0;
620 case UNW_PPC_R1:
621 return _registers.__r1;
622 case UNW_PPC_R2:
623 return _registers.__r2;
624 case UNW_PPC_R3:
625 return _registers.__r3;
626 case UNW_PPC_R4:
627 return _registers.__r4;
628 case UNW_PPC_R5:
629 return _registers.__r5;
630 case UNW_PPC_R6:
631 return _registers.__r6;
632 case UNW_PPC_R7:
633 return _registers.__r7;
634 case UNW_PPC_R8:
635 return _registers.__r8;
636 case UNW_PPC_R9:
637 return _registers.__r9;
638 case UNW_PPC_R10:
639 return _registers.__r10;
640 case UNW_PPC_R11:
641 return _registers.__r11;
642 case UNW_PPC_R12:
643 return _registers.__r12;
644 case UNW_PPC_R13:
645 return _registers.__r13;
646 case UNW_PPC_R14:
647 return _registers.__r14;
648 case UNW_PPC_R15:
649 return _registers.__r15;
650 case UNW_PPC_R16:
651 return _registers.__r16;
652 case UNW_PPC_R17:
653 return _registers.__r17;
654 case UNW_PPC_R18:
655 return _registers.__r18;
656 case UNW_PPC_R19:
657 return _registers.__r19;
658 case UNW_PPC_R20:
659 return _registers.__r20;
660 case UNW_PPC_R21:
661 return _registers.__r21;
662 case UNW_PPC_R22:
663 return _registers.__r22;
664 case UNW_PPC_R23:
665 return _registers.__r23;
666 case UNW_PPC_R24:
667 return _registers.__r24;
668 case UNW_PPC_R25:
669 return _registers.__r25;
670 case UNW_PPC_R26:
671 return _registers.__r26;
672 case UNW_PPC_R27:
673 return _registers.__r27;
674 case UNW_PPC_R28:
675 return _registers.__r28;
676 case UNW_PPC_R29:
677 return _registers.__r29;
678 case UNW_PPC_R30:
679 return _registers.__r30;
680 case UNW_PPC_R31:
681 return _registers.__r31;
682 case UNW_PPC_LR:
683 return _registers.__lr;
684 case UNW_PPC_CR0:
685 return (_registers.__cr & 0xF0000000);
686 case UNW_PPC_CR1:
687 return (_registers.__cr & 0x0F000000);
688 case UNW_PPC_CR2:
689 return (_registers.__cr & 0x00F00000);
690 case UNW_PPC_CR3:
691 return (_registers.__cr & 0x000F0000);
692 case UNW_PPC_CR4:
693 return (_registers.__cr & 0x0000F000);
694 case UNW_PPC_CR5:
695 return (_registers.__cr & 0x00000F00);
696 case UNW_PPC_CR6:
697 return (_registers.__cr & 0x000000F0);
698 case UNW_PPC_CR7:
699 return (_registers.__cr & 0x0000000F);
700 case UNW_PPC_VRSAVE:
701 return _registers.__vrsave;
702 }
703 _LIBUNWIND_ABORT("unsupported ppc register");
704}
705
706inline void Registers_ppc::setRegister(int regNum, uint32_t value) {
707 //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value);
708 switch (regNum) {
709 case UNW_REG_IP:
710 _registers.__srr0 = value;
711 return;
712 case UNW_REG_SP:
713 _registers.__r1 = value;
714 return;
715 case UNW_PPC_R0:
716 _registers.__r0 = value;
717 return;
718 case UNW_PPC_R1:
719 _registers.__r1 = value;
720 return;
721 case UNW_PPC_R2:
722 _registers.__r2 = value;
723 return;
724 case UNW_PPC_R3:
725 _registers.__r3 = value;
726 return;
727 case UNW_PPC_R4:
728 _registers.__r4 = value;
729 return;
730 case UNW_PPC_R5:
731 _registers.__r5 = value;
732 return;
733 case UNW_PPC_R6:
734 _registers.__r6 = value;
735 return;
736 case UNW_PPC_R7:
737 _registers.__r7 = value;
738 return;
739 case UNW_PPC_R8:
740 _registers.__r8 = value;
741 return;
742 case UNW_PPC_R9:
743 _registers.__r9 = value;
744 return;
745 case UNW_PPC_R10:
746 _registers.__r10 = value;
747 return;
748 case UNW_PPC_R11:
749 _registers.__r11 = value;
750 return;
751 case UNW_PPC_R12:
752 _registers.__r12 = value;
753 return;
754 case UNW_PPC_R13:
755 _registers.__r13 = value;
756 return;
757 case UNW_PPC_R14:
758 _registers.__r14 = value;
759 return;
760 case UNW_PPC_R15:
761 _registers.__r15 = value;
762 return;
763 case UNW_PPC_R16:
764 _registers.__r16 = value;
765 return;
766 case UNW_PPC_R17:
767 _registers.__r17 = value;
768 return;
769 case UNW_PPC_R18:
770 _registers.__r18 = value;
771 return;
772 case UNW_PPC_R19:
773 _registers.__r19 = value;
774 return;
775 case UNW_PPC_R20:
776 _registers.__r20 = value;
777 return;
778 case UNW_PPC_R21:
779 _registers.__r21 = value;
780 return;
781 case UNW_PPC_R22:
782 _registers.__r22 = value;
783 return;
784 case UNW_PPC_R23:
785 _registers.__r23 = value;
786 return;
787 case UNW_PPC_R24:
788 _registers.__r24 = value;
789 return;
790 case UNW_PPC_R25:
791 _registers.__r25 = value;
792 return;
793 case UNW_PPC_R26:
794 _registers.__r26 = value;
795 return;
796 case UNW_PPC_R27:
797 _registers.__r27 = value;
798 return;
799 case UNW_PPC_R28:
800 _registers.__r28 = value;
801 return;
802 case UNW_PPC_R29:
803 _registers.__r29 = value;
804 return;
805 case UNW_PPC_R30:
806 _registers.__r30 = value;
807 return;
808 case UNW_PPC_R31:
809 _registers.__r31 = value;
810 return;
811 case UNW_PPC_MQ:
812 _registers.__mq = value;
813 return;
814 case UNW_PPC_LR:
815 _registers.__lr = value;
816 return;
817 case UNW_PPC_CTR:
818 _registers.__ctr = value;
819 return;
820 case UNW_PPC_CR0:
821 _registers.__cr &= 0x0FFFFFFF;
822 _registers.__cr |= (value & 0xF0000000);
823 return;
824 case UNW_PPC_CR1:
825 _registers.__cr &= 0xF0FFFFFF;
826 _registers.__cr |= (value & 0x0F000000);
827 return;
828 case UNW_PPC_CR2:
829 _registers.__cr &= 0xFF0FFFFF;
830 _registers.__cr |= (value & 0x00F00000);
831 return;
832 case UNW_PPC_CR3:
833 _registers.__cr &= 0xFFF0FFFF;
834 _registers.__cr |= (value & 0x000F0000);
835 return;
836 case UNW_PPC_CR4:
837 _registers.__cr &= 0xFFFF0FFF;
838 _registers.__cr |= (value & 0x0000F000);
839 return;
840 case UNW_PPC_CR5:
841 _registers.__cr &= 0xFFFFF0FF;
842 _registers.__cr |= (value & 0x00000F00);
843 return;
844 case UNW_PPC_CR6:
845 _registers.__cr &= 0xFFFFFF0F;
846 _registers.__cr |= (value & 0x000000F0);
847 return;
848 case UNW_PPC_CR7:
849 _registers.__cr &= 0xFFFFFFF0;
850 _registers.__cr |= (value & 0x0000000F);
851 return;
852 case UNW_PPC_VRSAVE:
853 _registers.__vrsave = value;
854 return;
855 // not saved
856 return;
857 case UNW_PPC_XER:
858 _registers.__xer = value;
859 return;
860 case UNW_PPC_AP:
861 case UNW_PPC_VSCR:
862 case UNW_PPC_SPEFSCR:
863 // not saved
864 return;
865 }
866 _LIBUNWIND_ABORT("unsupported ppc register");
867}
868
869inline bool Registers_ppc::validFloatRegister(int regNum) const {
870 if (regNum < UNW_PPC_F0)
871 return false;
872 if (regNum > UNW_PPC_F31)
873 return false;
874 return true;
875}
876
877inline double Registers_ppc::getFloatRegister(int regNum) const {
878 assert(validFloatRegister(regNum));
879 return _floatRegisters.__fpregs[regNum - UNW_PPC_F0];
880}
881
882inline void Registers_ppc::setFloatRegister(int regNum, double value) {
883 assert(validFloatRegister(regNum));
884 _floatRegisters.__fpregs[regNum - UNW_PPC_F0] = value;
885}
886
887inline bool Registers_ppc::validVectorRegister(int regNum) const {
888 if (regNum < UNW_PPC_V0)
889 return false;
890 if (regNum > UNW_PPC_V31)
891 return false;
892 return true;
893}
894
895inline v128 Registers_ppc::getVectorRegister(int regNum) const {
896 assert(validVectorRegister(regNum));
897 v128 result = _vectorRegisters[regNum - UNW_PPC_V0];
898 return result;
899}
900
901inline void Registers_ppc::setVectorRegister(int regNum, v128 value) {
902 assert(validVectorRegister(regNum));
903 _vectorRegisters[regNum - UNW_PPC_V0] = value;
904}
905
906inline const char *Registers_ppc::getRegisterName(int regNum) {
907 switch (regNum) {
908 case UNW_REG_IP:
909 return "ip";
910 case UNW_REG_SP:
911 return "sp";
912 case UNW_PPC_R0:
913 return "r0";
914 case UNW_PPC_R1:
915 return "r1";
916 case UNW_PPC_R2:
917 return "r2";
918 case UNW_PPC_R3:
919 return "r3";
920 case UNW_PPC_R4:
921 return "r4";
922 case UNW_PPC_R5:
923 return "r5";
924 case UNW_PPC_R6:
925 return "r6";
926 case UNW_PPC_R7:
927 return "r7";
928 case UNW_PPC_R8:
929 return "r8";
930 case UNW_PPC_R9:
931 return "r9";
932 case UNW_PPC_R10:
933 return "r10";
934 case UNW_PPC_R11:
935 return "r11";
936 case UNW_PPC_R12:
937 return "r12";
938 case UNW_PPC_R13:
939 return "r13";
940 case UNW_PPC_R14:
941 return "r14";
942 case UNW_PPC_R15:
943 return "r15";
944 case UNW_PPC_R16:
945 return "r16";
946 case UNW_PPC_R17:
947 return "r17";
948 case UNW_PPC_R18:
949 return "r18";
950 case UNW_PPC_R19:
951 return "r19";
952 case UNW_PPC_R20:
953 return "r20";
954 case UNW_PPC_R21:
955 return "r21";
956 case UNW_PPC_R22:
957 return "r22";
958 case UNW_PPC_R23:
959 return "r23";
960 case UNW_PPC_R24:
961 return "r24";
962 case UNW_PPC_R25:
963 return "r25";
964 case UNW_PPC_R26:
965 return "r26";
966 case UNW_PPC_R27:
967 return "r27";
968 case UNW_PPC_R28:
969 return "r28";
970 case UNW_PPC_R29:
971 return "r29";
972 case UNW_PPC_R30:
973 return "r30";
974 case UNW_PPC_R31:
975 return "r31";
976 case UNW_PPC_F0:
977 return "fp0";
978 case UNW_PPC_F1:
979 return "fp1";
980 case UNW_PPC_F2:
981 return "fp2";
982 case UNW_PPC_F3:
983 return "fp3";
984 case UNW_PPC_F4:
985 return "fp4";
986 case UNW_PPC_F5:
987 return "fp5";
988 case UNW_PPC_F6:
989 return "fp6";
990 case UNW_PPC_F7:
991 return "fp7";
992 case UNW_PPC_F8:
993 return "fp8";
994 case UNW_PPC_F9:
995 return "fp9";
996 case UNW_PPC_F10:
997 return "fp10";
998 case UNW_PPC_F11:
999 return "fp11";
1000 case UNW_PPC_F12:
1001 return "fp12";
1002 case UNW_PPC_F13:
1003 return "fp13";
1004 case UNW_PPC_F14:
1005 return "fp14";
1006 case UNW_PPC_F15:
1007 return "fp15";
1008 case UNW_PPC_F16:
1009 return "fp16";
1010 case UNW_PPC_F17:
1011 return "fp17";
1012 case UNW_PPC_F18:
1013 return "fp18";
1014 case UNW_PPC_F19:
1015 return "fp19";
1016 case UNW_PPC_F20:
1017 return "fp20";
1018 case UNW_PPC_F21:
1019 return "fp21";
1020 case UNW_PPC_F22:
1021 return "fp22";
1022 case UNW_PPC_F23:
1023 return "fp23";
1024 case UNW_PPC_F24:
1025 return "fp24";
1026 case UNW_PPC_F25:
1027 return "fp25";
1028 case UNW_PPC_F26:
1029 return "fp26";
1030 case UNW_PPC_F27:
1031 return "fp27";
1032 case UNW_PPC_F28:
1033 return "fp28";
1034 case UNW_PPC_F29:
1035 return "fp29";
1036 case UNW_PPC_F30:
1037 return "fp30";
1038 case UNW_PPC_F31:
1039 return "fp31";
1040 case UNW_PPC_LR:
1041 return "lr";
1042 default:
1043 return "unknown register";
1044 }
1045
1046}
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001047#endif // _LIBUNWIND_TARGET_PPC
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001048
1049
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001050#if defined(_LIBUNWIND_TARGET_AARCH64)
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001051/// Registers_arm64 holds the register state of a thread in a 64-bit arm
1052/// process.
1053class _LIBUNWIND_HIDDEN Registers_arm64 {
1054public:
1055 Registers_arm64();
1056 Registers_arm64(const void *registers);
1057
1058 bool validRegister(int num) const;
1059 uint64_t getRegister(int num) const;
1060 void setRegister(int num, uint64_t value);
1061 bool validFloatRegister(int num) const;
1062 double getFloatRegister(int num) const;
1063 void setFloatRegister(int num, double value);
1064 bool validVectorRegister(int num) const;
1065 v128 getVectorRegister(int num) const;
1066 void setVectorRegister(int num, v128 value);
1067 const char *getRegisterName(int num);
1068 void jumpto();
1069 static int lastDwarfRegNum() { return 95; }
1070
1071 uint64_t getSP() const { return _registers.__sp; }
1072 void setSP(uint64_t value) { _registers.__sp = value; }
1073 uint64_t getIP() const { return _registers.__pc; }
1074 void setIP(uint64_t value) { _registers.__pc = value; }
1075 uint64_t getFP() const { return _registers.__fp; }
1076 void setFP(uint64_t value) { _registers.__fp = value; }
1077
1078private:
1079 struct GPRs {
1080 uint64_t __x[29]; // x0-x28
1081 uint64_t __fp; // Frame pointer x29
1082 uint64_t __lr; // Link register x30
1083 uint64_t __sp; // Stack pointer x31
1084 uint64_t __pc; // Program counter
1085 uint64_t padding; // 16-byte align
1086 };
1087
1088 GPRs _registers;
1089 double _vectorHalfRegisters[32];
1090 // Currently only the lower double in 128-bit vectore registers
1091 // is perserved during unwinding. We could define new register
1092 // numbers (> 96) which mean whole vector registers, then this
1093 // struct would need to change to contain whole vector registers.
1094};
1095
1096inline Registers_arm64::Registers_arm64(const void *registers) {
Asiri Rathnayake98bc6762016-05-26 21:45:54 +00001097 static_assert((check_fit<Registers_arm64, unw_context_t>::does_fit),
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001098 "arm64 registers do not fit into unw_context_t");
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001099 memcpy(&_registers, registers, sizeof(_registers));
1100 static_assert(sizeof(GPRs) == 0x110,
1101 "expected VFP registers to be at offset 272");
1102 memcpy(_vectorHalfRegisters,
1103 static_cast<const uint8_t *>(registers) + sizeof(GPRs),
1104 sizeof(_vectorHalfRegisters));
1105}
1106
1107inline Registers_arm64::Registers_arm64() {
1108 memset(&_registers, 0, sizeof(_registers));
1109 memset(&_vectorHalfRegisters, 0, sizeof(_vectorHalfRegisters));
1110}
1111
1112inline bool Registers_arm64::validRegister(int regNum) const {
1113 if (regNum == UNW_REG_IP)
1114 return true;
1115 if (regNum == UNW_REG_SP)
1116 return true;
1117 if (regNum < 0)
1118 return false;
1119 if (regNum > 95)
1120 return false;
1121 if ((regNum > 31) && (regNum < 64))
1122 return false;
1123 return true;
1124}
1125
1126inline uint64_t Registers_arm64::getRegister(int regNum) const {
1127 if (regNum == UNW_REG_IP)
1128 return _registers.__pc;
1129 if (regNum == UNW_REG_SP)
1130 return _registers.__sp;
1131 if ((regNum >= 0) && (regNum < 32))
1132 return _registers.__x[regNum];
1133 _LIBUNWIND_ABORT("unsupported arm64 register");
1134}
1135
1136inline void Registers_arm64::setRegister(int regNum, uint64_t value) {
1137 if (regNum == UNW_REG_IP)
1138 _registers.__pc = value;
1139 else if (regNum == UNW_REG_SP)
1140 _registers.__sp = value;
1141 else if ((regNum >= 0) && (regNum < 32))
1142 _registers.__x[regNum] = value;
1143 else
1144 _LIBUNWIND_ABORT("unsupported arm64 register");
1145}
1146
1147inline const char *Registers_arm64::getRegisterName(int regNum) {
1148 switch (regNum) {
1149 case UNW_REG_IP:
1150 return "pc";
1151 case UNW_REG_SP:
1152 return "sp";
1153 case UNW_ARM64_X0:
1154 return "x0";
1155 case UNW_ARM64_X1:
1156 return "x1";
1157 case UNW_ARM64_X2:
1158 return "x2";
1159 case UNW_ARM64_X3:
1160 return "x3";
1161 case UNW_ARM64_X4:
1162 return "x4";
1163 case UNW_ARM64_X5:
1164 return "x5";
1165 case UNW_ARM64_X6:
1166 return "x6";
1167 case UNW_ARM64_X7:
1168 return "x7";
1169 case UNW_ARM64_X8:
1170 return "x8";
1171 case UNW_ARM64_X9:
1172 return "x9";
1173 case UNW_ARM64_X10:
1174 return "x10";
1175 case UNW_ARM64_X11:
1176 return "x11";
1177 case UNW_ARM64_X12:
1178 return "x12";
1179 case UNW_ARM64_X13:
1180 return "x13";
1181 case UNW_ARM64_X14:
1182 return "x14";
1183 case UNW_ARM64_X15:
1184 return "x15";
1185 case UNW_ARM64_X16:
1186 return "x16";
1187 case UNW_ARM64_X17:
1188 return "x17";
1189 case UNW_ARM64_X18:
1190 return "x18";
1191 case UNW_ARM64_X19:
1192 return "x19";
1193 case UNW_ARM64_X20:
1194 return "x20";
1195 case UNW_ARM64_X21:
1196 return "x21";
1197 case UNW_ARM64_X22:
1198 return "x22";
1199 case UNW_ARM64_X23:
1200 return "x23";
1201 case UNW_ARM64_X24:
1202 return "x24";
1203 case UNW_ARM64_X25:
1204 return "x25";
1205 case UNW_ARM64_X26:
1206 return "x26";
1207 case UNW_ARM64_X27:
1208 return "x27";
1209 case UNW_ARM64_X28:
1210 return "x28";
1211 case UNW_ARM64_X29:
1212 return "fp";
1213 case UNW_ARM64_X30:
1214 return "lr";
1215 case UNW_ARM64_X31:
1216 return "sp";
1217 case UNW_ARM64_D0:
1218 return "d0";
1219 case UNW_ARM64_D1:
1220 return "d1";
1221 case UNW_ARM64_D2:
1222 return "d2";
1223 case UNW_ARM64_D3:
1224 return "d3";
1225 case UNW_ARM64_D4:
1226 return "d4";
1227 case UNW_ARM64_D5:
1228 return "d5";
1229 case UNW_ARM64_D6:
1230 return "d6";
1231 case UNW_ARM64_D7:
1232 return "d7";
1233 case UNW_ARM64_D8:
1234 return "d8";
1235 case UNW_ARM64_D9:
1236 return "d9";
1237 case UNW_ARM64_D10:
1238 return "d10";
1239 case UNW_ARM64_D11:
1240 return "d11";
1241 case UNW_ARM64_D12:
1242 return "d12";
1243 case UNW_ARM64_D13:
1244 return "d13";
1245 case UNW_ARM64_D14:
1246 return "d14";
1247 case UNW_ARM64_D15:
1248 return "d15";
1249 case UNW_ARM64_D16:
1250 return "d16";
1251 case UNW_ARM64_D17:
1252 return "d17";
1253 case UNW_ARM64_D18:
1254 return "d18";
1255 case UNW_ARM64_D19:
1256 return "d19";
1257 case UNW_ARM64_D20:
1258 return "d20";
1259 case UNW_ARM64_D21:
1260 return "d21";
1261 case UNW_ARM64_D22:
1262 return "d22";
1263 case UNW_ARM64_D23:
1264 return "d23";
1265 case UNW_ARM64_D24:
1266 return "d24";
1267 case UNW_ARM64_D25:
1268 return "d25";
1269 case UNW_ARM64_D26:
1270 return "d26";
1271 case UNW_ARM64_D27:
1272 return "d27";
1273 case UNW_ARM64_D28:
1274 return "d28";
1275 case UNW_ARM64_D29:
1276 return "d29";
1277 case UNW_ARM64_D30:
1278 return "d30";
1279 case UNW_ARM64_D31:
1280 return "d31";
1281 default:
1282 return "unknown register";
1283 }
1284}
1285
1286inline bool Registers_arm64::validFloatRegister(int regNum) const {
1287 if (regNum < UNW_ARM64_D0)
1288 return false;
1289 if (regNum > UNW_ARM64_D31)
1290 return false;
1291 return true;
1292}
1293
1294inline double Registers_arm64::getFloatRegister(int regNum) const {
1295 assert(validFloatRegister(regNum));
1296 return _vectorHalfRegisters[regNum - UNW_ARM64_D0];
1297}
1298
1299inline void Registers_arm64::setFloatRegister(int regNum, double value) {
1300 assert(validFloatRegister(regNum));
1301 _vectorHalfRegisters[regNum - UNW_ARM64_D0] = value;
1302}
1303
1304inline bool Registers_arm64::validVectorRegister(int) const {
1305 return false;
1306}
1307
1308inline v128 Registers_arm64::getVectorRegister(int) const {
1309 _LIBUNWIND_ABORT("no arm64 vector register support yet");
1310}
1311
1312inline void Registers_arm64::setVectorRegister(int, v128) {
1313 _LIBUNWIND_ABORT("no arm64 vector register support yet");
1314}
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001315#endif // _LIBUNWIND_TARGET_AARCH64
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001316
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001317#if defined(_LIBUNWIND_TARGET_ARM)
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001318/// Registers_arm holds the register state of a thread in a 32-bit arm
1319/// process.
1320///
1321/// NOTE: Assumes VFPv3. On ARM processors without a floating point unit,
1322/// this uses more memory than required.
1323class _LIBUNWIND_HIDDEN Registers_arm {
1324public:
1325 Registers_arm();
1326 Registers_arm(const void *registers);
1327
1328 bool validRegister(int num) const;
1329 uint32_t getRegister(int num);
1330 void setRegister(int num, uint32_t value);
1331 bool validFloatRegister(int num) const;
1332 unw_fpreg_t getFloatRegister(int num);
1333 void setFloatRegister(int num, unw_fpreg_t value);
1334 bool validVectorRegister(int num) const;
1335 v128 getVectorRegister(int num) const;
1336 void setVectorRegister(int num, v128 value);
1337 const char *getRegisterName(int num);
1338 void jumpto() {
1339 restoreSavedFloatRegisters();
1340 restoreCoreAndJumpTo();
1341 }
1342
1343 uint32_t getSP() const { return _registers.__sp; }
1344 void setSP(uint32_t value) { _registers.__sp = value; }
1345 uint32_t getIP() const { return _registers.__pc; }
1346 void setIP(uint32_t value) { _registers.__pc = value; }
1347
1348 void saveVFPAsX() {
1349 assert(_use_X_for_vfp_save || !_saved_vfp_d0_d15);
1350 _use_X_for_vfp_save = true;
1351 }
1352
1353 void restoreSavedFloatRegisters() {
1354 if (_saved_vfp_d0_d15) {
1355 if (_use_X_for_vfp_save)
1356 restoreVFPWithFLDMX(_vfp_d0_d15_pad);
1357 else
1358 restoreVFPWithFLDMD(_vfp_d0_d15_pad);
1359 }
1360 if (_saved_vfp_d16_d31)
1361 restoreVFPv3(_vfp_d16_d31);
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001362#if defined(__ARM_WMMX)
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001363 if (_saved_iwmmx)
1364 restoreiWMMX(_iwmmx);
1365 if (_saved_iwmmx_control)
1366 restoreiWMMXControl(_iwmmx_control);
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001367#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001368 }
1369
1370private:
1371 struct GPRs {
1372 uint32_t __r[13]; // r0-r12
1373 uint32_t __sp; // Stack pointer r13
1374 uint32_t __lr; // Link register r14
1375 uint32_t __pc; // Program counter r15
1376 };
1377
1378 static void saveVFPWithFSTMD(unw_fpreg_t*);
1379 static void saveVFPWithFSTMX(unw_fpreg_t*);
1380 static void saveVFPv3(unw_fpreg_t*);
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001381 static void restoreVFPWithFLDMD(unw_fpreg_t*);
1382 static void restoreVFPWithFLDMX(unw_fpreg_t*);
1383 static void restoreVFPv3(unw_fpreg_t*);
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001384#if defined(__ARM_WMMX)
1385 static void saveiWMMX(unw_fpreg_t*);
1386 static void saveiWMMXControl(uint32_t*);
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001387 static void restoreiWMMX(unw_fpreg_t*);
1388 static void restoreiWMMXControl(uint32_t*);
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001389#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001390 void restoreCoreAndJumpTo();
1391
1392 // ARM registers
1393 GPRs _registers;
1394
1395 // We save floating point registers lazily because we can't know ahead of
1396 // time which ones are used. See EHABI #4.7.
1397
1398 // Whether D0-D15 are saved in the FTSMX instead of FSTMD format.
1399 //
1400 // See EHABI #7.5 that explains how matching instruction sequences for load
1401 // and store need to be used to correctly restore the exact register bits.
1402 bool _use_X_for_vfp_save;
1403 // Whether VFP D0-D15 are saved.
1404 bool _saved_vfp_d0_d15;
1405 // Whether VFPv3 D16-D31 are saved.
1406 bool _saved_vfp_d16_d31;
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001407 // VFP registers D0-D15, + padding if saved using FSTMX
1408 unw_fpreg_t _vfp_d0_d15_pad[17];
1409 // VFPv3 registers D16-D31, always saved using FSTMD
1410 unw_fpreg_t _vfp_d16_d31[16];
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001411#if defined(__ARM_WMMX)
1412 // Whether iWMMX data registers are saved.
1413 bool _saved_iwmmx;
1414 // Whether iWMMX control registers are saved.
1415 bool _saved_iwmmx_control;
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001416 // iWMMX registers
1417 unw_fpreg_t _iwmmx[16];
1418 // iWMMX control registers
1419 uint32_t _iwmmx_control[4];
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001420#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001421};
1422
1423inline Registers_arm::Registers_arm(const void *registers)
1424 : _use_X_for_vfp_save(false),
1425 _saved_vfp_d0_d15(false),
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001426 _saved_vfp_d16_d31(false) {
Asiri Rathnayake98bc6762016-05-26 21:45:54 +00001427 static_assert((check_fit<Registers_arm, unw_context_t>::does_fit),
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001428 "arm registers do not fit into unw_context_t");
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001429 // See unw_getcontext() note about data.
1430 memcpy(&_registers, registers, sizeof(_registers));
1431 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1432 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001433#if defined(__ARM_WMMX)
1434 _saved_iwmmx = false;
1435 _saved_iwmmx_control = false;
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001436 memset(&_iwmmx, 0, sizeof(_iwmmx));
1437 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001438#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001439}
1440
1441inline Registers_arm::Registers_arm()
1442 : _use_X_for_vfp_save(false),
1443 _saved_vfp_d0_d15(false),
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001444 _saved_vfp_d16_d31(false) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001445 memset(&_registers, 0, sizeof(_registers));
1446 memset(&_vfp_d0_d15_pad, 0, sizeof(_vfp_d0_d15_pad));
1447 memset(&_vfp_d16_d31, 0, sizeof(_vfp_d16_d31));
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001448#if defined(__ARM_WMMX)
1449 _saved_iwmmx = false;
1450 _saved_iwmmx_control = false;
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001451 memset(&_iwmmx, 0, sizeof(_iwmmx));
1452 memset(&_iwmmx_control, 0, sizeof(_iwmmx_control));
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001453#endif
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001454}
1455
1456inline bool Registers_arm::validRegister(int regNum) const {
1457 // Returns true for all non-VFP registers supported by the EHABI
1458 // virtual register set (VRS).
1459 if (regNum == UNW_REG_IP)
1460 return true;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001461
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001462 if (regNum == UNW_REG_SP)
1463 return true;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001464
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001465 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R15)
1466 return true;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001467
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001468#if defined(__ARM_WMMX)
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001469 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3)
1470 return true;
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001471#endif
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001472
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001473 return false;
1474}
1475
1476inline uint32_t Registers_arm::getRegister(int regNum) {
1477 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP)
1478 return _registers.__sp;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001479
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001480 if (regNum == UNW_ARM_LR)
1481 return _registers.__lr;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001482
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001483 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP)
1484 return _registers.__pc;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001485
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001486 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12)
1487 return _registers.__r[regNum];
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001488
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001489#if defined(__ARM_WMMX)
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001490 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
1491 if (!_saved_iwmmx_control) {
1492 _saved_iwmmx_control = true;
1493 saveiWMMXControl(_iwmmx_control);
1494 }
1495 return _iwmmx_control[regNum - UNW_ARM_WC0];
1496 }
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001497#endif
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001498
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001499 _LIBUNWIND_ABORT("unsupported arm register");
1500}
1501
1502inline void Registers_arm::setRegister(int regNum, uint32_t value) {
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001503 if (regNum == UNW_REG_SP || regNum == UNW_ARM_SP) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001504 _registers.__sp = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001505 return;
1506 }
1507
1508 if (regNum == UNW_ARM_LR) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001509 _registers.__lr = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001510 return;
1511 }
1512
1513 if (regNum == UNW_REG_IP || regNum == UNW_ARM_IP) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001514 _registers.__pc = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001515 return;
1516 }
1517
1518 if (regNum >= UNW_ARM_R0 && regNum <= UNW_ARM_R12) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001519 _registers.__r[regNum] = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001520 return;
1521 }
1522
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001523#if defined(__ARM_WMMX)
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001524 if (regNum >= UNW_ARM_WC0 && regNum <= UNW_ARM_WC3) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001525 if (!_saved_iwmmx_control) {
1526 _saved_iwmmx_control = true;
1527 saveiWMMXControl(_iwmmx_control);
1528 }
1529 _iwmmx_control[regNum - UNW_ARM_WC0] = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001530 return;
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001531 }
1532#endif
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001533
1534 _LIBUNWIND_ABORT("unsupported arm register");
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001535}
1536
1537inline const char *Registers_arm::getRegisterName(int regNum) {
1538 switch (regNum) {
1539 case UNW_REG_IP:
1540 case UNW_ARM_IP: // UNW_ARM_R15 is alias
1541 return "pc";
1542 case UNW_ARM_LR: // UNW_ARM_R14 is alias
1543 return "lr";
1544 case UNW_REG_SP:
1545 case UNW_ARM_SP: // UNW_ARM_R13 is alias
1546 return "sp";
1547 case UNW_ARM_R0:
1548 return "r0";
1549 case UNW_ARM_R1:
1550 return "r1";
1551 case UNW_ARM_R2:
1552 return "r2";
1553 case UNW_ARM_R3:
1554 return "r3";
1555 case UNW_ARM_R4:
1556 return "r4";
1557 case UNW_ARM_R5:
1558 return "r5";
1559 case UNW_ARM_R6:
1560 return "r6";
1561 case UNW_ARM_R7:
1562 return "r7";
1563 case UNW_ARM_R8:
1564 return "r8";
1565 case UNW_ARM_R9:
1566 return "r9";
1567 case UNW_ARM_R10:
1568 return "r10";
1569 case UNW_ARM_R11:
1570 return "r11";
1571 case UNW_ARM_R12:
1572 return "r12";
1573 case UNW_ARM_S0:
1574 return "s0";
1575 case UNW_ARM_S1:
1576 return "s1";
1577 case UNW_ARM_S2:
1578 return "s2";
1579 case UNW_ARM_S3:
1580 return "s3";
1581 case UNW_ARM_S4:
1582 return "s4";
1583 case UNW_ARM_S5:
1584 return "s5";
1585 case UNW_ARM_S6:
1586 return "s6";
1587 case UNW_ARM_S7:
1588 return "s7";
1589 case UNW_ARM_S8:
1590 return "s8";
1591 case UNW_ARM_S9:
1592 return "s9";
1593 case UNW_ARM_S10:
1594 return "s10";
1595 case UNW_ARM_S11:
1596 return "s11";
1597 case UNW_ARM_S12:
1598 return "s12";
1599 case UNW_ARM_S13:
1600 return "s13";
1601 case UNW_ARM_S14:
1602 return "s14";
1603 case UNW_ARM_S15:
1604 return "s15";
1605 case UNW_ARM_S16:
1606 return "s16";
1607 case UNW_ARM_S17:
1608 return "s17";
1609 case UNW_ARM_S18:
1610 return "s18";
1611 case UNW_ARM_S19:
1612 return "s19";
1613 case UNW_ARM_S20:
1614 return "s20";
1615 case UNW_ARM_S21:
1616 return "s21";
1617 case UNW_ARM_S22:
1618 return "s22";
1619 case UNW_ARM_S23:
1620 return "s23";
1621 case UNW_ARM_S24:
1622 return "s24";
1623 case UNW_ARM_S25:
1624 return "s25";
1625 case UNW_ARM_S26:
1626 return "s26";
1627 case UNW_ARM_S27:
1628 return "s27";
1629 case UNW_ARM_S28:
1630 return "s28";
1631 case UNW_ARM_S29:
1632 return "s29";
1633 case UNW_ARM_S30:
1634 return "s30";
1635 case UNW_ARM_S31:
1636 return "s31";
1637 case UNW_ARM_D0:
1638 return "d0";
1639 case UNW_ARM_D1:
1640 return "d1";
1641 case UNW_ARM_D2:
1642 return "d2";
1643 case UNW_ARM_D3:
1644 return "d3";
1645 case UNW_ARM_D4:
1646 return "d4";
1647 case UNW_ARM_D5:
1648 return "d5";
1649 case UNW_ARM_D6:
1650 return "d6";
1651 case UNW_ARM_D7:
1652 return "d7";
1653 case UNW_ARM_D8:
1654 return "d8";
1655 case UNW_ARM_D9:
1656 return "d9";
1657 case UNW_ARM_D10:
1658 return "d10";
1659 case UNW_ARM_D11:
1660 return "d11";
1661 case UNW_ARM_D12:
1662 return "d12";
1663 case UNW_ARM_D13:
1664 return "d13";
1665 case UNW_ARM_D14:
1666 return "d14";
1667 case UNW_ARM_D15:
1668 return "d15";
1669 case UNW_ARM_D16:
1670 return "d16";
1671 case UNW_ARM_D17:
1672 return "d17";
1673 case UNW_ARM_D18:
1674 return "d18";
1675 case UNW_ARM_D19:
1676 return "d19";
1677 case UNW_ARM_D20:
1678 return "d20";
1679 case UNW_ARM_D21:
1680 return "d21";
1681 case UNW_ARM_D22:
1682 return "d22";
1683 case UNW_ARM_D23:
1684 return "d23";
1685 case UNW_ARM_D24:
1686 return "d24";
1687 case UNW_ARM_D25:
1688 return "d25";
1689 case UNW_ARM_D26:
1690 return "d26";
1691 case UNW_ARM_D27:
1692 return "d27";
1693 case UNW_ARM_D28:
1694 return "d28";
1695 case UNW_ARM_D29:
1696 return "d29";
1697 case UNW_ARM_D30:
1698 return "d30";
1699 case UNW_ARM_D31:
1700 return "d31";
1701 default:
1702 return "unknown register";
1703 }
1704}
1705
1706inline bool Registers_arm::validFloatRegister(int regNum) const {
1707 // NOTE: Consider the intel MMX registers floating points so the
1708 // unw_get_fpreg can be used to transmit the 64-bit data back.
1709 return ((regNum >= UNW_ARM_D0) && (regNum <= UNW_ARM_D31))
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001710#if defined(__ARM_WMMX)
1711 || ((regNum >= UNW_ARM_WR0) && (regNum <= UNW_ARM_WR15))
1712#endif
1713 ;
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001714}
1715
1716inline unw_fpreg_t Registers_arm::getFloatRegister(int regNum) {
1717 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1718 if (!_saved_vfp_d0_d15) {
1719 _saved_vfp_d0_d15 = true;
1720 if (_use_X_for_vfp_save)
1721 saveVFPWithFSTMX(_vfp_d0_d15_pad);
1722 else
1723 saveVFPWithFSTMD(_vfp_d0_d15_pad);
1724 }
1725 return _vfp_d0_d15_pad[regNum - UNW_ARM_D0];
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001726 }
1727
1728 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001729 if (!_saved_vfp_d16_d31) {
1730 _saved_vfp_d16_d31 = true;
1731 saveVFPv3(_vfp_d16_d31);
1732 }
1733 return _vfp_d16_d31[regNum - UNW_ARM_D16];
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001734 }
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001735
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001736#if defined(__ARM_WMMX)
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001737 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001738 if (!_saved_iwmmx) {
1739 _saved_iwmmx = true;
1740 saveiWMMX(_iwmmx);
1741 }
1742 return _iwmmx[regNum - UNW_ARM_WR0];
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001743 }
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001744#endif
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001745
1746 _LIBUNWIND_ABORT("Unknown ARM float register");
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001747}
1748
1749inline void Registers_arm::setFloatRegister(int regNum, unw_fpreg_t value) {
1750 if (regNum >= UNW_ARM_D0 && regNum <= UNW_ARM_D15) {
1751 if (!_saved_vfp_d0_d15) {
1752 _saved_vfp_d0_d15 = true;
1753 if (_use_X_for_vfp_save)
1754 saveVFPWithFSTMX(_vfp_d0_d15_pad);
1755 else
1756 saveVFPWithFSTMD(_vfp_d0_d15_pad);
1757 }
1758 _vfp_d0_d15_pad[regNum - UNW_ARM_D0] = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001759 return;
1760 }
1761
1762 if (regNum >= UNW_ARM_D16 && regNum <= UNW_ARM_D31) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001763 if (!_saved_vfp_d16_d31) {
1764 _saved_vfp_d16_d31 = true;
1765 saveVFPv3(_vfp_d16_d31);
1766 }
Saleem Abdulrasool7a61b662015-08-21 03:21:31 +00001767 _vfp_d16_d31[regNum - UNW_ARM_D16] = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001768 return;
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001769 }
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001770
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001771#if defined(__ARM_WMMX)
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001772 if (regNum >= UNW_ARM_WR0 && regNum <= UNW_ARM_WR15) {
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001773 if (!_saved_iwmmx) {
1774 _saved_iwmmx = true;
1775 saveiWMMX(_iwmmx);
1776 }
1777 _iwmmx[regNum - UNW_ARM_WR0] = value;
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001778 return;
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001779 }
Asiri Rathnayake0ddaf132016-07-07 10:55:39 +00001780#endif
Asiri Rathnayake878c40b2016-07-08 12:13:31 +00001781
1782 _LIBUNWIND_ABORT("Unknown ARM float register");
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001783}
1784
1785inline bool Registers_arm::validVectorRegister(int) const {
1786 return false;
1787}
1788
1789inline v128 Registers_arm::getVectorRegister(int) const {
1790 _LIBUNWIND_ABORT("ARM vector support not implemented");
1791}
1792
1793inline void Registers_arm::setVectorRegister(int, v128) {
1794 _LIBUNWIND_ABORT("ARM vector support not implemented");
1795}
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001796#endif // _LIBUNWIND_TARGET_ARM
1797
1798
1799#if defined(_LIBUNWIND_TARGET_OR1K)
Peter Zotovd4255ab2015-08-31 05:26:37 +00001800/// Registers_or1k holds the register state of a thread in an OpenRISC1000
1801/// process.
1802class _LIBUNWIND_HIDDEN Registers_or1k {
1803public:
1804 Registers_or1k();
1805 Registers_or1k(const void *registers);
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001806
Peter Zotovd4255ab2015-08-31 05:26:37 +00001807 bool validRegister(int num) const;
1808 uint32_t getRegister(int num) const;
1809 void setRegister(int num, uint32_t value);
1810 bool validFloatRegister(int num) const;
1811 double getFloatRegister(int num) const;
1812 void setFloatRegister(int num, double value);
1813 bool validVectorRegister(int num) const;
1814 v128 getVectorRegister(int num) const;
1815 void setVectorRegister(int num, v128 value);
1816 const char *getRegisterName(int num);
1817 void jumpto();
1818 static int lastDwarfRegNum() { return 31; }
1819
1820 uint64_t getSP() const { return _registers.__r[1]; }
1821 void setSP(uint32_t value) { _registers.__r[1] = value; }
1822 uint64_t getIP() const { return _registers.__r[9]; }
1823 void setIP(uint32_t value) { _registers.__r[9] = value; }
1824
1825private:
1826 struct or1k_thread_state_t {
1827 unsigned int __r[32];
1828 };
1829
1830 or1k_thread_state_t _registers;
1831};
1832
1833inline Registers_or1k::Registers_or1k(const void *registers) {
Asiri Rathnayake98bc6762016-05-26 21:45:54 +00001834 static_assert((check_fit<Registers_or1k, unw_context_t>::does_fit),
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001835 "or1k registers do not fit into unw_context_t");
Peter Zotovd4255ab2015-08-31 05:26:37 +00001836 memcpy(&_registers, static_cast<const uint8_t *>(registers),
1837 sizeof(_registers));
1838}
1839
1840inline Registers_or1k::Registers_or1k() {
1841 memset(&_registers, 0, sizeof(_registers));
1842}
1843
1844inline bool Registers_or1k::validRegister(int regNum) const {
1845 if (regNum == UNW_REG_IP)
1846 return true;
1847 if (regNum == UNW_REG_SP)
1848 return true;
1849 if (regNum < 0)
1850 return false;
1851 if (regNum <= UNW_OR1K_R31)
1852 return true;
1853 return false;
1854}
1855
1856inline uint32_t Registers_or1k::getRegister(int regNum) const {
1857 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
1858 return _registers.__r[regNum - UNW_OR1K_R0];
1859
1860 switch (regNum) {
1861 case UNW_REG_IP:
1862 return _registers.__r[9];
1863 case UNW_REG_SP:
1864 return _registers.__r[1];
1865 }
1866 _LIBUNWIND_ABORT("unsupported or1k register");
1867}
1868
1869inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
1870 if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
1871 _registers.__r[regNum - UNW_OR1K_R0] = value;
1872 return;
1873 }
1874
1875 switch (regNum) {
1876 case UNW_REG_IP:
1877 _registers.__r[9] = value;
1878 return;
1879 case UNW_REG_SP:
1880 _registers.__r[1] = value;
1881 return;
1882 }
1883 _LIBUNWIND_ABORT("unsupported or1k register");
1884}
1885
Saleem Abdulrasool4911b2f2015-09-01 04:29:03 +00001886inline bool Registers_or1k::validFloatRegister(int /* regNum */) const {
Peter Zotovd4255ab2015-08-31 05:26:37 +00001887 return false;
1888}
1889
Saleem Abdulrasool4911b2f2015-09-01 04:29:03 +00001890inline double Registers_or1k::getFloatRegister(int /* regNum */) const {
Peter Zotovd4255ab2015-08-31 05:26:37 +00001891 _LIBUNWIND_ABORT("or1k float support not implemented");
1892}
1893
Saleem Abdulrasool4911b2f2015-09-01 04:29:03 +00001894inline void Registers_or1k::setFloatRegister(int /* regNum */,
1895 double /* value */) {
Peter Zotovd4255ab2015-08-31 05:26:37 +00001896 _LIBUNWIND_ABORT("or1k float support not implemented");
1897}
1898
Saleem Abdulrasool4911b2f2015-09-01 04:29:03 +00001899inline bool Registers_or1k::validVectorRegister(int /* regNum */) const {
Peter Zotovd4255ab2015-08-31 05:26:37 +00001900 return false;
1901}
1902
Saleem Abdulrasool4911b2f2015-09-01 04:29:03 +00001903inline v128 Registers_or1k::getVectorRegister(int /* regNum */) const {
Peter Zotovd4255ab2015-08-31 05:26:37 +00001904 _LIBUNWIND_ABORT("or1k vector support not implemented");
1905}
1906
Saleem Abdulrasool4911b2f2015-09-01 04:29:03 +00001907inline void Registers_or1k::setVectorRegister(int /* regNum */, v128 /* value */) {
Peter Zotovd4255ab2015-08-31 05:26:37 +00001908 _LIBUNWIND_ABORT("or1k vector support not implemented");
1909}
1910
1911inline const char *Registers_or1k::getRegisterName(int regNum) {
1912 switch (regNum) {
1913 case UNW_OR1K_R0:
1914 return "r0";
1915 case UNW_OR1K_R1:
1916 return "r1";
1917 case UNW_OR1K_R2:
1918 return "r2";
1919 case UNW_OR1K_R3:
1920 return "r3";
1921 case UNW_OR1K_R4:
1922 return "r4";
1923 case UNW_OR1K_R5:
1924 return "r5";
1925 case UNW_OR1K_R6:
1926 return "r6";
1927 case UNW_OR1K_R7:
1928 return "r7";
1929 case UNW_OR1K_R8:
1930 return "r8";
1931 case UNW_OR1K_R9:
1932 return "r9";
1933 case UNW_OR1K_R10:
1934 return "r10";
1935 case UNW_OR1K_R11:
1936 return "r11";
1937 case UNW_OR1K_R12:
1938 return "r12";
1939 case UNW_OR1K_R13:
1940 return "r13";
1941 case UNW_OR1K_R14:
1942 return "r14";
1943 case UNW_OR1K_R15:
1944 return "r15";
1945 case UNW_OR1K_R16:
1946 return "r16";
1947 case UNW_OR1K_R17:
1948 return "r17";
1949 case UNW_OR1K_R18:
1950 return "r18";
1951 case UNW_OR1K_R19:
1952 return "r19";
1953 case UNW_OR1K_R20:
1954 return "r20";
1955 case UNW_OR1K_R21:
1956 return "r21";
1957 case UNW_OR1K_R22:
1958 return "r22";
1959 case UNW_OR1K_R23:
1960 return "r23";
1961 case UNW_OR1K_R24:
1962 return "r24";
1963 case UNW_OR1K_R25:
1964 return "r25";
1965 case UNW_OR1K_R26:
1966 return "r26";
1967 case UNW_OR1K_R27:
1968 return "r27";
1969 case UNW_OR1K_R28:
1970 return "r28";
1971 case UNW_OR1K_R29:
1972 return "r29";
1973 case UNW_OR1K_R30:
1974 return "r30";
1975 case UNW_OR1K_R31:
1976 return "r31";
1977 default:
1978 return "unknown register";
1979 }
1980
1981}
Asiri Rathnayaked2d1ea92016-05-25 12:36:34 +00001982#endif // _LIBUNWIND_TARGET_OR1K
Saleem Abdulrasool675df582015-04-24 19:39:17 +00001983} // namespace libunwind
1984
1985#endif // __REGISTERS_HPP__