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 e0df85554b533fab67a5a91193024e4876c5ec02
Author:     Tor Lillqvist <t...@collabora.com>
AuthorDate: Thu Nov 12 23:49:57 2020 +0200
Commit:     Tor Lillqvist <t...@collabora.com>
CommitDate: Fri Nov 13 20:01:51 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>

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 760a7b38551d..14e4afa46cc0 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

Reply via email to