[libunwind] add hexagon support
This commit is contained in:
parent
87735b5b1d
commit
9107594f37
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
//
|
||||
|
|
|
@ -34,6 +34,7 @@ enum {
|
|||
REGISTERS_MIPS_O32,
|
||||
REGISTERS_MIPS_NEWABI,
|
||||
REGISTERS_SPARC,
|
||||
REGISTERS_HEXAGON,
|
||||
REGISTERS_RISCV,
|
||||
};
|
||||
|
||||
|
@ -3528,6 +3529,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.
|
||||
|
|
|
@ -1123,6 +1123,12 @@ private:
|
|||
}
|
||||
#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;
|
||||
|
|
|
@ -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
|
||||
|
||||
//
|
||||
|
|
|
@ -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__)
|
||||
|
||||
#
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -104,7 +104,8 @@
|
|||
(!defined(__APPLE__) && defined(__arm__)) || \
|
||||
defined(__aarch64__) || \
|
||||
defined(__mips__) || \
|
||||
defined(__riscv)
|
||||
defined(__riscv) || \
|
||||
defined(__hexagon__)
|
||||
#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
|
||||
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
|
||||
#endif
|
||||
|
|
|
@ -50,6 +50,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
|
|||
# define REGISTER_KIND Registers_arm
|
||||
#elif defined(__or1k__)
|
||||
# define REGISTER_KIND Registers_or1k
|
||||
#elif defined(__hexagon__)
|
||||
# define REGISTER_KIND Registers_hexagon
|
||||
#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
|
||||
# define REGISTER_KIND Registers_mips_o32
|
||||
#elif defined(__mips64)
|
||||
|
|
Loading…
Reference in New Issue