From 9d4bdaa8a78859a007da379362112634897b93e4 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Thu, 11 Jan 2024 06:50:21 -0800 Subject: ppc64/clang: save/restore vector register vr31. This fixes crashes in the test cases when TXR is built with clang on little-endian PPC64. Clang uses vector instructions, but our jmp.S does not save any vector registers. In some places this causes a problem. I've noticed much of the code just uses vrs0, vrs1 and vrs63 for doing small things, like initializing small structures with a single instruction. The functions that use more of these registers don't call anything that saves and restores a context. In this patch we just save/restore vrs63, which maps to vr31. The vrs0 and vrs1 don't have to be saved and restored; the setjmp function doesn't do it. Everything is conditional on __ALTIVEC__. * unwind.h (jmp): We add vr31 to the PPC64 version of struct jmp. The instructions which load and store this requires 32 byte alignment, so we assert that. Note that the alignment leaves 8 bytes of padding at the end of the structure since there are 23 other registers to save. * jmp.S (jmp_save, jmp_restore): We save and restore v31 first and then move the pointer past it by 32 bytes to do the rest of the registers exactly as before. In jmp_save, we save an extra copy of the r11 register into the padding so that it is initialized. We don't like to encourage padding in the stack because in light of our GC's conservative scan of the stack, it promotes spurious retention of objects. --- unwind.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'unwind.h') diff --git a/unwind.h b/unwind.h index eda4b9f5..0bd569f5 100644 --- a/unwind.h +++ b/unwind.h @@ -86,7 +86,16 @@ struct jmp { #elif __PPC64__ -struct jmp { +#if __ALTIVEC__ +#define UW_JMP_ALIGN __attribute__ ((aligned (32))) +#else +#define UW_JMP_ALIGN +#endif + +struct UW_JMP_ALIGN jmp { +#if __ALTIVEC__ + unsigned long vr31[4]; +#endif unsigned long r1; unsigned long r2; unsigned long r11; -- cgit v1.2.3