diff options
| author | joerg <joerg@NetBSD.org> | 2014-04-02 22:34:29 +0000 |
|---|---|---|
| committer | joerg <joerg@NetBSD.org> | 2014-04-02 22:34:29 +0000 |
| commit | a280fb92acacbf5936fe7ee6f271e6daaabb9fef (patch) | |
| tree | 0318a8602b637e90dc875a351bb55b77e5315bfb /sys/lib | |
| parent | e2a6f0486ccab0b2b1014becfd84cb34e74f8155 (diff) | |
Support SH3 in our unwinder.
Diffstat (limited to 'sys/lib')
| -rw-r--r-- | sys/lib/libunwind/Registers.hpp | 64 | ||||
| -rw-r--r-- | sys/lib/libunwind/libunwind.cxx | 2 | ||||
| -rw-r--r-- | sys/lib/libunwind/unwind_registers.S | 57 |
3 files changed, 123 insertions, 0 deletions
diff --git a/sys/lib/libunwind/Registers.hpp b/sys/lib/libunwind/Registers.hpp index 12577e2ec36..eb0a6b6aa9d 100644 --- a/sys/lib/libunwind/Registers.hpp +++ b/sys/lib/libunwind/Registers.hpp @@ -454,6 +454,70 @@ private: fpreg_t fpreg[8]; }; +enum { + DWARF_SH3_R0 = 0, + DWARF_SH3_R15 = 15, + DWARF_SH3_PC = 16, + DWARF_SH3_PR = 17, + + REGNO_SH3_R0 = 0, + REGNO_SH3_R15 = 15, + REGNO_SH3_PC = 16, + REGNO_SH3_PR = 17, +}; + +class Registers_SH3 { +public: + enum { + LAST_REGISTER = REGNO_SH3_PR, + LAST_RESTORE_REG = REGNO_SH3_PR, + RETURN_REG = REGNO_SH3_PR, + }; + + __dso_hidden Registers_SH3(); + + static int dwarf2regno(int num) { + if (num >= DWARF_SH3_R0 && num <= DWARF_SH3_R15) + return REGNO_SH3_R0 + (num - DWARF_SH3_R0); + if (num == DWARF_SH3_PC) + return REGNO_SH3_PC; + if (num == DWARF_SH3_PR) + return REGNO_SH3_PR; + return LAST_REGISTER + 1; + } + + bool validRegister(int num) const { + return num >= 0 && num <= REGNO_SH3_PR; + } + + uint64_t getRegister(int num) const { + assert(validRegister(num)); + return reg[num]; + } + + void setRegister(int num, uint64_t value) { + assert(validRegister(num)); + reg[num] = value; + } + + uint64_t getIP() const { return reg[REGNO_SH3_PC]; } + + void setIP(uint64_t value) { reg[REGNO_SH3_PC] = value; } + + uint64_t getSP() const { return reg[REGNO_SH3_R15]; } + + void setSP(uint64_t value) { reg[REGNO_SH3_R15] = value; } + + bool validFloatVectorRegister(int num) const { return false; } + + void copyFloatVectorRegister(int num, uint64_t addr_) {} + + __dso_hidden void jumpto() const __dead; + +private: + uint32_t reg[REGNO_SH3_PR + 1]; +}; + } // namespace _Unwind #endif // __REGISTERS_HPP__ diff --git a/sys/lib/libunwind/libunwind.cxx b/sys/lib/libunwind/libunwind.cxx index 0564ca449c4..776ac5a677e 100644 --- a/sys/lib/libunwind/libunwind.cxx +++ b/sys/lib/libunwind/libunwind.cxx @@ -29,6 +29,8 @@ typedef Registers_arm32 ThisUnwindRegisters; typedef Registers_vax ThisUnwindRegisters; #elif __m68k__ typedef Registers_M68K ThisUnwindRegisters; +#elif __sh3__ +typedef Registers_SH3 ThisUnwindRegisters; #else #error Unsupported architecture #endif diff --git a/sys/lib/libunwind/unwind_registers.S b/sys/lib/libunwind/unwind_registers.S index 82a25a58341..d766f39273b 100644 --- a/sys/lib/libunwind/unwind_registers.S +++ b/sys/lib/libunwind/unwind_registers.S @@ -364,3 +364,60 @@ ENTRY(_ZNK7_Unwind14Registers_M68K6jumptoEv) rts END(_ZNK7_Unwind14Registers_M68K6jumptoEv) #endif + +#if defined(__sh3__) + .hidden _ZN7_Unwind13Registers_SH3C1Ev +ENTRY(_ZN7_Unwind13Registers_SH3C1Ev) + add #64, r4 + mov.l r8, @-r15 + sts.l pr, @-r15 + mov.l @r15+, r8 + mov.l r8, @r4 + mov.l @r15+, r8 + + mov.l r15, @-r4 + mov.l r14, @-r4 + mov.l r13, @-r4 + mov.l r12, @-r4 + mov.l r11, @-r4 + mov.l r10, @-r4 + mov.l r9, @-r4 + mov.l r8, @-r4 + mov.l r7, @-r4 + mov.l r6, @-r4 + mov.l r5, @-r4 + add #-4, r4 + mov.l r3, @-r4 + mov.l r2, @-r4 + mov.l r1, @-r4 + mov.l r0, @-r4 + rts + mov.l r4, @(16,r4) +SET_ENTRY_SIZE(_ZN7_Unwind13Registers_SH3C1Ev) + + .hidden _ZNK7_Unwind13Registers_SH36jumptoEv +ENTRY(_ZNK7_Unwind13Registers_SH36jumptoEv) + mov r4, r0 + add #4, r0 + mov.l @r0+, r1 + mov.l @r0+, r2 + mov.l @r0+, r3 + mov.l @r0+, r4 + mov.l @r0+, r5 + mov.l @r0+, r6 + mov.l @r0+, r7 + mov.l @r0+, r8 + mov.l @r0+, r9 + mov.l @r0+, r10 + mov.l @r0+, r11 + mov.l @r0+, r12 + mov.l @r0+, r13 + mov.l @(12, r0), r14 + lds r14, pr + mov.l @r0+, r14 + mov.l @r0+, r15 + mov.l @r0, r0 + jmp @r0 + nop +SET_ENTRY_SIZE(_ZNK7_Unwind13Registers_SH36jumptoEv) +#endif |
