[libunwind] 9107594 - [libunwind] add hexagon support
Brian Cain via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 10 02:24:30 PDT 2020
Author: Brian Cain
Date: 2020-04-10T04:24:10-05:00
New Revision: 9107594f376e37e99c71881404c686b306f93ad2
URL: https://github.com/llvm/llvm-project/commit/9107594f376e37e99c71881404c686b306f93ad2
DIFF: https://github.com/llvm/llvm-project/commit/9107594f376e37e99c71881404c686b306f93ad2.diff
LOG: [libunwind] add hexagon support
Added:
Modified:
libunwind/include/__libunwind_config.h
libunwind/include/libunwind.h
libunwind/src/Registers.hpp
libunwind/src/UnwindCursor.hpp
libunwind/src/UnwindRegistersRestore.S
libunwind/src/UnwindRegistersSave.S
libunwind/src/assembly.h
libunwind/src/config.h
libunwind/src/libunwind.cpp
Removed:
################################################################################
diff --git a/libunwind/include/__libunwind_config.h b/libunwind/include/__libunwind_config.h
index 4d03bd83d8c6..71d77ca65118 100644
--- a/libunwind/include/__libunwind_config.h
+++ b/libunwind/include/__libunwind_config.h
@@ -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
diff --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index 1a501b867dda..23ef47f4ac83 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -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:
//
diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index ffc75eee6bf8..26a0fa8f338e 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -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.
diff --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 32d71c2c1ed3..8200eeee4eaa 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -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;
diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S
index 266da5e82229..9ad521591918 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -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
//
diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S
index 5a89d1965d62..9e52c4c9b772 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -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__)
#
diff --git a/libunwind/src/assembly.h b/libunwind/src/assembly.h
index 2c1337bd53b1..4cf179e13edc 100644
--- a/libunwind/src/assembly.h
+++ b/libunwind/src/assembly.h
@@ -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__)
diff --git a/libunwind/src/config.h b/libunwind/src/config.h
index bce53c2f65b2..842fd829af19 100644
--- a/libunwind/src/config.h
+++ b/libunwind/src/config.h
@@ -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
diff --git a/libunwind/src/libunwind.cpp b/libunwind/src/libunwind.cpp
index 1ee58ad1971e..fd079da30895 100644
--- a/libunwind/src/libunwind.cpp
+++ b/libunwind/src/libunwind.cpp
@@ -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)
More information about the cfe-commits
mailing list