bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx | 139 ++++++++++++++++++ bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx | 121 +++++++++++++++ 2 files changed, 258 insertions(+), 2 deletions(-)
New commits: commit 99d3442285f983deb142a12ceb91574ef9800dec Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Thu Nov 12 23:49:57 2020 +0200 Commit: Tor Lillqvist <t...@collabora.com> CommitDate: Sun Nov 15 10:47:34 2020 +0100 Improve the C++/UNO bridge for macOS on Apple Silicon Now bridgetest (as improved by my previous commit) passes. That doesn't necessarily prove much, though, I am sure there are interesting corner cases that it doesn't exercise. Anyway, making this work was easier than I had feared. Unlike the arm64 ABI used on Linux, on macOS (and iOS, but we don't really use the C++/UNO bridge for iOS) we need to pack parameters smaller than eight bytes according to their natural alignment. Bytes take one byte, shorts two bytes aligned at a two-byte boundary, etc. Change-Id: I5b7dc2f8fce41ddec88df0e688898a074d8b2dad Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105773 Tested-by: Tor Lillqvist <t...@collabora.com> Reviewed-by: Tor Lillqvist <t...@collabora.com> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105889 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx index a67f2ca611ea..830c42eb52f8 100644 --- a/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/cpp2uno.cxx @@ -70,11 +70,142 @@ void call( sal_Int32 ngpr = 1; sal_Int32 nfpr = 0; sal_Int32 sp = 0; +#ifdef MACOSX + sal_Int32 subsp = 0; +#endif for (sal_Int32 i = 0; i != count; ++i) { if (!parameters[i].bOut && bridges::cpp_uno::shared::isSimpleType(parameters[i].pTypeRef)) { switch (parameters[i].pTypeRef->eTypeClass) { +#ifdef MACOSX + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + if (ngpr < 8) + { + args[i] = gpr + ngpr; + ngpr++; + } + else + { + args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp); + subsp += 1; + if (subsp == 8) + { + sp++; + subsp = 0; + } + } + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_CHAR: + if (ngpr < 8) + { + args[i] = gpr + ngpr; + ngpr++; + } + else + { + subsp = (subsp + 1) & ~0x1; + if (subsp == 8) + { + sp++; + subsp = 0; + } + args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp); + subsp += 2; + if (subsp == 8) + { + sp++; + subsp = 0; + } + } + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_ENUM: + if (ngpr < 8) + { + args[i] = gpr + ngpr; + ngpr++; + } + else + { + subsp = (subsp + 3) & ~0x3; + if (subsp == 8) + { + sp++; + subsp = 0; + } + args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp); + subsp += 4; + if (subsp == 8) + { + sp++; + subsp = 0; + } + } + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + if (ngpr < 8) + { + args[i] = gpr + ngpr; + ngpr++; + } + else + { + if (subsp > 0) + { + sp++; + subsp = 0; + } + args[i] = stack + sp; + sp++; + } + break; + case typelib_TypeClass_FLOAT: + if (nfpr < 8) + { + args[i] = fpr + nfpr; + nfpr++; + } + else + { + subsp = (subsp + 3) & ~0x3; + if (subsp == 8) + { + sp++; + subsp = 0; + } + args[i] = reinterpret_cast<void **>(reinterpret_cast<uintptr_t>(stack + sp) + subsp); + subsp += 4; + if (subsp == 8) + { + sp++; + subsp = 0; + } + } + break; + case typelib_TypeClass_DOUBLE: + if (nfpr < 8) + { + args[i] = fpr + nfpr; + nfpr++; + } + else + { + if (subsp > 0) + { + sp++; + subsp = 0; + } + args[i] = stack + sp; + sp++; + } + break; +#else case typelib_TypeClass_BOOLEAN: case typelib_TypeClass_BYTE: case typelib_TypeClass_SHORT: @@ -91,11 +222,19 @@ void call( case typelib_TypeClass_DOUBLE: args[i] = nfpr == 8 ? stack + sp++ : fpr + nfpr++; break; +#endif default: assert(false); } argtds[i] = 0; } else { +#ifdef MACOSX + if (subsp > 0) + { + sp++; + subsp = 0; + } +#endif cppArgs[i] = reinterpret_cast<void *>( ngpr == 8 ? stack[sp++] : gpr[ngpr++]); typelib_TypeDescription * ptd = 0; diff --git a/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx index 0847dfc76db5..8ce4705c93e5 100644 --- a/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx +++ b/bridges/source/cpp_uno/gcc3_linux_aarch64/uno2cpp.cxx @@ -46,10 +46,82 @@ namespace { void pushArgument( - unsigned long value, unsigned long * stack, sal_Int32 * sp, - unsigned long * regs, sal_Int32 * nregs) +#ifdef MACOSX + typelib_TypeClass typeclass, + sal_Int32 * const subsp, +#endif + unsigned long value, unsigned long * const stack, sal_Int32 * const sp, + unsigned long * const regs, sal_Int32 * const nregs) { +#ifdef MACOSX + if (*nregs != 8) + { + regs[(*nregs)++] = value; + } + else + { + switch (typeclass) { + case typelib_TypeClass_BOOLEAN: + case typelib_TypeClass_BYTE: + *reinterpret_cast<uint8_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value; + (*subsp) += 1; + if (*subsp == 8) + { + (*sp)++; + *subsp = 0; + } + break; + case typelib_TypeClass_SHORT: + case typelib_TypeClass_UNSIGNED_SHORT: + case typelib_TypeClass_CHAR: + *subsp = (*subsp + 1) & ~0x1; + if (*subsp == 8) + { + (*sp)++; + *subsp = 0; + } + *reinterpret_cast<uint16_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value; + (*subsp) += 2; + if (*subsp == 8) + { + (*sp)++; + *subsp = 0; + } + break; + case typelib_TypeClass_LONG: + case typelib_TypeClass_UNSIGNED_LONG: + case typelib_TypeClass_ENUM: + case typelib_TypeClass_FLOAT: + *subsp = (*subsp + 3) & ~0x3; + if (*subsp == 8) + { + (*sp)++; + *subsp = 0; + } + *reinterpret_cast<uint32_t*>(reinterpret_cast<uintptr_t>(stack + *sp) + *subsp) = value; + (*subsp) += 4; + if (*subsp == 8) + { + (*sp)++; + *subsp = 0; + } + break; + case typelib_TypeClass_HYPER: + case typelib_TypeClass_UNSIGNED_HYPER: + default: + if (*subsp > 0) + { + (*sp)++; + *subsp = 0; + } + stack[*sp] = value; + (*sp)++; + break; + } + } +#else (*nregs != 8 ? regs[(*nregs)++] : stack[(*sp)++]) = value; +#endif } void call( @@ -69,6 +141,9 @@ void call( unsigned long * stack = static_cast<unsigned long *>( alloca(count * sizeof (unsigned long))); sal_Int32 sp = 0; +#ifdef MACOSX + sal_Int32 subsp = 0; +#endif unsigned long gpr[8]; sal_Int32 ngpr = 0; unsigned long fpr[8]; @@ -86,57 +161,90 @@ void call( switch (parameters[i].pTypeRef->eTypeClass) { case typelib_TypeClass_BOOLEAN: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_Bool *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_BYTE: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_Int8 *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_SHORT: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_Int16 *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_UNSIGNED_SHORT: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_uInt16 *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_LONG: case typelib_TypeClass_ENUM: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_Int32 *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_UNSIGNED_LONG: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_uInt32 *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_HYPER: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_Int64 *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_UNSIGNED_HYPER: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_uInt64 *>(arguments[i]), stack, &sp, gpr, &ngpr); break; case typelib_TypeClass_FLOAT: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<unsigned int *>(arguments[i]), stack, &sp, fpr, &nfpr); break; case typelib_TypeClass_DOUBLE: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<unsigned long *>(arguments[i]), stack, &sp, fpr, &nfpr); break; case typelib_TypeClass_CHAR: pushArgument( +#ifdef MACOSX + parameters[i].pTypeRef->eTypeClass, &subsp, +#endif *static_cast<sal_Unicode *>(arguments[i]), stack, &sp, gpr, &ngpr); break; @@ -151,6 +259,9 @@ void call( uno_constructData(cppArgs[i], ptd); ptds[i] = ptd; pushArgument( +#ifdef MACOSX + typelib_TypeClass_HYPER, &subsp, +#endif reinterpret_cast<unsigned long>(cppArgs[i]), stack, &sp, gpr, &ngpr); } else if (bridges::cpp_uno::shared::relatesToInterfaceType(ptd)) { @@ -160,11 +271,17 @@ void call( proxy->getBridge()->getUno2Cpp()); ptds[i] = ptd; pushArgument( +#ifdef MACOSX + typelib_TypeClass_HYPER, &subsp, +#endif reinterpret_cast<unsigned long>(cppArgs[i]), stack, &sp, gpr, &ngpr); } else { cppArgs[i] = 0; pushArgument( +#ifdef MACOSX + typelib_TypeClass_HYPER, &subsp, +#endif reinterpret_cast<unsigned long>(arguments[i]), stack, &sp, gpr, &ngpr); TYPELIB_DANGER_RELEASE(ptd); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits