Skip to content

Commit ce4c5c9

Browse files
committedAug 31, 2015
[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
1 parent afeac30 commit ce4c5c9

File tree

6 files changed

+315
-0
lines changed

6 files changed

+315
-0
lines changed
 

‎libunwind/include/libunwind.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,4 +497,40 @@ enum {
497497
// 8192-16383 -- Unspecified vendor co-processor register.
498498
};
499499

500+
// OpenRISC1000 register numbers
501+
enum {
502+
UNW_OR1K_R0 = 0,
503+
UNW_OR1K_R1 = 1,
504+
UNW_OR1K_R2 = 2,
505+
UNW_OR1K_R3 = 3,
506+
UNW_OR1K_R4 = 4,
507+
UNW_OR1K_R5 = 5,
508+
UNW_OR1K_R6 = 6,
509+
UNW_OR1K_R7 = 7,
510+
UNW_OR1K_R8 = 8,
511+
UNW_OR1K_R9 = 9,
512+
UNW_OR1K_R10 = 10,
513+
UNW_OR1K_R11 = 11,
514+
UNW_OR1K_R12 = 12,
515+
UNW_OR1K_R13 = 13,
516+
UNW_OR1K_R14 = 14,
517+
UNW_OR1K_R15 = 15,
518+
UNW_OR1K_R16 = 16,
519+
UNW_OR1K_R17 = 17,
520+
UNW_OR1K_R18 = 18,
521+
UNW_OR1K_R19 = 19,
522+
UNW_OR1K_R20 = 20,
523+
UNW_OR1K_R21 = 21,
524+
UNW_OR1K_R22 = 22,
525+
UNW_OR1K_R23 = 23,
526+
UNW_OR1K_R24 = 24,
527+
UNW_OR1K_R25 = 25,
528+
UNW_OR1K_R26 = 26,
529+
UNW_OR1K_R27 = 27,
530+
UNW_OR1K_R28 = 28,
531+
UNW_OR1K_R29 = 29,
532+
UNW_OR1K_R30 = 30,
533+
UNW_OR1K_R31 = 31,
534+
};
535+
500536
#endif

‎libunwind/src/Registers.hpp

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,7 +1711,187 @@ inline v128 Registers_arm::getVectorRegister(int) const {
17111711
inline void Registers_arm::setVectorRegister(int, v128) {
17121712
_LIBUNWIND_ABORT("ARM vector support not implemented");
17131713
}
1714+
/// Registers_or1k holds the register state of a thread in an OpenRISC1000
1715+
/// process.
1716+
class _LIBUNWIND_HIDDEN Registers_or1k {
1717+
public:
1718+
Registers_or1k();
1719+
Registers_or1k(const void *registers);
1720+
1721+
bool validRegister(int num) const;
1722+
uint32_t getRegister(int num) const;
1723+
void setRegister(int num, uint32_t value);
1724+
bool validFloatRegister(int num) const;
1725+
double getFloatRegister(int num) const;
1726+
void setFloatRegister(int num, double value);
1727+
bool validVectorRegister(int num) const;
1728+
v128 getVectorRegister(int num) const;
1729+
void setVectorRegister(int num, v128 value);
1730+
const char *getRegisterName(int num);
1731+
void jumpto();
1732+
static int lastDwarfRegNum() { return 31; }
1733+
1734+
uint64_t getSP() const { return _registers.__r[1]; }
1735+
void setSP(uint32_t value) { _registers.__r[1] = value; }
1736+
uint64_t getIP() const { return _registers.__r[9]; }
1737+
void setIP(uint32_t value) { _registers.__r[9] = value; }
1738+
1739+
private:
1740+
struct or1k_thread_state_t {
1741+
unsigned int __r[32];
1742+
};
1743+
1744+
or1k_thread_state_t _registers;
1745+
};
1746+
1747+
inline Registers_or1k::Registers_or1k(const void *registers) {
1748+
static_assert(sizeof(Registers_or1k) < sizeof(unw_context_t),
1749+
"or1k registers do not fit into unw_context_t");
1750+
memcpy(&_registers, static_cast<const uint8_t *>(registers),
1751+
sizeof(_registers));
1752+
}
1753+
1754+
inline Registers_or1k::Registers_or1k() {
1755+
memset(&_registers, 0, sizeof(_registers));
1756+
}
17141757

1758+
inline bool Registers_or1k::validRegister(int regNum) const {
1759+
if (regNum == UNW_REG_IP)
1760+
return true;
1761+
if (regNum == UNW_REG_SP)
1762+
return true;
1763+
if (regNum < 0)
1764+
return false;
1765+
if (regNum <= UNW_OR1K_R31)
1766+
return true;
1767+
return false;
1768+
}
1769+
1770+
inline uint32_t Registers_or1k::getRegister(int regNum) const {
1771+
if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31)
1772+
return _registers.__r[regNum - UNW_OR1K_R0];
1773+
1774+
switch (regNum) {
1775+
case UNW_REG_IP:
1776+
return _registers.__r[9];
1777+
case UNW_REG_SP:
1778+
return _registers.__r[1];
1779+
}
1780+
_LIBUNWIND_ABORT("unsupported or1k register");
1781+
}
1782+
1783+
inline void Registers_or1k::setRegister(int regNum, uint32_t value) {
1784+
if (regNum >= UNW_OR1K_R0 && regNum <= UNW_OR1K_R31) {
1785+
_registers.__r[regNum - UNW_OR1K_R0] = value;
1786+
return;
1787+
}
1788+
1789+
switch (regNum) {
1790+
case UNW_REG_IP:
1791+
_registers.__r[9] = value;
1792+
return;
1793+
case UNW_REG_SP:
1794+
_registers.__r[1] = value;
1795+
return;
1796+
}
1797+
_LIBUNWIND_ABORT("unsupported or1k register");
1798+
}
1799+
1800+
inline bool Registers_or1k::validFloatRegister(int regNum) const {
1801+
return false;
1802+
}
1803+
1804+
inline double Registers_or1k::getFloatRegister(int regNum) const {
1805+
_LIBUNWIND_ABORT("or1k float support not implemented");
1806+
}
1807+
1808+
inline void Registers_or1k::setFloatRegister(int regNum, double value) {
1809+
_LIBUNWIND_ABORT("or1k float support not implemented");
1810+
}
1811+
1812+
inline bool Registers_or1k::validVectorRegister(int regNum) const {
1813+
return false;
1814+
}
1815+
1816+
inline v128 Registers_or1k::getVectorRegister(int regNum) const {
1817+
_LIBUNWIND_ABORT("or1k vector support not implemented");
1818+
}
1819+
1820+
inline void Registers_or1k::setVectorRegister(int regNum, v128 value) {
1821+
_LIBUNWIND_ABORT("or1k vector support not implemented");
1822+
}
1823+
1824+
inline const char *Registers_or1k::getRegisterName(int regNum) {
1825+
switch (regNum) {
1826+
case UNW_OR1K_R0:
1827+
return "r0";
1828+
case UNW_OR1K_R1:
1829+
return "r1";
1830+
case UNW_OR1K_R2:
1831+
return "r2";
1832+
case UNW_OR1K_R3:
1833+
return "r3";
1834+
case UNW_OR1K_R4:
1835+
return "r4";
1836+
case UNW_OR1K_R5:
1837+
return "r5";
1838+
case UNW_OR1K_R6:
1839+
return "r6";
1840+
case UNW_OR1K_R7:
1841+
return "r7";
1842+
case UNW_OR1K_R8:
1843+
return "r8";
1844+
case UNW_OR1K_R9:
1845+
return "r9";
1846+
case UNW_OR1K_R10:
1847+
return "r10";
1848+
case UNW_OR1K_R11:
1849+
return "r11";
1850+
case UNW_OR1K_R12:
1851+
return "r12";
1852+
case UNW_OR1K_R13:
1853+
return "r13";
1854+
case UNW_OR1K_R14:
1855+
return "r14";
1856+
case UNW_OR1K_R15:
1857+
return "r15";
1858+
case UNW_OR1K_R16:
1859+
return "r16";
1860+
case UNW_OR1K_R17:
1861+
return "r17";
1862+
case UNW_OR1K_R18:
1863+
return "r18";
1864+
case UNW_OR1K_R19:
1865+
return "r19";
1866+
case UNW_OR1K_R20:
1867+
return "r20";
1868+
case UNW_OR1K_R21:
1869+
return "r21";
1870+
case UNW_OR1K_R22:
1871+
return "r22";
1872+
case UNW_OR1K_R23:
1873+
return "r23";
1874+
case UNW_OR1K_R24:
1875+
return "r24";
1876+
case UNW_OR1K_R25:
1877+
return "r25";
1878+
case UNW_OR1K_R26:
1879+
return "r26";
1880+
case UNW_OR1K_R27:
1881+
return "r27";
1882+
case UNW_OR1K_R28:
1883+
return "r28";
1884+
case UNW_OR1K_R29:
1885+
return "r29";
1886+
case UNW_OR1K_R30:
1887+
return "r30";
1888+
case UNW_OR1K_R31:
1889+
return "r31";
1890+
default:
1891+
return "unknown register";
1892+
}
1893+
1894+
}
17151895
} // namespace libunwind
17161896

17171897
#endif // __REGISTERS_HPP__

‎libunwind/src/UnwindCursor.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,10 @@ class UnwindCursor : public AbstractUnwindCursor{
556556
compact_unwind_encoding_t dwarfEncoding(Registers_arm64 &) const {
557557
return UNWIND_ARM64_MODE_DWARF;
558558
}
559+
560+
compact_unwind_encoding_t dwarfEncoding(Registers_or1k &) const {
561+
return 0;
562+
}
559563
#endif // _LIBUNWIND_SUPPORT_DWARF_UNWIND
560564

561565

‎libunwind/src/UnwindRegistersRestore.S

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,55 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm19restoreiWMMXCont
427427
#endif
428428
JMP(lr)
429429

430+
#elif defined(__or1k__)
431+
432+
DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
433+
#
434+
# void libunwind::Registers_or1k::jumpto()
435+
#
436+
# On entry:
437+
# thread_state pointer is in r3
438+
#
439+
440+
# restore integral registerrs
441+
l.lwz r0, 0(r3)
442+
l.lwz r1, 4(r3)
443+
l.lwz r2, 8(r3)
444+
# skip r3 for now
445+
l.lwz r4, 16(r3)
446+
l.lwz r5, 20(r3)
447+
l.lwz r6, 24(r3)
448+
l.lwz r7, 28(r3)
449+
l.lwz r8, 32(r3)
450+
l.lwz r9, 36(r3)
451+
l.lwz r10, 40(r3)
452+
l.lwz r11, 44(r3)
453+
l.lwz r12, 48(r3)
454+
l.lwz r13, 52(r3)
455+
l.lwz r14, 56(r3)
456+
l.lwz r15, 60(r3)
457+
l.lwz r16, 64(r3)
458+
l.lwz r17, 68(r3)
459+
l.lwz r18, 72(r3)
460+
l.lwz r19, 76(r3)
461+
l.lwz r20, 80(r3)
462+
l.lwz r21, 84(r3)
463+
l.lwz r22, 88(r3)
464+
l.lwz r23, 92(r3)
465+
l.lwz r24, 96(r3)
466+
l.lwz r25,100(r3)
467+
l.lwz r26,104(r3)
468+
l.lwz r27,108(r3)
469+
l.lwz r28,112(r3)
470+
l.lwz r29,116(r3)
471+
l.lwz r30,120(r3)
472+
l.lwz r31,124(r3)
473+
474+
# at last, restore r3
475+
l.lwz r3, 12(r3)
476+
477+
# jump to pc
478+
l.jr r9
479+
l.nop
480+
430481
#endif

‎libunwind/src/UnwindRegistersSave.S

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,4 +413,45 @@ DEFINE_LIBUNWIND_PRIVATE_FUNCTION(_ZN9libunwind13Registers_arm16saveiWMMXControl
413413
#endif
414414
JMP(lr)
415415

416+
#elif defined(__or1k__)
417+
418+
#
419+
# extern int unw_getcontext(unw_context_t* thread_state)
420+
#
421+
# On entry:
422+
# thread_state pointer is in r3
423+
#
424+
DEFINE_LIBUNWIND_FUNCTION(unw_getcontext)
425+
l.sw 0(r3), r0
426+
l.sw 4(r3), r1
427+
l.sw 8(r3), r2
428+
l.sw 12(r3), r3
429+
l.sw 16(r3), r4
430+
l.sw 20(r3), r5
431+
l.sw 24(r3), r6
432+
l.sw 28(r3), r7
433+
l.sw 32(r3), r8
434+
l.sw 36(r3), r9
435+
l.sw 40(r3), r10
436+
l.sw 44(r3), r11
437+
l.sw 48(r3), r12
438+
l.sw 52(r3), r13
439+
l.sw 56(r3), r14
440+
l.sw 60(r3), r15
441+
l.sw 64(r3), r16
442+
l.sw 68(r3), r17
443+
l.sw 72(r3), r18
444+
l.sw 76(r3), r19
445+
l.sw 80(r3), r20
446+
l.sw 84(r3), r21
447+
l.sw 88(r3), r22
448+
l.sw 92(r3), r23
449+
l.sw 96(r3), r24
450+
l.sw 100(r3), r25
451+
l.sw 104(r3), r26
452+
l.sw 108(r3), r27
453+
l.sw 112(r3), r28
454+
l.sw 116(r3), r29
455+
l.sw 120(r3), r30
456+
l.sw 124(r3), r31
416457
#endif

‎libunwind/src/libunwind.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ _LIBUNWIND_EXPORT int unw_init_local(unw_cursor_t *cursor,
6161
#elif _LIBUNWIND_ARM_EHABI
6262
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_arm>(
6363
context, LocalAddressSpace::sThisAddressSpace);
64+
#elif defined(__or1k__)
65+
new ((void *)cursor) UnwindCursor<LocalAddressSpace, Registers_or1k>(
66+
context, LocalAddressSpace::sThisAddressSpace);
6467
#else
6568
#error Architecture not supported
6669
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.