Blob Blame History Raw
From 63a25f30c2b2eec9ebda54750b0e7e6bf889ef0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
Date: Thu, 21 Aug 2014 08:52:16 +0100
Subject: [PATCH] Resolves: rhbz#1125588 port LibreOffice to ppc64le

Related: rhbz#1125588 first steps for ppc64le

almost certainly won't get us too far, but a start

(cherry picked from commit 170109708e6a082252efba3d2f1726bbd82b6452)

openjdk appears to use ppc64/server/libjvm.so and not ppc64le/server/libjvm.so

(cherry picked from commit 632e4095ad92196480ad82cfa1f106c4c08ae1cc)

need to accept ppc64le as a lib64 using platform in ax_boost_base.m4

(cherry picked from commit 2d48c52da712f8fa3c4a579494c824491afb8515)

linux_powerpc64le->linux_powerpc64_le to match dp_platform.cxx

(cherry picked from commit 2ced4d39cc1b8de233cd886d3ef991b3079500d2)

Related: rhbz#1125588 get as far as privateSnippetExecutor

(cherry picked from commit 4c5bbbf059924f3aa24620a4cbbc35816978a606)

Related: rhbz#1125588 get to the end of cpp_mediate on ppc64le

(cherry picked from commit d8fcd8ca9af087e98a2f6d9cbcf6eb42cddd0c74)

Related: rhbz#1125588 force existence of argument save area

ELFv2 ABI on ppc64 optimises stack allocation
(http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html
so we're getting no argument save area

This now appears to pass the simple cases and onwards
to the tricky ones

(cherry picked from commit 6396e18f4d49c24283b170310a1892db40c128d3)

Related: rhbz#1125588 ppc64le has new struct passing rules

http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html

now we just fail instead of crash

(cherry picked from commit 970ad502e3ea2cc992c6cc1c7583231aec5bf5da)

Related: rhbz#1125588 ppc64le fix simple struct returning

(cherry picked from commit ee6fcdd18b1a839d7d60617d4fda622f6e6e7e66)

Resolves: rhbz#1125588 ppc64le passes testtools

*bzzt*, <lightning arcs, faint smell of ozone>, it's alive!

(cherry picked from commit 6ab1951ea2e31f47bc9f211dd9b2681c794b8e7f)

openjdk appears to use ppc64/server/libjvm.so and not ppc64le/server/libjvm.so

(cherry picked from commit 632e4095ad92196480ad82cfa1f106c4c08ae1cc)

Conflicts:
	configure.ac

need to accept ppc64le as a lib64 using platform in ax_boost_base.m4

(cherry picked from commit 2d48c52da712f8fa3c4a579494c824491afb8515)

linux_powerpc64le->linux_powerpc64_le to match dp_platform.cxx

(cherry picked from commit 2ced4d39cc1b8de233cd886d3ef991b3079500d2)

Related: rhbz#1125588 get as far as privateSnippetExecutor

(cherry picked from commit 4c5bbbf059924f3aa24620a4cbbc35816978a606)

Related: rhbz#1125588 get to the end of cpp_mediate on ppc64le

(cherry picked from commit d8fcd8ca9af087e98a2f6d9cbcf6eb42cddd0c74)

Conflicts:
	bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx

Related: rhbz#1125588 force existence of argument save area

ELFv2 ABI on ppc64 optimises stack allocation
(http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01149.html
so we're getting no argument save area

This now appears to pass the simple cases and onwards
to the tricky ones

(cherry picked from commit 6396e18f4d49c24283b170310a1892db40c128d3)

Related: rhbz#1125588 ppc64le has new struct passing rules

http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01145.html
http://gcc.gnu.org/ml/gcc-patches/2013-11/msg01147.html

now we just fail instead of crash

(cherry picked from commit 970ad502e3ea2cc992c6cc1c7583231aec5bf5da)

Related: rhbz#1125588 ppc64le fix simple struct returning

(cherry picked from commit ee6fcdd18b1a839d7d60617d4fda622f6e6e7e66)

Conflicts:
	bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx

Resolves: rhbz#1125588 ppc64le passes testtools

*bzzt*, <lightning arcs, faint smell of ozone>, it's alive!

(cherry picked from commit 6ab1951ea2e31f47bc9f211dd9b2681c794b8e7f)

Change-Id: Ic20b97a97b6d506c32322173bd8332d15c3a4555
ff9e2e0ac9921b0d9d36a49fdcd2323d5dd124ee
86ef068661082addbd165629d3d6905695090a6b
b63e5a28d7ff12780a1051d94c5976244eab1814
cc386083ecd9faefbedebbb9d2496a4eddfa0b2b
d3928ef5ac68ea13a7aa8723bc8b068ecf8075a0
e56d148ebea7fcfc023cb7183bc97f09186e66b4
329c676337885bcf4fdfdcdb5912d75424862126
1e253922fdb606648eff9865f1125a24e35b0d9a
0b42f4e2603e6d76200d63ab2e26bbb856ae1173
ff9e2e0ac9921b0d9d36a49fdcd2323d5dd124ee
86ef068661082addbd165629d3d6905695090a6b
b63e5a28d7ff12780a1051d94c5976244eab1814
cc386083ecd9faefbedebbb9d2496a4eddfa0b2b
d3928ef5ac68ea13a7aa8723bc8b068ecf8075a0
e56d148ebea7fcfc023cb7183bc97f09186e66b4
329c676337885bcf4fdfdcdb5912d75424862126
1e253922fdb606648eff9865f1125a24e35b0d9a
0b42f4e2603e6d76200d63ab2e26bbb856ae1173
---
 .../cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx       | 64 ++++++++++++++----
 .../source/cpp_uno/gcc3_linux_powerpc64/share.hxx  |  1 +
 .../cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx       | 79 ++++++++++++++++++++--
 configure.ac                                       | 11 ++-
 desktop/source/deployment/misc/dp_platform.cxx     |  3 +
 m4/ax_boost_base.m4                                |  2 +-
 6 files changed, 137 insertions(+), 23 deletions(-)

diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
index 8bb611f..877c1ab 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/cpp2uno.cxx
@@ -31,6 +31,11 @@
 #include <stdio.h>
 #include <string.h>
 
+#ifdef OSL_BIGENDIAN
+#define IS_BIG_ENDIAN 1
+#else
+#define IS_BIG_ENDIAN 0
+#endif
 
 using namespace ::com::sun::star::uno;
 
@@ -67,7 +72,7 @@ static typelib_TypeClass cpp2uno_call(
 
     if (pReturnTypeDescr)
     {
-        if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+        if (!ppc64::return_in_hidden_param(pReturnTypeRef))
         {
             pUnoReturn = pRegisterReturn; // direct way for simple types
         }
@@ -139,13 +144,13 @@ static typelib_TypeClass cpp2uno_call(
                 case typelib_TypeClass_BOOLEAN:
                     if (ng < ppc64::MAX_GPR_REGS)
                     {
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-1));
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + 7*IS_BIG_ENDIAN);
                         ng++;
                         gpreg++;
                     }
                     else
                     {
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-1));
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + 7*IS_BIG_ENDIAN);
                         bOverFlowUsed = true;
                     }
                     if (bOverFlowUsed) ovrflw++;
@@ -155,13 +160,13 @@ static typelib_TypeClass cpp2uno_call(
                 case typelib_TypeClass_UNSIGNED_SHORT:
                     if (ng < ppc64::MAX_GPR_REGS)
                     {
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-2));
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + 6*IS_BIG_ENDIAN);
                         ng++;
                         gpreg++;
                     }
                     else
                     {
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-2));
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + 6*IS_BIG_ENDIAN);
                         bOverFlowUsed = true;
                     }
                     if (bOverFlowUsed) ovrflw++;
@@ -171,13 +176,13 @@ static typelib_TypeClass cpp2uno_call(
                 case typelib_TypeClass_UNSIGNED_LONG:
                     if (ng < ppc64::MAX_GPR_REGS)
                     {
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + (sizeof(void*)-4));
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)gpreg) + 4*IS_BIG_ENDIAN);
                         ng++;
                         gpreg++;
                     }
                     else
                     {
-                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + (sizeof(void*)-4));
+                        pCppArgs[nPos] = pUnoArgs[nPos] = (((char *)ovrflw) + 4*IS_BIG_ENDIAN);
                         bOverFlowUsed = true;
                     }
                     if (bOverFlowUsed) ovrflw++;
@@ -321,6 +326,11 @@ static typelib_TypeClass cpp2uno_call(
     }
 }
 
+#if _CALL_ELF == 2
+#  define PARAMSAVE 32
+#else
+#  define PARAMSAVE 48
+#endif
 
 //==================================================================================================
 static typelib_TypeClass cpp_mediate(
@@ -334,7 +344,7 @@ static typelib_TypeClass cpp_mediate(
     sal_Int32 nFunctionIndex = (nOffsetAndIndex & 0xFFFFFFFF);
 
     long sf = *(long*)sp;
-    void ** ovrflw = (void**)(sf + 112);
+    void ** ovrflw = (void**)(sf + PARAMSAVE + 64);
 
     // gpreg:  [ret *], this, [other gpr params]
     // fpreg:  [fpr params]
@@ -540,7 +550,11 @@ extern "C" void privateSnippetExecutor( ... )
                 "mr     %0,    1\n\t"
                 : "=r" (sp) : );
 
+#if _CALL_ELF == 2
+    volatile long nRegReturn[2];
+#else
     volatile long nRegReturn[1];
+#endif
 
     typelib_TypeClass aType =
         cpp_mediate( nOffsetAndIndex, (void**)gpreg, (void**)fpreg, sp, (sal_Int64*)nRegReturn);
@@ -583,14 +597,22 @@ extern "C" void privateSnippetExecutor( ... )
         default:
             __asm__( "ld 3,%0\n\t"
                 : : "m" (nRegReturn[0]) );
+#if _CALL_ELF == 2
+            __asm__( "ld 4,%0\n\t"
+                : : "m" (nRegReturn[1]) );
+#endif
             break;
     }
 }
 
+#if _CALL_ELF == 2
+const int codeSnippetSize = 32;
+#else
 const int codeSnippetSize = 24;
+#endif
 
 unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
-                              bool simpleRetType)
+                              bool bHasHiddenParam)
 {
 #if OSL_DEBUG_LEVEL > 2
     fprintf(stderr,"in codeSnippet functionIndex is %x\n", nFunctionIndex);
@@ -599,15 +621,27 @@ unsigned char *  codeSnippet( unsigned char * code, sal_Int32 nFunctionIndex, sa
 
     sal_uInt64 nOffsetAndIndex = ( ( (sal_uInt64) nVtableOffset ) << 32 ) | ( (sal_uInt64) nFunctionIndex );
 
-    if ( !simpleRetType )
+    if ( bHasHiddenParam )
         nOffsetAndIndex |= 0x80000000;
-
+#if _CALL_ELF == 2
+    unsigned int *raw = (unsigned int *)&code[0];
+
+    raw[0] = 0xe96c0018;        /* 0:   ld      11,2f-0b(12)    */
+    raw[1] = 0xe98c0010;        /*      ld      12,1f-0b(12)    */
+    raw[2] = 0x7d8903a6;        /*      mtctr   12              */
+    raw[3] = 0x4e800420;        /*      bctr                    */
+                                /* 1:   .quad   function_addr   */
+                                /* 2:   .quad   context         */
+    *(void **)&raw[4] = (void *)privateSnippetExecutor;
+    *(void **)&raw[6] = (void*)nOffsetAndIndex;
+#else
     void ** raw = (void **)&code[0];
     memcpy(raw, (char*) privateSnippetExecutor, 16);
     raw[2] = (void*) nOffsetAndIndex;
+#endif
 #if OSL_DEBUG_LEVEL > 2
     fprintf(stderr, "in: offset/index is %x %x %d, %lx\n",
-    nFunctionIndex, nVtableOffset, !simpleRetType, raw[2]);
+    nFunctionIndex, nVtableOffset, bHasHiddenParam, raw[2]);
 #endif
     return (code + codeSnippetSize);
 }
@@ -673,7 +707,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
             (s++)->fn = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
-                bridges::cpp_uno::shared::isSimpleType(
+                ppc64::return_in_hidden_param(
                     reinterpret_cast<
                     typelib_InterfaceAttributeTypeDescription * >(
                         member)->pAttributeTypeRef));
@@ -684,7 +718,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
                     member)->bReadOnly)
             {
                 (s++)->fn = code + writetoexecdiff;
-                code = codeSnippet(code, functionOffset++, vtableOffset, true);
+                code = codeSnippet(code, functionOffset++, vtableOffset, false);
             }
             break;
 
@@ -692,7 +726,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
             (s++)->fn = code + writetoexecdiff;
             code = codeSnippet(
                 code, functionOffset++, vtableOffset,
-                bridges::cpp_uno::shared::isSimpleType(
+                ppc64::return_in_hidden_param(
                     reinterpret_cast<
                     typelib_InterfaceMethodTypeDescription * >(
                         member)->pReturnTypeRef));
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
index 4e7a197..a05193a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/share.hxx
@@ -85,6 +85,7 @@ void fillUnoException(
 namespace ppc64
 {
     enum ppclimits { MAX_GPR_REGS = 8, MAX_SSE_REGS = 13 };
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
index a1874d8..105335eb 100644
--- a/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_powerpc64/uno2cpp.cxx
@@ -37,9 +37,59 @@
 using namespace ::rtl;
 using namespace ::com::sun::star::uno;
 
-void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegisterReturn)
+namespace ppc64
 {
-    switch (eTypeClass)
+#if _CALL_ELF == 2
+    bool is_complex_struct(const typelib_TypeDescription * type)
+    {
+        const typelib_CompoundTypeDescription * p
+            = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+        for (sal_Int32 i = 0; i < p->nMembers; ++i)
+        {
+            if (p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_STRUCT ||
+                p->ppTypeRefs[i]->eTypeClass == typelib_TypeClass_EXCEPTION)
+            {
+                typelib_TypeDescription * t = 0;
+                TYPELIB_DANGER_GET(&t, p->ppTypeRefs[i]);
+                bool b = is_complex_struct(t);
+                TYPELIB_DANGER_RELEASE(t);
+                if (b) {
+                    return true;
+                }
+            }
+            else if (!bridges::cpp_uno::shared::isSimpleType(p->ppTypeRefs[i]->eTypeClass))
+                return true;
+        }
+        if (p->pBaseTypeDescription != 0)
+            return is_complex_struct(&p->pBaseTypeDescription->aBase);
+        return false;
+    }
+#endif
+
+    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+    {
+        if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+            return false;
+#if _CALL_ELF == 2
+        else if (pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION)
+        {
+            typelib_TypeDescription * pTypeDescr = 0;
+            TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
+
+            //A Composite Type not larger than 16 bytes is returned in up to two GPRs
+            bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
+
+            TYPELIB_DANGER_RELEASE( pTypeDescr );
+            return bRet;
+        }
+#endif
+        return true;
+    }
+}
+
+void MapReturn(long r3, long r4, double dret, typelib_TypeDescriptionReference* pReturnType, void *pRegisterReturn)
+{
+    switch (pReturnType->eTypeClass)
     {
     case typelib_TypeClass_HYPER:
     case typelib_TypeClass_UNSIGNED_HYPER:
@@ -65,6 +115,17 @@ void MapReturn(long r3, double dret, typelib_TypeClass eTypeClass, void *pRegist
     case typelib_TypeClass_DOUBLE:
             *reinterpret_cast<double *>( pRegisterReturn ) = dret;
             break;
+#if _CALL_ELF == 2
+    case typelib_TypeClass_STRUCT:
+    case typelib_TypeClass_EXCEPTION:
+            if (!ppc64::return_in_hidden_param(pReturnType))
+            {
+                sal_uInt64 *pRegisters = reinterpret_cast<sal_uInt64*>(pRegisterReturn);
+                pRegisters[0] = r3;
+                if (pReturnType->pType->nSize > 8)
+                    pRegisters[1] = r4;
+            }
+#endif
     default:
             break;
     }
@@ -114,7 +175,11 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
     pMethod += 8 * nVtableIndex;
     pMethod = *((sal_uInt64 *)pMethod);
 
+#if _CALL_ELF == 2
+    typedef void (* FunctionCall )(...);
+#else
     typedef void (* FunctionCall )( sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64, sal_uInt64 );
+#endif
     FunctionCall pFunc = (FunctionCall)pMethod;
 
     volatile double dret;
@@ -168,7 +233,7 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
                 "fmr    %0,     1\n\t"
                 : "=f" (dret), "=r" (r3), "=r" (r4) : );
 
-    MapReturn(r3, dret, pReturnTypeDescr->eTypeClass, pRegisterReturn);
+    MapReturn(r3, r4, dret, pReturnTypeRef, pRegisterReturn);
 }
 
 // Macros for easier insertion of values to registers or stack
@@ -252,14 +317,18 @@ static void cpp_call(
 
     void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
 
-        bool bOverFlow = false;
+    bool bOverFlow = false;
+    bool bSimpleReturn = true;
 
     if (pReturnTypeDescr)
     {
 #if OSL_DEBUG_LEVEL > 2
         fprintf(stderr, "return type is %d\n", pReturnTypeDescr->eTypeClass);
 #endif
-        if (bridges::cpp_uno::shared::isSimpleType( pReturnTypeDescr ))
+        if (ppc64::return_in_hidden_param(pReturnTypeRef))
+            bSimpleReturn = false;
+
+        if (bSimpleReturn)
         {
             pCppReturn = pUnoReturn; // direct way for simple types
 #if OSL_DEBUG_LEVEL > 2
diff --git a/configure.ac b/configure.ac
index 2560a0d..d72d272 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4157,6 +4157,13 @@ linux-gnu*)
         PLATFORMID=linux_powerpc_64
         OUTPATH=unxlngppc64
         ;;
+    powerpc64le)
+        CPUNAME=POWERPC64
+        RTL_ARCH=PowerPC_64_LE
+        LIB64="lib64"
+        PLATFORMID=linux_powerpc64_le
+        OUTPATH=unxlngppc64
+        ;;
     sparc)
         CPUNAME=SPARC
         RTL_ARCH=SPARC
@@ -7155,7 +7162,7 @@ if test -n "$ENABLE_JAVA" -a \( -z "$JAVALIB" -o -z "$JAVAINC" \); then
                 ;;
             esac
             ;;
-        powerpc64)
+        powerpc64*)
             JAVA_ARCH="ppc64"
             if test "$JDK" = "gcj"; then
                 JAVA_TOOLKIT="client"
@@ -10809,7 +10816,7 @@ AC_SUBST(RHINO_JAR)
 
 supports_multilib=
 case "$host_cpu" in
-x86_64 | powerpc64 | s390x)
+x86_64 | powerpc64 | powerpc64le | s390x)
     if test "$SAL_TYPES_SIZEOFLONG" = "8"; then
         supports_multilib="yes"
     fi
diff --git a/desktop/source/deployment/misc/dp_platform.cxx b/desktop/source/deployment/misc/dp_platform.cxx
index 830f865..adb5a9a 100644
--- a/desktop/source/deployment/misc/dp_platform.cxx
+++ b/desktop/source/deployment/misc/dp_platform.cxx
@@ -35,6 +35,7 @@
 #define PLATFORM_LINUX_SPARC        "linux_sparc"
 #define PLATFORM_LINUX_POWERPC      "linux_powerpc"
 #define PLATFORM_LINUX_POWERPC64    "linux_powerpc64"
+#define PLATFORM_LINUX_POWERPC64_LE "linux_powerpc64_le"
 #define PLATFORM_LINUX_ARM_EABI     "linux_arm_eabi"
 #define PLATFORM_LINUX_ARM_OABI     "linux_arm_oabi"
 #define PLATFORM_LINUX_MIPS_EL      "linux_mips_el"
@@ -129,6 +130,8 @@ namespace
             ret = checkOSandCPU("Linux", "PowerPC");
         else if (token == PLATFORM_LINUX_POWERPC64)
             ret = checkOSandCPU("Linux", "PowerPC_64");
+        else if (token == PLATFORM_LINUX_POWERPC64_LE)
+            ret = checkOSandCPU("Linux", "PowerPC_64_LE");
         else if (token == PLATFORM_LINUX_ARM_EABI)
             ret = checkOSandCPU("Linux", "ARM_EABI");
         else if (token == PLATFORM_LINUX_ARM_OABI)
diff --git a/m4/ax_boost_base.m4 b/m4/ax_boost_base.m4
index 7a0cf52..55de0c4 100644
--- a/m4/ax_boost_base.m4
+++ b/m4/ax_boost_base.m4
@@ -91,7 +91,7 @@ if test "x$want_boost" = "xyes"; then
     dnl are found, e.g. when only header-only libraries are installed!
     libsubdirs="lib"
     ax_arch=`uname -m`
-    if test $ax_arch = x86_64 -o $ax_arch = ppc64 -o $ax_arch = s390x -o $ax_arch = sparc64 -o $ax_arch = aarch64; then
+    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
         libsubdirs="lib64 lib lib64"
     fi
 
-- 
1.9.3