Add an alternative implementation of VG_MINIMAL_{SET,LONG}JMP
for ppc32-linux, that works for gcc >= 4.4.  Related to #259977.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11688 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_libcsetjmp.c b/coregrind/m_libcsetjmp.c
index 8d1c2c2..ae0b620 100644
--- a/coregrind/m_libcsetjmp.c
+++ b/coregrind/m_libcsetjmp.c
@@ -36,7 +36,112 @@
 
 /* See include/pub_tool_libcsetjmp.h for background and rationale. */
 
-/* No alternative implementations at present. */
+/* The only alternative implementations are for ppc{32,64}-linux.  See
+   #259977. */
+
+#if defined(VGP_ppc32_linux)
+
+__asm__(
+".text"  "\n"
+""  "\n"
+".global VG_MINIMAL_SETJMP"  "\n"  // r3 = jmp_buf
+"VG_MINIMAL_SETJMP:"  "\n"
+"        stw     0, 0(3)"  "\n"
+"        stw     1, 4(3)"  "\n"
+"        stw     2, 8(3)"  "\n"
+"        stw     3, 12(3)"  "\n"
+"        stw     4, 16(3)"  "\n"
+"        stw     5, 20(3)"  "\n"
+"        stw     6, 24(3)"  "\n"
+"        stw     7, 28(3)"  "\n"
+"        stw     8, 32(3)"  "\n"
+"        stw     9, 36(3)"  "\n"
+"        stw     10, 40(3)"  "\n"
+"        stw     11, 44(3)"  "\n"
+"        stw     12, 48(3)"  "\n"
+"        stw     13, 52(3)"  "\n"
+"        stw     14, 56(3)"  "\n"
+"        stw     15, 60(3)"  "\n"
+"        stw     16, 64(3)"  "\n"
+"        stw     17, 68(3)"  "\n"
+"        stw     18, 72(3)"  "\n"
+"        stw     19, 76(3)"  "\n"
+"        stw     20, 80(3)"  "\n"
+"        stw     21, 84(3)"  "\n"
+"        stw     22, 88(3)"  "\n"
+"        stw     23, 92(3)"  "\n"
+"        stw     24, 96(3)"  "\n"
+"        stw     25, 100(3)"  "\n"
+"        stw     26, 104(3)"  "\n"
+"        stw     27, 108(3)"  "\n"
+"        stw     28, 112(3)"  "\n"
+"        stw     29, 116(3)"  "\n"
+"        stw     30, 120(3)"  "\n"
+"        stw     31, 124(3)"  "\n"
+         // must use a caller-save register here as scratch, hence r4
+"        mflr    4"  "\n"
+"        stw     4, 128(3)"  "\n"
+"        mfcr    4"  "\n"
+"        stw     4, 132(3)"  "\n"
+"        li      3, 0"  "\n"
+"        blr"  "\n"
+""  "\n"
+
+
+".global VG_MINIMAL_LONGJMP"  "\n"
+"VG_MINIMAL_LONGJMP:"  "\n"    // r3 = jmp_buf
+         // do r4 = 1
+         // and park it in the restore slot for r3 (the ret reg)
+"        li      4, 1"  "\n"
+"        stw     4, 12(3)"  "\n"
+         // restore everything except r3
+         // then r3 last of all
+         // then blr
+"        lwz     0, 128(3)"  "\n"
+"        mtlr    0"  "\n"
+"        lwz     0, 132(3)"  "\n"
+"        mtcr    0"  "\n"
+"        lwz     0, 0(3)"  "\n"
+"        lwz     1, 4(3)"  "\n"
+"        lwz     2, 8(3)"  "\n"
+         // r3 is done at the end
+"        lwz     4, 16(3)"  "\n"
+"        lwz     5, 20(3)"  "\n"
+"        lwz     6, 24(3)"  "\n"
+"        lwz     7, 28(3)"  "\n"
+"        lwz     8, 32(3)"  "\n"
+"        lwz     9, 36(3)"  "\n"
+"        lwz     10, 40(3)"  "\n"
+"        lwz     11, 44(3)"  "\n"
+"        lwz     12, 48(3)"  "\n"
+"        lwz     13, 52(3)"  "\n"
+"        lwz     14, 56(3)"  "\n"
+"        lwz     15, 60(3)"  "\n"
+"        lwz     16, 64(3)"  "\n"
+"        lwz     17, 68(3)"  "\n"
+"        lwz     18, 72(3)"  "\n"
+"        lwz     19, 76(3)"  "\n"
+"        lwz     20, 80(3)"  "\n"
+"        lwz     21, 84(3)"  "\n"
+"        lwz     22, 88(3)"  "\n"
+"        lwz     23, 92(3)"  "\n"
+"        lwz     24, 96(3)"  "\n"
+"        lwz     25, 100(3)"  "\n"
+"        lwz     26, 104(3)"  "\n"
+"        lwz     27, 108(3)"  "\n"
+"        lwz     28, 112(3)"  "\n"
+"        lwz     29, 116(3)"  "\n"
+"        lwz     30, 120(3)"  "\n"
+"        lwz     31, 124(3)"  "\n"
+"        lwz     3, 12(3)"  "\n"
+"        blr"  "\n"
+""  "\n"
+
+
+".previous"  "\n"
+);
+
+#endif /* VGP_ppc32_linux */
 
 
 /*--------------------------------------------------------------------*/