32ee74a
From 63a25f30c2b2eec9ebda54750b0e7e6bf889ef0b Mon Sep 17 00:00:00 2001
32ee74a
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
32ee74a
Date: Thu, 21 Aug 2014 08:52:16 +0100
32ee74a
Subject: [PATCH] Resolves: rhbz#1125588 port LibreOffice to ppc64le
32ee74a
32ee74a
Related: rhbz#1125588 first steps for ppc64le
32ee74a
32ee74a
almost certainly won't get us too far, but a start
32ee74a
32ee74a
(cherry picked from commit 170109708e6a082252efba3d2f1726bbd82b6452)
32ee74a
32ee74a
openjdk appears to use ppc64/server/libjvm.so and not ppc64le/server/libjvm.so
32ee74a
32ee74a
(cherry picked from commit 632e4095ad92196480ad82cfa1f106c4c08ae1cc)
32ee74a
32ee74a
need to accept ppc64le as a lib64 using platform in ax_boost_base.m4
32ee74a
32ee74a
(cherry picked from commit 2d48c52da712f8fa3c4a579494c824491afb8515)
32ee74a
32ee74a
linux_powerpc64le->linux_powerpc64_le to match dp_platform.cxx
32ee74a
32ee74a
(cherry picked from commit 2ced4d39cc1b8de233cd886d3ef991b3079500d2)
32ee74a
32ee74a
Related: rhbz#1125588 get as far as privateSnippetExecutor
32ee74a
32ee74a
(cherry picked from commit 4c5bbbf059924f3aa24620a4cbbc35816978a606)
32ee74a
32ee74a
Related: rhbz#1125588 get to the end of cpp_mediate on ppc64le
32ee74a
32ee74a
(cherry picked from commit d8fcd8ca9af087e98a2f6d9cbcf6eb42cddd0c74)
32ee74a
32ee74a
Related: rhbz#1125588 force existence of argument save area
32ee74a
32ee74a
ELFv2 ABI on ppc64 optimises stack allocation
32ee74a
(http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html
32ee74a
so we're getting no argument save area
32ee74a
32ee74a
This now appears to pass the simple cases and onwards
32ee74a
to the tricky ones
32ee74a
32ee74a
(cherry picked from commit 6396e18f4d49c24283b170310a1892db40c128d3)
32ee74a
32ee74a
Related: rhbz#1125588 ppc64le has new struct passing rules
32ee74a
32ee74a
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
32ee74a
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html
32ee74a
32ee74a
now we just fail instead of crash
32ee74a
32ee74a
(cherry picked from commit 970ad502e3ea2cc992c6cc1c7583231aec5bf5da)
32ee74a
32ee74a
Related: rhbz#1125588 ppc64le fix simple struct returning
32ee74a
32ee74a
(cherry picked from commit ee6fcdd18b1a839d7d60617d4fda622f6e6e7e66)
32ee74a
32ee74a
Resolves: rhbz#1125588 ppc64le passes testtools
32ee74a
32ee74a
*bzzt*, <lightning arcs, faint smell of ozone>, it's alive!
32ee74a
32ee74a
(cherry picked from commit 6ab1951ea2e31f47bc9f211dd9b2681c794b8e7f)
32ee74a
32ee74a
openjdk appears to use ppc64/server/libjvm.so and not ppc64le/server/libjvm.so
32ee74a
32ee74a
(cherry picked from commit 632e4095ad92196480ad82cfa1f106c4c08ae1cc)
32ee74a
32ee74a
Conflicts:
32ee74a
	configure.ac
32ee74a
32ee74a
need to accept ppc64le as a lib64 using platform in ax_boost_base.m4
32ee74a
32ee74a
(cherry picked from commit 2d48c52da712f8fa3c4a579494c824491afb8515)
32ee74a
32ee74a
linux_powerpc64le->linux_powerpc64_le to match dp_platform.cxx
32ee74a
32ee74a
(cherry picked from commit 2ced4d39cc1b8de233cd886d3ef991b3079500d2)
32ee74a
32ee74a
Related: rhbz#1125588 get as far as privateSnippetExecutor
32ee74a
32ee74a
(cherry picked from commit 4c5bbbf059924f3aa24620a4cbbc35816978a606)
32ee74a
32ee74a
Related: rhbz#1125588 get to the end of cpp_mediate on ppc64le
32ee74a
32ee74a
(cherry picked from commit d8fcd8ca9af087e98a2f6d9cbcf6eb42cddd0c74)
32ee74a
32ee74a
Conflicts:
32ee74a
	bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
32ee74a
32ee74a
Related: rhbz#1125588 force existence of argument save area
32ee74a
32ee74a
ELFv2 ABI on ppc64 optimises stack allocation
32ee74a
(http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html
32ee74a
so we're getting no argument save area
32ee74a
32ee74a
This now appears to pass the simple cases and onwards
32ee74a
to the tricky ones
32ee74a
32ee74a
(cherry picked from commit 6396e18f4d49c24283b170310a1892db40c128d3)
32ee74a
32ee74a
Related: rhbz#1125588 ppc64le has new struct passing rules
32ee74a
32ee74a
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
32ee74a
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html
32ee74a
32ee74a
now we just fail instead of crash
32ee74a
32ee74a
(cherry picked from commit 970ad502e3ea2cc992c6cc1c7583231aec5bf5da)
32ee74a
32ee74a
Related: rhbz#1125588 ppc64le fix simple struct returning
32ee74a
32ee74a
(cherry picked from commit ee6fcdd18b1a839d7d60617d4fda622f6e6e7e66)
32ee74a
32ee74a
Conflicts:
32ee74a
	bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
32ee74a
32ee74a
Resolves: rhbz#1125588 ppc64le passes testtools
32ee74a
32ee74a
*bzzt*, <lightning arcs, faint smell of ozone>, it's alive!
32ee74a
32ee74a
(cherry picked from commit 6ab1951ea2e31f47bc9f211dd9b2681c794b8e7f)
32ee74a
32ee74a
Change-Id: Ic20b97a97b6d506c32322173bd8332d15c3a4555
32ee74a
ff9e2e0ac9921b0d9d36a49fdcd2323d5dd124ee
32ee74a
86ef068661082addbd165629d3d6905695090a6b
32ee74a
b63e5a28d7ff12780a1051d94c5976244eab1814
32ee74a
cc386083ecd9faefbedebbb9d2496a4eddfa0b2b
32ee74a
d3928ef5ac68ea13a7aa8723bc8b068ecf8075a0
32ee74a
e56d148ebea7fcfc023cb7183bc97f09186e66b4
32ee74a
329c676337885bcf4fdfdcdb5912d75424862126
32ee74a
1e253922fdb606648eff9865f1125a24e35b0d9a
32ee74a
0b42f4e2603e6d76200d63ab2e26bbb856ae1173
32ee74a
ff9e2e0ac9921b0d9d36a49fdcd2323d5dd124ee
32ee74a
86ef068661082addbd165629d3d6905695090a6b
32ee74a
b63e5a28d7ff12780a1051d94c5976244eab1814
32ee74a
cc386083ecd9faefbedebbb9d2496a4eddfa0b2b
32ee74a
d3928ef5ac68ea13a7aa8723bc8b068ecf8075a0
32ee74a
e56d148ebea7fcfc023cb7183bc97f09186e66b4
32ee74a
329c676337885bcf4fdfdcdb5912d75424862126
32ee74a
1e253922fdb606648eff9865f1125a24e35b0d9a
32ee74a
0b42f4e2603e6d76200d63ab2e26bbb856ae1173
32ee74a
---
32ee74a
 .../cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx       | 64 ++++++++++++++----
32ee74a
 .../source/cpp_uno/gcc3_linux_powerpc64/share.hxx  |  1 +
32ee74a
 .../cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx       | 79 ++++++++++++++++++++--
32ee74a
 configure.ac                                       | 11 ++-
32ee74a
 desktop/source/deployment/misc/dp_platform.cxx     |  3 +
32ee74a
 m4/ax_boost_base.m4                                |  2 +-
32ee74a
 6 files changed, 137 insertions(+), 23 deletions(-)
32ee74a
32ee74a
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
32ee74a
index 8bb611f..877c1ab 100644
32ee74a
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
32ee74a
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
32ee74a
@@ -31,6 +31,11 @@
32ee74a
 #include <stdio.h>
32ee74a
 #include <string.h>
32ee74a
 
32ee74a
+#ifdef OSL_BIGENDIAN
32ee74a
+#define IS_BIG_ENDIAN 1
32ee74a
+#else
32ee74a
+#define IS_BIG_ENDIAN 0
32ee74a
+#endif
32ee74a
 
32ee74a
 using namespace ::com::sun::star::uno;
32ee74a
 
32ee74a
@@ -67,7 +72,7 @@ static typelib_TypeClass cpp2uno_call(
32ee74a
 
32ee74a
     if (pReturnTypeDescr)
32ee74a
     {
32ee74a
-        if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
32ee74a
+        if (!ppc64::return_in_hidden_param(pReturnTypeRef))
32ee74a
         {
32ee74a
             pUnoReturn = pRegisterReturn; // direct way for simple types
32ee74a
         }
32ee74a
@@ -139,13 +144,13 @@ static typelib_TypeClass cpp2uno_call(
32ee74a
                 case typelib_TypeClass_BOOLEAN:
32ee74a
                     if (ng < ppc64::MAX_GPR_REGS)
32ee74a
                     {
32ee74a
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-1));
32ee74a
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + 7*IS_BIG_ENDIAN);
32ee74a
                         ng++;
32ee74a
                         gpreg++;
32ee74a
                     }
32ee74a
                     else
32ee74a
                     {
32ee74a
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
32ee74a
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + 7*IS_BIG_ENDIAN);
32ee74a
                         bOverFlowUsed = true;
32ee74a
                     }
32ee74a
                     if (bOverFlowUsed) ovrflw++;
32ee74a
@@ -155,13 +160,13 @@ static typelib_TypeClass cpp2uno_call(
32ee74a
                 case typelib_TypeClass_UNSIGNED_SHORT:
32ee74a
                     if (ng < ppc64::MAX_GPR_REGS)
32ee74a
                     {
32ee74a
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-2));
32ee74a
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + 6*IS_BIG_ENDIAN);
32ee74a
                         ng++;
32ee74a
                         gpreg++;
32ee74a
                     }
32ee74a
                     else
32ee74a
                     {
32ee74a
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
32ee74a
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + 6*IS_BIG_ENDIAN);
32ee74a
                         bOverFlowUsed = true;
32ee74a
                     }
32ee74a
                     if (bOverFlowUsed) ovrflw++;
32ee74a
@@ -171,13 +176,13 @@ static typelib_TypeClass cpp2uno_call(
32ee74a
                 case typelib_TypeClass_UNSIGNED_LONG:
32ee74a
                     if (ng < ppc64::MAX_GPR_REGS)
32ee74a
                     {
32ee74a
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-4));
32ee74a
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + 4*IS_BIG_ENDIAN);
32ee74a
                         ng++;
32ee74a
                         gpreg++;
32ee74a
                     }
32ee74a
                     else
32ee74a
                     {
32ee74a
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-4));
32ee74a
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + 4*IS_BIG_ENDIAN);
32ee74a
                         bOverFlowUsed = true;
32ee74a
                     }
32ee74a
                     if (bOverFlowUsed) ovrflw++;
32ee74a
@@ -321,6 +326,11 @@ static typelib_TypeClass cpp2uno_call(
32ee74a
     }
32ee74a
 }
32ee74a
 
32ee74a
+#if _CALL_ELF == 2
32ee74a
+#  define PARAMSAVE 32
32ee74a
+#else
32ee74a
+#  define PARAMSAVE 48
32ee74a
+#endif
32ee74a
 
32ee74a
 //==================================================================================================
32ee74a
 static typelib_TypeClass cpp_mediate(
32ee74a
@@ -334,7 +344,7 @@ static typelib_TypeClass cpp_mediate(
32ee74a
     sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
32ee74a
 
32ee74a
     long sf = *(long*)sp;
32ee74a
-    void ** ovrflw = (void**)(sf + 112);
32ee74a
+    void ** ovrflw = (void**)(sf + PARAMSAVE + 64);
32ee74a
 
32ee74a
     // gpreg:  [ret *], this, [other gpr params]
32ee74a
     // fpreg:  [fpr params]
32ee74a
@@ -540,7 +550,11 @@ extern "C" void privateSnippetExecutor( ... )
32ee74a
                 "mr     %0,    1\n\t"
32ee74a
                 : "=r" (sp) : );
32ee74a
 
32ee74a
+#if _CALL_ELF == 2
32ee74a
+    volatile long nRegReturn[2];
32ee74a
+#else
32ee74a
     volatile long nRegReturn[1];
32ee74a
+#endif
32ee74a
 
32ee74a
     typelib_TypeClass aType =
32ee74a
         cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, sp, (sal_Int64*)nRegReturn);
32ee74a
@@ -583,14 +597,22 @@ extern "C" void privateSnippetExecutor( ... )
32ee74a
         default:
32ee74a
             __asm__( "ld 3,%0\n\t"
32ee74a
                 : : "m" (nRegReturn[0]) );
32ee74a
+#if _CALL_ELF == 2
32ee74a
+            __asm__( "ld 4,%0\n\t"
32ee74a
+                : : "m" (nRegReturn[1]) );
32ee74a
+#endif
32ee74a
             break;
32ee74a
     }
32ee74a
 }
32ee74a
 
32ee74a
+#if _CALL_ELF == 2
32ee74a
+const int codeSnippetSize = 32;
32ee74a
+#else
32ee74a
 const int codeSnippetSize = 24;
32ee74a
+#endif
32ee74a
 
32ee74a
 unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
32ee74a
-                              bool simpleRetType)
32ee74a
+                              bool bHasHiddenParam)
32ee74a
 {
32ee74a
 #if OSL_DEBUG_LEVEL > 2
32ee74a
     fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
32ee74a
@@ -599,15 +621,27 @@ unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sa
32ee74a
 
32ee74a
     sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
32ee74a
 
32ee74a
-    if ( !simpleRetType )
32ee74a
+    if ( bHasHiddenParam )
32ee74a
         nOffsetAndIndex |= 0x80000000;
32ee74a
-
32ee74a
+#if _CALL_ELF == 2
32ee74a
+    unsigned int *raw = (unsigned int *)&code[0];
32ee74a
+
32ee74a
+    raw[0] = 0xe96c0018;        /* 0:   ld      11,2f-0b(12)    */
32ee74a
+    raw[1] = 0xe98c0010;        /*      ld      12,1f-0b(12)    */
32ee74a
+    raw[2] = 0x7d8903a6;        /*      mtctr   12              */
32ee74a
+    raw[3] = 0x4e800420;        /*      bctr                    */
32ee74a
+                                /* 1:   .quad   function_addr   */
32ee74a
+                                /* 2:   .quad   context         */
32ee74a
+    *(void **)&raw[4] = (void *)privateSnippetExecutor;
32ee74a
+    *(void **)&raw[6] = (void*)nOffsetAndIndex;
32ee74a
+#else
32ee74a
     void ** raw = (void **)&code[0];
32ee74a
     memcpy(raw, (char*) privateSnippetExecutor, 16);
32ee74a
     raw[2] = (void*) nOffsetAndIndex;
32ee74a
+#endif
32ee74a
 #if OSL_DEBUG_LEVEL > 2
32ee74a
     fprintf(stderr, "in: offset/index is %x %x %d, %lx\n",
32ee74a
-    nFunctionIndex, nVtableOffset, !simpleRetType, raw[2]);
32ee74a
+    nFunctionIndex, nVtableOffset, bHasHiddenParam, raw[2]);
32ee74a
 #endif
32ee74a
     return (code + codeSnippetSize);
32ee74a
 }
32ee74a
@@ -673,7 +707,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
32ee74a
             (s++)->fn = code + writetoexecdiff;
32ee74a
             code = codeSnippet(
32ee74a
                 code, functionOffset++, vtableOffset,
32ee74a
-                bridges::cpp_uno::shared::isSimpleType(
32ee74a
+                ppc64::return_in_hidden_param(
32ee74a
                     reinterpret_cast<
32ee74a
                     typelib_InterfaceAttributeTypeDescription * >(
32ee74a
                         member)->pAttributeTypeRef));
32ee74a
@@ -684,7 +718,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
32ee74a
                     member)->bReadOnly)
32ee74a
             {
32ee74a
                 (s++)->fn = code + writetoexecdiff;
32ee74a
-                code = codeSnippet(code, functionOffset++, vtableOffset, true);
32ee74a
+                code = codeSnippet(code, functionOffset++, vtableOffset, false);
32ee74a
             }
32ee74a
             break;
32ee74a
 
32ee74a
@@ -692,7 +726,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
32ee74a
             (s++)->fn = code + writetoexecdiff;
32ee74a
             code = codeSnippet(
32ee74a
                 code, functionOffset++, vtableOffset,
32ee74a
-                bridges::cpp_uno::shared::isSimpleType(
32ee74a
+                ppc64::return_in_hidden_param(
32ee74a
                     reinterpret_cast<
32ee74a
                     typelib_InterfaceMethodTypeDescription * >(
32ee74a
                         member)->pReturnTypeRef));
32ee74a
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
32ee74a
index 4e7a197..a05193a 100644
32ee74a
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
32ee74a
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
32ee74a
@@ -85,6 +85,7 @@ void fillUnoException(
32ee74a
 namespace ppc64
32ee74a
 {
32ee74a
     enum ppclimits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 13 };
32ee74a
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
32ee74a
 }
32ee74a
 
32ee74a
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
32ee74a
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
32ee74a
index a1874d8..105335eb 100644
32ee74a
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
32ee74a
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
32ee74a
@@ -37,9 +37,59 @@
32ee74a
 using namespace ::rtl;
32ee74a
 using namespace ::com::sun::star::uno;
32ee74a
 
32ee74a
-void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegisterReturn)
32ee74a
+namespace ppc64
32ee74a
 {
32ee74a
-    switch (eTypeClass)
32ee74a
+#if _CALL_ELF == 2
32ee74a
+    bool is_complex_struct(const typelib_TypeDescription * type)
32ee74a
+    {
32ee74a
+        const typelib_CompoundTypeDescription * p
32ee74a
+            = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
32ee74a
+        for (sal_Int32 i = 0; i < p->nMembers; ++i)
32ee74a
+        {
32ee74a
+            if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
32ee74a
+                p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
32ee74a
+            {
32ee74a
+                typelib_TypeDescription * t = 0;
32ee74a
+                TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
32ee74a
+                bool b = is_complex_struct(t);
32ee74a
+                TYPELIB_DANGER_RELEASE(t);
32ee74a
+                if (b) {
32ee74a
+                    return true;
32ee74a
+                }
32ee74a
+            }
32ee74a
+            else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
32ee74a
+                return true;
32ee74a
+        }
32ee74a
+        if (p->pBaseTypeDescription != 0)
32ee74a
+            return is_complex_struct(&p->pBaseTypeDescription->aBase);
32ee74a
+        return false;
32ee74a
+    }
32ee74a
+#endif
32ee74a
+
32ee74a
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
32ee74a
+    {
32ee74a
+        if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
32ee74a
+            return false;
32ee74a
+#if _CALL_ELF == 2
32ee74a
+        else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
32ee74a
+        {
32ee74a
+            typelib_TypeDescription * pTypeDescr = 0;
32ee74a
+            TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
32ee74a
+
32ee74a
+            //A Composite Type not larger than 16 bytes is returned in up to two GPRs
32ee74a
+            bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
32ee74a
+
32ee74a
+            TYPELIB_DANGER_RELEASE( pTypeDescr );
32ee74a
+            return bRet;
32ee74a
+        }
32ee74a
+#endif
32ee74a
+        return true;
32ee74a
+    }
32ee74a
+}
32ee74a
+
32ee74a
+void MapReturn(long r3, long r4, double dret, typelib_TypeDescriptionReference* pReturnType, void *pRegisterReturn)
32ee74a
+{
32ee74a
+    switch (pReturnType->eTypeClass)
32ee74a
     {
32ee74a
     case typelib_TypeClass_HYPER:
32ee74a
     case typelib_TypeClass_UNSIGNED_HYPER:
32ee74a
@@ -65,6 +115,17 @@ void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegist
32ee74a
     case typelib_TypeClass_DOUBLE:
32ee74a
             *reinterpret_cast<double *>( pRegisterReturn ) = dret;
32ee74a
             break;
32ee74a
+#if _CALL_ELF == 2
32ee74a
+    case typelib_TypeClass_STRUCT:
32ee74a
+    case typelib_TypeClass_EXCEPTION:
32ee74a
+            if (!ppc64::return_in_hidden_param(pReturnType))
32ee74a
+            {
32ee74a
+                sal_uInt64 *pRegisters = reinterpret_cast<sal_uInt64*>(pRegisterReturn);
32ee74a
+                pRegisters[0] = r3;
32ee74a
+                if (pReturnType->pType->nSize > 8)
32ee74a
+                    pRegisters[1] = r4;
32ee74a
+            }
32ee74a
+#endif
32ee74a
     default:
32ee74a
             break;
32ee74a
     }
32ee74a
@@ -114,7 +175,11 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
32ee74a
     pMethod += 8 * nVtableIndex;
32ee74a
     pMethod = *((sal_uInt64 *)pMethod);
32ee74a
 
32ee74a
+#if _CALL_ELF == 2
32ee74a
+    typedef void (* FunctionCall )(...);
32ee74a
+#else
32ee74a
     typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
32ee74a
+#endif
32ee74a
     FunctionCall pFunc = (FunctionCall)pMethod;
32ee74a
 
32ee74a
     volatile double dret;
32ee74a
@@ -168,7 +233,7 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
32ee74a
                 "fmr    %0,     1\n\t"
32ee74a
                 : "=f" (dret), "=r" (r3), "=r" (r4) : );
32ee74a
 
32ee74a
-    MapReturn(r3, dret, pReturnTypeDescr->eTypeClass, pRegisterReturn);
32ee74a
+    MapReturn(r3, r4, dret, pReturnTypeRef, pRegisterReturn);
32ee74a
 }
32ee74a
 
32ee74a
 // Macros for easier insertion of values to registers or stack
32ee74a
@@ -252,14 +317,18 @@ static void cpp_call(
32ee74a
 
32ee74a
     void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
32ee74a
 
32ee74a
-        bool bOverFlow = false;
120a5bd
+    bool bOverFlow = false;
32ee74a
+    bool bSimpleReturn = true;
32ee74a
 
32ee74a
     if (pReturnTypeDescr)
32ee74a
     {
32ee74a
 #if OSL_DEBUG_LEVEL > 2
32ee74a
         fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
32ee74a
 #endif
32ee74a
-        if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
32ee74a
+        if (ppc64::return_in_hidden_param(pReturnTypeRef))
32ee74a
+            bSimpleReturn = false;
32ee74a
+
32ee74a
+        if (bSimpleReturn)
32ee74a
         {
32ee74a
             pCppReturn = pUnoReturn; // direct way for simple types
32ee74a
 #if OSL_DEBUG_LEVEL > 2
32ee74a
diff --git a/configure.ac b/configure.ac
32ee74a
index 2560a0d..d72d272 100644
32ee74a
--- a/configure.ac
32ee74a
+++ b/configure.ac
32ee74a
@@ -4157,6 +4157,13 @@ linux-gnu*)
32ee74a
         PLATFORMID=linux_powerpc_64
32ee74a
         OUTPATH=unxlngppc64
32ee74a
         ;;
32ee74a
+    powerpc64le)
32ee74a
+        CPUNAME=POWERPC64
32ee74a
+        RTL_ARCH=PowerPC_64_LE
32ee74a
+        LIB64="lib64"
32ee74a
+        PLATFORMID=linux_powerpc64_le
32ee74a
+        OUTPATH=unxlngppc64
32ee74a
+        ;;
32ee74a
     sparc)
32ee74a
         CPUNAME=SPARC
32ee74a
         RTL_ARCH=SPARC
32ee74a
@@ -7155,7 +7162,7 @@ if test -n "$ENABLE_JAVA" -a \( -z "$JAVALIB" -o -z "$JAVAINC" \); then
32ee74a
                 ;;
32ee74a
             esac
32ee74a
             ;;
32ee74a
-        powerpc64)
32ee74a
+        powerpc64*)
32ee74a
             JAVA_ARCH="ppc64"
32ee74a
             if test "$JDK" = "gcj"; then
32ee74a
                 JAVA_TOOLKIT="client"
32ee74a
@@ -10809,7 +10816,7 @@ AC_SUBST(RHINO_JAR)
32ee74a
 
32ee74a
 supports_multilib=
32ee74a
 case "$host_cpu" in
32ee74a
-x86_64 | powerpc64 | s390x)
32ee74a
+x86_64 | powerpc64 | powerpc64le | s390x)
32ee74a
     if test "$SAL_TYPES_SIZEOFLONG" = "8"; then
32ee74a
         supports_multilib="yes"
32ee74a
     fi
32ee74a
diff --git a/desktop/source/deployment/misc/dp_platform.cxx b/desktop/source/deployment/misc/dp_platform.cxx
32ee74a
index 830f865..adb5a9a 100644
32ee74a
--- a/desktop/source/deployment/misc/dp_platform.cxx
32ee74a
+++ b/desktop/source/deployment/misc/dp_platform.cxx
32ee74a
@@ -35,6 +35,7 @@
32ee74a
 #define PLATFORM_LINUX_SPARC        "linux_sparc"
32ee74a
 #define PLATFORM_LINUX_POWERPC      "linux_powerpc"
32ee74a
 #define PLATFORM_LINUX_POWERPC64    "linux_powerpc64"
32ee74a
+#define PLATFORM_LINUX_POWERPC64_LE "linux_powerpc64_le"
32ee74a
 #define PLATFORM_LINUX_ARM_EABI     "linux_arm_eabi"
32ee74a
 #define PLATFORM_LINUX_ARM_OABI     "linux_arm_oabi"
32ee74a
 #define PLATFORM_LINUX_MIPS_EL      "linux_mips_el"
32ee74a
@@ -129,6 +130,8 @@ namespace
32ee74a
             ret = checkOSandCPU("Linux", "PowerPC");
32ee74a
         else if (token == PLATFORM_LINUX_POWERPC64)
32ee74a
             ret = checkOSandCPU("Linux", "PowerPC_64");
32ee74a
+        else if (token == PLATFORM_LINUX_POWERPC64_LE)
32ee74a
+            ret = checkOSandCPU("Linux", "PowerPC_64_LE");
32ee74a
         else if (token == PLATFORM_LINUX_ARM_EABI)
32ee74a
             ret = checkOSandCPU("Linux", "ARM_EABI");
32ee74a
         else if (token == PLATFORM_LINUX_ARM_OABI)
32ee74a
diff --git a/m4/ax_boost_base.m4 b/m4/ax_boost_base.m4
32ee74a
index 7a0cf52..55de0c4 100644
32ee74a
--- a/m4/ax_boost_base.m4
32ee74a
+++ b/m4/ax_boost_base.m4
32ee74a
@@ -91,7 +91,7 @@ if test "x$want_boost" = "xyes"; then
32ee74a
     dnl are found, e.g. when only header-only libraries are installed!
32ee74a
     libsubdirs="lib"
32ee74a
     ax_arch=`uname -m`
32ee74a
-    if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64 -o $ax_arch = aarch64; then
32ee74a
+    if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = ppc64le -o $ax_arch = s390x -o $ax_arch = sparc64 -o $ax_arch = aarch64; then
32ee74a
         libsubdirs="lib64 lib lib64"
32ee74a
     fi
32ee74a
 
32ee74a
-- 
32ee74a
1.9.3
32ee74a