Skip to content

Commit

Permalink
[libunwind] add hexagon support
Browse files Browse the repository at this point in the history
  • Loading branch information
androm3da authored and nikic committed May 5, 2020
1 parent f1a06bf commit e0bac6a
Show file tree
Hide file tree
Showing 9 changed files with 333 additions and 1 deletion.
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
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64

#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
Expand Down Expand Up @@ -82,6 +83,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 @@ -142,6 +149,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_TARGET_RISCV 1
# define _LIBUNWIND_CONTEXT_SIZE 167
# define _LIBUNWIND_CURSOR_SIZE 179
Expand Down
38 changes: 38 additions & 0 deletions libunwind/include/libunwind.h
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,44 @@ 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,
};

// RISC-V registers. These match the DWARF register numbers defined by section
// 4 of the RISC-V ELF psABI specification, which can be found at:
//
Expand Down
182 changes: 182 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,
REGISTERS_RISCV,
};

Expand Down Expand Up @@ -3518,6 +3519,187 @@ 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


#if defined(_LIBUNWIND_TARGET_RISCV)
/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
/// process.
Expand Down
6 changes: 6 additions & 0 deletions libunwind/src/UnwindCursor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,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
Loading

0 comments on commit e0bac6a

Please sign in to comment.