bridges:Fixed test fail caused by bridges on the loongarch64
Some failed test are caused by the bridges when testing on the loongarch64 machine. After adjust the function parameters and return value processing according to the characteristics of the loongarch64 architercture. I tested in version 7.4.3 on the loongarch64 machine, and all tests passed. Change-Id: I9c67287cd7cc89fd79a907afdbffa507bb6052e3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144986 Tested-by: Jenkins Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
parent
fbabd95906
commit
d3152ea3ae
8 changed files with 288 additions and 173 deletions
|
@ -119,7 +119,7 @@ else ifeq ($(CPUNAME),LOONGARCH64)
|
|||
ifneq ($(filter LINUX,$(OS)),)
|
||||
bridges_SELECTED_BRIDGE := gcc3_linux_loongarch64
|
||||
bridge_asm_objects := call
|
||||
bridge_noopt_objects := cpp2uno uno2cpp
|
||||
bridge_noopt_objects := abi cpp2uno uno2cpp
|
||||
bridge_exception_objects := except
|
||||
endif
|
||||
|
||||
|
|
137
bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx
Normal file
137
bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx
Normal file
|
@ -0,0 +1,137 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* 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 .
|
||||
*/
|
||||
|
||||
#include <sal/config.h>
|
||||
|
||||
#include "abi.hxx"
|
||||
|
||||
int loongarch64::flatten_struct(typelib_TypeDescription* pTypeDescr, Registers& regs)
|
||||
{
|
||||
const typelib_CompoundTypeDescription* p
|
||||
= reinterpret_cast<const typelib_CompoundTypeDescription*>(pTypeDescr);
|
||||
int sum = p->nMembers;
|
||||
for (sal_Int32 i = 0; i < p->nMembers; ++i)
|
||||
{
|
||||
typelib_TypeDescriptionReference* pTypeInStruct = p->ppTypeRefs[i];
|
||||
|
||||
switch (pTypeInStruct->eTypeClass)
|
||||
{
|
||||
case typelib_TypeClass_STRUCT:
|
||||
{
|
||||
typelib_TypeDescription* t = 0;
|
||||
TYPELIB_DANGER_GET(&t, pTypeInStruct);
|
||||
sum--;
|
||||
sum += flatten_struct(t, regs);
|
||||
TYPELIB_DANGER_RELEASE(t);
|
||||
}
|
||||
break;
|
||||
case typelib_TypeClass_CHAR:
|
||||
case typelib_TypeClass_BOOLEAN:
|
||||
case typelib_TypeClass_BYTE:
|
||||
case typelib_TypeClass_SHORT:
|
||||
case typelib_TypeClass_UNSIGNED_SHORT:
|
||||
case typelib_TypeClass_LONG:
|
||||
case typelib_TypeClass_UNSIGNED_LONG:
|
||||
case typelib_TypeClass_HYPER:
|
||||
case typelib_TypeClass_UNSIGNED_HYPER:
|
||||
case typelib_TypeClass_ENUM:
|
||||
regs.nr_int++;
|
||||
if (!regs.priorInt && !regs.priorFp)
|
||||
regs.priorInt = true;
|
||||
break;
|
||||
case typelib_TypeClass_FLOAT:
|
||||
case typelib_TypeClass_DOUBLE:
|
||||
regs.nr_fp++;
|
||||
if (!regs.priorInt && !regs.priorFp)
|
||||
regs.priorFp = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
loongarch64::ReturnKind loongarch64::getReturnKind(typelib_TypeDescriptionReference* pTypeRef)
|
||||
{
|
||||
switch (pTypeRef->eTypeClass)
|
||||
{
|
||||
case typelib_TypeClass_CHAR:
|
||||
case typelib_TypeClass_BOOLEAN:
|
||||
case typelib_TypeClass_BYTE:
|
||||
case typelib_TypeClass_SHORT:
|
||||
case typelib_TypeClass_UNSIGNED_SHORT:
|
||||
case typelib_TypeClass_LONG:
|
||||
case typelib_TypeClass_UNSIGNED_LONG:
|
||||
case typelib_TypeClass_HYPER:
|
||||
case typelib_TypeClass_UNSIGNED_HYPER:
|
||||
case typelib_TypeClass_ENUM:
|
||||
return ReturnKind::RegistersInt;
|
||||
case typelib_TypeClass_FLOAT:
|
||||
case typelib_TypeClass_DOUBLE:
|
||||
return ReturnKind::RegistersFp;
|
||||
case typelib_TypeClass_STRUCT:
|
||||
{
|
||||
Registers regs = { 0, 0, false, false };
|
||||
typelib_TypeDescription* pTypeDescr = nullptr;
|
||||
TYPELIB_DANGER_GET(&pTypeDescr, pTypeRef);
|
||||
int sum = flatten_struct(pTypeDescr, regs);
|
||||
TYPELIB_DANGER_RELEASE(pTypeDescr);
|
||||
if ((sum == 1 || sum == 2) && sum == regs.nr_fp)
|
||||
return ReturnKind::RegistersFp;
|
||||
if (sum == 2 && regs.nr_fp == regs.nr_int)
|
||||
{
|
||||
if (regs.priorInt)
|
||||
return ReturnKind::RegistersIntFp;
|
||||
if (regs.priorFp)
|
||||
return ReturnKind::RegistersFpInt;
|
||||
}
|
||||
return ReturnKind::RegistersInt;
|
||||
}
|
||||
default:
|
||||
return ReturnKind::RegistersInt;
|
||||
}
|
||||
}
|
||||
|
||||
void loongarch64::fillReturn(typelib_TypeDescriptionReference* pTypeRef, sal_Int64* gret,
|
||||
double* fret, void* pRegisterReturn)
|
||||
{
|
||||
ReturnKind returnKind = getReturnKind(pTypeRef);
|
||||
switch (returnKind)
|
||||
{
|
||||
case ReturnKind::RegistersFp:
|
||||
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
|
||||
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[1];
|
||||
break;
|
||||
case ReturnKind::RegistersFpInt:
|
||||
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
|
||||
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[0];
|
||||
break;
|
||||
case ReturnKind::RegistersIntFp:
|
||||
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
|
||||
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[0];
|
||||
break;
|
||||
default:
|
||||
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
|
||||
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
51
bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx
Normal file
51
bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx
Normal file
|
@ -0,0 +1,51 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
||||
/*
|
||||
* 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 .
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <typelib/typedescription.hxx>
|
||||
|
||||
#define MAX_GP_REGS 8
|
||||
#define MAX_FP_REGS 8
|
||||
|
||||
namespace loongarch64
|
||||
{
|
||||
enum class ReturnKind
|
||||
{
|
||||
RegistersInt,
|
||||
RegistersFp,
|
||||
RegistersFpInt,
|
||||
RegistersIntFp
|
||||
};
|
||||
typedef struct Registers
|
||||
{
|
||||
bool priorInt;
|
||||
bool priorFp;
|
||||
int nr_fp;
|
||||
int nr_int;
|
||||
} Registers;
|
||||
int flatten_struct(typelib_TypeDescription* pTypeDescr, Registers& regs);
|
||||
|
||||
ReturnKind getReturnKind(typelib_TypeDescriptionReference* type);
|
||||
|
||||
void fillReturn(typelib_TypeDescriptionReference* pTypeRef, sal_Int64* gret, double* fret,
|
||||
void* pRegisterReturn);
|
||||
} // namespace loongarch64
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
namespace
|
||||
{
|
||||
extern "C" typelib_TypeClass
|
||||
cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg, void** fpreg,
|
||||
void** ovrflw, sal_uInt64* pRegisterReturn /* space for register return */);
|
||||
extern "C" int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg,
|
||||
void** fpreg, void** ovrflw,
|
||||
sal_uInt64* pRegisterReturn /* space for register return */);
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|
||||
|
|
|
@ -30,6 +30,9 @@ privateSnippetExecutor:
|
|||
st.d $ra,$sp,152
|
||||
.cfi_offset 1, -8
|
||||
.LEHB0 = .
|
||||
// Clear return value space
|
||||
st.d $zero,$sp,0
|
||||
st.d $zero,$sp,8
|
||||
// Save the float point registers
|
||||
fst.d $f0,$sp,80
|
||||
fst.d $f1,$sp,88
|
||||
|
@ -67,11 +70,21 @@ privateSnippetExecutor:
|
|||
|
||||
.LEHE0 = .
|
||||
// Perform return value
|
||||
beq $a0,$zero,.Lintfp
|
||||
blt $zero,$a0,.Lfpint
|
||||
fld.d $f0,$sp,0
|
||||
fld.d $f1,$sp,8
|
||||
ld.d $a0,$sp,0
|
||||
ld.d $a1,$sp,8
|
||||
|
||||
b .Lfinish
|
||||
.Lintfp:
|
||||
ld.d $a0,$sp,0
|
||||
fld.d $f0,$sp,8
|
||||
b .Lfinish
|
||||
.Lfpint:
|
||||
fld.d $f0,$sp,0
|
||||
ld.d $a0,$sp,8
|
||||
.Lfinish:
|
||||
ld.d $ra,$sp,152
|
||||
.cfi_restore 1
|
||||
addi.d $sp,$sp,160
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "vtablefactory.hxx"
|
||||
#include "call.hxx"
|
||||
#include "share.hxx"
|
||||
#include "abi.hxx"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -85,19 +86,25 @@ bool return_in_hidden_param(typelib_TypeDescriptionReference* pTypeRef)
|
|||
|
||||
namespace
|
||||
{
|
||||
static typelib_TypeClass
|
||||
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** gpreg, void** fpreg,
|
||||
void** ovrflw, sal_uInt64* pRegisterReturn /* space for register return */)
|
||||
static int 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** gpreg,
|
||||
void** fpreg, void** ovrflw,
|
||||
sal_uInt64* pRegisterReturn /* space for register return */)
|
||||
{
|
||||
unsigned int nREG = 0;
|
||||
sal_Int32 gCount = 0;
|
||||
sal_Int32 fCount = 0;
|
||||
sal_Int32 sp = 0;
|
||||
|
||||
// return
|
||||
typelib_TypeDescription* pReturnTypeDescr = 0;
|
||||
if (pReturnTypeRef)
|
||||
TYPELIB_DANGER_GET(&pReturnTypeDescr, pReturnTypeRef);
|
||||
loongarch64::ReturnKind returnKind
|
||||
= (pReturnTypeRef == nullptr || pReturnTypeRef->eTypeClass == typelib_TypeClass_VOID)
|
||||
? loongarch64::ReturnKind::RegistersInt
|
||||
: loongarch64::getReturnKind(pReturnTypeRef);
|
||||
|
||||
void* pUnoReturn = 0;
|
||||
void* pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, reconversion need
|
||||
|
@ -106,9 +113,7 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|||
{
|
||||
if (CPPU_CURRENT_NAMESPACE::return_in_hidden_param(pReturnTypeRef))
|
||||
{
|
||||
pCppReturn = gpreg[nREG]; // complex return via ptr (pCppReturn)
|
||||
nREG++;
|
||||
|
||||
pCppReturn = gpreg[gCount++]; // complex return via ptr (pCppReturn)
|
||||
pUnoReturn = (bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr)
|
||||
? alloca(pReturnTypeDescr->nSize)
|
||||
: pCppReturn); // direct way
|
||||
|
@ -120,7 +125,7 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|||
}
|
||||
|
||||
// pop this
|
||||
nREG++;
|
||||
gCount++;
|
||||
|
||||
// stack space
|
||||
static_assert(sizeof(void*) == sizeof(sal_Int64), "### unexpected size!");
|
||||
|
@ -148,31 +153,15 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|||
{
|
||||
case typelib_TypeClass_FLOAT:
|
||||
case typelib_TypeClass_DOUBLE:
|
||||
if (nREG < MAX_FP_REGS)
|
||||
{
|
||||
pCppArgs[nPos] = &(fpreg[nREG]);
|
||||
pUnoArgs[nPos] = &(fpreg[nREG]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pCppArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
|
||||
pUnoArgs[nPos] = &(ovrflw[nREG - MAX_FP_REGS]);
|
||||
}
|
||||
nREG++;
|
||||
pCppArgs[nPos]
|
||||
= fCount != MAX_FP_REGS
|
||||
? &(fpreg[fCount++])
|
||||
: (gCount != MAX_GP_REGS ? &(gpreg[gCount++]) : &(ovrflw[sp++]));
|
||||
pUnoArgs[nPos] = pCppArgs[nPos];
|
||||
break;
|
||||
|
||||
default:
|
||||
if (nREG < MAX_GP_REGS)
|
||||
{
|
||||
pCppArgs[nPos] = &(gpreg[nREG]);
|
||||
pUnoArgs[nPos] = &(gpreg[nREG]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pCppArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
|
||||
pUnoArgs[nPos] = &(ovrflw[nREG - MAX_GP_REGS]);
|
||||
}
|
||||
nREG++;
|
||||
pCppArgs[nPos] = gCount == MAX_GP_REGS ? &(ovrflw[sp++]) : &(gpreg[gCount++]);
|
||||
pUnoArgs[nPos] = pCppArgs[nPos];
|
||||
break;
|
||||
}
|
||||
// no longer needed
|
||||
|
@ -181,16 +170,8 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|||
else // ptr to complex value | ref
|
||||
{
|
||||
void* pCppStack;
|
||||
if (nREG < MAX_GP_REGS)
|
||||
{
|
||||
pCppArgs[nPos] = pCppStack = gpreg[nREG];
|
||||
}
|
||||
else
|
||||
{
|
||||
pCppArgs[nPos] = pCppStack = ovrflw[nREG - MAX_GP_REGS];
|
||||
}
|
||||
nREG++;
|
||||
|
||||
pCppStack = gCount == MAX_GP_REGS ? ovrflw[sp++] : gpreg[gCount++];
|
||||
pCppArgs[nPos] = pCppStack;
|
||||
if (!rParam.bIn) // is pure out
|
||||
{
|
||||
// uno out is unconstructed mem!
|
||||
|
@ -241,7 +222,7 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|||
CPPU_CURRENT_NAMESPACE::raiseException(&aUnoExc, pThis->getBridge()->getUno2Cpp());
|
||||
// has to destruct the any
|
||||
// is here for dummy
|
||||
return typelib_TypeClass_VOID;
|
||||
return -1;
|
||||
}
|
||||
else // else no exception occurred...
|
||||
{
|
||||
|
@ -278,12 +259,17 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|||
}
|
||||
if (pReturnTypeDescr)
|
||||
{
|
||||
typelib_TypeClass eRet = (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
|
||||
TYPELIB_DANGER_RELEASE(pReturnTypeDescr);
|
||||
return eRet;
|
||||
}
|
||||
else
|
||||
return typelib_TypeClass_VOID;
|
||||
switch (returnKind)
|
||||
{
|
||||
case loongarch64::ReturnKind::RegistersIntFp:
|
||||
return 0;
|
||||
case loongarch64::ReturnKind::RegistersFpInt:
|
||||
return 1;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,9 +277,8 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
|
|||
* is called on incoming vtable calls
|
||||
* (called by asm snippets)
|
||||
*/
|
||||
typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg,
|
||||
void** fpreg, void** ovrflw,
|
||||
sal_uInt64* pRegisterReturn /* space for register return */)
|
||||
int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gpreg, void** fpreg,
|
||||
void** ovrflw, sal_uInt64* pRegisterReturn /* space for register return */)
|
||||
{
|
||||
static_assert(sizeof(sal_Int64) == sizeof(void*), "### unexpected!");
|
||||
|
||||
|
@ -332,7 +317,7 @@ typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOff
|
|||
|
||||
TypeDescription aMemberDescr(pTypeDescr->ppAllMembers[nMemberPos]);
|
||||
|
||||
typelib_TypeClass eRet;
|
||||
int eRet;
|
||||
switch (aMemberDescr.get()->eTypeClass)
|
||||
{
|
||||
case typelib_TypeClass_INTERFACE_ATTRIBUTE:
|
||||
|
@ -368,11 +353,11 @@ typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOff
|
|||
{
|
||||
case 1: // acquire()
|
||||
pCppI->acquireProxy(); // non virtual call!
|
||||
eRet = typelib_TypeClass_VOID;
|
||||
eRet = -1;
|
||||
break;
|
||||
case 2: // release()
|
||||
pCppI->releaseProxy(); // non virtual call!
|
||||
eRet = typelib_TypeClass_VOID;
|
||||
eRet = -1;
|
||||
break;
|
||||
case 0: // queryInterface() opt
|
||||
{
|
||||
|
@ -395,7 +380,7 @@ typelib_TypeClass cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOff
|
|||
TYPELIB_DANGER_RELEASE(pTD);
|
||||
|
||||
reinterpret_cast<void**>(pRegisterReturn)[0] = gpreg[0];
|
||||
eRet = typelib_TypeClass_ANY;
|
||||
eRet = -1;
|
||||
break;
|
||||
}
|
||||
TYPELIB_DANGER_RELEASE(pTD);
|
||||
|
|
|
@ -24,9 +24,6 @@
|
|||
#include <exception>
|
||||
#include <cstddef>
|
||||
|
||||
#define MAX_GP_REGS (8)
|
||||
#define MAX_FP_REGS (8)
|
||||
|
||||
namespace CPPU_CURRENT_NAMESPACE
|
||||
{
|
||||
void dummy_can_throw_anything(char const*);
|
||||
|
|
|
@ -36,108 +36,22 @@
|
|||
#include "vtables.hxx"
|
||||
|
||||
#include "share.hxx"
|
||||
|
||||
#define INSERT_FLOAT_DOUBLE(pSV, nr, pFPR, pDS) \
|
||||
if (nr < MAX_FP_REGS) \
|
||||
pFPR[nr++] = *reinterpret_cast<double*>(pSV); \
|
||||
else \
|
||||
*pDS++ = *reinterpret_cast<sal_uInt64*>(pSV); // verbatim!
|
||||
|
||||
#define INSERT_INT64(pSV, nr, pGPR, pDS) \
|
||||
if (nr < MAX_GP_REGS) \
|
||||
pGPR[nr++] = *reinterpret_cast<sal_Int64*>(pSV); \
|
||||
else \
|
||||
*pDS++ = *reinterpret_cast<sal_Int64*>(pSV);
|
||||
|
||||
#define INSERT_INT32(pSV, nr, pGPR, pDS) \
|
||||
if (nr < MAX_GP_REGS) \
|
||||
pGPR[nr++] = *reinterpret_cast<sal_Int32*>(pSV); \
|
||||
else \
|
||||
*pDS++ = *reinterpret_cast<sal_Int32*>(pSV);
|
||||
|
||||
#define INSERT_INT16(pSV, nr, pGPR, pDS) \
|
||||
if (nr < MAX_GP_REGS) \
|
||||
pGPR[nr++] = *reinterpret_cast<sal_Int16*>(pSV); \
|
||||
else \
|
||||
*pDS++ = *reinterpret_cast<sal_Int16*>(pSV);
|
||||
|
||||
#define INSERT_UINT16(pSV, nr, pGPR, pDS) \
|
||||
if (nr < MAX_GP_REGS) \
|
||||
pGPR[nr++] = *reinterpret_cast<sal_uInt16*>(pSV); \
|
||||
else \
|
||||
*pDS++ = *reinterpret_cast<sal_uInt16*>(pSV);
|
||||
|
||||
#define INSERT_INT8(pSV, nr, pGPR, pDS) \
|
||||
if (nr < MAX_GP_REGS) \
|
||||
pGPR[nr++] = *reinterpret_cast<sal_Int8*>(pSV); \
|
||||
else \
|
||||
*pDS++ = *reinterpret_cast<sal_Int8*>(pSV);
|
||||
#include "abi.hxx"
|
||||
|
||||
using namespace ::com::sun::star::uno;
|
||||
|
||||
namespace
|
||||
{
|
||||
bool isReturnInFPR(const typelib_TypeDescription* pTypeDescr, sal_uInt32& nSize)
|
||||
void pushArgs(unsigned long value, unsigned long* const stack, sal_Int32* const sp,
|
||||
unsigned long* const regs, sal_Int32* const nregs)
|
||||
{
|
||||
const typelib_CompoundTypeDescription* p
|
||||
= reinterpret_cast<const typelib_CompoundTypeDescription*>(pTypeDescr);
|
||||
|
||||
for (sal_Int32 i = 0; i < p->nMembers; ++i)
|
||||
{
|
||||
typelib_TypeDescriptionReference* pTypeInStruct = p->ppTypeRefs[i];
|
||||
|
||||
switch (pTypeInStruct->eTypeClass)
|
||||
{
|
||||
case typelib_TypeClass_STRUCT:
|
||||
case typelib_TypeClass_EXCEPTION:
|
||||
{
|
||||
typelib_TypeDescription* t = 0;
|
||||
TYPELIB_DANGER_GET(&t, pTypeInStruct);
|
||||
bool isFPR = isReturnInFPR(t, nSize);
|
||||
TYPELIB_DANGER_RELEASE(t);
|
||||
if (!isFPR)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case typelib_TypeClass_FLOAT:
|
||||
case typelib_TypeClass_DOUBLE:
|
||||
if (nSize >= 16)
|
||||
return false;
|
||||
nSize += 8;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void fillReturn(const typelib_TypeDescription* pTypeDescr, sal_Int64* gret, double* fret,
|
||||
void* pRegisterReturn)
|
||||
{
|
||||
sal_uInt32 nSize = 0;
|
||||
if (isReturnInFPR(pTypeDescr, nSize))
|
||||
{
|
||||
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
|
||||
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
|
||||
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[1];
|
||||
}
|
||||
(*nregs != 8 ? regs[(*nregs)++] : stack[(*sp)++]) = value;
|
||||
}
|
||||
|
||||
static void callVirtualMethod(void* pAdjustedThisPtr, sal_Int32 nVtableIndex, void* pRegisterReturn,
|
||||
typelib_TypeDescriptionReference* pReturnTypeRef, bool bSimpleReturn,
|
||||
sal_uInt64* pStack, sal_uInt32 nStack, sal_uInt64* pGPR, double* pFPR,
|
||||
sal_uInt32 nREG)
|
||||
sal_uInt64* pStack, sal_uInt32 nStack, sal_uInt64* pGPR, double* pFPR)
|
||||
{
|
||||
// Should not happen, but...
|
||||
static_assert(MAX_GP_REGS == MAX_FP_REGS, "must be the same size");
|
||||
if (nREG > MAX_GP_REGS)
|
||||
nREG = MAX_GP_REGS;
|
||||
|
||||
// Get pointer to method
|
||||
sal_uInt64 pMethod = *((sal_uInt64*)pAdjustedThisPtr);
|
||||
pMethod += 8 * nVtableIndex;
|
||||
|
@ -211,10 +125,7 @@ static void callVirtualMethod(void* pAdjustedThisPtr, sal_Int32 nVtableIndex, vo
|
|||
sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
|
||||
if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
|
||||
{
|
||||
typelib_TypeDescription* pTypeDescr = 0;
|
||||
TYPELIB_DANGER_GET(&pTypeDescr, pReturnTypeRef);
|
||||
fillReturn(pTypeDescr, gret, fret, pRegisterReturn);
|
||||
TYPELIB_DANGER_RELEASE(pTypeDescr);
|
||||
loongarch64::fillReturn(pReturnTypeRef, gret, fret, pRegisterReturn);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -232,10 +143,12 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
|
|||
// max space for: [complex ret ptr], values|ptr ...
|
||||
sal_uInt64* pStack = (sal_uInt64*)__builtin_alloca(((nParams + 3) * sizeof(sal_Int64)));
|
||||
sal_uInt64* pStackStart = pStack;
|
||||
sal_Int32 sp = 0;
|
||||
|
||||
sal_uInt64 pGPR[MAX_GP_REGS];
|
||||
sal_Int32 gCount = 0;
|
||||
double pFPR[MAX_FP_REGS];
|
||||
sal_uInt32 nREG = 0;
|
||||
sal_Int32 fCount = 0;
|
||||
|
||||
// return
|
||||
typelib_TypeDescription* pReturnTypeDescr = 0;
|
||||
|
@ -254,7 +167,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
|
|||
pCppReturn = bridges::cpp_uno::shared::relatesToInterfaceType(pReturnTypeDescr)
|
||||
? __builtin_alloca(pReturnTypeDescr->nSize)
|
||||
: pUnoReturn;
|
||||
INSERT_INT64(&pCppReturn, nREG, pGPR, pStack);
|
||||
pGPR[gCount++] = reinterpret_cast<unsigned long>(pCppReturn);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -264,7 +177,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
|
|||
|
||||
// push this
|
||||
void* pAdjustedThisPtr = reinterpret_cast<void**>(pThis->getCppI()) + aVtableSlot.offset;
|
||||
INSERT_INT64(&pAdjustedThisPtr, nREG, pGPR, pStack);
|
||||
pGPR[gCount++] = reinterpret_cast<unsigned long>(pAdjustedThisPtr);
|
||||
|
||||
// args
|
||||
void** pCppArgs = (void**)alloca(3 * sizeof(void*) * nParams);
|
||||
|
@ -290,30 +203,49 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
|
|||
switch (pParamTypeDescr->eTypeClass)
|
||||
{
|
||||
case typelib_TypeClass_LONG:
|
||||
case typelib_TypeClass_UNSIGNED_LONG:
|
||||
INSERT_INT64(pCppArgs[nPos], nREG, pGPR, pStack);
|
||||
break;
|
||||
case typelib_TypeClass_ENUM:
|
||||
INSERT_INT32(pCppArgs[nPos], nREG, pGPR, pStack);
|
||||
pushArgs(*static_cast<sal_Int32*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
case typelib_TypeClass_UNSIGNED_LONG:
|
||||
pushArgs(*static_cast<sal_uInt32*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
case typelib_TypeClass_CHAR:
|
||||
pushArgs(*static_cast<sal_Unicode*>(pCppArgs[nPos]), pStack, &sp, pGPR,
|
||||
&gCount);
|
||||
break;
|
||||
case typelib_TypeClass_SHORT:
|
||||
INSERT_INT16(pCppArgs[nPos], nREG, pGPR, pStack);
|
||||
pushArgs(*static_cast<sal_Int16*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
case typelib_TypeClass_UNSIGNED_SHORT:
|
||||
INSERT_UINT16(pCppArgs[nPos], nREG, pGPR, pStack);
|
||||
pushArgs(*static_cast<sal_uInt16*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
case typelib_TypeClass_BOOLEAN:
|
||||
pushArgs(static_cast<unsigned long>(*static_cast<sal_Bool*>(pCppArgs[nPos])),
|
||||
pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
case typelib_TypeClass_BYTE:
|
||||
INSERT_INT8(pCppArgs[nPos], nREG, pGPR, pStack);
|
||||
pushArgs(*static_cast<sal_Int8*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
case typelib_TypeClass_FLOAT:
|
||||
case typelib_TypeClass_DOUBLE:
|
||||
INSERT_FLOAT_DOUBLE(pCppArgs[nPos], nREG, pFPR, pStack);
|
||||
if (fCount != MAX_FP_REGS)
|
||||
{
|
||||
pFPR[fCount++] = *static_cast<double*>(pCppArgs[nPos]);
|
||||
}
|
||||
else if (gCount != MAX_GP_REGS)
|
||||
{
|
||||
pGPR[gCount++] = *static_cast<unsigned long*>(pCppArgs[nPos]);
|
||||
}
|
||||
else
|
||||
{
|
||||
pStack[sp++] = *static_cast<unsigned long*>(pCppArgs[nPos]);
|
||||
}
|
||||
break;
|
||||
case typelib_TypeClass_HYPER:
|
||||
pushArgs(*static_cast<sal_Int64*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
case typelib_TypeClass_UNSIGNED_HYPER:
|
||||
INSERT_INT64(pCppArgs[nPos], nREG, pGPR, pStack);
|
||||
pushArgs(*static_cast<sal_uInt64*>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -349,7 +281,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
|
|||
// no longer needed
|
||||
TYPELIB_DANGER_RELEASE(pParamTypeDescr);
|
||||
}
|
||||
INSERT_INT64(&(pCppArgs[nPos]), nREG, pGPR, pStack);
|
||||
pushArgs(reinterpret_cast<unsigned long>(pCppArgs[nPos]), pStack, &sp, pGPR, &gCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +290,7 @@ static void cpp_call(bridges::cpp_uno::shared::UnoInterfaceProxy* pThis,
|
|||
try
|
||||
{
|
||||
callVirtualMethod(pAdjustedThisPtr, aVtableSlot.index, pCppReturn, pReturnTypeRef,
|
||||
bSimpleReturn, pStackStart, (pStack - pStackStart), pGPR, pFPR, nREG);
|
||||
bSimpleReturn, pStackStart, sp, pGPR, pFPR);
|
||||
}
|
||||
catch (css::uno::Exception&)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue