summaryrefslogtreecommitdiff
path: root/bridges
diff options
context:
space:
mode:
authorCaolán McNamara <cmc@openoffice.org>2009-10-06 15:08:10 +0000
committerCaolán McNamara <cmc@openoffice.org>2009-10-06 15:08:10 +0000
commit8d4bb4276d78356cb15cf3d6d9c35eb3eb2ee3d1 (patch)
treebc31475694902fe9b3d614b94d7a7ec14efea834 /bridges
parentc4989e147f02f0c39e3cdaa9be4223d4fa4b438a (diff)
#i98028# SmallStruct and AllFloats
Diffstat (limited to 'bridges')
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx10
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx2
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/call.s3
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx23
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx25
5 files changed, 25 insertions, 38 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
index 2aeaf9423859..ad0faa1a01aa 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.cxx
@@ -229,6 +229,7 @@ classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_c
for ( sal_Int32 nMember = 0; nMember < pStruct->nMembers; ++nMember )
{
typelib_TypeDescriptionReference *pTypeInStruct = pStruct->ppTypeRefs[ nMember ];
+ rByteOffset = pStruct->pMemberOffsets[ nMember ];
int num = classify_argument( pTypeInStruct, subclasses, rByteOffset );
@@ -243,9 +244,6 @@ classify_argument( typelib_TypeDescriptionReference *pTypeRef, enum x86_64_reg_c
int pos = rByteOffset / 8;
classes[i + pos] = merge_classes( subclasses[i], classes[i + pos] );
}
-
- if ( pTypeInStruct->eTypeClass != typelib_TypeClass_STRUCT )
- rByteOffset = pStruct->pMemberOffsets[ nMember ];
}
TYPELIB_DANGER_RELEASE( pTypeDescr );
@@ -332,7 +330,7 @@ bool x86_64::return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef
return examine_argument( pTypeRef, true, g, s ) == 0;
}
-void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, void * const *pGPR, void * const *pSSE, void *pStruct )
+void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64 *pGPR, const double *pSSE, void *pStruct )
{
enum x86_64_reg_class classes[MAX_CLASSES];
int offset = 0;
@@ -346,12 +344,12 @@ void x86_64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, void * con
{
case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS:
- *pStructAlign++ = *reinterpret_cast<sal_uInt64 *>( *pGPR++ );
+ *pStructAlign++ = *pGPR++;
break;
case X86_64_SSE_CLASS:
case X86_64_SSESF_CLASS:
case X86_64_SSEDF_CLASS:
- *pStructAlign++ = *reinterpret_cast<sal_uInt64 *>( *pSSE++ );
+ *pStructAlign++ = *reinterpret_cast<const sal_uInt64 *>( pSSE++ );
break;
default:
break;
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
index 5fffe680c28a..c5b7d94d2e01 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/abi.hxx
@@ -63,7 +63,7 @@ bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInRetur
*/
bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
-void fill_struct( typelib_TypeDescriptionReference *pTypeRef, void * const *pGPR, void * const *pSSE, void *pStruct );
+void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pSSE, void *pStruct );
} // namespace x86_64
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
index 736230705d5a..a0572ef61641 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/call.s
@@ -43,6 +43,9 @@ privateSnippetExecutor:
je .Lfloat
movq -144(%rbp), %rax # Return value (int case)
+ movq -136(%rbp), %rdx # Return value (int case)
+ movq -144(%rbp), %xmm0 # Return value (int case)
+ movq -136(%rbp), %xmm1 # Return value (int case)
jmp .Lfinish
.Lfloat:
movlpd -144(%rbp), %xmm0 # Return value (float/double case)
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
index 5fb2bd7e12a3..d5d0425b7029 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/cpp2uno.cxx
@@ -159,28 +159,7 @@ static typelib_TypeClass cpp2uno_call(
else // struct <= 16 bytes || ptr to complex value || ref
{
void *pCppStack;
- char pTmpStruct[16];
-
- if ( bFitsRegisters && !rParam.bOut &&
- ( pParamTypeDescr->eTypeClass == typelib_TypeClass_STRUCT ||
- pParamTypeDescr->eTypeClass == typelib_TypeClass_EXCEPTION ) )
- {
- if ( ( nr_gpr + nUsedGPR <= x86_64::MAX_GPR_REGS ) && ( nr_fpr + nUsedSSE <= x86_64::MAX_SSE_REGS ) )
- {
- x86_64::fill_struct( rParam.pTypeRef, gpreg, fpreg, pTmpStruct );
-#if OSL_DEBUG_LEVEL > 1
- fprintf( stderr, "nUsedGPR == %d, nUsedSSE == %d, pTmpStruct[0] == 0x%x, pTmpStruct[1] == 0x%x, **gpreg == 0x%lx\n",
- nUsedGPR, nUsedSSE, pTmpStruct[0], pTmpStruct[1], *(sal_uInt64*)*gpreg );
-#endif
-
- pCppArgs[nPos] = pCppStack = reinterpret_cast<void *>( pTmpStruct );
- gpreg += nUsedGPR;
- fpreg += nUsedSSE;
- }
- else
- pCppArgs[nPos] = pCppStack = *ovrflw++;
- }
- else if ( nr_gpr < x86_64::MAX_GPR_REGS )
+ if ( nr_gpr < x86_64::MAX_GPR_REGS )
{
pCppArgs[nPos] = pCppStack = *gpreg++;
nr_gpr++;
diff --git a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
index 7199794409a8..23c40121afb7 100644
--- a/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_x86-64/uno2cpp.cxx
@@ -53,13 +53,13 @@ using namespace ::com::sun::star::uno;
//==================================================================================================
static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
- void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
sal_uInt64 *pStack, sal_uInt32 nStack,
sal_uInt64 *pGPR, sal_uInt32 nGPR,
double *pFPR, sal_uInt32 nFPR) __attribute__((noinline));
static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
- void * pRegisterReturn, typelib_TypeDescription * pReturnTypeDescr, bool bSimpleReturn,
+ void * pRegisterReturn, typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
sal_uInt64 *pStack, sal_uInt32 nStack,
sal_uInt64 *pGPR, sal_uInt32 nGPR,
double *pFPR, sal_uInt32 nFPR)
@@ -113,6 +113,7 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
sal_uInt64 rax;
sal_uInt64 rdx;
double xmm0;
+ double xmm1;
asm volatile (
@@ -147,13 +148,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
"movq %%rax, %4\n\t"
"movq %%rdx, %5\n\t"
"movsd %%xmm0, %6\n\t"
+ "movsd %%xmm1, %7\n\t"
:
: "m" ( pMethod ), "m" ( pGPR ), "m" ( pFPR ), "m" ( nFPR ),
- "m" ( rax ), "m" ( rdx ), "m" ( xmm0 )
+ "m" ( rax ), "m" ( rdx ), "m" ( xmm0 ), "m" ( xmm1 )
: "rax", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "r11"
);
- switch (pReturnTypeDescr->eTypeClass)
+ switch (pReturnTypeRef->eTypeClass)
{
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
@@ -179,12 +181,17 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
break;
default:
{
- sal_Int32 const nRetSize = pReturnTypeDescr->nSize;
+ sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
{
- if (nRetSize > 8)
- static_cast<sal_uInt64 *>(pRegisterReturn)[1] = rdx;
- static_cast<sal_uInt64 *>(pRegisterReturn)[0] = rax;
+ sal_uInt64 longs[2];
+ longs[0] = rax;
+ longs[1] = rdx;
+
+ double doubles[2];
+ doubles[0] = xmm0;
+ doubles[1] = xmm1;
+ x86_64::fill_struct( pReturnTypeRef, &longs[0], &doubles[0], pRegisterReturn);
}
break;
}
@@ -367,7 +374,7 @@ static void cpp_call(
{
callVirtualMethod(
pAdjustedThisPtr, aVtableSlot.index,
- pCppReturn, pReturnTypeDescr, bSimpleReturn,
+ pCppReturn, pReturnTypeRef, bSimpleReturn,
pStackStart, ( pStack - pStackStart ),
pGPR, nGPR,
pFPR, nFPR );