Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libunwind] add hexagon support #54

Merged
merged 1 commit into from
May 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions libunwind/include/__libunwind_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34

#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
# if defined(__i386__)
Expand Down Expand Up @@ -81,6 +82,12 @@
# define _LIBUNWIND_CONTEXT_SIZE 16
# define _LIBUNWIND_CURSOR_SIZE 24
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K
# elif defined(__hexagon__)
# define _LIBUNWIND_TARGET_HEXAGON 1
// Values here change when : Registers.hpp - hexagon_thread_state_t change
# define _LIBUNWIND_CONTEXT_SIZE 18
# define _LIBUNWIND_CURSOR_SIZE 24
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON
# elif defined(__mips__)
# if defined(_ABIO32) && _MIPS_SIM == _ABIO32
# define _LIBUNWIND_TARGET_MIPS_O32 1
Expand Down Expand Up @@ -132,6 +139,7 @@
# define _LIBUNWIND_TARGET_MIPS_O32 1
# define _LIBUNWIND_TARGET_MIPS_NEWABI 1
# define _LIBUNWIND_TARGET_SPARC 1
# define _LIBUNWIND_TARGET_HEXAGON 1
# define _LIBUNWIND_CONTEXT_SIZE 167
# define _LIBUNWIND_CURSOR_SIZE 179
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287
Expand Down
37 changes: 37 additions & 0 deletions libunwind/include/libunwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -832,4 +832,41 @@ enum {
UNW_SPARC_I7 = 31,
};

// Hexagon register numbers
enum {
UNW_HEXAGON_R0,
UNW_HEXAGON_R1,
UNW_HEXAGON_R2,
UNW_HEXAGON_R3,
UNW_HEXAGON_R4,
UNW_HEXAGON_R5,
UNW_HEXAGON_R6,
UNW_HEXAGON_R7,
UNW_HEXAGON_R8,
UNW_HEXAGON_R9,
UNW_HEXAGON_R10,
UNW_HEXAGON_R11,
UNW_HEXAGON_R12,
UNW_HEXAGON_R13,
UNW_HEXAGON_R14,
UNW_HEXAGON_R15,
UNW_HEXAGON_R16,
UNW_HEXAGON_R17,
UNW_HEXAGON_R18,
UNW_HEXAGON_R19,
UNW_HEXAGON_R20,
UNW_HEXAGON_R21,
UNW_HEXAGON_R22,
UNW_HEXAGON_R23,
UNW_HEXAGON_R24,
UNW_HEXAGON_R25,
UNW_HEXAGON_R26,
UNW_HEXAGON_R27,
UNW_HEXAGON_R28,
UNW_HEXAGON_R29,
UNW_HEXAGON_R30,
UNW_HEXAGON_R31,
UNW_HEXAGON_P3_0,
UNW_HEXAGON_PC,
};
#endif
181 changes: 181 additions & 0 deletions libunwind/src/Registers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum {
REGISTERS_MIPS_O32,
REGISTERS_MIPS_NEWABI,
REGISTERS_SPARC,
REGISTERS_HEXAGON,
};

#if defined(_LIBUNWIND_TARGET_I386)
Expand Down Expand Up @@ -3517,6 +3518,186 @@ inline const char *Registers_sparc::getRegisterName(int regNum) {
}
#endif // _LIBUNWIND_TARGET_SPARC

#if defined(_LIBUNWIND_TARGET_HEXAGON)
/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
/// process.
class _LIBUNWIND_HIDDEN Registers_hexagon {
public:
Registers_hexagon();
Registers_hexagon(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 _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; }
static int getArch() { return REGISTERS_HEXAGON; }

uint32_t getSP() const { return _registers.__r[UNW_HEXAGON_R29]; }
void setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
uint32_t getIP() const { return _registers.__r[UNW_HEXAGON_PC]; }
void setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }

private:
struct hexagon_thread_state_t {
unsigned int __r[35];
};

hexagon_thread_state_t _registers;
};

inline Registers_hexagon::Registers_hexagon(const void *registers) {
static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
"hexagon registers do not fit into unw_context_t");
memcpy(&_registers, static_cast<const uint8_t *>(registers),
sizeof(_registers));
}

inline Registers_hexagon::Registers_hexagon() {
memset(&_registers, 0, sizeof(_registers));
}

inline bool Registers_hexagon::validRegister(int regNum) const {
if (regNum <= UNW_HEXAGON_R31)
return true;
return false;
}

inline uint32_t Registers_hexagon::getRegister(int regNum) const {
if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
return _registers.__r[regNum - UNW_HEXAGON_R0];

switch (regNum) {
case UNW_REG_IP:
return _registers.__r[UNW_HEXAGON_PC];
case UNW_REG_SP:
return _registers.__r[UNW_HEXAGON_R29];
}
_LIBUNWIND_ABORT("unsupported hexagon register");
}

inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
_registers.__r[regNum - UNW_HEXAGON_R0] = value;
return;
}

switch (regNum) {
case UNW_REG_IP:
_registers.__r[UNW_HEXAGON_PC] = value;
return;
case UNW_REG_SP:
_registers.__r[UNW_HEXAGON_R29] = value;
return;
}
_LIBUNWIND_ABORT("unsupported hexagon register");
}

inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
return false;
}

inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
_LIBUNWIND_ABORT("hexagon float support not implemented");
}

inline void Registers_hexagon::setFloatRegister(int /* regNum */,
double /* value */) {
_LIBUNWIND_ABORT("hexagon float support not implemented");
}

inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
return false;
}

inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
_LIBUNWIND_ABORT("hexagon vector support not implemented");
}

inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
_LIBUNWIND_ABORT("hexagon vector support not implemented");
}

inline const char *Registers_hexagon::getRegisterName(int regNum) {
switch (regNum) {
case UNW_HEXAGON_R0:
return "r0";
case UNW_HEXAGON_R1:
return "r1";
case UNW_HEXAGON_R2:
return "r2";
case UNW_HEXAGON_R3:
return "r3";
case UNW_HEXAGON_R4:
return "r4";
case UNW_HEXAGON_R5:
return "r5";
case UNW_HEXAGON_R6:
return "r6";
case UNW_HEXAGON_R7:
return "r7";
case UNW_HEXAGON_R8:
return "r8";
case UNW_HEXAGON_R9:
return "r9";
case UNW_HEXAGON_R10:
return "r10";
case UNW_HEXAGON_R11:
return "r11";
case UNW_HEXAGON_R12:
return "r12";
case UNW_HEXAGON_R13:
return "r13";
case UNW_HEXAGON_R14:
return "r14";
case UNW_HEXAGON_R15:
return "r15";
case UNW_HEXAGON_R16:
return "r16";
case UNW_HEXAGON_R17:
return "r17";
case UNW_HEXAGON_R18:
return "r18";
case UNW_HEXAGON_R19:
return "r19";
case UNW_HEXAGON_R20:
return "r20";
case UNW_HEXAGON_R21:
return "r21";
case UNW_HEXAGON_R22:
return "r22";
case UNW_HEXAGON_R23:
return "r23";
case UNW_HEXAGON_R24:
return "r24";
case UNW_HEXAGON_R25:
return "r25";
case UNW_HEXAGON_R26:
return "r26";
case UNW_HEXAGON_R27:
return "r27";
case UNW_HEXAGON_R28:
return "r28";
case UNW_HEXAGON_R29:
return "r29";
case UNW_HEXAGON_R30:
return "r30";
case UNW_HEXAGON_R31:
return "r31";
default:
return "unknown register";
}

}
#endif // _LIBUNWIND_TARGET_HEXAGON

} // namespace libunwind

#endif // __REGISTERS_HPP__
6 changes: 6 additions & 0 deletions libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,12 @@ class UnwindCursor : public AbstractUnwindCursor{
}
#endif

#if defined (_LIBUNWIND_TARGET_HEXAGON)
compact_unwind_encoding_t dwarfEncoding(Registers_hexagon &) const {
return 0;
}
#endif

#if defined (_LIBUNWIND_TARGET_MIPS_O32)
compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const {
return 0;
Expand Down
42 changes: 42 additions & 0 deletions libunwind/src/UnwindRegistersRestore.S
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,48 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
l.jr r9
l.nop

#elif defined(__hexagon__)
# On entry:
# thread_state pointer is in r2
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_hexagon6jumptoEv)
#
# void libunwind::Registers_hexagon::jumpto()
#
r8 = memw(r0+#32)
r9 = memw(r0+#36)
r10 = memw(r0+#40)
r11 = memw(r0+#44)

r12 = memw(r0+#48)
r13 = memw(r0+#52)
r14 = memw(r0+#56)
r15 = memw(r0+#60)

r16 = memw(r0+#64)
r17 = memw(r0+#68)
r18 = memw(r0+#72)
r19 = memw(r0+#76)

r20 = memw(r0+#80)
r21 = memw(r0+#84)
r22 = memw(r0+#88)
r23 = memw(r0+#92)

r24 = memw(r0+#96)
r25 = memw(r0+#100)
r26 = memw(r0+#104)
r27 = memw(r0+#108)

r28 = memw(r0+#112)
r29 = memw(r0+#116)
r30 = memw(r0+#120)
r31 = memw(r0+#132)

r1 = memw(r0+#128)
c4 = r1 // Predicate register
r1 = memw(r0+#4)
r0 = memw(r0)
jumpr r31
#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32

//
Expand Down
46 changes: 46 additions & 0 deletions libunwind/src/UnwindRegistersSave.S
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,52 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
# zero epcr
l.sw 132(r3), r0

#elif defined(__hexagon__)
#
# extern int unw_getcontext(unw_context_t* thread_state)
#
# On entry:
# thread_state pointer is in r0
#
#define OFFSET(offset) (offset/4)
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
memw(r0+#32) = r8
memw(r0+#36) = r9
memw(r0+#40) = r10
memw(r0+#44) = r11

memw(r0+#48) = r12
memw(r0+#52) = r13
memw(r0+#56) = r14
memw(r0+#60) = r15

memw(r0+#64) = r16
memw(r0+#68) = r17
memw(r0+#72) = r18
memw(r0+#76) = r19

memw(r0+#80) = r20
memw(r0+#84) = r21
memw(r0+#88) = r22
memw(r0+#92) = r23

memw(r0+#96) = r24
memw(r0+#100) = r25
memw(r0+#104) = r26
memw(r0+#108) = r27

memw(r0+#112) = r28
memw(r0+#116) = r29
memw(r0+#120) = r30
memw(r0+#124) = r31
r1 = c4 // Predicate register
memw(r0+#128) = r1
r1 = memw(r30) // *FP == Saved FP
r1 = r31
memw(r0+#132) = r1

jumpr r31

#elif defined(__sparc__)

#
Expand Down
7 changes: 7 additions & 0 deletions libunwind/src/assembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,16 @@
#define EXPORT_SYMBOL(name)
#define HIDDEN_SYMBOL(name) .hidden name
#define WEAK_SYMBOL(name) .weak name

#if defined(__hexagon__)
#define WEAK_ALIAS(name, aliasname) \
WEAK_SYMBOL(aliasname) SEPARATOR \
.equiv SYMBOL_NAME(aliasname), SYMBOL_NAME(name)
#else
#define WEAK_ALIAS(name, aliasname) \
WEAK_SYMBOL(aliasname) SEPARATOR \
SYMBOL_NAME(aliasname) = SYMBOL_NAME(name)
#endif

#if defined(__GNU__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
defined(__linux__)
Expand Down
Loading