Skip to content

Commit 9107594

Browse files
committed
[libunwind] add hexagon support
1 parent 87735b5 commit 9107594

9 files changed

+333
-1
lines changed

libunwind/include/__libunwind_config.h

+8
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K 32
2424
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_MIPS 65
2525
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC 31
26+
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON 34
2627
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
2728

2829
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
@@ -82,6 +83,12 @@
8283
# define _LIBUNWIND_CONTEXT_SIZE 16
8384
# define _LIBUNWIND_CURSOR_SIZE 24
8485
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K
86+
# elif defined(__hexagon__)
87+
# define _LIBUNWIND_TARGET_HEXAGON 1
88+
// Values here change when : Registers.hpp - hexagon_thread_state_t change
89+
# define _LIBUNWIND_CONTEXT_SIZE 18
90+
# define _LIBUNWIND_CURSOR_SIZE 24
91+
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON
8592
# elif defined(__mips__)
8693
# if defined(_ABIO32) && _MIPS_SIM == _ABIO32
8794
# define _LIBUNWIND_TARGET_MIPS_O32 1
@@ -142,6 +149,7 @@
142149
# define _LIBUNWIND_TARGET_MIPS_O32 1
143150
# define _LIBUNWIND_TARGET_MIPS_NEWABI 1
144151
# define _LIBUNWIND_TARGET_SPARC 1
152+
# define _LIBUNWIND_TARGET_HEXAGON 1
145153
# define _LIBUNWIND_TARGET_RISCV 1
146154
# define _LIBUNWIND_CONTEXT_SIZE 167
147155
# define _LIBUNWIND_CURSOR_SIZE 179

libunwind/include/libunwind.h

+38
Original file line numberDiff line numberDiff line change
@@ -832,6 +832,44 @@ enum {
832832
UNW_SPARC_I7 = 31,
833833
};
834834

835+
// Hexagon register numbers
836+
enum {
837+
UNW_HEXAGON_R0,
838+
UNW_HEXAGON_R1,
839+
UNW_HEXAGON_R2,
840+
UNW_HEXAGON_R3,
841+
UNW_HEXAGON_R4,
842+
UNW_HEXAGON_R5,
843+
UNW_HEXAGON_R6,
844+
UNW_HEXAGON_R7,
845+
UNW_HEXAGON_R8,
846+
UNW_HEXAGON_R9,
847+
UNW_HEXAGON_R10,
848+
UNW_HEXAGON_R11,
849+
UNW_HEXAGON_R12,
850+
UNW_HEXAGON_R13,
851+
UNW_HEXAGON_R14,
852+
UNW_HEXAGON_R15,
853+
UNW_HEXAGON_R16,
854+
UNW_HEXAGON_R17,
855+
UNW_HEXAGON_R18,
856+
UNW_HEXAGON_R19,
857+
UNW_HEXAGON_R20,
858+
UNW_HEXAGON_R21,
859+
UNW_HEXAGON_R22,
860+
UNW_HEXAGON_R23,
861+
UNW_HEXAGON_R24,
862+
UNW_HEXAGON_R25,
863+
UNW_HEXAGON_R26,
864+
UNW_HEXAGON_R27,
865+
UNW_HEXAGON_R28,
866+
UNW_HEXAGON_R29,
867+
UNW_HEXAGON_R30,
868+
UNW_HEXAGON_R31,
869+
UNW_HEXAGON_P3_0,
870+
UNW_HEXAGON_PC,
871+
};
872+
835873
// RISC-V registers. These match the DWARF register numbers defined by section
836874
// 4 of the RISC-V ELF psABI specification, which can be found at:
837875
//

libunwind/src/Registers.hpp

+182
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ enum {
3434
REGISTERS_MIPS_O32,
3535
REGISTERS_MIPS_NEWABI,
3636
REGISTERS_SPARC,
37+
REGISTERS_HEXAGON,
3738
REGISTERS_RISCV,
3839
};
3940

@@ -3528,6 +3529,187 @@ inline const char *Registers_sparc::getRegisterName(int regNum) {
35283529
}
35293530
#endif // _LIBUNWIND_TARGET_SPARC
35303531

3532+
#if defined(_LIBUNWIND_TARGET_HEXAGON)
3533+
/// Registers_hexagon holds the register state of a thread in a Hexagon QDSP6
3534+
/// process.
3535+
class _LIBUNWIND_HIDDEN Registers_hexagon {
3536+
public:
3537+
Registers_hexagon();
3538+
Registers_hexagon(const void *registers);
3539+
3540+
bool validRegister(int num) const;
3541+
uint32_t getRegister(int num) const;
3542+
void setRegister(int num, uint32_t value);
3543+
bool validFloatRegister(int num) const;
3544+
double getFloatRegister(int num) const;
3545+
void setFloatRegister(int num, double value);
3546+
bool validVectorRegister(int num) const;
3547+
v128 getVectorRegister(int num) const;
3548+
void setVectorRegister(int num, v128 value);
3549+
const char *getRegisterName(int num);
3550+
void jumpto();
3551+
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_HEXAGON; }
3552+
static int getArch() { return REGISTERS_HEXAGON; }
3553+
3554+
uint32_t getSP() const { return _registers.__r[UNW_HEXAGON_R29]; }
3555+
void setSP(uint32_t value) { _registers.__r[UNW_HEXAGON_R29] = value; }
3556+
uint32_t getIP() const { return _registers.__r[UNW_HEXAGON_PC]; }
3557+
void setIP(uint32_t value) { _registers.__r[UNW_HEXAGON_PC] = value; }
3558+
3559+
private:
3560+
struct hexagon_thread_state_t {
3561+
unsigned int __r[35];
3562+
};
3563+
3564+
hexagon_thread_state_t _registers;
3565+
};
3566+
3567+
inline Registers_hexagon::Registers_hexagon(const void *registers) {
3568+
static_assert((check_fit<Registers_hexagon, unw_context_t>::does_fit),
3569+
"hexagon registers do not fit into unw_context_t");
3570+
memcpy(&_registers, static_cast<const uint8_t *>(registers),
3571+
sizeof(_registers));
3572+
}
3573+
3574+
inline Registers_hexagon::Registers_hexagon() {
3575+
memset(&_registers, 0, sizeof(_registers));
3576+
}
3577+
3578+
inline bool Registers_hexagon::validRegister(int regNum) const {
3579+
if (regNum <= UNW_HEXAGON_R31)
3580+
return true;
3581+
return false;
3582+
}
3583+
3584+
inline uint32_t Registers_hexagon::getRegister(int regNum) const {
3585+
if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31)
3586+
return _registers.__r[regNum - UNW_HEXAGON_R0];
3587+
3588+
switch (regNum) {
3589+
case UNW_REG_IP:
3590+
return _registers.__r[UNW_HEXAGON_PC];
3591+
case UNW_REG_SP:
3592+
return _registers.__r[UNW_HEXAGON_R29];
3593+
}
3594+
_LIBUNWIND_ABORT("unsupported hexagon register");
3595+
}
3596+
3597+
inline void Registers_hexagon::setRegister(int regNum, uint32_t value) {
3598+
if (regNum >= UNW_HEXAGON_R0 && regNum <= UNW_HEXAGON_R31) {
3599+
_registers.__r[regNum - UNW_HEXAGON_R0] = value;
3600+
return;
3601+
}
3602+
3603+
switch (regNum) {
3604+
case UNW_REG_IP:
3605+
_registers.__r[UNW_HEXAGON_PC] = value;
3606+
return;
3607+
case UNW_REG_SP:
3608+
_registers.__r[UNW_HEXAGON_R29] = value;
3609+
return;
3610+
}
3611+
_LIBUNWIND_ABORT("unsupported hexagon register");
3612+
}
3613+
3614+
inline bool Registers_hexagon::validFloatRegister(int /* regNum */) const {
3615+
return false;
3616+
}
3617+
3618+
inline double Registers_hexagon::getFloatRegister(int /* regNum */) const {
3619+
_LIBUNWIND_ABORT("hexagon float support not implemented");
3620+
}
3621+
3622+
inline void Registers_hexagon::setFloatRegister(int /* regNum */,
3623+
double /* value */) {
3624+
_LIBUNWIND_ABORT("hexagon float support not implemented");
3625+
}
3626+
3627+
inline bool Registers_hexagon::validVectorRegister(int /* regNum */) const {
3628+
return false;
3629+
}
3630+
3631+
inline v128 Registers_hexagon::getVectorRegister(int /* regNum */) const {
3632+
_LIBUNWIND_ABORT("hexagon vector support not implemented");
3633+
}
3634+
3635+
inline void Registers_hexagon::setVectorRegister(int /* regNum */, v128 /* value */) {
3636+
_LIBUNWIND_ABORT("hexagon vector support not implemented");
3637+
}
3638+
3639+
inline const char *Registers_hexagon::getRegisterName(int regNum) {
3640+
switch (regNum) {
3641+
case UNW_HEXAGON_R0:
3642+
return "r0";
3643+
case UNW_HEXAGON_R1:
3644+
return "r1";
3645+
case UNW_HEXAGON_R2:
3646+
return "r2";
3647+
case UNW_HEXAGON_R3:
3648+
return "r3";
3649+
case UNW_HEXAGON_R4:
3650+
return "r4";
3651+
case UNW_HEXAGON_R5:
3652+
return "r5";
3653+
case UNW_HEXAGON_R6:
3654+
return "r6";
3655+
case UNW_HEXAGON_R7:
3656+
return "r7";
3657+
case UNW_HEXAGON_R8:
3658+
return "r8";
3659+
case UNW_HEXAGON_R9:
3660+
return "r9";
3661+
case UNW_HEXAGON_R10:
3662+
return "r10";
3663+
case UNW_HEXAGON_R11:
3664+
return "r11";
3665+
case UNW_HEXAGON_R12:
3666+
return "r12";
3667+
case UNW_HEXAGON_R13:
3668+
return "r13";
3669+
case UNW_HEXAGON_R14:
3670+
return "r14";
3671+
case UNW_HEXAGON_R15:
3672+
return "r15";
3673+
case UNW_HEXAGON_R16:
3674+
return "r16";
3675+
case UNW_HEXAGON_R17:
3676+
return "r17";
3677+
case UNW_HEXAGON_R18:
3678+
return "r18";
3679+
case UNW_HEXAGON_R19:
3680+
return "r19";
3681+
case UNW_HEXAGON_R20:
3682+
return "r20";
3683+
case UNW_HEXAGON_R21:
3684+
return "r21";
3685+
case UNW_HEXAGON_R22:
3686+
return "r22";
3687+
case UNW_HEXAGON_R23:
3688+
return "r23";
3689+
case UNW_HEXAGON_R24:
3690+
return "r24";
3691+
case UNW_HEXAGON_R25:
3692+
return "r25";
3693+
case UNW_HEXAGON_R26:
3694+
return "r26";
3695+
case UNW_HEXAGON_R27:
3696+
return "r27";
3697+
case UNW_HEXAGON_R28:
3698+
return "r28";
3699+
case UNW_HEXAGON_R29:
3700+
return "r29";
3701+
case UNW_HEXAGON_R30:
3702+
return "r30";
3703+
case UNW_HEXAGON_R31:
3704+
return "r31";
3705+
default:
3706+
return "unknown register";
3707+
}
3708+
3709+
}
3710+
#endif // _LIBUNWIND_TARGET_HEXAGON
3711+
3712+
35313713
#if defined(_LIBUNWIND_TARGET_RISCV)
35323714
/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
35333715
/// process.

libunwind/src/UnwindCursor.hpp

+6
Original file line numberDiff line numberDiff line change
@@ -1123,6 +1123,12 @@ class UnwindCursor : public AbstractUnwindCursor{
11231123
}
11241124
#endif
11251125

1126+
#if defined (_LIBUNWIND_TARGET_HEXAGON)
1127+
compact_unwind_encoding_t dwarfEncoding(Registers_hexagon &) const {
1128+
return 0;
1129+
}
1130+
#endif
1131+
11261132
#if defined (_LIBUNWIND_TARGET_MIPS_O32)
11271133
compact_unwind_encoding_t dwarfEncoding(Registers_mips_o32 &) const {
11281134
return 0;

libunwind/src/UnwindRegistersRestore.S

+42
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,48 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind14Registers_or1k6jumptoEv)
808808
l.jr r9
809809
l.nop
810810

811+
#elif defined(__hexagon__)
812+
# On entry:
813+
# thread_state pointer is in r2
814+
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind17Registers_hexagon6jumptoEv)
815+
#
816+
# void libunwind::Registers_hexagon::jumpto()
817+
#
818+
r8 = memw(r0+#32)
819+
r9 = memw(r0+#36)
820+
r10 = memw(r0+#40)
821+
r11 = memw(r0+#44)
822+
823+
r12 = memw(r0+#48)
824+
r13 = memw(r0+#52)
825+
r14 = memw(r0+#56)
826+
r15 = memw(r0+#60)
827+
828+
r16 = memw(r0+#64)
829+
r17 = memw(r0+#68)
830+
r18 = memw(r0+#72)
831+
r19 = memw(r0+#76)
832+
833+
r20 = memw(r0+#80)
834+
r21 = memw(r0+#84)
835+
r22 = memw(r0+#88)
836+
r23 = memw(r0+#92)
837+
838+
r24 = memw(r0+#96)
839+
r25 = memw(r0+#100)
840+
r26 = memw(r0+#104)
841+
r27 = memw(r0+#108)
842+
843+
r28 = memw(r0+#112)
844+
r29 = memw(r0+#116)
845+
r30 = memw(r0+#120)
846+
r31 = memw(r0+#132)
847+
848+
r1 = memw(r0+#128)
849+
c4 = r1 // Predicate register
850+
r1 = memw(r0+#4)
851+
r0 = memw(r0)
852+
jumpr r31
811853
#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
812854

813855
//

libunwind/src/UnwindRegistersSave.S

+46
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,52 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
945945
# zero epcr
946946
l.sw 132(r3), r0
947947

948+
#elif defined(__hexagon__)
949+
#
950+
# extern int unw_getcontext(unw_context_t* thread_state)
951+
#
952+
# On entry:
953+
# thread_state pointer is in r0
954+
#
955+
#define OFFSET(offset) (offset/4)
956+
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
957+
memw(r0+#32) = r8
958+
memw(r0+#36) = r9
959+
memw(r0+#40) = r10
960+
memw(r0+#44) = r11
961+
962+
memw(r0+#48) = r12
963+
memw(r0+#52) = r13
964+
memw(r0+#56) = r14
965+
memw(r0+#60) = r15
966+
967+
memw(r0+#64) = r16
968+
memw(r0+#68) = r17
969+
memw(r0+#72) = r18
970+
memw(r0+#76) = r19
971+
972+
memw(r0+#80) = r20
973+
memw(r0+#84) = r21
974+
memw(r0+#88) = r22
975+
memw(r0+#92) = r23
976+
977+
memw(r0+#96) = r24
978+
memw(r0+#100) = r25
979+
memw(r0+#104) = r26
980+
memw(r0+#108) = r27
981+
982+
memw(r0+#112) = r28
983+
memw(r0+#116) = r29
984+
memw(r0+#120) = r30
985+
memw(r0+#124) = r31
986+
r1 = c4 // Predicate register
987+
memw(r0+#128) = r1
988+
r1 = memw(r30) // *FP == Saved FP
989+
r1 = r31
990+
memw(r0+#132) = r1
991+
992+
jumpr r31
993+
948994
#elif defined(__sparc__)
949995

950996
#

0 commit comments

Comments
 (0)