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

jan Iversen jani at libreoffice.org
Thu Sep 21 12:08:47 UTC 2017


 bridges/Library_cpp_uno.mk                        |    2 
 bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx |  560 ----------------------
 bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx  |  532 --------------------
 bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx       |  529 ++++++++++++++++++++
 bridges/source/cpp_uno/gcc3_ios/share.hxx         |    8 
 bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx |  557 ---------------------
 bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx       |  527 ++++++++++++++++++++
 7 files changed, 1055 insertions(+), 1660 deletions(-)

New commits:
commit 0dedbd2040a10098c6079443e21d1949ff384c14
Author: jan Iversen <jani at libreoffice.org>
Date:   Thu Sep 21 11:17:35 2017 +0200

    iOS, change bridges to 64bit and reduce
    
    Changed __i386 to not __arm64
    iOS either compiles for arm64 (production) or x86_64 (simulator)
    
    add common parts to cpp2uno and uno2cpp
    
    Change-Id: I059f3cc23bb658d6d53dbf2bf4aa6634eeac9662

diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
index 993342baea58..7c85b051f27d 100644
--- a/bridges/Library_cpp_uno.mk
+++ b/bridges/Library_cpp_uno.mk
@@ -11,7 +11,7 @@ $(eval $(call gb_Library_Library,$(gb_CPPU_ENV)_uno))
 
 ifeq ($(OS),IOS)
 bridges_SELECTED_BRIDGE := gcc3_ios
-bridge_noopt_objects := cpp2uno cpp2uno-arm64 cpp2uno-i386 except uno2cpp uno2cpp-arm64 uno2cpp-i386
+bridge_noopt_objects := cpp2uno except uno2cpp uno2cpp-i386
 
 else ifeq ($(CPUNAME),ARM)
 
diff --git a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx b/bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx
deleted file mode 100644
index 64ac9ed38b2b..000000000000
--- a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-arm64.cxx
+++ /dev/null
@@ -1,560 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifdef __arm64
-
-// For iOS devices (64-bit ARM). Originally a copy of
-// ../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
-// done. Which is sad. But then the whole bridges/source/cpp_uno is
-// full of copy/paste. So I continue in that tradition...
-
-#include <com/sun/star/uno/RuntimeException.hpp>
-#include <sal/log.hxx>
-#include <uno/data.h>
-#include <typelib/typedescription.hxx>
-
-#include "bridge.hxx"
-#include "cppinterfaceproxy.hxx"
-#include "types.hxx"
-#include "vtablefactory.hxx"
-
-#include "share.hxx"
-
-extern "C" {
-    extern int nFunIndexes, nVtableOffsets;
-    extern int codeSnippets[];
-}
-
-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,
-        void ** pCallStack,
-        sal_Int64 * pRegisterReturn /* space for register return */ )
-    {
-        // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
-        char *pTopStack = (char *)pCallStack;
-        char *pFloatRegs = pTopStack + 2;
-        char *pGPRegs =  pTopStack + (2+8)*8;
-        char *pStackedArgs = pTopStack + (2+8+8)*8;
-
-        int nGPR = 0;
-        int nFPR = 0;
-
-        // return
-        typelib_TypeDescription * pReturnTypeDescr = 0;
-        if (pReturnTypeRef)
-            TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
-
-        void * pUnoReturn = 0;
-        // complex return ptr: if != 0 && != pUnoReturn, reconversion need
-        void * pCppReturn = 0;
-
-        if (pReturnTypeDescr)
-        {
-            if (!arm::return_in_x8(pReturnTypeRef))
-                pUnoReturn = pRegisterReturn; // direct way for simple types
-            else // complex return via x8
-            {
-                pCppReturn = pCallStack[0];
-
-                pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
-                    pReturnTypeDescr )
-                        ? alloca( pReturnTypeDescr->nSize )
-                        : pCppReturn); // direct way
-            }
-        }
-
-        // Skip 'this'
-        pGPRegs += 8;
-        nGPR++;
-
-        // Parameters
-        void ** pUnoArgs = (void **)alloca( sizeof(void *) * nParams );
-        void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams );
-
-        // Indices of values this have to be converted (interface conversion
-        // cpp<=>uno)
-        int * pTempIndices = (sal_Int32 *)alloca( sizeof(int) * nParams);
-
-        // Type descriptions for reconversions
-        typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(typelib_TypeDescription *) * nParams);
-
-        int nTempIndices = 0;
-
-        for ( int nPos = 0; nPos < nParams; ++nPos )
-        {
-            const typelib_MethodParameter & rParam = pParams[nPos];
-            typelib_TypeDescription * pParamTypeDescr = 0;
-            TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
-
-            if (!rParam.bOut &&
-                bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
-            {
-                if (nFPR < 8 && (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT ||
-                                 pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE))
-                {
-                    pCppArgs[nPos] = pUnoArgs[nPos] = pFloatRegs;
-                    pFloatRegs += 8;
-                    nFPR++;
-                }
-                else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
-                {
-                    if ((pStackedArgs - pTopStack) % 4)
-                        pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
-                    pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
-                    pStackedArgs += 4;
-                }
-                else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE)
-                {
-                    if ((pStackedArgs - pTopStack) % 8)
-                        pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
-                    pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
-                    pStackedArgs += 8;
-                }
-                else if (nGPR < 8)
-                {
-                    pCppArgs[nPos] = pUnoArgs[nPos] = pGPRegs;
-                    pGPRegs += 8;
-                    nGPR++;
-                }
-                else
-                switch (pParamTypeDescr->eTypeClass)
-                {
-                    case typelib_TypeClass_HYPER:
-                    case typelib_TypeClass_UNSIGNED_HYPER:
-                        if ((pStackedArgs - pTopStack) % 8)
-                            pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
-                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
-                        pStackedArgs += 8;
-                        break;
-                    case typelib_TypeClass_ENUM:
-                    case typelib_TypeClass_LONG:
-                    case typelib_TypeClass_UNSIGNED_LONG:
-                        if ((pStackedArgs - pTopStack) % 4)
-                            pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
-                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
-                        pStackedArgs += 4;
-                        break;
-                    case typelib_TypeClass_CHAR:
-                    case typelib_TypeClass_SHORT:
-                    case typelib_TypeClass_UNSIGNED_SHORT:
-                        if ((pStackedArgs - pTopStack) % 2)
-                            pStackedArgs += 1;
-                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
-                        pStackedArgs += 2;
-                        break;
-                    case typelib_TypeClass_BOOLEAN:
-                    case typelib_TypeClass_BYTE:
-                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
-                        pStackedArgs += 1;
-                        break;
-                    default:
-                        assert(!"should not happen");
-                        break;
-                }
-                // no longer needed
-                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-            }
-            else // ptr to complex value | ref
-            {
-                if (nGPR < 8)
-                {
-                    pCppArgs[nPos] = *(void **)pGPRegs;
-                    pGPRegs += 8;
-                }
-                else
-                {
-                    if ((pStackedArgs - pTopStack) % 8)
-                        pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
-                    pCppArgs[nPos] = pStackedArgs;
-                    pStackedArgs += 8;
-                }
-
-                if (! rParam.bIn) // is pure out
-                {
-                    // uno out is unconstructed mem!
-                    pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
-                    pTempIndices[nTempIndices] = nPos;
-                    // will be released at reconversion
-                    ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
-                }
-                // is in/inout
-                else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
-                {
-                    uno_copyAndConvertData( pUnoArgs[nPos] =
-                        alloca( pParamTypeDescr->nSize ),
-                        pCppArgs[nPos], pParamTypeDescr,
-                        pThis->getBridge()->getCpp2Uno() );
-                    pTempIndices[nTempIndices] = nPos; // has to be reconverted
-                    // will be released at reconversion
-                    ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
-                }
-                else // direct way
-                {
-                    pUnoArgs[nPos] = pCppArgs[nPos];
-                    // no longer needed
-                    TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-                }
-            }
-        }
-
-        // ExceptionHolder
-        uno_Any aUnoExc; // Any will be constructed by callee
-        uno_Any * pUnoExc = &aUnoExc;
-
-        // invoke uno dispatch call
-        (*pThis->getUnoI()->pDispatcher)(
-          pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
-
-        // in case an exception occurred...
-        if (pUnoExc)
-        {
-            // destruct temporary in/inout params
-            for ( ; nTempIndices--; )
-            {
-                int nIndex = pTempIndices[nTempIndices];
-
-                if (pParams[nIndex].bIn) // is in/inout => was constructed
-                    uno_destructData( pUnoArgs[nIndex],
-                        ppTempParamTypeDescr[nTempIndices], 0 );
-                TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
-            }
-            if (pReturnTypeDescr)
-                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-
-            CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc,
-                pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
-            // is here for dummy
-            return typelib_TypeClass_VOID;
-        }
-        else // else no exception occurred...
-        {
-            // temporary params
-            for ( ; nTempIndices--; )
-            {
-                int nIndex = pTempIndices[nTempIndices];
-                typelib_TypeDescription * pParamTypeDescr =
-                    ppTempParamTypeDescr[nTempIndices];
-
-                if (pParams[nIndex].bOut) // inout/out
-                {
-                    // convert and assign
-                    uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
-                        cpp_release );
-                    uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex],
-                        pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
-                }
-                // destroy temp uno param
-                uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
-
-                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-            }
-            // return
-            if (pCppReturn) // has complex return
-            {
-                if (pUnoReturn != pCppReturn) // needs reconversion
-                {
-                    uno_copyAndConvertData( pCppReturn, pUnoReturn,
-                        pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
-                    // destroy temp uno return
-                    uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
-                }
-                *(void **)pRegisterReturn = pCppReturn;
-            }
-            if (pReturnTypeDescr)
-            {
-                typelib_TypeClass eRet =
-                    (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
-                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-                return eRet;
-            }
-            else
-                return typelib_TypeClass_VOID;
-        }
-    }
-
-
-    static typelib_TypeClass cpp_mediate( sal_Int32 nFunctionIndex,
-                                          sal_Int32 nVtableOffset,
-                                          void ** pCallStack,
-                                          sal_Int64 * pRegisterReturn )
-    {
-        // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
-        // _this_ ptr is patched cppu_XInterfaceProxy object
-        void *pThis = pCallStack[2 + 8];
-
-        pThis = static_cast< char * >(pThis) - nVtableOffset;
-        bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
-            bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
-                pThis);
-
-        typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
-
-        // determine called method
-        assert( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex );
-
-        if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
-        {
-            throw RuntimeException( "illegal vtable index!", (XInterface *)pCppI );
-        }
-
-        sal_Int32 nMemberPos =
-            pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
-        assert( nMemberPos < pTypeDescr->nAllMembers );
-
-        TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
-
-        typelib_TypeClass eRet;
-        switch (aMemberDescr.get()->eTypeClass)
-        {
-        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
-        {
-            if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
-                nFunctionIndex)
-            {
-                // is GET method
-                eRet = cpp2uno_call(
-                    pCppI, aMemberDescr.get(),
-                    ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
-                    0, 0, // no params
-                    pCallStack, pRegisterReturn );
-            }
-            else
-            {
-                // is SET method
-                typelib_MethodParameter aParam;
-                aParam.pTypeRef =
-                    ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
-                aParam.bIn      = sal_True;
-                aParam.bOut     = sal_False;
-
-                eRet = cpp2uno_call(
-                    pCppI, aMemberDescr.get(),
-                    0, // indicates void return
-                    1, &aParam,
-                    pCallStack, pRegisterReturn );
-            }
-            break;
-        }
-        case typelib_TypeClass_INTERFACE_METHOD:
-        {
-            // is METHOD
-            switch (nFunctionIndex)
-            {
-            case 1: // acquire()
-                pCppI->acquireProxy(); // non virtual call!
-                eRet = typelib_TypeClass_VOID;
-                break;
-            case 2: // release()
-                pCppI->releaseProxy(); // non virtual call!
-                eRet = typelib_TypeClass_VOID;
-                break;
-            case 0: // queryInterface() opt
-            {
-                typelib_TypeDescription * pTD = 0;
-                TYPELIB_DANGER_GET(&pTD,
-                    reinterpret_cast<Type *>(pCallStack[2])->getTypeLibType());
-                if (pTD)
-                {
-                    XInterface * pInterface = 0;
-                    (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
-                        pCppI->getBridge()->getCppEnv(),
-                        (void **)&pInterface, pCppI->getOid().pData,
-                        (typelib_InterfaceTypeDescription *)pTD );
-
-                    if (pInterface)
-                    {
-                        ::uno_any_construct(
-                            reinterpret_cast< uno_Any * >( pCallStack[0] ),
-                            &pInterface, pTD, cpp_acquire );
-                        pInterface->release();
-                        TYPELIB_DANGER_RELEASE( pTD );
-                        *(void **)pRegisterReturn = pCallStack[0];
-                        eRet = typelib_TypeClass_ANY;
-                        break;
-                    }
-                    TYPELIB_DANGER_RELEASE( pTD );
-                }
-            } // else perform queryInterface()
-            SAL_FALLTHROUGH;
-            default:
-                eRet = cpp2uno_call(
-                    pCppI, aMemberDescr.get(),
-                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
-                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
-                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
-                    pCallStack, pRegisterReturn );
-            }
-            break;
-        }
-        default:
-        {
-            throw RuntimeException( "no member description found!", (XInterface *)pCppI );
-        }
-        }
-
-        return eRet;
-    }
-}
-
-/**
- * is called on incoming vtable calls
- * (called by asm snippets)
- */
-
-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 );
-
-    switch( aType )
-    {
-        case typelib_TypeClass_BOOLEAN:
-        case typelib_TypeClass_BYTE:
-            nRegReturn = (unsigned long)(*(unsigned char *)&nRegReturn);
-            break;
-        case typelib_TypeClass_CHAR:
-        case typelib_TypeClass_UNSIGNED_SHORT:
-        case typelib_TypeClass_SHORT:
-            nRegReturn = (unsigned long)(*(unsigned short *)&nRegReturn);
-            break;
-        case typelib_TypeClass_ENUM:
-        case typelib_TypeClass_UNSIGNED_LONG:
-        case typelib_TypeClass_LONG:
-            nRegReturn = (unsigned long)(*(unsigned int *)&nRegReturn);
-            break;
-        case typelib_TypeClass_VOID:
-        default:
-            break;
-    }
-
-    return nRegReturn;
-}
-
-namespace
-{
-    unsigned char *codeSnippet(const typelib_InterfaceTypeDescription *type,
-                               const typelib_TypeDescription *member,
-                               sal_Int32 functionIndex,
-                               sal_Int32 vtableOffset)
-    {
-        assert(functionIndex < nFunIndexes);
-        if (!(functionIndex < nFunIndexes))
-            return NULL;
-
-        assert(vtableOffset < nVtableOffsets);
-        if (!(vtableOffset < nVtableOffsets))
-            return NULL;
-
-        // The codeSnippets table is indexed by functionIndex and vtableOffset
-
-        int index = functionIndex*nVtableOffsets + vtableOffset;
-        unsigned char *result = ((unsigned char *) &codeSnippets) + codeSnippets[index];
-
-        SAL_INFO( "bridges.ios", "codeSnippet(" << OUString(type->aBase.pTypeName) << "::" << OUString(member->pTypeName) << "): [" << functionIndex << "," << vtableOffset << "]=" << (void *) result << " (" << std::hex << ((int*)result)[0] << "," << ((int*)result)[1] << "," << ((int*)result)[2] << "," << ((int*)result)[3] << ")");
-
-        return result;
-    }
-}
-
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
-{
-    return static_cast< Slot * >(block) + 2;
-}
-
-std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
-    sal_Int32 slotCount)
-{
-    return (slotCount + 2) * sizeof (Slot);
-}
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::initializeBlock(
-    void * block, sal_Int32 slotCount, sal_Int32,
-    typelib_InterfaceTypeDescription *)
-{
-    Slot * slots = mapBlockToVtable(block);
-    slots[-2].fn = 0;
-    slots[-1].fn = 0;
-    return slots + slotCount;
-}
-
-unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-    Slot ** slots,
-    unsigned char * code,
-    typelib_InterfaceTypeDescription const * type,
-    sal_Int32 functionOffset,
-    sal_Int32 functionCount,
-    sal_Int32 vtableOffset)
-{
-    (*slots) -= functionCount;
-    Slot * s = *slots;
-    for (sal_Int32 i = 0; i < type->nMembers; ++i)
-    {
-        typelib_TypeDescription * member = 0;
-        TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
-        assert(member != 0);
-        switch (member->eTypeClass)
-        {
-            case typelib_TypeClass_INTERFACE_ATTRIBUTE:
-            {
-                typelib_InterfaceAttributeTypeDescription *pAttrTD =
-                    reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( member );
-
-                // Getter:
-                (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
-
-                // Setter:
-                if (!pAttrTD->bReadOnly)
-                {
-                    (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
-                }
-                break;
-            }
-            case typelib_TypeClass_INTERFACE_METHOD:
-            {
-                (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
-                break;
-            }
-        default:
-            assert(false);
-            break;
-        }
-        TYPELIB_DANGER_RELEASE(member);
-    }
-    return code;
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx b/bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx
deleted file mode 100644
index 6a3689ca6c33..000000000000
--- a/bridges/source/cpp_uno/gcc3_ios/cpp2uno-i386.cxx
+++ /dev/null
@@ -1,532 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifdef __i386
-
-// For the iOS emulator (i386). Basically a copy of
-// ../gcc3_macosx_intel/cpp2uno.cxx with some cleanups and necessary
-// changes: To match what we do on iOS devices, we don't do any
-// dynamic code generation on the emulator either (even if it as such
-// wouldn't be prohibited).
-
-// No attempts at factoring out the large amounts of more or less
-// common code in this and cpp2uno-arm.cxx have been done. Which is
-// sad. But then the whole bridges/source/cpp_uno is full of
-// copy/paste. So I continue in that tradition...
-
-#include <com/sun/star/uno/RuntimeException.hpp>
-#include <sal/log.hxx>
-#include <uno/data.h>
-#include <typelib/typedescription.hxx>
-
-#include "bridge.hxx"
-#include "cppinterfaceproxy.hxx"
-#include "types.hxx"
-#include "vtablefactory.hxx"
-
-#include "share.hxx"
-
-extern "C" {
-    extern int nFunIndexes, nVtableOffsets;
-    extern int codeSnippets[];
-}
-
-using namespace ::com::sun::star::uno;
-
-namespace
-{
-
-void cpp2uno_call(
-    bridges::cpp_uno::shared::CppInterfaceProxy * pThis,
-    const typelib_TypeDescription * pMemberTypeDescr,
-    typelib_TypeDescriptionReference * pReturnTypeRef, // 0 indicates void return
-    sal_Int32 nParams, typelib_MethodParameter * pParams,
-    void ** pCallStack,
-    void * pReturnValue )
-{
-    // pCallStack: ret, [return ptr], this, params
-    char * pCppStack = (char *)(pCallStack +1);
-
-    // return
-    typelib_TypeDescription * pReturnTypeDescr = 0;
-    if (pReturnTypeRef)
-        TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
-
-    void * pUnoReturn = 0;
-    void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
-
-    if (pReturnTypeDescr)
-    {
-        // xxx todo: test PolyStructy<STRUCT<long>> foo()
-        if (CPPU_CURRENT_NAMESPACE::isSimpleReturnType( pReturnTypeDescr ))
-        {
-            pUnoReturn = pReturnValue; // direct way for simple types
-        }
-        else // complex return via ptr (pCppReturn)
-        {
-            pCppReturn = *(void **)pCppStack;
-            pCppStack += sizeof(void *);
-            pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
-                              pReturnTypeDescr )
-                          ? alloca( pReturnTypeDescr->nSize )
-                          : pCppReturn); // direct way
-        }
-    }
-    // pop this
-    pCppStack += sizeof( void* );
-
-    // stack space
-    static_assert(sizeof(void *) == sizeof(sal_Int32), "### unexpected size!");
-    // parameters
-    void ** pUnoArgs = (void **)alloca( 4 * sizeof(void *) * nParams );
-    void ** pCppArgs = pUnoArgs + nParams;
-    // indices of values this have to be converted (interface conversion cpp<=>uno)
-    sal_Int32 * pTempIndices = (sal_Int32 *)(pUnoArgs + (2 * nParams));
-    // type descriptions for reconversions
-    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)(pUnoArgs + (3 * nParams));
-
-    sal_Int32 nTempIndices   = 0;
-
-    for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
-    {
-        const typelib_MethodParameter & rParam = pParams[nPos];
-        typelib_TypeDescription * pParamTypeDescr = 0;
-        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
-
-        if (!rParam.bOut
-            && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
-            // value
-        {
-            pCppArgs[nPos] = pCppStack;
-            pUnoArgs[nPos] = pCppStack;
-            switch (pParamTypeDescr->eTypeClass)
-            {
-            case typelib_TypeClass_HYPER:
-            case typelib_TypeClass_UNSIGNED_HYPER:
-            case typelib_TypeClass_DOUBLE:
-                pCppStack += sizeof(sal_Int32); // extra long
-                SAL_FALLTHROUGH;
-            default:
-                break;
-            }
-            // no longer needed
-            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-        }
-        else // ptr to complex value | ref
-        {
-            pCppArgs[nPos] = *(void **)pCppStack;
-
-            if (! rParam.bIn) // is pure out
-            {
-                // uno out is unconstructed mem!
-                pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
-                pTempIndices[nTempIndices] = nPos;
-                // will be released at reconversion
-                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
-            }
-            // is in/inout
-            else if (bridges::cpp_uno::shared::relatesToInterfaceType(
-                         pParamTypeDescr ))
-            {
-                uno_copyAndConvertData( pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize ),
-                                        *(void **)pCppStack, pParamTypeDescr,
-                                        pThis->getBridge()->getCpp2Uno() );
-                pTempIndices[nTempIndices] = nPos; // has to be reconverted
-                // will be released at reconversion
-                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
-            }
-            else // direct way
-            {
-                pUnoArgs[nPos] = *(void **)pCppStack;
-                // no longer needed
-                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-            }
-        }
-        pCppStack += sizeof(sal_Int32); // standard parameter length
-    }
-
-    // ExceptionHolder
-    uno_Any aUnoExc; // Any will be constructed by callee
-    uno_Any * pUnoExc = &aUnoExc;
-
-    // invoke uno dispatch call
-    (*pThis->getUnoI()->pDispatcher)(
-        pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
-
-    // in case an exception occurred...
-    if (pUnoExc)
-    {
-        // destruct temporary in/inout params
-        for ( ; nTempIndices--; )
-        {
-            sal_Int32 nIndex = pTempIndices[nTempIndices];
-
-            if (pParams[nIndex].bIn) // is in/inout => was constructed
-                uno_destructData( pUnoArgs[nIndex], ppTempParamTypeDescr[nTempIndices], 0 );
-            TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
-        }
-        if (pReturnTypeDescr)
-            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-
-        CPPU_CURRENT_NAMESPACE::raiseException(
-            &aUnoExc, pThis->getBridge()->getUno2Cpp() );
-            // has to destruct the any
-    }
-    else // else no exception occurred...
-    {
-        // temporary params
-        for ( ; nTempIndices--; )
-        {
-            sal_Int32 nIndex = pTempIndices[nTempIndices];
-            typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
-
-            if (pParams[nIndex].bOut) // inout/out
-            {
-                // convert and assign
-                uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
-                uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex], pParamTypeDescr,
-                                        pThis->getBridge()->getUno2Cpp() );
-            }
-            // destroy temp uno param
-            uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
-
-            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-        }
-        // return
-        if (pCppReturn) // has complex return
-        {
-            if (pUnoReturn != pCppReturn) // needs reconversion
-            {
-                uno_copyAndConvertData( pCppReturn, pUnoReturn, pReturnTypeDescr,
-                                        pThis->getBridge()->getUno2Cpp() );
-                // destroy temp uno return
-                uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
-            }
-            if (pReturnValue != pCppReturn) {
-                // complex return ptr is set to eax if return value
-                // is not transferred via eax[/edx]:
-                *static_cast< void ** >(pReturnValue) = pCppReturn;
-            }
-        }
-        if (pReturnTypeDescr)
-        {
-            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-        }
-    }
-}
-
-
-extern "C" void cpp_vtable_call(
-    int nFunctionIndex, int nVtableOffset, void** pCallStack,
-    void * pReturnValue )
-{
-    static_assert(sizeof(sal_Int32)==sizeof(void *), "### unexpected!");
-
-    // pCallStack: ret adr, [ret *], this, params
-    void * pThis;
-    if( nFunctionIndex & 0x80000000 )
-    {
-        nFunctionIndex &= 0x7fffffff;
-        pThis = pCallStack[2];
-    }
-    else
-    {
-        pThis = pCallStack[1];
-    }
-    pThis = static_cast< char * >(pThis) - nVtableOffset;
-    bridges::cpp_uno::shared::CppInterfaceProxy * pCppI
-        = bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
-            pThis);
-
-    typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
-
-    SAL_INFO( "bridges.ios", "cpp_vtable_call: pCallStack=[" <<
-              std::hex << pCallStack[0] << "," << pCallStack[1] << "," << pCallStack[2] << ",...]" <<
-              ", pThis=" << pThis << ", pCppI=" << pCppI <<
-              std::dec << ", nFunctionIndex=" << nFunctionIndex << ", nVtableOffset=" << nVtableOffset );
-
-    SAL_INFO( "bridges.ios", "name=" << OUString::unacquired(&pTypeDescr->aBase.pTypeName) );
-
-    assert( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex );
-
-    if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
-    {
-        throw RuntimeException( "illegal vtable index!", (XInterface *)pThis );
-    }
-
-    // determine called method
-    sal_Int32 nMemberPos = pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
-
-    assert( nMemberPos < pTypeDescr->nAllMembers );
-
-    TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
-
-    SAL_INFO( "bridges.ios", "Calling " << OUString::unacquired(&aMemberDescr.get()->pTypeName) );
-
-    switch (aMemberDescr.get()->eTypeClass)
-    {
-    case typelib_TypeClass_INTERFACE_ATTRIBUTE:
-    {
-        if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex)
-        {
-            // is GET method
-            cpp2uno_call(
-                pCppI, aMemberDescr.get(),
-                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
-                0, 0, // no params
-                pCallStack, pReturnValue );
-        }
-        else
-        {
-            // is SET method
-            typelib_MethodParameter aParam;
-            aParam.pTypeRef =
-                ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
-            aParam.bIn      = sal_True;
-            aParam.bOut     = sal_False;
-
-            cpp2uno_call(
-                pCppI, aMemberDescr.get(),
-                0, // indicates void return
-                1, &aParam,
-                pCallStack, pReturnValue );
-        }
-        break;
-    }
-    case typelib_TypeClass_INTERFACE_METHOD:
-    {
-        // is METHOD
-        switch (nFunctionIndex)
-        {
-        case 1: // acquire()
-            pCppI->acquireProxy(); // non virtual call!
-            break;
-        case 2: // release()
-            pCppI->releaseProxy(); // non virtual call!
-            break;
-        case 0: // queryInterface() opt
-        {
-            typelib_TypeDescription * pTD = 0;
-            TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pCallStack[3] )->getTypeLibType() );
-            if (pTD)
-            {
-                XInterface * pInterface = 0;
-                (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
-                    pCppI->getBridge()->getCppEnv(),
-                    (void **)&pInterface, pCppI->getOid().pData,
-                    (typelib_InterfaceTypeDescription *)pTD );
-
-                if (pInterface)
-                {
-                    ::uno_any_construct(
-                        reinterpret_cast< uno_Any * >( pCallStack[1] ),
-                        &pInterface, pTD, cpp_acquire );
-                    pInterface->release();
-                    TYPELIB_DANGER_RELEASE( pTD );
-                    *static_cast< void ** >(pReturnValue) = pCallStack[1];
-                    break;
-                }
-                TYPELIB_DANGER_RELEASE( pTD );
-            }
-        } // else perform queryInterface()
-        SAL_FALLTHROUGH;
-        default:
-            cpp2uno_call(
-                pCppI, aMemberDescr.get(),
-                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
-                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
-                ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
-                pCallStack, pReturnValue );
-        }
-        break;
-    }
-    default:
-    {
-        throw RuntimeException( "no member description found!", (XInterface *)pThis );
-    }
-    }
-}
-
-typedef enum { privateSnippetExecutorGeneral, privateSnippetExecutorVoid, privateSnippetExecutorHyper, privateSnippetExecutorFloat, privateSnippetExecutorDouble, privateSnippetExecutorClass } snippetExecutorKind;
-
-static const char * snippetExecutorClassName(
-    snippetExecutorKind exec)
-{
-    switch (exec) {
-    case privateSnippetExecutorGeneral: return "General";
-    case privateSnippetExecutorVoid: return "Void";
-    case privateSnippetExecutorHyper: return "Hyper";
-    case privateSnippetExecutorFloat: return "Float";
-    case privateSnippetExecutorDouble: return "Double";
-    case privateSnippetExecutorClass: return "Class";
-    default:
-        abort();
-    }
-}
-
-unsigned char * codeSnippet(
-    sal_Int32 functionIndex, sal_Int32 vtableOffset,
-    typelib_TypeDescriptionReference * pReturnTypeRef)
-{
-    assert(functionIndex < nFunIndexes);
-    if (!(functionIndex < nFunIndexes))
-        return NULL;
-
-    assert(vtableOffset < nVtableOffsets);
-    if (!(vtableOffset < nVtableOffsets))
-        return NULL;
-
-    snippetExecutorKind exec;
-    bool bHasHiddenParam = false;
-    if (pReturnTypeRef == 0) {
-        exec = privateSnippetExecutorVoid;
-    }
-    else {
-        switch (pReturnTypeRef->eTypeClass) {
-        case typelib_TypeClass_VOID:
-            exec = privateSnippetExecutorVoid;
-            break;
-        case typelib_TypeClass_HYPER:
-        case typelib_TypeClass_UNSIGNED_HYPER:
-            exec = privateSnippetExecutorHyper;
-            break;
-        case typelib_TypeClass_FLOAT:
-            exec = privateSnippetExecutorFloat;
-            break;
-        case typelib_TypeClass_DOUBLE:
-            exec = privateSnippetExecutorDouble;
-            break;
-        case typelib_TypeClass_STRUCT:
-        case typelib_TypeClass_EXCEPTION: {
-            typelib_TypeDescription * pReturnTypeDescr = 0;
-            TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
-            bool const bSimpleReturnStruct =
-                CPPU_CURRENT_NAMESPACE::isSimpleReturnType(pReturnTypeDescr);
-            sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
-            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-            if (bSimpleReturnStruct && nRetSize <= 8) {
-                exec = privateSnippetExecutorGeneral; // fills eax
-                if (nRetSize > 4)
-                    exec = privateSnippetExecutorHyper; // fills eax/edx
-                break;
-            }
-        }
-        SAL_FALLTHROUGH;
-        case typelib_TypeClass_STRING:
-        case typelib_TypeClass_TYPE:
-        case typelib_TypeClass_SEQUENCE:
-        case typelib_TypeClass_INTERFACE:
-        case typelib_TypeClass_ANY:
-            bHasHiddenParam = 1;
-            exec = privateSnippetExecutorClass;
-            break;
-        default:
-            exec = privateSnippetExecutorGeneral;
-            break;
-        }
-    }
-
-    // The codeSnippets table is indexed by functionIndex,
-    // vtableOffset, exec and the has-hidden-param flag
-
-    int index = functionIndex*nVtableOffsets*6*2 + vtableOffset*6*2 + exec*2 + bHasHiddenParam;
-    unsigned char *result = ((unsigned char *) &codeSnippets) + codeSnippets[index];
-
-    SAL_INFO( "bridges.ios", "codeSnippet: [" <<
-              functionIndex << "," << vtableOffset << "," << snippetExecutorClassName(exec) << "," << bHasHiddenParam << "]=" <<
-              (void *) result);
-
-    return result;
-}
-
-}
-
-struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
-{
-    return static_cast< Slot * >(block) + 2;
-}
-
-std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
-    sal_Int32 slotCount)
-{
-    return (slotCount + 2) * sizeof (Slot);
-}
-
-bridges::cpp_uno::shared::VtableFactory::Slot *
-bridges::cpp_uno::shared::VtableFactory::initializeBlock(
-    void * block, sal_Int32 slotCount, sal_Int32,
-    typelib_InterfaceTypeDescription *)
-{
-    Slot * slots = mapBlockToVtable(block);
-    slots[-2].fn = 0;
-    slots[-1].fn = 0;
-    return slots + slotCount;
-}
-
-unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
-    Slot ** slots, unsigned char * code,
-    typelib_InterfaceTypeDescription const * type, sal_Int32 functionOffset,
-    sal_Int32 functionCount, sal_Int32 vtableOffset)
-{
-    (*slots) -= functionCount;
-    Slot * s = *slots;
-    for (sal_Int32 i = 0; i < type->nMembers; ++i) {
-        typelib_TypeDescription * member = 0;
-        TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
-        assert(member != 0);
-        switch (member->eTypeClass) {
-        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
-            // Getter:
-            (s++)->fn = codeSnippet(
-                functionOffset++, vtableOffset,
-                reinterpret_cast< typelib_InterfaceAttributeTypeDescription * >(
-                    member)->pAttributeTypeRef);
-            // Setter:
-            if (!reinterpret_cast<
-                typelib_InterfaceAttributeTypeDescription * >(
-                    member)->bReadOnly)
-            {
-                (s++)->fn = codeSnippet(
-                    functionOffset++, vtableOffset,
-                    0 /* indicates VOID */);
-            }
-            break;
-
-        case typelib_TypeClass_INTERFACE_METHOD:
-            (s++)->fn = codeSnippet(
-                functionOffset++, vtableOffset,
-                reinterpret_cast< typelib_InterfaceMethodTypeDescription * >(
-                    member)->pReturnTypeRef);
-            break;
-
-        default:
-            assert(false);
-            break;
-        }
-        TYPELIB_DANGER_RELEASE(member);
-    }
-    return code;
-}
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
index 46726a8b30ba..6773486e9c9c 100644
--- a/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios/cpp2uno.cxx
@@ -17,11 +17,536 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
-// If we eventually get around to factoring out stuff from
-// cpp2uno-arm.cxx and cpp2uno-i386.cxx here, this is where to put it.
+#include <com/sun/star/uno/RuntimeException.hpp>
+#include <sal/log.hxx>
+#include <uno/data.h>
+#include <typelib/typedescription.hxx>
 
+#include "bridge.hxx"
+#include "cppinterfaceproxy.hxx"
+#include "types.hxx"
 #include "vtablefactory.hxx"
 
+#include "share.hxx"
+
+extern "C" {
+    extern int nFunIndexes, nVtableOffsets;
+    extern int codeSnippets[];
+}
+
+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,
+        void ** pCallStack,
+        sal_Int64 * pRegisterReturn /* space for register return */ )
+    {
+        // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
+        char *pTopStack = (char *)pCallStack;
+        char *pFloatRegs = pTopStack + 2;
+        char *pGPRegs =  pTopStack + (2+8)*8;
+        char *pStackedArgs = pTopStack + (2+8+8)*8;
+
+        int nGPR = 0;
+        int nFPR = 0;
+
+        // return
+        typelib_TypeDescription * pReturnTypeDescr = 0;
+        if (pReturnTypeRef)
+            TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+
+        void * pUnoReturn = 0;
+        // complex return ptr: if != 0 && != pUnoReturn, reconversion need
+        void * pCppReturn = 0;
+
+        if (pReturnTypeDescr)
+        {
+            if (!arm::return_in_x8(pReturnTypeRef))
+                pUnoReturn = pRegisterReturn; // direct way for simple types
+            else // complex return via x8
+            {
+                pCppReturn = pCallStack[0];
+
+                pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(
+                    pReturnTypeDescr )
+                        ? alloca( pReturnTypeDescr->nSize )
+                        : pCppReturn); // direct way
+            }
+        }
+
+        // Skip 'this'
+        pGPRegs += 8;
+        nGPR++;
+
+        // Parameters
+        void ** pUnoArgs = (void **)alloca( sizeof(void *) * nParams );
+        void ** pCppArgs = (void **)alloca( sizeof(void *) * nParams );
+
+        // Indices of values this have to be converted (interface conversion
+        // cpp<=>uno)
+        int * pTempIndices = (sal_Int32 *)alloca( sizeof(int) * nParams);
+
+        // Type descriptions for reconversions
+        typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(typelib_TypeDescription *) * nParams);
+
+        int nTempIndices = 0;
+
+        for ( int nPos = 0; nPos < nParams; ++nPos )
+        {
+            const typelib_MethodParameter & rParam = pParams[nPos];
+            typelib_TypeDescription * pParamTypeDescr = 0;
+            TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+            if (!rParam.bOut &&
+                bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+            {
+                if (nFPR < 8 && (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT ||
+                                 pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE))
+                {
+                    pCppArgs[nPos] = pUnoArgs[nPos] = pFloatRegs;
+                    pFloatRegs += 8;
+                    nFPR++;
+                }
+                else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_FLOAT)
+                {
+                    if ((pStackedArgs - pTopStack) % 4)
+                        pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
+                    pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+                    pStackedArgs += 4;
+                }
+                else if (pParamTypeDescr->eTypeClass == typelib_TypeClass_DOUBLE)
+                {
+                    if ((pStackedArgs - pTopStack) % 8)
+                        pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
+                    pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+                    pStackedArgs += 8;
+                }
+                else if (nGPR < 8)
+                {
+                    pCppArgs[nPos] = pUnoArgs[nPos] = pGPRegs;
+                    pGPRegs += 8;
+                    nGPR++;
+                }
+                else
+                switch (pParamTypeDescr->eTypeClass)
+                {
+                    case typelib_TypeClass_HYPER:
+                    case typelib_TypeClass_UNSIGNED_HYPER:
+                        if ((pStackedArgs - pTopStack) % 8)
+                            pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
+                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+                        pStackedArgs += 8;
+                        break;
+                    case typelib_TypeClass_ENUM:
+                    case typelib_TypeClass_LONG:
+                    case typelib_TypeClass_UNSIGNED_LONG:
+                        if ((pStackedArgs - pTopStack) % 4)
+                            pStackedArgs += 4 - ((pStackedArgs - pTopStack) % 4);
+                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+                        pStackedArgs += 4;
+                        break;
+                    case typelib_TypeClass_CHAR:
+                    case typelib_TypeClass_SHORT:
+                    case typelib_TypeClass_UNSIGNED_SHORT:
+                        if ((pStackedArgs - pTopStack) % 2)
+                            pStackedArgs += 1;
+                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+                        pStackedArgs += 2;
+                        break;
+                    case typelib_TypeClass_BOOLEAN:
+                    case typelib_TypeClass_BYTE:
+                        pCppArgs[nPos] = pUnoArgs[nPos] = pStackedArgs;
+                        pStackedArgs += 1;
+                        break;
+                    default:
+                        assert(!"should not happen");
+                        break;
+                }
+                // no longer needed
+                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+            }
+            else // ptr to complex value | ref
+            {
+                if (nGPR < 8)
+                {
+                    pCppArgs[nPos] = *(void **)pGPRegs;
+                    pGPRegs += 8;
+                }
+                else
+                {
+                    if ((pStackedArgs - pTopStack) % 8)
+                        pStackedArgs += 8 - ((pStackedArgs - pTopStack) % 8);
+                    pCppArgs[nPos] = pStackedArgs;
+                    pStackedArgs += 8;
+                }
+
+                if (! rParam.bIn) // is pure out
+                {
+                    // uno out is unconstructed mem!
+                    pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize );
+                    pTempIndices[nTempIndices] = nPos;
+                    // will be released at reconversion
+                    ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+                }
+                // is in/inout
+                else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+                {
+                    uno_copyAndConvertData( pUnoArgs[nPos] =
+                        alloca( pParamTypeDescr->nSize ),
+                        pCppArgs[nPos], pParamTypeDescr,
+                        pThis->getBridge()->getCpp2Uno() );
+                    pTempIndices[nTempIndices] = nPos; // has to be reconverted
+                    // will be released at reconversion
+                    ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+                }
+                else // direct way
+                {
+                    pUnoArgs[nPos] = pCppArgs[nPos];
+                    // no longer needed
+                    TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+                }
+            }
+        }
+
+        // ExceptionHolder
+        uno_Any aUnoExc; // Any will be constructed by callee
+        uno_Any * pUnoExc = &aUnoExc;
+
+        // invoke uno dispatch call
+        (*pThis->getUnoI()->pDispatcher)(
+          pThis->getUnoI(), pMemberTypeDescr, pUnoReturn, pUnoArgs, &pUnoExc );
+
+        // in case an exception occurred...
+        if (pUnoExc)
+        {
+            // destruct temporary in/inout params
+            for ( ; nTempIndices--; )
+            {
+                int nIndex = pTempIndices[nTempIndices];
+
+                if (pParams[nIndex].bIn) // is in/inout => was constructed
+                    uno_destructData( pUnoArgs[nIndex],
+                        ppTempParamTypeDescr[nTempIndices], 0 );
+                TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
+            }
+            if (pReturnTypeDescr)
+                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+
+            CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc,
+                pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
+            // is here for dummy
+            return typelib_TypeClass_VOID;
+        }
+        else // else no exception occurred...
+        {
+            // temporary params
+            for ( ; nTempIndices--; )
+            {
+                int nIndex = pTempIndices[nTempIndices];
+                typelib_TypeDescription * pParamTypeDescr =
+                    ppTempParamTypeDescr[nTempIndices];
+
+                if (pParams[nIndex].bOut) // inout/out
+                {
+                    // convert and assign
+                    uno_destructData( pCppArgs[nIndex], pParamTypeDescr,
+                        cpp_release );
+                    uno_copyAndConvertData( pCppArgs[nIndex], pUnoArgs[nIndex],
+                        pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+                }
+                // destroy temp uno param
+                uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 );
+
+                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+            }
+            // return
+            if (pCppReturn) // has complex return
+            {
+                if (pUnoReturn != pCppReturn) // needs reconversion
+                {
+                    uno_copyAndConvertData( pCppReturn, pUnoReturn,
+                        pReturnTypeDescr, pThis->getBridge()->getUno2Cpp() );
+                    // destroy temp uno return
+                    uno_destructData( pUnoReturn, pReturnTypeDescr, 0 );
+                }
+                *(void **)pRegisterReturn = pCppReturn;
+            }
+            if (pReturnTypeDescr)
+            {
+                typelib_TypeClass eRet =
+                    (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
+                TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+                return eRet;
+            }
+            else
+                return typelib_TypeClass_VOID;
+        }
+    }
+
+    static typelib_TypeClass cpp_mediate( sal_Int32 nFunctionIndex,
+                                          sal_Int32 nVtableOffset,
+                                          void ** pCallStack,
+                                          sal_Int64 * pRegisterReturn )
+    {
+        // pCallStack: x8, lr, d0..d7, x0..x7, rest of params originally on stack
+        // _this_ ptr is patched cppu_XInterfaceProxy object
+        void *pThis = pCallStack[2 + 8];
+
+        pThis = static_cast< char * >(pThis) - nVtableOffset;
+        bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
+            bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy(
+                pThis);
+
+        typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
+
+        // determine called method
+        assert( nFunctionIndex < pTypeDescr->nMapFunctionIndexToMemberIndex );
+
+        if (nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex)
+        {
+            throw RuntimeException( "illegal vtable index!", (XInterface *)pCppI );
+        }
+
+        sal_Int32 nMemberPos =
+            pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
+        assert( nMemberPos < pTypeDescr->nAllMembers );
+
+        TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
+
+        typelib_TypeClass eRet;
+        switch (aMemberDescr.get()->eTypeClass)
+        {
+        case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+        {
+            if (pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] ==
+                nFunctionIndex)
+            {
+                // is GET method
+                eRet = cpp2uno_call(
+                    pCppI, aMemberDescr.get(),
+                    ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef,
+                    0, 0, // no params
+                    pCallStack, pRegisterReturn );
+            }
+            else
+            {
+                // is SET method
+                typelib_MethodParameter aParam;
+                aParam.pTypeRef =
+                    ((typelib_InterfaceAttributeTypeDescription *)aMemberDescr.get())->pAttributeTypeRef;
+                aParam.bIn      = sal_True;
+                aParam.bOut     = sal_False;
+
+                eRet = cpp2uno_call(
+                    pCppI, aMemberDescr.get(),
+                    0, // indicates void return
+                    1, &aParam,
+                    pCallStack, pRegisterReturn );
+            }
+            break;
+        }
+        case typelib_TypeClass_INTERFACE_METHOD:
+        {
+            // is METHOD
+            switch (nFunctionIndex)
+            {
+            case 1: // acquire()
+                pCppI->acquireProxy(); // non virtual call!
+                eRet = typelib_TypeClass_VOID;
+                break;
+            case 2: // release()
+                pCppI->releaseProxy(); // non virtual call!
+                eRet = typelib_TypeClass_VOID;
+                break;
+            case 0: // queryInterface() opt
+            {
+                typelib_TypeDescription * pTD = 0;
+                TYPELIB_DANGER_GET(&pTD,
+                    reinterpret_cast<Type *>(pCallStack[2])->getTypeLibType());
+                if (pTD)
+                {
+                    XInterface * pInterface = 0;
+                    (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)(
+                        pCppI->getBridge()->getCppEnv(),
+                        (void **)&pInterface, pCppI->getOid().pData,
+                        (typelib_InterfaceTypeDescription *)pTD );
+
+                    if (pInterface)
+                    {
+                        ::uno_any_construct(
+                            reinterpret_cast< uno_Any * >( pCallStack[0] ),
+                            &pInterface, pTD, cpp_acquire );
+                        pInterface->release();
+                        TYPELIB_DANGER_RELEASE( pTD );
+                        *(void **)pRegisterReturn = pCallStack[0];
+                        eRet = typelib_TypeClass_ANY;
+                        break;
+                    }
+                    TYPELIB_DANGER_RELEASE( pTD );
+                }
+            } // else perform queryInterface()
+            SAL_FALLTHROUGH;
+            default:
+                eRet = cpp2uno_call(
+                    pCppI, aMemberDescr.get(),
+                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pReturnTypeRef,
+                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->nParams,
+                    ((typelib_InterfaceMethodTypeDescription *)aMemberDescr.get())->pParams,
+                    pCallStack, pRegisterReturn );
+            }
+            break;
+        }
+        default:
+        {
+            throw RuntimeException( "no member description found!", (XInterface *)pCppI );
+        }
+        }
+
+        return eRet;
+    }
+}
+
+/**
+ * is called on incoming vtable calls
+ * (called by asm snippets)
+ */
+
+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 );
+
+    switch( aType )
+    {
+        case typelib_TypeClass_BOOLEAN:
+        case typelib_TypeClass_BYTE:
+            nRegReturn = (unsigned long)(*(unsigned char *)&nRegReturn);
+            break;
+        case typelib_TypeClass_CHAR:
+        case typelib_TypeClass_UNSIGNED_SHORT:
+        case typelib_TypeClass_SHORT:
+            nRegReturn = (unsigned long)(*(unsigned short *)&nRegReturn);
+            break;
+        case typelib_TypeClass_ENUM:
+        case typelib_TypeClass_UNSIGNED_LONG:
+        case typelib_TypeClass_LONG:
+            nRegReturn = (unsigned long)(*(unsigned int *)&nRegReturn);
+            break;
+        case typelib_TypeClass_VOID:
+        default:
+            break;
+    }
+
+    return nRegReturn;
+}
+
+#ifdef __arm64
+namespace
+{
+    unsigned char *codeSnippet(const typelib_InterfaceTypeDescription *type,
+                               const typelib_TypeDescription *member,
+                               sal_Int32 functionIndex,
+                               sal_Int32 vtableOffset)
+    {
+        assert(functionIndex < nFunIndexes);
+        if (!(functionIndex < nFunIndexes))
+            return NULL;
+
+        assert(vtableOffset < nVtableOffsets);
+        if (!(vtableOffset < nVtableOffsets))
+            return NULL;
+
+        // The codeSnippets table is indexed by functionIndex and vtableOffset
+
+        int index = functionIndex*nVtableOffsets + vtableOffset;
+        unsigned char *result = ((unsigned char *) &codeSnippets) + codeSnippets[index];
+
+        SAL_INFO( "bridges.ios", "codeSnippet(" << OUString(type->aBase.pTypeName) << "::" << OUString(member->pTypeName) << "): [" << functionIndex << "," << vtableOffset << "]=" << (void *) result << " (" << std::hex << ((int*)result)[0] << "," << ((int*)result)[1] << "," << ((int*)result)[2] << "," << ((int*)result)[3] << ")");
+
+        return result;
+    }
+}
+
+struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
+{
+    return static_cast< Slot * >(block) + 2;
+}
+
+std::size_t bridges::cpp_uno::shared::VtableFactory::getBlockSize(
+    sal_Int32 slotCount)
+{
+    return (slotCount + 2) * sizeof (Slot);
+}
+
+bridges::cpp_uno::shared::VtableFactory::Slot *
+bridges::cpp_uno::shared::VtableFactory::initializeBlock(
+    void * block, sal_Int32 slotCount, sal_Int32,
+    typelib_InterfaceTypeDescription *)
+{
+    Slot * slots = mapBlockToVtable(block);
+    slots[-2].fn = 0;
+    slots[-1].fn = 0;
+    return slots + slotCount;
+}
+
+unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
+    Slot ** slots,
+    unsigned char * code,
+    typelib_InterfaceTypeDescription const * type,
+    sal_Int32 functionOffset,
+    sal_Int32 functionCount,
+    sal_Int32 vtableOffset)
+{
+    (*slots) -= functionCount;
+    Slot * s = *slots;
+    for (sal_Int32 i = 0; i < type->nMembers; ++i)
+    {
+        typelib_TypeDescription * member = 0;
+        TYPELIB_DANGER_GET(&member, type->ppMembers[i]);
+        assert(member != 0);
+        switch (member->eTypeClass)
+        {
+            case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+            {
+                typelib_InterfaceAttributeTypeDescription *pAttrTD =
+                    reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( member );
+
+                // Getter:
+                (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
+
+                // Setter:
+                if (!pAttrTD->bReadOnly)
+                {
+                    (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
+                }
+                break;
+            }
+            case typelib_TypeClass_INTERFACE_METHOD:
+            {
+                (s++)->fn = codeSnippet( type, member, functionOffset++, vtableOffset );
+                break;
+            }
+        default:
+            assert(false);
+            break;
+        }
+        TYPELIB_DANGER_RELEASE(member);
+    }
+    return code;
+}
+#endif
+
+
 void bridges::cpp_uno::shared::VtableFactory::flushCode(
     unsigned char const *, unsigned char const *)
 {
diff --git a/bridges/source/cpp_uno/gcc3_ios/share.hxx b/bridges/source/cpp_uno/gcc3_ios/share.hxx
index 589f4ba7a174..bcddcdb1f807 100644
--- a/bridges/source/cpp_uno/gcc3_ios/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_ios/share.hxx
@@ -49,19 +49,11 @@ namespace CPPU_CURRENT_NAMESPACE
 
 namespace arm
 {
-#if defined(__arm)
-    enum armlimits {
-        MAX_GPR_REGS = 4,
-        MAX_FPR_REGS = 8
-    };
-    bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
-#elif defined(__arm64)
     enum armlimits {
         MAX_GPR_REGS = 8,
         MAX_FPR_REGS = 8
     };
     bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef );
-#endif
 }
 
 #endif
diff --git a/bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx b/bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx
deleted file mode 100644
index 7915fa7a9513..000000000000
--- a/bridges/source/cpp_uno/gcc3_ios/uno2cpp-arm64.cxx
+++ /dev/null
@@ -1,557 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifdef __arm64
-
-#include <com/sun/star/uno/RuntimeException.hpp>
-
-#include "bridge.hxx"
-#include "types.hxx"
-#include "unointerfaceproxy.hxx"
-#include "vtables.hxx"
-
-#include "share.hxx"
-
-using namespace ::com::sun::star::uno;
-
-namespace arm
-{
-    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) ||
-                p->ppTypeRefs[i]->eTypeClass != p->ppTypeRefs[0]->eTypeClass)
-                return false;
-        }
-        return true;
-    }
-
-    bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef )
-    {
-        if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
-            return false;
-        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 x0, x1
-            bool bRet = pTypeDescr->nSize > 16;
-
-            if (is_hfa_struct(pTypeDescr))
-                bRet = false;
-
-            TYPELIB_DANGER_RELEASE( pTypeDescr );
-            return bRet;
-        }
-        return true;
-    }
-}
-
-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] = x1;
-        SAL_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;
-#pragma GCC diagnostic pop
-        break;
-    case typelib_TypeClass_DOUBLE:
-        register double dret asm("d0");
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wuninitialized"
-        *(double*)pRegisterReturn = dret;
-#pragma GCC diagnostic pop
-        break;
-    case typelib_TypeClass_STRUCT:
-    case typelib_TypeClass_EXCEPTION:
-        if (!arm::return_in_x8(pReturnType))
-        {
-            pRegisterReturn[0] = x0;
-            pRegisterReturn[1] = x1;
-        }
-        break;
-    default:
-        break;
-    }
-}
-
-namespace
-{
-void callVirtualMethod(
-    void *pThis,
-    sal_Int32 nVtableIndex,
-    void *pRegisterReturn,
-    typelib_TypeDescriptionReference *pReturnType,
-    sal_uInt64 *pStack,
-    int nStack,
-    sal_uInt64 *pGPR,
-    double *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 );
-    }
-
-    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_INT64( pSV, nr, pGPR, pDS ) \
-        if ( nr < arm::MAX_GPR_REGS ) \
-                pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
-        else \
-                *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
-
-#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
-        if ( nr < arm::MAX_GPR_REGS ) \
-                pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
-        else \
-                *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
-
-#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
-        if ( nr < arm::MAX_GPR_REGS ) \
-                pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
-        else \
-                *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
-
-#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
-        if ( nr < arm::MAX_GPR_REGS ) \
-                pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
-        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,
-    typelib_TypeDescriptionReference * pReturnTypeRef,
-    sal_Int32 nParams, typelib_MethodParameter * pParams,
-    void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
-{
-    // max space for: values|ptr ...
-    sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+2) * sizeof(sal_Int64) );
-    sal_uInt64 * pStackStart = pStack;
-
-    sal_uInt64 pGPR[arm::MAX_GPR_REGS];
-    int nGPR = 0;
-
-    // storage and counter for SIMD/FP registers
-    double pFPR[arm::MAX_FPR_REGS];
-    int nFPR = 0;
-
-    // return
-    typelib_TypeDescription * pReturnTypeDescr = 0;
-    TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
-    assert( pReturnTypeDescr);
-
-    void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
-
-    if (pReturnTypeDescr)
-    {
-        if (!arm::return_in_x8( pReturnTypeRef ) )
-            pCppReturn = pUnoReturn; // direct way for simple types
-        else
-        {
-            // complex return via x8
-            pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
-                    ? alloca( pReturnTypeDescr->nSize )
-                    : pUnoReturn); // direct way
-        }
-    }
-    // push this
-    void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
-        + aVtableSlot.offset;
-    INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
-
-    // stack space
-    // args
-    void ** pCppArgs  = (void **)alloca( sizeof(void *) * nParams );
-
-    // indices of values this have to be converted (interface conversion cpp<=>uno)
-    int * pTempIndices = (int *)alloca( sizeof(int) * nParams );
-
-    // type descriptions for reconversions
-    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(void *) * nParams );
-
-    sal_Int32 nTempIndices = 0;
-
-    for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
-    {
-        const typelib_MethodParameter & rParam = pParams[nPos];
-        typelib_TypeDescription * pParamTypeDescr = 0;
-        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
-
-        if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
-        {
-            uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
-                pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
-
-            switch (pParamTypeDescr->eTypeClass)
-            {
-            case typelib_TypeClass_HYPER:
-            case typelib_TypeClass_UNSIGNED_HYPER:
-                INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
-                break;
-            case typelib_TypeClass_LONG:
-            case typelib_TypeClass_UNSIGNED_LONG:
-            case typelib_TypeClass_ENUM:
-                INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
-                break;
-            case typelib_TypeClass_SHORT:
-            case typelib_TypeClass_CHAR:
-            case typelib_TypeClass_UNSIGNED_SHORT:
-                INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
-                break;
-            case typelib_TypeClass_BOOLEAN:
-            case typelib_TypeClass_BYTE:
-                INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
-                break;
-            case typelib_TypeClass_FLOAT:
-                INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack );
-                break;
-            case typelib_TypeClass_DOUBLE:
-                INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
-                break;
-            default:
-                break;
-            }
-            // no longer needed
-            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-        }
-        else // ptr to complex value | ref
-        {
-            if (! rParam.bIn) // is pure out
-            {
-                // cpp out is constructed mem, uno out is not!
-                uno_constructData(
-                    pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
-                    pParamTypeDescr );
-                pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
-                // will be released at reconversion
-                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
-            }
-            // is in/inout
-            else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
-            {
-                uno_copyAndConvertData(
-                    pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
-                    pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
-
-                pTempIndices[nTempIndices] = nPos; // has to be reconverted
-                // will be released at reconversion
-                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
-            }
-            else // direct way
-            {
-                pCppArgs[nPos] = pUnoArgs[nPos];
-                // no longer needed
-                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-            }
-            INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
-        }
-    }
-
-    assert( nGPR <= arm::MAX_GPR_REGS );
-    assert( nFPR <= arm::MAX_FPR_REGS );
-
-    try
-    {
-        callVirtualMethod(
-            pAdjustedThisPtr, aVtableSlot.index,
-            pCppReturn, pReturnTypeRef,
-            pStackStart,
-            (pStack - pStackStart),
-            pGPR,
-            pFPR);
-
-        // NO exception occurred...
-        *ppUnoExc = 0;
-
-        // reconvert temporary params
-        for ( ; nTempIndices--; )
-        {
-            sal_Int32 nIndex = pTempIndices[nTempIndices];
-            typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
-
-            if (pParams[nIndex].bIn)
-            {
-                if (pParams[nIndex].bOut) // inout
-                {
-                    uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
-                    uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
-                                            pThis->getBridge()->getCpp2Uno() );
-                }
-            }
-            else // pure out
-            {
-                uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
-                                        pThis->getBridge()->getCpp2Uno() );
-            }
-            // destroy temp cpp param => cpp: every param was constructed
-            uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
-
-            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
-        }
-        // return value
-        if (pCppReturn && pUnoReturn != pCppReturn)
-        {
-            uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
-                                    pThis->getBridge()->getCpp2Uno() );
-            uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
-        }
-    }
-    catch (...)
-    {
-        // fill uno exception
-        CPPU_CURRENT_NAMESPACE::fillUnoException( abi::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
-
-        // temporary params
-        for ( ; nTempIndices--; )
-        {
-            sal_Int32 nIndex = pTempIndices[nTempIndices];
-            // destroy temp cpp param => cpp: every param was constructed
-            uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
-            TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
-        }
-
-        // return type
-        if (pReturnTypeDescr)
-            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
-    }
-}
-}
-
-namespace bridges { namespace cpp_uno { namespace shared {
-
-void unoInterfaceProxyDispatch(
-    uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
-    void * pReturn, void * pArgs[], uno_Any ** ppException )
-{
-    // is my surrogate
-    bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
-          = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
-#if OSL_DEBUG_LEVEL > 0
-    typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
-#endif
-
-    switch (pMemberDescr->eTypeClass)
-    {
-    case typelib_TypeClass_INTERFACE_ATTRIBUTE:
-    {
-#if OSL_DEBUG_LEVEL > 0
-        // determine vtable call index
-        sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
-        assert( nMemberPos < pTypeDescr->nAllMembers && "### member pos out of range!");
-#endif
-
-        VtableSlot aVtableSlot(
-            getVtableSlot(
-            reinterpret_cast<typelib_InterfaceAttributeTypeDescription const *>
-              (pMemberDescr)));
-
-        if (pReturn)
-        {
-            // dependent dispatch
-            cpp_call(
-                pThis, aVtableSlot,
-                ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef,
-                0, 0, // no params
-                pReturn, pArgs, ppException );
-        }
-        else
-        {
-            // is SET
-            typelib_MethodParameter aParam;
-            aParam.pTypeRef =
-                ((typelib_InterfaceAttributeTypeDescription *)pMemberDescr)->pAttributeTypeRef;
-            aParam.bIn      = sal_True;
-            aParam.bOut     = sal_False;
-
-            typelib_TypeDescriptionReference * pReturnTypeRef = 0;
-            OUString aVoidName("void");
-            typelib_typedescriptionreference_new(
-                &pReturnTypeRef, typelib_TypeClass_VOID, aVoidName.pData );
-
-            // dependent dispatch
-            aVtableSlot.index += 1;
-            cpp_call(
-                pThis, aVtableSlot, // get, then set method
-                pReturnTypeRef,
-                1, &aParam,
-                pReturn, pArgs, ppException );
-
-            typelib_typedescriptionreference_release( pReturnTypeRef );
-        }
-
-        break;
-    }
-    case typelib_TypeClass_INTERFACE_METHOD:
-    {
-#if OSL_DEBUG_LEVEL > 0
-        // determine vtable call index
-        sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription *)pMemberDescr)->nPosition;
-        assert(nMemberPos < pTypeDescr->nAllMembers && "### member pos out of range!");
-#endif
-
-        VtableSlot aVtableSlot(
-            getVtableSlot(
-            reinterpret_cast<typelib_InterfaceMethodTypeDescription const *>
-              (pMemberDescr)));
-
-        switch (aVtableSlot.index)
-        {
-            // standard calls
-        case 1: // acquire uno interface
-            (*pUnoI->acquire)( pUnoI );
-            *ppException = 0;
-            break;
-        case 2: // release uno interface
-            (*pUnoI->release)( pUnoI );
-            *ppException = 0;
-            break;
-        case 0: // queryInterface() opt
-        {
-            typelib_TypeDescription * pTD = 0;
-            TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( pArgs[0] )->getTypeLibType() );
-            if (pTD)
-            {
-                uno_Interface * pInterface = 0;
-                (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
-                    pThis->getBridge()->getUnoEnv(),
-                    (void **)&pInterface, pThis->oid.pData, (typelib_InterfaceTypeDescription *)pTD );
-
-                if (pInterface)
-                {
-                    ::uno_any_construct(
-                        reinterpret_cast< uno_Any * >( pReturn ),
-                        &pInterface, pTD, 0 );
-                    (*pInterface->release)( pInterface );
-                    TYPELIB_DANGER_RELEASE( pTD );
-                    *ppException = 0;
-                    break;
-                }
-                TYPELIB_DANGER_RELEASE( pTD );
-            }
-        } // else perform queryInterface()
-        SAL_FALLTHROUGH;
-        default:
-            // dependent dispatch
-            cpp_call(
-                pThis, aVtableSlot,
-                ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pReturnTypeRef,
-                ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->nParams,
-                ((typelib_InterfaceMethodTypeDescription *)pMemberDescr)->pParams,
-                pReturn, pArgs, ppException );
-        }
-        break;
-    }
-    default:
-    {
-        ::com::sun::star::uno::RuntimeException aExc(
-            "illegal member type description!",
-            ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
-
-        Type const & rExcType = cppu::UnoType<decltype(aExc)>::get();
-        // binary identical null reference
-        ::uno_type_any_construct( *ppException, &aExc, rExcType.getTypeLibType(), 0 );
-    }
-    }
-}
-
-} } }
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx
index 17bd59583737..6d2c82fbe0d4 100644
--- a/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_ios/uno2cpp.cxx
@@ -17,6 +17,8 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <com/sun/star/uno/RuntimeException.hpp>
+
 #include "bridge.hxx"
 #include "types.hxx"
 #include "unointerfaceproxy.hxx"
@@ -26,4 +28,529 @@
 
 using namespace ::com::sun::star::uno;
 
+#ifdef __arm64
+namespace arm
+{
+    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) ||
+                p->ppTypeRefs[i]->eTypeClass != p->ppTypeRefs[0]->eTypeClass)
+                return false;
+        }
+        return true;
+    }
+
+    bool return_in_x8( typelib_TypeDescriptionReference *pTypeRef )
+    {
+        if (bridges::cpp_uno::shared::isSimpleType(pTypeRef))
+            return false;
+        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 x0, x1
+            bool bRet = pTypeDescr->nSize > 16;
+
+            if (is_hfa_struct(pTypeDescr))
+                bRet = false;
+
+            TYPELIB_DANGER_RELEASE( pTypeDescr );
+            return bRet;
+        }
+        return true;
+    }
+}
+
+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] = x1;
+        SAL_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;
+#pragma GCC diagnostic pop
+        break;
+    case typelib_TypeClass_DOUBLE:
+        register double dret asm("d0");
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuninitialized"
+        *(double*)pRegisterReturn = dret;
+#pragma GCC diagnostic pop
+        break;
+    case typelib_TypeClass_STRUCT:
+    case typelib_TypeClass_EXCEPTION:
+        if (!arm::return_in_x8(pReturnType))
+        {
+            pRegisterReturn[0] = x0;
+            pRegisterReturn[1] = x1;
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+namespace
+{
+void callVirtualMethod(
+    void *pThis,
+    sal_Int32 nVtableIndex,
+    void *pRegisterReturn,
+    typelib_TypeDescriptionReference *pReturnType,
+    sal_uInt64 *pStack,
+    int nStack,
+    sal_uInt64 *pGPR,
+    double *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 );
+    }
+
+    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_INT64( pSV, nr, pGPR, pDS ) \
+        if ( nr < arm::MAX_GPR_REGS ) \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
+        else \
+                *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
+
+#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
+        if ( nr < arm::MAX_GPR_REGS ) \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
+        else \
+                *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
+
+#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
+        if ( nr < arm::MAX_GPR_REGS ) \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
+        else \
+                *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
+
+#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
+        if ( nr < arm::MAX_GPR_REGS ) \
+                pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
+        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,
+    typelib_TypeDescriptionReference * pReturnTypeRef,
+    sal_Int32 nParams, typelib_MethodParameter * pParams,
+    void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
+{
+    // max space for: values|ptr ...
+    sal_uInt64 * pStack = (sal_uInt64 *)alloca( (nParams+2) * sizeof(sal_Int64) );
+    sal_uInt64 * pStackStart = pStack;
+
+    sal_uInt64 pGPR[arm::MAX_GPR_REGS];
+    int nGPR = 0;
+
+    // storage and counter for SIMD/FP registers
+    double pFPR[arm::MAX_FPR_REGS];
+    int nFPR = 0;
+
+    // return
+    typelib_TypeDescription * pReturnTypeDescr = 0;
+    TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
+    assert( pReturnTypeDescr);
+
+    void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion
+
+    if (pReturnTypeDescr)
+    {
+        if (!arm::return_in_x8( pReturnTypeRef ) )
+            pCppReturn = pUnoReturn; // direct way for simple types
+        else
+        {
+            // complex return via x8
+            pCppReturn = (bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
+                    ? alloca( pReturnTypeDescr->nSize )
+                    : pUnoReturn); // direct way
+        }
+    }
+    // push this
+    void * pAdjustedThisPtr = reinterpret_cast< void ** >(pThis->getCppI())
+        + aVtableSlot.offset;
+    INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
+
+    // stack space
+    // args
+    void ** pCppArgs  = (void **)alloca( sizeof(void *) * nParams );
+
+    // indices of values this have to be converted (interface conversion cpp<=>uno)
+    int * pTempIndices = (int *)alloca( sizeof(int) * nParams );
+
+    // type descriptions for reconversions
+    typelib_TypeDescription ** ppTempParamTypeDescr = (typelib_TypeDescription **)alloca( sizeof(void *) * nParams );
+
+    sal_Int32 nTempIndices = 0;
+
+    for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+    {
+        const typelib_MethodParameter & rParam = pParams[nPos];
+        typelib_TypeDescription * pParamTypeDescr = 0;
+        TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
+
+        if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( pParamTypeDescr ))
+        {
+            uno_copyAndConvertData( pCppArgs[nPos] = alloca(8), pUnoArgs[nPos],
+                pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+            switch (pParamTypeDescr->eTypeClass)
+            {
+            case typelib_TypeClass_HYPER:
+            case typelib_TypeClass_UNSIGNED_HYPER:
+                INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack );
+                break;
+            case typelib_TypeClass_LONG:
+            case typelib_TypeClass_UNSIGNED_LONG:
+            case typelib_TypeClass_ENUM:
+                INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack );
+                break;
+            case typelib_TypeClass_SHORT:
+            case typelib_TypeClass_CHAR:
+            case typelib_TypeClass_UNSIGNED_SHORT:
+                INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack );
+                break;
+            case typelib_TypeClass_BOOLEAN:
+            case typelib_TypeClass_BYTE:
+                INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack );
+                break;
+            case typelib_TypeClass_FLOAT:
+                INSERT_FLOAT( pCppArgs[nPos], nFPR, pFPR, pStack );
+                break;
+            case typelib_TypeClass_DOUBLE:
+                INSERT_DOUBLE( pCppArgs[nPos], nFPR, pFPR, pStack );
+                break;
+            default:
+                break;
+            }
+            // no longer needed
+            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+        }
+        else // ptr to complex value | ref
+        {
+            if (! rParam.bIn) // is pure out
+            {
+                // cpp out is constructed mem, uno out is not!
+                uno_constructData(
+                    pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+                    pParamTypeDescr );
+                pTempIndices[nTempIndices] = nPos; // default constructed for cpp call
+                // will be released at reconversion
+                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+            }
+            // is in/inout
+            else if (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
+            {
+                uno_copyAndConvertData(
+                    pCppArgs[nPos] = alloca( pParamTypeDescr->nSize ),
+                    pUnoArgs[nPos], pParamTypeDescr, pThis->getBridge()->getUno2Cpp() );
+
+                pTempIndices[nTempIndices] = nPos; // has to be reconverted
+                // will be released at reconversion
+                ppTempParamTypeDescr[nTempIndices++] = pParamTypeDescr;
+            }
+            else // direct way
+            {
+                pCppArgs[nPos] = pUnoArgs[nPos];
+                // no longer needed
+                TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+            }
+            INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
+        }
+    }
+
+    assert( nGPR <= arm::MAX_GPR_REGS );
+    assert( nFPR <= arm::MAX_FPR_REGS );
+
+    try
+    {
+        callVirtualMethod(
+            pAdjustedThisPtr, aVtableSlot.index,
+            pCppReturn, pReturnTypeRef,
+            pStackStart,
+            (pStack - pStackStart),
+            pGPR,
+            pFPR);
+
+        // NO exception occurred...
+        *ppUnoExc = 0;
+
+        // reconvert temporary params
+        for ( ; nTempIndices--; )
+        {
+            sal_Int32 nIndex = pTempIndices[nTempIndices];
+            typelib_TypeDescription * pParamTypeDescr = ppTempParamTypeDescr[nTempIndices];
+
+            if (pParams[nIndex].bIn)
+            {
+                if (pParams[nIndex].bOut) // inout
+                {
+                    uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 ); // destroy uno value
+                    uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+                                            pThis->getBridge()->getCpp2Uno() );
+                }
+            }
+            else // pure out
+            {
+                uno_copyAndConvertData( pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
+                                        pThis->getBridge()->getCpp2Uno() );
+            }
+            // destroy temp cpp param => cpp: every param was constructed
+            uno_destructData( pCppArgs[nIndex], pParamTypeDescr, cpp_release );
+
+            TYPELIB_DANGER_RELEASE( pParamTypeDescr );
+        }
+        // return value
+        if (pCppReturn && pUnoReturn != pCppReturn)
+        {
+            uno_copyAndConvertData( pUnoReturn, pCppReturn, pReturnTypeDescr,
+                                    pThis->getBridge()->getCpp2Uno() );
+            uno_destructData( pCppReturn, pReturnTypeDescr, cpp_release );
+        }
+    }
+    catch (...)
+    {
+        // fill uno exception
+        CPPU_CURRENT_NAMESPACE::fillUnoException( abi::__cxa_get_globals()->caughtExceptions, *ppUnoExc, pThis->getBridge()->getCpp2Uno() );
+
+        // temporary params
+        for ( ; nTempIndices--; )
+        {
+            sal_Int32 nIndex = pTempIndices[nTempIndices];
+            // destroy temp cpp param => cpp: every param was constructed
+            uno_destructData( pCppArgs[nIndex], ppTempParamTypeDescr[nTempIndices], cpp_release );
+            TYPELIB_DANGER_RELEASE( ppTempParamTypeDescr[nTempIndices] );
+        }
+
+        // return type
+        if (pReturnTypeDescr)
+            TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
+    }
+}
+}
+
+namespace bridges { namespace cpp_uno { namespace shared {
+
+void unoInterfaceProxyDispatch(
+    uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
+    void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+    // is my surrogate
+    bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
+          = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * >(pUnoI);
+#if OSL_DEBUG_LEVEL > 0
+    typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
+#endif
+
+    switch (pMemberDescr->eTypeClass)
+    {
+    case typelib_TypeClass_INTERFACE_ATTRIBUTE:
+    {
+#if OSL_DEBUG_LEVEL > 0
+        // determine vtable call index

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list