summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx30
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx6
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx10
-rw-r--r--bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx1
4 files changed, 44 insertions, 3 deletions
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx
index 686cbb596317..f9eb09517358 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.cxx
@@ -56,6 +56,8 @@ int loongarch64::flatten_struct(typelib_TypeDescription* pTypeDescr, Registers&
regs.priorInt = true;
break;
case typelib_TypeClass_FLOAT:
+ regs.complex_float = true;
+ [[fallthrough]];
case typelib_TypeClass_DOUBLE:
regs.nr_fp++;
if (!regs.priorInt && !regs.priorFp)
@@ -88,22 +90,34 @@ loongarch64::ReturnKind loongarch64::getReturnKind(typelib_TypeDescriptionRefere
return ReturnKind::RegistersFp;
case typelib_TypeClass_STRUCT:
{
- Registers regs = { 0, 0, false, false };
+ Registers regs = { false, false, false, 0, 0 };
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)
+ {
+ if (regs.complex_float && pTypeRef->pType->nSize == 8)
+ return ReturnKind::RegistersTwoFloat;
return ReturnKind::RegistersFp;
+ }
if (sum == 2 && regs.nr_fp == regs.nr_int)
{
if (regs.priorInt)
+ {
+ if (regs.complex_float && pTypeRef->pType->nSize == 8)
+ return ReturnKind::RegistersIntFloat;
return ReturnKind::RegistersIntFp;
+ }
if (regs.priorFp)
+ {
+ if (regs.complex_float && pTypeRef->pType->nSize == 8)
+ return ReturnKind::RegistersFloatInt;
return ReturnKind::RegistersFpInt;
+ }
}
- return ReturnKind::RegistersInt;
}
+ [[fallthrough]];
default:
return ReturnKind::RegistersInt;
}
@@ -119,14 +133,26 @@ void loongarch64::fillReturn(typelib_TypeDescriptionReference* pTypeRef, sal_Int
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[1];
break;
+ case ReturnKind::RegistersTwoFloat:
+ memcpy(reinterpret_cast<char*>(pRegisterReturn), &(fret[0]), 4);
+ memcpy(reinterpret_cast<char*>(pRegisterReturn) + 4, &(fret[1]), 4);
+ break;
case ReturnKind::RegistersFpInt:
reinterpret_cast<double*>(pRegisterReturn)[0] = fret[0];
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[0];
break;
+ case ReturnKind::RegistersFloatInt:
+ memcpy(reinterpret_cast<char*>(pRegisterReturn), fret, 4);
+ memcpy(reinterpret_cast<char*>(pRegisterReturn) + 4, gret, 4);
+ break;
case ReturnKind::RegistersIntFp:
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
reinterpret_cast<double*>(pRegisterReturn)[1] = fret[0];
break;
+ case ReturnKind::RegistersIntFloat:
+ memcpy(reinterpret_cast<char*>(pRegisterReturn), gret, 4);
+ memcpy(reinterpret_cast<char*>(pRegisterReturn) + 4, fret, 4);
+ break;
default:
reinterpret_cast<sal_Int64*>(pRegisterReturn)[0] = gret[0];
reinterpret_cast<sal_Int64*>(pRegisterReturn)[1] = gret[1];
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx
index 90aa544f128b..1fe9e9b58866 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/abi.hxx
@@ -30,11 +30,15 @@ enum class ReturnKind
{
RegistersInt,
RegistersFp,
+ RegistersTwoFloat,
RegistersFpInt,
- RegistersIntFp
+ RegistersFloatInt,
+ RegistersIntFp,
+ RegistersIntFloat
};
typedef struct Registers
{
+ bool complex_float;
bool priorInt;
bool priorFp;
int nr_fp;
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
index aa8f4be3cf72..1a0c42b0da67 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/cpp2uno.cxx
@@ -263,10 +263,19 @@ static int cpp2uno_call(bridges::cpp_uno::shared::CppInterfaceProxy* pThis,
}
switch (returnKind)
{
+ case loongarch64::ReturnKind::RegistersIntFloat:
+ memcpy(pRegisterReturn + 1, static_cast<char*>(pUnoReturn) + 4, 4);
+ [[fallthrough]];
case loongarch64::ReturnKind::RegistersIntFp:
return 0;
+ case loongarch64::ReturnKind::RegistersFloatInt:
+ memcpy(pRegisterReturn + 1, static_cast<char*>(pUnoReturn) + 4, 4);
+ [[fallthrough]];
case loongarch64::ReturnKind::RegistersFpInt:
return 1;
+ case loongarch64::ReturnKind::RegistersTwoFloat:
+ memcpy(pRegisterReturn + 1, static_cast<char*>(pUnoReturn) + 4, 4);
+ [[fallthrough]];
default:
return -1;
}
@@ -386,6 +395,7 @@ int cpp_vtable_call(sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset, void** gp
TYPELIB_DANGER_RELEASE(pTD);
}
} // else perform queryInterface()
+ [[fallthrough]];
default:
typelib_InterfaceMethodTypeDescription* pMethodTD
= reinterpret_cast<typelib_InterfaceMethodTypeDescription*>(
diff --git a/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx
index 7242a43bd76c..c4e7815e0a0a 100644
--- a/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx
+++ b/bridges/source/cpp_uno/gcc3_linux_loongarch64/uno2cpp.cxx
@@ -450,6 +450,7 @@ void unoInterfaceProxyDispatch(uno_Interface* pUnoI, const typelib_TypeDescripti
TYPELIB_DANGER_RELEASE(pTD);
}
} // else perform queryInterface()
+ [[fallthrough]];
default:
// dependent dispatch
cpp_call(