[libunwind] ce3d1c6 - [libunwind][RISCV] Add 64-bit RISC-V support

Sam Elliott via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 16 08:37:06 PST 2019


Author: Sam Elliott
Date: 2019-12-16T16:36:56Z
New Revision: ce3d1c6d61dcd96f44492516f8b613bbcadaeb8e

URL: https://github.com/llvm/llvm-project/commit/ce3d1c6d61dcd96f44492516f8b613bbcadaeb8e
DIFF: https://github.com/llvm/llvm-project/commit/ce3d1c6d61dcd96f44492516f8b613bbcadaeb8e.diff

LOG: [libunwind][RISCV] Add 64-bit RISC-V support

Summary:
Add unwinding support for 64-bit RISC-V.

This is from the FreeBSD implementation with the following minor
changes:

- Renamed and renumbered DWARF registers to match the RISC-V ABI [1]
- Use the ABI mneumonics in getRegisterName() instead of the exact
   register names
- Include checks for __riscv_xlen == 64 to facilitate adding the 32-bit
   ABI in the future.

[1] https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md

Patch by Mitchell Horne (mhorne)

Reviewers: lenary, luismarques, compnerd, phosek

Reviewed By: lenary, luismarques

Subscribers: arichardson, sameer.abuasal, abidh, asb, aprantl, krytarowski, simoncook, kito-cheng, christof, shiva0217, rogfer01, rkruppe, PkmX, psnobl, benna, lenary, s.egerton, luismarques, emaste, cfe-commits

Differential Revision: https://reviews.llvm.org/D68362

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/config.h
    libunwind/src/libunwind.cpp

Removed: 
    


################################################################################
diff  --git a/libunwind/include/__libunwind_config.h b/libunwind/include/__libunwind_config.h
index 6e7e5e6f7f86..4d03bd83d8c6 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_RISCV     64
 
 #if defined(_LIBUNWIND_IS_NATIVE_ONLY)
 # if defined(__i386__)
@@ -118,6 +119,15 @@
   #define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_SPARC
   #define _LIBUNWIND_CONTEXT_SIZE 16
   #define _LIBUNWIND_CURSOR_SIZE 23
+# elif defined(__riscv)
+#  if __riscv_xlen == 64
+#    define _LIBUNWIND_TARGET_RISCV 1
+#    define _LIBUNWIND_CONTEXT_SIZE 64
+#    define _LIBUNWIND_CURSOR_SIZE 76
+#  else
+#    error "Unsupported RISC-V ABI"
+#  endif
+# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
 # else
 #  error "Unsupported architecture."
 # endif
@@ -132,6 +142,7 @@
 # define _LIBUNWIND_TARGET_MIPS_O32 1
 # define _LIBUNWIND_TARGET_MIPS_NEWABI 1
 # define _LIBUNWIND_TARGET_SPARC 1
+# define _LIBUNWIND_TARGET_RISCV 1
 # define _LIBUNWIND_CONTEXT_SIZE 167
 # define _LIBUNWIND_CURSOR_SIZE 179
 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287

diff  --git a/libunwind/include/libunwind.h b/libunwind/include/libunwind.h
index d06724d3c31f..1a501b867dda 100644
--- a/libunwind/include/libunwind.h
+++ b/libunwind/include/libunwind.h
@@ -832,4 +832,75 @@ enum {
   UNW_SPARC_I7 = 31,
 };
 
+// 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:
+//
+// https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
+enum {
+  UNW_RISCV_X0  = 0,
+  UNW_RISCV_X1  = 1,
+  UNW_RISCV_X2  = 2,
+  UNW_RISCV_X3  = 3,
+  UNW_RISCV_X4  = 4,
+  UNW_RISCV_X5  = 5,
+  UNW_RISCV_X6  = 6,
+  UNW_RISCV_X7  = 7,
+  UNW_RISCV_X8  = 8,
+  UNW_RISCV_X9  = 9,
+  UNW_RISCV_X10 = 10,
+  UNW_RISCV_X11 = 11,
+  UNW_RISCV_X12 = 12,
+  UNW_RISCV_X13 = 13,
+  UNW_RISCV_X14 = 14,
+  UNW_RISCV_X15 = 15,
+  UNW_RISCV_X16 = 16,
+  UNW_RISCV_X17 = 17,
+  UNW_RISCV_X18 = 18,
+  UNW_RISCV_X19 = 19,
+  UNW_RISCV_X20 = 20,
+  UNW_RISCV_X21 = 21,
+  UNW_RISCV_X22 = 22,
+  UNW_RISCV_X23 = 23,
+  UNW_RISCV_X24 = 24,
+  UNW_RISCV_X25 = 25,
+  UNW_RISCV_X26 = 26,
+  UNW_RISCV_X27 = 27,
+  UNW_RISCV_X28 = 28,
+  UNW_RISCV_X29 = 29,
+  UNW_RISCV_X30 = 30,
+  UNW_RISCV_X31 = 31,
+  UNW_RISCV_F0  = 32,
+  UNW_RISCV_F1  = 33,
+  UNW_RISCV_F2  = 34,
+  UNW_RISCV_F3  = 35,
+  UNW_RISCV_F4  = 36,
+  UNW_RISCV_F5  = 37,
+  UNW_RISCV_F6  = 38,
+  UNW_RISCV_F7  = 39,
+  UNW_RISCV_F8  = 40,
+  UNW_RISCV_F9  = 41,
+  UNW_RISCV_F10 = 42,
+  UNW_RISCV_F11 = 43,
+  UNW_RISCV_F12 = 44,
+  UNW_RISCV_F13 = 45,
+  UNW_RISCV_F14 = 46,
+  UNW_RISCV_F15 = 47,
+  UNW_RISCV_F16 = 48,
+  UNW_RISCV_F17 = 49,
+  UNW_RISCV_F18 = 50,
+  UNW_RISCV_F19 = 51,
+  UNW_RISCV_F20 = 52,
+  UNW_RISCV_F21 = 53,
+  UNW_RISCV_F22 = 54,
+  UNW_RISCV_F23 = 55,
+  UNW_RISCV_F24 = 56,
+  UNW_RISCV_F25 = 57,
+  UNW_RISCV_F26 = 58,
+  UNW_RISCV_F27 = 59,
+  UNW_RISCV_F28 = 60,
+  UNW_RISCV_F29 = 61,
+  UNW_RISCV_F30 = 62,
+  UNW_RISCV_F31 = 63,
+};
+
 #endif

diff  --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index a36c6cf90d3f..416ed61df74a 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_RISCV,
 };
 
 #if defined(_LIBUNWIND_TARGET_I386)
@@ -3517,6 +3518,270 @@ inline const char *Registers_sparc::getRegisterName(int regNum) {
 }
 #endif // _LIBUNWIND_TARGET_SPARC
 
+#if defined(_LIBUNWIND_TARGET_RISCV)
+/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
+/// process.
+class _LIBUNWIND_HIDDEN Registers_riscv {
+public:
+  Registers_riscv();
+  Registers_riscv(const void *registers);
+
+  bool        validRegister(int num) const;
+  uint64_t    getRegister(int num) const;
+  void        setRegister(int num, uint64_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);
+  static const char *getRegisterName(int num);
+  void        jumpto();
+  static int  lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
+  static int  getArch() { return REGISTERS_RISCV; }
+
+  uint64_t  getSP() const         { return _registers[2]; }
+  void      setSP(uint64_t value) { _registers[2] = value; }
+  uint64_t  getIP() const         { return _registers[1]; }
+  void      setIP(uint64_t value) { _registers[1] = value; }
+
+private:
+
+  uint64_t _registers[32];
+  double   _floats[32];
+};
+
+inline Registers_riscv::Registers_riscv(const void *registers) {
+  static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
+                "riscv registers do not fit into unw_context_t");
+  memcpy(&_registers, registers, sizeof(_registers));
+  static_assert(sizeof(_registers) == 0x100,
+                "expected float registers to be at offset 256");
+  memcpy(_floats,
+         static_cast<const uint8_t *>(registers) + sizeof(_registers),
+         sizeof(_floats));
+}
+
+inline Registers_riscv::Registers_riscv() {
+  memset(&_registers, 0, sizeof(_registers));
+  memset(&_floats, 0, sizeof(_floats));
+}
+
+inline bool Registers_riscv::validRegister(int regNum) const {
+  if (regNum == UNW_REG_IP)
+    return true;
+  if (regNum == UNW_REG_SP)
+    return true;
+  if (regNum < 0)
+    return false;
+  if (regNum > UNW_RISCV_F31)
+    return false;
+  return true;
+}
+
+inline uint64_t Registers_riscv::getRegister(int regNum) const {
+  if (regNum == UNW_REG_IP)
+    return _registers[1];
+  if (regNum == UNW_REG_SP)
+    return _registers[2];
+  if (regNum == UNW_RISCV_X0)
+    return 0;
+  if ((regNum > 0) && (regNum < 32))
+    return _registers[regNum];
+  _LIBUNWIND_ABORT("unsupported riscv register");
+}
+
+inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
+  if (regNum == UNW_REG_IP)
+    _registers[1] = value;
+  else if (regNum == UNW_REG_SP)
+    _registers[2] = value;
+  else if (regNum == UNW_RISCV_X0)
+    /* x0 is hardwired to zero */
+    return;
+  else if ((regNum > 0) && (regNum < 32))
+    _registers[regNum] = value;
+  else
+    _LIBUNWIND_ABORT("unsupported riscv register");
+}
+
+inline const char *Registers_riscv::getRegisterName(int regNum) {
+  switch (regNum) {
+  case UNW_REG_IP:
+    return "pc";
+  case UNW_REG_SP:
+    return "sp";
+  case UNW_RISCV_X0:
+    return "zero";
+  case UNW_RISCV_X1:
+    return "ra";
+  case UNW_RISCV_X2:
+    return "sp";
+  case UNW_RISCV_X3:
+    return "gp";
+  case UNW_RISCV_X4:
+    return "tp";
+  case UNW_RISCV_X5:
+    return "t0";
+  case UNW_RISCV_X6:
+    return "t1";
+  case UNW_RISCV_X7:
+    return "t2";
+  case UNW_RISCV_X8:
+    return "s0";
+  case UNW_RISCV_X9:
+    return "s1";
+  case UNW_RISCV_X10:
+    return "a0";
+  case UNW_RISCV_X11:
+    return "a1";
+  case UNW_RISCV_X12:
+    return "a2";
+  case UNW_RISCV_X13:
+    return "a3";
+  case UNW_RISCV_X14:
+    return "a4";
+  case UNW_RISCV_X15:
+    return "a5";
+  case UNW_RISCV_X16:
+    return "a6";
+  case UNW_RISCV_X17:
+    return "a7";
+  case UNW_RISCV_X18:
+    return "s2";
+  case UNW_RISCV_X19:
+    return "s3";
+  case UNW_RISCV_X20:
+    return "s4";
+  case UNW_RISCV_X21:
+    return "s5";
+  case UNW_RISCV_X22:
+    return "s6";
+  case UNW_RISCV_X23:
+    return "s7";
+  case UNW_RISCV_X24:
+    return "s8";
+  case UNW_RISCV_X25:
+    return "s9";
+  case UNW_RISCV_X26:
+    return "s10";
+  case UNW_RISCV_X27:
+    return "s11";
+  case UNW_RISCV_X28:
+    return "t3";
+  case UNW_RISCV_X29:
+    return "t4";
+  case UNW_RISCV_X30:
+    return "t5";
+  case UNW_RISCV_X31:
+    return "t6";
+  case UNW_RISCV_F0:
+    return "ft0";
+  case UNW_RISCV_F1:
+    return "ft1";
+  case UNW_RISCV_F2:
+    return "ft2";
+  case UNW_RISCV_F3:
+    return "ft3";
+  case UNW_RISCV_F4:
+    return "ft4";
+  case UNW_RISCV_F5:
+    return "ft5";
+  case UNW_RISCV_F6:
+    return "ft6";
+  case UNW_RISCV_F7:
+    return "ft7";
+  case UNW_RISCV_F8:
+    return "fs0";
+  case UNW_RISCV_F9:
+    return "fs1";
+  case UNW_RISCV_F10:
+    return "fa0";
+  case UNW_RISCV_F11:
+    return "fa1";
+  case UNW_RISCV_F12:
+    return "fa2";
+  case UNW_RISCV_F13:
+    return "fa3";
+  case UNW_RISCV_F14:
+    return "fa4";
+  case UNW_RISCV_F15:
+    return "fa5";
+  case UNW_RISCV_F16:
+    return "fa6";
+  case UNW_RISCV_F17:
+    return "fa7";
+  case UNW_RISCV_F18:
+    return "fs2";
+  case UNW_RISCV_F19:
+    return "fs3";
+  case UNW_RISCV_F20:
+    return "fs4";
+  case UNW_RISCV_F21:
+    return "fs5";
+  case UNW_RISCV_F22:
+    return "fs6";
+  case UNW_RISCV_F23:
+    return "fs7";
+  case UNW_RISCV_F24:
+    return "fs8";
+  case UNW_RISCV_F25:
+    return "fs9";
+  case UNW_RISCV_F26:
+    return "fs10";
+  case UNW_RISCV_F27:
+    return "fs11";
+  case UNW_RISCV_F28:
+    return "ft8";
+  case UNW_RISCV_F29:
+    return "ft9";
+  case UNW_RISCV_F30:
+    return "ft10";
+  case UNW_RISCV_F31:
+    return "ft11";
+  default:
+    return "unknown register";
+  }
+}
+
+inline bool Registers_riscv::validFloatRegister(int regNum) const {
+  if (regNum < UNW_RISCV_F0)
+    return false;
+  if (regNum > UNW_RISCV_F31)
+    return false;
+  return true;
+}
+
+inline double Registers_riscv::getFloatRegister(int regNum) const {
+#if defined(__riscv_flen) && __riscv_flen == 64
+  assert(validFloatRegister(regNum));
+  return _floats[regNum - UNW_RISCV_F0];
+#else
+  _LIBUNWIND_ABORT("libunwind not built with float support");
+#endif
+}
+
+inline void Registers_riscv::setFloatRegister(int regNum, double value) {
+#if defined(__riscv_flen) && __riscv_flen == 64
+  assert(validFloatRegister(regNum));
+  _floats[regNum - UNW_RISCV_F0] = value;
+#else
+  _LIBUNWIND_ABORT("libunwind not built with float support");
+#endif
+}
+
+inline bool Registers_riscv::validVectorRegister(int) const {
+  return false;
+}
+
+inline v128 Registers_riscv::getVectorRegister(int) const {
+  _LIBUNWIND_ABORT("no riscv vector register support yet");
+}
+
+inline void Registers_riscv::setVectorRegister(int, v128) {
+  _LIBUNWIND_ABORT("no riscv vector register support yet");
+}
+#endif // _LIBUNWIND_TARGET_RISCV
 } // namespace libunwind
 
 #endif // __REGISTERS_HPP__

diff  --git a/libunwind/src/UnwindCursor.hpp b/libunwind/src/UnwindCursor.hpp
index 4c18614b33d2..31be8366d238 100644
--- a/libunwind/src/UnwindCursor.hpp
+++ b/libunwind/src/UnwindCursor.hpp
@@ -995,6 +995,12 @@ class UnwindCursor : public AbstractUnwindCursor{
   int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
 #endif
 
+#if defined (_LIBUNWIND_TARGET_RISCV)
+  int stepWithCompactEncoding(Registers_riscv &) {
+    return UNW_EINVAL;
+  }
+#endif
+
   bool compactSaysUseDwarf(uint32_t *offset=NULL) const {
     R dummy;
     return compactSaysUseDwarf(dummy, offset);
@@ -1061,6 +1067,12 @@ class UnwindCursor : public AbstractUnwindCursor{
   bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
 #endif
 
+#if defined (_LIBUNWIND_TARGET_RISCV)
+  bool compactSaysUseDwarf(Registers_riscv &, uint32_t *) const {
+    return true;
+  }
+#endif
+
 #endif // defined(_LIBUNWIND_SUPPORT_COMPACT_UNWIND)
 
 #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
@@ -1127,6 +1139,12 @@ class UnwindCursor : public AbstractUnwindCursor{
   compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
 #endif
 
+#if defined (_LIBUNWIND_TARGET_RISCV)
+  compact_unwind_encoding_t dwarfEncoding(Registers_riscv &) const {
+    return 0;
+  }
+#endif
+
 #endif // defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
 
 #if defined(_LIBUNWIND_SUPPORT_SEH_UNWIND)

diff  --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S
index 8122bf3e1b2e..cbb2fd447005 100644
--- a/libunwind/src/UnwindRegistersRestore.S
+++ b/libunwind/src/UnwindRegistersRestore.S
@@ -1029,6 +1029,87 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
   jmp %o7
    nop
 
+#elif defined(__riscv) && __riscv_xlen == 64
+
+//
+// void libunwind::Registers_riscv::jumpto()
+//
+// On entry:
+//  thread_state pointer is in a0
+//
+  .p2align 2
+DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
+#if defined(__riscv_flen) && __riscv_flen == 64
+  fld    f0, (8 * 32 + 8 * 0)(a0)
+  fld    f1, (8 * 32 + 8 * 1)(a0)
+  fld    f2, (8 * 32 + 8 * 2)(a0)
+  fld    f3, (8 * 32 + 8 * 3)(a0)
+  fld    f4, (8 * 32 + 8 * 4)(a0)
+  fld    f5, (8 * 32 + 8 * 5)(a0)
+  fld    f6, (8 * 32 + 8 * 6)(a0)
+  fld    f7, (8 * 32 + 8 * 7)(a0)
+  fld    f8, (8 * 32 + 8 * 8)(a0)
+  fld    f9, (8 * 32 + 8 * 9)(a0)
+  fld    f10, (8 * 32 + 8 * 10)(a0)
+  fld    f11, (8 * 32 + 8 * 11)(a0)
+  fld    f12, (8 * 32 + 8 * 12)(a0)
+  fld    f13, (8 * 32 + 8 * 13)(a0)
+  fld    f14, (8 * 32 + 8 * 14)(a0)
+  fld    f15, (8 * 32 + 8 * 15)(a0)
+  fld    f16, (8 * 32 + 8 * 16)(a0)
+  fld    f17, (8 * 32 + 8 * 17)(a0)
+  fld    f18, (8 * 32 + 8 * 18)(a0)
+  fld    f19, (8 * 32 + 8 * 19)(a0)
+  fld    f20, (8 * 32 + 8 * 20)(a0)
+  fld    f21, (8 * 32 + 8 * 21)(a0)
+  fld    f22, (8 * 32 + 8 * 22)(a0)
+  fld    f23, (8 * 32 + 8 * 23)(a0)
+  fld    f24, (8 * 32 + 8 * 24)(a0)
+  fld    f25, (8 * 32 + 8 * 25)(a0)
+  fld    f26, (8 * 32 + 8 * 26)(a0)
+  fld    f27, (8 * 32 + 8 * 27)(a0)
+  fld    f28, (8 * 32 + 8 * 28)(a0)
+  fld    f29, (8 * 32 + 8 * 29)(a0)
+  fld    f30, (8 * 32 + 8 * 30)(a0)
+  fld    f31, (8 * 32 + 8 * 31)(a0)
+#endif
+
+  // x0 is zero
+  ld    x1, (8 * 1)(a0)
+  ld    x2, (8 * 2)(a0)
+  ld    x3, (8 * 3)(a0)
+  ld    x4, (8 * 4)(a0)
+  ld    x5, (8 * 5)(a0)
+  ld    x6, (8 * 6)(a0)
+  ld    x7, (8 * 7)(a0)
+  ld    x8, (8 * 8)(a0)
+  ld    x9, (8 * 9)(a0)
+  // skip a0 for now
+  ld    x11, (8 * 11)(a0)
+  ld    x12, (8 * 12)(a0)
+  ld    x13, (8 * 13)(a0)
+  ld    x14, (8 * 14)(a0)
+  ld    x15, (8 * 15)(a0)
+  ld    x16, (8 * 16)(a0)
+  ld    x17, (8 * 17)(a0)
+  ld    x18, (8 * 18)(a0)
+  ld    x19, (8 * 19)(a0)
+  ld    x20, (8 * 20)(a0)
+  ld    x21, (8 * 21)(a0)
+  ld    x22, (8 * 22)(a0)
+  ld    x23, (8 * 23)(a0)
+  ld    x24, (8 * 24)(a0)
+  ld    x25, (8 * 25)(a0)
+  ld    x26, (8 * 26)(a0)
+  ld    x27, (8 * 27)(a0)
+  ld    x28, (8 * 28)(a0)
+  ld    x29, (8 * 29)(a0)
+  ld    x30, (8 * 30)(a0)
+  ld    x31, (8 * 31)(a0)
+  ld    x10, (8 * 10)(a0)   // restore a0
+
+  ret                       // jump to ra
+
 #endif
 
 #endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */

diff  --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S
index 54505e53bac7..da91abc233de 100644
--- a/libunwind/src/UnwindRegistersSave.S
+++ b/libunwind/src/UnwindRegistersSave.S
@@ -974,6 +974,86 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
   std %i6, [%o0 + 120]
   jmp %o7
    clr %o0                   // return UNW_ESUCCESS
+
+#elif defined(__riscv) && __riscv_xlen == 64
+
+#
+# extern int __unw_getcontext(unw_context_t* thread_state)
+#
+# On entry:
+#  thread_state pointer is in a0
+#
+DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
+  // x0 is zero
+  sd    x1, (8 * 1)(a0)
+  sd    x2, (8 * 2)(a0)
+  sd    x3, (8 * 3)(a0)
+  sd    x4, (8 * 4)(a0)
+  sd    x5, (8 * 5)(a0)
+  sd    x6, (8 * 6)(a0)
+  sd    x7, (8 * 7)(a0)
+  sd    x8, (8 * 8)(a0)
+  sd    x9, (8 * 9)(a0)
+  sd    x10, (8 * 10)(a0)
+  sd    x11, (8 * 11)(a0)
+  sd    x12, (8 * 12)(a0)
+  sd    x13, (8 * 13)(a0)
+  sd    x14, (8 * 14)(a0)
+  sd    x15, (8 * 15)(a0)
+  sd    x16, (8 * 16)(a0)
+  sd    x17, (8 * 17)(a0)
+  sd    x18, (8 * 18)(a0)
+  sd    x19, (8 * 19)(a0)
+  sd    x20, (8 * 20)(a0)
+  sd    x21, (8 * 21)(a0)
+  sd    x22, (8 * 22)(a0)
+  sd    x23, (8 * 23)(a0)
+  sd    x24, (8 * 24)(a0)
+  sd    x25, (8 * 25)(a0)
+  sd    x26, (8 * 26)(a0)
+  sd    x27, (8 * 27)(a0)
+  sd    x28, (8 * 28)(a0)
+  sd    x29, (8 * 29)(a0)
+  sd    x30, (8 * 30)(a0)
+  sd    x31, (8 * 31)(a0)
+
+#if defined(__riscv_flen) && __riscv_flen == 64
+  fsd    f0, (8 * 32 + 8 * 0)(a0)
+  fsd    f1, (8 * 32 + 8 * 1)(a0)
+  fsd    f2, (8 * 32 + 8 * 2)(a0)
+  fsd    f3, (8 * 32 + 8 * 3)(a0)
+  fsd    f4, (8 * 32 + 8 * 4)(a0)
+  fsd    f5, (8 * 32 + 8 * 5)(a0)
+  fsd    f6, (8 * 32 + 8 * 6)(a0)
+  fsd    f7, (8 * 32 + 8 * 7)(a0)
+  fsd    f8, (8 * 32 + 8 * 8)(a0)
+  fsd    f9, (8 * 32 + 8 * 9)(a0)
+  fsd    f10, (8 * 32 + 8 * 10)(a0)
+  fsd    f11, (8 * 32 + 8 * 11)(a0)
+  fsd    f12, (8 * 32 + 8 * 12)(a0)
+  fsd    f13, (8 * 32 + 8 * 13)(a0)
+  fsd    f14, (8 * 32 + 8 * 14)(a0)
+  fsd    f15, (8 * 32 + 8 * 15)(a0)
+  fsd    f16, (8 * 32 + 8 * 16)(a0)
+  fsd    f17, (8 * 32 + 8 * 17)(a0)
+  fsd    f18, (8 * 32 + 8 * 18)(a0)
+  fsd    f19, (8 * 32 + 8 * 19)(a0)
+  fsd    f20, (8 * 32 + 8 * 20)(a0)
+  fsd    f21, (8 * 32 + 8 * 21)(a0)
+  fsd    f22, (8 * 32 + 8 * 22)(a0)
+  fsd    f23, (8 * 32 + 8 * 23)(a0)
+  fsd    f24, (8 * 32 + 8 * 24)(a0)
+  fsd    f25, (8 * 32 + 8 * 25)(a0)
+  fsd    f26, (8 * 32 + 8 * 26)(a0)
+  fsd    f27, (8 * 32 + 8 * 27)(a0)
+  fsd    f28, (8 * 32 + 8 * 28)(a0)
+  fsd    f29, (8 * 32 + 8 * 29)(a0)
+  fsd    f30, (8 * 32 + 8 * 30)(a0)
+  fsd    f31, (8 * 32 + 8 * 31)(a0)
+#endif
+
+  li     a0, 0  // return UNW_ESUCCESS
+  ret           // jump to ra
 #endif
 
   WEAK_ALIAS(__unw_getcontext, unw_getcontext)

diff  --git a/libunwind/src/config.h b/libunwind/src/config.h
index 09bb261647ca..dcd3cef94552 100644
--- a/libunwind/src/config.h
+++ b/libunwind/src/config.h
@@ -103,7 +103,8 @@
     defined(__ppc__) || defined(__ppc64__) || defined(__powerpc64__) ||        \
     (!defined(__APPLE__) && defined(__arm__)) ||                               \
     (defined(__arm64__) || defined(__aarch64__)) ||                            \
-    defined(__mips__)
+    defined(__mips__) ||                                                       \
+    defined(__riscv)
 #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 31f30f5cd709..1ee58ad1971e 100644
--- a/libunwind/src/libunwind.cpp
+++ b/libunwind/src/libunwind.cpp
@@ -58,6 +58,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
 # warning The MIPS architecture is not supported with this ABI and environment!
 #elif defined(__sparc__)
 # define REGISTER_KIND Registers_sparc
+#elif defined(__riscv) && __riscv_xlen == 64
+# define REGISTER_KIND Registers_riscv
 #else
 # error Architecture not supported
 #endif


        


More information about the cfe-commits mailing list