diff options
Diffstat (limited to 'libunwind')
-rw-r--r-- | libunwind/src/UnwindRegistersRestore.S | 18 | ||||
-rw-r--r-- | libunwind/src/UnwindRegistersSave.S | 11 |
2 files changed, 29 insertions, 0 deletions
diff --git a/libunwind/src/UnwindRegistersRestore.S b/libunwind/src/UnwindRegistersRestore.S index 2a472be943f3..543b19f7e72a 100644 --- a/libunwind/src/UnwindRegistersRestore.S +++ b/libunwind/src/UnwindRegistersRestore.S @@ -194,9 +194,20 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) addi 4, 3, PPC64_OFFS_FP // load VS register +#ifdef __LITTLE_ENDIAN__ +// For little-endian targets, we need a swap since lxvd2x will load the register +// in the incorrect doubleword order. +// FIXME: when supporting targets older than Power9 on LE is no longer required, +// this can be changed to simply `lxv n, (16 * n)(4)`. #define PPC64_LVS(n) \ lxvd2x n, 0, 4 ;\ + xxswapd n, n ;\ addi 4, 4, 16 +#else +#define PPC64_LVS(n) \ + lxvd2x n, 0, 4 ;\ + addi 4, 4, 16 +#endif // restore the first 32 VS regs (and also all floating point regs) PPC64_LVS(0) @@ -232,9 +243,16 @@ DEFINE_LIBUNWIND_FUNCTION(_ZN9libunwind15Registers_ppc646jumptoEv) PPC64_LVS(30) PPC64_LVS(31) +#ifdef __LITTLE_ENDIAN__ +#define PPC64_CLVS_RESTORE(n) \ + addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ + lxvd2x n, 0, 4 ;\ + xxswapd n, n +#else #define PPC64_CLVS_RESTORE(n) \ addi 4, 3, PPC64_OFFS_FP + n * 16 ;\ lxvd2x n, 0, 4 +#endif #if !defined(_AIX) // use VRSAVE to conditionally restore the remaining VS regs, that are diff --git a/libunwind/src/UnwindRegistersSave.S b/libunwind/src/UnwindRegistersSave.S index 6c26b79877f6..79f5696a9888 100644 --- a/libunwind/src/UnwindRegistersSave.S +++ b/libunwind/src/UnwindRegistersSave.S @@ -351,9 +351,20 @@ DEFINE_LIBUNWIND_FUNCTION(__unw_getcontext) addi 4, 3, PPC64_OFFS_FP // store VS register +#ifdef __LITTLE_ENDIAN__ +// For little-endian targets, we need a swap since stxvd2x will store the +// register in the incorrect doubleword order. +// FIXME: when supporting targets older than Power9 on LE is no longer required +// this can be changed to simply `stxv n, 16 * n(4)`. #define PPC64_STVS(n) \ + xxswapd n, n ;\ stxvd2x n, 0, 4 ;\ addi 4, 4, 16 +#else +#define PPC64_STVS(n) \ + stxvd2x n, 0, 4 ;\ + addi 4, 4, 16 +#endif PPC64_STVS(0) PPC64_STVS(1) |