xref: /trunk/main/bridges/source/cpp_uno/s5abi_macosx_aarch64/abi.hxx (revision 5e139d9fe42a654147771da4118aea6285c03168)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
25 #define _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
26 
27 // This is an implementation of the AArch64 procedure call standard, as
28 // described in "Procedure Call Standard for the Arm 64-bit Architecture"
29 // (ARM IHI 0055), with the deviations documented in Apple's "Writing ARM64
30 // Code for Apple Platforms".  It is a clean-room implementation written from
31 // those public specifications; see ../../../../AAPCS64_BRIDGE_SPEC.md.
32 
33 #include <typelib/typedescription.hxx>
34 
35 namespace aarch64
36 {
37 
38 /* 8 general purpose registers (x0..x7) are used for parameter passing.
39    Note: the indirect-result-location register x8 is *separate* and is NOT
40    part of this count. */
41 const sal_uInt32 MAX_GPR_REGS = 8;
42 
43 /* 8 SIMD/FP registers (v0..v7) are used for parameter passing. */
44 const sal_uInt32 MAX_FPR_REGS = 8;
45 
46 /* The largest number of registers a single aggregate can occupy: an HFA/HVA
47    may use up to 4 FP registers; a non-HFA aggregate passed in GPRs uses at
48    most 2 (16 bytes / 8). */
49 const sal_uInt32 MAX_AGGREGATE_REGS = 4;
50 
51 /* Count the number of registers required to pass the given type.
52 
53    Examines the argument and sets the number of GPR (x) and FPR (v) registers
54    it would consume.  For a Homogeneous Floating-point Aggregate the FPR count
55    is the number of members (<= 4); for a non-HFA aggregate <= 16 bytes the GPR
56    count is 1 or 2; scalars use exactly one register of the appropriate bank.
57 
58    Returns false iff the parameter must be passed indirectly (in memory): a
59    non-HFA aggregate larger than 16 bytes.  When bInReturn is true the same
60    classification answers "can this be returned in registers?" (false => the
61    caller must allocate a buffer and pass it in x8).
62 */
63 bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedFPR );
64 
65 /** Does a function returning this type use the hidden indirect-result pointer
66     (passed by the caller in x8), or can it return in registers?
67 
68     A scalar returns in x0 or v0; an HFA returns in v0..v3; a non-HFA aggregate
69     of <= 16 bytes returns in x0,x1.  Anything larger (non-HFA aggregate
70     > 16 bytes) is returned via the caller-allocated buffer addressed by x8 -
71     that is the "hidden param" case, for which this returns true.
72 */
73 bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
74 
75 /** Scatter a register-resident return value (an HFA returned in v0..v3, or a
76     non-HFA aggregate <= 16 bytes returned in x0,x1) into the caller's struct.
77 
78     pGPR points at the saved x0,x1,... ; pFPR at the saved v0,v1,... (each
79     element the low 8 bytes of a v register, i.e. a double slot).  Only valid
80     when return_in_hidden_param() is false.
81 */
82 void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pFPR, void *pStruct );
83 
84 } // namespace aarch64
85 
86 #endif // _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
87