Add an alternative implementation of VG_MINIMAL_{SET,LONG}JMP
for ppc32-linux, that works for gcc >= 4.4.  Related to #259977.
(modified version of patch from Maynard Johnson <maynardj@us.ibm.com>)


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@11689 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/m_libcsetjmp.c b/coregrind/m_libcsetjmp.c
index ae0b620..3ca3303 100644
--- a/coregrind/m_libcsetjmp.c
+++ b/coregrind/m_libcsetjmp.c
@@ -39,11 +39,13 @@
 /* The only alternative implementations are for ppc{32,64}-linux.  See
    #259977. */
 
+/* ------------ ppc32-linux ------------ */
+
 #if defined(VGP_ppc32_linux)
 
 __asm__(
 ".text"  "\n"
-""  "\n"
+""       "\n"
 ".global VG_MINIMAL_SETJMP"  "\n"  // r3 = jmp_buf
 "VG_MINIMAL_SETJMP:"  "\n"
 "        stw     0, 0(3)"  "\n"
@@ -85,7 +87,7 @@
 "        stw     4, 132(3)"  "\n"
 "        li      3, 0"  "\n"
 "        blr"  "\n"
-""  "\n"
+""       "\n"
 
 
 ".global VG_MINIMAL_LONGJMP"  "\n"
@@ -135,8 +137,7 @@
 "        lwz     31, 124(3)"  "\n"
 "        lwz     3, 12(3)"  "\n"
 "        blr"  "\n"
-""  "\n"
-
+""       "\n"
 
 ".previous"  "\n"
 );
@@ -144,6 +145,132 @@
 #endif /* VGP_ppc32_linux */
 
 
+/* ------------ ppc64-linux ------------ */
+
+#if defined(VGP_ppc64_linux)
+
+__asm__(
+".section \".toc\",\"aw\""          "\n"
+
+".section \".text\""                "\n"
+".align 2"                          "\n"
+".p2align 4,,15"                    "\n"
+".globl VG_MINIMAL_SETJMP"          "\n"
+
+".section \".opd\",\"aw\""          "\n"
+".align 3"                          "\n"
+"VG_MINIMAL_SETJMP:"                "\n"
+".quad .L.VG_MINIMAL_SETJMP,.TOC.@tocbase,0"   "\n"
+".previous"                         "\n"
+
+".type VG_MINIMAL_SETJMP, @function"   "\n"
+".L.VG_MINIMAL_SETJMP:"   "\n"
+"        std     0, 0(3)"  "\n"
+"        std     1, 8(3)"  "\n"
+"        std     2, 16(3)"  "\n"
+"        std     3, 24(3)"  "\n"
+"        std     4, 32(3)"  "\n"
+"        std     5, 40(3)"  "\n"
+"        std     6, 48(3)"  "\n"
+"        std     7, 56(3)"  "\n"
+"        std     8, 64(3)"  "\n"
+"        std     9, 72(3)"  "\n"
+"        std     10, 80(3)"  "\n"
+"        std     11, 88(3)"  "\n"
+"        std     12, 96(3)"  "\n"
+"        std     13, 104(3)"  "\n"
+"        std     14, 112(3)"  "\n"
+"        std     15, 120(3)"  "\n"
+"        std     16, 128(3)"  "\n"
+"        std     17, 136(3)"  "\n"
+"        std     18, 144(3)"  "\n"
+"        std     19, 152(3)"  "\n"
+"        std     20, 160(3)"  "\n"
+"        std     21, 168(3)"  "\n"
+"        std     22, 176(3)"  "\n"
+"        std     23, 184(3)"  "\n"
+"        std     24, 192(3)"  "\n"
+"        std     25, 200(3)"  "\n"
+"        std     26, 208(3)"  "\n"
+"        std     27, 216(3)"  "\n"
+"        std     28, 224(3)"  "\n"
+"        std     29, 232(3)"  "\n"
+"        std     30, 240(3)"  "\n"
+"        std     31, 248(3)"  "\n"
+         // must use a caller-save register here as scratch, hence r4
+"        mflr    4"  "\n"
+"        std     4, 256(3)"  "\n"
+"        mfcr    4"  "\n"
+"        std     4, 264(3)"  "\n"
+"        li      3, 0"  "\n"
+"        blr"  "\n"
+""       "\n"
+
+
+".globl VG_MINIMAL_LONGJMP"         "\n"
+
+".section \".opd\",\"aw\""          "\n"
+".align 3"                          "\n"
+"VG_MINIMAL_LONGJMP:"               "\n"
+".quad .L.VG_MINIMAL_LONGJMP,.TOC.@tocbase,0"   "\n"
+".previous" "\n"
+
+".type   VG_MINIMAL_LONGJMP, @function"    "\n"
+".L.VG_MINIMAL_LONGJMP:"            "\n"
+         // do r4 = 1
+         // and park it in the restore slot for r3 (the ret reg)
+"        li      4, 1"  "\n"
+"        std     4, 24(3)"  "\n"
+         // restore everything except r3
+         // then r3 last of all
+         // then blr
+"        ld      0, 256(3)"  "\n"
+"        mtlr    0"  "\n"
+"        ld      0, 264(3)"  "\n"
+"        mtcr    0"  "\n"
+"        ld      0, 0(3)"  "\n"
+"        ld      1, 8(3)"  "\n"
+"        ld      2, 16(3)"  "\n"
+         // r3 is done at the end
+"        ld      4, 32(3)"  "\n"
+"        ld      5, 40(3)"  "\n"
+"        ld      6, 48(3)"  "\n"
+"        ld      7, 56(3)"  "\n"
+"        ld      8, 64(3)"  "\n"
+"        ld      9, 72(3)"  "\n"
+"        ld      10, 80(3)"  "\n"
+"        ld      11, 88(3)"  "\n"
+"        ld      12, 96(3)"  "\n"
+"        ld      13, 104(3)"  "\n"
+"        ld      14, 112(3)"  "\n"
+"        ld      15, 120(3)"  "\n"
+"        ld      16, 128(3)"  "\n"
+"        ld      17, 136(3)"  "\n"
+"        ld      18, 144(3)"  "\n"
+"        ld      19, 152(3)"  "\n"
+"        ld      20, 160(3)"  "\n"
+"        ld      21, 168(3)"  "\n"
+"        ld      22, 176(3)"  "\n"
+"        ld      23, 184(3)"  "\n"
+"        ld      24, 192(3)"  "\n"
+"        ld      25, 200(3)"  "\n"
+"        ld      26, 208(3)"  "\n"
+"        ld      27, 216(3)"  "\n"
+"        ld      28, 224(3)"  "\n"
+"        ld      29, 232(3)"  "\n"
+"        ld      30, 240(3)"  "\n"
+"        ld      31, 248(3)"  "\n"
+"        ld      3, 24(3)"  "\n"
+"        blr"               "\n"
+""       "\n"
+
+".previous"  "\n"
+".previous"  "\n"
+);
+
+
+#endif /* VGP_ppc64_linux */
+
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/