forked from OSchip/llvm-project
[libunwind] Add support for OpenRISC 1000.
This patch makes no assumptions on ABI past the ABI defined in the OpenRISC 1000 spec except that the DWARF register numbers will be 0-31 for registers r0-r31, which is true for both gcc and clang at the moment. llvm-svn: 246413
This commit is contained in:
parent
afeac301b1
commit
ce4c5c9849
|
@ -497,4 +497,40 @@ enum {
|
|||
// 8192-16383 -- Unspecified vendor co-processor register.
|
||||
};
|
||||
|
||||
// OpenRISC1000 register numbers
|
||||
enum {
|
||||
UNW_OR1K_R0 = 0,
|
||||
UNW_OR1K_R1 = 1,
|
||||
UNW_OR1K_R2 = 2,
|
||||
UNW_OR1K_R3 = 3,
|
||||
UNW_OR1K_R4 = 4,
|
||||
UNW_OR1K_R5 = 5,
|
||||
UNW_OR1K_R6 = 6,
|
||||
UNW_OR1K_R7 = 7,
|
||||
UNW_OR1K_R8 = 8,
|
||||
UNW_OR1K_R9 = 9,
|
||||
UNW_OR1K_R10 = 10,
|
||||
UNW_OR1K_R11 = 11,
|
||||
UNW_OR1K_R12 = 12,
|
||||
UNW_OR1K_R13 = 13,
|
||||
UNW_OR1K_R14 = 14,
|
||||
UNW_OR1K_R15 = 15,
|
||||
UNW_OR1K_R16 = 16,
|
||||
UNW_OR1K_R17 = 17,
|
||||
UNW_OR1K_R18 = 18,
|
||||
UNW_OR1K_R19 = 19,
|
||||
UNW_OR1K_R20 = 20,
|
||||
UNW_OR1K_R21 = 21,
|
||||
UNW_OR1K_R22 = 22,
|
||||
UNW_OR1K_R23 = 23,
|
||||
UNW_OR1K_R24 = 24,
|
||||
UNW_OR1K_R25 = 25,
|
||||
UNW_OR1K_R26 = 26,
|
||||
UNW_OR1K_R27 = 27,
|
||||
UNW_OR1K_R28 = 28,
|
||||
UNW_OR1K_R29 = 29,
|
||||
UNW_OR1K_R30 = 30,
|
||||
UNW_OR1K_R31 = 31,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1711,7 +1711,187 @@ inline v128 Registers_arm::getVectorRegister(int) const {
|
|||
inline void Registers_arm::setVectorRegister(int, v128) {
|
||||
_LIBUNWIND_ABORT("ARM vector support not implemented");
|
||||
}
|
||||
/// Registers_or1k holds the register state of a thread in an OpenRISC1000
|
||||
/// process.
|
||||
class _LIBUNWIND_HIDDEN Registers_or1k {
|
||||
public:
|
||||
Registers_or1k();
|
||||
Registers_or1k(const void *registers);
|
||||
|
||||
bool validRegister(int num) const;
|
||||
uint32_t getRegister(int num) const;
|
||||
void setRegister(int num, uint32_t value);
|
||||
bool validFloatRegister(int num) const;
|
||||
double getFloatRegister(int num) const;
|
||||
void setFloatRegister(int num, double value);
|
||||
bool validVectorRegister(int num) const;
|
||||
v128 getVectorRegister(int num) const;
|
||||
void setVectorRegister(int num, v128 value);
|
||||
const char *getRegisterName(int num);
|
||||
void jumpto();
|
||||
static int lastDwarfRegNum() { return 31; }
|
||||
|
||||
uint64_t getSP() const { return _registers.__r[1]; }
|
||||
void setSP(uint32_t value) { _registers.__r[1] = value; }
|
||||
uint64_t getIP() const { return _registers.__r[9]; }
|
||||
void setIP(uint32_t value) { _registers.__r[9] = value; }
|
||||
|
||||
private:
|
||||
struct or1k_thread_state_t {
|
||||
unsigned int __r[32];
|
||||
};
|
||||
|
||||
or1k_thread_state_t _registers;
|
||||
};
|
||||
|
||||
inline Registers_or1k::Registers_or1k(const void *registers) {
|
||||
static_assert(sizeof(Registers_or1k) < sizeof(unw_context_t),
|
||||
"or1k registers do not fit into unw_context_t");
|
||||
memcpy(&_registers, static_cast<const uint8_t *>(registers),
|
||||
sizeof(_registers));
|
||||
}
|
||||
|
||||
inline Registers_or1k::Registers_or1k() {
|
||||
memset(&_registers, 0, sizeof(_registers));
|
||||
}
|
||||
|
||||
inline bool Registers_or1k::validRegister(int regNum) const {
|
||||
if (regNum == UNW_REG_IP)
|
||||
return true;
|
||||
if (regNum == UNW_REG_SP)
|
||||
return true;
|
||||
if (regNum < 0)
|
||||
return false;
|
||||
if (regNum <= UNW_OR1K_R31)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint32_t Registers_or1k::getRegister(int regNum) const {
|
||||
if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
|
||||
return _registers.__r[regNum - UNW_OR1K_R0];
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
return _registers.__r[9];
|
||||
case UNW_REG_SP:
|
||||
return _registers.__r[1];
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported or1k register");
|
||||
}
|
||||
|
||||
inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
|
||||
if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
|
||||
_registers.__r[regNum - UNW_OR1K_R0] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (regNum) {
|
||||
case UNW_REG_IP:
|
||||
_registers.__r[9] = value;
|
||||
return;
|
||||
case UNW_REG_SP:
|
||||
_registers.__r[1] = value;
|
||||
return;
|
||||
}
|
||||
_LIBUNWIND_ABORT("unsupported or1k register");
|
||||
}
|
||||
|
||||
inline bool Registers_or1k::validFloatRegister(int regNum) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline double Registers_or1k::getFloatRegister(int regNum) const {
|
||||
_LIBUNWIND_ABORT("or1k float support not implemented");
|
||||
}
|
||||
|
||||
inline void Registers_or1k::setFloatRegister(int regNum, double value) {
|
||||
_LIBUNWIND_ABORT("or1k float support not implemented");
|
||||
}
|
||||
|
||||
inline bool Registers_or1k::validVectorRegister(int regNum) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline v128 Registers_or1k::getVectorRegister(int regNum) const {
|
||||
_LIBUNWIND_ABORT("or1k vector support not implemented");
|
||||
}
|
||||
|
||||
inline void Registers_or1k::setVectorRegister(int regNum, v128 value) {
|
||||
_LIBUNWIND_ABORT("or1k vector support not implemented");
|
||||
}
|
||||
|
||||
inline const char *Registers_or1k::getRegisterName(int regNum) {
|
||||
switch (regNum) {
|
||||
case UNW_OR1K_R0:
|
||||
return "r0";
|
||||
case UNW_OR1K_R1:
|
||||
return "r1";
|
||||
case UNW_OR1K_R2:
|
||||
return "r2";
|
||||
case UNW_OR1K_R3:
|
||||
return "r3";
|
||||
case UNW_OR1K_R4:
|
||||
return "r4";
|
||||
case UNW_OR1K_R5:
|
||||
return "r5";
|
||||
case UNW_OR1K_R6:
|
||||
return "r6";
|
||||
case UNW_OR1K_R7:
|
||||
return "r7";
|
||||
case UNW_OR1K_R8:
|
||||
return "r8";
|
||||
case UNW_OR1K_R9:
|
||||
return "r9";
|
||||
case UNW_OR1K_R10:
|
||||
return "r10";
|
||||
case UNW_OR1K_R11:
|
||||
return "r11";
|
||||
case UNW_OR1K_R12:
|
||||
return "r12";
|
||||
case UNW_OR1K_R13:
|
||||
return "r13";
|
||||
case UNW_OR1K_R14:
|
||||
return "r14";
|
||||
case UNW_OR1K_R15:
|
||||
return "r15";
|
||||
case UNW_OR1K_R16:
|
||||
return "r16";
|
||||
case UNW_OR1K_R17:
|
||||
return "r17";
|
||||
case UNW_OR1K_R18:
|
||||
return "r18";
|
||||
case UNW_OR1K_R19:
|
||||
return "r19";
|
||||
case UNW_OR1K_R20:
|
||||
return "r20";
|
||||
case UNW_OR1K_R21:
|
||||
return "r21";
|
||||
case UNW_OR1K_R22:
|
||||
return "r22";
|
||||
case UNW_OR1K_R23:
|
||||
return "r23";
|
||||
case UNW_OR1K_R24:
|
||||
return "r24";
|
||||
case UNW_OR1K_R25:
|
||||
return "r25";
|
||||
case UNW_OR1K_R26:
|
||||
return "r26";
|
||||
case UNW_OR1K_R27:
|
||||
return "r27";
|
||||
case UNW_OR1K_R28:
|
||||
return "r28";
|
||||
case UNW_OR1K_R29:
|
||||
return "r29";
|
||||
case UNW_OR1K_R30:
|
||||
return "r30";
|
||||
case UNW_OR1K_R31:
|
||||
return "r31";
|
||||
default:
|
||||
return "unknown register";
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace libunwind
|
||||
|
||||
#endif // __REGISTERS_HPP__
|
||||
|
|
|
@ -556,6 +556,10 @@ private:
|
|||
compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
|
||||
return UNWIND_ARM64_MODE_DWARF;
|
||||
}
|
||||
|
||||
compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
|
||||
return 0;
|
||||
}
|
||||
#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
|
||||
|
||||
|
||||
|
|
|
@ -427,4 +427,55 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXCont
|
|||
#endif
|
||||
JMP(lr)
|
||||
|
||||
#elif defined(__or1k__)
|
||||
|
||||
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
|
||||
#
|
||||
# void libunwind::Registers_or1k::jumpto()
|
||||
#
|
||||
# On entry:
|
||||
# thread_state pointer is in r3
|
||||
#
|
||||
|
||||
# restore integral registerrs
|
||||
l.lwz r0, 0(r3)
|
||||
l.lwz r1, 4(r3)
|
||||
l.lwz r2, 8(r3)
|
||||
# skip r3 for now
|
||||
l.lwz r4, 16(r3)
|
||||
l.lwz r5, 20(r3)
|
||||
l.lwz r6, 24(r3)
|
||||
l.lwz r7, 28(r3)
|
||||
l.lwz r8, 32(r3)
|
||||
l.lwz r9, 36(r3)
|
||||
l.lwz r10, 40(r3)
|
||||
l.lwz r11, 44(r3)
|
||||
l.lwz r12, 48(r3)
|
||||
l.lwz r13, 52(r3)
|
||||
l.lwz r14, 56(r3)
|
||||
l.lwz r15, 60(r3)
|
||||
l.lwz r16, 64(r3)
|
||||
l.lwz r17, 68(r3)
|
||||
l.lwz r18, 72(r3)
|
||||
l.lwz r19, 76(r3)
|
||||
l.lwz r20, 80(r3)
|
||||
l.lwz r21, 84(r3)
|
||||
l.lwz r22, 88(r3)
|
||||
l.lwz r23, 92(r3)
|
||||
l.lwz r24, 96(r3)
|
||||
l.lwz r25,100(r3)
|
||||
l.lwz r26,104(r3)
|
||||
l.lwz r27,108(r3)
|
||||
l.lwz r28,112(r3)
|
||||
l.lwz r29,116(r3)
|
||||
l.lwz r30,120(r3)
|
||||
l.lwz r31,124(r3)
|
||||
|
||||
# at last, restore r3
|
||||
l.lwz r3, 12(r3)
|
||||
|
||||
# jump to pc
|
||||
l.jr r9
|
||||
l.nop
|
||||
|
||||
#endif
|
||||
|
|
|
@ -413,4 +413,45 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControl
|
|||
#endif
|
||||
JMP(lr)
|
||||
|
||||
#elif defined(__or1k__)
|
||||
|
||||
#
|
||||
# extern int unw_getcontext(unw_context_t* thread_state)
|
||||
#
|
||||
# On entry:
|
||||
# thread_state pointer is in r3
|
||||
#
|
||||
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
|
||||
l.sw 0(r3), r0
|
||||
l.sw 4(r3), r1
|
||||
l.sw 8(r3), r2
|
||||
l.sw 12(r3), r3
|
||||
l.sw 16(r3), r4
|
||||
l.sw 20(r3), r5
|
||||
l.sw 24(r3), r6
|
||||
l.sw 28(r3), r7
|
||||
l.sw 32(r3), r8
|
||||
l.sw 36(r3), r9
|
||||
l.sw 40(r3), r10
|
||||
l.sw 44(r3), r11
|
||||
l.sw 48(r3), r12
|
||||
l.sw 52(r3), r13
|
||||
l.sw 56(r3), r14
|
||||
l.sw 60(r3), r15
|
||||
l.sw 64(r3), r16
|
||||
l.sw 68(r3), r17
|
||||
l.sw 72(r3), r18
|
||||
l.sw 76(r3), r19
|
||||
l.sw 80(r3), r20
|
||||
l.sw 84(r3), r21
|
||||
l.sw 88(r3), r22
|
||||
l.sw 92(r3), r23
|
||||
l.sw 96(r3), r24
|
||||
l.sw 100(r3), r25
|
||||
l.sw 104(r3), r26
|
||||
l.sw 108(r3), r27
|
||||
l.sw 112(r3), r28
|
||||
l.sw 116(r3), r29
|
||||
l.sw 120(r3), r30
|
||||
l.sw 124(r3), r31
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,9 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
|
|||
#elif _LIBUNWIND_ARM_EHABI
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
#elif defined(__or1k__)
|
||||
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_or1k>(
|
||||
context, LocalAddressSpace::sThisAddressSpace);
|
||||
#else
|
||||
#error Architecture not supported
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue