xref: /trunk/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/abi.cxx (revision 9c15e1abd703a7953928d7a80655ae1a76a41f6d)
1*9c15e1abSPedro Giffuni /*
2*9c15e1abSPedro Giffuni  * Licensed to the Apache Software Foundation (ASF) under one
3*9c15e1abSPedro Giffuni  * or more contributor license agreements.  See the NOTICE file
4*9c15e1abSPedro Giffuni  * distributed with this work for additional information
5*9c15e1abSPedro Giffuni  * regarding copyright ownership.  The ASF licenses this file
6*9c15e1abSPedro Giffuni  * to you under the Apache License, Version 2.0 (the
7*9c15e1abSPedro Giffuni  * "License"); you may not use this file except in compliance
8*9c15e1abSPedro Giffuni  * with the License.  You may obtain a copy of the License at
9*9c15e1abSPedro Giffuni  *
10*9c15e1abSPedro Giffuni  *   http://www.apache.org/licenses/LICENSE-2.0
11*9c15e1abSPedro Giffuni  *
12*9c15e1abSPedro Giffuni  * Unless required by applicable law or agreed to in writing,
13*9c15e1abSPedro Giffuni  * software distributed under the License is distributed on an
14*9c15e1abSPedro Giffuni  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15*9c15e1abSPedro Giffuni  * KIND, either express or implied.  See the License for the
16*9c15e1abSPedro Giffuni  * specific language governing permissions and limitations
17*9c15e1abSPedro Giffuni  * under the License.
18*9c15e1abSPedro Giffuni  */
19*9c15e1abSPedro Giffuni 
20*9c15e1abSPedro Giffuni 
21*9c15e1abSPedro Giffuni // MARKER(update_precomp.py): autogen include statement, do not remove
22*9c15e1abSPedro Giffuni #include "precompiled_bridges.hxx"
23*9c15e1abSPedro Giffuni 
24*9c15e1abSPedro Giffuni // This is an implementation of the parameter-classification rules of the
25*9c15e1abSPedro Giffuni // AArch64 procedure call standard ("Procedure Call Standard for the Arm 64-bit
26*9c15e1abSPedro Giffuni // Architecture", ARM IHI 0055).
27*9c15e1abSPedro Giffuni //
28*9c15e1abSPedro Giffuni // Unlike the System V AMD64 ABI (used by the x86-64 bridge), AAPCS64 does not
29*9c15e1abSPedro Giffuni // split aggregates into per-eightbyte INTEGER/SSE classes.  Instead:
30*9c15e1abSPedro Giffuni //   * scalars go in one GPR (x) or one FP/SIMD (v) register;
31*9c15e1abSPedro Giffuni //   * a Homogeneous Floating-point Aggregate (HFA: <= 4 members, all the same
32*9c15e1abSPedro Giffuni //     FP type, recursively) goes in consecutive v registers;
33*9c15e1abSPedro Giffuni //   * any other aggregate <= 16 bytes goes in 1-2 GPRs;
34*9c15e1abSPedro Giffuni //   * a non-HFA aggregate > 16 bytes is passed indirectly (a pointer to a
35*9c15e1abSPedro Giffuni //     caller-allocated copy).
36*9c15e1abSPedro Giffuni // Register fill is "all or nothing": if an aggregate does not fit entirely in
37*9c15e1abSPedro Giffuni // the remaining registers of its bank, it is passed wholly on the stack.
38*9c15e1abSPedro Giffuni //
39*9c15e1abSPedro Giffuni // This is a clean-room implementation from the public specifications; see
40*9c15e1abSPedro Giffuni // ../../../../AAPCS64_BRIDGE_SPEC.md.
41*9c15e1abSPedro Giffuni 
42*9c15e1abSPedro Giffuni #include "abi.hxx"
43*9c15e1abSPedro Giffuni 
44*9c15e1abSPedro Giffuni #include "bridges/cpp_uno/shared/types.hxx"
45*9c15e1abSPedro Giffuni 
46*9c15e1abSPedro Giffuni #include <rtl/ustring.hxx>
47*9c15e1abSPedro Giffuni #include <string.h>
48*9c15e1abSPedro Giffuni 
49*9c15e1abSPedro Giffuni using namespace aarch64;
50*9c15e1abSPedro Giffuni 
51*9c15e1abSPedro Giffuni namespace {
52*9c15e1abSPedro Giffuni 
53*9c15e1abSPedro Giffuni // The element type of a Homogeneous Floating-point Aggregate.
54*9c15e1abSPedro Giffuni enum HfaKind
55*9c15e1abSPedro Giffuni {
56*9c15e1abSPedro Giffuni     HFA_NONE,       // not (yet) an HFA
57*9c15e1abSPedro Giffuni     HFA_FLOAT,      // all members are FLOAT (4-byte)
58*9c15e1abSPedro Giffuni     HFA_DOUBLE      // all members are DOUBLE (8-byte)
59*9c15e1abSPedro Giffuni };
60*9c15e1abSPedro Giffuni 
61*9c15e1abSPedro Giffuni // Combine the running HFA kind with a newly-seen member kind.  Two members
62*9c15e1abSPedro Giffuni // of different FP types, or any non-FP member, break the homogeneity.
mergeHfa(HfaKind running,HfaKind seen)63*9c15e1abSPedro Giffuni HfaKind mergeHfa( HfaKind running, HfaKind seen )
64*9c15e1abSPedro Giffuni {
65*9c15e1abSPedro Giffuni     if ( seen == HFA_NONE )
66*9c15e1abSPedro Giffuni         return HFA_NONE;
67*9c15e1abSPedro Giffuni     if ( running == HFA_NONE )
68*9c15e1abSPedro Giffuni         return seen;
69*9c15e1abSPedro Giffuni     return ( running == seen ) ? running : HFA_NONE;
70*9c15e1abSPedro Giffuni }
71*9c15e1abSPedro Giffuni 
isComplexAggregate(typelib_TypeDescriptionReference * pTypeRef)72*9c15e1abSPedro Giffuni bool isComplexAggregate( typelib_TypeDescriptionReference *pTypeRef )
73*9c15e1abSPedro Giffuni {
74*9c15e1abSPedro Giffuni     typelib_TypeDescription * pTypeDescr = 0;
75*9c15e1abSPedro Giffuni     TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
76*9c15e1abSPedro Giffuni     const typelib_CompoundTypeDescription *pComp =
77*9c15e1abSPedro Giffuni         reinterpret_cast<const typelib_CompoundTypeDescription *>( pTypeDescr );
78*9c15e1abSPedro Giffuni     bool complex = pComp->pBaseTypeDescription != 0 &&
79*9c15e1abSPedro Giffuni         isComplexAggregate( pComp->pBaseTypeDescription->aBase.pWeakRef );
80*9c15e1abSPedro Giffuni     for ( sal_Int32 i = 0; !complex && i < pComp->nMembers; ++i )
81*9c15e1abSPedro Giffuni     {
82*9c15e1abSPedro Giffuni         typelib_TypeClass typeClass = pComp->ppTypeRefs[i]->eTypeClass;
83*9c15e1abSPedro Giffuni         if ( typeClass == typelib_TypeClass_STRUCT ||
84*9c15e1abSPedro Giffuni              typeClass == typelib_TypeClass_EXCEPTION )
85*9c15e1abSPedro Giffuni             complex = isComplexAggregate( pComp->ppTypeRefs[i] );
86*9c15e1abSPedro Giffuni         else
87*9c15e1abSPedro Giffuni             complex = !bridges::cpp_uno::shared::isSimpleType( typeClass );
88*9c15e1abSPedro Giffuni     }
89*9c15e1abSPedro Giffuni     TYPELIB_DANGER_RELEASE( pTypeDescr );
90*9c15e1abSPedro Giffuni     return complex;
91*9c15e1abSPedro Giffuni }
92*9c15e1abSPedro Giffuni 
93*9c15e1abSPedro Giffuni // Recursively determine whether pTypeRef is (part of) a homogeneous
94*9c15e1abSPedro Giffuni // floating-point aggregate, accumulating the element kind and member count.
95*9c15e1abSPedro Giffuni //
96*9c15e1abSPedro Giffuni // Returns false the moment homogeneity is violated (a non-FP scalar, or a
97*9c15e1abSPedro Giffuni // second distinct FP type, or > 4 elements).  A FLOAT/DOUBLE scalar counts as
98*9c15e1abSPedro Giffuni // a 1-element HFA of itself; a struct flattens its members (and base classes).
collectHfa(typelib_TypeDescriptionReference * pTypeRef,HfaKind & rKind,int & rCount)99*9c15e1abSPedro Giffuni bool collectHfa( typelib_TypeDescriptionReference *pTypeRef, HfaKind &rKind, int &rCount )
100*9c15e1abSPedro Giffuni {
101*9c15e1abSPedro Giffuni     switch ( pTypeRef->eTypeClass )
102*9c15e1abSPedro Giffuni     {
103*9c15e1abSPedro Giffuni         case typelib_TypeClass_FLOAT:
104*9c15e1abSPedro Giffuni             rKind = mergeHfa( rKind, HFA_FLOAT );
105*9c15e1abSPedro Giffuni             if ( rKind == HFA_NONE ) return false;
106*9c15e1abSPedro Giffuni             return ( ++rCount <= 4 );
107*9c15e1abSPedro Giffuni 
108*9c15e1abSPedro Giffuni         case typelib_TypeClass_DOUBLE:
109*9c15e1abSPedro Giffuni             rKind = mergeHfa( rKind, HFA_DOUBLE );
110*9c15e1abSPedro Giffuni             if ( rKind == HFA_NONE ) return false;
111*9c15e1abSPedro Giffuni             return ( ++rCount <= 4 );
112*9c15e1abSPedro Giffuni 
113*9c15e1abSPedro Giffuni         case typelib_TypeClass_STRUCT:
114*9c15e1abSPedro Giffuni         case typelib_TypeClass_EXCEPTION:
115*9c15e1abSPedro Giffuni         {
116*9c15e1abSPedro Giffuni             typelib_TypeDescription * pTypeDescr = 0;
117*9c15e1abSPedro Giffuni             TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
118*9c15e1abSPedro Giffuni 
119*9c15e1abSPedro Giffuni             const typelib_CompoundTypeDescription *pComp =
120*9c15e1abSPedro Giffuni                 reinterpret_cast<const typelib_CompoundTypeDescription*>( pTypeDescr );
121*9c15e1abSPedro Giffuni 
122*9c15e1abSPedro Giffuni             // rCount is cumulative over the whole recursion, so remember where
123*9c15e1abSPedro Giffuni             // this aggregate started in order to size-check it below.
124*9c15e1abSPedro Giffuni             const int nCountAtEntry = rCount;
125*9c15e1abSPedro Giffuni             bool bOk = true;
126*9c15e1abSPedro Giffuni 
127*9c15e1abSPedro Giffuni             // Flatten base class first (its members precede ours in layout).
128*9c15e1abSPedro Giffuni             if ( pComp->pBaseTypeDescription )
129*9c15e1abSPedro Giffuni             {
130*9c15e1abSPedro Giffuni                 bOk = collectHfa(
131*9c15e1abSPedro Giffuni                     pComp->pBaseTypeDescription->aBase.pWeakRef, rKind, rCount );
132*9c15e1abSPedro Giffuni             }
133*9c15e1abSPedro Giffuni 
134*9c15e1abSPedro Giffuni             for ( sal_Int32 i = 0; bOk && i < pComp->nMembers; ++i )
135*9c15e1abSPedro Giffuni                 bOk = collectHfa( pComp->ppTypeRefs[i], rKind, rCount );
136*9c15e1abSPedro Giffuni 
137*9c15e1abSPedro Giffuni             if ( bOk )
138*9c15e1abSPedro Giffuni             {
139*9c15e1abSPedro Giffuni                 // Reject anything the elements do not tile exactly: only the
140*9c15e1abSPedro Giffuni                 // elements contributed by THIS aggregate count towards its size.
141*9c15e1abSPedro Giffuni                 sal_Int32 elementSize = rKind == HFA_FLOAT ? 4 : 8;
142*9c15e1abSPedro Giffuni                 bOk = pTypeDescr->nSize ==
143*9c15e1abSPedro Giffuni                     ( rCount - nCountAtEntry ) * elementSize;
144*9c15e1abSPedro Giffuni                 for ( sal_Int32 i = 0; bOk && i < pComp->nMembers; ++i )
145*9c15e1abSPedro Giffuni                     bOk = pComp->pMemberOffsets[i] % elementSize == 0;
146*9c15e1abSPedro Giffuni             }
147*9c15e1abSPedro Giffuni 
148*9c15e1abSPedro Giffuni             TYPELIB_DANGER_RELEASE( pTypeDescr );
149*9c15e1abSPedro Giffuni             return bOk;
150*9c15e1abSPedro Giffuni         }
151*9c15e1abSPedro Giffuni 
152*9c15e1abSPedro Giffuni         default:
153*9c15e1abSPedro Giffuni             // Any non-FP, non-aggregate member breaks homogeneity.
154*9c15e1abSPedro Giffuni             rKind = HFA_NONE;
155*9c15e1abSPedro Giffuni             return false;
156*9c15e1abSPedro Giffuni     }
157*9c15e1abSPedro Giffuni }
158*9c15e1abSPedro Giffuni 
159*9c15e1abSPedro Giffuni // Classify an aggregate (STRUCT/EXCEPTION).  Sets the GPR/FPR counts and
160*9c15e1abSPedro Giffuni // returns true if it is passed in registers, false if it must be passed
161*9c15e1abSPedro Giffuni // indirectly (in memory).
classifyAggregate(typelib_TypeDescriptionReference * pTypeRef,int & nUsedGPR,int & nUsedFPR)162*9c15e1abSPedro Giffuni bool classifyAggregate( typelib_TypeDescriptionReference *pTypeRef, int &nUsedGPR, int &nUsedFPR )
163*9c15e1abSPedro Giffuni {
164*9c15e1abSPedro Giffuni     // First, the HFA test.
165*9c15e1abSPedro Giffuni     HfaKind kind = HFA_NONE;
166*9c15e1abSPedro Giffuni     int count = 0;
167*9c15e1abSPedro Giffuni     if ( collectHfa( pTypeRef, kind, count ) && kind != HFA_NONE )
168*9c15e1abSPedro Giffuni     {
169*9c15e1abSPedro Giffuni         nUsedFPR = count;
170*9c15e1abSPedro Giffuni         nUsedGPR = 0;
171*9c15e1abSPedro Giffuni         return true; // HFA passed in consecutive FP regs
172*9c15e1abSPedro Giffuni     }
173*9c15e1abSPedro Giffuni 
174*9c15e1abSPedro Giffuni     // Not HFA: if bigger than 16 bytes, pass indirectly.
175*9c15e1abSPedro Giffuni     typelib_TypeDescription * pTypeDescr = 0;
176*9c15e1abSPedro Giffuni     TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
177*9c15e1abSPedro Giffuni     if ( pTypeDescr->nSize > 16 )
178*9c15e1abSPedro Giffuni     {
179*9c15e1abSPedro Giffuni         TYPELIB_DANGER_RELEASE( pTypeDescr );
180*9c15e1abSPedro Giffuni         nUsedGPR = nUsedFPR = 0;
181*9c15e1abSPedro Giffuni         return false; // indirect
182*9c15e1abSPedro Giffuni     }
183*9c15e1abSPedro Giffuni 
184*9c15e1abSPedro Giffuni     // small aggregate: it occupies 1 or 2 GPRs depending on size
185*9c15e1abSPedro Giffuni     nUsedFPR = 0;
186*9c15e1abSPedro Giffuni     nUsedGPR = ( pTypeDescr->nSize + 7 ) / 8;
187*9c15e1abSPedro Giffuni     if ( nUsedGPR < 1 ) nUsedGPR = 1;
188*9c15e1abSPedro Giffuni     TYPELIB_DANGER_RELEASE( pTypeDescr );
189*9c15e1abSPedro Giffuni     return true;
190*9c15e1abSPedro Giffuni }
191*9c15e1abSPedro Giffuni 
192*9c15e1abSPedro Giffuni } // anonymous namespace
193*9c15e1abSPedro Giffuni 
194*9c15e1abSPedro Giffuni // Public API implementations.
195*9c15e1abSPedro Giffuni namespace aarch64
196*9c15e1abSPedro Giffuni {
197*9c15e1abSPedro Giffuni 
examine_argument(typelib_TypeDescriptionReference * pTypeRef,bool bInReturn,int & nUsedGPR,int & nUsedFPR)198*9c15e1abSPedro Giffuni bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedFPR )
199*9c15e1abSPedro Giffuni {
200*9c15e1abSPedro Giffuni     // For returns, the hidden param rule uses >16 bytes for aggregates.
201*9c15e1abSPedro Giffuni     if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
202*9c15e1abSPedro Giffuni     {
203*9c15e1abSPedro Giffuni         return classifyAggregate( pTypeRef, nUsedGPR, nUsedFPR );
204*9c15e1abSPedro Giffuni     }
205*9c15e1abSPedro Giffuni 
206*9c15e1abSPedro Giffuni     // Scalars: floats -> FPR, others -> GPR
207*9c15e1abSPedro Giffuni     switch ( pTypeRef->eTypeClass )
208*9c15e1abSPedro Giffuni     {
209*9c15e1abSPedro Giffuni         case typelib_TypeClass_FLOAT:
210*9c15e1abSPedro Giffuni             nUsedFPR = 1; nUsedGPR = 0; return true;
211*9c15e1abSPedro Giffuni         case typelib_TypeClass_DOUBLE:
212*9c15e1abSPedro Giffuni             nUsedFPR = 1; nUsedGPR = 0; return true;
213*9c15e1abSPedro Giffuni         default:
214*9c15e1abSPedro Giffuni             nUsedFPR = 0; nUsedGPR = 1; return true;
215*9c15e1abSPedro Giffuni     }
216*9c15e1abSPedro Giffuni }
217*9c15e1abSPedro Giffuni 
return_in_hidden_param(typelib_TypeDescriptionReference * pTypeRef)218*9c15e1abSPedro Giffuni bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef )
219*9c15e1abSPedro Giffuni {
220*9c15e1abSPedro Giffuni     if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
221*9c15e1abSPedro Giffuni     {
222*9c15e1abSPedro Giffuni         typelib_TypeDescription * pTypeDescr = 0;
223*9c15e1abSPedro Giffuni         TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
224*9c15e1abSPedro Giffuni         bool ret = pTypeDescr->nSize > 16;
225*9c15e1abSPedro Giffuni         TYPELIB_DANGER_RELEASE( pTypeDescr );
226*9c15e1abSPedro Giffuni         return ret;
227*9c15e1abSPedro Giffuni     }
228*9c15e1abSPedro Giffuni     return false; // scalars and small aggregates return in registers
229*9c15e1abSPedro Giffuni }
230*9c15e1abSPedro Giffuni 
get_return_kind(typelib_TypeDescriptionReference * pTypeRef)231*9c15e1abSPedro Giffuni sal_uInt32 get_return_kind( typelib_TypeDescriptionReference *pTypeRef )
232*9c15e1abSPedro Giffuni {
233*9c15e1abSPedro Giffuni     if ( pTypeRef->eTypeClass == typelib_TypeClass_FLOAT )
234*9c15e1abSPedro Giffuni         return typelib_TypeClass_FLOAT;
235*9c15e1abSPedro Giffuni 
236*9c15e1abSPedro Giffuni     if ( pTypeRef->eTypeClass == typelib_TypeClass_DOUBLE )
237*9c15e1abSPedro Giffuni         return typelib_TypeClass_DOUBLE;
238*9c15e1abSPedro Giffuni 
239*9c15e1abSPedro Giffuni     if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT ||
240*9c15e1abSPedro Giffuni          pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
241*9c15e1abSPedro Giffuni     {
242*9c15e1abSPedro Giffuni         HfaKind kind = HFA_NONE;
243*9c15e1abSPedro Giffuni         int count = 0;
244*9c15e1abSPedro Giffuni 
245*9c15e1abSPedro Giffuni         if ( collectHfa( pTypeRef, kind, count ) )
246*9c15e1abSPedro Giffuni         {
247*9c15e1abSPedro Giffuni             if ( kind == HFA_FLOAT )
248*9c15e1abSPedro Giffuni                 return RETURN_KIND_HFA_FLOAT;
249*9c15e1abSPedro Giffuni 
250*9c15e1abSPedro Giffuni             if ( kind == HFA_DOUBLE )
251*9c15e1abSPedro Giffuni                 return RETURN_KIND_HFA_DOUBLE;
252*9c15e1abSPedro Giffuni         }
253*9c15e1abSPedro Giffuni     }
254*9c15e1abSPedro Giffuni 
255*9c15e1abSPedro Giffuni     return pTypeRef->eTypeClass;
256*9c15e1abSPedro Giffuni }
257*9c15e1abSPedro Giffuni 
fill_struct(typelib_TypeDescriptionReference * pTypeRef,const sal_uInt64 * pGPR,const double * pFPR,void * pStruct)258*9c15e1abSPedro Giffuni void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pFPR, void *pStruct )
259*9c15e1abSPedro Giffuni {
260*9c15e1abSPedro Giffuni     // For small aggregates, copy from GPR slots; for HFAs, copy from FPR slots.
261*9c15e1abSPedro Giffuni     if ( pTypeRef->eTypeClass == typelib_TypeClass_STRUCT || pTypeRef->eTypeClass == typelib_TypeClass_EXCEPTION )
262*9c15e1abSPedro Giffuni     {
263*9c15e1abSPedro Giffuni         int nGPR=0, nFPR=0;
264*9c15e1abSPedro Giffuni         if ( classifyAggregate( pTypeRef, nGPR, nFPR ) )
265*9c15e1abSPedro Giffuni         {
266*9c15e1abSPedro Giffuni             if ( nFPR > 0 )
267*9c15e1abSPedro Giffuni             {
268*9c15e1abSPedro Giffuni             // HFA: copy elements from FPR slots. For FLOAT HFAs each element is
269*9c15e1abSPedro Giffuni             // 4 bytes but occupies an 8-byte saved slot; copy each float from the
270*9c15e1abSPedro Giffuni             // low 4 bytes of the corresponding double-sized slot. DOUBLE HFAs
271*9c15e1abSPedro Giffuni             // can be copied directly.
272*9c15e1abSPedro Giffuni             HfaKind kind = HFA_NONE;
273*9c15e1abSPedro Giffuni             int count = 0;
274*9c15e1abSPedro Giffuni             if ( collectHfa( pTypeRef, kind, count ) && kind == HFA_FLOAT )
275*9c15e1abSPedro Giffuni             {
276*9c15e1abSPedro Giffuni                 for ( int i = 0; i < nFPR; ++i )
277*9c15e1abSPedro Giffuni                     memcpy(
278*9c15e1abSPedro Giffuni                         static_cast<char *>( pStruct ) + i * sizeof(float),
279*9c15e1abSPedro Giffuni                         reinterpret_cast<const char *>( pFPR) + i * sizeof(double),
280*9c15e1abSPedro Giffuni                         sizeof(float) );
281*9c15e1abSPedro Giffuni             }
282*9c15e1abSPedro Giffuni             else
283*9c15e1abSPedro Giffuni             {
284*9c15e1abSPedro Giffuni                 memcpy( pStruct, pFPR, nFPR * sizeof(double) );
285*9c15e1abSPedro Giffuni             }
286*9c15e1abSPedro Giffuni             }
287*9c15e1abSPedro Giffuni             else
288*9c15e1abSPedro Giffuni             {
289*9c15e1abSPedro Giffuni                 memcpy( pStruct, pGPR, nGPR * sizeof(sal_uInt64) );
290*9c15e1abSPedro Giffuni             }
291*9c15e1abSPedro Giffuni         }
292*9c15e1abSPedro Giffuni     }
293*9c15e1abSPedro Giffuni }
294*9c15e1abSPedro Giffuni 
align_stack_offset(sal_uInt32 offset,typelib_TypeDescriptionReference * pTypeRef)295*9c15e1abSPedro Giffuni sal_uInt32 align_stack_offset( sal_uInt32 offset, typelib_TypeDescriptionReference *pTypeRef )
296*9c15e1abSPedro Giffuni {
297*9c15e1abSPedro Giffuni     // AArch64 stack overflow area is packed; align to natural alignment of the type (8)
298*9c15e1abSPedro Giffuni     const sal_uInt32 align = 8;
299*9c15e1abSPedro Giffuni     return ( offset + align - 1 ) & ~( align - 1 );
300*9c15e1abSPedro Giffuni }
301*9c15e1abSPedro Giffuni 
stack_size(typelib_TypeDescriptionReference * pTypeRef)302*9c15e1abSPedro Giffuni sal_uInt32 stack_size( typelib_TypeDescriptionReference *pTypeRef )
303*9c15e1abSPedro Giffuni {
304*9c15e1abSPedro Giffuni     // For simple types and small aggregates, size is rounded to 8
305*9c15e1abSPedro Giffuni     typelib_TypeDescription * pTypeDescr = 0;
306*9c15e1abSPedro Giffuni     TYPELIB_DANGER_GET( &pTypeDescr, pTypeRef );
307*9c15e1abSPedro Giffuni     sal_uInt32 size = pTypeDescr->nSize;
308*9c15e1abSPedro Giffuni     TYPELIB_DANGER_RELEASE( pTypeDescr );
309*9c15e1abSPedro Giffuni     return ( size + 7 ) & ~7u;
310*9c15e1abSPedro Giffuni }
311*9c15e1abSPedro Giffuni 
312*9c15e1abSPedro Giffuni } // namespace aarch64
313