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