diff options
Diffstat (limited to 'libunwind/src/UnwindRegistersRestore.S')
| -rw-r--r-- | libunwind/src/UnwindRegistersRestore.S | 18 |
1 files changed, 18 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 |
