bridge/powerpc64: fix integer ABI

The ABI document for PowerPC64 specifies that integer values shorter than
a doubleword are sign or zero extended as necessary. Until now the smaller
values were treated as unsigned values and only zero-extended. Handling of
signed values was incorrect.

Change-Id: Icbbe8fc8d4facfa6d1b3252c99ec2d8c2552d9f0
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156847
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
Dan Horák 2023-09-12 10:20:51 +02:00 committed by Stephan Bergmann
parent cdf4b60e3e
commit 6d24e32d02

View file

@ -256,6 +256,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
*pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
#define INSERT_INT64( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_Int64 *>( pSV ); \
else \
bOverflow = true; \
if (bOverflow) \
*pDS++ = *reinterpret_cast<sal_Int64 *>( pSV );
#define INSERT_UINT64( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
else \
@ -264,6 +272,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
*pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
#define INSERT_INT32( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_Int32 *>( pSV ); \
else \
bOverflow = true; \
if (bOverflow) \
*pDS++ = *reinterpret_cast<sal_Int32 *>( pSV );
#define INSERT_UINT32( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
else \
@ -272,6 +288,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
*pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
#define INSERT_INT16( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_Int16 *>( pSV ); \
else \
bOverflow = true; \
if (bOverflow) \
*pDS++ = *reinterpret_cast<sal_Int16 *>( pSV );
#define INSERT_UINT16( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
else \
@ -280,6 +304,14 @@ static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
*pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
#define INSERT_INT8( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_Int8 *>( pSV ); \
else \
bOverflow = true; \
if (bOverflow) \
*pDS++ = *reinterpret_cast<sal_Int8 *>( pSV );
#define INSERT_UINT8( pSV, nr, pGPR, pDS, bOverflow ) \
if ( nr < ppc64::MAX_GPR_REGS ) \
pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
else \
@ -339,7 +371,7 @@ static void cpp_call(
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "pCppReturn/pUnoReturn is %p/%p\n", pCppReturn, pUnoReturn);
#endif
INSERT_INT64( &pCppReturn, nGPR, pGPR, pStack, bOverflow );
INSERT_UINT64( &pCppReturn, nGPR, pGPR, pStack, bOverflow );
}
}
// push "this" pointer
@ -347,7 +379,7 @@ static void cpp_call(
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "this pointer is %p\n", pAdjustedThisPtr);
#endif
INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverflow );
INSERT_UINT64( &pAdjustedThisPtr, nGPR, pGPR, pStack, bOverflow );
// Args
void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
@ -380,26 +412,40 @@ static void cpp_call(
switch (pParamTypeDescr->eTypeClass)
{
case typelib_TypeClass_HYPER:
case typelib_TypeClass_UNSIGNED_HYPER:
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "hyper is 0x%lx\n", *(sal_Int64 *)pCppArgs[nPos]);
#endif
INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_UNSIGNED_HYPER:
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "uhyper is 0x%lx\n", *(sal_Int64 *)pCppArgs[nPos]);
#endif
INSERT_UINT64( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_LONG:
case typelib_TypeClass_UNSIGNED_LONG:
case typelib_TypeClass_ENUM:
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "long is 0x%x\n", *(sal_Int32 *)pCppArgs[nPos]);
#endif
INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_UNSIGNED_LONG:
#if OSL_DEBUG_LEVEL > 2
fprintf(stderr, "ulong is 0x%x\n", *(sal_Int32 *)pCppArgs[nPos]);
#endif
INSERT_UINT32( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_SHORT:
case typelib_TypeClass_CHAR:
case typelib_TypeClass_UNSIGNED_SHORT:
INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_CHAR:
case typelib_TypeClass_UNSIGNED_SHORT:
INSERT_UINT16( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_BOOLEAN:
INSERT_UINT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
case typelib_TypeClass_BYTE:
INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack, bOverflow );
break;
@ -458,7 +504,7 @@ static void cpp_call(
// no longer needed
TYPELIB_DANGER_RELEASE( pParamTypeDescr );
}
INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverflow );
INSERT_UINT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack, bOverflow );
}
}