There is still lots to do w/ the Python3 stuff.

This also changes the thing for macOS baseline: We have to bump up to BigSur 
being the oldest supported version, and even then we might even need to go 
newer as I dig more into it. The key isn't just Aarch64 support but also the 
oldest version of Xcode that _knows_ about Apple Silicon!

Still. Progress.

> On Jun 5, 2026, at 12:16 PM, [email protected] wrote:
> 
> Awesome Job! this is a great step. Highly appreciated on my side.
> 
> 
> 
> Am 05.06.2026 um 17:12 schrieb Dave Fisher:
>> I want to highlight the two hugely important contributions in this commit.
>> 
>> 1. Native Apple Silicon support.
>> 2. Python 3.10 support.
>> 
>> A big thanks to Jim!
>> 
>> Best,
>> Dave
>> 
>>> On Jun 5, 2026, at 8:46 AM, [email protected] wrote:
>>> 
>>> This is an automated email from the ASF dual-hosted git repository.
>>> 
>>> jimjag pushed a commit to branch trunk
>>> in repository https://gitbox.apache.org/repos/asf/openoffice.git
>>> 
>>> 
>>> The following commit(s) were added to refs/heads/trunk by this push:
>>>     new 5e139d9fe4 Native Apple Silicon (arm64) support and bundled Python 
>>> 3.10 baseline
>>> 5e139d9fe4 is described below
>>> 
>>> commit 5e139d9fe42a654147771da4118aea6285c03168
>>> Author: Jim Jagielski <[email protected]>
>>> AuthorDate: Fri Jun 5 09:44:36 2026 -0400
>>> 
>>>    Native Apple Silicon (arm64) support and bundled Python 3.10 baseline
>>> 
>>>    Squashed combination of two efforts, applied onto trunk as a single
>>>    commit. (trunk is not intended to be buildable; this lands the work for
>>>    reference/integration.)
>>> 
>>>    === Apple Silicon (macOS arm64 / AAPCS64) ===
>>>    Build plumbing: set_soenv.in + source_soenv.sh arm64 Darwin branch
>>>    (CPU=R, CPUNAME=AARCH64, OUTPATH=unxmaccr); new solenv/inc/unxmaccr.mk
>>>    and unx.mk dispatch; macro.hxx AARCH64 arch string; osarch.pm +
>>>    gbuild/platform/macosx.mk arch entries; configure.ac arm64 host
>>>    detection, Big Sur+ version math, and 11.0 deployment target.
>>> 
>>>    C++/UNO bridge (new s5abi_macosx_aarch64): abi.cxx/hxx AAPCS64 classifier
>>>    (HFA + <=16B/>16B size rules), uno2cpp + call.s AArch64 trampoline,
>>>    cpp2uno incoming path + privateSnippetExecutor + AArch64 codeSnippet
>>>    codegen (x8 indirect-result handled, not displacing this/x0), share.hxx
>>>    __cxa_exception reserved-member alignment fix; Library_cpp_uno.mk +
>>>    makefile.mk wiring. sal/osl/unx/interlck.c arm64 atomics (__sync_* ->
>>>    LSE).
>>> 
>>>    Externals: openssl darwin64-arm64-cc; icu arm64 little-endian. (NSS 3.39
>>>    deferred -- too old for arm64.)
>>> 
>>>    Packaging/JVM: Info.plist LSMinimumSystemVersion 11.0; installer
>>>    download.pm/worker.pm/update_module_ignore_lists.pl recognize unxmaccr;
>>>    jvmfwk modern macOS JDK discovery (/Library/Java/JavaVirtualMachines +
>>>    Contents/Home probe).
>>> 
>>>    The ABI/atomics/trampoline/JDK-discovery code was unit-tested natively
>>>    on an arm64 macOS host; a full AOO build (and bridgetest) was not run.
>>>    Code-signing infra (mandatory for arm64 distribution) is NOT included.
>>> 
>>>    === Bundled Python 2.7.18 -> 3.10 baseline (Unix/macOS first) ===
>>>    pyversion.mk/_dmake.mk -> 3.10.18 (single version knob). Shipped .py
>>>    fixes: imp -> types.ModuleType (pythonscript.py, pythonloader.py) and
>>>    file() -> open(); mailmerge.py Py3 email module imports + encoders.
>>>    Windows Python 3 build and the makefile.mk/d.lst/configure.ac Py3 work
>>>    are NOT included (separate, larger effort).
>>> 
>>>    NOTE: macOS 11 becomes the minimum supported version. Python 3.10 is
>>>    EOL 2026-10; the version knob allows a later bump.
>>> ---
>>> main/bridges/Library_cpp_uno.mk                    |  18 +
>>> .../source/cpp_uno/s5abi_macosx_aarch64/abi.cxx    | 261 +++++++++
>>> .../source/cpp_uno/s5abi_macosx_aarch64/abi.hxx    |  86 +++
>>> .../source/cpp_uno/s5abi_macosx_aarch64/call.s     | 168 ++++++
>>> .../cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx       | 543 +++++++++++++++++++
>>> .../source/cpp_uno/s5abi_macosx_aarch64/except.cxx | 358 +++++++++++++
>>> .../cpp_uno/s5abi_macosx_aarch64/makefile.mk       |  81 +++
>>> .../source/cpp_uno/s5abi_macosx_aarch64/share.hxx  | 116 ++++
>>> .../cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx       | 581 
>>> +++++++++++++++++++++
>>> main/configure.ac                                  |  42 +-
>>> main/icu/icu4c-4_2_1-src.patch                     |   2 +-
>>> main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx    |  14 +
>>> main/openssl/makefile.mk                           |   4 +
>>> main/python/pyversion.mk                           |   4 +-
>>> main/python/pyversion_dmake.mk                     |   4 +-
>>> main/pyuno/source/loader/pythonloader.py           |   6 +-
>>> main/sal/osl/unx/interlck.c                        |  23 +
>>> main/sal/rtl/source/macro.hxx                      |   2 +
>>> main/scripting/source/pyprov/mailmerge.py          |  16 +-
>>> main/scripting/source/pyprov/pythonscript.py       |  10 +-
>>> main/set_soenv.in                                  |   8 +
>>> main/setup_native/source/mac/Info.plist.langpack   |   2 +-
>>> main/solenv/bin/modules/installer/download.pm      |   4 +
>>> main/solenv/bin/modules/installer/worker.pm        |   4 +
>>> main/solenv/bin/modules/osarch.pm                  |  12 +-
>>> main/solenv/bin/update_module_ignore_lists.pl      |   1 +
>>> main/solenv/gbuild/platform/macosx.mk              |   2 +
>>> main/solenv/inc/unx.mk                             |   4 +
>>> main/solenv/inc/unxmaccr.mk                        |  42 ++
>>> main/source_soenv.sh                               |   3 +
>>> main/sysui/desktop/macosx/Info.plist               |   2 +-
>>> 31 files changed, 2391 insertions(+), 32 deletions(-)
>>> 
>>> diff --git a/main/bridges/Library_cpp_uno.mk 
>>> b/main/bridges/Library_cpp_uno.mk
>>> index d868df954f..0d8525362a 100644
>>> --- a/main/bridges/Library_cpp_uno.mk
>>> +++ b/main/bridges/Library_cpp_uno.mk
>>> @@ -431,6 +431,24 @@ $(eval $(call 
>>> gb_Library_add_exception_objects,$(COMNAME)_uno,\
>>>     bridges/source/cpp_uno/s5abi_macosx_x86-64/uno2cpp \
>>> ))
>>> 
>>> +###########################################################
>>> +else ifeq ($(OS)-$(CPUNAME)-$(COMNAME),MACOSX-AARCH64-s5abi)
>>> +###########################################################
>>> +# Apple Silicon (arm64) bridge. The COMNAME is "s5abi" macOS-wide (set in
>>> +# solenv/gbuild/platform/macosx.mk); for arm64 the actual calling 
>>> convention
>>> +# is AAPCS64, so "s5abi" here is a historical label, not a literal ABI 
>>> claim.
>>> +
>>> +$(eval $(call gb_Library_add_exception_objects,$(COMNAME)_uno,\
>>> +   bridges/source/cpp_uno/s5abi_macosx_aarch64/abi \
>>> +   bridges/source/cpp_uno/s5abi_macosx_aarch64/except \
>>> +   bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno \
>>> +   bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp \
>>> +))
>>> +
>>> +$(eval $(call gb_Library_add_asmobjects,$(COMNAME)_uno,\
>>> +   bridges/source/cpp_uno/s5abi_macosx_aarch64/call \
>>> +))
>>> +
>>> #########################################################
>>> else ifeq ($(OS)-$(CPUNAME)-$(COMNAME),NETBSD-INTEL-gcc3)
>>> #########################################################
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
>>> new file mode 100644
>>> index 0000000000..d51c5ccf12
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.cxx
>>> @@ -0,0 +1,261 @@
>>> +/**************************************************************
>>> + *
>>> + * 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
>>> + *
>>> + * Unless required by applicable law or agreed to in writing,
>>> + * software distributed under the License is distributed on an
>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> + * KIND, either express or implied.  See the License for the
>>> + * specific language governing permissions and limitations
>>> + * under the License.
>>> + *
>>> + *************************************************************/
>>> +
>>> +
>>> +
>>> +// MARKER(update_precomp.py): autogen include statement, do not remove
>>> +#include "precompiled_bridges.hxx"
>>> +
>>> +// This is an implementation of the parameter-classification rules of the
>>> +// AArch64 procedure call standard ("Procedure Call Standard for the Arm 
>>> 64-bit
>>> +// Architecture", ARM IHI 0055), with the deviations documented in Apple's
>>> +// "Writing ARM64 Code for Apple Platforms".
>>> +//
>>> +// Unlike the System V AMD64 ABI (used by the x86-64 bridge), AAPCS64 does 
>>> not
>>> +// split aggregates into per-eightbyte INTEGER/SSE classes.  Instead:
>>> +//   * scalars go in one GPR (x) or one FP/SIMD (v) register;
>>> +//   * a Homogeneous Floating-point Aggregate (HFA: <= 4 members, all the 
>>> same
>>> +//     FP type, recursively) goes in consecutive v registers;
>>> +//   * any other aggregate <= 16 bytes goes in 1-2 GPRs;
>>> +//   * a non-HFA aggregate > 16 bytes is passed indirectly (a pointer to a
>>> +//     caller-allocated copy).
>>> +// Register fill is "all or nothing": if an aggregate does not fit 
>>> entirely in
>>> +// the remaining registers of its bank, it is passed wholly on the stack.
>>> +//
>>> +// This is a clean-room implementation from the public specifications; see
>>> +// ../../../../AAPCS64_BRIDGE_SPEC.md.  libffi's aarch64 backend was 
>>> consulted
>>> +// only as a behavioural reference; no code is copied.
>>> +
>>> +#include "abi.hxx"
>>> +
>>> +#include <rtl/ustring.hxx>
>>> +
>>> +using namespace aarch64;
>>> +
>>> +namespace {
>>> +
>>> +// The element type of a Homogeneous Floating-point Aggregate.
>>> +enum HfaKind
>>> +{
>>> +    HFA_NONE,       // not (yet) an HFA
>>> +    HFA_FLOAT,      // all members are FLOAT (4-byte)
>>> +    HFA_DOUBLE      // all members are DOUBLE (8-byte)
>>> +};
>>> +
>>> +// Combine the running HFA kind with a newly-seen member kind.  Two members
>>> +// of different FP types, or any non-FP member, break the homogeneity.
>>> +HfaKind mergeHfa( HfaKind running, HfaKind seen )
>>> +{
>>> +    if ( seen == HFA_NONE )
>>> +        return HFA_NONE;
>>> +    if ( running == HFA_NONE )
>>> +        return seen;
>>> +    return ( running == seen ) ? running : HFA_NONE;
>>> +}
>>> +
>>> +// Recursively determine whether pTypeRef is (part of) a homogeneous
>>> +// floating-point aggregate, accumulating the element kind and member 
>>> count.
>>> +//
>>> +// Returns false the moment homogeneity is violated (a non-FP scalar, or a
>>> +// second distinct FP type, or > 4 elements).  A FLOAT/DOUBLE scalar 
>>> counts as
>>> +// a 1-element HFA of itself; a struct flattens its members (and base 
>>> classes).
>>> +bool collectHfa( typelib_TypeDescriptionReference *pTypeRef, HfaKind 
>>> &rKind, int &rCount )
>>> +{
>>> +    switch ( pTypeRef->eTypeClass )
>>> +    {
>>> +        case typelib_TypeClass_FLOAT:
>>> +            rKind = mergeHfa( rKind, HFA_FLOAT );
>>> +            if ( rKind == HFA_NONE ) return false;
>>> +            return ( ++rCount <= 4 );
>>> +
>>> +        case typelib_TypeClass_DOUBLE:
>>> +            rKind = mergeHfa( rKind, HFA_DOUBLE );
>>> +            if ( rKind == HFA_NONE ) return false;
>>> +            return ( ++rCount <= 4 );
>>> +
>>> +        case typelib_TypeClass_STRUCT:
>>> +        case typelib_TypeClass_EXCEPTION:
>>> +        {
>>> +            typelib_TypeDescription * pTypeDescr = 0;
>>> +            TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
>>> +
>>> +            const typelib_CompoundTypeDescription *pComp =
>>> +                reinterpret_cast<const typelib_CompoundTypeDescription*>( 
>>> pTypeDescr );
>>> +
>>> +            bool bOk = true;
>>> +
>>> +            // Flatten base class first (its members precede ours in 
>>> layout).
>>> +            if ( pComp->pBaseTypeDescription )
>>> +            {
>>> +                bOk = collectHfa(
>>> +                    pComp->pBaseTypeDescription->aBase.pWeakRef, rKind, 
>>> rCount );
>>> +            }
>>> +
>>> +            for ( sal_Int32 i = 0; bOk && i < pComp->nMembers; ++i )
>>> +                bOk = collectHfa( pComp->ppTypeRefs[i], rKind, rCount );
>>> +
>>> +            TYPELIB_DANGER_RELEASE( pTypeDescr );
>>> +            return bOk;
>>> +        }
>>> +
>>> +        default:
>>> +            // Any non-FP, non-aggregate member breaks homogeneity.
>>> +            rKind = HFA_NONE;
>>> +            return false;
>>> +    }
>>> +}
>>> +
>>> +// Classify an aggregate (STRUCT/EXCEPTION).  Sets the GPR/FPR counts and
>>> +// returns true if it is passed in registers, false if it must be passed
>>> +// indirectly (in memory).
>>> +bool classifyAggregate( typelib_TypeDescriptionReference *pTypeRef, int 
>>> &nUsedGPR, int &nUsedFPR )
>>> +{
>>> +    // First, the HFA test.
>>> +    HfaKind kind = HFA_NONE;
>>> +    int count = 0;
>>> +    if ( collectHfa( pTypeRef, kind, count ) && kind != HFA_NONE && count 
>>> >= 1 && count <= 4 )
>>> +    {
>>> +        nUsedGPR = 0;
>>> +        nUsedFPR = count;       // one v register per member
>>> +        return true;
>>> +    }
>>> +
>>> +    // Otherwise classify by size.
>>> +    typelib_TypeDescription * pTypeDescr = 0;
>>> +    TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
>>> +    sal_Int32 nSize = pTypeDescr->nSize;
>>> +    TYPELIB_DANGER_RELEASE( pTypeDescr );
>>> +
>>> +    if ( nSize > 16 )
>>> +    {
>>> +        // Non-HFA aggregate > 16 bytes => passed indirectly.
>>> +        return false;
>>> +    }
>>> +
>>> +    // Non-HFA aggregate <= 16 bytes => 1 or 2 GPRs (8 bytes each).
>>> +    nUsedGPR = ( nSize > 8 ) ? 2 : 1;
>>> +    nUsedFPR = 0;
>>> +    return true;
>>> +}
>>> +
>>> +} // anonymous namespace
>>> +
>>> +bool aarch64::examine_argument( typelib_TypeDescriptionReference 
>>> *pTypeRef, bool /*bInReturn*/, int &nUsedGPR, int &nUsedFPR )
>>> +{
>>> +    nUsedGPR = 0;
>>> +    nUsedFPR = 0;
>>> +
>>> +    switch ( pTypeRef->eTypeClass )
>>> +    {
>>> +        case typelib_TypeClass_VOID:
>>> +            return true;
>>> +
>>> +        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:
>>> +            nUsedGPR = 1;
>>> +            return true;
>>> +
>>> +        case typelib_TypeClass_FLOAT:
>>> +        case typelib_TypeClass_DOUBLE:
>>> +            nUsedFPR = 1;
>>> +            return true;
>>> +
>>> +        // These UNO types are always handled by the bridge as a pointer/
>>> +        // reference (one GPR), never passed by value through this 
>>> classifier.
>>> +        case typelib_TypeClass_STRING:
>>> +        case typelib_TypeClass_TYPE:
>>> +        case typelib_TypeClass_ANY:
>>> +        case typelib_TypeClass_TYPEDEF:
>>> +        case typelib_TypeClass_SEQUENCE:
>>> +        case typelib_TypeClass_INTERFACE:
>>> +            nUsedGPR = 1;
>>> +            return true;
>>> +
>>> +        case typelib_TypeClass_STRUCT:
>>> +        case typelib_TypeClass_EXCEPTION:
>>> +            return classifyAggregate( pTypeRef, nUsedGPR, nUsedFPR );
>>> +
>>> +        default:
>>> +#if OSL_DEBUG_LEVEL > 1
>>> +            OSL_TRACE( "Unhandled case: pTypeRef->eTypeClass == %d\n", 
>>> pTypeRef->eTypeClass );
>>> +#endif
>>> +            OSL_ASSERT( 0 );
>>> +    }
>>> +    return false;
>>> +}
>>> +
>>> +bool aarch64::return_in_hidden_param( typelib_TypeDescriptionReference 
>>> *pTypeRef )
>>> +{
>>> +    int g, s;
>>> +    // Returned in registers iff examine_argument() says it fits; 
>>> otherwise the
>>> +    // caller must pass an indirect-result buffer in x8.
>>> +    return !examine_argument( pTypeRef, true, g, s );
>>> +}
>>> +
>>> +void aarch64::fill_struct( typelib_TypeDescriptionReference *pTypeRef, 
>>> const sal_uInt64 *pGPR, const double *pFPR, void *pStruct )
>>> +{
>>> +    int nUsedGPR = 0;
>>> +    int nUsedFPR = 0;
>>> +    if ( !examine_argument( pTypeRef, true, nUsedGPR, nUsedFPR ) )
>>> +    {
>>> +        // Should not happen: indirect returns are written through x8 
>>> directly,
>>> +        // not scattered here.
>>> +        OSL_ASSERT( 0 );
>>> +        return;
>>> +    }
>>> +
>>> +    if ( nUsedFPR > 0 )
>>> +    {
>>> +        // HFA: each member occupies one v register; the members are 
>>> contiguous
>>> +        // in the struct.  Copy element-by-element to honour FLOAT 
>>> (4-byte) vs
>>> +        // DOUBLE (8-byte) element width.
>>> +        HfaKind kind = HFA_NONE;
>>> +        int count = 0;
>>> +        collectHfa( pTypeRef, kind, count );
>>> +        if ( kind == HFA_FLOAT )
>>> +        {
>>> +            float *pDest = reinterpret_cast<float *>( pStruct );
>>> +            for ( int i = 0; i < nUsedFPR; ++i )
>>> +                pDest[i] = static_cast<float>( pFPR[i] );
>>> +        }
>>> +        else // HFA_DOUBLE
>>> +        {
>>> +            double *pDest = reinterpret_cast<double *>( pStruct );
>>> +            for ( int i = 0; i < nUsedFPR; ++i )
>>> +                pDest[i] = pFPR[i];
>>> +        }
>>> +    }
>>> +    else
>>> +    {
>>> +        // Non-HFA aggregate <= 16 bytes: raw copy of the 1-2 GPRs.
>>> +        sal_uInt64 *pDest = reinterpret_cast<sal_uInt64 *>( pStruct );
>>> +        for ( int i = 0; i < nUsedGPR; ++i )
>>> +            pDest[i] = pGPR[i];
>>> +    }
>>> +}
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
>>> new file mode 100644
>>> index 0000000000..7d55ac076c
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx
>>> @@ -0,0 +1,86 @@
>>> +/**************************************************************
>>> + *
>>> + * 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
>>> + *
>>> + * Unless required by applicable law or agreed to in writing,
>>> + * software distributed under the License is distributed on an
>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> + * KIND, either express or implied.  See the License for the
>>> + * specific language governing permissions and limitations
>>> + * under the License.
>>> + *
>>> + *************************************************************/
>>> +
>>> +
>>> +
>>> +#ifndef _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
>>> +#define _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
>>> +
>>> +// This is an implementation of the AArch64 procedure call standard, as
>>> +// described in "Procedure Call Standard for the Arm 64-bit Architecture"
>>> +// (ARM IHI 0055), with the deviations documented in Apple's "Writing ARM64
>>> +// Code for Apple Platforms".  It is a clean-room implementation written 
>>> from
>>> +// those public specifications; see ../../../../AAPCS64_BRIDGE_SPEC.md.
>>> +
>>> +#include <typelib/typedescription.hxx>
>>> +
>>> +namespace aarch64
>>> +{
>>> +
>>> +/* 8 general purpose registers (x0..x7) are used for parameter passing.
>>> +   Note: the indirect-result-location register x8 is *separate* and is NOT
>>> +   part of this count. */
>>> +const sal_uInt32 MAX_GPR_REGS = 8;
>>> +
>>> +/* 8 SIMD/FP registers (v0..v7) are used for parameter passing. */
>>> +const sal_uInt32 MAX_FPR_REGS = 8;
>>> +
>>> +/* The largest number of registers a single aggregate can occupy: an 
>>> HFA/HVA
>>> +   may use up to 4 FP registers; a non-HFA aggregate passed in GPRs uses at
>>> +   most 2 (16 bytes / 8). */
>>> +const sal_uInt32 MAX_AGGREGATE_REGS = 4;
>>> +
>>> +/* Count the number of registers required to pass the given type.
>>> +
>>> +   Examines the argument and sets the number of GPR (x) and FPR (v) 
>>> registers
>>> +   it would consume.  For a Homogeneous Floating-point Aggregate the FPR 
>>> count
>>> +   is the number of members (<= 4); for a non-HFA aggregate <= 16 bytes 
>>> the GPR
>>> +   count is 1 or 2; scalars use exactly one register of the appropriate 
>>> bank.
>>> +
>>> +   Returns false iff the parameter must be passed indirectly (in memory): a
>>> +   non-HFA aggregate larger than 16 bytes.  When bInReturn is true the same
>>> +   classification answers "can this be returned in registers?" (false => 
>>> the
>>> +   caller must allocate a buffer and pass it in x8).
>>> +*/
>>> +bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool 
>>> bInReturn, int &nUsedGPR, int &nUsedFPR );
>>> +
>>> +/** Does a function returning this type use the hidden indirect-result 
>>> pointer
>>> +    (passed by the caller in x8), or can it return in registers?
>>> +
>>> +    A scalar returns in x0 or v0; an HFA returns in v0..v3; a non-HFA 
>>> aggregate
>>> +    of <= 16 bytes returns in x0,x1.  Anything larger (non-HFA aggregate
>>> +    > 16 bytes) is returned via the caller-allocated buffer addressed by 
>>> x8 -
>>> +    that is the "hidden param" case, for which this returns true.
>>> +*/
>>> +bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
>>> +
>>> +/** Scatter a register-resident return value (an HFA returned in v0..v3, 
>>> or a
>>> +    non-HFA aggregate <= 16 bytes returned in x0,x1) into the caller's 
>>> struct.
>>> +
>>> +    pGPR points at the saved x0,x1,... ; pFPR at the saved v0,v1,... (each
>>> +    element the low 8 bytes of a v register, i.e. a double slot).  Only 
>>> valid
>>> +    when return_in_hidden_param() is false.
>>> +*/
>>> +void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const 
>>> sal_uInt64* pGPR, const double* pFPR, void *pStruct );
>>> +
>>> +} // namespace aarch64
>>> +
>>> +#endif // _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
>>> new file mode 100644
>>> index 0000000000..035b38555a
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/call.s
>>> @@ -0,0 +1,168 @@
>>> +/**************************************************************
>>> + *
>>> + * 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
>>> + *
>>> + * Unless required by applicable law or agreed to in writing,
>>> + * software distributed under the License is distributed on an
>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> + * KIND, either express or implied.  See the License for the
>>> + * specific language governing permissions and limitations
>>> + * under the License.
>>> + *
>>> + *************************************************************/
>>> +
>>> +// AArch64 (Apple Silicon, AAPCS64) outgoing-call trampoline for the 
>>> C++-UNO
>>> +// bridge.  Loads the argument registers from caller-prepared arrays, 
>>> copies
>>> +// any overflow arguments to the outgoing stack, performs the indirect 
>>> call,
>>> +// and stores the integer and FP/SIMD return registers back.
>>> +//
>>> +// See AAPCS64_BRIDGE_SPEC.md.  Mach-O assembler syntax; symbols are 
>>> prefixed
>>> +// with an underscore per the Darwin C ABI.
>>> +//
>>> +// extern "C" void callVirtualFunction(
>>> +//     sal_uInt64  pFunction,     // x0: target C++ virtual method
>>> +//     sal_uInt64  pIndirectRet,  // x1: value for x8 (indirect result 
>>> ptr), 0 if none
>>> +//     sal_uInt64 *pGPR,          // x2: 8 words  -> x0..x7
>>> +//     double     *pFPR,          // x3: 8 doubles -> d0..d7
>>> +//     sal_uInt64 *pStack,        // x4: overflow-arg words
>>> +//     sal_uInt32  nStackWords,   // x5: number of 8-byte overflow words
>>> +//     sal_uInt64 *pGPRReturn,    // x6: [out] x0,x1
>>> +//     double     *pFPRReturn);   // x7: [out] d0..d3 (HFA up to 4 
>>> elements)
>>> +
>>> +    .text
>>> +    .globl _callVirtualFunction
>>> +    .p2align 2
>>> +_callVirtualFunction:
>>> +    // prologue: save fp/lr and the callee-saved registers we use
>>> +    stp     x29, x30, [sp, #-16]!
>>> +    stp     x19, x20, [sp, #-16]!
>>> +    stp     x21, x22, [sp, #-16]!
>>> +    stp     x23, x24, [sp, #-16]!
>>> +    mov     x29, sp
>>> +
>>> +    // stash inputs that must survive the call into callee-saved registers
>>> +    mov     x19, x0                     // pFunction
>>> +    mov     x20, x2                     // pGPR
>>> +    mov     x21, x3                     // pFPR
>>> +    mov     x22, x6                     // pGPRReturn
>>> +    mov     x23, x7                     // pFPRReturn
>>> +    mov     x24, x1                     // x8 indirect-result value
>>> +
>>> +    // allocate and copy the outgoing overflow stack arguments.
>>> +    // bytes = ((nStackWords + 1) & ~1) * 8, to keep sp 16-byte aligned.
>>> +    add     x9, x5, #1
>>> +    bic     x9, x9, #1
>>> +    lsl     x9, x9, #3
>>> +    sub     sp, sp, x9
>>> +    mov     x10, #0
>>> +Lcvf_copy:
>>> +    cmp     x10, x5
>>> +    b.ge    Lcvf_copied
>>> +    ldr     x11, [x4, x10, lsl #3]
>>> +    str     x11, [sp, x10, lsl #3]
>>> +    add     x10, x10, #1
>>> +    b       Lcvf_copy
>>> +Lcvf_copied:
>>> +
>>> +    // load the FP/SIMD argument registers d0..d7
>>> +    ldp     d0, d1, [x21, #0]
>>> +    ldp     d2, d3, [x21, #16]
>>> +    ldp     d4, d5, [x21, #32]
>>> +    ldp     d6, d7, [x21, #48]
>>> +
>>> +    // load the GP argument registers x0..x7 and the x8 indirect-result reg
>>> +    mov     x8, x24
>>> +    ldp     x6, x7, [x20, #48]
>>> +    ldp     x4, x5, [x20, #32]
>>> +    ldp     x2, x3, [x20, #16]
>>> +    ldp     x0, x1, [x20, #0]
>>> +
>>> +    // perform the virtual call
>>> +    blr     x19
>>> +
>>> +    // store the return registers
>>> +    str     x0, [x22, #0]
>>> +    str     x1, [x22, #8]
>>> +    str     d0, [x23, #0]
>>> +    str     d1, [x23, #8]
>>> +    str     d2, [x23, #16]
>>> +    str     d3, [x23, #24]
>>> +
>>> +    // epilogue
>>> +    mov     sp, x29
>>> +    ldp     x23, x24, [sp], #16
>>> +    ldp     x21, x22, [sp], #16
>>> +    ldp     x19, x20, [sp], #16
>>> +    ldp     x29, x30, [sp], #16
>>> +    ret
>>> +
>>> +// 
>>> ---------------------------------------------------------------------------
>>> +// privateSnippetExecutor: the incoming (cpp2uno) register-spill executor.
>>> +//
>>> +// Reached by a BR from a per-vtable-slot code snippet (see codeSnippet() 
>>> in
>>> +// cpp2uno.cxx) with:
>>> +//   x16 = (nVtableOffset << 32) | nFunctionIndex  (low bit 0x80000000 
>>> flags a
>>> +//         hidden/indirect return)
>>> +//   x0..x7, d0..d7, x8 = the original incoming arguments (untouched)
>>> +//   sp  = the caller's stack-argument area (overflow)
>>> +//   x30 = return address back into the original C++ caller
>>> +//
>>> +// It spills the argument registers to a save area and calls 
>>> cpp_vtable_call,
>>> +// then loads the return value back into x0/x1 and d0/d1 (or d0 for fp).
>>> +//
>>> +//   typelib_TypeClass cpp_vtable_call(
>>> +//       sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
>>> +//       void** gpreg, void** fpreg, void** ovrflw,
>>> +//       void* pIndirectReturn, sal_uInt64* pRegisterReturn);
>>> +//
>>> +// Frame (176 bytes): [0]=x29,x30  [16..79]=x0..x7  [80..143]=d0..d7
>>> +//                    [144..159]=return buffer.
>>> +    .globl _privateSnippetExecutor
>>> +    .p2align 2
>>> +_privateSnippetExecutor:
>>> +    mov     x17, sp                     // x17 = ovrflw (incoming stack 
>>> args)
>>> +    stp     x29, x30, [sp, #-176]!
>>> +    mov     x29, sp
>>> +
>>> +    stp     x0, x1, [sp, #16]           // save GP argument registers 
>>> x0..x7
>>> +    stp     x2, x3, [sp, #32]
>>> +    stp     x4, x5, [sp, #48]
>>> +    stp     x6, x7, [sp, #64]
>>> +
>>> +    stp     d0, d1, [sp, #80]           // save FP/SIMD argument registers 
>>> d0..d7
>>> +    stp     d2, d3, [sp, #96]
>>> +    stp     d4, d5, [sp, #112]
>>> +    stp     d6, d7, [sp, #128]
>>> +
>>> +    mov     w0, w16                     // nFunctionIndex (low 32 bits)
>>> +    lsr     x1, x16, #32                // nVtableOffset (high 32 bits)
>>> +    add     x2, sp, #16                 // gpreg
>>> +    add     x3, sp, #80                 // fpreg
>>> +    mov     x4, x17                     // ovrflw
>>> +    mov     x5, x8                      // pIndirectReturn (x8 
>>> indirect-result reg)
>>> +    add     x6, sp, #144                // pRegisterReturn (16-byte buffer)
>>> +    bl      _cpp_vtable_call
>>> +
>>> +    cmp     w0, #10                     // typelib_TypeClass_FLOAT
>>> +    b.eq    Lpse_float
>>> +    cmp     w0, #11                     // typelib_TypeClass_DOUBLE
>>> +    b.eq    Lpse_float
>>> +    // integer / pointer / <=16B aggregate: load both banks; caller reads 
>>> the
>>> +    // ones that matter for its return type.
>>> +    ldp     x0, x1, [sp, #144]
>>> +    ldp     d0, d1, [sp, #144]
>>> +    b       Lpse_done
>>> +Lpse_float:
>>> +    ldr     d0, [sp, #144]
>>> +Lpse_done:
>>> +    mov     sp, x29
>>> +    ldp     x29, x30, [sp], #176
>>> +    ret
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
>>> new file mode 100644
>>> index 0000000000..6fa6bac7a2
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/cpp2uno.cxx
>>> @@ -0,0 +1,543 @@
>>> +/**************************************************************
>>> + *
>>> + * 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
>>> + *
>>> + * Unless required by applicable law or agreed to in writing,
>>> + * software distributed under the License is distributed on an
>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> + * KIND, either express or implied.  See the License for the
>>> + * specific language governing permissions and limitations
>>> + * under the License.
>>> + *
>>> + *************************************************************/
>>> +
>>> +
>>> +
>>> +// MARKER(update_precomp.py): autogen include statement, do not remove
>>> +#include "precompiled_bridges.hxx"
>>> +
>>> +#include <stdio.h>
>>> +#include <stdlib.h>
>>> +#include <hash_map>
>>> +
>>> +#include <rtl/alloc.h>
>>> +#include <osl/mutex.hxx>
>>> +
>>> +#include <com/sun/star/uno/genfunc.hxx>
>>> +#include "com/sun/star/uno/RuntimeException.hpp"
>>> +#include <uno/data.h>
>>> +#include <typelib/typedescription.hxx>
>>> +
>>> +#include "bridges/cpp_uno/shared/bridge.hxx"
>>> +#include "bridges/cpp_uno/shared/cppinterfaceproxy.hxx"
>>> +#include "bridges/cpp_uno/shared/types.hxx"
>>> +#include "bridges/cpp_uno/shared/vtablefactory.hxx"
>>> +
>>> +#include "abi.hxx"
>>> +#include "share.hxx"
>>> +
>>> +using namespace ::osl;
>>> +using namespace ::rtl;
>>> +using namespace ::com::sun::star::uno;
>>> +
>>> +//==================================================================================================
>>> +
>>> +// Perform the UNO call
>>> +//
>>> +// We must convert the parameters stored in gpreg, fpreg and ovrflw to UNO
>>> +// arguments and call pThis->getUnoI()->pDispatcher.
>>> +//
>>> +// gpreg:  this, [gpr params x0..x7]   (the indirect-result ptr is x8, 
>>> separate)
>>> +// fpreg:  [fpr params d0..d7]
>>> +// ovrflw: [gpr or fpr params (properly aligned)]
>>> +//
>>> +// On AArch64 a structure bigger than 16 bytes is returned via the buffer
>>> +// addressed by x8 (pIndirectReturn); 'this' is always x0 = gpreg[0].
>>> +// Simple types are returned in x0,x1 (int) or d0,d1 (fp); HFAs in d0..d3;
>>> +// non-HFA structures <= 16 bytes in x0,x1.
>>> +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,
>>> +   void * pIndirectReturn, // AArch64 x8 indirect-result pointer (0 if 
>>> none)
>>> +   sal_uInt64 * pRegisterReturn /* space for register return */ )
>>> +{
>>> +   unsigned int nr_gpr = 0; //number of gpr registers used
>>> +   unsigned int nr_fpr = 0; //number of fpr registers used
>>> +
>>> +   // return
>>> +   typelib_TypeDescription * pReturnTypeDescr = 0;
>>> +   if (pReturnTypeRef)
>>> +           TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
>>> +
>>> +   void * pUnoReturn = 0;
>>> +   void * pCppReturn = 0; // complex return ptr: if != 0 && != pUnoReturn, 
>>> reconversion need
>>> +
>>> +   if ( pReturnTypeDescr )
>>> +   {
>>> +           if ( aarch64::return_in_hidden_param( pReturnTypeRef ) )
>>> +           {
>>> +                   // AArch64: the indirect-result pointer arrives in x8, 
>>> NOT in the
>>> +                   // first general-purpose argument register (unlike 
>>> x86-64 SysV).
>>> +                   // So we take it from pIndirectReturn and do NOT 
>>> consume a gpreg
>>> +                   // slot here; 'this' still occupies gpreg[0] below.
>>> +                   pCppReturn = pIndirectReturn;
>>> +
>>> +                   pUnoReturn = ( 
>>> bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )
>>> +                                              ? alloca( 
>>> pReturnTypeDescr->nSize )
>>> +                                              : pCppReturn ); // direct way
>>> +           }
>>> +           else
>>> +                   pUnoReturn = pRegisterReturn; // direct way for simple 
>>> types
>>> +   }
>>> +
>>> +   // pop this (x0)
>>> +   gpreg++;
>>> +   nr_gpr++;
>>> +
>>> +   // stack space
>>> +   // parameters
>>> +   void ** pUnoArgs = reinterpret_cast<void **>(alloca( 4 * sizeof(void *) 
>>> * nParams ));
>>> +   void ** pCppArgs = pUnoArgs + nParams;
>>> +   // indizes of values this have to be converted (interface conversion 
>>> cpp<=>uno)
>>> +   sal_Int32 * pTempIndizes = reinterpret_cast<sal_Int32 *>(pUnoArgs + (2 
>>> * nParams));
>>> +   // type descriptions for reconversions
>>> +   typelib_TypeDescription ** ppTempParamTypeDescr = 
>>> reinterpret_cast<typelib_TypeDescription **>(pUnoArgs + (3 * nParams));
>>> +
>>> +   sal_Int32 nTempIndizes = 0;
>>> +
>>> +   for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
>>> +   {
>>> +           const typelib_MethodParameter & rParam = pParams[nPos];
>>> +
>>> +           int nUsedGPR = 0;
>>> +           int nUsedFPR = 0;
>>> +           bool bFitsRegisters = aarch64::examine_argument( 
>>> rParam.pTypeRef, false, nUsedGPR, nUsedFPR );
>>> +           if ( !rParam.bOut && bridges::cpp_uno::shared::isSimpleType( 
>>> rParam.pTypeRef ) ) // value
>>> +           {
>>> +                   // A simple UNO type occupies exactly one register, GPR 
>>> or FPR.
>>> +                   OSL_ASSERT( bFitsRegisters && ( ( nUsedFPR == 1 && 
>>> nUsedGPR == 0 ) || ( nUsedFPR == 0 && nUsedGPR == 1 ) ) );
>>> +
>>> +                   if ( nUsedFPR == 1 )
>>> +                   {
>>> +                           if ( nr_fpr < aarch64::MAX_FPR_REGS )
>>> +                           {
>>> +                                   pCppArgs[nPos] = pUnoArgs[nPos] = 
>>> fpreg++;
>>> +                                   nr_fpr++;
>>> +                           }
>>> +                           else
>>> +                                   pCppArgs[nPos] = pUnoArgs[nPos] = 
>>> ovrflw++;
>>> +                   }
>>> +                   else if ( nUsedGPR == 1 )
>>> +                   {
>>> +                           if ( nr_gpr < aarch64::MAX_GPR_REGS )
>>> +                           {
>>> +                                   pCppArgs[nPos] = pUnoArgs[nPos] = 
>>> gpreg++;
>>> +                                   nr_gpr++;
>>> +                           }
>>> +                           else
>>> +                                   pCppArgs[nPos] = pUnoArgs[nPos] = 
>>> ovrflw++;
>>> +                   }
>>> +           }
>>> +           else // struct <= 16 bytes || ptr to complex value || ref
>>> +           {
>>> +                   typelib_TypeDescription * pParamTypeDescr = 0;
>>> +                   TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
>>> +
>>> +                   void *pCppStack;
>>> +                   if ( nr_gpr < aarch64::MAX_GPR_REGS )
>>> +                   {
>>> +                           pCppArgs[nPos] = pCppStack = *gpreg++;
>>> +                           nr_gpr++;
>>> +                   }
>>> +                   else
>>> +                           pCppArgs[nPos] = pCppStack = *ovrflw++;
>>> +
>>> +                   if (! rParam.bIn) // is pure out
>>> +                   {
>>> +                           // uno out is unconstructed mem!
>>> +                           pUnoArgs[nPos] = alloca( pParamTypeDescr->nSize 
>>> );
>>> +                           pTempIndizes[nTempIndizes] = nPos;
>>> +                           // will be released at reconversion
>>> +                           ppTempParamTypeDescr[nTempIndizes++] = 
>>> pParamTypeDescr;
>>> +                   }
>>> +                   else if ( 
>>> bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ) ) // is 
>>> in/inout
>>> +                   {
>>> +                           uno_copyAndConvertData( pUnoArgs[nPos] = 
>>> alloca( pParamTypeDescr->nSize ),
>>> +                                                                           
>>> pCppStack, pParamTypeDescr,
>>> +                                                                           
>>> pThis->getBridge()->getCpp2Uno() );
>>> +                           pTempIndizes[nTempIndizes] = nPos; // has to be 
>>> reconverted
>>> +                           // will be released at reconversion
>>> +                           ppTempParamTypeDescr[nTempIndizes++] = 
>>> pParamTypeDescr;
>>> +                   }
>>> +                   else // direct way
>>> +                   {
>>> +                           pUnoArgs[nPos] = pCppStack;
>>> +                           // no longer needed
>>> +                           TYPELIB_DANGER_RELEASE( pParamTypeDescr );
>>> +                   }
>>> +           }
>>> +   }
>>> +
>>> +   // ExceptionHolder
>>> +   uno_Any aUnoExc; // Any will be constructed by callee
>>> +   uno_Any * pUnoExc = &aUnoExc;
>>> +
>>> +   // invoke uno dispatch call
>>> +   (*pThis->getUnoI()->pDispatcher)( pThis->getUnoI(), pMemberTypeDescr, 
>>> pUnoReturn, pUnoArgs, &pUnoExc );
>>> +
>>> +   // in case an exception occurred...
>>> +   if ( pUnoExc )
>>> +   {
>>> +           // destruct temporary in/inout params
>>> +           for ( ; nTempIndizes--; )
>>> +           {
>>> +                   sal_Int32 nIndex = pTempIndizes[nTempIndizes];
>>> +
>>> +                   if (pParams[nIndex].bIn) // is in/inout => was 
>>> constructed
>>> +                           uno_destructData( pUnoArgs[nIndex], 
>>> ppTempParamTypeDescr[nTempIndizes], 0 );
>>> +                   TYPELIB_DANGER_RELEASE( 
>>> ppTempParamTypeDescr[nTempIndizes] );
>>> +           }
>>> +           if (pReturnTypeDescr)
>>> +                   TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
>>> +
>>> +           CPPU_CURRENT_NAMESPACE::raiseException( &aUnoExc, 
>>> pThis->getBridge()->getUno2Cpp() ); // has to destruct the any
>>> +           // is here for dummy
>>> +           return typelib_TypeClass_VOID;
>>> +   }
>>> +   else // else no exception occurred...
>>> +   {
>>> +           // temporary params
>>> +           for ( ; nTempIndizes--; )
>>> +           {
>>> +                   sal_Int32 nIndex = pTempIndizes[nTempIndizes];
>>> +                   typelib_TypeDescription * pParamTypeDescr = 
>>> ppTempParamTypeDescr[nTempIndizes];
>>> +
>>> +                   if ( pParams[nIndex].bOut ) // inout/out
>>> +                   {
>>> +                           // convert and assign
>>> +                           uno_destructData( pCppArgs[nIndex], 
>>> pParamTypeDescr, cpp_release );
>>> +                           uno_copyAndConvertData( pCppArgs[nIndex], 
>>> pUnoArgs[nIndex], pParamTypeDescr,
>>> +                                                                           
>>> pThis->getBridge()->getUno2Cpp() );
>>> +                   }
>>> +                   // destroy temp uno param
>>> +                   uno_destructData( pUnoArgs[nIndex], pParamTypeDescr, 0 
>>> );
>>> +
>>> +                   TYPELIB_DANGER_RELEASE( pParamTypeDescr );
>>> +           }
>>> +           // return
>>> +           if ( pCppReturn ) // has complex return
>>> +           {
>>> +                   if ( pUnoReturn != pCppReturn ) // needs reconversion
>>> +                   {
>>> +                           uno_copyAndConvertData( pCppReturn, pUnoReturn, 
>>> pReturnTypeDescr,
>>> +                                                                           
>>> pThis->getBridge()->getUno2Cpp() );
>>> +                           // destroy temp uno return
>>> +                           uno_destructData( pUnoReturn, pReturnTypeDescr, 
>>> 0 );
>>> +                   }
>>> +                   // complex return ptr is set to return reg
>>> +                   *reinterpret_cast<void **>(pRegisterReturn) = 
>>> pCppReturn;
>>> +           }
>>> +           if ( pReturnTypeDescr )
>>> +           {
>>> +                   typelib_TypeClass eRet = 
>>> (typelib_TypeClass)pReturnTypeDescr->eTypeClass;
>>> +                   TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
>>> +                   return eRet;
>>> +           }
>>> +           else
>>> +                   return typelib_TypeClass_VOID;
>>> +   }
>>> +}
>>> +
>>> +
>>> +//==================================================================================================
>>> +extern "C" typelib_TypeClass cpp_vtable_call(
>>> +   sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
>>> +   void ** gpreg, void ** fpreg, void ** ovrflw,
>>> +   void * pIndirectReturn, // AArch64 x8 indirect-result pointer (0 if 
>>> none)
>>> +   sal_uInt64 * pRegisterReturn /* space for register return */ )
>>> +{
>>> +   // gpreg:  this, [other gpr params x0..x7]
>>> +   // fpreg:  [fpr params d0..d7]
>>> +   // ovrflw: [gpr or fpr params (properly aligned)]
>>> +   // pIndirectReturn: x8 (the hidden return buffer), when bit 0x80000000 
>>> set.
>>> +   //
>>> +   // On AArch64 'this' is ALWAYS x0 = gpreg[0]; the hidden return pointer 
>>> is
>>> +   // the separate x8 register, not a displaced first GPR (unlike x86-64 
>>> SysV
>>> +   // where it occupied gpreg[0] and 'this' moved to gpreg[1]).
>>> +   if ( nFunctionIndex & 0x80000000 )
>>> +           nFunctionIndex &= 0x7fffffff;
>>> +
>>> +   void * pThis = gpreg[0];
>>> +   pThis = static_cast<char *>( pThis ) - nVtableOffset;
>>> +
>>> +   bridges::cpp_uno::shared::CppInterfaceProxy * pCppI =
>>> +           
>>> bridges::cpp_uno::shared::CppInterfaceProxy::castInterfaceToProxy( pThis );
>>> +
>>> +   typelib_InterfaceTypeDescription * pTypeDescr = pCppI->getTypeDescr();
>>> +
>>> +   OSL_ENSURE( nFunctionIndex < 
>>> pTypeDescr->nMapFunctionIndexToMemberIndex, "### illegal vtable index!\n" );
>>> +   if ( nFunctionIndex >= pTypeDescr->nMapFunctionIndexToMemberIndex )
>>> +   {
>>> +           throw RuntimeException( OUString::createFromAscii("illegal 
>>> vtable index!"),
>>> +                                                           
>>> reinterpret_cast<XInterface *>( pCppI ) );
>>> +   }
>>> +
>>> +   // determine called method
>>> +   sal_Int32 nMemberPos = 
>>> pTypeDescr->pMapFunctionIndexToMemberIndex[nFunctionIndex];
>>> +   OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### illegal member 
>>> index!\n" );
>>> +
>>> +   TypeDescription aMemberDescr( pTypeDescr->ppAllMembers[nMemberPos] );
>>> +
>>> +   typelib_TypeClass eRet;
>>> +   switch ( aMemberDescr.get()->eTypeClass )
>>> +   {
>>> +           case typelib_TypeClass_INTERFACE_ATTRIBUTE:
>>> +           {
>>> +                   typelib_TypeDescriptionReference *pAttrTypeRef =
>>> +                           
>>> reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( 
>>> aMemberDescr.get() )->pAttributeTypeRef;
>>> +
>>> +                   if ( 
>>> pTypeDescr->pMapMemberIndexToFunctionIndex[nMemberPos] == nFunctionIndex )
>>> +                   {
>>> +                           // is GET method
>>> +                           eRet = cpp2uno_call( pCppI, aMemberDescr.get(), 
>>> pAttrTypeRef,
>>> +                                           0, 0, // no params
>>> +                                           gpreg, fpreg, ovrflw, 
>>> pIndirectReturn, pRegisterReturn );
>>> +                   }
>>> +                   else
>>> +                   {
>>> +                           // is SET method
>>> +                           typelib_MethodParameter aParam;
>>> +                           aParam.pTypeRef = pAttrTypeRef;
>>> +                           aParam.bIn              = sal_True;
>>> +                           aParam.bOut             = sal_False;
>>> +
>>> +                           eRet = cpp2uno_call( pCppI, aMemberDescr.get(),
>>> +                                           0, // indicates void return
>>> +                                           1, &aParam,
>>> +                                           gpreg, fpreg, ovrflw, 
>>> pIndirectReturn, pRegisterReturn );
>>> +                   }
>>> +                   break;
>>> +           }
>>> +           case typelib_TypeClass_INTERFACE_METHOD:
>>> +           {
>>> +                   // is METHOD
>>> +                   switch ( nFunctionIndex )
>>> +                   {
>>> +                           case 1: // acquire()
>>> +                                   pCppI->acquireProxy(); // non virtual 
>>> call!
>>> +                                   eRet = typelib_TypeClass_VOID;
>>> +                                   break;
>>> +                           case 2: // release()
>>> +                                   pCppI->releaseProxy(); // non virtual 
>>> call!
>>> +                                   eRet = typelib_TypeClass_VOID;
>>> +                                   break;
>>> +                           case 0: // queryInterface() opt
>>> +                           {
>>> +                                   // queryInterface([in] type) returns an 
>>> Any (> 16 bytes),
>>> +                                   // so on AArch64 the result buffer is 
>>> x8 (pIndirectReturn),
>>> +                                   // 'this' is gpreg[0], and the type 
>>> argument is the first
>>> +                                   // real parameter, gpreg[1].
>>> +                                   typelib_TypeDescription * pTD = 0;
>>> +                                   TYPELIB_DANGER_GET( &pTD, 
>>> reinterpret_cast<Type *>( gpreg[1] )->getTypeLibType() );
>>> +                                   if ( pTD )
>>> +                                   {
>>> +                                           XInterface * pInterface = 0;
>>> +                                           
>>> (*pCppI->getBridge()->getCppEnv()->getRegisteredInterface)
>>> +                                                   ( 
>>> pCppI->getBridge()->getCppEnv(),
>>> +                                                     reinterpret_cast<void 
>>> **>(&pInterface),
>>> +                                                     pCppI->getOid().pData,
>>> +                                                     
>>> reinterpret_cast<typelib_InterfaceTypeDescription *>( pTD ) );
>>> +
>>> +                                           if ( pInterface )
>>> +                                           {
>>> +                                                   ::uno_any_construct( 
>>> reinterpret_cast<uno_Any *>( pIndirectReturn ),
>>> +                                                                           
>>>                  &pInterface, pTD, cpp_acquire );
>>> +
>>> +                                                   pInterface->release();
>>> +                                                   TYPELIB_DANGER_RELEASE( 
>>> pTD );
>>> +
>>> +                                                   reinterpret_cast<void 
>>> **>( pRegisterReturn )[0] = pIndirectReturn;
>>> +                                                   eRet = 
>>> typelib_TypeClass_ANY;
>>> +                                                   break;
>>> +                                           }
>>> +                                           TYPELIB_DANGER_RELEASE( pTD );
>>> +                                   }
>>> +                           } // else perform queryInterface()
>>> +                           default:
>>> +                           {
>>> +                                   typelib_InterfaceMethodTypeDescription 
>>> *pMethodTD =
>>> +                                           
>>> reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( 
>>> aMemberDescr.get() );
>>> +
>>> +                                   eRet = cpp2uno_call( pCppI, 
>>> aMemberDescr.get(),
>>> +                                                                           
>>>  pMethodTD->pReturnTypeRef,
>>> +                                                                           
>>>  pMethodTD->nParams,
>>> +                                                                           
>>>  pMethodTD->pParams,
>>> +                                                                           
>>>  gpreg, fpreg, ovrflw, pIndirectReturn, pRegisterReturn );
>>> +                           }
>>> +                   }
>>> +                   break;
>>> +           }
>>> +           default:
>>> +           {
>>> +                   throw RuntimeException( OUString::createFromAscii("no 
>>> member description found!"),
>>> +                                                                   
>>> reinterpret_cast<XInterface *>( pCppI ) );
>>> +                   // is here for dummy
>>> +                   eRet = typelib_TypeClass_VOID;
>>> +           }
>>> +   }
>>> +
>>> +   return eRet;
>>> +}
>>> +
>>> +//==================================================================================================
>>> +// The incoming register-spill executor, implemented in call.s.  It is 
>>> reached
>>> +// via BR from a per-slot snippet (codeSnippet below) with x16 carrying the
>>> +// packed (nVtableOffset << 32) | nFunctionIndex; it spills the argument
>>> +// registers and calls cpp_vtable_call.
>>> +extern "C" void privateSnippetExecutor( void );
>>> +
>>> +// Each snippet is 5 AArch64 instructions (20 bytes) + 4 bytes padding to 
>>> an
>>> +// 8-byte boundary + two 8-byte literals (the packed index and the executor
>>> +// address) = 40 bytes.
>>> +const int codeSnippetSize = 40;
>>> +
>>> +// Generate a per-vtable-slot trampoline that loads the packed function 
>>> index
>>> +// into x16 and branches to privateSnippetExecutor(), preserving every
>>> +// argument register.  Uses PC-relative literal loads because AArch64 
>>> cannot
>>> +// embed a 64-bit immediate in a single instruction.
>>> +//
>>> +// Layout (offsets in bytes from code):
>>> +//    0:  ldr  x16, #24      ; x16 = nOffsetAndIndex (literal at +24)
>>> +//    4:  ldr  x17, #28      ; x17 = privateSnippetExecutor (literal at 
>>> +32)
>>> +//    8:  br   x17
>>> +//   12:  (unused / padding)
>>> +//   16:  (padding to 8-byte align the literals at 24)
>>> +//   24:  .quad nOffsetAndIndex
>>> +//   32:  .quad privateSnippetExecutor
>>> +//
>>> +// Note: the snippet creates no stack frame, so the C++ unwinder walks 
>>> straight
>>> +// through it to the original caller (required for UNO exception 
>>> propagation).
>>> +unsigned char * codeSnippet( unsigned char * code,
>>> +        sal_Int32 nFunctionIndex, sal_Int32 nVtableOffset,
>>> +        bool bHasHiddenParam ) SAL_THROW( () )
>>> +{
>>> +   sal_uInt64 nOffsetAndIndex = ( static_cast<sal_uInt64>( nVtableOffset ) 
>>> << 32 ) | static_cast<sal_uInt64>( nFunctionIndex );
>>> +
>>> +   if ( bHasHiddenParam )
>>> +           nOffsetAndIndex |= 0x80000000;
>>> +
>>> +   sal_uInt32 * p = reinterpret_cast<sal_uInt32 *>( code );
>>> +
>>> +   // ldr x16, #24  -> literal at code+24. imm19 = 24/4 = 6.
>>> +   //   encoding: 0x58000000 | (imm19 << 5) | Rt(16)
>>> +   p[0] = 0x58000000 | ( 6 << 5 ) | 16;
>>> +   // ldr x17, #28  -> literal at code+32 (relative to this insn at +4): 
>>> 28.
>>> +   //   imm19 = 28/4 = 7.
>>> +   p[1] = 0x58000000 | ( 7 << 5 ) | 17;
>>> +   // br x17  -> 0xD61F0000 | (Rn(17) << 5)
>>> +   p[2] = 0xD61F0000 | ( 17 << 5 );
>>> +   // p[3] (offset 12) and p[4] (offset 16..20) are padding.
>>> +   p[3] = 0xD503201F; // NOP
>>> +   p[4] = 0xD503201F; // NOP
>>> +
>>> +   // literals, 8-byte aligned at offset 24 and 32
>>> +   *reinterpret_cast<sal_uInt64 *>( code + 24 ) = nOffsetAndIndex;
>>> +   *reinterpret_cast<sal_uInt64 *>( code + 32 ) = 
>>> reinterpret_cast<sal_uInt64>( privateSnippetExecutor );
>>> +
>>> +   return code + codeSnippetSize;
>>> +}
>>> +
>>> +//==================================================================================================
>>> +struct bridges::cpp_uno::shared::VtableFactory::Slot { void * fn; };
>>> +
>>> +bridges::cpp_uno::shared::VtableFactory::Slot *
>>> +bridges::cpp_uno::shared::VtableFactory::mapBlockToVtable(void * block)
>>> +{
>>> +    return static_cast< Slot * >(block) + 2;
>>> +}
>>> +
>>> +//==================================================================================================
>>> +sal_Size bridges::cpp_uno::shared::VtableFactory::getBlockSize(
>>> +    sal_Int32 slotCount)
>>> +{
>>> +    return (slotCount + 2) * sizeof (Slot) + slotCount * codeSnippetSize;
>>> +}
>>> +
>>> +//==================================================================================================
>>> +bridges::cpp_uno::shared::VtableFactory::Slot *
>>> +bridges::cpp_uno::shared::VtableFactory::initializeBlock(
>>> +    void * block, sal_Int32 slotCount)
>>> +{
>>> +    Slot * slots = mapBlockToVtable(block);
>>> +    slots[-2].fn = 0;
>>> +    slots[-1].fn = 0;
>>> +    return slots + slotCount;
>>> +}
>>> +
>>> +//==================================================================================================
>>> +
>>> +unsigned char * bridges::cpp_uno::shared::VtableFactory::addLocalFunctions(
>>> +   Slot ** slots, unsigned char * code, /*sal_PtrDiff writetoexecdiff,*/
>>> +   typelib_InterfaceTypeDescription const * type, sal_Int32 
>>> nFunctionOffset,
>>> +   sal_Int32 functionCount, sal_Int32 nVtableOffset )
>>> +{
>>> +   const sal_PtrDiff writetoexecdiff = 0;
>>> +   (*slots) -= functionCount;
>>> +   Slot * s = *slots;
>>> +   for ( sal_Int32 nPos = 0; nPos < type->nMembers; ++nPos )
>>> +   {
>>> +           typelib_TypeDescription * pTD = 0;
>>> +
>>> +           TYPELIB_DANGER_GET( &pTD, type->ppMembers[ nPos ] );
>>> +           OSL_ASSERT( pTD );
>>> +
>>> +           if ( typelib_TypeClass_INTERFACE_ATTRIBUTE == pTD->eTypeClass )
>>> +           {
>>> +                   typelib_InterfaceAttributeTypeDescription *pAttrTD =
>>> +                           
>>> reinterpret_cast<typelib_InterfaceAttributeTypeDescription *>( pTD );
>>> +
>>> +                   // get method
>>> +                   (s++)->fn = code + writetoexecdiff;
>>> +                   code = codeSnippet( code, nFunctionOffset++, 
>>> nVtableOffset,
>>> +                                                           
>>> aarch64::return_in_hidden_param( pAttrTD->pAttributeTypeRef ) );
>>> +
>>> +                   if ( ! pAttrTD->bReadOnly )
>>> +                   {
>>> +                           // set method
>>> +                           (s++)->fn = code + writetoexecdiff;
>>> +                           code = codeSnippet( code, nFunctionOffset++, 
>>> nVtableOffset, false );
>>> +                   }
>>> +           }
>>> +           else if ( typelib_TypeClass_INTERFACE_METHOD == pTD->eTypeClass 
>>> )
>>> +           {
>>> +                   typelib_InterfaceMethodTypeDescription *pMethodTD =
>>> +                           
>>> reinterpret_cast<typelib_InterfaceMethodTypeDescription *>( pTD );
>>> +
>>> +                   (s++)->fn = code + writetoexecdiff;
>>> +                   code = codeSnippet( code, nFunctionOffset++, 
>>> nVtableOffset,
>>> +                                                           
>>> aarch64::return_in_hidden_param( pMethodTD->pReturnTypeRef ) );
>>> +           }
>>> +           else
>>> +                   OSL_ASSERT( false );
>>> +
>>> +           TYPELIB_DANGER_RELEASE( pTD );
>>> +   }
>>> +   return code;
>>> +}
>>> +
>>> +//==================================================================================================
>>> +void bridges::cpp_uno::shared::VtableFactory::flushCode(
>>> +   unsigned char const *, unsigned char const * )
>>> +{
>>> +}
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
>>> new file mode 100644
>>> index 0000000000..60784a4172
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/except.cxx
>>> @@ -0,0 +1,358 @@
>>> +/**************************************************************
>>> + *
>>> + * 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
>>> + *
>>> + * Unless required by applicable law or agreed to in writing,
>>> + * software distributed under the License is distributed on an
>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> + * KIND, either express or implied.  See the License for the
>>> + * specific language governing permissions and limitations
>>> + * under the License.
>>> + *
>>> + *************************************************************/
>>> +
>>> +
>>> +
>>> +// MARKER(update_precomp.py): autogen include statement, do not remove
>>> +#include "precompiled_bridges.hxx"
>>> +
>>> +#if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
>>> +#include <exception>
>>> +#endif
>>> +
>>> +#include <stdio.h>
>>> +#include <string.h>
>>> +#include <dlfcn.h>
>>> +#include <cxxabi.h>
>>> +#include <hash_map>
>>> +#include <sys/param.h>
>>> +
>>> +#include <rtl/strbuf.hxx>
>>> +#include <rtl/ustrbuf.hxx>
>>> +#include <osl/diagnose.h>
>>> +#include <osl/mutex.hxx>
>>> +
>>> +#include <com/sun/star/uno/genfunc.hxx>
>>> +#include "com/sun/star/uno/RuntimeException.hpp"
>>> +#include <typelib/typedescription.hxx>
>>> +#include <uno/any2.h>
>>> +
>>> +#include "share.hxx"
>>> +
>>> +
>>> +using namespace ::std;
>>> +using namespace ::osl;
>>> +using namespace ::rtl;
>>> +using namespace ::com::sun::star::uno;
>>> +using namespace ::__cxxabiv1;
>>> +
>>> +
>>> +namespace CPPU_CURRENT_NAMESPACE
>>> +{
>>> +
>>> +void dummy_can_throw_anything( char const * )
>>> +{
>>> +}
>>> +
>>> +//==================================================================================================
>>> +static OUString toUNOname( char const * p ) SAL_THROW( () )
>>> +{
>>> +#if OSL_DEBUG_LEVEL > 1
>>> +    char const * start = p;
>>> +#endif
>>> +
>>> +    // example: N3com3sun4star4lang24IllegalArgumentExceptionE
>>> +
>>> +   OUStringBuffer buf( 64 );
>>> +    OSL_ASSERT( 'N' == *p );
>>> +    ++p; // skip N
>>> +
>>> +    while ('E' != *p)
>>> +    {
>>> +        // read chars count
>>> +        long n = (*p++ - '0');
>>> +        while ('0' <= *p && '9' >= *p)
>>> +        {
>>> +            n *= 10;
>>> +            n += (*p++ - '0');
>>> +        }
>>> +        buf.appendAscii( p, n );
>>> +        p += n;
>>> +        if ('E' != *p)
>>> +            buf.append( (sal_Unicode)'.' );
>>> +    }
>>> +
>>> +#if OSL_DEBUG_LEVEL > 1
>>> +    OUString ret( buf.makeStringAndClear() );
>>> +    OString c_ret( OUStringToOString( ret, RTL_TEXTENCODING_ASCII_US ) );
>>> +    fprintf( stderr, "> toUNOname(): %s => %s\n", start, c_ret.getStr() );
>>> +    return ret;
>>> +#else
>>> +    return buf.makeStringAndClear();
>>> +#endif
>>> +}
>>> +
>>> +//==================================================================================================
>>> +class RTTI
>>> +{
>>> +    typedef hash_map< OUString, type_info *, OUStringHash > t_rtti_map;
>>> +
>>> +    Mutex m_mutex;
>>> +   t_rtti_map m_rttis;
>>> +    t_rtti_map m_generatedRttis;
>>> +
>>> +    void * m_hApp;
>>> +
>>> +public:
>>> +    RTTI() SAL_THROW( () );
>>> +    ~RTTI() SAL_THROW( () );
>>> +
>>> +    type_info * getRTTI( typelib_CompoundTypeDescription * ) SAL_THROW( () 
>>> );
>>> +};
>>> +
>>> +//__________________________________________________________________________________________________
>>> +RTTI::RTTI() SAL_THROW( () )
>>> +    : m_hApp( dlopen( 0, RTLD_LAZY ) )
>>> +{
>>> +}
>>> +
>>> +//__________________________________________________________________________________________________
>>> +RTTI::~RTTI() SAL_THROW( () )
>>> +{
>>> +    dlclose( m_hApp );
>>> +}
>>> +
>>> +//__________________________________________________________________________________________________
>>> +type_info * RTTI::getRTTI( typelib_CompoundTypeDescription *pTypeDescr ) 
>>> SAL_THROW( () )
>>> +{
>>> +    type_info * rtti;
>>> +
>>> +    OUString const & unoName = *(OUString const 
>>> *)&pTypeDescr->aBase.pTypeName;
>>> +
>>> +    MutexGuard guard( m_mutex );
>>> +    t_rtti_map::const_iterator iFind( m_rttis.find( unoName ) );
>>> +    if (iFind == m_rttis.end())
>>> +    {
>>> +        // RTTI symbol
>>> +        OStringBuffer buf( 64 );
>>> +        buf.append( RTL_CONSTASCII_STRINGPARAM("_ZTIN") );
>>> +        sal_Int32 index = 0;
>>> +        do
>>> +        {
>>> +            OUString token( unoName.getToken( 0, '.', index ) );
>>> +            buf.append( token.getLength() );
>>> +            OString c_token( OUStringToOString( token, 
>>> RTL_TEXTENCODING_ASCII_US ) );
>>> +            buf.append( c_token );
>>> +        }
>>> +        while (index >= 0);
>>> +        buf.append( 'E' );
>>> +
>>> +        OString symName( buf.makeStringAndClear() );
>>> +        rtti = static_cast<std::type_info *>(dlsym( m_hApp, 
>>> symName.getStr() ));
>>> +
>>> +        if (rtti)
>>> +        {
>>> +            pair< t_rtti_map::iterator, bool > insertion(
>>> +                m_rttis.insert( t_rtti_map::value_type( unoName, rtti ) ) 
>>> );
>>> +            OSL_ENSURE( insertion.second, "### inserting new rtti 
>>> failed?!" );
>>> +        }
>>> +        else
>>> +        {
>>> +            // try to lookup the symbol in the generated rtti map
>>> +            t_rtti_map::const_iterator iFind2( m_generatedRttis.find( 
>>> unoName ) );
>>> +            if (iFind2 == m_generatedRttis.end())
>>> +            {
>>> +                // we must generate it !
>>> +                // symbol and rtti-name is nearly identical,
>>> +                // the symbol is prefixed with _ZTI
>>> +                char const * rttiName = symName.getStr() +4;
>>> +#if OSL_DEBUG_LEVEL > 1
>>> +                fprintf( stderr,"generated rtti for %s\n", rttiName );
>>> +                const OString aCUnoName = OUStringToOString( unoName, 
>>> RTL_TEXTENCODING_UTF8);
>>> +                OSL_TRACE( "TypeInfo for \"%s\" not found and cannot be 
>>> generated.\n", aCUnoName.getStr());
>>> +#endif
>>> +#ifndef AOO_BYPASS_RTTI
>>> +                if (pTypeDescr->pBaseTypeDescription)
>>> +                {
>>> +                    // ensure availability of base
>>> +                    type_info * base_rtti = getRTTI(
>>> +                        (typelib_CompoundTypeDescription 
>>> *)pTypeDescr->pBaseTypeDescription );
>>> +                    rtti = new __si_class_type_info(
>>> +                        strdup( rttiName ), (__class_type_info *)base_rtti 
>>> );
>>> +                }
>>> +                else
>>> +                {
>>> +                    // this class has no base class
>>> +                    rtti = new __class_type_info( strdup( rttiName ) );
>>> +                }
>>> +#else
>>> +                rtti = NULL;
>>> +#endif
>>> +                bool bOK = m_generatedRttis.insert( 
>>> t_rtti_map::value_type( unoName, rtti )).second;
>>> +                OSL_ENSURE( bOK, "### inserting new generated rtti 
>>> failed?!" );
>>> +            }
>>> +            else // taking already generated rtti
>>> +            {
>>> +                rtti = iFind2->second;
>>> +            }
>>> +        }
>>> +    }
>>> +    else
>>> +    {
>>> +        rtti = iFind->second;
>>> +    }
>>> +
>>> +    return rtti;
>>> +}
>>> +
>>> +//--------------------------------------------------------------------------------------------------
>>> +static void deleteException( void * pExc )
>>> +{
>>> +    __cxa_exception const * header = static_cast<__cxa_exception const 
>>> *>(pExc) - 1;
>>> +    /* More __cxa_exception mumbo-jumbo. See share.hxx and 
>>> fillUnoException() below */
>>> +    if (header->exceptionDestructor != &deleteException)
>>> +    {
>>> +        header = reinterpret_cast<__cxa_exception const 
>>> *>(reinterpret_cast<char const *>(header) - 8);
>>> +    }
>>> +    if( !header->exceptionType)
>>> +    {
>>> +        return; // NOTE: leak for now
>>> +    }
>>> +    typelib_TypeDescription * pTD = 0;
>>> +    OUString unoName( toUNOname( header->exceptionType->name() ) );
>>> +    ::typelib_typedescription_getByName( &pTD, unoName.pData );
>>> +    OSL_ENSURE( pTD, "### unknown exception type! leaving out destruction 
>>> => leaking!!!" );
>>> +    if (pTD)
>>> +    {
>>> +           ::uno_destructData( pExc, pTD, cpp_release );
>>> +           ::typelib_typedescription_release( pTD );
>>> +   }
>>> +}
>>> +
>>> +//==================================================================================================
>>> +void raiseException( uno_Any * pUnoExc, uno_Mapping * pUno2Cpp )
>>> +{
>>> +#if OSL_DEBUG_LEVEL > 1
>>> +    OString cstr(
>>> +        OUStringToOString(
>>> +            *reinterpret_cast< OUString const * >( 
>>> &pUnoExc->pType->pTypeName ),
>>> +            RTL_TEXTENCODING_ASCII_US ) );
>>> +    fprintf( stderr, "> uno exception occurred: %s\n", cstr.getStr() );
>>> +#endif
>>> +    void * pCppExc;
>>> +    type_info * rtti;
>>> +
>>> +    {
>>> +    // construct cpp exception object
>>> +   typelib_TypeDescription * pTypeDescr = 0;
>>> +   TYPELIB_DANGER_GET( &pTypeDescr, pUnoExc->pType );
>>> +    OSL_ASSERT( pTypeDescr );
>>> +    if (! pTypeDescr)
>>> +    {
>>> +        throw RuntimeException(
>>> +            OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get 
>>> typedescription for type ") ) +
>>> +            *reinterpret_cast< OUString const * >( 
>>> &pUnoExc->pType->pTypeName ),
>>> +            Reference< XInterface >() );
>>> +    }
>>> +
>>> +   pCppExc = __cxa_allocate_exception( pTypeDescr->nSize );
>>> +   ::uno_copyAndConvertData( pCppExc, pUnoExc->pData, pTypeDescr, pUno2Cpp 
>>> );
>>> +
>>> +   // destruct uno exception
>>> +   ::uno_any_destruct( pUnoExc, 0 );
>>> +    // avoiding locked counts
>>> +    static RTTI * s_rtti = 0;
>>> +    if (! s_rtti)
>>> +    {
>>> +        MutexGuard guard( Mutex::getGlobalMutex() );
>>> +        if (! s_rtti)
>>> +        {
>>> +#ifdef LEAK_STATIC_DATA
>>> +            s_rtti = new RTTI();
>>> +#else
>>> +            static RTTI rtti_data;
>>> +            s_rtti = &rtti_data;
>>> +#endif
>>> +        }
>>> +    }
>>> +   rtti = (type_info *)s_rtti->getRTTI( (typelib_CompoundTypeDescription 
>>> *) pTypeDescr );
>>> +    TYPELIB_DANGER_RELEASE( pTypeDescr );
>>> +    OSL_ENSURE( rtti, "### no rtti for throwing exception!" );
>>> +    if (! rtti)
>>> +    {
>>> +        throw RuntimeException(
>>> +            OUString( RTL_CONSTASCII_USTRINGPARAM("no rtti for type ") ) +
>>> +            *reinterpret_cast< OUString const * >( 
>>> &pUnoExc->pType->pTypeName ),
>>> +            Reference< XInterface >() );
>>> +    }
>>> +    }
>>> +
>>> +   __cxa_throw( pCppExc, rtti, deleteException );
>>> +}
>>> +
>>> +//==================================================================================================
>>> +void fillUnoException( __cxa_exception * header, uno_Any * pUnoExc, 
>>> uno_Mapping * pCpp2Uno )
>>> +{
>>> +    if (! header)
>>> +    {
>>> +        RuntimeException aRE(
>>> +            OUString( RTL_CONSTASCII_USTRINGPARAM("no exception header!") 
>>> ),
>>> +            Reference< XInterface >() );
>>> +        Type const & rType = ::getCppuType( &aRE );
>>> +        uno_type_any_constructAndConvert( pUnoExc, &aRE, 
>>> rType.getTypeLibType(), pCpp2Uno );
>>> +#if OSL_DEBUG_LEVEL > 0
>>> +        OString cstr( OUStringToOString( aRE.Message, 
>>> RTL_TEXTENCODING_ASCII_US ) );
>>> +        OSL_ENSURE( 0, cstr.getStr() );
>>> +#endif
>>> +        return;
>>> +    }
>>> +
>>> +    /*
>>> +     * Handle the case where we are built on llvm 10 (or later) but are 
>>> running
>>> +     * on an earlier version (eg, community builds). In this situation the
>>> +     * reserved ptr doesn't exist in the struct returned and so the offsets
>>> +     * that header uses are wrong. This assumes that reserved isn't used
>>> +     * and that referenceCount is always >0 in the cases we handle.
>>> +     * See share.hxx for the definition of __cxa_exception
>>> +     */
>>> +    if (*reinterpret_cast<void **>(header) == 0)
>>> +    {
>>> +        header = reinterpret_cast<__cxa_exception *>(reinterpret_cast<char 
>>> *>(header) + 8);
>>> +    }
>>> +
>>> +   typelib_TypeDescription * pExcTypeDescr = 0;
>>> +    OUString unoName( toUNOname( header->exceptionType->name() ) );
>>> +#if OSL_DEBUG_LEVEL > 1
>>> +    OString cstr_unoName( OUStringToOString( unoName, 
>>> RTL_TEXTENCODING_ASCII_US ) );
>>> +    fprintf( stderr, "> c++ exception occurred: %s\n", 
>>> cstr_unoName.getStr() );
>>> +#endif
>>> +   typelib_typedescription_getByName( &pExcTypeDescr, unoName.pData );
>>> +    if (0 == pExcTypeDescr)
>>> +    {
>>> +        RuntimeException aRE(
>>> +            OUString( RTL_CONSTASCII_USTRINGPARAM("exception type not 
>>> found: ") ) + unoName,
>>> +            Reference< XInterface >() );
>>> +        Type const & rType = ::getCppuType( &aRE );
>>> +        uno_type_any_constructAndConvert( pUnoExc, &aRE, 
>>> rType.getTypeLibType(), pCpp2Uno );
>>> +#if OSL_DEBUG_LEVEL > 0
>>> +        OString cstr( OUStringToOString( aRE.Message, 
>>> RTL_TEXTENCODING_ASCII_US ) );
>>> +        OSL_ENSURE( 0, cstr.getStr() );
>>> +#endif
>>> +    }
>>> +    else
>>> +    {
>>> +        // construct uno exception any
>>> +        uno_any_constructAndConvert( pUnoExc, header->adjustedPtr, 
>>> pExcTypeDescr, pCpp2Uno );
>>> +        typelib_typedescription_release( pExcTypeDescr );
>>> +    }
>>> +}
>>> +
>>> +}
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/makefile.mk 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/makefile.mk
>>> new file mode 100644
>>> index 0000000000..af6c6c22d4
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/makefile.mk
>>> @@ -0,0 +1,81 @@
>>> +#**************************************************************
>>> +#
>>> +#  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
>>> +#
>>> +#  Unless required by applicable law or agreed to in writing,
>>> +#  software distributed under the License is distributed on an
>>> +#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> +#  KIND, either express or implied.  See the License for the
>>> +#  specific language governing permissions and limitations
>>> +#  under the License.
>>> +#
>>> +#**************************************************************
>>> +
>>> +
>>> +
>>> +PRJ=..$/..$/..
>>> +
>>> +PRJNAME=bridges
>>> +TARGET=$(COMNAME)_uno
>>> +LIBTARGET=no
>>> +ENABLE_EXCEPTIONS=TRUE
>>> +
>>> +# --- Settings -----------------------------------------------------
>>> +
>>> +.INCLUDE :  settings.mk
>>> +
>>> +# --- Files --------------------------------------------------------
>>> +
>>> +# Apple Silicon (arm64 / AAPCS64) C++-UNO bridge. CPU=R, CPUNAME=AARCH64.
>>> +# Note: the "s5abi" in this directory's name is the macOS-wide COMNAME (see
>>> +# solenv/gbuild/platform/macosx.mk); the actual arm64 calling convention is
>>> +# AAPCS64, so "s5abi" here is a historical label, not a literal ABI claim.
>>> +.IF "$(OS)$(CPU)" == "MACOSXR"
>>> +
>>> +.IF "$(cppu_no_leak)" == ""
>>> +CFLAGS += -DLEAK_STATIC_DATA
>>> +.ENDIF
>>> +
>>> +# In case someone enabled the non-standard -fomit-frame-pointer which does 
>>> not
>>> +# work with the .cxx sources in this directory:
>>> +CFLAGSCXX += -fno-omit-frame-pointer -fnon-call-exceptions
>>> +
>>> +SLOFILES= \
>>> +   $(SLO)$/abi.obj                 \
>>> +   $(SLO)$/except.obj              \
>>> +   $(SLO)$/cpp2uno.obj             \
>>> +   $(SLO)$/uno2cpp.obj             \
>>> +   $(SLO)$/call.obj
>>> +
>>> +SHL1TARGET= $(TARGET)
>>> +
>>> +SHL1DEF=$(MISC)$/$(SHL1TARGET).def
>>> +SHL1IMPLIB=i$(TARGET)
>>> +SHL1VERSIONMAP=..$/..$/bridge_exports.map
>>> +SHL1RPATH=URELIB
>>> +
>>> +SHL1OBJS = $(SLOFILES)
>>> +SHL1LIBS = $(SLB)$/cpp_uno_shared.lib
>>> +
>>> +SHL1STDLIBS= \
>>> +   $(CPPULIB)                      \
>>> +   $(SALLIB)
>>> +
>>> +.ENDIF
>>> +
>>> +# --- Targets ------------------------------------------------------
>>> +
>>> +.INCLUDE :  target.mk
>>> +
>>> +# Assemble the AArch64 call trampoline (call.s) into call.obj, mirroring 
>>> the
>>> +# pattern rule used by the gcc3_linux_arm bridge for its armhelper.S.
>>> +$(SLO)$/%.obj: %.s
>>> +   $(CXX) -c -o $(SLO)$/$(@:b).o $< -fPIC ; touch $@
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
>>> new file mode 100644
>>> index 0000000000..e4fcf4dbf9
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/share.hxx
>>> @@ -0,0 +1,116 @@
>>> +/**************************************************************
>>> + *
>>> + * 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
>>> + *
>>> + * Unless required by applicable law or agreed to in writing,
>>> + * software distributed under the License is distributed on an
>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> + * KIND, either express or implied.  See the License for the
>>> + * specific language governing permissions and limitations
>>> + * under the License.
>>> + *
>>> + *************************************************************/
>>> +
>>> +
>>> +
>>> +#include "uno/mapping.h"
>>> +
>>> +#include <typeinfo>
>>> +#include <exception>
>>> +#include <cstddef>
>>> +
>>> +namespace CPPU_CURRENT_NAMESPACE
>>> +{
>>> +
>>> +void dummy_can_throw_anything( char const * );
>>> +
>>> +typedef unsigned _Unwind_Ptr __attribute__((__mode__(__pointer__)));
>>> +
>>> +// ----- the following structure is compatible with the one declared in 
>>> libunwind's unwind.h
>>> +// (use forced types)
>>> +
>>> +struct _Unwind_Exception
>>> +{
>>> +    uint64_t exception_class;
>>> +    void * exception_cleanup;
>>> +    uintptr_t private_1;
>>> +    uintptr_t private_2;
>>> +};
>>> +
>>> +struct __cxa_exception
>>> +{
>>> +    /* From LLVM 10 a reserved member was added at the top of the struct on
>>> +       64-bit targets. Who the hell does that?
>>> +       https://reviews.llvm.org/rG674ec1eb16678b8addc02a4b0534ab383d22fa77
>>> +       It is required on arm64 (Apple Silicon): the trailing 
>>> _Unwind_Exception
>>> +       must be 16-byte aligned within the allocation, and only WITH this 
>>> member
>>> +       does unwindHeader land at a 16-byte boundary (offset 96, vs a 
>>> misaligned
>>> +       88 without it).  Verified empirically against this host's libc++abi.
>>> +       NOTE: Apple clang version != upstream LLVM version. */
>>> +    void *reserved;
>>> +    size_t referenceCount;
>>> +    ::std::type_info *exceptionType;
>>> +    void (*exceptionDestructor)(void *);
>>> +    ::std::unexpected_handler unexpectedHandler;
>>> +    ::std::terminate_handler terminateHandler;
>>> +    __cxa_exception *nextException;
>>> +    int handlerCount;
>>> +    int handlerSwitchValue;
>>> +    const unsigned char *actionRecord;
>>> +    const unsigned char *languageSpecificData;
>>> +    void *catchTemp;
>>> +    void *adjustedPtr;
>>> +    _Unwind_Exception unwindHeader;
>>> +};
>>> +
>>> +extern "C" void *__cxa_allocate_exception(
>>> +    std::size_t thrown_size ) throw();
>>> +extern "C" void __cxa_throw (
>>> +    void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) 
>>> __attribute__((noreturn));
>>> +
>>> +struct __cxa_eh_globals
>>> +{
>>> +    __cxa_exception *caughtExceptions;
>>> +    unsigned int uncaughtExceptions;
>>> +};
>>> +extern "C" __cxa_eh_globals *__cxa_get_globals () throw();
>>> +
>>> +// -----
>>> +
>>> +// on OSX 64bit the class_type_info classes are specified
>>> +// in http://refspecs.linuxbase.org/cxxabi-1.86.html#rtti but
>>> +// these details are not generally available in a public header
>>> +// of most development environments. So we define them here.
>>> +// NOTE: 
>>> https://www.hexblog.com/wp-content/uploads/2012/06/Recon-2012-Skochinsky-Compiler-Internals.pdf
>>> +class __class_type_info : public std::type_info
>>> +{
>>> +public:
>>> +        explicit __class_type_info( const char* pRttiName)
>>> +        : std::type_info( pRttiName)
>>> +        {}
>>> +};
>>> +
>>> +class __si_class_type_info : public __class_type_info
>>> +{
>>> +        const __class_type_info* mpBaseType;
>>> +public:
>>> +        explicit __si_class_type_info( const char* pRttiName, 
>>> __class_type_info* pBaseType)
>>> +        : __class_type_info( pRttiName), mpBaseType( pBaseType)
>>> +        {}
>>> +};
>>> +
>>> +//==================================================================================================
>>> +void raiseException(
>>> +    uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
>>> +//==================================================================================================
>>> +void fillUnoException(
>>> +    __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
>>> +}
>>> diff --git a/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx 
>>> b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
>>> new file mode 100644
>>> index 0000000000..adaa3f2a5f
>>> --- /dev/null
>>> +++ b/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/uno2cpp.cxx
>>> @@ -0,0 +1,581 @@
>>> +/**************************************************************
>>> + *
>>> + * 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
>>> + *
>>> + * Unless required by applicable law or agreed to in writing,
>>> + * software distributed under the License is distributed on an
>>> + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> + * KIND, either express or implied.  See the License for the
>>> + * specific language governing permissions and limitations
>>> + * under the License.
>>> + *
>>> + *************************************************************/
>>> +
>>> +
>>> +
>>> +// MARKER(update_precomp.py): autogen include statement, do not remove
>>> +#include "precompiled_bridges.hxx"
>>> +
>>> +#include <exception>
>>> +#include <typeinfo>
>>> +#include <stdio.h>
>>> +#include <stdlib.h>
>>> +#include <string.h>
>>> +
>>> +#include "rtl/alloc.h"
>>> +#include "rtl/ustrbuf.hxx"
>>> +
>>> +#include <com/sun/star/uno/genfunc.hxx>
>>> +#include "com/sun/star/uno/RuntimeException.hpp"
>>> +#include <uno/data.h>
>>> +
>>> +#include <bridges/cpp_uno/shared/bridge.hxx>
>>> +#include <bridges/cpp_uno/shared/types.hxx>
>>> +#include "bridges/cpp_uno/shared/unointerfaceproxy.hxx"
>>> +#include "bridges/cpp_uno/shared/vtables.hxx"
>>> +
>>> +#include "abi.hxx"
>>> +#include "share.hxx"
>>> +
>>> +using namespace ::rtl;
>>> +using namespace ::com::sun::star::uno;
>>> +
>>> +//==================================================================================================
>>> +
>>> +// The AArch64 outgoing-call trampoline, implemented in call.s.  It loads 
>>> the
>>> +// argument registers from the caller-prepared arrays, copies overflow 
>>> args to
>>> +// the outgoing stack, performs the indirect call, and returns x0/x1 and 
>>> d0..d3.
>>> +extern "C" void callVirtualFunction(
>>> +    sal_uInt64 pFunction, sal_uInt64 pIndirectRet,
>>> +    sal_uInt64 *pGPR, double *pFPR,
>>> +    sal_uInt64 *pStack, sal_uInt32 nStackWords,
>>> +    sal_uInt64 *pGPRReturn, double *pFPRReturn );
>>> +
>>> +static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
>>> +                              void * pRegisterReturn, 
>>> typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
>>> +                              void * pIndirectReturn,
>>> +                              sal_uInt64 *pStack, sal_uInt32 nStack,
>>> +                              sal_uInt64 *pGPR, sal_uInt32 nGPR,
>>> +                              double *pFPR, sal_uInt32 nFPR) 
>>> __attribute__((noinline));
>>> +
>>> +static void callVirtualMethod(void * pThis, sal_uInt32 nVtableIndex,
>>> +                              void * pRegisterReturn, 
>>> typelib_TypeDescriptionReference * pReturnTypeRef, bool bSimpleReturn,
>>> +                              void * pIndirectReturn,
>>> +                              sal_uInt64 *pStack, sal_uInt32 nStack,
>>> +                              sal_uInt64 *pGPR, sal_uInt32 nGPR,
>>> +                              double *pFPR, sal_uInt32 nFPR)
>>> +{
>>> +#if OSL_DEBUG_LEVEL > 1
>>> +    // Let's figure out what is really going on here
>>> +    {
>>> +        fprintf( stderr, "= callVirtualMethod() =\nGPR's (%d): ", nGPR );
>>> +        for ( unsigned int i = 0; i < nGPR; ++i )
>>> +            fprintf( stderr, "0x%lx, ", pGPR[i] );
>>> +        fprintf( stderr, "\nFPR's (%d): ", nFPR );
>>> +        for ( unsigned int i = 0; i < nFPR; ++i )
>>> +            fprintf( stderr, "%f, ", pFPR[i] );
>>> +        fprintf( stderr, "\nStack (%d): ", nStack );
>>> +        for ( unsigned int i = 0; i < nStack; ++i )
>>> +            fprintf( stderr, "0x%lx, ", pStack[i] );
>>> +        fprintf( stderr, "\n" );
>>> +    }
>>> +#endif
>>> +
>>> +    // The call instruction within callVirtualFunction may throw 
>>> exceptions.  So
>>> +    // that the compiler handles this correctly, it is important that (a)
>>> +    // callVirtualMethod might call dummy_can_throw_anything (although 
>>> this never
>>> +    // happens at runtime), which in turn can throw exceptions, and (b)
>>> +    // callVirtualMethod is not inlined at its call site (so that any 
>>> exceptions
>>> +    // thrown across the call are caught):
>>> +    if ( !pThis )
>>> +        CPPU_CURRENT_NAMESPACE::dummy_can_throw_anything( "xxx" ); // 
>>> address something
>>> +
>>> +    // Should not happen, but...
>>> +    if ( nFPR > aarch64::MAX_FPR_REGS )
>>> +        nFPR = aarch64::MAX_FPR_REGS;
>>> +    if ( nGPR > aarch64::MAX_GPR_REGS )
>>> +        nGPR = aarch64::MAX_GPR_REGS;
>>> +
>>> +    // Get pointer to the C++ virtual method from the vtable.
>>> +    sal_uInt64 pMethod = *((sal_uInt64 *)pThis);
>>> +    pMethod += 8 * nVtableIndex;
>>> +    pMethod = *((sal_uInt64 *)pMethod);
>>> +
>>> +    // Return register save areas: x0,x1 and d0..d3 (HFA up to 4 elements).
>>> +    sal_uInt64 gpReturn[2] = { 0, 0 };
>>> +    double fpReturn[4] = { 0, 0, 0, 0 };
>>> +
>>> +    // Ensure the GPR/FPR arrays are the full register width even if fewer 
>>> were
>>> +    // filled (the trampoline always loads all 8 of each).
>>> +    sal_uInt64 gpr[aarch64::MAX_GPR_REGS];
>>> +    double fpr[aarch64::MAX_FPR_REGS];
>>> +    for ( sal_uInt32 i = 0; i < aarch64::MAX_GPR_REGS; ++i )
>>> +        gpr[i] = ( i < nGPR ) ? pGPR[i] : 0;
>>> +    for ( sal_uInt32 i = 0; i < aarch64::MAX_FPR_REGS; ++i )
>>> +        fpr[i] = ( i < nFPR ) ? pFPR[i] : 0;
>>> +
>>> +    callVirtualFunction(
>>> +        pMethod,
>>> +        reinterpret_cast<sal_uInt64>( pIndirectReturn ), // x8, 0 if none
>>> +        gpr, fpr,
>>> +        pStack, nStack,
>>> +        gpReturn, fpReturn );
>>> +
>>> +    switch (pReturnTypeRef->eTypeClass)
>>> +    {
>>> +    case typelib_TypeClass_HYPER:
>>> +    case typelib_TypeClass_UNSIGNED_HYPER:
>>> +        *reinterpret_cast<sal_uInt64 *>( pRegisterReturn ) = gpReturn[0];
>>> +        break;
>>> +    case typelib_TypeClass_LONG:
>>> +    case typelib_TypeClass_UNSIGNED_LONG:
>>> +    case typelib_TypeClass_ENUM:
>>> +        *reinterpret_cast<sal_uInt32 *>( pRegisterReturn ) = 
>>> *reinterpret_cast<sal_uInt32*>( &gpReturn[0] );
>>> +        break;
>>> +    case typelib_TypeClass_CHAR:
>>> +    case typelib_TypeClass_SHORT:
>>> +    case typelib_TypeClass_UNSIGNED_SHORT:
>>> +        *reinterpret_cast<sal_uInt16 *>( pRegisterReturn ) = 
>>> *reinterpret_cast<sal_uInt16*>( &gpReturn[0] );
>>> +        break;
>>> +    case typelib_TypeClass_BOOLEAN:
>>> +    case typelib_TypeClass_BYTE:
>>> +        *reinterpret_cast<sal_uInt8 *>( pRegisterReturn ) = 
>>> *reinterpret_cast<sal_uInt8*>( &gpReturn[0] );
>>> +        break;
>>> +    case typelib_TypeClass_FLOAT:
>>> +    case typelib_TypeClass_DOUBLE:
>>> +        *reinterpret_cast<double *>( pRegisterReturn ) = fpReturn[0];
>>> +        break;
>>> +    default:
>>> +        {
>>> +            sal_Int32 const nRetSize = pReturnTypeRef->pType->nSize;
>>> +            if (bSimpleReturn && nRetSize <= 16 && nRetSize > 0)
>>> +            {
>>> +                // Register-returned aggregate: an HFA arrives in d0..d3, a
>>> +                // non-HFA <= 16 bytes in x0,x1.  fill_struct picks the 
>>> right one.
>>> +                aarch64::fill_struct( pReturnTypeRef, &gpReturn[0], 
>>> &fpReturn[0], pRegisterReturn);
>>> +            }
>>> +            break;
>>> +        }
>>> +    }
>>> +}
>>> +
>>> +//==================================================================================================
>>> +
>>> +// Macros for easier insertion of values to registers or stack
>>> +// pSV - pointer to the source
>>> +// nr - order of the value [will be increased if stored to register]
>>> +// pFPR, pGPR - pointer to the registers
>>> +// pDS - pointer to the stack [will be increased if stored here]
>>> +
>>> +// The pFPR slot holds the value to be loaded into a v register; the 
>>> trampoline
>>> +// loads it with LDR d<n>, so float and double are stored the same way 
>>> here.
>>> +#define INSERT_FLOAT_DOUBLE( pSV, nr, pFPR, pDS ) \
>>> +   if ( nr < aarch64::MAX_FPR_REGS ) \
>>> +           pFPR[nr++] = *reinterpret_cast<double *>( pSV ); \
>>> +   else \
>>> +           *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV ); // verbatim!
>>> +
>>> +#define INSERT_INT64( pSV, nr, pGPR, pDS ) \
>>> +   if ( nr < aarch64::MAX_GPR_REGS ) \
>>> +           pGPR[nr++] = *reinterpret_cast<sal_uInt64 *>( pSV ); \
>>> +   else \
>>> +           *pDS++ = *reinterpret_cast<sal_uInt64 *>( pSV );
>>> +
>>> +#define INSERT_INT32( pSV, nr, pGPR, pDS ) \
>>> +   if ( nr < aarch64::MAX_GPR_REGS ) \
>>> +           pGPR[nr++] = *reinterpret_cast<sal_uInt32 *>( pSV ); \
>>> +   else \
>>> +           *pDS++ = *reinterpret_cast<sal_uInt32 *>( pSV );
>>> +
>>> +#define INSERT_INT16( pSV, nr, pGPR, pDS ) \
>>> +   if ( nr < aarch64::MAX_GPR_REGS ) \
>>> +           pGPR[nr++] = *reinterpret_cast<sal_uInt16 *>( pSV ); \
>>> +   else \
>>> +           *pDS++ = *reinterpret_cast<sal_uInt16 *>( pSV );
>>> +
>>> +#define INSERT_INT8( pSV, nr, pGPR, pDS ) \
>>> +   if ( nr < aarch64::MAX_GPR_REGS ) \
>>> +           pGPR[nr++] = *reinterpret_cast<sal_uInt8 *>( pSV ); \
>>> +   else \
>>> +           *pDS++ = *reinterpret_cast<sal_uInt8 *>( pSV );
>>> +
>>> +//==================================================================================================
>>> +
>>> +namespace {
>>> +
>>> +void appendCString(OUStringBuffer & buffer, char const * text) {
>>> +    if (text != 0) {
>>> +        buffer.append(
>>> +            OStringToOUString(OString(text), RTL_TEXTENCODING_ISO_8859_1));
>>> +            // use 8859-1 to avoid conversion failure
>>> +    }
>>> +}
>>> +
>>> +}
>>> +
>>> +static void cpp_call(
>>> +   bridges::cpp_uno::shared::UnoInterfaceProxy * pThis,
>>> +   bridges::cpp_uno::shared::VtableSlot aVtableSlot,
>>> +   typelib_TypeDescriptionReference * pReturnTypeRef,
>>> +   sal_Int32 nParams, typelib_MethodParameter * pParams,
>>> +   void * pUnoReturn, void * pUnoArgs[], uno_Any ** ppUnoExc )
>>> +{
>>> +   // Maxium space for [complex ret ptr], values | ptr ...
>>> +   // (but will be used less - some of the values will be in pGPR and pFPR)
>>> +   sal_uInt64 *pStack = (sal_uInt64 *)__builtin_alloca( (nParams + 3) * 
>>> sizeof(sal_uInt64) );
>>> +   sal_uInt64 *pStackStart = pStack;
>>> +
>>> +   sal_uInt64 pGPR[aarch64::MAX_GPR_REGS];
>>> +   sal_uInt32 nGPR = 0;
>>> +
>>> +   double pFPR[aarch64::MAX_FPR_REGS];
>>> +   sal_uInt32 nFPR = 0;
>>> +
>>> +   // Return
>>> +   typelib_TypeDescription * pReturnTypeDescr = 0;
>>> +   TYPELIB_DANGER_GET( &pReturnTypeDescr, pReturnTypeRef );
>>> +   OSL_ENSURE( pReturnTypeDescr, "### expected return type description!" );
>>> +
>>> +   void * pCppReturn = 0; // if != 0 && != pUnoReturn, needs reconversion 
>>> (see below)
>>> +
>>> +   // Indirect-result pointer. On AArch64 this is passed in the dedicated 
>>> x8
>>> +   // register, NOT as the first general-purpose argument (unlike x86-64 
>>> SysV).
>>> +   // So we do NOT insert it into pGPR here; it is threaded to the 
>>> trampoline
>>> +   // separately as pIndirectReturn.
>>> +   void * pIndirectReturn = 0;
>>> +
>>> +   bool bSimpleReturn = true;
>>> +   if ( pReturnTypeDescr )
>>> +   {
>>> +           if ( aarch64::return_in_hidden_param( pReturnTypeRef ) )
>>> +                   bSimpleReturn = false;
>>> +
>>> +           if ( bSimpleReturn )
>>> +                   pCppReturn = pUnoReturn; // direct way for simple types
>>> +           else
>>> +           {
>>> +                   // complex return via the x8 indirect-result buffer
>>> +                   pCppReturn = 
>>> bridges::cpp_uno::shared::relatesToInterfaceType( pReturnTypeDescr )?
>>> +                                            __builtin_alloca( 
>>> pReturnTypeDescr->nSize ) : pUnoReturn;
>>> +                   pIndirectReturn = pCppReturn;
>>> +           }
>>> +   }
>>> +
>>> +   // Push "this" pointer
>>> +   void * pAdjustedThisPtr = reinterpret_cast< void ** >( pThis->getCppI() 
>>> ) + aVtableSlot.offset;
>>> +   INSERT_INT64( &pAdjustedThisPtr, nGPR, pGPR, pStack );
>>> +
>>> +   // Args
>>> +   void ** pCppArgs = (void **)alloca( 3 * sizeof(void *) * nParams );
>>> +   // Indizes of values this have to be converted (interface conversion 
>>> cpp<=>uno)
>>> +   sal_Int32 * pTempIndizes = (sal_Int32 *)(pCppArgs + nParams);
>>> +   // Type descriptions for reconversions
>>> +   typelib_TypeDescription ** ppTempParamTypeDescr = 
>>> (typelib_TypeDescription **)(pCppArgs + (2 * nParams));
>>> +
>>> +   sal_Int32 nTempIndizes = 0;
>>> +
>>> +   for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
>>> +   {
>>> +           const typelib_MethodParameter & rParam = pParams[nPos];
>>> +           typelib_TypeDescription * pParamTypeDescr = 0;
>>> +           TYPELIB_DANGER_GET( &pParamTypeDescr, rParam.pTypeRef );
>>> +
>>> +           if (!rParam.bOut && bridges::cpp_uno::shared::isSimpleType( 
>>> pParamTypeDescr ))
>>> +           {
>>> +                   uno_copyAndConvertData( pCppArgs[nPos] = alloca( 8 ), 
>>> pUnoArgs[nPos], pParamTypeDescr,
>>> +                                                                   
>>> pThis->getBridge()->getUno2Cpp() );
>>> +
>>> +                   switch (pParamTypeDescr->eTypeClass)
>>> +                   {
>>> +                   case typelib_TypeClass_HYPER:
>>> +                   case typelib_TypeClass_UNSIGNED_HYPER:
>>> +                           INSERT_INT64( pCppArgs[nPos], nGPR, pGPR, 
>>> pStack );
>>> +                           break;
>>> +                   case typelib_TypeClass_LONG:
>>> +                   case typelib_TypeClass_UNSIGNED_LONG:
>>> +                   case typelib_TypeClass_ENUM:
>>> +                           INSERT_INT32( pCppArgs[nPos], nGPR, pGPR, 
>>> pStack );
>>> +                           break;
>>> +                   case typelib_TypeClass_SHORT:
>>> +                   case typelib_TypeClass_CHAR:
>>> +                   case typelib_TypeClass_UNSIGNED_SHORT:
>>> +                           INSERT_INT16( pCppArgs[nPos], nGPR, pGPR, 
>>> pStack );
>>> +                           break;
>>> +                   case typelib_TypeClass_BOOLEAN:
>>> +                   case typelib_TypeClass_BYTE:
>>> +                           INSERT_INT8( pCppArgs[nPos], nGPR, pGPR, pStack 
>>> );
>>> +                           break;
>>> +                   case typelib_TypeClass_FLOAT:
>>> +                   case typelib_TypeClass_DOUBLE:
>>> +                           INSERT_FLOAT_DOUBLE( pCppArgs[nPos], nFPR, 
>>> pFPR, pStack );
>>> +                           break;
>>> +                   default:
>>> +                           break;
>>> +                   }
>>> +
>>> +                   // no longer needed
>>> +                   TYPELIB_DANGER_RELEASE( pParamTypeDescr );
>>> +           }
>>> +           else // ptr to complex value | ref
>>> +           {
>>> +                   if (! rParam.bIn) // is pure out
>>> +                   {
>>> +                           // cpp out is constructed mem, uno out is not!
>>> +                           uno_constructData(
>>> +                                   pCppArgs[nPos] = alloca( 
>>> pParamTypeDescr->nSize ),
>>> +                                   pParamTypeDescr );
>>> +                           pTempIndizes[nTempIndizes] = nPos; // default 
>>> constructed for cpp call
>>> +                           // will be released at reconversion
>>> +                           ppTempParamTypeDescr[nTempIndizes++] = 
>>> pParamTypeDescr;
>>> +                   }
>>> +                   // is in/inout
>>> +                   else if 
>>> (bridges::cpp_uno::shared::relatesToInterfaceType( pParamTypeDescr ))
>>> +                   {
>>> +                           uno_copyAndConvertData(
>>> +                                   pCppArgs[nPos] = alloca( 
>>> pParamTypeDescr->nSize ),
>>> +                                   pUnoArgs[nPos], pParamTypeDescr, 
>>> pThis->getBridge()->getUno2Cpp() );
>>> +
>>> +                           pTempIndizes[nTempIndizes] = nPos; // has to be 
>>> reconverted
>>> +                           // will be released at reconversion
>>> +                           ppTempParamTypeDescr[nTempIndizes++] = 
>>> pParamTypeDescr;
>>> +                   }
>>> +                   else // direct way
>>> +                   {
>>> +                           pCppArgs[nPos] = pUnoArgs[nPos];
>>> +                           // no longer needed
>>> +                           TYPELIB_DANGER_RELEASE( pParamTypeDescr );
>>> +                   }
>>> +                   INSERT_INT64( &(pCppArgs[nPos]), nGPR, pGPR, pStack );
>>> +           }
>>> +   }
>>> +
>>> +   try
>>> +   {
>>> +        try {
>>> +            callVirtualMethod(
>>> +                pAdjustedThisPtr, aVtableSlot.index,
>>> +                pCppReturn, pReturnTypeRef, bSimpleReturn,
>>> +                pIndirectReturn,
>>> +                pStackStart, ( pStack - pStackStart ),
>>> +                pGPR, nGPR,
>>> +                pFPR, nFPR );
>>> +        } catch (Exception &) {
>>> +            throw;
>>> +        } catch (std::exception & e) {
>>> +            OUStringBuffer buf;
>>> +            buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("C++ code threw "));
>>> +            appendCString(buf, typeid(e).name());
>>> +            buf.appendAscii(RTL_CONSTASCII_STRINGPARAM(": "));
>>> +            appendCString(buf, e.what());
>>> +            throw RuntimeException(
>>> +                buf.makeStringAndClear(), Reference< XInterface >());
>>> +        } catch (...) {
>>> +            throw RuntimeException(
>>> +                OUString(
>>> +                    RTL_CONSTASCII_USTRINGPARAM(
>>> +                        "C++ code threw unknown exception")),
>>> +                Reference< XInterface >());
>>> +        }
>>> +
>>> +           // NO exception occurred...
>>> +           *ppUnoExc = 0;
>>> +
>>> +           // reconvert temporary params
>>> +           for ( ; nTempIndizes--; )
>>> +           {
>>> +                   sal_Int32 nIndex = pTempIndizes[nTempIndizes];
>>> +                   typelib_TypeDescription * pParamTypeDescr = 
>>> ppTempParamTypeDescr[nTempIndizes];
>>> +
>>> +                   if (pParams[nIndex].bIn)
>>> +                   {
>>> +                           if (pParams[nIndex].bOut) // inout
>>> +                           {
>>> +                                   uno_destructData( pUnoArgs[nIndex], 
>>> pParamTypeDescr, 0 ); // destroy uno value
>>> +                                   uno_copyAndConvertData( 
>>> pUnoArgs[nIndex], pCppArgs[nIndex], pParamTypeDescr,
>>> +                                                                           
>>>         pThis->getBridge()->getCpp2Uno() );
>>> +                           }
>>> +                   }
>>> +                   else // pure out
>>> +                   {
>>> +                           uno_copyAndConvertData( pUnoArgs[nIndex], 
>>> pCppArgs[nIndex], pParamTypeDescr,
>>> +                                                                           
>>> pThis->getBridge()->getCpp2Uno() );
>>> +                   }
>>> +                   // destroy temp cpp param => cpp: every param was 
>>> constructed
>>> +                   uno_destructData( pCppArgs[nIndex], pParamTypeDescr, 
>>> cpp_release );
>>> +
>>> +                   TYPELIB_DANGER_RELEASE( pParamTypeDescr );
>>> +           }
>>> +           // return value
>>> +           if (pCppReturn && pUnoReturn != pCppReturn)
>>> +           {
>>> +                   uno_copyAndConvertData( pUnoReturn, pCppReturn, 
>>> pReturnTypeDescr,
>>> +                                                                   
>>> pThis->getBridge()->getCpp2Uno() );
>>> +                   uno_destructData( pCppReturn, pReturnTypeDescr, 
>>> cpp_release );
>>> +           }
>>> +   }
>>> +   catch (...)
>>> +   {
>>> +           // fill uno exception
>>> +           fillUnoException( 
>>> CPPU_CURRENT_NAMESPACE::__cxa_get_globals()->caughtExceptions, *ppUnoExc, 
>>> pThis->getBridge()->getCpp2Uno() );
>>> +
>>> +           // temporary params
>>> +           for ( ; nTempIndizes--; )
>>> +           {
>>> +                   sal_Int32 nIndex = pTempIndizes[nTempIndizes];
>>> +                   // destroy temp cpp param => cpp: every param was 
>>> constructed
>>> +                   uno_destructData( pCppArgs[nIndex], 
>>> ppTempParamTypeDescr[nTempIndizes], cpp_release );
>>> +                   TYPELIB_DANGER_RELEASE( 
>>> ppTempParamTypeDescr[nTempIndizes] );
>>> +           }
>>> +           // return type
>>> +           if (pReturnTypeDescr)
>>> +                   TYPELIB_DANGER_RELEASE( pReturnTypeDescr );
>>> +   }
>>> +}
>>> +
>>> +//==================================================================================================
>>> +
>>> +namespace bridges { namespace cpp_uno { namespace shared {
>>> +
>>> +void unoInterfaceProxyDispatch(
>>> +   uno_Interface * pUnoI, const typelib_TypeDescription * pMemberDescr,
>>> +   void * pReturn, void * pArgs[], uno_Any ** ppException )
>>> +{
>>> +   // is my surrogate
>>> +   bridges::cpp_uno::shared::UnoInterfaceProxy * pThis
>>> +           = static_cast< bridges::cpp_uno::shared::UnoInterfaceProxy * 
>>> >(pUnoI);
>>> +#if OSL_DEBUG_LEVEL > 0
>>> +   typelib_InterfaceTypeDescription * pTypeDescr = pThis->pTypeDescr;
>>> +#endif
>>> +
>>> +   switch (pMemberDescr->eTypeClass)
>>> +   {
>>> +   case typelib_TypeClass_INTERFACE_ATTRIBUTE:
>>> +   {
>>> +#if OSL_DEBUG_LEVEL > 0
>>> +           // determine vtable call index
>>> +           sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
>>> *)pMemberDescr)->nPosition;
>>> +           OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member 
>>> pos out of range!" );
>>> +#endif
>>> +           VtableSlot aVtableSlot(
>>> +                           getVtableSlot(
>>> +                                   reinterpret_cast<
>>> +                                   
>>> typelib_InterfaceAttributeTypeDescription const * >(
>>> +                                           pMemberDescr)));
>>> +
>>> +           if (pReturn)
>>> +           {
>>> +                   // dependent dispatch
>>> +                   cpp_call(
>>> +                           pThis, aVtableSlot,
>>> +                           ((typelib_InterfaceAttributeTypeDescription 
>>> *)pMemberDescr)->pAttributeTypeRef,
>>> +                           0, 0, // no params
>>> +                           pReturn, pArgs, ppException );
>>> +           }
>>> +           else
>>> +           {
>>> +                   // is SET
>>> +                   typelib_MethodParameter aParam;
>>> +                   aParam.pTypeRef =
>>> +                           ((typelib_InterfaceAttributeTypeDescription 
>>> *)pMemberDescr)->pAttributeTypeRef;
>>> +                   aParam.bIn              = sal_True;
>>> +                   aParam.bOut             = sal_False;
>>> +
>>> +                   typelib_TypeDescriptionReference * pReturnTypeRef = 0;
>>> +                   OUString aVoidName( RTL_CONSTASCII_USTRINGPARAM("void") 
>>> );
>>> +                   typelib_typedescriptionreference_new(
>>> +                           &pReturnTypeRef, typelib_TypeClass_VOID, 
>>> aVoidName.pData );
>>> +
>>> +                   // dependent dispatch
>>> +                   aVtableSlot.index += 1; // get, then set method
>>> +                   cpp_call(
>>> +                           pThis, aVtableSlot, // get, then set method
>>> +                           pReturnTypeRef,
>>> +                           1, &aParam,
>>> +                           pReturn, pArgs, ppException );
>>> +
>>> +                   typelib_typedescriptionreference_release( 
>>> pReturnTypeRef );
>>> +           }
>>> +
>>> +           break;
>>> +   }
>>> +   case typelib_TypeClass_INTERFACE_METHOD:
>>> +   {
>>> +#if OSL_DEBUG_LEVEL > 0
>>> +           // determine vtable call index
>>> +           sal_Int32 nMemberPos = ((typelib_InterfaceMemberTypeDescription 
>>> *)pMemberDescr)->nPosition;
>>> +           OSL_ENSURE( nMemberPos < pTypeDescr->nAllMembers, "### member 
>>> pos out of range!" );
>>> +#endif
>>> +           VtableSlot aVtableSlot(
>>> +                           getVtableSlot(
>>> +                                   reinterpret_cast<
>>> +                                   typelib_InterfaceMethodTypeDescription 
>>> const * >(
>>> +                                           pMemberDescr)));
>>> +
>>> +           switch (aVtableSlot.index)
>>> +           {
>>> +                   // standard calls
>>> +           case 1: // acquire uno interface
>>> +                   (*pUnoI->acquire)( pUnoI );
>>> +                   *ppException = 0;
>>> +                   break;
>>> +           case 2: // release uno interface
>>> +                   (*pUnoI->release)( pUnoI );
>>> +                   *ppException = 0;
>>> +                   break;
>>> +           case 0: // queryInterface() opt
>>> +           {
>>> +                   typelib_TypeDescription * pTD = 0;
>>> +                   TYPELIB_DANGER_GET( &pTD, reinterpret_cast< Type * >( 
>>> pArgs[0] )->getTypeLibType() );
>>> +                   if (pTD)
>>> +                   {
>>> +                uno_Interface * pInterface = 0;
>>> +                (*pThis->getBridge()->getUnoEnv()->getRegisteredInterface)(
>>> +                    pThis->getBridge()->getUnoEnv(),
>>> +                    (void **)&pInterface, pThis->oid.pData, 
>>> (typelib_InterfaceTypeDescription *)pTD );
>>> +
>>> +                if (pInterface)
>>> +                {
>>> +                    ::uno_any_construct(
>>> +                        reinterpret_cast< uno_Any * >( pReturn ),
>>> +                        &pInterface, pTD, 0 );
>>> +                    (*pInterface->release)( pInterface );
>>> +                    TYPELIB_DANGER_RELEASE( pTD );
>>> +                    *ppException = 0;
>>> +                    break;
>>> +                }
>>> +                TYPELIB_DANGER_RELEASE( pTD );
>>> +            }
>>> +           } // else perform queryInterface()
>>> +           default:
>>> +                   // dependent dispatch
>>> +                   cpp_call(
>>> +                           pThis, aVtableSlot,
>>> +                           ((typelib_InterfaceMethodTypeDescription 
>>> *)pMemberDescr)->pReturnTypeRef,
>>> +                           ((typelib_InterfaceMethodTypeDescription 
>>> *)pMemberDescr)->nParams,
>>> +                           ((typelib_InterfaceMethodTypeDescription 
>>> *)pMemberDescr)->pParams,
>>> +                           pReturn, pArgs, ppException );
>>> +           }
>>> +           break;
>>> +   }
>>> +   default:
>>> +   {
>>> +           ::com::sun::star::uno::RuntimeException aExc(
>>> +                   OUString( RTL_CONSTASCII_USTRINGPARAM("illegal member 
>>> type description!") ),
>>> +                   ::com::sun::star::uno::Reference< 
>>> ::com::sun::star::uno::XInterface >() );
>>> +
>>> +           Type const & rExcType = ::getCppuType( &aExc );
>>> +           // binary identical null reference
>>> +           ::uno_type_any_construct( *ppException, &aExc, 
>>> rExcType.getTypeLibType(), 0 );
>>> +   }
>>> +   }
>>> +}
>>> +
>>> +} } }
>>> diff --git a/main/configure.ac b/main/configure.ac
>>> index 3f67e5b3fb..8731dc71f4 100644
>>> --- a/main/configure.ac
>>> +++ b/main/configure.ac
>>> @@ -922,8 +922,8 @@ AC_ARG_WITH(arm-target,
>>> AC_ARG_WITH(macosx-target,
>>> [  --macosx-target            The minimal macOS/OSX deployment and build 
>>> target
>>> 
>>> -                              Usage: --with-macosx-target=10.9
>>> -],with_macosx_target=$withval,with_macosx_target=10.9)
>>> +                              Usage: --with-macosx-target=11.0
>>> +],with_macosx_target=$withval,with_macosx_target=11.0)
>>> AC_ARG_WITH(macosx-sdk,
>>> [  --macosx-sdk            The macOS SDK to build against
>>> 
>>> @@ -1159,9 +1159,29 @@ case "$build_os" in
>>>             fi
>>>             # Don't use OSVERSION until we know no conflicts result from it
>>>             _darwin_version="`uname -r | $AWK -F . '{ print $1 }'`"
>>> -           # FIXME: Assumes 10.x, breaks w/ Big Sur
>>> -           _osx_version="10.`expr $_darwin_version - 4`"
>>> +           # Map the Darwin (XNU) major version to the macOS version.
>>> +           # Darwin 6..19  => macOS 10.(darwin-4)   (10.2 .. 10.15)
>>> +           # Darwin 20+    => macOS (darwin-9)       (11, 12, 13, ...)
>>> +           if test "$_darwin_version" -ge 20; then
>>> +              _osx_version="`expr $_darwin_version - 9`"
>>> +           else
>>> +              _osx_version="10.`expr $_darwin_version - 4`"
>>> +           fi
>>>             AC_MSG_NOTICE([Detected Darwin version: $_darwin_version 
>>> ($_osx_version)])
>>> +           # Detect the build CPU architecture. Apple Silicon (arm64) 
>>> reports
>>> +           # "arm64" from uname -m and maps to the aarch64 
>>> toolchain/bridge.
>>> +           _darwin_cpu="`uname -m`"
>>> +           case "$_darwin_cpu" in
>>> +              arm64|aarch64)
>>> +                 AC_MSG_NOTICE([Detected Apple Silicon (arm64) build host])
>>> +                 ;;
>>> +              x86_64|i*86)
>>> +                 AC_MSG_NOTICE([Detected Intel (x86_64) build host])
>>> +                 ;;
>>> +              *)
>>> +                 AC_MSG_ERROR([Unsupported macOS CPU architecture: 
>>> $_darwin_cpu])
>>> +                 ;;
>>> +           esac
>>>             ;;
>>>     os2*)
>>>             test_x=no
>>> @@ -3907,10 +3927,20 @@ if test  "$_os" = "Darwin"; then
>>>    sdk_target=$with_macosx_target
>>>    AC_MSG_CHECKING([checking SDK compatibility with OSX $sdk_target])
>>> 
>>> +   sdk_major=`echo $sdk_target | cut -d"." -f1`
>>>    sdk_minor=`echo $sdk_target | cut -d"." -f2`
>>> +   test -z "$sdk_minor" && sdk_minor=0
>>> +
>>> +   dnl Minimum supported macOS is 11.0 (Big Sur). Pre-11 targets are only
>>> +   dnl accepted down to the old 10.9 floor for legacy Intel builds.
>>> +   if test "$_darwin_cpu" = "arm64" -o "$_darwin_cpu" = "aarch64"; then
>>> +      if test "$sdk_major" -lt "11"; then
>>> +         AC_MSG_ERROR([Apple Silicon (arm64) requires 
>>> --with-macosx-target=11.0 or later])
>>> +      fi
>>> +   fi
>>> 
>>> -   if test "$sdk_minor" -lt "9"; then
>>> -      AC_MSG_ERROR([SDK version < 10.9 is not longer supported])
>>> +   if test "$sdk_major" -lt "10" -o \( "$sdk_major" -eq "10" -a 
>>> "$sdk_minor" -lt "9" \); then
>>> +      AC_MSG_ERROR([macOS deployment target < 10.9 is no longer supported])
>>>    else
>>>       MACOSX_DEPLOYMENT_TARGET=$sdk_target
>>>       sdk_path=$with_macosx_sdk
>>> diff --git a/main/icu/icu4c-4_2_1-src.patch b/main/icu/icu4c-4_2_1-src.patch
>>> index 77fc719528..572572a3ea 100644
>>> --- a/main/icu/icu4c-4_2_1-src.patch
>>> +++ b/main/icu/icu4c-4_2_1-src.patch
>>> @@ -212,7 +212,7 @@ diff -ru misc/icu/source/tools/genuca/genuca.cpp 
>>> misc/build/icu/source/tools/gen
>>> +   echo "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}"
>>>     case "${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}" in  #(
>>> -     *-arch*ppc*|*-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=universal;;
>>> -+    *-arch*i386*|*-arch*x86_64*) ac_cv_c_bigendian=no;;
>>> ++    *-arch*i386*|*-arch*x86_64*|*-arch*arm64*|*-arch*aarch64*) 
>>> ac_cv_c_bigendian=no;;
>>> +     *-arch*ppc*) ac_cv_c_bigendian=yes;;
>>>     esac
>>>  else
>>> diff --git a/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx 
>>> b/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
>>> index daec7fe94a..fbeb1ef201 100644
>>> --- a/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
>>> +++ b/main/jvmfwk/plugins/sunmajor/pluginlib/util.cxx
>>> @@ -102,6 +102,12 @@ struct JavaSearchPathEntry {
>>> struct JavaSearchPathEntry g_arSearchPaths[] = {
>>> #ifdef MACOSX
>>>     { 0, "" },
>>> +    // Modern macOS JDK location (Oracle/Temurin/etc., both arm64 and 
>>> x86_64
>>> +    // install here). Each subdirectory is a JDK whose home is 
>>> Contents/Home,
>>> +    // so scan the immediate contents. A JDK of the wrong architecture 
>>> (e.g. a
>>> +    // Rosetta x86_64 JDK on Apple Silicon) is harmlessly skipped when its
>>> +    // libjvm.dylib fails to load into the native-arch process.
>>> +    { 1, "Library/Java/JavaVirtualMachines/" },
>>>     { 0, "Library/Internet 
>>> Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin" },
>>>     { 0, "System/Library/Frameworks/JavaVM.framework/Versions/1.4.2/" },
>>> #else
>>> @@ -1245,6 +1251,14 @@ void 
>>> createJavaInfoDirScan(vector<rtl::Reference<VendorBase> >& vecInfos)
>>>                                    OUSTR(" is a Java. \n"));
>>> 
>>>                         getJREInfoByPath(aStatus.getFileURL(),vecInfos);
>>> +#ifdef MACOSX
>>> +                        // On macOS a JDK bundle's home is at 
>>> <bundle>/Contents/Home
>>> +                        // (e.g. under 
>>> /Library/Java/JavaVirtualMachines/<jdk>/),
>>> +                        // not the bundle directory itself, so also probe 
>>> there.
>>> +                        getJREInfoByPath(
>>> +                            aStatus.getFileURL() +
>>> +                            OUSTR("/Contents/Home"), vecInfos);
>>> +#endif
>>>                     }
>>> 
>>>                     JFW_ENSURE(errNext == File::E_None || errNext == 
>>> File::E_NOENT,
>>> diff --git a/main/openssl/makefile.mk b/main/openssl/makefile.mk
>>> index cecba9e26e..a5662eabea 100644
>>> --- a/main/openssl/makefile.mk
>>> +++ b/main/openssl/makefile.mk
>>> @@ -107,8 +107,12 @@ UNAME=$(shell uname)
>>> .ENDIF
>>> 
>>> .IF "$(OS)" == "MACOSX"
>>> +.IF "$(CPUNAME)" == "AARCH64"
>>> +   CONFIGURE_ACTION=Configure darwin64-arm64-cc no-dso no-shared $(NO_ASM)
>>> +.ELSE
>>>     CONFIGURE_ACTION=Configure darwin64-x86_64-cc no-dso no-shared $(NO_ASM)
>>> .ENDIF
>>> +.ENDIF
>>> 
>>> .IF "$(OS)" == "WNT"
>>> 
>>> diff --git a/main/python/pyversion.mk b/main/python/pyversion.mk
>>> index 353925e92e..95f7b299da 100644
>>> --- a/main/python/pyversion.mk
>>> +++ b/main/python/pyversion.mk
>>> @@ -20,8 +20,8 @@
>>> # *************************************************************
>>> # when you want to change the python version, you must update the d.lst
>>> # in the python project accordingly !!!
>>> -PYMAJOR=2
>>> -PYMINOR=7
>>> +PYMAJOR=3
>>> +PYMINOR=10
>>> PYMICRO=18
>>> PYVERSION=$(PYMAJOR).$(PYMINOR).$(PYMICRO)
>>> 
>>> diff --git a/main/python/pyversion_dmake.mk b/main/python/pyversion_dmake.mk
>>> index 37aa099277..b8252a9767 100644
>>> --- a/main/python/pyversion_dmake.mk
>>> +++ b/main/python/pyversion_dmake.mk
>>> @@ -20,8 +20,8 @@
>>> # *************************************************************
>>> # when you want to change the python version, you must update the d.lst
>>> # in the python project accordingly !!!
>>> -PYMAJOR=2
>>> -PYMINOR=7
>>> +PYMAJOR=3
>>> +PYMINOR=10
>>> PYMICRO=18
>>> PYVERSION=$(PYMAJOR).$(PYMINOR).$(PYMICRO)
>>> 
>>> diff --git a/main/pyuno/source/loader/pythonloader.py 
>>> b/main/pyuno/source/loader/pythonloader.py
>>> index 46e051da98..34ff1c532b 100644
>>> --- a/main/pyuno/source/loader/pythonloader.py
>>> +++ b/main/pyuno/source/loader/pythonloader.py
>>> @@ -21,7 +21,7 @@
>>> import uno
>>> import unohelper
>>> import sys
>>> -import imp
>>> +import types
>>> import os
>>> from com.sun.star.uno import Exception,RuntimeException
>>> from com.sun.star.loader import XImplementationLoader
>>> @@ -84,14 +84,14 @@ class Loader( XImplementationLoader, XServiceInfo, 
>>> unohelper.Base ):
>>>                 # did we load the module already ?
>>>                 mod = g_loadedComponents.get( url )
>>>                 if not mod:
>>> -                    mod = imp.new_module("uno_component")
>>> +                    mod = types.ModuleType("uno_component")
>>> 
>>>                     # check for pythonpath.zip beside .py files
>>>                     checkForPythonPathBesideComponent( 
>>> url[0:url.rfind('/')] )
>>> 
>>>                     # read the file
>>>                     filename = unohelper.fileUrlToSystemPath( url )
>>> -                    fileHandle = file( filename )
>>> +                    fileHandle = open( filename )
>>>                     src = fileHandle.read().replace("\r","")
>>>                     if not src.endswith( "\n" ):
>>>                         src = src + "\n"
>>> diff --git a/main/sal/osl/unx/interlck.c b/main/sal/osl/unx/interlck.c
>>> index cfcea0fbc0..d24db7b341 100644
>>> --- a/main/sal/osl/unx/interlck.c
>>> +++ b/main/sal/osl/unx/interlck.c
>>> @@ -178,6 +178,29 @@ oslInterlockedCount SAL_CALL 
>>> osl_decrementInterlockedCount(oslInterlockedCount*
>>> #endif
>>> }
>>> 
>>> +#elif (defined(__GNUC__) || defined(__clang__)) && defined ( AARCH64 )
>>> +/* AArch64 (ARM 64-bit, e.g. Apple Silicon). Use the compiler's atomic
>>> +   built-ins, which clang/gcc lower to the AArch64 
>>> load-exclusive/store-exclusive
>>> +   (ldaxr/stlxr) sequence, or to LSE atomics (ldadd) on ARMv8.1+. This 
>>> avoids the
>>> +   global-mutex fallback below. __sync_*_and_fetch are full-barrier and 
>>> return
>>> +   the new value, matching the required semantics. */
>>> +
>>> +/*****************************************************************************/
>>> +/* osl_incrementInterlockedCount */
>>> +/*****************************************************************************/
>>> +oslInterlockedCount SAL_CALL 
>>> osl_incrementInterlockedCount(oslInterlockedCount* pCount)
>>> +{
>>> +    return __sync_add_and_fetch( pCount, 1 );
>>> +}
>>> +
>>> +/*****************************************************************************/
>>> +/* osl_decrementInterlockedCount */
>>> +/*****************************************************************************/
>>> +oslInterlockedCount SAL_CALL 
>>> osl_decrementInterlockedCount(oslInterlockedCount* pCount)
>>> +{
>>> +    return __sync_sub_and_fetch( pCount, 1 );
>>> +}
>>> +
>>> #else
>>> /* use only if nothing else works, expensive due to single mutex for all 
>>> reference counts */
>>> 
>>> diff --git a/main/sal/rtl/source/macro.hxx b/main/sal/rtl/source/macro.hxx
>>> index 10948868f3..4aee4358aa 100644
>>> --- a/main/sal/rtl/source/macro.hxx
>>> +++ b/main/sal/rtl/source/macro.hxx
>>> @@ -77,6 +77,8 @@ this is inserted for the case that the preprocessor 
>>> ignores error
>>> #    else
>>> #        define THIS_ARCH "MIPS_EL"
>>> #    endif
>>> +#elif defined AARCH64
>>> +#    define THIS_ARCH "AARCH64"
>>> #elif defined ARM
>>> #    ifdef __ARM_EABI__
>>> #        define THIS_ARCH "ARM_EABI"
>>> diff --git a/main/scripting/source/pyprov/mailmerge.py 
>>> b/main/scripting/source/pyprov/mailmerge.py
>>> index 4a4c430c28..c11ddd8c7a 100644
>>> --- a/main/scripting/source/pyprov/mailmerge.py
>>> +++ b/main/scripting/source/pyprov/mailmerge.py
>>> @@ -54,13 +54,13 @@ from com.sun.star.lang import IllegalArgumentException
>>> from com.sun.star.lang import EventObject
>>> from com.sun.star.mail import SendMailMessageFailedException
>>> 
>>> -from email.MIMEBase import MIMEBase
>>> -from email.Message import Message
>>> -from email import Encoders
>>> -from email.Header import Header
>>> -from email.MIMEMultipart import MIMEMultipart
>>> -from email.Utils import formatdate
>>> -from email.Utils import parseaddr
>>> +from email.mime.base import MIMEBase
>>> +from email.message import Message
>>> +from email import encoders
>>> +from email.header import Header
>>> +from email.mime.multipart import MIMEMultipart
>>> +from email.utils import formatdate
>>> +from email.utils import parseaddr
>>> from socket import _GLOBAL_DEFAULT_TIMEOUT
>>> 
>>> import sys, smtplib, imaplib, poplib
>>> @@ -245,7 +245,7 @@ class PyMailSMTPService(unohelper.Base, XSmtpService):
>>>             msgattachment = MIMEBase(maintype, subtype)
>>>             data = content.getTransferData(flavor)
>>>             msgattachment.set_payload(data)
>>> -            Encoders.encode_base64(msgattachment)
>>> +            encoders.encode_base64(msgattachment)
>>>             fname = attachment.ReadableName
>>>             try:
>>>                 fname.encode('ascii')
>>> diff --git a/main/scripting/source/pyprov/pythonscript.py 
>>> b/main/scripting/source/pyprov/pythonscript.py
>>> index 4e7fc4667e..03f52b897a 100644
>>> --- a/main/scripting/source/pyprov/pythonscript.py
>>> +++ b/main/scripting/source/pyprov/pythonscript.py
>>> @@ -24,7 +24,7 @@ import uno
>>> import unohelper
>>> import sys
>>> import os
>>> -import imp
>>> +import types
>>> import time
>>> import ast
>>> 
>>> @@ -356,7 +356,7 @@ class ScriptContext(unohelper.Base):
>>> #        code = readTextFromStream( sfa.openFileRead( url ) )
>>> 
>>>         # execute the module
>>> -#        entry = ModuleEntry( lastRead, 
>>> imp.new_module("ooo_script_framework") )
>>> +#        entry = ModuleEntry( lastRead, 
>>> types.ModuleType("ooo_script_framework") )
>>> #        entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = g_scriptContext
>>> #        entry.module.__file__ = url
>>> #        exec code in entry.module.__dict__
>>> @@ -489,7 +489,7 @@ class ProviderContext:
>>>             src = ensureSourceState( src )
>>> 
>>>             # execute the module
>>> -            entry = ModuleEntry( lastRead, 
>>> imp.new_module("ooo_script_framework") )
>>> +            entry = ModuleEntry( lastRead, 
>>> types.ModuleType("ooo_script_framework") )
>>>             entry.module.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = 
>>> self.scriptContext
>>> 
>>>             code = None
>>> @@ -666,7 +666,7 @@ class ScriptBrowseNode( unohelper.Base, XBrowseNode, 
>>> XPropertySet, XInvocation,
>>>             if event.ActionCommand == "Run":
>>>                 code = self.editor.getControl("EditorTextField").getText()
>>>                 code = ensureSourceState( code )
>>> -                mod = imp.new_module("ooo_script_framework")
>>> +                mod = types.ModuleType("ooo_script_framework")
>>>                 mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = 
>>> self.provCtx.scriptContext
>>>                 exec(code, mod.__dict__)
>>>                 values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
>>> @@ -827,7 +827,7 @@ class FileBrowseNode( unohelper.Base, XBrowseNode, 
>>> XPropertySet, XInvocation, XA
>>>             if event.ActionCommand == "Run":
>>>                 code = self.editor.getControl("EditorTextField").getText()
>>>                 code = ensureSourceState( code )
>>> -                mod = imp.new_module("ooo_script_framework")
>>> +                mod = types.ModuleType("ooo_script_framework")
>>>                 mod.__dict__[GLOBAL_SCRIPTCONTEXT_NAME] = 
>>> self.provCtx.scriptContext
>>>                 exec(code, mod.__dict__)
>>>                 values = mod.__dict__.get( CALLABLE_CONTAINER_NAME , None )
>>> diff --git a/main/set_soenv.in b/main/set_soenv.in
>>> index 189b6afdfe..6812905f8e 100644
>>> --- a/main/set_soenv.in
>>> +++ b/main/set_soenv.in
>>> @@ -807,6 +807,14 @@ elsif ( $platform =~ m/darwin/ )
>>>           $CPUNAME        = "X86_64";
>>>           $OUTPATH        = "unxmaccx";
>>>       }
>>> +      elsif ($platform =~ m/^(aarch64|arm64)/)
>>> +      {
>>> +          print "Setting values for MacOSX/Darwin on aarch64 (Apple 
>>> Silicon)... ";
>>> +          $outfile        = "MacOSXAARCH64Env.Set";
>>> +          $CPU            = "R";
>>> +          $CPUNAME        = "AARCH64";
>>> +          $OUTPATH        = "unxmaccr";
>>> +      }
>>>       else
>>>       {
>>>       print "\nset_soenv: Unknown MacOSX/Darwin platform: $platform\n";
>>> diff --git a/main/setup_native/source/mac/Info.plist.langpack 
>>> b/main/setup_native/source/mac/Info.plist.langpack
>>> index 0e12cc1c19..80ad91f30b 100644
>>> --- a/main/setup_native/source/mac/Info.plist.langpack
>>> +++ b/main/setup_native/source/mac/Info.plist.langpack
>>> @@ -23,7 +23,7 @@
>>> <plist version="1.0">
>>> <dict>
>>>     <key>LSMinimumSystemVersion</key>
>>> -   <string>10.7.0</string>
>>> +   <string>11.0</string>
>>>     <key>CFBundleDevelopmentRegion</key>
>>>     <string>English</string>
>>>     <!-- UTI declarations for OS X >= 10.4  -->
>>> diff --git a/main/solenv/bin/modules/installer/download.pm 
>>> b/main/solenv/bin/modules/installer/download.pm
>>> index 6605bbdbc6..6ad1570ab0 100644
>>> --- a/main/solenv/bin/modules/installer/download.pm
>>> +++ b/main/solenv/bin/modules/installer/download.pm
>>> @@ -607,6 +607,10 @@ sub get_download_architecture
>>>     {
>>>             $arch = "x86-64";
>>>     }
>>> +   elsif ( $installer::globals::compiler =~ /^unxmaccr/ )
>>> +   {
>>> +           $arch = "aarch64";
>>> +   }
>>>     elsif ( $installer::globals::issolarissparcbuild )
>>>     {
>>>             $arch = "Sparc";
>>> diff --git a/main/solenv/bin/modules/installer/worker.pm 
>>> b/main/solenv/bin/modules/installer/worker.pm
>>> index 0d387a3e33..ef22a34e2a 100644
>>> --- a/main/solenv/bin/modules/installer/worker.pm
>>> +++ b/main/solenv/bin/modules/installer/worker.pm
>>> @@ -2280,6 +2280,10 @@ sub get_platform_name
>>>     {
>>>             $platformname = "MacOSXX86-64";
>>>     }
>>> +   elsif ( $installer::globals::compiler =~ /^unxmaccr/ )
>>> +   {
>>> +           $platformname = "MacOSXAArch64";
>>> +   }
>>>     elsif ( $installer::globals::compiler =~ /^unxmacxp/ )
>>>     {
>>>             $platformname = "MacOSXPowerPC";
>>> diff --git a/main/solenv/bin/modules/osarch.pm 
>>> b/main/solenv/bin/modules/osarch.pm
>>> index 4ded37ed15..1093b81a27 100644
>>> --- a/main/solenv/bin/modules/osarch.pm
>>> +++ b/main/solenv/bin/modules/osarch.pm
>>> @@ -102,7 +102,9 @@ chop( $m_str, $s_str );
>>>                        "IP22",          "mips",         # voyager
>>>                        "IP32",          "mips",         # giotto
>>>                        "Power Macintosh",                   "ppc",          
>>>         # NetBSD/arm32
>>> -                      "arm32",                     "arm32"                 
>>> # NetBSD/arm32
>>> +                      "arm32",                     "arm32",                
>>> # NetBSD/arm32
>>> +                      "arm64",                     "aarch64",              
>>> # macOS Apple Silicon (uname -m)
>>> +                      "aarch64",           "aarch64"               # Linux 
>>> aarch64
>>>                        );
>>> 
>>> %archDefTable=("sun4c",                     "-DSPARC -DSUN -DSUN4", # hawai
>>> @@ -130,7 +132,9 @@ chop( $m_str, $s_str );
>>>                        "IP22",          "-DMIPS",                   # 
>>> voyager
>>>                        "IP32",          "-DMIPS",                   # giotto
>>>                        "Power Macintosh",           "-DPPC",                
>>> # NetBSD/arm32
>>> -                      "arm32",                     "-DARM32"               
>>> # NetBSD/arm32
>>> +                      "arm32",                     "-DARM32",              
>>> # NetBSD/arm32
>>> +                      "arm64",                     "-DAARCH64",            
>>> # macOS Apple Silicon (uname -m)
>>> +                      "aarch64",           "-DAARCH64"             # Linux 
>>> aarch64
>>>                        );
>>> 
>>> %archDosTable=("sun4c",                     "s",            # hawai
>>> @@ -158,7 +162,9 @@ chop( $m_str, $s_str );
>>>                        "IP22",          "m",                # voyager
>>>                        "IP32",          "m",                # giotto
>>>                        "Power Macintosh",                   "p",            
>>>         # NetBSD/arm32
>>> -                      "arm32",                     "a"                     
>>> # NetBSD/arm32
>>> +                      "arm32",                     "a",                    
>>> # NetBSD/arm32
>>> +                      "arm64",                     "r",                    
>>> # macOS Apple Silicon (uname -m)
>>> +                      "aarch64",           "r"                     # Linux 
>>> aarch64
>>>                        );
>>> 
>>> $main::solarDef             = $osDefTable{ $s_str }.' '.$archDefTable{ 
>>> $m_str };
>>> diff --git a/main/solenv/bin/update_module_ignore_lists.pl 
>>> b/main/solenv/bin/update_module_ignore_lists.pl
>>> index 3a827d743f..f7eecef05d 100644
>>> --- a/main/solenv/bin/update_module_ignore_lists.pl
>>> +++ b/main/solenv/bin/update_module_ignore_lists.pl
>>> @@ -47,6 +47,7 @@ my @platforms = (
>>>         "unxmacxp",
>>>         "unxmacci",
>>>         "unxmaccx",
>>> +        "unxmaccr",
>>>         "unxubit8",
>>>         "unxaixp",
>>>         "unxbsda",
>>> diff --git a/main/solenv/gbuild/platform/macosx.mk 
>>> b/main/solenv/gbuild/platform/macosx.mk
>>> index 3b5d65805a..b9501be453 100644
>>> --- a/main/solenv/gbuild/platform/macosx.mk
>>> +++ b/main/solenv/gbuild/platform/macosx.mk
>>> @@ -64,6 +64,8 @@ ifeq ($(CPUNAME),POWERPC)
>>> gb_CPUDEFS += -DPOWERPC -DPPC
>>> else ifeq ($(CPUNAME),INTEL)
>>> gb_CPUDEFS += -DX86
>>> +else ifeq ($(CPUNAME),AARCH64)
>>> +gb_CPUDEFS += -DARM64
>>> endif
>>> 
>>> ifeq ($(strip $(SYSBASE)),)
>>> diff --git a/main/solenv/inc/unx.mk b/main/solenv/inc/unx.mk
>>> index f956e43a82..b5b4731cd6 100644
>>> --- a/main/solenv/inc/unx.mk
>>> +++ b/main/solenv/inc/unx.mk
>>> @@ -160,6 +160,10 @@
>>> .INCLUDE : unxmaccx.mk
>>> .ENDIF
>>> 
>>> +.IF "$(COM)$(OS)$(CPU)" == "CLANGMACOSXR"
>>> +.INCLUDE : unxmaccr.mk
>>> +.ENDIF
>>> +
>>> .IF "$(OS)$(CPU)" == "LINUXM"
>>> .INCLUDE : unxlngmips.mk
>>> .ENDIF
>>> diff --git a/main/solenv/inc/unxmaccr.mk b/main/solenv/inc/unxmaccr.mk
>>> new file mode 100644
>>> index 0000000000..0fdf36cc2d
>>> --- /dev/null
>>> +++ b/main/solenv/inc/unxmaccr.mk
>>> @@ -0,0 +1,42 @@
>>> +#**************************************************************
>>> +#
>>> +#  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
>>> +#
>>> +#  Unless required by applicable law or agreed to in writing,
>>> +#  software distributed under the License is distributed on an
>>> +#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
>>> +#  KIND, either express or implied.  See the License for the
>>> +#  specific language governing permissions and limitations
>>> +#  under the License.
>>> +#
>>> +#**************************************************************
>>> +
>>> +# Mac OSX aarch64 (Apple Silicon) specific defines
>>> +
>>> +PROCESSOR_DEFINES=-DAARCH64
>>> +BUILD64=1
>>> +
>>> +DLLPOSTFIX=
>>> +
>>> +# Build explicitly for arm64. Use conditional assignment (*=) so the value 
>>> can
>>> +# still be overridden by exporting ARCH_FLAGS in the environment. 
>>> unxmacc.mk
>>> +# also declares ARCH_FLAGS*= (empty), which becomes a no-op once set here.
>>> +ARCH_FLAGS*=-arch arm64
>>> +
>>> +# flags to enable build with symbols; required by crashdump feature
>>> +.IF "$(ENABLE_SYMBOLS)"=="SMALL"
>>> +CFLAGSENABLESYMBOLS=-g1
>>> +.ELSE
>>> +CFLAGSENABLESYMBOLS=-g
>>> +.ENDIF
>>> +
>>> +# Include generic Mac OS X makefile
>>> +.INCLUDE : unxmacc.mk
>>> diff --git a/main/source_soenv.sh b/main/source_soenv.sh
>>> index 9d522c359f..ce87621c36 100644
>>> --- a/main/source_soenv.sh
>>> +++ b/main/source_soenv.sh
>>> @@ -108,6 +108,9 @@ else
>>>         i[3456]86-*-darwin*|x86_64-*-darwin*)
>>>             . ./MacOSXX64Env.Set.sh
>>>         ;;
>>> +        aarch64-*-darwin*|arm64-*-darwin*)
>>> +            . ./MacOSXAARCH64Env.Set.sh
>>> +        ;;
>>>         powerpc-*-darwin*)
>>>             . ./MacOSXPPCEnv.Set.sh
>>>         ;;
>>> diff --git a/main/sysui/desktop/macosx/Info.plist 
>>> b/main/sysui/desktop/macosx/Info.plist
>>> index d26d4251fe..9ffda6b8fa 100644
>>> --- a/main/sysui/desktop/macosx/Info.plist
>>> +++ b/main/sysui/desktop/macosx/Info.plist
>>> @@ -23,7 +23,7 @@
>>> <plist version="1.0">
>>> <dict>
>>>     <key>LSMinimumSystemVersion</key>
>>> -   <string>10.7.0</string>
>>> +   <string>11.0</string>
>>>     <key>CFBundleDevelopmentRegion</key>
>>>     <string>English</string>
>>>     <!-- UTI declarations for OS X >= 10.4  -->
>>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [email protected]
>> For additional commands, e-mail: [email protected]
>> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
> 

--
Jim
  "This is an outrage!"
                        Tony Harrison

Reply via email to