summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwjh-la <wujiahuan@loongson.cn>2023-01-03 17:22:11 +0800
committerStephan Bergmann <sbergman@redhat.com>2023-01-12 09:02:44 +0000
commit14b4f0701c1d8f21e550c57e68c37ae3d8d6f9d6 (patch)
tree8d90556e3fd534fe7d4bfac1fce37522f1a9ea78
parentfix deadlock observed on jenkins (diff)
downloadcore-14b4f0701c1d8f21e550c57e68c37ae3d8d6f9d6.tar.gz
core-14b4f0701c1d8f21e550c57e68c37ae3d8d6f9d6.zip
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> (cherry picked from commit d3152ea3ae0d6d1bdbc6379c3505812434da6466) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145303
-rw-r--r--bridges/Library_cpp_uno.mk2
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx137
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx51
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/call.hxx6
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/call.s15
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx97
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/share.hxx3
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx150
8 files changed, 288 insertions, 173 deletions
diff --git a/bridges/Library_cpp_uno.mk b/bridges/Library_cpp_uno.mk
index 1718202e94d0..5dc92c23cdbb 100644
--- a/bridges/Library_cpp_uno.mk
+++ b/bridges/Library_cpp_uno.mk
@@ -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
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx
new file mode 100644
index 000000000000..686cbb596317
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx
@@ -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: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx
new file mode 100644
index 000000000000..90aa544f128b
--- /dev/null
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx
@@ -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: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.hxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.hxx
index 51b9772c0f51..ee8daa9ad04a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.hxx
@@ -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: */
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.s b/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.s
index b8388508eea1..d27b5bd8a552 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.s
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/call.s
@@ -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
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
index 0273b39da4e3..299861de753c 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
@@ -28,6 +28,7 @@
#include "vtablefactory.hxx"
#include "call.hxx"
#include "share.hxx"
+#include "abi.hxx"
#include <stdio.h>
#include <string.h>
@@ -84,19 +85,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
@@ -105,9 +112,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
@@ -119,7 +124,7 @@ cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
}
// pop this
- nREG++;
+ gCount++;
// stack space
static_assert(sizeof(void*) == sizeof(sal_Int64), "### unexpected size!");
@@ -147,31 +152,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
@@ -180,16 +169,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!
@@ -240,7 +221,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...
{
@@ -277,12 +258,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;
+ }
}
}
@@ -290,9 +276,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!");
@@ -331,7 +316,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:
@@ -367,11 +352,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
{
@@ -394,7 +379,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);
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/share.hxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/share.hxx
index 331ed789e39f..258aac64a77e 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/share.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/share.hxx
@@ -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*);
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx
index 0004794ce55d..7242a43bd76c 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx
@@ -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&)
{