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