Skip to content

Commit 1d187f8

Browse files
kamleshbhaluimemfrob
authored and
memfrob
committed
[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
1 parent 00b47f6 commit 1d187f8

File tree

6 files changed

+239
-161
lines changed

6 files changed

+239
-161
lines changed

libunwind/include/__libunwind_config.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,19 @@
131131
#define _LIBUNWIND_CONTEXT_SIZE 16
132132
#define _LIBUNWIND_CURSOR_SIZE 23
133133
# elif defined(__riscv)
134-
# if __riscv_xlen == 64
135-
# define _LIBUNWIND_TARGET_RISCV 1
136-
# define _LIBUNWIND_CONTEXT_SIZE 64
137-
# define _LIBUNWIND_CURSOR_SIZE 76
134+
# define _LIBUNWIND_TARGET_RISCV 1
135+
# if defined(__riscv_flen)
136+
# define RISCV_FLEN __riscv_flen
138137
# else
139-
# error "Unsupported RISC-V ABI"
138+
# define RISCV_FLEN 0
139+
# endif
140+
# define _LIBUNWIND_CONTEXT_SIZE (32 * (__riscv_xlen + RISCV_FLEN) / 64)
141+
# if __riscv_xlen == 32
142+
# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 7)
143+
# elif __riscv_xlen == 64
144+
# define _LIBUNWIND_CURSOR_SIZE (_LIBUNWIND_CONTEXT_SIZE + 12)
145+
# else
146+
# error "Unsupported RISC-V ABI"
140147
# endif
141148
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV
142149
# elif defined(__ve__)

libunwind/src/Registers.hpp

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3728,19 +3728,42 @@ inline const char *Registers_hexagon::getRegisterName(int regNum) {
37283728

37293729

37303730
#if defined(_LIBUNWIND_TARGET_RISCV)
3731-
/// Registers_riscv holds the register state of a thread in a 64-bit RISC-V
3731+
/// Registers_riscv holds the register state of a thread in a RISC-V
37323732
/// process.
3733+
3734+
# if __riscv_xlen == 32
3735+
typedef uint32_t reg_t;
3736+
# elif __riscv_xlen == 64
3737+
typedef uint64_t reg_t;
3738+
# else
3739+
# error "Unsupported __riscv_xlen"
3740+
# endif
3741+
3742+
# if defined(__riscv_flen)
3743+
# if __riscv_flen == 64
3744+
typedef double fp_t;
3745+
# elif __riscv_flen == 32
3746+
typedef float fp_t;
3747+
# else
3748+
# error "Unsupported __riscv_flen"
3749+
# endif
3750+
# else
3751+
// This is just for supressing undeclared error of fp_t.
3752+
typedef double fp_t;
3753+
# endif
3754+
3755+
/// Registers_riscv holds the register state of a thread.
37333756
class _LIBUNWIND_HIDDEN Registers_riscv {
37343757
public:
37353758
Registers_riscv();
37363759
Registers_riscv(const void *registers);
37373760

37383761
bool validRegister(int num) const;
3739-
uint64_t getRegister(int num) const;
3740-
void setRegister(int num, uint64_t value);
3762+
reg_t getRegister(int num) const;
3763+
void setRegister(int num, reg_t value);
37413764
bool validFloatRegister(int num) const;
3742-
double getFloatRegister(int num) const;
3743-
void setFloatRegister(int num, double value);
3765+
fp_t getFloatRegister(int num) const;
3766+
void setFloatRegister(int num, fp_t value);
37443767
bool validVectorRegister(int num) const;
37453768
v128 getVectorRegister(int num) const;
37463769
void setVectorRegister(int num, v128 value);
@@ -3749,31 +3772,45 @@ class _LIBUNWIND_HIDDEN Registers_riscv {
37493772
static int lastDwarfRegNum() { return _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV; }
37503773
static int getArch() { return REGISTERS_RISCV; }
37513774

3752-
uint64_t getSP() const { return _registers[2]; }
3753-
void setSP(uint64_t value) { _registers[2] = value; }
3754-
uint64_t getIP() const { return _registers[0]; }
3755-
void setIP(uint64_t value) { _registers[0] = value; }
3775+
reg_t getSP() const { return _registers[2]; }
3776+
void setSP(reg_t value) { _registers[2] = value; }
3777+
reg_t getIP() const { return _registers[0]; }
3778+
void setIP(reg_t value) { _registers[0] = value; }
37563779

37573780
private:
37583781
// _registers[0] holds the pc
3759-
uint64_t _registers[32];
3760-
double _floats[32];
3782+
reg_t _registers[32];
3783+
# if defined(__riscv_flen)
3784+
fp_t _floats[32];
3785+
# endif
37613786
};
37623787

37633788
inline Registers_riscv::Registers_riscv(const void *registers) {
37643789
static_assert((check_fit<Registers_riscv, unw_context_t>::does_fit),
37653790
"riscv registers do not fit into unw_context_t");
37663791
memcpy(&_registers, registers, sizeof(_registers));
3792+
# if __riscv_xlen == 32
3793+
static_assert(sizeof(_registers) == 0x80,
3794+
"expected float registers to be at offset 128");
3795+
# elif __riscv_xlen == 64
37673796
static_assert(sizeof(_registers) == 0x100,
37683797
"expected float registers to be at offset 256");
3798+
# else
3799+
# error "Unexpected float registers."
3800+
# endif
3801+
3802+
# if defined(__riscv_flen)
37693803
memcpy(_floats,
37703804
static_cast<const uint8_t *>(registers) + sizeof(_registers),
37713805
sizeof(_floats));
3806+
# endif
37723807
}
37733808

37743809
inline Registers_riscv::Registers_riscv() {
37753810
memset(&_registers, 0, sizeof(_registers));
3811+
# if defined(__riscv_flen)
37763812
memset(&_floats, 0, sizeof(_floats));
3813+
# endif
37773814
}
37783815

37793816
inline bool Registers_riscv::validRegister(int regNum) const {
@@ -3788,7 +3825,7 @@ inline bool Registers_riscv::validRegister(int regNum) const {
37883825
return true;
37893826
}
37903827

3791-
inline uint64_t Registers_riscv::getRegister(int regNum) const {
3828+
inline reg_t Registers_riscv::getRegister(int regNum) const {
37923829
if (regNum == UNW_REG_IP)
37933830
return _registers[0];
37943831
if (regNum == UNW_REG_SP)
@@ -3800,7 +3837,7 @@ inline uint64_t Registers_riscv::getRegister(int regNum) const {
38003837
_LIBUNWIND_ABORT("unsupported riscv register");
38013838
}
38023839

3803-
inline void Registers_riscv::setRegister(int regNum, uint64_t value) {
3840+
inline void Registers_riscv::setRegister(int regNum, reg_t value) {
38043841
if (regNum == UNW_REG_IP)
38053842
_registers[0] = value;
38063843
else if (regNum == UNW_REG_SP)
@@ -3954,32 +3991,37 @@ inline const char *Registers_riscv::getRegisterName(int regNum) {
39543991
}
39553992

39563993
inline bool Registers_riscv::validFloatRegister(int regNum) const {
3994+
# if defined(__riscv_flen)
39573995
if (regNum < UNW_RISCV_F0)
39583996
return false;
39593997
if (regNum > UNW_RISCV_F31)
39603998
return false;
39613999
return true;
4000+
# else
4001+
(void)regNum;
4002+
return false;
4003+
# endif
39624004
}
39634005

3964-
inline double Registers_riscv::getFloatRegister(int regNum) const {
3965-
#if defined(__riscv_flen) && __riscv_flen == 64
4006+
inline fp_t Registers_riscv::getFloatRegister(int regNum) const {
4007+
# if defined(__riscv_flen)
39664008
assert(validFloatRegister(regNum));
39674009
return _floats[regNum - UNW_RISCV_F0];
3968-
#else
4010+
# else
39694011
(void)regNum;
39704012
_LIBUNWIND_ABORT("libunwind not built with float support");
3971-
#endif
4013+
# endif
39724014
}
39734015

3974-
inline void Registers_riscv::setFloatRegister(int regNum, double value) {
3975-
#if defined(__riscv_flen) && __riscv_flen == 64
4016+
inline void Registers_riscv::setFloatRegister(int regNum, fp_t value) {
4017+
# if defined(__riscv_flen)
39764018
assert(validFloatRegister(regNum));
39774019
_floats[regNum - UNW_RISCV_F0] = value;
3978-
#else
4020+
# else
39794021
(void)regNum;
39804022
(void)value;
39814023
_LIBUNWIND_ABORT("libunwind not built with float support");
3982-
#endif
4024+
# endif
39834025
}
39844026

39854027
inline bool Registers_riscv::validVectorRegister(int) const {

libunwind/src/UnwindRegistersRestore.S

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
10721072
jmp %o7
10731073
nop
10741074

1075-
#elif defined(__riscv) && __riscv_xlen == 64
1075+
#elif defined(__riscv)
10761076

10771077
//
10781078
// void libunwind::Registers_riscv::jumpto()
@@ -1082,74 +1082,74 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_sparc6jumptoEv)
10821082
//
10831083
.p2align 2
10841084
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_riscv6jumptoEv)
1085-
#if defined(__riscv_flen) && __riscv_flen == 64
1086-
fld f0, (8 * 32 + 8 * 0)(a0)
1087-
fld f1, (8 * 32 + 8 * 1)(a0)
1088-
fld f2, (8 * 32 + 8 * 2)(a0)
1089-
fld f3, (8 * 32 + 8 * 3)(a0)
1090-
fld f4, (8 * 32 + 8 * 4)(a0)
1091-
fld f5, (8 * 32 + 8 * 5)(a0)
1092-
fld f6, (8 * 32 + 8 * 6)(a0)
1093-
fld f7, (8 * 32 + 8 * 7)(a0)
1094-
fld f8, (8 * 32 + 8 * 8)(a0)
1095-
fld f9, (8 * 32 + 8 * 9)(a0)
1096-
fld f10, (8 * 32 + 8 * 10)(a0)
1097-
fld f11, (8 * 32 + 8 * 11)(a0)
1098-
fld f12, (8 * 32 + 8 * 12)(a0)
1099-
fld f13, (8 * 32 + 8 * 13)(a0)
1100-
fld f14, (8 * 32 + 8 * 14)(a0)
1101-
fld f15, (8 * 32 + 8 * 15)(a0)
1102-
fld f16, (8 * 32 + 8 * 16)(a0)
1103-
fld f17, (8 * 32 + 8 * 17)(a0)
1104-
fld f18, (8 * 32 + 8 * 18)(a0)
1105-
fld f19, (8 * 32 + 8 * 19)(a0)
1106-
fld f20, (8 * 32 + 8 * 20)(a0)
1107-
fld f21, (8 * 32 + 8 * 21)(a0)
1108-
fld f22, (8 * 32 + 8 * 22)(a0)
1109-
fld f23, (8 * 32 + 8 * 23)(a0)
1110-
fld f24, (8 * 32 + 8 * 24)(a0)
1111-
fld f25, (8 * 32 + 8 * 25)(a0)
1112-
fld f26, (8 * 32 + 8 * 26)(a0)
1113-
fld f27, (8 * 32 + 8 * 27)(a0)
1114-
fld f28, (8 * 32 + 8 * 28)(a0)
1115-
fld f29, (8 * 32 + 8 * 29)(a0)
1116-
fld f30, (8 * 32 + 8 * 30)(a0)
1117-
fld f31, (8 * 32 + 8 * 31)(a0)
1118-
#endif
1085+
# if defined(__riscv_flen)
1086+
FLOAD f0, (RISCV_FOFFSET + RISCV_FSIZE * 0)(a0)
1087+
FLOAD f1, (RISCV_FOFFSET + RISCV_FSIZE * 1)(a0)
1088+
FLOAD f2, (RISCV_FOFFSET + RISCV_FSIZE * 2)(a0)
1089+
FLOAD f3, (RISCV_FOFFSET + RISCV_FSIZE * 3)(a0)
1090+
FLOAD f4, (RISCV_FOFFSET + RISCV_FSIZE * 4)(a0)
1091+
FLOAD f5, (RISCV_FOFFSET + RISCV_FSIZE * 5)(a0)
1092+
FLOAD f6, (RISCV_FOFFSET + RISCV_FSIZE * 6)(a0)
1093+
FLOAD f7, (RISCV_FOFFSET + RISCV_FSIZE * 7)(a0)
1094+
FLOAD f8, (RISCV_FOFFSET + RISCV_FSIZE * 8)(a0)
1095+
FLOAD f9, (RISCV_FOFFSET + RISCV_FSIZE * 9)(a0)
1096+
FLOAD f10, (RISCV_FOFFSET + RISCV_FSIZE * 10)(a0)
1097+
FLOAD f11, (RISCV_FOFFSET + RISCV_FSIZE * 11)(a0)
1098+
FLOAD f12, (RISCV_FOFFSET + RISCV_FSIZE * 12)(a0)
1099+
FLOAD f13, (RISCV_FOFFSET + RISCV_FSIZE * 13)(a0)
1100+
FLOAD f14, (RISCV_FOFFSET + RISCV_FSIZE * 14)(a0)
1101+
FLOAD f15, (RISCV_FOFFSET + RISCV_FSIZE * 15)(a0)
1102+
FLOAD f16, (RISCV_FOFFSET + RISCV_FSIZE * 16)(a0)
1103+
FLOAD f17, (RISCV_FOFFSET + RISCV_FSIZE * 17)(a0)
1104+
FLOAD f18, (RISCV_FOFFSET + RISCV_FSIZE * 18)(a0)
1105+
FLOAD f19, (RISCV_FOFFSET + RISCV_FSIZE * 19)(a0)
1106+
FLOAD f20, (RISCV_FOFFSET + RISCV_FSIZE * 20)(a0)
1107+
FLOAD f21, (RISCV_FOFFSET + RISCV_FSIZE * 21)(a0)
1108+
FLOAD f22, (RISCV_FOFFSET + RISCV_FSIZE * 22)(a0)
1109+
FLOAD f23, (RISCV_FOFFSET + RISCV_FSIZE * 23)(a0)
1110+
FLOAD f24, (RISCV_FOFFSET + RISCV_FSIZE * 24)(a0)
1111+
FLOAD f25, (RISCV_FOFFSET + RISCV_FSIZE * 25)(a0)
1112+
FLOAD f26, (RISCV_FOFFSET + RISCV_FSIZE * 26)(a0)
1113+
FLOAD f27, (RISCV_FOFFSET + RISCV_FSIZE * 27)(a0)
1114+
FLOAD f28, (RISCV_FOFFSET + RISCV_FSIZE * 28)(a0)
1115+
FLOAD f29, (RISCV_FOFFSET + RISCV_FSIZE * 29)(a0)
1116+
FLOAD f30, (RISCV_FOFFSET + RISCV_FSIZE * 30)(a0)
1117+
FLOAD f31, (RISCV_FOFFSET + RISCV_FSIZE * 31)(a0)
1118+
# endif
11191119

11201120
// x0 is zero
1121-
ld x1, (8 * 0)(a0) // restore pc into ra
1122-
ld x2, (8 * 2)(a0)
1123-
ld x3, (8 * 3)(a0)
1124-
ld x4, (8 * 4)(a0)
1125-
ld x5, (8 * 5)(a0)
1126-
ld x6, (8 * 6)(a0)
1127-
ld x7, (8 * 7)(a0)
1128-
ld x8, (8 * 8)(a0)
1129-
ld x9, (8 * 9)(a0)
1121+
ILOAD x1, (RISCV_ISIZE * 0)(a0) // restore pc into ra
1122+
ILOAD x2, (RISCV_ISIZE * 2)(a0)
1123+
ILOAD x3, (RISCV_ISIZE * 3)(a0)
1124+
ILOAD x4, (RISCV_ISIZE * 4)(a0)
1125+
ILOAD x5, (RISCV_ISIZE * 5)(a0)
1126+
ILOAD x6, (RISCV_ISIZE * 6)(a0)
1127+
ILOAD x7, (RISCV_ISIZE * 7)(a0)
1128+
ILOAD x8, (RISCV_ISIZE * 8)(a0)
1129+
ILOAD x9, (RISCV_ISIZE * 9)(a0)
11301130
// skip a0 for now
1131-
ld x11, (8 * 11)(a0)
1132-
ld x12, (8 * 12)(a0)
1133-
ld x13, (8 * 13)(a0)
1134-
ld x14, (8 * 14)(a0)
1135-
ld x15, (8 * 15)(a0)
1136-
ld x16, (8 * 16)(a0)
1137-
ld x17, (8 * 17)(a0)
1138-
ld x18, (8 * 18)(a0)
1139-
ld x19, (8 * 19)(a0)
1140-
ld x20, (8 * 20)(a0)
1141-
ld x21, (8 * 21)(a0)
1142-
ld x22, (8 * 22)(a0)
1143-
ld x23, (8 * 23)(a0)
1144-
ld x24, (8 * 24)(a0)
1145-
ld x25, (8 * 25)(a0)
1146-
ld x26, (8 * 26)(a0)
1147-
ld x27, (8 * 27)(a0)
1148-
ld x28, (8 * 28)(a0)
1149-
ld x29, (8 * 29)(a0)
1150-
ld x30, (8 * 30)(a0)
1151-
ld x31, (8 * 31)(a0)
1152-
ld x10, (8 * 10)(a0) // restore a0
1131+
ILOAD x11, (RISCV_ISIZE * 11)(a0)
1132+
ILOAD x12, (RISCV_ISIZE * 12)(a0)
1133+
ILOAD x13, (RISCV_ISIZE * 13)(a0)
1134+
ILOAD x14, (RISCV_ISIZE * 14)(a0)
1135+
ILOAD x15, (RISCV_ISIZE * 15)(a0)
1136+
ILOAD x16, (RISCV_ISIZE * 16)(a0)
1137+
ILOAD x17, (RISCV_ISIZE * 17)(a0)
1138+
ILOAD x18, (RISCV_ISIZE * 18)(a0)
1139+
ILOAD x19, (RISCV_ISIZE * 19)(a0)
1140+
ILOAD x20, (RISCV_ISIZE * 20)(a0)
1141+
ILOAD x21, (RISCV_ISIZE * 21)(a0)
1142+
ILOAD x22, (RISCV_ISIZE * 22)(a0)
1143+
ILOAD x23, (RISCV_ISIZE * 23)(a0)
1144+
ILOAD x24, (RISCV_ISIZE * 24)(a0)
1145+
ILOAD x25, (RISCV_ISIZE * 25)(a0)
1146+
ILOAD x26, (RISCV_ISIZE * 26)(a0)
1147+
ILOAD x27, (RISCV_ISIZE * 27)(a0)
1148+
ILOAD x28, (RISCV_ISIZE * 28)(a0)
1149+
ILOAD x29, (RISCV_ISIZE * 29)(a0)
1150+
ILOAD x30, (RISCV_ISIZE * 30)(a0)
1151+
ILOAD x31, (RISCV_ISIZE * 31)(a0)
1152+
ILOAD x10, (RISCV_ISIZE * 10)(a0) // restore a0
11531153

11541154
ret // jump to ra
11551155

0 commit comments

Comments
 (0)