[libunwind][LoongArch] Add 64-bit LoongArch support

Defines enums for the LoongArch registers.
Adds the register class implementation for LoongArch.
Adds save and restore context functionality.

This only supports 64 bits integer and float-point register
implementation.

Fix https://github.com/llvm/llvm-project/issues/55398

Reviewed By: SixWeining

Differential Revision: https://reviews.llvm.org/D137010
This commit is contained in:
zhanglimin 2022-11-15 14:36:30 +08:00 committed by Weining Lu
parent 25dcca60f4
commit c507269512
8 changed files with 527 additions and 1 deletions

View File

@ -30,6 +30,7 @@
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_RISCV 64
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_VE 143
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X 83
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH 64
#if defined(_LIBUNWIND_IS_NATIVE_ONLY)
# if defined(__linux__)
@ -166,6 +167,16 @@
# define _LIBUNWIND_CONTEXT_SIZE 34
# define _LIBUNWIND_CURSOR_SIZE 46
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_S390X
#elif defined(__loongarch__)
#define _LIBUNWIND_TARGET_LOONGARCH 1
#if __loongarch_grlen == 64
#define _LIBUNWIND_CONTEXT_SIZE 65
#define _LIBUNWIND_CURSOR_SIZE 77
#else
#error "Unsupported LoongArch ABI"
#endif
#define _LIBUNWIND_HIGHEST_DWARF_REGISTER \
_LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH
# else
# error "Unsupported architecture."
# endif
@ -185,6 +196,7 @@
# define _LIBUNWIND_TARGET_RISCV 1
# define _LIBUNWIND_TARGET_VE 1
# define _LIBUNWIND_TARGET_S390X 1
#define _LIBUNWIND_TARGET_LOONGARCH 1
# define _LIBUNWIND_CONTEXT_SIZE 167
# define _LIBUNWIND_CURSOR_SIZE 179
# define _LIBUNWIND_HIGHEST_DWARF_REGISTER 287

View File

@ -1219,4 +1219,72 @@ enum {
// 68-83 Vector Registers %v16-%v31
};
// LoongArch registers.
enum {
UNW_LOONGARCH_R0 = 0,
UNW_LOONGARCH_R1 = 1,
UNW_LOONGARCH_R2 = 2,
UNW_LOONGARCH_R3 = 3,
UNW_LOONGARCH_R4 = 4,
UNW_LOONGARCH_R5 = 5,
UNW_LOONGARCH_R6 = 6,
UNW_LOONGARCH_R7 = 7,
UNW_LOONGARCH_R8 = 8,
UNW_LOONGARCH_R9 = 9,
UNW_LOONGARCH_R10 = 10,
UNW_LOONGARCH_R11 = 11,
UNW_LOONGARCH_R12 = 12,
UNW_LOONGARCH_R13 = 13,
UNW_LOONGARCH_R14 = 14,
UNW_LOONGARCH_R15 = 15,
UNW_LOONGARCH_R16 = 16,
UNW_LOONGARCH_R17 = 17,
UNW_LOONGARCH_R18 = 18,
UNW_LOONGARCH_R19 = 19,
UNW_LOONGARCH_R20 = 20,
UNW_LOONGARCH_R21 = 21,
UNW_LOONGARCH_R22 = 22,
UNW_LOONGARCH_R23 = 23,
UNW_LOONGARCH_R24 = 24,
UNW_LOONGARCH_R25 = 25,
UNW_LOONGARCH_R26 = 26,
UNW_LOONGARCH_R27 = 27,
UNW_LOONGARCH_R28 = 28,
UNW_LOONGARCH_R29 = 29,
UNW_LOONGARCH_R30 = 30,
UNW_LOONGARCH_R31 = 31,
UNW_LOONGARCH_F0 = 32,
UNW_LOONGARCH_F1 = 33,
UNW_LOONGARCH_F2 = 34,
UNW_LOONGARCH_F3 = 35,
UNW_LOONGARCH_F4 = 36,
UNW_LOONGARCH_F5 = 37,
UNW_LOONGARCH_F6 = 38,
UNW_LOONGARCH_F7 = 39,
UNW_LOONGARCH_F8 = 40,
UNW_LOONGARCH_F9 = 41,
UNW_LOONGARCH_F10 = 42,
UNW_LOONGARCH_F11 = 43,
UNW_LOONGARCH_F12 = 44,
UNW_LOONGARCH_F13 = 45,
UNW_LOONGARCH_F14 = 46,
UNW_LOONGARCH_F15 = 47,
UNW_LOONGARCH_F16 = 48,
UNW_LOONGARCH_F17 = 49,
UNW_LOONGARCH_F18 = 50,
UNW_LOONGARCH_F19 = 51,
UNW_LOONGARCH_F20 = 52,
UNW_LOONGARCH_F21 = 53,
UNW_LOONGARCH_F22 = 54,
UNW_LOONGARCH_F23 = 55,
UNW_LOONGARCH_F24 = 56,
UNW_LOONGARCH_F25 = 57,
UNW_LOONGARCH_F26 = 58,
UNW_LOONGARCH_F27 = 59,
UNW_LOONGARCH_F28 = 60,
UNW_LOONGARCH_F29 = 61,
UNW_LOONGARCH_F30 = 62,
UNW_LOONGARCH_F31 = 63,
};
#endif

View File

@ -40,6 +40,7 @@ enum {
REGISTERS_RISCV,
REGISTERS_VE,
REGISTERS_S390X,
REGISTERS_LOONGARCH,
};
#if defined(_LIBUNWIND_TARGET_I386)
@ -5031,6 +5032,271 @@ inline const char *Registers_s390x::getRegisterName(int regNum) {
}
#endif // _LIBUNWIND_TARGET_S390X
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
/// Registers_loongarch holds the register state of a thread in a 64-bit
/// LoongArch process.
class _LIBUNWIND_HIDDEN Registers_loongarch {
public:
Registers_loongarch();
Registers_loongarch(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 constexpr int lastDwarfRegNum() {
return _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH;
}
static int getArch() { return REGISTERS_LOONGARCH; }
uint64_t getSP() const { return _registers.__r[3]; }
void setSP(uint64_t value) { _registers.__r[3] = value; }
uint64_t getIP() const { return _registers.__pc; }
void setIP(uint64_t value) { _registers.__pc = value; }
private:
struct loongarch_thread_state_t {
uint64_t __r[32];
uint64_t __pc;
};
loongarch_thread_state_t _registers;
#if __loongarch_frlen == 64
double _floats[32];
#endif
};
inline Registers_loongarch::Registers_loongarch(const void *registers) {
static_assert((check_fit<Registers_loongarch, unw_context_t>::does_fit),
"loongarch registers do not fit into unw_context_t");
memcpy(&_registers, registers, sizeof(_registers));
static_assert(sizeof(_registers) == 0x108,
"expected float registers to be at offset 264");
#if __loongarch_frlen == 64
memcpy(_floats, static_cast<const uint8_t *>(registers) + sizeof(_registers),
sizeof(_floats));
#endif
}
inline Registers_loongarch::Registers_loongarch() {
memset(&_registers, 0, sizeof(_registers));
#if __loongarch_frlen == 64
memset(&_floats, 0, sizeof(_floats));
#endif
}
inline bool Registers_loongarch::validRegister(int regNum) const {
if (regNum == UNW_REG_IP || regNum == UNW_REG_SP)
return true;
if (regNum < 0 || regNum > UNW_LOONGARCH_F31)
return false;
return true;
}
inline uint64_t Registers_loongarch::getRegister(int regNum) const {
if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
return _registers.__r[regNum - UNW_LOONGARCH_R0];
if (regNum == UNW_REG_IP)
return _registers.__pc;
if (regNum == UNW_REG_SP)
return _registers.__r[3];
_LIBUNWIND_ABORT("unsupported loongarch register");
}
inline void Registers_loongarch::setRegister(int regNum, uint64_t value) {
if (regNum >= UNW_LOONGARCH_R0 && regNum <= UNW_LOONGARCH_R31)
_registers.__r[regNum - UNW_LOONGARCH_R0] = value;
else if (regNum == UNW_REG_IP)
_registers.__pc = value;
else if (regNum == UNW_REG_SP)
_registers.__r[3] = value;
else
_LIBUNWIND_ABORT("unsupported loongarch register");
}
inline const char *Registers_loongarch::getRegisterName(int regNum) {
switch (regNum) {
case UNW_REG_IP:
return "$pc";
case UNW_REG_SP:
return "$sp";
case UNW_LOONGARCH_R0:
return "$r0";
case UNW_LOONGARCH_R1:
return "$r1";
case UNW_LOONGARCH_R2:
return "$r2";
case UNW_LOONGARCH_R3:
return "$r3";
case UNW_LOONGARCH_R4:
return "$r4";
case UNW_LOONGARCH_R5:
return "$r5";
case UNW_LOONGARCH_R6:
return "$r6";
case UNW_LOONGARCH_R7:
return "$r7";
case UNW_LOONGARCH_R8:
return "$r8";
case UNW_LOONGARCH_R9:
return "$r9";
case UNW_LOONGARCH_R10:
return "$r10";
case UNW_LOONGARCH_R11:
return "$r11";
case UNW_LOONGARCH_R12:
return "$r12";
case UNW_LOONGARCH_R13:
return "$r13";
case UNW_LOONGARCH_R14:
return "$r14";
case UNW_LOONGARCH_R15:
return "$r15";
case UNW_LOONGARCH_R16:
return "$r16";
case UNW_LOONGARCH_R17:
return "$r17";
case UNW_LOONGARCH_R18:
return "$r18";
case UNW_LOONGARCH_R19:
return "$r19";
case UNW_LOONGARCH_R20:
return "$r20";
case UNW_LOONGARCH_R21:
return "$r21";
case UNW_LOONGARCH_R22:
return "$r22";
case UNW_LOONGARCH_R23:
return "$r23";
case UNW_LOONGARCH_R24:
return "$r24";
case UNW_LOONGARCH_R25:
return "$r25";
case UNW_LOONGARCH_R26:
return "$r26";
case UNW_LOONGARCH_R27:
return "$r27";
case UNW_LOONGARCH_R28:
return "$r28";
case UNW_LOONGARCH_R29:
return "$r29";
case UNW_LOONGARCH_R30:
return "$r30";
case UNW_LOONGARCH_R31:
return "$r31";
case UNW_LOONGARCH_F0:
return "$f0";
case UNW_LOONGARCH_F1:
return "$f1";
case UNW_LOONGARCH_F2:
return "$f2";
case UNW_LOONGARCH_F3:
return "$f3";
case UNW_LOONGARCH_F4:
return "$f4";
case UNW_LOONGARCH_F5:
return "$f5";
case UNW_LOONGARCH_F6:
return "$f6";
case UNW_LOONGARCH_F7:
return "$f7";
case UNW_LOONGARCH_F8:
return "$f8";
case UNW_LOONGARCH_F9:
return "$f9";
case UNW_LOONGARCH_F10:
return "$f10";
case UNW_LOONGARCH_F11:
return "$f11";
case UNW_LOONGARCH_F12:
return "$f12";
case UNW_LOONGARCH_F13:
return "$f13";
case UNW_LOONGARCH_F14:
return "$f14";
case UNW_LOONGARCH_F15:
return "$f15";
case UNW_LOONGARCH_F16:
return "$f16";
case UNW_LOONGARCH_F17:
return "$f17";
case UNW_LOONGARCH_F18:
return "$f18";
case UNW_LOONGARCH_F19:
return "$f19";
case UNW_LOONGARCH_F20:
return "$f20";
case UNW_LOONGARCH_F21:
return "$f21";
case UNW_LOONGARCH_F22:
return "$f22";
case UNW_LOONGARCH_F23:
return "$f23";
case UNW_LOONGARCH_F24:
return "$f24";
case UNW_LOONGARCH_F25:
return "$f25";
case UNW_LOONGARCH_F26:
return "$f26";
case UNW_LOONGARCH_F27:
return "$f27";
case UNW_LOONGARCH_F28:
return "$f28";
case UNW_LOONGARCH_F29:
return "$f29";
case UNW_LOONGARCH_F30:
return "$f30";
case UNW_LOONGARCH_F31:
return "$f31";
default:
return "unknown register";
}
}
inline bool Registers_loongarch::validFloatRegister(int regNum) const {
if (regNum < UNW_LOONGARCH_F0 || regNum > UNW_LOONGARCH_F31)
return false;
return true;
}
inline double Registers_loongarch::getFloatRegister(int regNum) const {
#if __loongarch_frlen == 64
assert(validFloatRegister(regNum));
return _floats[regNum - UNW_LOONGARCH_F0];
#else
_LIBUNWIND_ABORT("libunwind not built with float support");
#endif
}
inline void Registers_loongarch::setFloatRegister(int regNum, double value) {
#if __loongarch_frlen == 64
assert(validFloatRegister(regNum));
_floats[regNum - UNW_LOONGARCH_F0] = value;
#else
_LIBUNWIND_ABORT("libunwind not built with float support");
#endif
}
inline bool Registers_loongarch::validVectorRegister(int) const {
return false;
}
inline v128 Registers_loongarch::getVectorRegister(int) const {
_LIBUNWIND_ABORT("loongarch vector support not implemented");
}
inline void Registers_loongarch::setVectorRegister(int, v128) {
_LIBUNWIND_ABORT("loongarch vector support not implemented");
}
#endif //_LIBUNWIND_TARGET_LOONGARCH
} // namespace libunwind

View File

@ -1064,6 +1064,10 @@ private:
}
#endif
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
int stepWithCompactEncoding(Registers_loongarch &) { return UNW_EINVAL; }
#endif
#if defined(_LIBUNWIND_TARGET_SPARC)
int stepWithCompactEncoding(Registers_sparc &) { return UNW_EINVAL; }
#endif
@ -1140,6 +1144,12 @@ private:
}
#endif
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
bool compactSaysUseDwarf(Registers_loongarch &, uint32_t *) const {
return true;
}
#endif
#if defined(_LIBUNWIND_TARGET_SPARC)
bool compactSaysUseDwarf(Registers_sparc &, uint32_t *) const { return true; }
#endif
@ -1224,6 +1234,12 @@ private:
}
#endif
#if defined(_LIBUNWIND_TARGET_LOONGARCH)
compact_unwind_encoding_t dwarfEncoding(Registers_loongarch &) const {
return 0;
}
#endif
#if defined(_LIBUNWIND_TARGET_SPARC)
compact_unwind_encoding_t dwarfEncoding(Registers_sparc &) const { return 0; }
#endif

View File

@ -1289,6 +1289,88 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_s390x6jumptoEv)
// Return to PSWA (was loaded into %r1 above)
br %r1
#elif defined(__loongarch__) && __loongarch_grlen == 64
//
// void libunwind::Registers_loongarch::jumpto()
//
// On entry:
// thread_state pointer is in $a0($r4)
//
.p2align 2
DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind19Registers_loongarch6jumptoEv)
# if __loongarch_frlen == 64
fld.d $f0, $a0, (8 * 33 + 8 * 0)
fld.d $f1, $a0, (8 * 33 + 8 * 1)
fld.d $f2, $a0, (8 * 33 + 8 * 2)
fld.d $f3, $a0, (8 * 33 + 8 * 3)
fld.d $f4, $a0, (8 * 33 + 8 * 4)
fld.d $f5, $a0, (8 * 33 + 8 * 5)
fld.d $f6, $a0, (8 * 33 + 8 * 6)
fld.d $f7, $a0, (8 * 33 + 8 * 7)
fld.d $f8, $a0, (8 * 33 + 8 * 8)
fld.d $f9, $a0, (8 * 33 + 8 * 9)
fld.d $f10, $a0, (8 * 33 + 8 * 10)
fld.d $f11, $a0, (8 * 33 + 8 * 11)
fld.d $f12, $a0, (8 * 33 + 8 * 12)
fld.d $f13, $a0, (8 * 33 + 8 * 13)
fld.d $f14, $a0, (8 * 33 + 8 * 14)
fld.d $f15, $a0, (8 * 33 + 8 * 15)
fld.d $f16, $a0, (8 * 33 + 8 * 16)
fld.d $f17, $a0, (8 * 33 + 8 * 17)
fld.d $f18, $a0, (8 * 33 + 8 * 18)
fld.d $f19, $a0, (8 * 33 + 8 * 19)
fld.d $f20, $a0, (8 * 33 + 8 * 20)
fld.d $f21, $a0, (8 * 33 + 8 * 21)
fld.d $f22, $a0, (8 * 33 + 8 * 22)
fld.d $f23, $a0, (8 * 33 + 8 * 23)
fld.d $f24, $a0, (8 * 33 + 8 * 24)
fld.d $f25, $a0, (8 * 33 + 8 * 25)
fld.d $f26, $a0, (8 * 33 + 8 * 26)
fld.d $f27, $a0, (8 * 33 + 8 * 27)
fld.d $f28, $a0, (8 * 33 + 8 * 28)
fld.d $f29, $a0, (8 * 33 + 8 * 29)
fld.d $f30, $a0, (8 * 33 + 8 * 30)
fld.d $f31, $a0, (8 * 33 + 8 * 31)
# endif
// $r0 is zero
ld.d $r1, $a0, (8 * 1)
ld.d $r2, $a0, (8 * 2)
ld.d $r3, $a0, (8 * 3)
// skip $a0 for now
ld.d $r5, $a0, (8 * 5)
ld.d $r6, $a0, (8 * 6)
ld.d $r7, $a0, (8 * 7)
ld.d $r8, $a0, (8 * 8)
ld.d $r9, $a0, (8 * 9)
ld.d $r10, $a0, (8 * 10)
ld.d $r11, $a0, (8 * 11)
ld.d $r12, $a0, (8 * 12)
ld.d $r13, $a0, (8 * 13)
ld.d $r14, $a0, (8 * 14)
ld.d $r15, $a0, (8 * 15)
ld.d $r16, $a0, (8 * 16)
ld.d $r17, $a0, (8 * 17)
ld.d $r18, $a0, (8 * 18)
ld.d $r19, $a0, (8 * 19)
ld.d $r20, $a0, (8 * 20)
ld.d $r21, $a0, (8 * 21)
ld.d $r22, $a0, (8 * 22)
ld.d $r23, $a0, (8 * 23)
ld.d $r24, $a0, (8 * 24)
ld.d $r25, $a0, (8 * 25)
ld.d $r26, $a0, (8 * 26)
ld.d $r27, $a0, (8 * 27)
ld.d $r28, $a0, (8 * 28)
ld.d $r29, $a0, (8 * 29)
ld.d $r30, $a0, (8 * 30)
ld.d $r31, $a0, (8 * 31)
ld.d $r4, $a0, (8 * 4) // restore $a0 last
ld.d $r1, $a0, (8 * 32) // load new pc into $ra
jr $ra
#endif
#endif /* !defined(__USING_SJLJ_EXCEPTIONS__) */

View File

@ -1222,6 +1222,86 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
lghi %r2, 0
br %r14
#elif defined(__loongarch__) && __loongarch_grlen == 64
#
# extern int __unw_getcontext(unw_context_t* thread_state)
#
# On entry:
# thread_state pointer is in $a0($r4)
#
DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext)
st.d $r1, $a0, (8 * 1)
st.d $r2, $a0, (8 * 2)
st.d $r3, $a0, (8 * 3)
st.d $r4, $a0, (8 * 4)
st.d $r5, $a0, (8 * 5)
st.d $r6, $a0, (8 * 6)
st.d $r7, $a0, (8 * 7)
st.d $r8, $a0, (8 * 8)
st.d $r9, $a0, (8 * 9)
st.d $r10, $a0, (8 * 10)
st.d $r11, $a0, (8 * 11)
st.d $r12, $a0, (8 * 12)
st.d $r13, $a0, (8 * 13)
st.d $r14, $a0, (8 * 14)
st.d $r15, $a0, (8 * 15)
st.d $r16, $a0, (8 * 16)
st.d $r17, $a0, (8 * 17)
st.d $r18, $a0, (8 * 18)
st.d $r19, $a0, (8 * 19)
st.d $r20, $a0, (8 * 20)
st.d $r21, $a0, (8 * 21)
st.d $r22, $a0, (8 * 22)
st.d $r23, $a0, (8 * 23)
st.d $r24, $a0, (8 * 24)
st.d $r25, $a0, (8 * 25)
st.d $r26, $a0, (8 * 26)
st.d $r27, $a0, (8 * 27)
st.d $r28, $a0, (8 * 28)
st.d $r29, $a0, (8 * 29)
st.d $r30, $a0, (8 * 30)
st.d $r31, $a0, (8 * 31)
st.d $r1, $a0, (8 * 32) // store $ra to pc
# if __loongarch_frlen == 64
fst.d $f0, $a0, (8 * 33 + 8 * 0)
fst.d $f1, $a0, (8 * 33 + 8 * 1)
fst.d $f2, $a0, (8 * 33 + 8 * 2)
fst.d $f3, $a0, (8 * 33 + 8 * 3)
fst.d $f4, $a0, (8 * 33 + 8 * 4)
fst.d $f5, $a0, (8 * 33 + 8 * 5)
fst.d $f6, $a0, (8 * 33 + 8 * 6)
fst.d $f7, $a0, (8 * 33 + 8 * 7)
fst.d $f8, $a0, (8 * 33 + 8 * 8)
fst.d $f9, $a0, (8 * 33 + 8 * 9)
fst.d $f10, $a0, (8 * 33 + 8 * 10)
fst.d $f11, $a0, (8 * 33 + 8 * 11)
fst.d $f12, $a0, (8 * 33 + 8 * 12)
fst.d $f13, $a0, (8 * 33 + 8 * 13)
fst.d $f14, $a0, (8 * 33 + 8 * 14)
fst.d $f15, $a0, (8 * 33 + 8 * 15)
fst.d $f16, $a0, (8 * 33 + 8 * 16)
fst.d $f17, $a0, (8 * 33 + 8 * 17)
fst.d $f18, $a0, (8 * 33 + 8 * 18)
fst.d $f19, $a0, (8 * 33 + 8 * 19)
fst.d $f20, $a0, (8 * 33 + 8 * 20)
fst.d $f21, $a0, (8 * 33 + 8 * 21)
fst.d $f22, $a0, (8 * 33 + 8 * 22)
fst.d $f23, $a0, (8 * 33 + 8 * 23)
fst.d $f24, $a0, (8 * 33 + 8 * 24)
fst.d $f25, $a0, (8 * 33 + 8 * 25)
fst.d $f26, $a0, (8 * 33 + 8 * 26)
fst.d $f27, $a0, (8 * 33 + 8 * 27)
fst.d $f28, $a0, (8 * 33 + 8 * 28)
fst.d $f29, $a0, (8 * 33 + 8 * 29)
fst.d $f30, $a0, (8 * 33 + 8 * 30)
fst.d $f31, $a0, (8 * 33 + 8 * 31)
# endif
move $a0, $zero // UNW_ESUCCESS
jr $ra
#endif
WEAK_ALIAS(__unw_getcontext, unw_getcontext)

View File

@ -115,7 +115,7 @@
#if defined(__i386__) || defined(__x86_64__) || defined(__powerpc__) || \
(!defined(__APPLE__) && defined(__arm__)) || defined(__aarch64__) || \
defined(__mips__) || defined(__riscv) || defined(__hexagon__) || \
defined(__sparc__) || defined(__s390x__)
defined(__sparc__) || defined(__s390x__) || defined(__loongarch__)
#if !defined(_LIBUNWIND_BUILD_SJLJ_APIS)
#define _LIBUNWIND_BUILD_ZERO_COST_APIS
#endif

View File

@ -77,6 +77,8 @@ _LIBUNWIND_HIDDEN int __unw_init_local(unw_cursor_t *cursor,
# define REGISTER_KIND Registers_ve
#elif defined(__s390x__)
# define REGISTER_KIND Registers_s390x
#elif defined(__loongarch__) && __loongarch_grlen == 64
#define REGISTER_KIND Registers_loongarch
#else
# error Architecture not supported
#endif