[Libreoffice-commits] core.git: bridges/source

Tor Lillqvist tml at collabora.com
Sat Dec 21 08:57:51 PST 2013


 bridges/source/cpp_uno/gcc3_ios_arm/cpp2uno-arm64.cxx    |   69 +-
 bridges/source/cpp_uno/gcc3_ios_arm/except.cxx           |    1 
 bridges/source/cpp_uno/gcc3_ios_arm/generate-snippets.pl |    8 
 bridges/source/cpp_uno/gcc3_ios_arm/helper.s             |   19 
 bridges/source/cpp_uno/gcc3_ios_arm/share.hxx            |   14 
 bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp-arm64.cxx    |  354 +++++----------
 6 files changed, 193 insertions(+), 272 deletions(-)

New commits:
commit 928c8c800e2d6c17a768ea8fe2767a2ea68fba20
Author: Tor Lillqvist <tml at collabora.com>
Date:   Fri Dec 20 23:57:06 2013 +0200

    iOS arm64 C++/UNO bridge WIP
    
    Change-Id: I5eb994e4a48b043f463940d1c34ad7a9459b83cd

diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/cpp2uno-arm64.cxx b/bridges/source/cpp_uno/gcc3_ios_arm/cpp2uno-arm64.cxx
index 54441b8..1b68c1e 100644
--- a/bridges/source/cpp_uno/gcc3_ios_arm/cpp2uno-arm64.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios_arm/cpp2uno-arm64.cxx
@@ -20,9 +20,7 @@
 #ifdef __arm64
 
 // For iOS devices (64-bit ARM). Originally a copy of
-// ../gcc3_linux_arm/cpp2uno.cxx with some cleanups and necessary
-// changes: No dynamic code generation as that is prohibited for apps
-// in the App Store. Instead we use a set of pre-generated snippets.
+// ../gcc3_linux_arm/cpp2uno.cxx.
 
 // No attempts at factoring out the large amounts of more or less
 // common code in this, cpp2uno-arm.cxx and cpp2uno-i386.cxx have been
@@ -49,23 +47,19 @@ using namespace ::com::sun::star::uno;
 
 namespace
 {
-
     static typelib_TypeClass cpp2uno_call(
         bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
         const typelib_TypeDescription * pMemberTypeDescr,
         typelib_TypeDescriptionReference * pReturnTypeRef,
-        sal_Int32 nParams, typelib_MethodParameter * pParams,
+        sal_Int32 nParams,
+        typelib_MethodParameter * pParams,
         void ** pCallStack,
         sal_Int64 * pRegisterReturn /* space for register return */ )
     {
-        // pCallStack: ret, [return ptr], this, params
+        // pCallStack: x8, ret, [return ptr], this, params
         char * pTopStack = (char *)(pCallStack + 0);
         char * pCppStack = pTopStack;
 
-#ifdef __ARM_PCS_VFP
-        int dc = 0;
-        char * pFloatArgs = (char *)(pCppStack - 64);
-#endif
         // return
         typelib_TypeDescription * pReturnTypeDescr = 0;
         if (pReturnTypeRef)
@@ -77,7 +71,7 @@ namespace
 
         if (pReturnTypeDescr)
         {
-            if (!arm::return_in_hidden_param(pReturnTypeRef))
+            if (!arm::return_in_x8(pReturnTypeRef))
                 pUnoReturn = pRegisterReturn; // direct way for simple types
             else // complex return via ptr (pCppReturn)
             {
@@ -99,14 +93,14 @@ namespace
 
         // Indices of values this have to be converted (interface conversion
         // cpp<=>uno)
-        sal_Int32 * pTempIndices = (sal_Int32 *)alloca( sizeof(sal_Int32) * nParams);
+        int * pTempIndices = (sal_Int32 *)alloca( sizeof(int) * nParams);
 
         // Type descriptions for reconversions
         typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(typelib_TypeDescription *) * nParams);
 
-        sal_Int32 nTempIndices   = 0;
+        int nTempIndices = 0;
 
-        for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+        for ( int nPos = 0; nPos < nParams; ++nPos )
         {
             const typelib_MethodParameter & rParam = pParams[nPos];
             typelib_TypeDescription * pParamTypeDescr = 0;
@@ -221,7 +215,7 @@ namespace
             // destruct temporary in/inout params
             for ( ; nTempIndices--; )
             {
-                sal_Int32 nIndex = pTempIndices[nTempIndices];
+                int nIndex = pTempIndices[nTempIndices];
 
                 if (pParams[nIndex].bIn) // is in/inout => was constructed
                     uno_destructData( pUnoArgs[nIndex],
@@ -241,7 +235,7 @@ namespace
             // temporary params
             for ( ; nTempIndices--; )
             {
-                sal_Int32 nIndex = pTempIndices[nTempIndices];
+                int nIndex = pTempIndices[nTempIndices];
                 typelib_TypeDescription * pParamTypeDescr =
                     ppTempParamTypeDescr[nTempIndices];
 
@@ -285,25 +279,15 @@ namespace
 
 
     //=====================================================================
-    static typelib_TypeClass cpp_mediate(
-        sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
-        void ** pCallStack,
-        sal_Int64 * pRegisterReturn /* space for register return */ )
+    static typelib_TypeClass cpp_mediate( sal_Int32 nFunctionIndex,
+                                          sal_Int32 nVtableOffset,
+                                          void ** pCallStack,
+                                          sal_Int64 * pRegisterReturn )
     {
-        OSL_ENSURE( sizeof(sal_Int32)==sizeof(void *), "### unexpected!" );
-
-        // pCallStack: [ret *], this, params
+        // pCallStack: x8, ret *, this, params
         // _this_ ptr is patched cppu_XInterfaceProxy object
-        void *pThis;
-        if( nFunctionIndex & 0x80000000 )
-        {
-            nFunctionIndex &= 0x7fffffff;
-            pThis = pCallStack[1];
-        }
-        else
-        {
-            pThis = pCallStack[0];
-        }
+        nFunctionIndex &= 0x7fffffff;
+        void *pThis = pCallStack[2];
 
         pThis = static_cast< char * >(pThis) - nVtableOffset;
         bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
@@ -427,12 +411,11 @@ namespace
  * (called by asm snippets)
  */
 
-extern "C" sal_Int64 cpp_vtable_call( long *pFunctionAndOffset,
-    void **pCallStack )
+extern "C" sal_Int64 cpp_vtable_call( sal_Int32 *pFunctionAndOffset,
+                                      void **pCallStack )
 {
     sal_Int64 nRegReturn;
-    typelib_TypeClass aType = cpp_mediate( pFunctionAndOffset[0], pFunctionAndOffset[1], pCallStack,
-        &nRegReturn );
+    typelib_TypeClass aType = cpp_mediate( pFunctionAndOffset[0], pFunctionAndOffset[1], pCallStack, &nRegReturn );
 
     switch( aType )
     {
@@ -461,7 +444,7 @@ extern "C" sal_Int64 cpp_vtable_call( long *pFunctionAndOffset,
 namespace
 {
     unsigned char *codeSnippet(sal_Int32 functionIndex,
-        sal_Int32 vtableOffset, bool bHasHiddenParam)
+        sal_Int32 vtableOffset, bool bReturnThroughX8)
     {
         assert(functionIndex < nFunIndexes);
         if (!(functionIndex < nFunIndexes))
@@ -472,14 +455,14 @@ namespace
             return NULL;
 
         // The codeSnippets table is indexed by functionIndex,
-        // vtableOffset, and the has-hidden-param flag
+        // vtableOffset, and the return-through-x8 flag
 
-        int index = functionIndex*nVtableOffsets*2 + vtableOffset*2 + bHasHiddenParam;
+        int index = functionIndex*nVtableOffsets*2 + vtableOffset*2 + bReturnThroughX8;
         unsigned char *result = ((unsigned char *) &codeSnippets) + codeSnippets[index];
 
         SAL_INFO( "bridges.ios",
                   "codeSnippet: [" <<
-                  functionIndex << "," << vtableOffset << "," << bHasHiddenParam << "]=" <<
+                  functionIndex << "," << vtableOffset << "," << bReturnThroughX8 << "]=" <<
                   (void *) result);
 
         return result;
@@ -532,7 +515,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
                 // Getter:
                 (s++)->fn = codeSnippet(
                     functionOffset++, vtableOffset,
-                    arm::return_in_hidden_param( pAttrTD->pAttributeTypeRef ));
+                    arm::return_in_x8( pAttrTD->pAttributeTypeRef ));
 
                 // Setter:
                 if (!pAttrTD->bReadOnly)
@@ -549,7 +532,7 @@ unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
                         typelib_InterfaceMethodTypeDescription * >(member);
 
                 (s++)->fn = codeSnippet(functionOffset++, vtableOffset,
-                    arm::return_in_hidden_param(pMethodTD->pReturnTypeRef));
+                    arm::return_in_x8(pMethodTD->pReturnTypeRef));
                 break;
             }
         default:
diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/except.cxx b/bridges/source/cpp_uno/gcc3_ios_arm/except.cxx
index e023297..e21dce7 100644
--- a/bridges/source/cpp_uno/gcc3_ios_arm/except.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios_arm/except.cxx
@@ -17,7 +17,6 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-
 #include <dlfcn.h>
 #include <cxxabi.h>
 #include <boost/unordered_map.hpp>
diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/generate-snippets.pl b/bridges/source/cpp_uno/gcc3_ios_arm/generate-snippets.pl
index c89f2ed..b6ffc07 100755
--- a/bridges/source/cpp_uno/gcc3_ios_arm/generate-snippets.pl
+++ b/bridges/source/cpp_uno/gcc3_ios_arm/generate-snippets.pl
@@ -39,10 +39,10 @@ printf (".text\n");
 printf ("#if defined(__arm) || defined(__arm64)\n");
 
 printf ("\n");
-printf ("// Each codeSnippetX function stores into ip/x15 an address and branches to _privateSnippetExecutor\n");
-printf ("// The branch instruction is followed by two longs that ip/x15 points to:\n");
-printf ("// - the function index, as such and with the 0x80000000 bit set\n");
-printf ("//   (to indicate a hidden parameter for returning large values)\n");
+printf ("// Each codeSnippetX function stores into ip (arm64: x15) an address and branches to _privateSnippetExecutor\n");
+printf ("// The address is that following the branch instruction, containing two 32-bit ints:\n");
+printf ("// - the function index, as such or with the 0x80000000 bit set\n");
+printf ("//   (to indicate that a hidden parameter (arm64: x8) is used for returning large values)\n");
 printf ("// - the vtable offset\n");
 printf ("\n");
 
diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/helper.s b/bridges/source/cpp_uno/gcc3_ios_arm/helper.s
index 27c7c04..bf84f65 100644
--- a/bridges/source/cpp_uno/gcc3_ios_arm/helper.s
+++ b/bridges/source/cpp_uno/gcc3_ios_arm/helper.s
@@ -35,7 +35,7 @@ _privateSnippetExecutor:
     mov     r0, ip          // r0 points to functionoffset/vtable
     mov     r1, sp          // r1 points to this and params
                             // (see cpp2uno.cxx:codeSnippet())
-    stmfd   sp!, {r4,lr}    // save return address 
+    stmfd   sp!, {r4, lr}   // save return address
                             // (r4 pushed to preserve stack alignment)
     bl      _cpp_vtable_call
 
@@ -49,9 +49,20 @@ _privateSnippetExecutor:
 
 _privateSnippetExecutor:
 
-	// Not done yet, intentionally crash for now...
-    mov     x15, #0
-    ldr     x15, [x15]
+    stp     x6, x7, [sp, #-16]!
+    stp     x4, x5, [sp, #-16]!
+    stp     x2, x3, [sp, #-16]!
+    stp     x0, x1, [sp, #-16]!
+
+    mov     x0, x15
+    stp     x8, lr, [sp, #-16]!
+    mov     x1, sp
+
+    bl      _cpp_vtable_call
+
+    ldp     x8, lr, [sp, #0]
+    add     sp, sp, #80
+    ret     lr
 
 #else
     .text
diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/share.hxx b/bridges/source/cpp_uno/gcc3_ios_arm/share.hxx
index 37ae457..c719aa2 100644
--- a/bridges/source/cpp_uno/gcc3_ios_arm/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_ios_arm/share.hxx
@@ -47,8 +47,18 @@ namespace CPPU_CURRENT_NAMESPACE
 
 namespace arm
 {
-    enum armlimits { MAX_GPR_REGS = 4, MAX_FPR_REGS = 8 };
-    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
+    enum armlimits {
+#if defined(__arm)
+        MAX_GPR_REGS = 4,
+        MAX_FPR_REGS = 8
+#elif defined(__arm64)
+        MAX_GPR_REGS = 8,
+        MAX_FPR_REGS = 8
+#else
+#error wtf
+#endif
+    };
+    bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef );
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp-arm64.cxx b/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp-arm64.cxx
index 9b2c676..e3c9e81 100644
--- a/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp-arm64.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios_arm/uno2cpp-arm64.cxx
@@ -32,46 +32,23 @@ using namespace ::com::sun::star::uno;
 
 namespace arm
 {
-    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;
-    }
-
-#ifdef __ARM_PCS_VFP
-    bool is_float_only_struct(const typelib_TypeDescription * type)
+    bool is_hfa_struct(const typelib_TypeDescription * type)
     {
         const typelib_CompoundTypeDescription * p
             = reinterpret_cast< const typelib_CompoundTypeDescription * >(type);
+        if (p->nMembers >= 4)
+            return false;
         for (sal_Int32 i = 0; i < p->nMembers; ++i)
         {
-            if (p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_FLOAT &&
-                p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_DOUBLE)
+            if ((p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_FLOAT &&
+                 p->ppTypeRefs[i]->eTypeClass != typelib_TypeClass_DOUBLE) ||
+                p->ppTypeRefs[i]->eTypeClass != p->ppTypeRefs[0]->eTypeClass)
                 return false;
         }
         return true;
     }
-#endif
-    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
+
+    bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef )
     {
         if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
             return false;
@@ -81,15 +58,10 @@ namespace arm
             TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
 
             // A Composite Type not larger than 16 bytes is returned in x0, x1
-            // FIXME: what about the "complex struct" thing, is that relevant at all?
-            bool bRet = pTypeDescr->nSize > 16 || is_complex_struct(pTypeDescr);
+            bool bRet = pTypeDescr->nSize > 16;
 
-#ifdef __ARM_PCS_VFP
-            // In the VFP ABI, structs with only float/double values that fit in
-            // 16 bytes are returned in registers
-            if( pTypeDescr->nSize <= 16 && is_float_only_struct(pTypeDescr))
+            if (is_hfa_struct(pTypeDescr))
                 bRet = false;
-#endif
 
             TYPELIB_DANGER_RELEASE( pTypeDescr );
             return bRet;
@@ -98,174 +70,131 @@ namespace arm
     }
 }
 
-void MapReturn(sal_uInt32 r0, sal_uInt32 r1, typelib_TypeDescriptionReference * pReturnType, sal_uInt32* pRegisterReturn)
+void MapReturn(sal_uInt64 x0, sal_uInt64 x1, typelib_TypeDescriptionReference *pReturnType, sal_uInt64 *pRegisterReturn)
 {
     switch( pReturnType->eTypeClass )
     {
-        case typelib_TypeClass_HYPER:
-        case typelib_TypeClass_UNSIGNED_HYPER:
-            pRegisterReturn[1] = r1;
-        case typelib_TypeClass_LONG:
-        case typelib_TypeClass_UNSIGNED_LONG:
-        case typelib_TypeClass_ENUM:
-        case typelib_TypeClass_CHAR:
-        case typelib_TypeClass_SHORT:
-        case typelib_TypeClass_UNSIGNED_SHORT:
-        case typelib_TypeClass_BOOLEAN:
-        case typelib_TypeClass_BYTE:
-            pRegisterReturn[0] = r0;
-            break;
-        case typelib_TypeClass_FLOAT:
-#if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__) || defined(IOS))
-            pRegisterReturn[0] = r0;
-#else
-            register float fret asm("s0");
+    case typelib_TypeClass_HYPER:
+    case typelib_TypeClass_UNSIGNED_HYPER:
+        pRegisterReturn[1] = x1;
+        // fallthrough
+    case typelib_TypeClass_LONG:
+    case typelib_TypeClass_UNSIGNED_LONG:
+    case typelib_TypeClass_ENUM:
+    case typelib_TypeClass_CHAR:
+    case typelib_TypeClass_SHORT:
+    case typelib_TypeClass_UNSIGNED_SHORT:
+    case typelib_TypeClass_BOOLEAN:
+    case typelib_TypeClass_BYTE:
+        pRegisterReturn[0] = x0;
+        break;
+    case typelib_TypeClass_FLOAT:
+        register float fret asm("s0");
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wuninitialized"
-            *(float*)pRegisterReturn = fret;
+        *(float*)pRegisterReturn = fret;
 #pragma GCC diagnostic pop
-#endif
-            break;
-        case typelib_TypeClass_DOUBLE:
-#if !defined(__ARM_PCS_VFP) && (defined(__ARM_EABI__) || defined(__SOFTFP__) || defined(IOS))
-            pRegisterReturn[1] = r1;
-            pRegisterReturn[0] = r0;
-#else
-            register double dret asm("d0");
+        break;
+    case typelib_TypeClass_DOUBLE:
+        register double dret asm("d0");
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wuninitialized"
-            *(double*)pRegisterReturn = dret;
+        *(double*)pRegisterReturn = dret;
 #pragma GCC diagnostic pop
-#endif
-            break;
-        case typelib_TypeClass_STRUCT:
-        case typelib_TypeClass_EXCEPTION:
+        break;
+    case typelib_TypeClass_STRUCT:
+    case typelib_TypeClass_EXCEPTION:
+        if (!arm::return_in_x8(pReturnType))
         {
-            if (!arm::return_in_hidden_param(pReturnType))
-                pRegisterReturn[0] = r0;
-            break;
+            pRegisterReturn[0] = x0;
+            pRegisterReturn[1] = x1;
         }
-        default:
-            break;
+        break;
+    default:
+        break;
     }
 }
 
 namespace
 {
-//================================================================
-
-void callVirtualMethod(
-    void * pThis,
-    sal_Int32 nVtableIndex,
-    void * pRegisterReturn,
-    typelib_TypeDescriptionReference * pReturnType,
-    sal_uInt32 *pStack,
-    sal_uInt32 nStack,
-    sal_uInt32 *pGPR,
-    sal_uInt32 nGPR,
-    double *pFPR) __attribute__((noinline));
-
 void callVirtualMethod(
-    void * pThis,
+    void *pThis,
     sal_Int32 nVtableIndex,
-    void * pRegisterReturn,
-    typelib_TypeDescriptionReference * pReturnType,
-    sal_uInt32 *pStack,
-    sal_uInt32 nStack,
-    sal_uInt32 *pGPR,
-    sal_uInt32 nGPR,
-    double *pFPR)
+    void *pRegisterReturn,
+    typelib_TypeDescriptionReference *pReturnType,
+    sal_uInt64 *pStack,
+    int nStack,
+    sal_uInt64 *pGPR,
+    int nGPR,
+    double *pFPR,
+    int nFPR)
 {
-    abort(); // arm64 code not yet implemented
-
-    (void) pThis;
-    (void) nVtableIndex;
-    (void) pRegisterReturn;
-    (void) pReturnType;
-    (void) pStack;
-    (void) nStack;
-    (void) pGPR;
-    (void) nGPR;
-    (void) pFPR;
+    // never called
+    if (! pThis)
+        CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything("xxx"); // address something
+
+    if ( nStack )
+    {
+        // 16-bytes aligned
+        sal_uInt32 nStackBytes = ( ( nStack + 3 ) >> 2 ) * 16;
+        sal_uInt32 *stack = (sal_uInt32 *) alloca( nStackBytes );
+        memcpy( stack, pStack, nStackBytes );
+    }
+
+    assert( nGPR <= arm::MAX_GPR_REGS );
+    assert( nFPR <= arm::MAX_FPR_REGS );
+
+    sal_uInt64 pMethod = *((sal_uInt64*)pThis);
+    pMethod += 8 * nVtableIndex;
+    pMethod = *((sal_uInt64 *)pMethod);
+
+    // For value returned in registers
+    sal_uInt64 x0;
+    sal_uInt64 x1;
+
+  __asm__ __volatile__
+    (
+     "  ldp x0, x1, %[pgpr_0]\n"
+     "  ldp x2, x3, %[pgpr_2]\n"
+     "  ldp x4, x5, %[pgpr_4]\n"
+     "  ldp x6, x7, %[pgpr_6]\n"
+     "  ldr x8, %[pregisterreturn]\n"
+     "  ldp d0, d1, %[pfpr_0]\n"
+     "  ldp d2, d3, %[pfpr_2]\n"
+     "  ldp d4, d5, %[pfpr_4]\n"
+     "  ldp d6, d7, %[pfpr_6]\n"
+     "  blr %[pmethod]\n"
+     "  str x0, %[x0]\n"
+     "  str x1, %[x1]\n"
+     : [x0]"=m" (x0), [x1]"=m" (x1)
+     : [pgpr_0]"m" (pGPR[0]),
+       [pgpr_2]"m" (pGPR[2]),
+       [pgpr_4]"m" (pGPR[4]),
+       [pgpr_6]"m" (pGPR[6]),
+       [pregisterreturn]"m" (pRegisterReturn),
+       [pfpr_0]"m" (pFPR[0]),
+       [pfpr_2]"m" (pFPR[2]),
+       [pfpr_4]"m" (pFPR[4]),
+       [pfpr_6]"m" (pFPR[6]),
+       [pmethod]"r" (pMethod)
+     : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7"
+     );
+
+  MapReturn(x0, x1, pReturnType, (sal_uInt64 *) pRegisterReturn);
 }
 }
 
-#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
         if ( nr < arm::MAX_GPR_REGS ) \
-                pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
         else \
-                *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+                *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
 
-#ifdef __ARM_EABI__
-#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart ) \
-        if ( (nr < arm::MAX_GPR_REGS) && (nr % 2) ) \
-        { \
-                ++nr; \
-        } \
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
         if ( nr < arm::MAX_GPR_REGS ) \
-        { \
                 pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
-                pGPR[nr++] = *(reinterpret_cast<sal_uInt32 *>( pSV ) + 1); \
-        } \
         else \
-    { \
-        if ( (pDS - pStart) % 2) \
-                { \
-                    ++pDS; \
-                } \
-                *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[0]; \
-                *pDS++ = reinterpret_cast<sal_uInt32 *>( pSV )[1]; \
-    }
-#else
-#define INSERT_INT64( pSV, nr, pGPR, pDS, pStart ) \
-        INSERT_INT32( pSV, nr, pGPR, pDS ) \
-        INSERT_INT32( ((sal_uInt32*)pSV)+1, nr, pGPR, pDS )
-#endif
-
-#ifdef __ARM_PCS_VFP
-// Since single and double arguments share the same register bank the filling of the
-// registers is not always linear. Single values go to the first available single register,
-// while doubles need to have an 8 byte alignment, so only go into double registers starting
-// at every other single register. For ex a float, double, float sequence will fill registers
-// s0, d1, and s1, actually corresponding to the linear order s0,s1, d1.
-//
-// These use the single/double register array and counters and ignore the pGPR argument
-// nSR and nDR are the number of single and double precision registers that are no longer
-// available
-#define INSERT_FLOAT( pSV, nr, pGPR, pDS ) \
-        if (nSR % 2 == 0) {\
-            nSR = 2*nDR; \
-        }\
-        if ( nSR < arm::MAX_FPR_REGS*2 ) {\
-                pSPR[nSR++] = *reinterpret_cast<float *>( pSV ); \
-                if ((nSR % 2 == 1) && (nSR > 2*nDR)) {\
-                    nDR++; \
-                }\
-        }\
-        else \
-        {\
-                *pDS++ = *reinterpret_cast<float *>( pSV );\
-        }
-#define INSERT_DOUBLE( pSV, nr, pGPR, pDS, pStart ) \
-        if ( nDR < arm::MAX_FPR_REGS ) { \
-                pFPR[nDR++] = *reinterpret_cast<double *>( pSV ); \
-        }\
-        else\
-        {\
-            if ( (pDS - pStart) % 2) \
-                { \
-                    ++pDS; \
-                } \
-            *(double *)pDS = *reinterpret_cast<double *>( pSV );\
-            pDS += 2;\
-        }
-#else
-#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
-        INSERT_INT32( pSV, nr, pGPR, pDS )
-
-#define INSERT_DOUBLE( pSV, nr, pFPR, pDS, pStart ) \
-        INSERT_INT64( pSV, nr, pGPR, pDS, pStart )
-#endif
+                *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
 
 #define INSERT_INT16( pSV, nr, pGPR, pDS ) \
         if ( nr < arm::MAX_GPR_REGS ) \
@@ -279,8 +208,16 @@ void callVirtualMethod(
         else \
                 *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
 
+#define INSERT_DOUBLE( pSV, nr, pFPR, pDS ) \
+        if ( nr < arm::MAX_FPR_REGS ) \
+                pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
+        else \
+                *pDS++ = *reinterpret_cast<double *>( pSV );
+
+#define INSERT_FLOAT( pSV, nr, pFPR, pDS ) \
+        INSERT_DOUBLE( pSV, nr, pGPR, pDS )
+
 namespace {
-//=======================================================================
 static void cpp_call(
     bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
     bridges::cpp_uno::shared::VtableSlot aVtableSlot,
@@ -288,21 +225,16 @@ static void cpp_call(
     sal_Int32 nParams, typelib_MethodParameter * pParams,
     void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
 {
-    // max space for: [complex ret ptr], values|ptr ...
-    sal_uInt32 * pStack = (sal_uInt32 *)__builtin_alloca(
-        sizeof(sal_Int32) + ((nParams+2) * sizeof(sal_Int64)) );
-    sal_uInt32 * pStackStart = pStack;
+    // max space for: values|ptr ...
+    sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+2) * sizeof(sal_Int64) );
+    sal_uInt64 * pStackStart = pStack;
 
-    sal_uInt32 pGPR[arm::MAX_GPR_REGS];
-    sal_uInt32 nGPR = 0;
+    sal_uInt64 pGPR[arm::MAX_GPR_REGS];
+    int nGPR = 0;
 
-    // storage and counters for single and double precision VFP registers
+    // storage and counter for SIMD/FP registers
     double pFPR[arm::MAX_FPR_REGS];
-#ifdef __ARM_PCS_VFP
-    sal_uInt32 nDR = 0;
-    float *pSPR = reinterpret_cast< float *>(&pFPR);
-    sal_uInt32 nSR = 0;
-#endif
+    int nFPR = 0;
 
     // return
     typelib_TypeDescription * pReturnTypeDescr = 0;
@@ -311,22 +243,16 @@ static void cpp_call(
 
     void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
 
-    bool bSimpleReturn = true;
     if (pReturnTypeDescr)
     {
-        if (arm::return_in_hidden_param( pReturnTypeRef ) )
-            bSimpleReturn = false;
-
-        if (bSimpleReturn)
+        if (!arm::return_in_x8( pReturnTypeRef ) )
             pCppReturn = pUnoReturn; // direct way for simple types
         else
         {
-            // complex return via ptr
+            // complex return via x8
             pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
-                    ? __builtin_alloca( pReturnTypeDescr->nSize )
+                    ? alloca( pReturnTypeDescr->nSize )
                     : pUnoReturn); // direct way
-
-            INSERT_INT32( &pCppReturn, nGPR, pGPR, pStack );
         }
     }
     // push this
@@ -335,15 +261,16 @@ static void cpp_call(
     INSERT_INT32( &pAdjustedThisPtr, nGPR, pGPR, pStack );
 
     // stack space
-    OSL_ENSURE( sizeof(void *) == sizeof(sal_Int32), "### unexpected size!" );
     // args
-    void ** pCppArgs  = (void **)alloca( 3 * sizeof(void *) * nParams );
+    void ** pCppArgs  = (void **)alloca( sizeof(void *) * nParams );
+
     // indices of values this have to be converted (interface conversion cpp<=>uno)
-    sal_Int32 * pTempIndices = (sal_Int32 *)(pCppArgs + nParams);
+    int * pTempIndices = (int *)alloca( sizeof(int) * nParams );
+
     // type descriptions for reconversions
-    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
+    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(void *) * nParams );
 
-    sal_Int32 nTempIndices   = 0;
+    sal_Int32 nTempIndices = 0;
 
     for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
     {
@@ -353,7 +280,6 @@ static void cpp_call(
 
         if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
         {
-//            uno_copyAndConvertData( pCppArgs[nPos] = pStack, pUnoArgs[nPos],
             uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
                 pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
 
@@ -361,17 +287,11 @@ static void cpp_call(
             {
             case typelib_TypeClass_HYPER:
             case typelib_TypeClass_UNSIGNED_HYPER:
-
-                SAL_INFO( "bridges.ios", "hyper is " << pCppArgs[nPos] );
-
-                INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart );
+                INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
                 break;
             case typelib_TypeClass_LONG:
             case typelib_TypeClass_UNSIGNED_LONG:
             case typelib_TypeClass_ENUM:
-
-                SAL_INFO( "bridges.ios", "long is " << pCppArgs[nPos] );
-
                 INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
                 break;
             case typelib_TypeClass_SHORT:
@@ -384,10 +304,10 @@ static void cpp_call(
                 INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
                 break;
             case typelib_TypeClass_FLOAT:
-                INSERT_FLOAT( pCppArgs[nPos], nGPR, pGPR, pStack );
+                INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack );
                 break;
             case typelib_TypeClass_DOUBLE:
-                INSERT_DOUBLE( pCppArgs[nPos], nGPR, pGPR, pStack, pStackStart );
+                INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
                 break;
             default:
                 break;
@@ -436,7 +356,7 @@ static void cpp_call(
             pStackStart,
             (pStack - pStackStart),
             pGPR, nGPR,
-            pFPR);
+            pFPR, nFPR);
 
         // NO exception occurred...
         *ppUnoExc = 0;
@@ -476,8 +396,6 @@ static void cpp_call(
     }
     catch (...)
     {
-//        __asm__ __volatile__ ("sub sp, sp, #2048\n");
-
         // fill uno exception
         CPPU_CURRENT_NAMESPACE::fillUnoException( abi::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
 


More information about the Libreoffice-commits mailing list