xref: /trunk/main/bridges/source/cpp_uno/gcc3_freebsd_aarch64/abi.hxx (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 #ifndef _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
22*9c15e1abSPedro Giffuni #define _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
23*9c15e1abSPedro Giffuni 
24*9c15e1abSPedro Giffuni // This is an implementation of the AArch64 procedure call standard, as
25*9c15e1abSPedro Giffuni // described in "Procedure Call Standard for the Arm 64-bit Architecture"
26*9c15e1abSPedro Giffuni // (ARM IHI 0055). It is a clean-room implementation written from that
27*9c15e1abSPedro Giffuni // public specification; see ../../../../AAPCS64_BRIDGE_SPEC.md.
28*9c15e1abSPedro Giffuni 
29*9c15e1abSPedro Giffuni #include <typelib/typedescription.hxx>
30*9c15e1abSPedro Giffuni 
31*9c15e1abSPedro Giffuni namespace aarch64
32*9c15e1abSPedro Giffuni {
33*9c15e1abSPedro Giffuni 
34*9c15e1abSPedro Giffuni /* 8 general purpose registers (x0..x7) are used for parameter passing.
35*9c15e1abSPedro Giffuni    Note: the indirect-result-location register x8 is *separate* and is NOT
36*9c15e1abSPedro Giffuni    part of this count. */
37*9c15e1abSPedro Giffuni const sal_uInt32 MAX_GPR_REGS = 8;
38*9c15e1abSPedro Giffuni 
39*9c15e1abSPedro Giffuni /* 8 SIMD/FP registers (v0..v7) are used for parameter passing. */
40*9c15e1abSPedro Giffuni const sal_uInt32 MAX_FPR_REGS = 8;
41*9c15e1abSPedro Giffuni 
42*9c15e1abSPedro Giffuni /* The largest number of registers a single aggregate can occupy: an HFA/HVA
43*9c15e1abSPedro Giffuni    may use up to 4 FP registers; a non-HFA aggregate passed in GPRs uses at
44*9c15e1abSPedro Giffuni    most 2 (16 bytes / 8). */
45*9c15e1abSPedro Giffuni const sal_uInt32 MAX_AGGREGATE_REGS = 4;
46*9c15e1abSPedro Giffuni 
47*9c15e1abSPedro Giffuni enum ReturnKind
48*9c15e1abSPedro Giffuni {
49*9c15e1abSPedro Giffuni     RETURN_KIND_HFA_FLOAT = 0x100,
50*9c15e1abSPedro Giffuni     RETURN_KIND_HFA_DOUBLE = 0x101
51*9c15e1abSPedro Giffuni };
52*9c15e1abSPedro Giffuni 
53*9c15e1abSPedro Giffuni /* Count the number of registers required to pass the given type.
54*9c15e1abSPedro Giffuni 
55*9c15e1abSPedro Giffuni    Examines the argument and sets the number of GPR (x) and FPR (v) registers
56*9c15e1abSPedro Giffuni    it would consume.  For a Homogeneous Floating-point Aggregate the FPR count
57*9c15e1abSPedro Giffuni    is the number of members (<= 4); for a non-HFA aggregate <= 16 bytes the GPR
58*9c15e1abSPedro Giffuni    count is 1 or 2; scalars use exactly one register of the appropriate bank.
59*9c15e1abSPedro Giffuni 
60*9c15e1abSPedro Giffuni    Returns false iff the parameter must be passed indirectly (in memory): a
61*9c15e1abSPedro Giffuni    non-HFA aggregate larger than 16 bytes.  When bInReturn is true the same
62*9c15e1abSPedro Giffuni    classification answers "can this be returned in registers?" (false => the
63*9c15e1abSPedro Giffuni    caller must allocate a buffer and pass it in x8).
64*9c15e1abSPedro Giffuni */
65*9c15e1abSPedro Giffuni bool examine_argument( typelib_TypeDescriptionReference *pTypeRef, bool bInReturn, int &nUsedGPR, int &nUsedFPR );
66*9c15e1abSPedro Giffuni 
67*9c15e1abSPedro Giffuni /** Does a function returning this type use the hidden indirect-result pointer
68*9c15e1abSPedro Giffuni     (passed by the caller in x8), or can it return in registers?
69*9c15e1abSPedro Giffuni 
70*9c15e1abSPedro Giffuni     A scalar returns in x0 or v0; an HFA returns in v0..v3; a non-HFA aggregate
71*9c15e1abSPedro Giffuni     of <= 16 bytes returns in x0,x1.  Anything larger (non-HFA aggregate
72*9c15e1abSPedro Giffuni     > 16 bytes) is returned via the caller-allocated buffer addressed by x8 -
73*9c15e1abSPedro Giffuni     that is the "hidden param" case, for which this returns true.
74*9c15e1abSPedro Giffuni */
75*9c15e1abSPedro Giffuni bool return_in_hidden_param( typelib_TypeDescriptionReference *pTypeRef );
76*9c15e1abSPedro Giffuni 
77*9c15e1abSPedro Giffuni /** Return the assembly return kind for an HFA, or the type class otherwise. */
78*9c15e1abSPedro Giffuni sal_uInt32 get_return_kind( typelib_TypeDescriptionReference *pTypeRef );
79*9c15e1abSPedro Giffuni 
80*9c15e1abSPedro Giffuni /** Scatter a register-resident return value (an HFA returned in v0..v3, or a
81*9c15e1abSPedro Giffuni     non-HFA aggregate <= 16 bytes returned in x0,x1) into the caller's struct.
82*9c15e1abSPedro Giffuni 
83*9c15e1abSPedro Giffuni     pGPR points at the saved x0,x1,... ; pFPR at the saved v0,v1,... (each
84*9c15e1abSPedro Giffuni     element the low 8 bytes of a v register, i.e. a double slot).  Only valid
85*9c15e1abSPedro Giffuni     when return_in_hidden_param() is false.
86*9c15e1abSPedro Giffuni */
87*9c15e1abSPedro Giffuni void fill_struct( typelib_TypeDescriptionReference *pTypeRef, const sal_uInt64* pGPR, const double* pFPR, void *pStruct );
88*9c15e1abSPedro Giffuni 
89*9c15e1abSPedro Giffuni sal_uInt32 align_stack_offset(
90*9c15e1abSPedro Giffuni     sal_uInt32 offset, typelib_TypeDescriptionReference *pTypeRef );
91*9c15e1abSPedro Giffuni 
92*9c15e1abSPedro Giffuni sal_uInt32 stack_size( typelib_TypeDescriptionReference *pTypeRef );
93*9c15e1abSPedro Giffuni 
94*9c15e1abSPedro Giffuni } // namespace aarch64
95*9c15e1abSPedro Giffuni 
96*9c15e1abSPedro Giffuni #endif // _BRIDGES_CPP_UNO_AARCH64_ABI_HXX_
97