Author: Kamlesh Kumar
Date: 2021-03-02T06:58:24+05:30
New Revision: b17d46430fce665d23661e23ade3ca57c3791836
URL:
https://github.com/llvm/llvm-project/commit/b17d46430fce665d23661e23ade3ca57c3791836
DIFF:
https://github.com/llvm/llvm-project/commit/b17d46430fce665d23661e23ade3ca57c3791836.diff
LOG: [libunwind] This adds support in libunwind for rv32 hard float
and soft-float for both rv32 and rv64.
Differential Revision: https://reviews.llvm.org/D80690
Added:
Modified:
libunwind/include/__libunwind_config.h
libunwind/src/Registers.hpp
libunwind/src/UnwindRegistersRestore.S
libunwind/src/UnwindRegistersSave.S
libunwind/src/assembly.h
libunwind/src/libunwind.cpp
Removed:
diff --git a/libunwind/include/__libunwind_config.h
b/libunwind/include/__libunwind_config.h
index 34ac6f717d6e..a50ba053884b 100644
--- a/libunwind/include/__libunwind_config.h
+++ b/libunwind/include/__libunwind_config.h
@@ -131,12 +131,19 @@
#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
+# define _LIBUNWIND_TARGET_RISCV 1
+# if defined(__riscv_flen)
+# define RISCV_FLEN __riscv_flen
# else
-#error "Unsupported RISC-V ABI"
+# define RISCV_FLEN 0
+# endif
+# define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64)
+# if __riscv_xlen == 32
+# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 7)
+# elif __riscv_xlen == 64
+# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 12)
+# else
+# error "Unsupported RISC-V ABI"
# endif
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER
_LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
# elif defined(__ve__)
diff --git a/libunwind/src/Registers.hpp b/libunwind/src/Registers.hpp
index de8e067b9d0c..1d23f97aedfb 100644
--- a/libunwind/src/Registers.hpp
+++ b/libunwind/src/Registers.hpp
@@ -3728,19 +3728,42 @@ inline const char
*Registers_hexagon::getRegisterName(int regNum) {
#if defined(_LIBUNWIND_TARGET_RISCV)
-/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
+/// Registers_riscv holds the register state of a thread in a RISC-V
/// process.
+
+# if __riscv_xlen == 32
+typedef uint32_t reg_t;
+# elif __riscv_xlen == 64
+typedef uint64_t reg_t;
+# else
+# error "Unsupported __riscv_xlen"
+# endif
+
+# if defined(__riscv_flen)
+# if __riscv_flen == 64
+typedef double fp_t;
+# elif __riscv_flen == 32
+typedef float fp_t;
+# else
+# error "Unsupported __riscv_flen"
+# endif
+# else
+// This is just for supressing undeclared error of fp_t.
+typedef double fp_t;
+# endif
+
+/// Registers_riscv holds the register state of a thread.
class _LIBUNWIND_HIDDEN Registers_riscv {
public:
Registers_riscv();
Registers_riscv(const void *registers);
boolvalidRegister(int num) const;
- uint64_tgetRegister(int num) const;
- voidsetRegister(int num, uint64_t value);
+ reg_t getRegister(int num) const;
+ voidsetRegister(int num, reg_t value);
boolvalidFloatRegister(int num) const;
- double getFloatRegister(int num) const;
- voidsetFloatRegister(int num, double value);
+ fp_tgetFloatRegister(int num) const;
+ voidsetFloatRegister(int num, fp_t value);
boolvalidVectorRegister(int num) const;
v128getVectorRegister(int num) const;
voidsetVectorRegister(int num, v128 value);
@@ -3749,31 +3772,45 @@ class _LIBUNWIND_HIDDEN Registers_riscv {
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[0]; }
- void setIP(uint64_t value) { _registers[0] = value; }
+ reg_t getSP() const { return _registers[2]; }
+ voidsetSP(reg_t value) { _registers[2] = value; }
+ reg_t getIP() const { return _registers[0]; }
+ voidsetIP(reg_t value) { _registers[0] = value; }
private:
// _registers[0] holds the pc
- uint64_t _registers[32];
- double _floats[32];
+ reg_t _registers[32];
+# if defined(__riscv_flen)
+ fp_t _floats[32];
+# endif
};
inline Registers_riscv::Registers_riscv(const void *registers) {
static_assert((check_fit::does_fit),
"riscv registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
+# if __riscv_xlen == 32
+ static_assert(sizeof(_registers) == 0x80,
+"expected float registers to be at offset 128");
+# elif __riscv_xlen == 64
static_assert(sizeof(_registers) == 0x100,
"expected float