Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/abi.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -333,24 +333,26 @@ void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64*

sal_uInt32 align_stack_offset( sal_uInt32 offset, typelib_TypeDescriptionReference *pTypeRef )
{
// On aarch64 System V ABI, the smallest stack slot is 8 bytes.
// Align to 8 bytes regardless of the type's natural alignment.
const sal_uInt32 align = 8;
return ( offset + align - 1 ) & ~( align - 1 );
typelib_TypeDescription * pTypeDescr = 0;
TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
sal_uInt32 alignment = pTypeDescr->nAlignment;
TYPELIB_DANGER_RELEASE( pTypeDescr );
if ( alignment == 0 )
alignment = 1;
return ( offset + alignment - 1 ) & ~( alignment - 1 );
}

sal_uInt32 stack_size( typelib_TypeDescriptionReference *pTypeRef )
{
typelib_TypeDescription * pTypeDescr = 0;
TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
sal_uInt32 size = pTypeDescr->nSize;
// AAPCS64 requires each stack argument to occupy a full 8-byte
// slot; small types are sign- or zero-extended into the slot.
if ( size < 8 )
size = 8;
TYPELIB_DANGER_RELEASE( pTypeDescr );
// In the System V AMD64 / AAPCS64 stack layout, the smallest slot that
// can be passed is 8 bytes (the natural stack slot size). Round up
// so that small types like BOOLEAN (1B), SHORT (2B), LONG (4B) each
// occupy a full 8-byte slot on the overflow stack, matching what the
// callee's ABI expects.
return ( size + 7 ) & ~7u;
return size;
}

} // namespace aarch64
61 changes: 53 additions & 8 deletions main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/uno2cpp.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,15 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
case typelib_TypeClass_DOUBLE:
*reinterpret_cast<double *>( pRegisterReturn ) = fpReturn[0];
break;
case typelib_TypeClass_STRUCT:
case typelib_TypeClass_EXCEPTION:
aarch64::fill_struct( pReturnTypeRef, &gpReturn[0], &fpReturn[0], pRegisterReturn );
break;
default:
break;
{
sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
if (bSimpleReturn && nRetSize > 0)
{
aarch64::fill_struct( pReturnTypeRef, &gpReturn[0], &fpReturn[0], pRegisterReturn );
}
break;
}
}
}

Expand Down Expand Up @@ -353,9 +356,51 @@ static void cpp_call(
}
if ( onStack )
{
nStack = aarch64::align_stack_offset( nStack, rParam.pTypeRef );
sal_uInt32 size = aarch64::stack_size( rParam.pTypeRef );
memcpy( pStackStart + nStack, pCppArgs[nPos], size );
// AAPCS64: each stack argument occupies a full 8-byte slot
// with the value sign- or zero-extended. The INSERT macros
// already perform the correct extension into a GPR-sized
// (sal_uInt64) scratch slot; reuse them with a local counter.
nStack = aarch64::align_stack_offset( nStack, rParam.pTypeRef );
sal_uInt32 size = aarch64::stack_size( rParam.pTypeRef );
sal_uInt64 scratch[1] = {0};
int tempNr = 0;
switch (pParamTypeDescr->eTypeClass)
{
case typelib_TypeClass_FLOAT:
INSERT_FLOAT( pCppArgs[nPos], tempNr, reinterpret_cast<double *>(scratch) );
break;
case typelib_TypeClass_DOUBLE:
INSERT_DOUBLE( pCppArgs[nPos], tempNr, reinterpret_cast<double *>(scratch) );
break;
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
INSERT_INT64( pCppArgs[nPos], tempNr, scratch );
break;
case typelib_TypeClass_LONG:
INSERT_SIGNED_INT32( pCppArgs[nPos], tempNr, scratch );
break;
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
INSERT_INT32( pCppArgs[nPos], tempNr, scratch );
break;
case typelib_TypeClass_SHORT:
INSERT_SIGNED_INT16( pCppArgs[nPos], tempNr, scratch );
break;
case typelib_TypeClass_CHAR:
case typelib_TypeClass_UNSIGNED_SHORT:
INSERT_INT16( pCppArgs[nPos], tempNr, scratch );
break;
case typelib_TypeClass_BYTE:
INSERT_SIGNED_INT8( pCppArgs[nPos], tempNr, scratch );
break;
case typelib_TypeClass_BOOLEAN:
INSERT_INT8( pCppArgs[nPos], tempNr, scratch );
break;
default:
memcpy( scratch, pCppArgs[nPos], pParamTypeDescr->nSize );
break;
}
memcpy( pStackStart + nStack, scratch, size );
nStack += size;
}

Expand Down